Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=d7448a8d9d06ca2ca4fd1f17404450ecba8bea3a
Commit:     d7448a8d9d06ca2ca4fd1f17404450ecba8bea3a
Parent:     6d79468dd8537530f4150e76ed9b4b63f80571c6
Author:     Mauro Carvalho Chehab <[EMAIL PROTECTED]>
AuthorDate: Sat Jan 5 09:59:03 2008 -0300
Committer:  Mauro Carvalho Chehab <[EMAIL PROTECTED]>
CommitDate: Fri Jan 25 19:04:32 2008 -0200

    V4L/DVB (6952): Add code for autoloading em28xx-alsa, if needed
    
    Older em28xx devices does implement standard Audio Class.
    
    However, on newer devices, this were replaced by a Vendor Class. This
    patch autodetects that an em28xx lacks Audio Class and auto-loads
    em28xx-alsa, for the devices that implements only a Vendor Class.
    
    For devices with Audio Class, snd-usb-audio module will provide an ALSA
    interface.
    
    This patch uses the request_module_async function as defined on cx88-mpeg.c,
    originally wrote by Markus Rechberger.
    
    Signed-off-by: Mauro Carvalho Chehab <[EMAIL PROTECTED]>
---
 drivers/media/video/em28xx/em28xx-audio.c |    1 -
 drivers/media/video/em28xx/em28xx-video.c |   38 +++++++++++++++++++++++++++++
 drivers/media/video/em28xx/em28xx.h       |    3 ++
 3 files changed, 41 insertions(+), 1 deletions(-)

diff --git a/drivers/media/video/em28xx/em28xx-audio.c 
b/drivers/media/video/em28xx/em28xx-audio.c
index c91ff52..941357c 100644
--- a/drivers/media/video/em28xx/em28xx-audio.c
+++ b/drivers/media/video/em28xx/em28xx-audio.c
@@ -472,7 +472,6 @@ static struct em28xx_ops audio_ops = {
 
 static int __init em28xx_alsa_register(void)
 {
-       request_module("em28xx");
        return em28xx_register_extension(&audio_ops);
 }
 
diff --git a/drivers/media/video/em28xx/em28xx-video.c 
b/drivers/media/video/em28xx/em28xx-video.c
index caa4757..a03e9d7 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -1668,6 +1668,10 @@ static int em28xx_init_dev(struct em28xx **devhandle, 
struct usb_device *udev,
        dev->em28xx_read_reg_req = em28xx_read_reg_req;
        dev->is_em2800 = em28xx_boards[dev->model].is_em2800;
 
+       errCode = em28xx_read_reg(dev, CHIPID_REG);
+       if (errCode >= 0)
+               em28xx_info("em28xx chip ID = %d\n", errCode);
+
        em28xx_pre_card_setup(dev);
 
        errCode = em28xx_config(dev);
@@ -1794,6 +1798,25 @@ static int em28xx_init_dev(struct em28xx **devhandle, 
struct usb_device *udev,
        return 0;
 }
 
+#if defined(CONFIG_MODULES) && defined(MODULE)
+static void request_module_async(struct work_struct *work)
+{
+       struct em28xx *dev = container_of(work,
+                            struct em28xx, request_module_wk);
+
+       if (!dev->has_audio_class)
+               request_module("em28xx-alsa");
+}
+
+static void request_modules(struct em28xx *dev)
+{
+       INIT_WORK(&dev->request_module_wk, request_module_async);
+       schedule_work(&dev->request_module_wk);
+}
+#else
+#define request_modules(dev)
+#endif /* CONFIG_MODULES */
+
 /*
  * em28xx_usb_probe()
  * checks for supported devices
@@ -1864,6 +1887,18 @@ static int em28xx_usb_probe(struct usb_interface 
*interface,
        dev->devno = nr;
        dev->model = id->driver_info;
 
+       /* Checks if audio is provided by some interface */
+       for (i = 0; i < udev->config->desc.bNumInterfaces; i++) {
+               uif = udev->config->interface[i];
+               if (uif->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) 
{
+                       dev->has_audio_class = 1;
+                       break;
+               }
+       }
+
+       printk(KERN_INFO DRIVER_NAME " %s usb audio class\n",
+                  dev->has_audio_class ? "Has" : "Doesn't have");
+
        /* compute alternate max packet sizes */
        uif = udev->actconfig->interface[0];
 
@@ -1900,6 +1935,9 @@ static int em28xx_usb_probe(struct usb_interface 
*interface,
 
        /* save our data pointer in this interface device */
        usb_set_intfdata(interface, dev);
+
+       request_modules(dev);
+
        return 0;
 }
 
diff --git a/drivers/media/video/em28xx/em28xx.h 
b/drivers/media/video/em28xx/em28xx.h
index c2d9ae0..9eb2131 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -246,6 +246,7 @@ struct em28xx {
        unsigned int has_msp34xx:1;
        unsigned int has_tda9887:1;
        unsigned int stream_on:1;       /* Locks streams */
+       unsigned int has_audio_class:1;
 
        int video_inputs;       /* number of video inputs */
        struct list_head        devlist;
@@ -295,6 +296,8 @@ struct em28xx {
        enum em28xx_stream_state stream;
        enum em28xx_io_method io;
 
+       struct work_struct         request_module_wk;
+
        /* locks */
        struct mutex lock;
        spinlock_t queue_lock;
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to