diff options
-rw-r--r-- | Documentation/usb/zc0301.txt | 29 | ||||
-rw-r--r-- | drivers/usb/media/zc0301.h | 20 | ||||
-rw-r--r-- | drivers/usb/media/zc0301_core.c | 58 | ||||
-rw-r--r-- | drivers/usb/media/zc0301_pas202bcb.c | 38 | ||||
-rw-r--r-- | drivers/usb/media/zc0301_sensor.h | 25 |
5 files changed, 108 insertions, 62 deletions
diff --git a/Documentation/usb/zc0301.txt b/Documentation/usb/zc0301.txt index 0889ae6ac7d8..095838420e82 100644 --- a/Documentation/usb/zc0301.txt +++ b/Documentation/usb/zc0301.txt | |||
@@ -68,11 +68,6 @@ Some of the features of the driver are: | |||
68 | data transfers; | 68 | data transfers; |
69 | - automatic detection of image sensor; | 69 | - automatic detection of image sensor; |
70 | - video format is standard JPEG; | 70 | - video format is standard JPEG; |
71 | - full support for the capabilities of every possible image sensors that can | ||
72 | be connected to the ZC0301 bridges, including, for istance, red, green, | ||
73 | blue and global gain adjustments and exposure control (see "Supported | ||
74 | devices" paragraph for details); | ||
75 | - use of default color settings for sunlight conditions; | ||
76 | - dynamic driver control thanks to various module parameters (see "Module | 71 | - dynamic driver control thanks to various module parameters (see "Module |
77 | parameters" paragraph); | 72 | parameters" paragraph); |
78 | - up to 64 cameras can be handled at the same time; they can be connected and | 73 | - up to 64 cameras can be handled at the same time; they can be connected and |
@@ -171,6 +166,14 @@ Description: Force the application to unmap previously mapped buffer memory | |||
171 | 1 = force memory unmapping (save memory) | 166 | 1 = force memory unmapping (save memory) |
172 | Default: 0 | 167 | Default: 0 |
173 | ------------------------------------------------------------------------------- | 168 | ------------------------------------------------------------------------------- |
169 | Name: frame_timeout | ||
170 | Type: uint array (min = 0, max = 64) | ||
171 | Syntax: <n[,...]> | ||
172 | Description: Timeout for a video frame in seconds. This parameter is | ||
173 | specific for each detected camera. This parameter can be | ||
174 | changed at runtime thanks to the /sys filesystem interface. | ||
175 | Default: 2 | ||
176 | ------------------------------------------------------------------------------- | ||
174 | Name: debug | 177 | Name: debug |
175 | Type: ushort | 178 | Type: ushort |
176 | Syntax: <n> | 179 | Syntax: <n> |
@@ -198,17 +201,23 @@ devices mounting the ZC0301 Image Processor and Control Chips: | |||
198 | 201 | ||
199 | Vendor ID Product ID | 202 | Vendor ID Product ID |
200 | --------- ---------- | 203 | --------- ---------- |
204 | 0x10fd 0x8050 | ||
205 | 0x041e 0x0417 | ||
206 | 0x041e 0x041e | ||
207 | 0x041e 0x081c | ||
208 | 0x041e 0x0834 | ||
209 | 0x041e 0x0835 | ||
201 | 0x046d 0x08ae | 210 | 0x046d 0x08ae |
211 | 0x0ac8 0x0301 | ||
202 | 212 | ||
203 | The following image sensors are supported: | 213 | The list above does not imply that all those devices work with this driver: up |
214 | until now only the ones that mount the following image sensors are supported; | ||
215 | kernel messages will always tell you whether this is the case: | ||
204 | 216 | ||
205 | Model Manufacturer | 217 | Model Manufacturer |
206 | ----- ------------ | 218 | ----- ------------ |
207 | PAS202BCB PixArt Imaging, Inc. | 219 | PAS202BCB PixArt Imaging, Inc. |
208 | 220 | ||
209 | All the available control settings of each image sensor are supported through | ||
210 | the V4L2 interface. | ||
211 | |||
212 | 221 | ||
213 | 9. Notes for V4L2 application developers | 222 | 9. Notes for V4L2 application developers |
214 | ======================================== | 223 | ======================================== |
@@ -240,6 +249,6 @@ the fingerprint is: '88E8 F32F 7244 68BA 3958 5D40 99DA 5D2A FCE6 35A4'. | |||
240 | - Informations about the chip internals needed to enable the I2C protocol have | 249 | - Informations about the chip internals needed to enable the I2C protocol have |
241 | been taken from the documentation of the ZC030x Video4Linux1 driver written | 250 | been taken from the documentation of the ZC030x Video4Linux1 driver written |
242 | by Andrew Birkett <andy@nobugs.org>; | 251 | by Andrew Birkett <andy@nobugs.org>; |
243 | - Initialization values of the ZC0301 controller connected to the PAS202BCB | 252 | - The initialization values of the ZC0301 controller connected to the PAS202BCB |
244 | image sensor have been taken from the SPCA5XX driver maintained by | 253 | image sensor have been taken from the SPCA5XX driver maintained by |
245 | Michel Xhaard <mxhaard@magic.fr>. | 254 | Michel Xhaard <mxhaard@magic.fr>. |
diff --git a/drivers/usb/media/zc0301.h b/drivers/usb/media/zc0301.h index cb1a0823bc63..9ba9135e824b 100644 --- a/drivers/usb/media/zc0301.h +++ b/drivers/usb/media/zc0301.h | |||
@@ -34,7 +34,8 @@ | |||
34 | #include <linux/param.h> | 34 | #include <linux/param.h> |
35 | #include <linux/mutex.h> | 35 | #include <linux/mutex.h> |
36 | #include <linux/rwsem.h> | 36 | #include <linux/rwsem.h> |
37 | #include <asm/semaphore.h> | 37 | #include <linux/stddef.h> |
38 | #include <linux/string.h> | ||
38 | 39 | ||
39 | #include "zc0301_sensor.h" | 40 | #include "zc0301_sensor.h" |
40 | 41 | ||
@@ -51,7 +52,7 @@ | |||
51 | #define ZC0301_ALTERNATE_SETTING 7 | 52 | #define ZC0301_ALTERNATE_SETTING 7 |
52 | #define ZC0301_URB_TIMEOUT msecs_to_jiffies(2 * ZC0301_ISO_PACKETS) | 53 | #define ZC0301_URB_TIMEOUT msecs_to_jiffies(2 * ZC0301_ISO_PACKETS) |
53 | #define ZC0301_CTRL_TIMEOUT 100 | 54 | #define ZC0301_CTRL_TIMEOUT 100 |
54 | #define ZC0301_FRAME_TIMEOUT 2 * 1000 * msecs_to_jiffies(1) | 55 | #define ZC0301_FRAME_TIMEOUT 2 |
55 | 56 | ||
56 | /*****************************************************************************/ | 57 | /*****************************************************************************/ |
57 | 58 | ||
@@ -94,6 +95,7 @@ enum zc0301_stream_state { | |||
94 | 95 | ||
95 | struct zc0301_module_param { | 96 | struct zc0301_module_param { |
96 | u8 force_munmap; | 97 | u8 force_munmap; |
98 | u16 frame_timeout; | ||
97 | }; | 99 | }; |
98 | 100 | ||
99 | static DECLARE_RWSEM(zc0301_disconnect); | 101 | static DECLARE_RWSEM(zc0301_disconnect); |
@@ -101,7 +103,7 @@ static DECLARE_RWSEM(zc0301_disconnect); | |||
101 | struct zc0301_device { | 103 | struct zc0301_device { |
102 | struct video_device* v4ldev; | 104 | struct video_device* v4ldev; |
103 | 105 | ||
104 | struct zc0301_sensor* sensor; | 106 | struct zc0301_sensor sensor; |
105 | 107 | ||
106 | struct usb_device* usbdev; | 108 | struct usb_device* usbdev; |
107 | struct urb* urb[ZC0301_URBS]; | 109 | struct urb* urb[ZC0301_URBS]; |
@@ -129,11 +131,19 @@ struct zc0301_device { | |||
129 | 131 | ||
130 | /*****************************************************************************/ | 132 | /*****************************************************************************/ |
131 | 133 | ||
134 | struct zc0301_device* | ||
135 | zc0301_match_id(struct zc0301_device* cam, const struct usb_device_id *id) | ||
136 | { | ||
137 | if (usb_match_id(usb_ifnum_to_if(cam->usbdev, 0), id)) | ||
138 | return cam; | ||
139 | |||
140 | return NULL; | ||
141 | } | ||
142 | |||
132 | void | 143 | void |
133 | zc0301_attach_sensor(struct zc0301_device* cam, struct zc0301_sensor* sensor) | 144 | zc0301_attach_sensor(struct zc0301_device* cam, struct zc0301_sensor* sensor) |
134 | { | 145 | { |
135 | cam->sensor = sensor; | 146 | memcpy(&cam->sensor, sensor, sizeof(struct zc0301_sensor)); |
136 | cam->sensor->usbdev = cam->usbdev; | ||
137 | } | 147 | } |
138 | 148 | ||
139 | /*****************************************************************************/ | 149 | /*****************************************************************************/ |
diff --git a/drivers/usb/media/zc0301_core.c b/drivers/usb/media/zc0301_core.c index 7e8b1676d144..5773688d3dae 100644 --- a/drivers/usb/media/zc0301_core.c +++ b/drivers/usb/media/zc0301_core.c | |||
@@ -29,11 +29,9 @@ | |||
29 | #include <linux/moduleparam.h> | 29 | #include <linux/moduleparam.h> |
30 | #include <linux/errno.h> | 30 | #include <linux/errno.h> |
31 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
32 | #include <linux/string.h> | ||
33 | #include <linux/device.h> | 32 | #include <linux/device.h> |
34 | #include <linux/fs.h> | 33 | #include <linux/fs.h> |
35 | #include <linux/delay.h> | 34 | #include <linux/delay.h> |
36 | #include <linux/stddef.h> | ||
37 | #include <linux/compiler.h> | 35 | #include <linux/compiler.h> |
38 | #include <linux/ioctl.h> | 36 | #include <linux/ioctl.h> |
39 | #include <linux/poll.h> | 37 | #include <linux/poll.h> |
@@ -54,8 +52,8 @@ | |||
54 | #define ZC0301_MODULE_AUTHOR "(C) 2006 Luca Risolia" | 52 | #define ZC0301_MODULE_AUTHOR "(C) 2006 Luca Risolia" |
55 | #define ZC0301_AUTHOR_EMAIL "<luca.risolia@studio.unibo.it>" | 53 | #define ZC0301_AUTHOR_EMAIL "<luca.risolia@studio.unibo.it>" |
56 | #define ZC0301_MODULE_LICENSE "GPL" | 54 | #define ZC0301_MODULE_LICENSE "GPL" |
57 | #define ZC0301_MODULE_VERSION "1:1.01" | 55 | #define ZC0301_MODULE_VERSION "1:1.02" |
58 | #define ZC0301_MODULE_VERSION_CODE KERNEL_VERSION(1, 0, 1) | 56 | #define ZC0301_MODULE_VERSION_CODE KERNEL_VERSION(1, 0, 2) |
59 | 57 | ||
60 | /*****************************************************************************/ | 58 | /*****************************************************************************/ |
61 | 59 | ||
@@ -94,6 +92,15 @@ MODULE_PARM_DESC(force_munmap, | |||
94 | "\nDefault value is "__MODULE_STRING(SN9C102_FORCE_MUNMAP)"." | 92 | "\nDefault value is "__MODULE_STRING(SN9C102_FORCE_MUNMAP)"." |
95 | "\n"); | 93 | "\n"); |
96 | 94 | ||
95 | static unsigned int frame_timeout[] = {[0 ... ZC0301_MAX_DEVICES-1] = | ||
96 | ZC0301_FRAME_TIMEOUT}; | ||
97 | module_param_array(frame_timeout, uint, NULL, 0644); | ||
98 | MODULE_PARM_DESC(frame_timeout, | ||
99 | "\n<n[,...]> Timeout for a video frame in seconds." | ||
100 | "\nThis parameter is specific for each detected camera." | ||
101 | "\nDefault value is "__MODULE_STRING(ZC0301_FRAME_TIMEOUT)"." | ||
102 | "\n"); | ||
103 | |||
97 | #ifdef ZC0301_DEBUG | 104 | #ifdef ZC0301_DEBUG |
98 | static unsigned short debug = ZC0301_DEBUG_LEVEL; | 105 | static unsigned short debug = ZC0301_DEBUG_LEVEL; |
99 | module_param(debug, ushort, 0644); | 106 | module_param(debug, ushort, 0644); |
@@ -115,8 +122,8 @@ static u32 | |||
115 | zc0301_request_buffers(struct zc0301_device* cam, u32 count, | 122 | zc0301_request_buffers(struct zc0301_device* cam, u32 count, |
116 | enum zc0301_io_method io) | 123 | enum zc0301_io_method io) |
117 | { | 124 | { |
118 | struct v4l2_pix_format* p = &(cam->sensor->pix_format); | 125 | struct v4l2_pix_format* p = &(cam->sensor.pix_format); |
119 | struct v4l2_rect* r = &(cam->sensor->cropcap.bounds); | 126 | struct v4l2_rect* r = &(cam->sensor.cropcap.bounds); |
120 | const size_t imagesize = cam->module_param.force_munmap || | 127 | const size_t imagesize = cam->module_param.force_munmap || |
121 | io == IO_READ ? | 128 | io == IO_READ ? |
122 | (p->width * p->height * p->priv) / 8 : | 129 | (p->width * p->height * p->priv) / 8 : |
@@ -332,9 +339,9 @@ static void zc0301_urb_complete(struct urb *urb, struct pt_regs* regs) | |||
332 | (*f) = list_entry(cam->inqueue.next, struct zc0301_frame_t, | 339 | (*f) = list_entry(cam->inqueue.next, struct zc0301_frame_t, |
333 | frame); | 340 | frame); |
334 | 341 | ||
335 | imagesize = (cam->sensor->pix_format.width * | 342 | imagesize = (cam->sensor.pix_format.width * |
336 | cam->sensor->pix_format.height * | 343 | cam->sensor.pix_format.height * |
337 | cam->sensor->pix_format.priv) / 8; | 344 | cam->sensor.pix_format.priv) / 8; |
338 | 345 | ||
339 | for (i = 0; i < urb->number_of_packets; i++) { | 346 | for (i = 0; i < urb->number_of_packets; i++) { |
340 | unsigned int len, status; | 347 | unsigned int len, status; |
@@ -555,7 +562,7 @@ zc0301_set_compression(struct zc0301_device* cam, | |||
555 | 562 | ||
556 | static int zc0301_init(struct zc0301_device* cam) | 563 | static int zc0301_init(struct zc0301_device* cam) |
557 | { | 564 | { |
558 | struct zc0301_sensor* s = cam->sensor; | 565 | struct zc0301_sensor* s = &cam->sensor; |
559 | struct v4l2_control ctrl; | 566 | struct v4l2_control ctrl; |
560 | struct v4l2_queryctrl *qctrl; | 567 | struct v4l2_queryctrl *qctrl; |
561 | struct v4l2_rect* rect; | 568 | struct v4l2_rect* rect; |
@@ -630,6 +637,7 @@ static void zc0301_release_resources(struct zc0301_device* cam) | |||
630 | DBG(2, "V4L2 device /dev/video%d deregistered", cam->v4ldev->minor); | 637 | DBG(2, "V4L2 device /dev/video%d deregistered", cam->v4ldev->minor); |
631 | video_set_drvdata(cam->v4ldev, NULL); | 638 | video_set_drvdata(cam->v4ldev, NULL); |
632 | video_unregister_device(cam->v4ldev); | 639 | video_unregister_device(cam->v4ldev); |
640 | usb_put_dev(cam->usbdev); | ||
633 | kfree(cam->control_buffer); | 641 | kfree(cam->control_buffer); |
634 | } | 642 | } |
635 | 643 | ||
@@ -798,7 +806,8 @@ zc0301_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos) | |||
798 | (!list_empty(&cam->outqueue)) || | 806 | (!list_empty(&cam->outqueue)) || |
799 | (cam->state & DEV_DISCONNECTED) || | 807 | (cam->state & DEV_DISCONNECTED) || |
800 | (cam->state & DEV_MISCONFIGURED), | 808 | (cam->state & DEV_MISCONFIGURED), |
801 | ZC0301_FRAME_TIMEOUT ); | 809 | cam->module_param.frame_timeout * |
810 | 1000 * msecs_to_jiffies(1) ); | ||
802 | if (timeout < 0) { | 811 | if (timeout < 0) { |
803 | mutex_unlock(&cam->fileop_mutex); | 812 | mutex_unlock(&cam->fileop_mutex); |
804 | return timeout; | 813 | return timeout; |
@@ -1056,7 +1065,7 @@ zc0301_vidioc_s_input(struct zc0301_device* cam, void __user * arg) | |||
1056 | static int | 1065 | static int |
1057 | zc0301_vidioc_query_ctrl(struct zc0301_device* cam, void __user * arg) | 1066 | zc0301_vidioc_query_ctrl(struct zc0301_device* cam, void __user * arg) |
1058 | { | 1067 | { |
1059 | struct zc0301_sensor* s = cam->sensor; | 1068 | struct zc0301_sensor* s = &cam->sensor; |
1060 | struct v4l2_queryctrl qc; | 1069 | struct v4l2_queryctrl qc; |
1061 | u8 i; | 1070 | u8 i; |
1062 | 1071 | ||
@@ -1078,7 +1087,7 @@ zc0301_vidioc_query_ctrl(struct zc0301_device* cam, void __user * arg) | |||
1078 | static int | 1087 | static int |
1079 | zc0301_vidioc_g_ctrl(struct zc0301_device* cam, void __user * arg) | 1088 | zc0301_vidioc_g_ctrl(struct zc0301_device* cam, void __user * arg) |
1080 | { | 1089 | { |
1081 | struct zc0301_sensor* s = cam->sensor; | 1090 | struct zc0301_sensor* s = &cam->sensor; |
1082 | struct v4l2_control ctrl; | 1091 | struct v4l2_control ctrl; |
1083 | int err = 0; | 1092 | int err = 0; |
1084 | u8 i; | 1093 | u8 i; |
@@ -1110,7 +1119,7 @@ exit: | |||
1110 | static int | 1119 | static int |
1111 | zc0301_vidioc_s_ctrl(struct zc0301_device* cam, void __user * arg) | 1120 | zc0301_vidioc_s_ctrl(struct zc0301_device* cam, void __user * arg) |
1112 | { | 1121 | { |
1113 | struct zc0301_sensor* s = cam->sensor; | 1122 | struct zc0301_sensor* s = &cam->sensor; |
1114 | struct v4l2_control ctrl; | 1123 | struct v4l2_control ctrl; |
1115 | u8 i; | 1124 | u8 i; |
1116 | int err = 0; | 1125 | int err = 0; |
@@ -1123,6 +1132,8 @@ zc0301_vidioc_s_ctrl(struct zc0301_device* cam, void __user * arg) | |||
1123 | 1132 | ||
1124 | for (i = 0; i < ARRAY_SIZE(s->qctrl); i++) | 1133 | for (i = 0; i < ARRAY_SIZE(s->qctrl); i++) |
1125 | if (ctrl.id == s->qctrl[i].id) { | 1134 | if (ctrl.id == s->qctrl[i].id) { |
1135 | if (s->qctrl[i].flags & V4L2_CTRL_FLAG_DISABLED) | ||
1136 | return -EINVAL; | ||
1126 | if (ctrl.value < s->qctrl[i].minimum || | 1137 | if (ctrl.value < s->qctrl[i].minimum || |
1127 | ctrl.value > s->qctrl[i].maximum) | 1138 | ctrl.value > s->qctrl[i].maximum) |
1128 | return -ERANGE; | 1139 | return -ERANGE; |
@@ -1142,7 +1153,7 @@ zc0301_vidioc_s_ctrl(struct zc0301_device* cam, void __user * arg) | |||
1142 | static int | 1153 | static int |
1143 | zc0301_vidioc_cropcap(struct zc0301_device* cam, void __user * arg) | 1154 | zc0301_vidioc_cropcap(struct zc0301_device* cam, void __user * arg) |
1144 | { | 1155 | { |
1145 | struct v4l2_cropcap* cc = &(cam->sensor->cropcap); | 1156 | struct v4l2_cropcap* cc = &(cam->sensor.cropcap); |
1146 | 1157 | ||
1147 | cc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 1158 | cc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
1148 | cc->pixelaspect.numerator = 1; | 1159 | cc->pixelaspect.numerator = 1; |
@@ -1158,7 +1169,7 @@ zc0301_vidioc_cropcap(struct zc0301_device* cam, void __user * arg) | |||
1158 | static int | 1169 | static int |
1159 | zc0301_vidioc_g_crop(struct zc0301_device* cam, void __user * arg) | 1170 | zc0301_vidioc_g_crop(struct zc0301_device* cam, void __user * arg) |
1160 | { | 1171 | { |
1161 | struct zc0301_sensor* s = cam->sensor; | 1172 | struct zc0301_sensor* s = &cam->sensor; |
1162 | struct v4l2_crop crop = { | 1173 | struct v4l2_crop crop = { |
1163 | .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, | 1174 | .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, |
1164 | }; | 1175 | }; |
@@ -1175,7 +1186,7 @@ zc0301_vidioc_g_crop(struct zc0301_device* cam, void __user * arg) | |||
1175 | static int | 1186 | static int |
1176 | zc0301_vidioc_s_crop(struct zc0301_device* cam, void __user * arg) | 1187 | zc0301_vidioc_s_crop(struct zc0301_device* cam, void __user * arg) |
1177 | { | 1188 | { |
1178 | struct zc0301_sensor* s = cam->sensor; | 1189 | struct zc0301_sensor* s = &cam->sensor; |
1179 | struct v4l2_crop crop; | 1190 | struct v4l2_crop crop; |
1180 | struct v4l2_rect* rect; | 1191 | struct v4l2_rect* rect; |
1181 | struct v4l2_rect* bounds = &(s->cropcap.bounds); | 1192 | struct v4l2_rect* bounds = &(s->cropcap.bounds); |
@@ -1304,7 +1315,7 @@ static int | |||
1304 | zc0301_vidioc_g_fmt(struct zc0301_device* cam, void __user * arg) | 1315 | zc0301_vidioc_g_fmt(struct zc0301_device* cam, void __user * arg) |
1305 | { | 1316 | { |
1306 | struct v4l2_format format; | 1317 | struct v4l2_format format; |
1307 | struct v4l2_pix_format* pfmt = &(cam->sensor->pix_format); | 1318 | struct v4l2_pix_format* pfmt = &(cam->sensor.pix_format); |
1308 | 1319 | ||
1309 | if (copy_from_user(&format, arg, sizeof(format))) | 1320 | if (copy_from_user(&format, arg, sizeof(format))) |
1310 | return -EFAULT; | 1321 | return -EFAULT; |
@@ -1328,7 +1339,7 @@ static int | |||
1328 | zc0301_vidioc_try_s_fmt(struct zc0301_device* cam, unsigned int cmd, | 1339 | zc0301_vidioc_try_s_fmt(struct zc0301_device* cam, unsigned int cmd, |
1329 | void __user * arg) | 1340 | void __user * arg) |
1330 | { | 1341 | { |
1331 | struct zc0301_sensor* s = cam->sensor; | 1342 | struct zc0301_sensor* s = &cam->sensor; |
1332 | struct v4l2_format format; | 1343 | struct v4l2_format format; |
1333 | struct v4l2_pix_format* pix; | 1344 | struct v4l2_pix_format* pix; |
1334 | struct v4l2_pix_format* pfmt = &(s->pix_format); | 1345 | struct v4l2_pix_format* pfmt = &(s->pix_format); |
@@ -1612,7 +1623,8 @@ zc0301_vidioc_dqbuf(struct zc0301_device* cam, struct file* filp, | |||
1612 | (!list_empty(&cam->outqueue)) || | 1623 | (!list_empty(&cam->outqueue)) || |
1613 | (cam->state & DEV_DISCONNECTED) || | 1624 | (cam->state & DEV_DISCONNECTED) || |
1614 | (cam->state & DEV_MISCONFIGURED), | 1625 | (cam->state & DEV_MISCONFIGURED), |
1615 | ZC0301_FRAME_TIMEOUT ); | 1626 | cam->module_param.frame_timeout * |
1627 | 1000 * msecs_to_jiffies(1) ); | ||
1616 | if (timeout < 0) | 1628 | if (timeout < 0) |
1617 | return timeout; | 1629 | return timeout; |
1618 | if (cam->state & DEV_DISCONNECTED) | 1630 | if (cam->state & DEV_DISCONNECTED) |
@@ -1911,8 +1923,8 @@ zc0301_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) | |||
1911 | break; | 1923 | break; |
1912 | } | 1924 | } |
1913 | 1925 | ||
1914 | if (!err && cam->sensor) | 1926 | if (!err) |
1915 | DBG(2, "%s image sensor detected", cam->sensor->name); | 1927 | DBG(2, "%s image sensor detected", cam->sensor.name); |
1916 | else { | 1928 | else { |
1917 | DBG(1, "No supported image sensor detected"); | 1929 | DBG(1, "No supported image sensor detected"); |
1918 | err = -ENODEV; | 1930 | err = -ENODEV; |
@@ -1950,6 +1962,7 @@ zc0301_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) | |||
1950 | DBG(2, "V4L2 device registered as /dev/video%d", cam->v4ldev->minor); | 1962 | DBG(2, "V4L2 device registered as /dev/video%d", cam->v4ldev->minor); |
1951 | 1963 | ||
1952 | cam->module_param.force_munmap = force_munmap[dev_nr]; | 1964 | cam->module_param.force_munmap = force_munmap[dev_nr]; |
1965 | cam->module_param.frame_timeout = frame_timeout[dev_nr]; | ||
1953 | 1966 | ||
1954 | dev_nr = (dev_nr < ZC0301_MAX_DEVICES-1) ? dev_nr+1 : 0; | 1967 | dev_nr = (dev_nr < ZC0301_MAX_DEVICES-1) ? dev_nr+1 : 0; |
1955 | 1968 | ||
@@ -1994,6 +2007,7 @@ static void zc0301_usb_disconnect(struct usb_interface* intf) | |||
1994 | cam->state |= DEV_DISCONNECTED; | 2007 | cam->state |= DEV_DISCONNECTED; |
1995 | wake_up_interruptible(&cam->wait_frame); | 2008 | wake_up_interruptible(&cam->wait_frame); |
1996 | wake_up(&cam->wait_stream); | 2009 | wake_up(&cam->wait_stream); |
2010 | usb_get_dev(cam->usbdev); | ||
1997 | } else { | 2011 | } else { |
1998 | cam->state |= DEV_DISCONNECTED; | 2012 | cam->state |= DEV_DISCONNECTED; |
1999 | zc0301_release_resources(cam); | 2013 | zc0301_release_resources(cam); |
diff --git a/drivers/usb/media/zc0301_pas202bcb.c b/drivers/usb/media/zc0301_pas202bcb.c index 32b9b9329cbf..9d282a22c15f 100644 --- a/drivers/usb/media/zc0301_pas202bcb.c +++ b/drivers/usb/media/zc0301_pas202bcb.c | |||
@@ -22,6 +22,14 @@ | |||
22 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * | 22 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * |
23 | ***************************************************************************/ | 23 | ***************************************************************************/ |
24 | 24 | ||
25 | /* | ||
26 | NOTE: Sensor controls are disabled for now, becouse changing them while | ||
27 | streaming sometimes results in out-of-sync video frames. We'll use | ||
28 | the default initialization, until we know how to stop and start video | ||
29 | in the chip. However, the image quality still looks good under various | ||
30 | light conditions. | ||
31 | */ | ||
32 | |||
25 | #include <linux/delay.h> | 33 | #include <linux/delay.h> |
26 | #include "zc0301_sensor.h" | 34 | #include "zc0301_sensor.h" |
27 | 35 | ||
@@ -245,7 +253,7 @@ static struct zc0301_sensor pas202bcb = { | |||
245 | .maximum = 0x3fff, | 253 | .maximum = 0x3fff, |
246 | .step = 0x0001, | 254 | .step = 0x0001, |
247 | .default_value = 0x01e5, | 255 | .default_value = 0x01e5, |
248 | .flags = 0, | 256 | .flags = V4L2_CTRL_FLAG_DISABLED, |
249 | }, | 257 | }, |
250 | { | 258 | { |
251 | .id = V4L2_CID_GAIN, | 259 | .id = V4L2_CID_GAIN, |
@@ -255,7 +263,17 @@ static struct zc0301_sensor pas202bcb = { | |||
255 | .maximum = 0x1f, | 263 | .maximum = 0x1f, |
256 | .step = 0x01, | 264 | .step = 0x01, |
257 | .default_value = 0x0c, | 265 | .default_value = 0x0c, |
258 | .flags = 0, | 266 | .flags = V4L2_CTRL_FLAG_DISABLED, |
267 | }, | ||
268 | { | ||
269 | .id = ZC0301_V4L2_CID_DAC_MAGNITUDE, | ||
270 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
271 | .name = "DAC magnitude", | ||
272 | .minimum = 0x00, | ||
273 | .maximum = 0xff, | ||
274 | .step = 0x01, | ||
275 | .default_value = 0x00, | ||
276 | .flags = V4L2_CTRL_FLAG_DISABLED, | ||
259 | }, | 277 | }, |
260 | { | 278 | { |
261 | .id = V4L2_CID_RED_BALANCE, | 279 | .id = V4L2_CID_RED_BALANCE, |
@@ -265,7 +283,7 @@ static struct zc0301_sensor pas202bcb = { | |||
265 | .maximum = 0x0f, | 283 | .maximum = 0x0f, |
266 | .step = 0x01, | 284 | .step = 0x01, |
267 | .default_value = 0x01, | 285 | .default_value = 0x01, |
268 | .flags = 0, | 286 | .flags = V4L2_CTRL_FLAG_DISABLED, |
269 | }, | 287 | }, |
270 | { | 288 | { |
271 | .id = V4L2_CID_BLUE_BALANCE, | 289 | .id = V4L2_CID_BLUE_BALANCE, |
@@ -275,7 +293,7 @@ static struct zc0301_sensor pas202bcb = { | |||
275 | .maximum = 0x0f, | 293 | .maximum = 0x0f, |
276 | .step = 0x01, | 294 | .step = 0x01, |
277 | .default_value = 0x05, | 295 | .default_value = 0x05, |
278 | .flags = 0, | 296 | .flags = V4L2_CTRL_FLAG_DISABLED, |
279 | }, | 297 | }, |
280 | { | 298 | { |
281 | .id = ZC0301_V4L2_CID_GREEN_BALANCE, | 299 | .id = ZC0301_V4L2_CID_GREEN_BALANCE, |
@@ -285,17 +303,7 @@ static struct zc0301_sensor pas202bcb = { | |||
285 | .maximum = 0x0f, | 303 | .maximum = 0x0f, |
286 | .step = 0x01, | 304 | .step = 0x01, |
287 | .default_value = 0x00, | 305 | .default_value = 0x00, |
288 | .flags = 0, | 306 | .flags = V4L2_CTRL_FLAG_DISABLED, |
289 | }, | ||
290 | { | ||
291 | .id = ZC0301_V4L2_CID_DAC_MAGNITUDE, | ||
292 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
293 | .name = "DAC magnitude", | ||
294 | .minimum = 0x00, | ||
295 | .maximum = 0xff, | ||
296 | .step = 0x01, | ||
297 | .default_value = 0x04, | ||
298 | .flags = 0, | ||
299 | }, | 307 | }, |
300 | }, | 308 | }, |
301 | .get_ctrl = &pas202bcb_get_ctrl, | 309 | .get_ctrl = &pas202bcb_get_ctrl, |
diff --git a/drivers/usb/media/zc0301_sensor.h b/drivers/usb/media/zc0301_sensor.h index 8890e32405d4..e3cb6cc920ca 100644 --- a/drivers/usb/media/zc0301_sensor.h +++ b/drivers/usb/media/zc0301_sensor.h | |||
@@ -43,9 +43,11 @@ static int (*zc0301_sensor_table[])(struct zc0301_device*) = { \ | |||
43 | NULL, \ | 43 | NULL, \ |
44 | }; | 44 | }; |
45 | 45 | ||
46 | extern struct zc0301_device* | ||
47 | zc0301_match_id(struct zc0301_device* cam, const struct usb_device_id *id); | ||
48 | |||
46 | extern void | 49 | extern void |
47 | zc0301_attach_sensor(struct zc0301_device* cam, | 50 | zc0301_attach_sensor(struct zc0301_device* cam, struct zc0301_sensor* sensor); |
48 | struct zc0301_sensor* sensor); | ||
49 | 51 | ||
50 | #define ZC0301_USB_DEVICE(vend, prod, intclass) \ | 52 | #define ZC0301_USB_DEVICE(vend, prod, intclass) \ |
51 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \ | 53 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \ |
@@ -56,7 +58,14 @@ zc0301_attach_sensor(struct zc0301_device* cam, | |||
56 | 58 | ||
57 | #define ZC0301_ID_TABLE \ | 59 | #define ZC0301_ID_TABLE \ |
58 | static const struct usb_device_id zc0301_id_table[] = { \ | 60 | static const struct usb_device_id zc0301_id_table[] = { \ |
61 | { ZC0301_USB_DEVICE(0x10fd, 0x8050, 0xff), }, /* TAS5130D */ \ | ||
62 | { ZC0301_USB_DEVICE(0x041e, 0x0417, 0xff), }, \ | ||
63 | { ZC0301_USB_DEVICE(0x041e, 0x041e, 0xff), }, /* HV7131B */ \ | ||
64 | { ZC0301_USB_DEVICE(0x041e, 0x081c, 0xff), }, /* PAS106 */ \ | ||
65 | { ZC0301_USB_DEVICE(0x041e, 0x0834, 0xff), }, /* PAS106 */ \ | ||
66 | { ZC0301_USB_DEVICE(0x041e, 0x0835, 0xff), }, /* PAS106 */ \ | ||
59 | { ZC0301_USB_DEVICE(0x046d, 0x08ae, 0xff), }, /* PAS202BCB */ \ | 67 | { ZC0301_USB_DEVICE(0x046d, 0x08ae, 0xff), }, /* PAS202BCB */ \ |
68 | { ZC0301_USB_DEVICE(0x0ac8, 0x0301, 0xff), }, \ | ||
60 | { } \ | 69 | { } \ |
61 | }; | 70 | }; |
62 | 71 | ||
@@ -80,15 +89,11 @@ struct zc0301_sensor { | |||
80 | struct v4l2_cropcap cropcap; | 89 | struct v4l2_cropcap cropcap; |
81 | struct v4l2_pix_format pix_format; | 90 | struct v4l2_pix_format pix_format; |
82 | 91 | ||
83 | int (*init)(struct zc0301_device* cam); | 92 | int (*init)(struct zc0301_device*); |
84 | int (*get_ctrl)(struct zc0301_device* cam, | 93 | int (*get_ctrl)(struct zc0301_device*, struct v4l2_control* ctrl); |
85 | struct v4l2_control* ctrl); | 94 | int (*set_ctrl)(struct zc0301_device*, |
86 | int (*set_ctrl)(struct zc0301_device* cam, | ||
87 | const struct v4l2_control* ctrl); | 95 | const struct v4l2_control* ctrl); |
88 | int (*set_crop)(struct zc0301_device* cam, | 96 | int (*set_crop)(struct zc0301_device*, const struct v4l2_rect* rect); |
89 | const struct v4l2_rect* rect); | ||
90 | |||
91 | const struct usb_device* usbdev; | ||
92 | 97 | ||
93 | /* Private */ | 98 | /* Private */ |
94 | struct v4l2_queryctrl _qctrl[ZC0301_MAX_CTRLS]; | 99 | struct v4l2_queryctrl _qctrl[ZC0301_MAX_CTRLS]; |