aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/em28xx/em28xx-cards.c
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2008-12-28 20:18:14 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2008-12-30 06:39:37 -0500
commit1a23f81b7dc3115b29cff0e4f58b5dd04a6242ad (patch)
tree643b900aae78870a53fec3fdf1e15b400ae960c0 /drivers/media/video/em28xx/em28xx-cards.c
parent126be90f720d9b23e89c68519022fb806882f42d (diff)
V4L/DVB (9979): em28xx: move usb probe code to a proper place
em28xx-video were holding several code that are not specific to V4L2 interface. This patch moves the core code for em28xx-core, and usb probing code into em28xx-cards. This opens the possibility of breaking em28xx into a core module and a V4L2 module, loaded only on devices that have analog interfaces. Some cleanup may be done at em28xx-cards to optimize the config code. Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/em28xx/em28xx-cards.c')
-rw-r--r--drivers/media/video/em28xx/em28xx-cards.c430
1 files changed, 430 insertions, 0 deletions
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index e5d9424d03f9..42978f9592b7 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -37,6 +37,8 @@
37 37
38#include "em28xx.h" 38#include "em28xx.h"
39 39
40#define DRIVER_NAME "em28xx"
41
40static int tuner = -1; 42static int tuner = -1;
41module_param(tuner, int, 0444); 43module_param(tuner, int, 0444);
42MODULE_PARM_DESC(tuner, "tuner type"); 44MODULE_PARM_DESC(tuner, "tuner type");
@@ -45,6 +47,13 @@ static unsigned int disable_ir;
45module_param(disable_ir, int, 0444); 47module_param(disable_ir, int, 0444);
46MODULE_PARM_DESC(disable_ir, "disable infrared remote support"); 48MODULE_PARM_DESC(disable_ir, "disable infrared remote support");
47 49
50static unsigned int card[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET };
51module_param_array(card, int, NULL, 0444);
52MODULE_PARM_DESC(card, "card type");
53
54/* Bitmask marking allocated devices from 0 to EM28XX_MAXBOARDS */
55static unsigned long em28xx_devused;
56
48struct em28xx_hash_table { 57struct em28xx_hash_table {
49 unsigned long hash; 58 unsigned long hash;
50 unsigned int model; 59 unsigned int model;
@@ -1801,3 +1810,424 @@ void em28xx_card_setup(struct em28xx *dev)
1801 em28xx_ir_init(dev); 1810 em28xx_ir_init(dev);
1802} 1811}
1803 1812
1813
1814#if defined(CONFIG_MODULES) && defined(MODULE)
1815static void request_module_async(struct work_struct *work)
1816{
1817 struct em28xx *dev = container_of(work,
1818 struct em28xx, request_module_wk);
1819
1820 if (dev->has_audio_class)
1821 request_module("snd-usb-audio");
1822 else if (dev->has_alsa_audio)
1823 request_module("em28xx-alsa");
1824
1825 if (dev->board.has_dvb)
1826 request_module("em28xx-dvb");
1827}
1828
1829static void request_modules(struct em28xx *dev)
1830{
1831 INIT_WORK(&dev->request_module_wk, request_module_async);
1832 schedule_work(&dev->request_module_wk);
1833}
1834#else
1835#define request_modules(dev)
1836#endif /* CONFIG_MODULES */
1837
1838/*
1839 * em28xx_realease_resources()
1840 * unregisters the v4l2,i2c and usb devices
1841 * called when the device gets disconected or at module unload
1842*/
1843void em28xx_release_resources(struct em28xx *dev)
1844{
1845 if (dev->sbutton_input_dev)
1846 em28xx_deregister_snapshot_button(dev);
1847
1848 if (dev->ir)
1849 em28xx_ir_fini(dev);
1850
1851 /*FIXME: I2C IR should be disconnected */
1852
1853 em28xx_release_analog_resources(dev);
1854
1855 em28xx_remove_from_devlist(dev);
1856
1857 em28xx_i2c_unregister(dev);
1858 usb_put_dev(dev->udev);
1859
1860 /* Mark device as unused */
1861 em28xx_devused &= ~(1 << dev->devno);
1862};
1863
1864/*
1865 * em28xx_init_dev()
1866 * allocates and inits the device structs, registers i2c bus and v4l device
1867 */
1868int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
1869 int minor)
1870{
1871 struct em28xx *dev = *devhandle;
1872 int retval = -ENOMEM;
1873 int errCode;
1874
1875 dev->udev = udev;
1876 mutex_init(&dev->ctrl_urb_lock);
1877 spin_lock_init(&dev->slock);
1878 init_waitqueue_head(&dev->open);
1879 init_waitqueue_head(&dev->wait_frame);
1880 init_waitqueue_head(&dev->wait_stream);
1881
1882 dev->em28xx_write_regs = em28xx_write_regs;
1883 dev->em28xx_read_reg = em28xx_read_reg;
1884 dev->em28xx_read_reg_req_len = em28xx_read_reg_req_len;
1885 dev->em28xx_write_regs_req = em28xx_write_regs_req;
1886 dev->em28xx_read_reg_req = em28xx_read_reg_req;
1887 dev->board.is_em2800 = em28xx_boards[dev->model].is_em2800;
1888
1889 em28xx_pre_card_setup(dev);
1890
1891 if (!dev->board.is_em2800) {
1892 /* Sets I2C speed to 100 KHz */
1893 retval = em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x40);
1894 if (retval < 0) {
1895 em28xx_errdev("%s: em28xx_write_regs_req failed!"
1896 " retval [%d]\n",
1897 __func__, retval);
1898 return retval;
1899 }
1900 }
1901
1902 /* register i2c bus */
1903 errCode = em28xx_i2c_register(dev);
1904 if (errCode < 0) {
1905 em28xx_errdev("%s: em28xx_i2c_register - errCode [%d]!\n",
1906 __func__, errCode);
1907 return errCode;
1908 }
1909
1910 /* Do board specific init and eeprom reading */
1911 em28xx_card_setup(dev);
1912
1913 /* Configure audio */
1914 errCode = em28xx_audio_setup(dev);
1915 if (errCode < 0) {
1916 em28xx_errdev("%s: Error while setting audio - errCode [%d]!\n",
1917 __func__, errCode);
1918 }
1919
1920 /* wake i2c devices */
1921 em28xx_wake_i2c(dev);
1922
1923 /* init video dma queues */
1924 INIT_LIST_HEAD(&dev->vidq.active);
1925 INIT_LIST_HEAD(&dev->vidq.queued);
1926
1927
1928 if (dev->board.has_msp34xx) {
1929 /* Send a reset to other chips via gpio */
1930 errCode = em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xf7);
1931 if (errCode < 0) {
1932 em28xx_errdev("%s: em28xx_write_regs_req - "
1933 "msp34xx(1) failed! errCode [%d]\n",
1934 __func__, errCode);
1935 return errCode;
1936 }
1937 msleep(3);
1938
1939 errCode = em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xff);
1940 if (errCode < 0) {
1941 em28xx_errdev("%s: em28xx_write_regs_req - "
1942 "msp34xx(2) failed! errCode [%d]\n",
1943 __func__, errCode);
1944 return errCode;
1945 }
1946 msleep(3);
1947 }
1948
1949 em28xx_add_into_devlist(dev);
1950
1951 errCode = em28xx_analog_config(dev);
1952 if (errCode) {
1953 em28xx_errdev("error configuring device\n");
1954 return -ENOMEM;
1955 }
1956
1957 retval = em28xx_register_analog_devices(dev);
1958 if (retval < 0) {
1959 em28xx_release_resources(dev);
1960 goto fail_reg_devices;
1961 }
1962
1963 em28xx_init_extension(dev);
1964
1965 /* Save some power by putting tuner to sleep */
1966 em28xx_i2c_call_clients(dev, TUNER_SET_STANDBY, NULL);
1967
1968 return 0;
1969
1970fail_reg_devices:
1971 return retval;
1972}
1973
1974/*
1975 * em28xx_usb_probe()
1976 * checks for supported devices
1977 */
1978static int em28xx_usb_probe(struct usb_interface *interface,
1979 const struct usb_device_id *id)
1980{
1981 const struct usb_endpoint_descriptor *endpoint;
1982 struct usb_device *udev;
1983 struct usb_interface *uif;
1984 struct em28xx *dev = NULL;
1985 int retval = -ENODEV;
1986 int i, nr, ifnum, isoc_pipe;
1987 char *speed;
1988 char descr[255] = "";
1989
1990 udev = usb_get_dev(interface_to_usbdev(interface));
1991 ifnum = interface->altsetting[0].desc.bInterfaceNumber;
1992
1993 /* Check to see next free device and mark as used */
1994 nr = find_first_zero_bit(&em28xx_devused, EM28XX_MAXBOARDS);
1995 em28xx_devused |= 1<<nr;
1996
1997 /* Don't register audio interfaces */
1998 if (interface->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) {
1999 em28xx_err(DRIVER_NAME " audio device (%04x:%04x): "
2000 "interface %i, class %i\n",
2001 le16_to_cpu(udev->descriptor.idVendor),
2002 le16_to_cpu(udev->descriptor.idProduct),
2003 ifnum,
2004 interface->altsetting[0].desc.bInterfaceClass);
2005
2006 em28xx_devused &= ~(1<<nr);
2007 return -ENODEV;
2008 }
2009
2010 endpoint = &interface->cur_altsetting->endpoint[0].desc;
2011
2012 /* check if the device has the iso in endpoint at the correct place */
2013 if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
2014 USB_ENDPOINT_XFER_ISOC &&
2015 (interface->altsetting[1].endpoint[0].desc.wMaxPacketSize == 940)) {
2016 /* It's a newer em2874/em2875 device */
2017 isoc_pipe = 0;
2018 } else {
2019 int check_interface = 1;
2020 isoc_pipe = 1;
2021 endpoint = &interface->cur_altsetting->endpoint[1].desc;
2022 if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) !=
2023 USB_ENDPOINT_XFER_ISOC)
2024 check_interface = 0;
2025
2026 if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT)
2027 check_interface = 0;
2028
2029 if (!check_interface) {
2030 em28xx_err(DRIVER_NAME " video device (%04x:%04x): "
2031 "interface %i, class %i found.\n",
2032 le16_to_cpu(udev->descriptor.idVendor),
2033 le16_to_cpu(udev->descriptor.idProduct),
2034 ifnum,
2035 interface->altsetting[0].desc.bInterfaceClass);
2036
2037 em28xx_err(DRIVER_NAME " This is an anciliary "
2038 "interface not used by the driver\n");
2039
2040 em28xx_devused &= ~(1<<nr);
2041 return -ENODEV;
2042 }
2043 }
2044
2045 switch (udev->speed) {
2046 case USB_SPEED_LOW:
2047 speed = "1.5";
2048 break;
2049 case USB_SPEED_UNKNOWN:
2050 case USB_SPEED_FULL:
2051 speed = "12";
2052 break;
2053 case USB_SPEED_HIGH:
2054 speed = "480";
2055 break;
2056 default:
2057 speed = "unknown";
2058 }
2059
2060 if (udev->manufacturer)
2061 strlcpy(descr, udev->manufacturer, sizeof(descr));
2062
2063 if (udev->product) {
2064 if (*descr)
2065 strlcat(descr, " ", sizeof(descr));
2066 strlcat(descr, udev->product, sizeof(descr));
2067 }
2068 if (*descr)
2069 strlcat(descr, " ", sizeof(descr));
2070
2071 printk(DRIVER_NAME ": New device %s@ %s Mbps "
2072 "(%04x:%04x, interface %d, class %d)\n",
2073 descr,
2074 speed,
2075 le16_to_cpu(udev->descriptor.idVendor),
2076 le16_to_cpu(udev->descriptor.idProduct),
2077 ifnum,
2078 interface->altsetting->desc.bInterfaceNumber);
2079
2080 if (nr >= EM28XX_MAXBOARDS) {
2081 printk(DRIVER_NAME ": Supports only %i em28xx boards.\n",
2082 EM28XX_MAXBOARDS);
2083 em28xx_devused &= ~(1<<nr);
2084 return -ENOMEM;
2085 }
2086
2087 /* allocate memory for our device state and initialize it */
2088 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
2089 if (dev == NULL) {
2090 em28xx_err(DRIVER_NAME ": out of memory!\n");
2091 em28xx_devused &= ~(1<<nr);
2092 return -ENOMEM;
2093 }
2094
2095 snprintf(dev->name, 29, "em28xx #%d", nr);
2096 dev->devno = nr;
2097 dev->model = id->driver_info;
2098 dev->alt = -1;
2099
2100 /* Checks if audio is provided by some interface */
2101 for (i = 0; i < udev->config->desc.bNumInterfaces; i++) {
2102 uif = udev->config->interface[i];
2103 if (uif->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) {
2104 dev->has_audio_class = 1;
2105 break;
2106 }
2107 }
2108
2109 /* compute alternate max packet sizes */
2110 uif = udev->actconfig->interface[0];
2111
2112 dev->num_alt = uif->num_altsetting;
2113 dev->alt_max_pkt_size = kmalloc(32 * dev->num_alt, GFP_KERNEL);
2114
2115 if (dev->alt_max_pkt_size == NULL) {
2116 em28xx_errdev("out of memory!\n");
2117 em28xx_devused &= ~(1<<nr);
2118 kfree(dev);
2119 return -ENOMEM;
2120 }
2121
2122 for (i = 0; i < dev->num_alt ; i++) {
2123 u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].desc.wMaxPacketSize);
2124 dev->alt_max_pkt_size[i] =
2125 (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
2126 }
2127
2128 if ((card[nr] >= 0) && (card[nr] < em28xx_bcount))
2129 dev->model = card[nr];
2130
2131 /* allocate device struct */
2132 mutex_init(&dev->lock);
2133 mutex_lock(&dev->lock);
2134 retval = em28xx_init_dev(&dev, udev, nr);
2135 if (retval) {
2136 em28xx_devused &= ~(1<<dev->devno);
2137 kfree(dev);
2138
2139 return retval;
2140 }
2141
2142 /* save our data pointer in this interface device */
2143 usb_set_intfdata(interface, dev);
2144
2145 request_modules(dev);
2146
2147 /* Should be the last thing to do, to avoid newer udev's to
2148 open the device before fully initializing it
2149 */
2150 mutex_unlock(&dev->lock);
2151
2152 return 0;
2153}
2154
2155/*
2156 * em28xx_usb_disconnect()
2157 * called when the device gets diconencted
2158 * video device will be unregistered on v4l2_close in case it is still open
2159 */
2160static void em28xx_usb_disconnect(struct usb_interface *interface)
2161{
2162 struct em28xx *dev;
2163
2164 dev = usb_get_intfdata(interface);
2165 usb_set_intfdata(interface, NULL);
2166
2167 if (!dev)
2168 return;
2169
2170 em28xx_info("disconnecting %s\n", dev->vdev->name);
2171
2172 /* wait until all current v4l2 io is finished then deallocate
2173 resources */
2174 mutex_lock(&dev->lock);
2175
2176 wake_up_interruptible_all(&dev->open);
2177
2178 if (dev->users) {
2179 em28xx_warn
2180 ("device /dev/video%d is open! Deregistration and memory "
2181 "deallocation are deferred on close.\n",
2182 dev->vdev->num);
2183
2184 dev->state |= DEV_MISCONFIGURED;
2185 em28xx_uninit_isoc(dev);
2186 dev->state |= DEV_DISCONNECTED;
2187 wake_up_interruptible(&dev->wait_frame);
2188 wake_up_interruptible(&dev->wait_stream);
2189 } else {
2190 dev->state |= DEV_DISCONNECTED;
2191 em28xx_release_resources(dev);
2192 }
2193
2194 em28xx_close_extension(dev);
2195
2196 mutex_unlock(&dev->lock);
2197
2198 if (!dev->users) {
2199 kfree(dev->alt_max_pkt_size);
2200 kfree(dev);
2201 }
2202}
2203
2204static struct usb_driver em28xx_usb_driver = {
2205 .name = "em28xx",
2206 .probe = em28xx_usb_probe,
2207 .disconnect = em28xx_usb_disconnect,
2208 .id_table = em28xx_id_table,
2209};
2210
2211static int __init em28xx_module_init(void)
2212{
2213 int result;
2214
2215 /* register this driver with the USB subsystem */
2216 result = usb_register(&em28xx_usb_driver);
2217 if (result)
2218 em28xx_err(DRIVER_NAME
2219 " usb_register failed. Error number %d.\n", result);
2220
2221 printk(KERN_INFO DRIVER_NAME " driver loaded\n");
2222
2223 return result;
2224}
2225
2226static void __exit em28xx_module_exit(void)
2227{
2228 /* deregister this driver with the USB subsystem */
2229 usb_deregister(&em28xx_usb_driver);
2230}
2231
2232module_init(em28xx_module_init);
2233module_exit(em28xx_module_exit);