diff options
-rw-r--r-- | drivers/media/usb/em28xx/Kconfig | 6 | ||||
-rw-r--r-- | drivers/media/usb/em28xx/Makefile | 5 | ||||
-rw-r--r-- | drivers/media/usb/em28xx/em28xx-camera.c | 1 | ||||
-rw-r--r-- | drivers/media/usb/em28xx/em28xx-cards.c | 32 | ||||
-rw-r--r-- | drivers/media/usb/em28xx/em28xx-core.c | 12 | ||||
-rw-r--r-- | drivers/media/usb/em28xx/em28xx-v4l.h | 20 | ||||
-rw-r--r-- | drivers/media/usb/em28xx/em28xx-vbi.c | 1 | ||||
-rw-r--r-- | drivers/media/usb/em28xx/em28xx-video.c | 71 | ||||
-rw-r--r-- | drivers/media/usb/em28xx/em28xx.h | 23 |
9 files changed, 102 insertions, 69 deletions
diff --git a/drivers/media/usb/em28xx/Kconfig b/drivers/media/usb/em28xx/Kconfig index d6ba514d31eb..a1fccf3096de 100644 --- a/drivers/media/usb/em28xx/Kconfig +++ b/drivers/media/usb/em28xx/Kconfig | |||
@@ -1,8 +1,12 @@ | |||
1 | config VIDEO_EM28XX | 1 | config VIDEO_EM28XX |
2 | tristate "Empia EM28xx USB video capture support" | 2 | tristate "Empia EM28xx USB devices support" |
3 | depends on VIDEO_DEV && I2C | 3 | depends on VIDEO_DEV && I2C |
4 | select VIDEO_TUNER | 4 | select VIDEO_TUNER |
5 | select VIDEO_TVEEPROM | 5 | select VIDEO_TVEEPROM |
6 | |||
7 | config VIDEO_EM28XX_V4L2 | ||
8 | tristate "Empia EM28xx analog TV, video capture and/or webcam support" | ||
9 | depends on VIDEO_EM28XX | ||
6 | select VIDEOBUF2_VMALLOC | 10 | select VIDEOBUF2_VMALLOC |
7 | select VIDEO_SAA711X if MEDIA_SUBDRV_AUTOSELECT | 11 | select VIDEO_SAA711X if MEDIA_SUBDRV_AUTOSELECT |
8 | select VIDEO_TVP5150 if MEDIA_SUBDRV_AUTOSELECT | 12 | select VIDEO_TVP5150 if MEDIA_SUBDRV_AUTOSELECT |
diff --git a/drivers/media/usb/em28xx/Makefile b/drivers/media/usb/em28xx/Makefile index ad6d48557940..3f850d5063d0 100644 --- a/drivers/media/usb/em28xx/Makefile +++ b/drivers/media/usb/em28xx/Makefile | |||
@@ -1,10 +1,11 @@ | |||
1 | em28xx-y += em28xx-video.o em28xx-i2c.o em28xx-cards.o | 1 | em28xx-y += em28xx-core.o em28xx-i2c.o em28xx-cards.o em28xx-camera.o |
2 | em28xx-y += em28xx-core.o em28xx-vbi.o em28xx-camera.o | ||
3 | 2 | ||
3 | em28xx-v4l-objs := em28xx-video.o em28xx-vbi.o | ||
4 | em28xx-alsa-objs := em28xx-audio.o | 4 | em28xx-alsa-objs := em28xx-audio.o |
5 | em28xx-rc-objs := em28xx-input.o | 5 | em28xx-rc-objs := em28xx-input.o |
6 | 6 | ||
7 | obj-$(CONFIG_VIDEO_EM28XX) += em28xx.o | 7 | obj-$(CONFIG_VIDEO_EM28XX) += em28xx.o |
8 | obj-$(CONFIG_VIDEO_EM28XX_V4L2) += em28xx-v4l.o | ||
8 | obj-$(CONFIG_VIDEO_EM28XX_ALSA) += em28xx-alsa.o | 9 | obj-$(CONFIG_VIDEO_EM28XX_ALSA) += em28xx-alsa.o |
9 | obj-$(CONFIG_VIDEO_EM28XX_DVB) += em28xx-dvb.o | 10 | obj-$(CONFIG_VIDEO_EM28XX_DVB) += em28xx-dvb.o |
10 | obj-$(CONFIG_VIDEO_EM28XX_RC) += em28xx-rc.o | 11 | obj-$(CONFIG_VIDEO_EM28XX_RC) += em28xx-rc.o |
diff --git a/drivers/media/usb/em28xx/em28xx-camera.c b/drivers/media/usb/em28xx/em28xx-camera.c index d666741797d4..c29f5c4e7b40 100644 --- a/drivers/media/usb/em28xx/em28xx-camera.c +++ b/drivers/media/usb/em28xx/em28xx-camera.c | |||
@@ -454,3 +454,4 @@ int em28xx_init_camera(struct em28xx *dev) | |||
454 | 454 | ||
455 | return ret; | 455 | return ret; |
456 | } | 456 | } |
457 | EXPORT_SYMBOL_GPL(em28xx_init_camera); | ||
diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c index dbce4dc421f9..b25869331284 100644 --- a/drivers/media/usb/em28xx/em28xx-cards.c +++ b/drivers/media/usb/em28xx/em28xx-cards.c | |||
@@ -2159,6 +2159,8 @@ struct em28xx_board em28xx_boards[] = { | |||
2159 | .ir_codes = RC_MAP_PINNACLE_PCTV_HD, | 2159 | .ir_codes = RC_MAP_PINNACLE_PCTV_HD, |
2160 | }, | 2160 | }, |
2161 | }; | 2161 | }; |
2162 | EXPORT_SYMBOL_GPL(em28xx_boards); | ||
2163 | |||
2162 | const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards); | 2164 | const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards); |
2163 | 2165 | ||
2164 | /* table of devices that work with this driver */ | 2166 | /* table of devices that work with this driver */ |
@@ -2780,11 +2782,12 @@ static void request_module_async(struct work_struct *work) | |||
2780 | em28xx_init_extension(dev); | 2782 | em28xx_init_extension(dev); |
2781 | 2783 | ||
2782 | #if defined(CONFIG_MODULES) && defined(MODULE) | 2784 | #if defined(CONFIG_MODULES) && defined(MODULE) |
2785 | if (dev->has_video) | ||
2786 | request_module("em28xx-v4l"); | ||
2783 | if (dev->has_audio_class) | 2787 | if (dev->has_audio_class) |
2784 | request_module("snd-usb-audio"); | 2788 | request_module("snd-usb-audio"); |
2785 | else if (dev->has_alsa_audio) | 2789 | else if (dev->has_alsa_audio) |
2786 | request_module("em28xx-alsa"); | 2790 | request_module("em28xx-alsa"); |
2787 | |||
2788 | if (dev->board.has_dvb) | 2791 | if (dev->board.has_dvb) |
2789 | request_module("em28xx-dvb"); | 2792 | request_module("em28xx-dvb"); |
2790 | if (dev->board.buttons || | 2793 | if (dev->board.buttons || |
@@ -2813,18 +2816,12 @@ void em28xx_release_resources(struct em28xx *dev) | |||
2813 | { | 2816 | { |
2814 | /*FIXME: I2C IR should be disconnected */ | 2817 | /*FIXME: I2C IR should be disconnected */ |
2815 | 2818 | ||
2816 | em28xx_release_analog_resources(dev); | ||
2817 | |||
2818 | if (dev->def_i2c_bus) | 2819 | if (dev->def_i2c_bus) |
2819 | em28xx_i2c_unregister(dev, 1); | 2820 | em28xx_i2c_unregister(dev, 1); |
2820 | em28xx_i2c_unregister(dev, 0); | 2821 | em28xx_i2c_unregister(dev, 0); |
2821 | if (dev->clk) | 2822 | if (dev->clk) |
2822 | v4l2_clk_unregister_fixed(dev->clk); | 2823 | v4l2_clk_unregister_fixed(dev->clk); |
2823 | 2824 | ||
2824 | v4l2_ctrl_handler_free(&dev->ctrl_handler); | ||
2825 | |||
2826 | v4l2_device_unregister(&dev->v4l2_dev); | ||
2827 | |||
2828 | usb_put_dev(dev->udev); | 2825 | usb_put_dev(dev->udev); |
2829 | 2826 | ||
2830 | /* Mark device as unused */ | 2827 | /* Mark device as unused */ |
@@ -2999,18 +2996,7 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev, | |||
2999 | /* Do board specific init and eeprom reading */ | 2996 | /* Do board specific init and eeprom reading */ |
3000 | em28xx_card_setup(dev); | 2997 | em28xx_card_setup(dev); |
3001 | 2998 | ||
3002 | retval = em28xx_register_analog_devices(dev); | ||
3003 | if (retval < 0) | ||
3004 | goto fail; | ||
3005 | |||
3006 | return 0; | 2999 | return 0; |
3007 | |||
3008 | fail: | ||
3009 | if (dev->def_i2c_bus) | ||
3010 | em28xx_i2c_unregister(dev, 1); | ||
3011 | em28xx_i2c_unregister(dev, 0); | ||
3012 | |||
3013 | return retval; | ||
3014 | } | 3000 | } |
3015 | 3001 | ||
3016 | /* high bandwidth multiplier, as encoded in highspeed endpoint descriptors */ | 3002 | /* high bandwidth multiplier, as encoded in highspeed endpoint descriptors */ |
@@ -3213,6 +3199,7 @@ static int em28xx_usb_probe(struct usb_interface *interface, | |||
3213 | dev->alt = -1; | 3199 | dev->alt = -1; |
3214 | dev->is_audio_only = has_audio && !(has_video || has_dvb); | 3200 | dev->is_audio_only = has_audio && !(has_video || has_dvb); |
3215 | dev->has_alsa_audio = has_audio; | 3201 | dev->has_alsa_audio = has_audio; |
3202 | dev->has_video = has_video; | ||
3216 | dev->audio_ifnum = ifnum; | 3203 | dev->audio_ifnum = ifnum; |
3217 | 3204 | ||
3218 | /* Checks if audio is provided by some interface */ | 3205 | /* Checks if audio is provided by some interface */ |
@@ -3252,10 +3239,9 @@ static int em28xx_usb_probe(struct usb_interface *interface, | |||
3252 | 3239 | ||
3253 | /* allocate device struct */ | 3240 | /* allocate device struct */ |
3254 | mutex_init(&dev->lock); | 3241 | mutex_init(&dev->lock); |
3255 | mutex_lock(&dev->lock); | ||
3256 | retval = em28xx_init_dev(dev, udev, interface, nr); | 3242 | retval = em28xx_init_dev(dev, udev, interface, nr); |
3257 | if (retval) { | 3243 | if (retval) { |
3258 | goto unlock_and_free; | 3244 | goto err_free; |
3259 | } | 3245 | } |
3260 | 3246 | ||
3261 | if (usb_xfer_mode < 0) { | 3247 | if (usb_xfer_mode < 0) { |
@@ -3298,7 +3284,7 @@ static int em28xx_usb_probe(struct usb_interface *interface, | |||
3298 | if (retval) { | 3284 | if (retval) { |
3299 | printk(DRIVER_NAME | 3285 | printk(DRIVER_NAME |
3300 | ": Failed to pre-allocate USB transfer buffers for DVB.\n"); | 3286 | ": Failed to pre-allocate USB transfer buffers for DVB.\n"); |
3301 | goto unlock_and_free; | 3287 | goto err_free; |
3302 | } | 3288 | } |
3303 | } | 3289 | } |
3304 | 3290 | ||
@@ -3307,13 +3293,9 @@ static int em28xx_usb_probe(struct usb_interface *interface, | |||
3307 | /* Should be the last thing to do, to avoid newer udev's to | 3293 | /* Should be the last thing to do, to avoid newer udev's to |
3308 | open the device before fully initializing it | 3294 | open the device before fully initializing it |
3309 | */ | 3295 | */ |
3310 | mutex_unlock(&dev->lock); | ||
3311 | 3296 | ||
3312 | return 0; | 3297 | return 0; |
3313 | 3298 | ||
3314 | unlock_and_free: | ||
3315 | mutex_unlock(&dev->lock); | ||
3316 | |||
3317 | err_free: | 3299 | err_free: |
3318 | kfree(dev->alt_max_pkt_size_isoc); | 3300 | kfree(dev->alt_max_pkt_size_isoc); |
3319 | kfree(dev); | 3301 | kfree(dev); |
diff --git a/drivers/media/usb/em28xx/em28xx-core.c b/drivers/media/usb/em28xx/em28xx-core.c index f77301773aee..c416dd33af3f 100644 --- a/drivers/media/usb/em28xx/em28xx-core.c +++ b/drivers/media/usb/em28xx/em28xx-core.c | |||
@@ -33,6 +33,18 @@ | |||
33 | 33 | ||
34 | #include "em28xx.h" | 34 | #include "em28xx.h" |
35 | 35 | ||
36 | #define DRIVER_AUTHOR "Ludovico Cavedon <cavedon@sssup.it>, " \ | ||
37 | "Markus Rechberger <mrechberger@gmail.com>, " \ | ||
38 | "Mauro Carvalho Chehab <mchehab@infradead.org>, " \ | ||
39 | "Sascha Sommer <saschasommer@freenet.de>" | ||
40 | |||
41 | #define DRIVER_DESC "Empia em28xx based USB core driver" | ||
42 | |||
43 | MODULE_AUTHOR(DRIVER_AUTHOR); | ||
44 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
45 | MODULE_LICENSE("GPL"); | ||
46 | MODULE_VERSION(EM28XX_VERSION); | ||
47 | |||
36 | /* #define ENABLE_DEBUG_ISOC_FRAMES */ | 48 | /* #define ENABLE_DEBUG_ISOC_FRAMES */ |
37 | 49 | ||
38 | static unsigned int core_debug; | 50 | static unsigned int core_debug; |
diff --git a/drivers/media/usb/em28xx/em28xx-v4l.h b/drivers/media/usb/em28xx/em28xx-v4l.h new file mode 100644 index 000000000000..bce438691e0e --- /dev/null +++ b/drivers/media/usb/em28xx/em28xx-v4l.h | |||
@@ -0,0 +1,20 @@ | |||
1 | /* | ||
2 | em28xx-video.c - driver for Empia EM2800/EM2820/2840 USB | ||
3 | video capture devices | ||
4 | |||
5 | Copyright (C) 2013-2014 Mauro Carvalho Chehab <m.chehab@samsung.com> | ||
6 | |||
7 | This program is free software; you can redistribute it and/or modify | ||
8 | it under the terms of the GNU General Public License as published by | ||
9 | the Free Software Foundation version 2 of the License. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | */ | ||
16 | |||
17 | |||
18 | int em28xx_start_analog_streaming(struct vb2_queue *vq, unsigned int count); | ||
19 | int em28xx_stop_vbi_streaming(struct vb2_queue *vq); | ||
20 | extern struct vb2_ops em28xx_vbi_qops; | ||
diff --git a/drivers/media/usb/em28xx/em28xx-vbi.c b/drivers/media/usb/em28xx/em28xx-vbi.c index 39f39c527c13..db3d655600df 100644 --- a/drivers/media/usb/em28xx/em28xx-vbi.c +++ b/drivers/media/usb/em28xx/em28xx-vbi.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/init.h> | 27 | #include <linux/init.h> |
28 | 28 | ||
29 | #include "em28xx.h" | 29 | #include "em28xx.h" |
30 | #include "em28xx-v4l.h" | ||
30 | 31 | ||
31 | static unsigned int vbibufs = 5; | 32 | static unsigned int vbibufs = 5; |
32 | module_param(vbibufs, int, 0644); | 33 | module_param(vbibufs, int, 0644); |
diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index 3726af134f39..7d11a16e72b5 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
39 | 39 | ||
40 | #include "em28xx.h" | 40 | #include "em28xx.h" |
41 | #include "em28xx-v4l.h" | ||
41 | #include <media/v4l2-common.h> | 42 | #include <media/v4l2-common.h> |
42 | #include <media/v4l2-ioctl.h> | 43 | #include <media/v4l2-ioctl.h> |
43 | #include <media/v4l2-event.h> | 44 | #include <media/v4l2-event.h> |
@@ -141,7 +142,7 @@ static struct em28xx_fmt format[] = { | |||
141 | }, | 142 | }, |
142 | }; | 143 | }; |
143 | 144 | ||
144 | int em28xx_vbi_supported(struct em28xx *dev) | 145 | static int em28xx_vbi_supported(struct em28xx *dev) |
145 | { | 146 | { |
146 | /* Modprobe option to manually disable */ | 147 | /* Modprobe option to manually disable */ |
147 | if (disable_vbi == 1) | 148 | if (disable_vbi == 1) |
@@ -164,7 +165,7 @@ int em28xx_vbi_supported(struct em28xx *dev) | |||
164 | * em28xx_wake_i2c() | 165 | * em28xx_wake_i2c() |
165 | * configure i2c attached devices | 166 | * configure i2c attached devices |
166 | */ | 167 | */ |
167 | void em28xx_wake_i2c(struct em28xx *dev) | 168 | static void em28xx_wake_i2c(struct em28xx *dev) |
168 | { | 169 | { |
169 | v4l2_device_call_all(&dev->v4l2_dev, 0, core, reset, 0); | 170 | v4l2_device_call_all(&dev->v4l2_dev, 0, core, reset, 0); |
170 | v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_routing, | 171 | v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_routing, |
@@ -172,7 +173,7 @@ void em28xx_wake_i2c(struct em28xx *dev) | |||
172 | v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 0); | 173 | v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 0); |
173 | } | 174 | } |
174 | 175 | ||
175 | int em28xx_colorlevels_set_default(struct em28xx *dev) | 176 | static int em28xx_colorlevels_set_default(struct em28xx *dev) |
176 | { | 177 | { |
177 | em28xx_write_reg(dev, EM28XX_R20_YGAIN, CONTRAST_DEFAULT); | 178 | em28xx_write_reg(dev, EM28XX_R20_YGAIN, CONTRAST_DEFAULT); |
178 | em28xx_write_reg(dev, EM28XX_R21_YOFFSET, BRIGHTNESS_DEFAULT); | 179 | em28xx_write_reg(dev, EM28XX_R21_YOFFSET, BRIGHTNESS_DEFAULT); |
@@ -190,7 +191,7 @@ int em28xx_colorlevels_set_default(struct em28xx *dev) | |||
190 | return em28xx_write_reg(dev, EM28XX_R1A_BOFFSET, 0x00); | 191 | return em28xx_write_reg(dev, EM28XX_R1A_BOFFSET, 0x00); |
191 | } | 192 | } |
192 | 193 | ||
193 | int em28xx_set_outfmt(struct em28xx *dev) | 194 | static int em28xx_set_outfmt(struct em28xx *dev) |
194 | { | 195 | { |
195 | int ret; | 196 | int ret; |
196 | u8 fmt, vinctrl; | 197 | u8 fmt, vinctrl; |
@@ -297,7 +298,7 @@ static int em28xx_scaler_set(struct em28xx *dev, u16 h, u16 v) | |||
297 | } | 298 | } |
298 | 299 | ||
299 | /* FIXME: this only function read values from dev */ | 300 | /* FIXME: this only function read values from dev */ |
300 | int em28xx_resolution_set(struct em28xx *dev) | 301 | static int em28xx_resolution_set(struct em28xx *dev) |
301 | { | 302 | { |
302 | int width, height; | 303 | int width, height; |
303 | width = norm_maxw(dev); | 304 | width = norm_maxw(dev); |
@@ -330,7 +331,7 @@ int em28xx_resolution_set(struct em28xx *dev) | |||
330 | } | 331 | } |
331 | 332 | ||
332 | /* Set USB alternate setting for analog video */ | 333 | /* Set USB alternate setting for analog video */ |
333 | int em28xx_set_alternate(struct em28xx *dev) | 334 | static int em28xx_set_alternate(struct em28xx *dev) |
334 | { | 335 | { |
335 | int errCode; | 336 | int errCode; |
336 | int i; | 337 | int i; |
@@ -1020,7 +1021,7 @@ static struct vb2_ops em28xx_video_qops = { | |||
1020 | .wait_finish = vb2_ops_wait_finish, | 1021 | .wait_finish = vb2_ops_wait_finish, |
1021 | }; | 1022 | }; |
1022 | 1023 | ||
1023 | int em28xx_vb2_setup(struct em28xx *dev) | 1024 | static int em28xx_vb2_setup(struct em28xx *dev) |
1024 | { | 1025 | { |
1025 | int rc; | 1026 | int rc; |
1026 | struct vb2_queue *q; | 1027 | struct vb2_queue *q; |
@@ -1088,7 +1089,7 @@ static void video_mux(struct em28xx *dev, int index) | |||
1088 | em28xx_audio_analog_set(dev); | 1089 | em28xx_audio_analog_set(dev); |
1089 | } | 1090 | } |
1090 | 1091 | ||
1091 | void em28xx_ctrl_notify(struct v4l2_ctrl *ctrl, void *priv) | 1092 | static void em28xx_ctrl_notify(struct v4l2_ctrl *ctrl, void *priv) |
1092 | { | 1093 | { |
1093 | struct em28xx *dev = priv; | 1094 | struct em28xx *dev = priv; |
1094 | 1095 | ||
@@ -1625,7 +1626,7 @@ static int vidioc_g_register(struct file *file, void *priv, | |||
1625 | reg->val = ret; | 1626 | reg->val = ret; |
1626 | } else { | 1627 | } else { |
1627 | __le16 val = 0; | 1628 | __le16 val = 0; |
1628 | ret = em28xx_read_reg_req_len(dev, USB_REQ_GET_STATUS, | 1629 | ret = dev->em28xx_read_reg_req_len(dev, USB_REQ_GET_STATUS, |
1629 | reg->reg, (char *)&val, 2); | 1630 | reg->reg, (char *)&val, 2); |
1630 | if (ret < 0) | 1631 | if (ret < 0) |
1631 | return ret; | 1632 | return ret; |
@@ -1872,14 +1873,16 @@ static int em28xx_v4l2_open(struct file *filp) | |||
1872 | } | 1873 | } |
1873 | 1874 | ||
1874 | /* | 1875 | /* |
1875 | * em28xx_realease_resources() | 1876 | * em28xx_v4l2_fini() |
1876 | * unregisters the v4l2,i2c and usb devices | 1877 | * unregisters the v4l2,i2c and usb devices |
1877 | * called when the device gets disconected or at module unload | 1878 | * called when the device gets disconected or at module unload |
1878 | */ | 1879 | */ |
1879 | void em28xx_release_analog_resources(struct em28xx *dev) | 1880 | static int em28xx_v4l2_fini(struct em28xx *dev) |
1880 | { | 1881 | { |
1881 | 1882 | if (!dev->has_video) { | |
1882 | /*FIXME: I2C IR should be disconnected */ | 1883 | /* This device does not support the v4l2 extension */ |
1884 | return 0; | ||
1885 | } | ||
1883 | 1886 | ||
1884 | if (dev->radio_dev) { | 1887 | if (dev->radio_dev) { |
1885 | if (video_is_registered(dev->radio_dev)) | 1888 | if (video_is_registered(dev->radio_dev)) |
@@ -1906,6 +1909,8 @@ void em28xx_release_analog_resources(struct em28xx *dev) | |||
1906 | video_device_release(dev->vdev); | 1909 | video_device_release(dev->vdev); |
1907 | dev->vdev = NULL; | 1910 | dev->vdev = NULL; |
1908 | } | 1911 | } |
1912 | |||
1913 | return 0; | ||
1909 | } | 1914 | } |
1910 | 1915 | ||
1911 | /* | 1916 | /* |
@@ -1927,12 +1932,13 @@ static int em28xx_v4l2_close(struct file *filp) | |||
1927 | if (dev->users == 1) { | 1932 | if (dev->users == 1) { |
1928 | /* the device is already disconnect, | 1933 | /* the device is already disconnect, |
1929 | free the remaining resources */ | 1934 | free the remaining resources */ |
1935 | |||
1930 | if (dev->disconnected) { | 1936 | if (dev->disconnected) { |
1931 | em28xx_release_resources(dev); | 1937 | em28xx_release_resources(dev); |
1938 | v4l2_ctrl_handler_free(&dev->ctrl_handler); | ||
1939 | v4l2_device_unregister(&dev->v4l2_dev); | ||
1932 | kfree(dev->alt_max_pkt_size_isoc); | 1940 | kfree(dev->alt_max_pkt_size_isoc); |
1933 | mutex_unlock(&dev->lock); | 1941 | goto exit; |
1934 | kfree(dev); | ||
1935 | return 0; | ||
1936 | } | 1942 | } |
1937 | 1943 | ||
1938 | /* Save some power by putting tuner to sleep */ | 1944 | /* Save some power by putting tuner to sleep */ |
@@ -1951,6 +1957,7 @@ static int em28xx_v4l2_close(struct file *filp) | |||
1951 | } | 1957 | } |
1952 | } | 1958 | } |
1953 | 1959 | ||
1960 | exit: | ||
1954 | dev->users--; | 1961 | dev->users--; |
1955 | mutex_unlock(&dev->lock); | 1962 | mutex_unlock(&dev->lock); |
1956 | return 0; | 1963 | return 0; |
@@ -2065,8 +2072,6 @@ static unsigned short msp3400_addrs[] = { | |||
2065 | 2072 | ||
2066 | /******************************** usb interface ******************************/ | 2073 | /******************************** usb interface ******************************/ |
2067 | 2074 | ||
2068 | |||
2069 | |||
2070 | static struct video_device *em28xx_vdev_init(struct em28xx *dev, | 2075 | static struct video_device *em28xx_vdev_init(struct em28xx *dev, |
2071 | const struct video_device *template, | 2076 | const struct video_device *template, |
2072 | const char *type_name) | 2077 | const char *type_name) |
@@ -2140,7 +2145,7 @@ static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl) | |||
2140 | } | 2145 | } |
2141 | } | 2146 | } |
2142 | 2147 | ||
2143 | void em28xx_tuner_setup(struct em28xx *dev) | 2148 | static void em28xx_tuner_setup(struct em28xx *dev) |
2144 | { | 2149 | { |
2145 | struct tuner_setup tun_setup; | 2150 | struct tuner_setup tun_setup; |
2146 | struct v4l2_frequency f; | 2151 | struct v4l2_frequency f; |
@@ -2199,14 +2204,14 @@ void em28xx_tuner_setup(struct em28xx *dev) | |||
2199 | v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, &f); | 2204 | v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, &f); |
2200 | } | 2205 | } |
2201 | 2206 | ||
2202 | int em28xx_register_analog_devices(struct em28xx *dev) | 2207 | static int em28xx_v4l2_init(struct em28xx *dev) |
2203 | { | 2208 | { |
2204 | u8 val; | 2209 | u8 val; |
2205 | int ret; | 2210 | int ret; |
2206 | unsigned int maxw; | 2211 | unsigned int maxw; |
2207 | struct v4l2_ctrl_handler *hdl = &dev->ctrl_handler; | 2212 | struct v4l2_ctrl_handler *hdl = &dev->ctrl_handler; |
2208 | 2213 | ||
2209 | if (dev->is_audio_only) { | 2214 | if (!dev->has_video) { |
2210 | /* This device does not support the v4l2 extension */ | 2215 | /* This device does not support the v4l2 extension */ |
2211 | return 0; | 2216 | return 0; |
2212 | } | 2217 | } |
@@ -2214,6 +2219,8 @@ int em28xx_register_analog_devices(struct em28xx *dev) | |||
2214 | printk(KERN_INFO "%s: v4l2 driver version %s\n", | 2219 | printk(KERN_INFO "%s: v4l2 driver version %s\n", |
2215 | dev->name, EM28XX_VERSION); | 2220 | dev->name, EM28XX_VERSION); |
2216 | 2221 | ||
2222 | mutex_lock(&dev->lock); | ||
2223 | |||
2217 | ret = v4l2_device_register(&dev->udev->dev, &dev->v4l2_dev); | 2224 | ret = v4l2_device_register(&dev->udev->dev, &dev->v4l2_dev); |
2218 | if (ret < 0) { | 2225 | if (ret < 0) { |
2219 | em28xx_errdev("Call to v4l2_device_register() failed!\n"); | 2226 | em28xx_errdev("Call to v4l2_device_register() failed!\n"); |
@@ -2492,11 +2499,33 @@ int em28xx_register_analog_devices(struct em28xx *dev) | |||
2492 | /* initialize videobuf2 stuff */ | 2499 | /* initialize videobuf2 stuff */ |
2493 | em28xx_vb2_setup(dev); | 2500 | em28xx_vb2_setup(dev); |
2494 | 2501 | ||
2502 | mutex_unlock(&dev->lock); | ||
2495 | return 0; | 2503 | return 0; |
2496 | 2504 | ||
2497 | unregister_dev: | 2505 | unregister_dev: |
2498 | v4l2_ctrl_handler_free(&dev->ctrl_handler); | 2506 | v4l2_ctrl_handler_free(&dev->ctrl_handler); |
2499 | v4l2_device_unregister(&dev->v4l2_dev); | 2507 | v4l2_device_unregister(&dev->v4l2_dev); |
2500 | err: | 2508 | err: |
2509 | mutex_unlock(&dev->lock); | ||
2501 | return ret; | 2510 | return ret; |
2502 | } | 2511 | } |
2512 | |||
2513 | static struct em28xx_ops v4l2_ops = { | ||
2514 | .id = EM28XX_V4L2, | ||
2515 | .name = "Em28xx v4l2 Extension", | ||
2516 | .init = em28xx_v4l2_init, | ||
2517 | .fini = em28xx_v4l2_fini, | ||
2518 | }; | ||
2519 | |||
2520 | static int __init em28xx_video_register(void) | ||
2521 | { | ||
2522 | return em28xx_register_extension(&v4l2_ops); | ||
2523 | } | ||
2524 | |||
2525 | static void __exit em28xx_video_unregister(void) | ||
2526 | { | ||
2527 | em28xx_unregister_extension(&v4l2_ops); | ||
2528 | } | ||
2529 | |||
2530 | module_init(em28xx_video_register); | ||
2531 | module_exit(em28xx_video_unregister); | ||
diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h index 7ae05ebc13c1..9d6f43e4681f 100644 --- a/drivers/media/usb/em28xx/em28xx.h +++ b/drivers/media/usb/em28xx/em28xx.h | |||
@@ -26,7 +26,7 @@ | |||
26 | #ifndef _EM28XX_H | 26 | #ifndef _EM28XX_H |
27 | #define _EM28XX_H | 27 | #define _EM28XX_H |
28 | 28 | ||
29 | #define EM28XX_VERSION "0.2.0" | 29 | #define EM28XX_VERSION "0.2.1" |
30 | 30 | ||
31 | #include <linux/workqueue.h> | 31 | #include <linux/workqueue.h> |
32 | #include <linux/i2c.h> | 32 | #include <linux/i2c.h> |
@@ -474,6 +474,7 @@ struct em28xx_eeprom { | |||
474 | #define EM28XX_AUDIO 0x10 | 474 | #define EM28XX_AUDIO 0x10 |
475 | #define EM28XX_DVB 0x20 | 475 | #define EM28XX_DVB 0x20 |
476 | #define EM28XX_RC 0x30 | 476 | #define EM28XX_RC 0x30 |
477 | #define EM28XX_V4L2 0x40 | ||
477 | 478 | ||
478 | /* em28xx resource types (used for res_get/res_lock etc */ | 479 | /* em28xx resource types (used for res_get/res_lock etc */ |
479 | #define EM28XX_RESOURCE_VIDEO 0x01 | 480 | #define EM28XX_RESOURCE_VIDEO 0x01 |
@@ -527,6 +528,7 @@ struct em28xx { | |||
527 | 528 | ||
528 | unsigned int is_em25xx:1; /* em25xx/em276x/7x/8x family bridge */ | 529 | unsigned int is_em25xx:1; /* em25xx/em276x/7x/8x family bridge */ |
529 | unsigned char disconnected:1; /* device has been diconnected */ | 530 | unsigned char disconnected:1; /* device has been diconnected */ |
531 | unsigned int has_video:1; | ||
530 | unsigned int has_audio_class:1; | 532 | unsigned int has_audio_class:1; |
531 | unsigned int has_alsa_audio:1; | 533 | unsigned int has_alsa_audio:1; |
532 | unsigned int is_audio_only:1; | 534 | unsigned int is_audio_only:1; |
@@ -723,14 +725,9 @@ int em28xx_write_ac97(struct em28xx *dev, u8 reg, u16 val); | |||
723 | int em28xx_audio_analog_set(struct em28xx *dev); | 725 | int em28xx_audio_analog_set(struct em28xx *dev); |
724 | int em28xx_audio_setup(struct em28xx *dev); | 726 | int em28xx_audio_setup(struct em28xx *dev); |
725 | 727 | ||
726 | int em28xx_colorlevels_set_default(struct em28xx *dev); | ||
727 | const struct em28xx_led *em28xx_find_led(struct em28xx *dev, | 728 | const struct em28xx_led *em28xx_find_led(struct em28xx *dev, |
728 | enum em28xx_led_role role); | 729 | enum em28xx_led_role role); |
729 | int em28xx_capture_start(struct em28xx *dev, int start); | 730 | int em28xx_capture_start(struct em28xx *dev, int start); |
730 | int em28xx_vbi_supported(struct em28xx *dev); | ||
731 | int em28xx_set_outfmt(struct em28xx *dev); | ||
732 | int em28xx_resolution_set(struct em28xx *dev); | ||
733 | int em28xx_set_alternate(struct em28xx *dev); | ||
734 | int em28xx_alloc_urbs(struct em28xx *dev, enum em28xx_mode mode, int xfer_bulk, | 731 | int em28xx_alloc_urbs(struct em28xx *dev, enum em28xx_mode mode, int xfer_bulk, |
735 | int num_bufs, int max_pkt_size, int packet_multiplier); | 732 | int num_bufs, int max_pkt_size, int packet_multiplier); |
736 | int em28xx_init_usb_xfer(struct em28xx *dev, enum em28xx_mode mode, | 733 | int em28xx_init_usb_xfer(struct em28xx *dev, enum em28xx_mode mode, |
@@ -742,31 +739,17 @@ void em28xx_uninit_usb_xfer(struct em28xx *dev, enum em28xx_mode mode); | |||
742 | void em28xx_stop_urbs(struct em28xx *dev); | 739 | void em28xx_stop_urbs(struct em28xx *dev); |
743 | int em28xx_set_mode(struct em28xx *dev, enum em28xx_mode set_mode); | 740 | int em28xx_set_mode(struct em28xx *dev, enum em28xx_mode set_mode); |
744 | int em28xx_gpio_set(struct em28xx *dev, struct em28xx_reg_seq *gpio); | 741 | int em28xx_gpio_set(struct em28xx *dev, struct em28xx_reg_seq *gpio); |
745 | void em28xx_wake_i2c(struct em28xx *dev); | ||
746 | int em28xx_register_extension(struct em28xx_ops *dev); | 742 | int em28xx_register_extension(struct em28xx_ops *dev); |
747 | void em28xx_unregister_extension(struct em28xx_ops *dev); | 743 | void em28xx_unregister_extension(struct em28xx_ops *dev); |
748 | void em28xx_init_extension(struct em28xx *dev); | 744 | void em28xx_init_extension(struct em28xx *dev); |
749 | void em28xx_close_extension(struct em28xx *dev); | 745 | void em28xx_close_extension(struct em28xx *dev); |
750 | 746 | ||
751 | /* Provided by em28xx-video.c */ | ||
752 | void em28xx_tuner_setup(struct em28xx *dev); | ||
753 | int em28xx_vb2_setup(struct em28xx *dev); | ||
754 | int em28xx_register_analog_devices(struct em28xx *dev); | ||
755 | void em28xx_release_analog_resources(struct em28xx *dev); | ||
756 | void em28xx_ctrl_notify(struct v4l2_ctrl *ctrl, void *priv); | ||
757 | int em28xx_start_analog_streaming(struct vb2_queue *vq, unsigned int count); | ||
758 | int em28xx_stop_vbi_streaming(struct vb2_queue *vq); | ||
759 | extern const struct v4l2_ctrl_ops em28xx_ctrl_ops; | ||
760 | |||
761 | /* Provided by em28xx-cards.c */ | 747 | /* Provided by em28xx-cards.c */ |
762 | extern struct em28xx_board em28xx_boards[]; | 748 | extern struct em28xx_board em28xx_boards[]; |
763 | extern struct usb_device_id em28xx_id_table[]; | 749 | extern struct usb_device_id em28xx_id_table[]; |
764 | int em28xx_tuner_callback(void *ptr, int component, int command, int arg); | 750 | int em28xx_tuner_callback(void *ptr, int component, int command, int arg); |
765 | void em28xx_release_resources(struct em28xx *dev); | 751 | void em28xx_release_resources(struct em28xx *dev); |
766 | 752 | ||
767 | /* Provided by em28xx-vbi.c */ | ||
768 | extern struct vb2_ops em28xx_vbi_qops; | ||
769 | |||
770 | /* Provided by em28xx-camera.c */ | 753 | /* Provided by em28xx-camera.c */ |
771 | int em28xx_detect_sensor(struct em28xx *dev); | 754 | int em28xx_detect_sensor(struct em28xx *dev); |
772 | int em28xx_init_camera(struct em28xx *dev); | 755 | int em28xx_init_camera(struct em28xx *dev); |