summaryrefslogtreecommitdiff
path: root/linux/drivers/media
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@infradead.org>2008-01-05 10:59:03 -0200
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-01-05 10:59:03 -0200
commit55d8d49cc70bab1115e2ce34939ca5b5db5b3dfb (patch)
treeeaf0506dade92d4cdbb26ea69705107227eceb6e /linux/drivers/media
parent05c059b96e21efe3087c55a1cc9d7ee598eaa92d (diff)
downloadmediapointer-dvb-s2-55d8d49cc70bab1115e2ce34939ca5b5db5b3dfb.tar.gz
mediapointer-dvb-s2-55d8d49cc70bab1115e2ce34939ca5b5db5b3dfb.tar.bz2
Add code for autoloading em28xx-alsa, if needed
From: Mauro Carvalho Chehab <mchehab@infradead.org> 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. Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'linux/drivers/media')
-rw-r--r--linux/drivers/media/video/em28xx/em28xx-audio.c1
-rw-r--r--linux/drivers/media/video/em28xx/em28xx-video.c53
-rw-r--r--linux/drivers/media/video/em28xx/em28xx.h3
3 files changed, 56 insertions, 1 deletions
diff --git a/linux/drivers/media/video/em28xx/em28xx-audio.c b/linux/drivers/media/video/em28xx/em28xx-audio.c
index 8329ba287..901eeeb5c 100644
--- a/linux/drivers/media/video/em28xx/em28xx-audio.c
+++ b/linux/drivers/media/video/em28xx/em28xx-audio.c
@@ -542,7 +542,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/linux/drivers/media/video/em28xx/em28xx-video.c b/linux/drivers/media/video/em28xx/em28xx-video.c
index a550eeb89..1a269b643 100644
--- a/linux/drivers/media/video/em28xx/em28xx-video.c
+++ b/linux/drivers/media/video/em28xx/em28xx-video.c
@@ -1740,6 +1740,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);
@@ -1869,6 +1873,40 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
return 0;
}
+#if defined(CONFIG_MODULES) && defined(MODULE)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
+static void request_module_async(void *ptr)
+{
+ struct em28xx *dev = (struct em28xx *)ptr;
+#else
+static void request_module_async(struct work_struct *work)
+{
+ struct em28xx *dev = container_of(work,
+ struct em28xx, request_module_wk);
+#endif
+
+ if (!dev->has_audio_class)
+ request_module("em28xx-alsa");
+}
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)
+#define request_modules(dev)
+#else
+static void request_modules(struct em28xx *dev)
+{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
+ INIT_WORK(&dev->request_module_wk, request_module_async,
+ (void *)dev);
+#else
+ INIT_WORK(&dev->request_module_wk, request_module_async);
+#endif
+ schedule_work(&dev->request_module_wk);
+}
+#endif
+#else
+#define request_modules(dev)
+#endif /* CONFIG_MODULES */
+
/*
* em28xx_usb_probe()
* checks for supported devices
@@ -1939,6 +1977,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];
@@ -1975,6 +2025,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/linux/drivers/media/video/em28xx/em28xx.h b/linux/drivers/media/video/em28xx/em28xx.h
index ffe109077..64a63b2c8 100644
--- a/linux/drivers/media/video/em28xx/em28xx.h
+++ b/linux/drivers/media/video/em28xx/em28xx.h
@@ -257,6 +257,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;
@@ -306,6 +307,8 @@ struct em28xx {
enum em28xx_stream_state stream;
enum em28xx_io_method io;
+ struct work_struct request_module_wk;
+
/* locks */
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
struct mutex lock;