aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/em28xx/em28xx-video.c
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@infradead.org>2008-01-05 07:59:03 -0500
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-01-25 16:04:32 -0500
commitd7448a8d9d06ca2ca4fd1f17404450ecba8bea3a (patch)
tree61be9e95bdf31c4cde511c67ce2f526bb816d0f8 /drivers/media/video/em28xx/em28xx-video.c
parent6d79468dd8537530f4150e76ed9b4b63f80571c6 (diff)
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 <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video/em28xx/em28xx-video.c')
-rw-r--r--drivers/media/video/em28xx/em28xx-video.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index caa4757b7eb6..a03e9d724b5f 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,
1668 dev->em28xx_read_reg_req = em28xx_read_reg_req; 1668 dev->em28xx_read_reg_req = em28xx_read_reg_req;
1669 dev->is_em2800 = em28xx_boards[dev->model].is_em2800; 1669 dev->is_em2800 = em28xx_boards[dev->model].is_em2800;
1670 1670
1671 errCode = em28xx_read_reg(dev, CHIPID_REG);
1672 if (errCode >= 0)
1673 em28xx_info("em28xx chip ID = %d\n", errCode);
1674
1671 em28xx_pre_card_setup(dev); 1675 em28xx_pre_card_setup(dev);
1672 1676
1673 errCode = em28xx_config(dev); 1677 errCode = em28xx_config(dev);
@@ -1794,6 +1798,25 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
1794 return 0; 1798 return 0;
1795} 1799}
1796 1800
1801#if defined(CONFIG_MODULES) && defined(MODULE)
1802static void request_module_async(struct work_struct *work)
1803{
1804 struct em28xx *dev = container_of(work,
1805 struct em28xx, request_module_wk);
1806
1807 if (!dev->has_audio_class)
1808 request_module("em28xx-alsa");
1809}
1810
1811static void request_modules(struct em28xx *dev)
1812{
1813 INIT_WORK(&dev->request_module_wk, request_module_async);
1814 schedule_work(&dev->request_module_wk);
1815}
1816#else
1817#define request_modules(dev)
1818#endif /* CONFIG_MODULES */
1819
1797/* 1820/*
1798 * em28xx_usb_probe() 1821 * em28xx_usb_probe()
1799 * checks for supported devices 1822 * checks for supported devices
@@ -1864,6 +1887,18 @@ static int em28xx_usb_probe(struct usb_interface *interface,
1864 dev->devno = nr; 1887 dev->devno = nr;
1865 dev->model = id->driver_info; 1888 dev->model = id->driver_info;
1866 1889
1890 /* Checks if audio is provided by some interface */
1891 for (i = 0; i < udev->config->desc.bNumInterfaces; i++) {
1892 uif = udev->config->interface[i];
1893 if (uif->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) {
1894 dev->has_audio_class = 1;
1895 break;
1896 }
1897 }
1898
1899 printk(KERN_INFO DRIVER_NAME " %s usb audio class\n",
1900 dev->has_audio_class ? "Has" : "Doesn't have");
1901
1867 /* compute alternate max packet sizes */ 1902 /* compute alternate max packet sizes */
1868 uif = udev->actconfig->interface[0]; 1903 uif = udev->actconfig->interface[0];
1869 1904
@@ -1900,6 +1935,9 @@ static int em28xx_usb_probe(struct usb_interface *interface,
1900 1935
1901 /* save our data pointer in this interface device */ 1936 /* save our data pointer in this interface device */
1902 usb_set_intfdata(interface, dev); 1937 usb_set_intfdata(interface, dev);
1938
1939 request_modules(dev);
1940
1903 return 0; 1941 return 0;
1904} 1942}
1905 1943