diff options
Diffstat (limited to 'drivers/media/video/em28xx/em28xx-video.c')
-rw-r--r-- | drivers/media/video/em28xx/em28xx-video.c | 143 |
1 files changed, 83 insertions, 60 deletions
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index a1ab2ef45578..4ea1f1e04897 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c | |||
@@ -73,6 +73,7 @@ MODULE_DESCRIPTION(DRIVER_DESC); | |||
73 | MODULE_LICENSE("GPL"); | 73 | MODULE_LICENSE("GPL"); |
74 | 74 | ||
75 | static LIST_HEAD(em28xx_devlist); | 75 | static LIST_HEAD(em28xx_devlist); |
76 | static DEFINE_MUTEX(em28xx_devlist_mutex); | ||
76 | 77 | ||
77 | static unsigned int card[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET }; | 78 | static unsigned int card[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET }; |
78 | static unsigned int video_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET }; | 79 | static unsigned int video_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET }; |
@@ -548,10 +549,11 @@ static int em28xx_config(struct em28xx *dev) | |||
548 | static void em28xx_config_i2c(struct em28xx *dev) | 549 | static void em28xx_config_i2c(struct em28xx *dev) |
549 | { | 550 | { |
550 | struct v4l2_routing route; | 551 | struct v4l2_routing route; |
552 | int zero = 0; | ||
551 | 553 | ||
552 | route.input = INPUT(dev->ctl_input)->vmux; | 554 | route.input = INPUT(dev->ctl_input)->vmux; |
553 | route.output = 0; | 555 | route.output = 0; |
554 | em28xx_i2c_call_clients(dev, VIDIOC_INT_RESET, NULL); | 556 | em28xx_i2c_call_clients(dev, VIDIOC_INT_RESET, &zero); |
555 | em28xx_i2c_call_clients(dev, VIDIOC_INT_S_VIDEO_ROUTING, &route); | 557 | em28xx_i2c_call_clients(dev, VIDIOC_INT_S_VIDEO_ROUTING, &route); |
556 | em28xx_i2c_call_clients(dev, VIDIOC_STREAMON, NULL); | 558 | em28xx_i2c_call_clients(dev, VIDIOC_STREAMON, NULL); |
557 | } | 559 | } |
@@ -1519,7 +1521,7 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp) | |||
1519 | struct em28xx_fh *fh; | 1521 | struct em28xx_fh *fh; |
1520 | enum v4l2_buf_type fh_type = 0; | 1522 | enum v4l2_buf_type fh_type = 0; |
1521 | 1523 | ||
1522 | lock_kernel(); | 1524 | mutex_lock(&em28xx_devlist_mutex); |
1523 | list_for_each_entry(h, &em28xx_devlist, devlist) { | 1525 | list_for_each_entry(h, &em28xx_devlist, devlist) { |
1524 | if (h->vdev->minor == minor) { | 1526 | if (h->vdev->minor == minor) { |
1525 | dev = h; | 1527 | dev = h; |
@@ -1535,10 +1537,11 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp) | |||
1535 | dev = h; | 1537 | dev = h; |
1536 | } | 1538 | } |
1537 | } | 1539 | } |
1538 | if (NULL == dev) { | 1540 | mutex_unlock(&em28xx_devlist_mutex); |
1539 | unlock_kernel(); | 1541 | if (NULL == dev) |
1540 | return -ENODEV; | 1542 | return -ENODEV; |
1541 | } | 1543 | |
1544 | mutex_lock(&dev->lock); | ||
1542 | 1545 | ||
1543 | em28xx_videodbg("open minor=%d type=%s users=%d\n", | 1546 | em28xx_videodbg("open minor=%d type=%s users=%d\n", |
1544 | minor, v4l2_type_names[fh_type], dev->users); | 1547 | minor, v4l2_type_names[fh_type], dev->users); |
@@ -1547,10 +1550,9 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp) | |||
1547 | fh = kzalloc(sizeof(struct em28xx_fh), GFP_KERNEL); | 1550 | fh = kzalloc(sizeof(struct em28xx_fh), GFP_KERNEL); |
1548 | if (!fh) { | 1551 | if (!fh) { |
1549 | em28xx_errdev("em28xx-video.c: Out of memory?!\n"); | 1552 | em28xx_errdev("em28xx-video.c: Out of memory?!\n"); |
1550 | unlock_kernel(); | 1553 | mutex_unlock(&dev->lock); |
1551 | return -ENOMEM; | 1554 | return -ENOMEM; |
1552 | } | 1555 | } |
1553 | mutex_lock(&dev->lock); | ||
1554 | fh->dev = dev; | 1556 | fh->dev = dev; |
1555 | fh->radio = radio; | 1557 | fh->radio = radio; |
1556 | fh->type = fh_type; | 1558 | fh->type = fh_type; |
@@ -1584,7 +1586,6 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp) | |||
1584 | sizeof(struct em28xx_buffer), fh); | 1586 | sizeof(struct em28xx_buffer), fh); |
1585 | 1587 | ||
1586 | mutex_unlock(&dev->lock); | 1588 | mutex_unlock(&dev->lock); |
1587 | unlock_kernel(); | ||
1588 | 1589 | ||
1589 | return errCode; | 1590 | return errCode; |
1590 | } | 1591 | } |
@@ -1871,6 +1872,7 @@ int em28xx_register_extension(struct em28xx_ops *ops) | |||
1871 | { | 1872 | { |
1872 | struct em28xx *dev = NULL; | 1873 | struct em28xx *dev = NULL; |
1873 | 1874 | ||
1875 | mutex_lock(&em28xx_devlist_mutex); | ||
1874 | mutex_lock(&em28xx_extension_devlist_lock); | 1876 | mutex_lock(&em28xx_extension_devlist_lock); |
1875 | list_add_tail(&ops->next, &em28xx_extension_devlist); | 1877 | list_add_tail(&ops->next, &em28xx_extension_devlist); |
1876 | list_for_each_entry(dev, &em28xx_devlist, devlist) { | 1878 | list_for_each_entry(dev, &em28xx_devlist, devlist) { |
@@ -1879,6 +1881,7 @@ int em28xx_register_extension(struct em28xx_ops *ops) | |||
1879 | } | 1881 | } |
1880 | printk(KERN_INFO "Em28xx: Initialized (%s) extension\n", ops->name); | 1882 | printk(KERN_INFO "Em28xx: Initialized (%s) extension\n", ops->name); |
1881 | mutex_unlock(&em28xx_extension_devlist_lock); | 1883 | mutex_unlock(&em28xx_extension_devlist_lock); |
1884 | mutex_unlock(&em28xx_devlist_mutex); | ||
1882 | return 0; | 1885 | return 0; |
1883 | } | 1886 | } |
1884 | EXPORT_SYMBOL(em28xx_register_extension); | 1887 | EXPORT_SYMBOL(em28xx_register_extension); |
@@ -1887,6 +1890,7 @@ void em28xx_unregister_extension(struct em28xx_ops *ops) | |||
1887 | { | 1890 | { |
1888 | struct em28xx *dev = NULL; | 1891 | struct em28xx *dev = NULL; |
1889 | 1892 | ||
1893 | mutex_lock(&em28xx_devlist_mutex); | ||
1890 | list_for_each_entry(dev, &em28xx_devlist, devlist) { | 1894 | list_for_each_entry(dev, &em28xx_devlist, devlist) { |
1891 | if (dev) | 1895 | if (dev) |
1892 | ops->fini(dev); | 1896 | ops->fini(dev); |
@@ -1896,6 +1900,7 @@ void em28xx_unregister_extension(struct em28xx_ops *ops) | |||
1896 | printk(KERN_INFO "Em28xx: Removed (%s) extension\n", ops->name); | 1900 | printk(KERN_INFO "Em28xx: Removed (%s) extension\n", ops->name); |
1897 | list_del(&ops->next); | 1901 | list_del(&ops->next); |
1898 | mutex_unlock(&em28xx_extension_devlist_lock); | 1902 | mutex_unlock(&em28xx_extension_devlist_lock); |
1903 | mutex_unlock(&em28xx_devlist_mutex); | ||
1899 | } | 1904 | } |
1900 | EXPORT_SYMBOL(em28xx_unregister_extension); | 1905 | EXPORT_SYMBOL(em28xx_unregister_extension); |
1901 | 1906 | ||
@@ -1921,6 +1926,60 @@ static struct video_device *em28xx_vdev_init(struct em28xx *dev, | |||
1921 | } | 1926 | } |
1922 | 1927 | ||
1923 | 1928 | ||
1929 | static int register_analog_devices(struct em28xx *dev) | ||
1930 | { | ||
1931 | int ret; | ||
1932 | |||
1933 | /* allocate and fill video video_device struct */ | ||
1934 | dev->vdev = em28xx_vdev_init(dev, &em28xx_video_template, "video"); | ||
1935 | if (!dev->vdev) { | ||
1936 | em28xx_errdev("cannot allocate video_device.\n"); | ||
1937 | return -ENODEV; | ||
1938 | } | ||
1939 | |||
1940 | /* register v4l2 video video_device */ | ||
1941 | ret = video_register_device(dev->vdev, VFL_TYPE_GRABBER, | ||
1942 | video_nr[dev->devno]); | ||
1943 | if (ret) { | ||
1944 | em28xx_errdev("unable to register video device (error=%i).\n", | ||
1945 | ret); | ||
1946 | return ret; | ||
1947 | } | ||
1948 | |||
1949 | /* Allocate and fill vbi video_device struct */ | ||
1950 | dev->vbi_dev = em28xx_vdev_init(dev, &em28xx_video_template, "vbi"); | ||
1951 | |||
1952 | /* register v4l2 vbi video_device */ | ||
1953 | ret = video_register_device(dev->vbi_dev, VFL_TYPE_VBI, | ||
1954 | vbi_nr[dev->devno]); | ||
1955 | if (ret < 0) { | ||
1956 | em28xx_errdev("unable to register vbi device\n"); | ||
1957 | return ret; | ||
1958 | } | ||
1959 | |||
1960 | if (em28xx_boards[dev->model].radio.type == EM28XX_RADIO) { | ||
1961 | dev->radio_dev = em28xx_vdev_init(dev, &em28xx_radio_template, "radio"); | ||
1962 | if (!dev->radio_dev) { | ||
1963 | em28xx_errdev("cannot allocate video_device.\n"); | ||
1964 | return -ENODEV; | ||
1965 | } | ||
1966 | ret = video_register_device(dev->radio_dev, VFL_TYPE_RADIO, | ||
1967 | radio_nr[dev->devno]); | ||
1968 | if (ret < 0) { | ||
1969 | em28xx_errdev("can't register radio device\n"); | ||
1970 | return ret; | ||
1971 | } | ||
1972 | em28xx_info("Registered radio device as /dev/radio%d\n", | ||
1973 | dev->radio_dev->num); | ||
1974 | } | ||
1975 | |||
1976 | em28xx_info("V4L2 device registered as /dev/video%d and /dev/vbi%d\n", | ||
1977 | dev->vdev->num, dev->vbi_dev->num); | ||
1978 | |||
1979 | return 0; | ||
1980 | } | ||
1981 | |||
1982 | |||
1924 | /* | 1983 | /* |
1925 | * em28xx_init_dev() | 1984 | * em28xx_init_dev() |
1926 | * allocates and inits the device structs, registers i2c bus and v4l device | 1985 | * allocates and inits the device structs, registers i2c bus and v4l device |
@@ -1936,6 +1995,7 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, | |||
1936 | 1995 | ||
1937 | dev->udev = udev; | 1996 | dev->udev = udev; |
1938 | mutex_init(&dev->lock); | 1997 | mutex_init(&dev->lock); |
1998 | mutex_init(&dev->ctrl_urb_lock); | ||
1939 | spin_lock_init(&dev->slock); | 1999 | spin_lock_init(&dev->slock); |
1940 | init_waitqueue_head(&dev->open); | 2000 | init_waitqueue_head(&dev->open); |
1941 | init_waitqueue_head(&dev->wait_frame); | 2001 | init_waitqueue_head(&dev->wait_frame); |
@@ -1953,8 +2013,6 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, | |||
1953 | errCode = em28xx_config(dev); | 2013 | errCode = em28xx_config(dev); |
1954 | if (errCode) { | 2014 | if (errCode) { |
1955 | em28xx_errdev("error configuring device\n"); | 2015 | em28xx_errdev("error configuring device\n"); |
1956 | em28xx_devused &= ~(1<<dev->devno); | ||
1957 | kfree(dev); | ||
1958 | return -ENOMEM; | 2016 | return -ENOMEM; |
1959 | } | 2017 | } |
1960 | 2018 | ||
@@ -2001,50 +2059,6 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, | |||
2001 | return errCode; | 2059 | return errCode; |
2002 | } | 2060 | } |
2003 | 2061 | ||
2004 | list_add_tail(&dev->devlist, &em28xx_devlist); | ||
2005 | |||
2006 | /* allocate and fill video video_device struct */ | ||
2007 | dev->vdev = em28xx_vdev_init(dev, &em28xx_video_template, "video"); | ||
2008 | if (NULL == dev->vdev) { | ||
2009 | em28xx_errdev("cannot allocate video_device.\n"); | ||
2010 | goto fail_unreg; | ||
2011 | } | ||
2012 | |||
2013 | /* register v4l2 video video_device */ | ||
2014 | retval = video_register_device(dev->vdev, VFL_TYPE_GRABBER, | ||
2015 | video_nr[dev->devno]); | ||
2016 | if (retval) { | ||
2017 | em28xx_errdev("unable to register video device (error=%i).\n", | ||
2018 | retval); | ||
2019 | goto fail_unreg; | ||
2020 | } | ||
2021 | |||
2022 | /* Allocate and fill vbi video_device struct */ | ||
2023 | dev->vbi_dev = em28xx_vdev_init(dev, &em28xx_video_template, "vbi"); | ||
2024 | /* register v4l2 vbi video_device */ | ||
2025 | if (video_register_device(dev->vbi_dev, VFL_TYPE_VBI, | ||
2026 | vbi_nr[dev->devno]) < 0) { | ||
2027 | em28xx_errdev("unable to register vbi device\n"); | ||
2028 | retval = -ENODEV; | ||
2029 | goto fail_unreg; | ||
2030 | } | ||
2031 | |||
2032 | if (em28xx_boards[dev->model].radio.type == EM28XX_RADIO) { | ||
2033 | dev->radio_dev = em28xx_vdev_init(dev, &em28xx_radio_template, "radio"); | ||
2034 | if (NULL == dev->radio_dev) { | ||
2035 | em28xx_errdev("cannot allocate video_device.\n"); | ||
2036 | goto fail_unreg; | ||
2037 | } | ||
2038 | retval = video_register_device(dev->radio_dev, VFL_TYPE_RADIO, | ||
2039 | radio_nr[dev->devno]); | ||
2040 | if (retval < 0) { | ||
2041 | em28xx_errdev("can't register radio device\n"); | ||
2042 | goto fail_unreg; | ||
2043 | } | ||
2044 | em28xx_info("Registered radio device as /dev/radio%d\n", | ||
2045 | dev->radio_dev->num); | ||
2046 | } | ||
2047 | |||
2048 | /* init video dma queues */ | 2062 | /* init video dma queues */ |
2049 | INIT_LIST_HEAD(&dev->vidq.active); | 2063 | INIT_LIST_HEAD(&dev->vidq.active); |
2050 | INIT_LIST_HEAD(&dev->vidq.queued); | 2064 | INIT_LIST_HEAD(&dev->vidq.queued); |
@@ -2071,8 +2085,14 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, | |||
2071 | 2085 | ||
2072 | video_mux(dev, 0); | 2086 | video_mux(dev, 0); |
2073 | 2087 | ||
2074 | em28xx_info("V4L2 device registered as /dev/video%d and /dev/vbi%d\n", | 2088 | mutex_lock(&em28xx_devlist_mutex); |
2075 | dev->vdev->num, dev->vbi_dev->num); | 2089 | list_add_tail(&dev->devlist, &em28xx_devlist); |
2090 | retval = register_analog_devices(dev); | ||
2091 | if (retval < 0) { | ||
2092 | em28xx_release_resources(dev); | ||
2093 | mutex_unlock(&em28xx_devlist_mutex); | ||
2094 | goto fail_reg_devices; | ||
2095 | } | ||
2076 | 2096 | ||
2077 | mutex_lock(&em28xx_extension_devlist_lock); | 2097 | mutex_lock(&em28xx_extension_devlist_lock); |
2078 | if (!list_empty(&em28xx_extension_devlist)) { | 2098 | if (!list_empty(&em28xx_extension_devlist)) { |
@@ -2082,13 +2102,12 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, | |||
2082 | } | 2102 | } |
2083 | } | 2103 | } |
2084 | mutex_unlock(&em28xx_extension_devlist_lock); | 2104 | mutex_unlock(&em28xx_extension_devlist_lock); |
2105 | mutex_unlock(&em28xx_devlist_mutex); | ||
2085 | 2106 | ||
2086 | return 0; | 2107 | return 0; |
2087 | 2108 | ||
2088 | fail_unreg: | 2109 | fail_reg_devices: |
2089 | em28xx_release_resources(dev); | ||
2090 | mutex_unlock(&dev->lock); | 2110 | mutex_unlock(&dev->lock); |
2091 | kfree(dev); | ||
2092 | return retval; | 2111 | return retval; |
2093 | } | 2112 | } |
2094 | 2113 | ||
@@ -2231,8 +2250,12 @@ static int em28xx_usb_probe(struct usb_interface *interface, | |||
2231 | 2250 | ||
2232 | /* allocate device struct */ | 2251 | /* allocate device struct */ |
2233 | retval = em28xx_init_dev(&dev, udev, nr); | 2252 | retval = em28xx_init_dev(&dev, udev, nr); |
2234 | if (retval) | 2253 | if (retval) { |
2254 | em28xx_devused &= ~(1<<dev->devno); | ||
2255 | kfree(dev); | ||
2256 | |||
2235 | return retval; | 2257 | return retval; |
2258 | } | ||
2236 | 2259 | ||
2237 | em28xx_info("Found %s\n", em28xx_boards[dev->model].name); | 2260 | em28xx_info("Found %s\n", em28xx_boards[dev->model].name); |
2238 | 2261 | ||