diff options
author | Luca Risolia <luca.risolia@studio.unibo.it> | 2006-02-25 01:54:18 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-03-20 17:49:59 -0500 |
commit | ccad7789d5e557644d1c866b018394872af0ec5b (patch) | |
tree | c3894cc5b75fe11b4db85229927591387aa332a8 | |
parent | 2ffab02fea5880da284dc5511479b25a796a8dee (diff) |
[PATCH] USB: ET61X[12]51 driver updates
USB: ET61X[12]51 driver updates
Changes: + new, - removed, * cleanup, @ bugfix
@ Fix stream_interrupt()
@ Fix vidioc_enum_input() and split vidioc_gs_input()
@ Need usb_get|put_dev() when disconnecting, if the device is open
* Use wait_event_interruptible_timeout() instead of wait_event_interruptible()
when waiting for video frames
* replace wake_up_interruptible(&wait_stream) with wake_up(&wait_stream)
* Cleanups and updates in the documentation
* Use mutexes instead of semaphores
+ Use per-device sensor structures
+ Add support for PAS202BCA image sensors
+ Add frame_timeout module parameter
Signed-off-by: Luca Risolia <luca.risolia@studio.unibo.it>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | Documentation/usb/et61x251.txt | 10 | ||||
-rw-r--r-- | drivers/usb/media/et61x251.h | 28 | ||||
-rw-r--r-- | drivers/usb/media/et61x251_core.c | 321 | ||||
-rw-r--r-- | drivers/usb/media/et61x251_sensor.h | 5 | ||||
-rw-r--r-- | drivers/usb/media/et61x251_tas5130d1b.c | 10 |
5 files changed, 213 insertions, 161 deletions
diff --git a/Documentation/usb/et61x251.txt b/Documentation/usb/et61x251.txt index b44dda407ce2..29340282ab5f 100644 --- a/Documentation/usb/et61x251.txt +++ b/Documentation/usb/et61x251.txt | |||
@@ -176,6 +176,14 @@ Description: Force the application to unmap previously mapped buffer memory | |||
176 | 1 = force memory unmapping (save memory) | 176 | 1 = force memory unmapping (save memory) |
177 | Default: 0 | 177 | Default: 0 |
178 | ------------------------------------------------------------------------------- | 178 | ------------------------------------------------------------------------------- |
179 | Name: frame_timeout | ||
180 | Type: uint array (min = 0, max = 64) | ||
181 | Syntax: <n[,...]> | ||
182 | Description: Timeout for a video frame in seconds. This parameter is | ||
183 | specific for each detected camera. This parameter can be | ||
184 | changed at runtime thanks to the /sys filesystem interface. | ||
185 | Default: 2 | ||
186 | ------------------------------------------------------------------------------- | ||
179 | Name: debug | 187 | Name: debug |
180 | Type: ushort | 188 | Type: ushort |
181 | Syntax: <n> | 189 | Syntax: <n> |
@@ -266,7 +274,7 @@ the V4L2 interface. | |||
266 | 274 | ||
267 | 275 | ||
268 | 10. Notes for V4L2 application developers | 276 | 10. Notes for V4L2 application developers |
269 | ======================================== | 277 | ========================================= |
270 | This driver follows the V4L2 API specifications. In particular, it enforces two | 278 | This driver follows the V4L2 API specifications. In particular, it enforces two |
271 | rules: | 279 | rules: |
272 | 280 | ||
diff --git a/drivers/usb/media/et61x251.h b/drivers/usb/media/et61x251.h index 652238f329f3..eee8afc9be72 100644 --- a/drivers/usb/media/et61x251.h +++ b/drivers/usb/media/et61x251.h | |||
@@ -33,7 +33,9 @@ | |||
33 | #include <linux/types.h> | 33 | #include <linux/types.h> |
34 | #include <linux/param.h> | 34 | #include <linux/param.h> |
35 | #include <linux/rwsem.h> | 35 | #include <linux/rwsem.h> |
36 | #include <asm/semaphore.h> | 36 | #include <linux/mutex.h> |
37 | #include <linux/stddef.h> | ||
38 | #include <linux/string.h> | ||
37 | 39 | ||
38 | #include "et61x251_sensor.h" | 40 | #include "et61x251_sensor.h" |
39 | 41 | ||
@@ -51,6 +53,7 @@ | |||
51 | #define ET61X251_ALTERNATE_SETTING 13 | 53 | #define ET61X251_ALTERNATE_SETTING 13 |
52 | #define ET61X251_URB_TIMEOUT msecs_to_jiffies(2 * ET61X251_ISO_PACKETS) | 54 | #define ET61X251_URB_TIMEOUT msecs_to_jiffies(2 * ET61X251_ISO_PACKETS) |
53 | #define ET61X251_CTRL_TIMEOUT 100 | 55 | #define ET61X251_CTRL_TIMEOUT 100 |
56 | #define ET61X251_FRAME_TIMEOUT 2 | ||
54 | 57 | ||
55 | /*****************************************************************************/ | 58 | /*****************************************************************************/ |
56 | 59 | ||
@@ -127,15 +130,16 @@ struct et61x251_sysfs_attr { | |||
127 | 130 | ||
128 | struct et61x251_module_param { | 131 | struct et61x251_module_param { |
129 | u8 force_munmap; | 132 | u8 force_munmap; |
133 | u16 frame_timeout; | ||
130 | }; | 134 | }; |
131 | 135 | ||
132 | static DECLARE_MUTEX(et61x251_sysfs_lock); | 136 | static DEFINE_MUTEX(et61x251_sysfs_lock); |
133 | static DECLARE_RWSEM(et61x251_disconnect); | 137 | static DECLARE_RWSEM(et61x251_disconnect); |
134 | 138 | ||
135 | struct et61x251_device { | 139 | struct et61x251_device { |
136 | struct video_device* v4ldev; | 140 | struct video_device* v4ldev; |
137 | 141 | ||
138 | struct et61x251_sensor* sensor; | 142 | struct et61x251_sensor sensor; |
139 | 143 | ||
140 | struct usb_device* usbdev; | 144 | struct usb_device* usbdev; |
141 | struct urb* urb[ET61X251_URBS]; | 145 | struct urb* urb[ET61X251_URBS]; |
@@ -157,19 +161,28 @@ struct et61x251_device { | |||
157 | enum et61x251_dev_state state; | 161 | enum et61x251_dev_state state; |
158 | u8 users; | 162 | u8 users; |
159 | 163 | ||
160 | struct semaphore dev_sem, fileop_sem; | 164 | struct mutex dev_mutex, fileop_mutex; |
161 | spinlock_t queue_lock; | 165 | spinlock_t queue_lock; |
162 | wait_queue_head_t open, wait_frame, wait_stream; | 166 | wait_queue_head_t open, wait_frame, wait_stream; |
163 | }; | 167 | }; |
164 | 168 | ||
165 | /*****************************************************************************/ | 169 | /*****************************************************************************/ |
166 | 170 | ||
171 | struct et61x251_device* | ||
172 | et61x251_match_id(struct et61x251_device* cam, const struct usb_device_id *id) | ||
173 | { | ||
174 | if (usb_match_id(usb_ifnum_to_if(cam->usbdev, 0), id)) | ||
175 | return cam; | ||
176 | |||
177 | return NULL; | ||
178 | } | ||
179 | |||
180 | |||
167 | void | 181 | void |
168 | et61x251_attach_sensor(struct et61x251_device* cam, | 182 | et61x251_attach_sensor(struct et61x251_device* cam, |
169 | struct et61x251_sensor* sensor) | 183 | struct et61x251_sensor* sensor) |
170 | { | 184 | { |
171 | cam->sensor = sensor; | 185 | memcpy(&cam->sensor, sensor, sizeof(struct et61x251_sensor)); |
172 | cam->sensor->usbdev = cam->usbdev; | ||
173 | } | 186 | } |
174 | 187 | ||
175 | /*****************************************************************************/ | 188 | /*****************************************************************************/ |
@@ -212,7 +225,8 @@ do { \ | |||
212 | 225 | ||
213 | #undef PDBG | 226 | #undef PDBG |
214 | #define PDBG(fmt, args...) \ | 227 | #define PDBG(fmt, args...) \ |
215 | dev_info(&cam->dev, "[%s:%d] " fmt "\n", __FUNCTION__, __LINE__ , ## args) | 228 | dev_info(&cam->usbdev->dev, "[%s:%d] " fmt "\n", \ |
229 | __FUNCTION__, __LINE__ , ## args) | ||
216 | 230 | ||
217 | #undef PDBGG | 231 | #undef PDBGG |
218 | #define PDBGG(fmt, args...) do {;} while(0) /* placeholder */ | 232 | #define PDBGG(fmt, args...) do {;} while(0) /* placeholder */ |
diff --git a/drivers/usb/media/et61x251_core.c b/drivers/usb/media/et61x251_core.c index 2c0171a5ad62..7cc01b828b3d 100644 --- a/drivers/usb/media/et61x251_core.c +++ b/drivers/usb/media/et61x251_core.c | |||
@@ -25,11 +25,9 @@ | |||
25 | #include <linux/moduleparam.h> | 25 | #include <linux/moduleparam.h> |
26 | #include <linux/errno.h> | 26 | #include <linux/errno.h> |
27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | #include <linux/string.h> | ||
29 | #include <linux/device.h> | 28 | #include <linux/device.h> |
30 | #include <linux/fs.h> | 29 | #include <linux/fs.h> |
31 | #include <linux/delay.h> | 30 | #include <linux/delay.h> |
32 | #include <linux/stddef.h> | ||
33 | #include <linux/compiler.h> | 31 | #include <linux/compiler.h> |
34 | #include <linux/ioctl.h> | 32 | #include <linux/ioctl.h> |
35 | #include <linux/poll.h> | 33 | #include <linux/poll.h> |
@@ -50,8 +48,8 @@ | |||
50 | #define ET61X251_MODULE_AUTHOR "(C) 2006 Luca Risolia" | 48 | #define ET61X251_MODULE_AUTHOR "(C) 2006 Luca Risolia" |
51 | #define ET61X251_AUTHOR_EMAIL "<luca.risolia@studio.unibo.it>" | 49 | #define ET61X251_AUTHOR_EMAIL "<luca.risolia@studio.unibo.it>" |
52 | #define ET61X251_MODULE_LICENSE "GPL" | 50 | #define ET61X251_MODULE_LICENSE "GPL" |
53 | #define ET61X251_MODULE_VERSION "1:1.01" | 51 | #define ET61X251_MODULE_VERSION "1:1.02" |
54 | #define ET61X251_MODULE_VERSION_CODE KERNEL_VERSION(1, 0, 1) | 52 | #define ET61X251_MODULE_VERSION_CODE KERNEL_VERSION(1, 0, 2) |
55 | 53 | ||
56 | /*****************************************************************************/ | 54 | /*****************************************************************************/ |
57 | 55 | ||
@@ -90,6 +88,16 @@ MODULE_PARM_DESC(force_munmap, | |||
90 | "\nDefault value is "__MODULE_STRING(SN9C102_FORCE_MUNMAP)"." | 88 | "\nDefault value is "__MODULE_STRING(SN9C102_FORCE_MUNMAP)"." |
91 | "\n"); | 89 | "\n"); |
92 | 90 | ||
91 | static unsigned int frame_timeout[] = {[0 ... ET61X251_MAX_DEVICES-1] = | ||
92 | ET61X251_FRAME_TIMEOUT}; | ||
93 | module_param_array(frame_timeout, uint, NULL, 0644); | ||
94 | MODULE_PARM_DESC(frame_timeout, | ||
95 | "\n<n[,...]> Timeout for a video frame in seconds." | ||
96 | "\nThis parameter is specific for each detected camera." | ||
97 | "\nDefault value is " | ||
98 | __MODULE_STRING(ET61X251_FRAME_TIMEOUT)"." | ||
99 | "\n"); | ||
100 | |||
93 | #ifdef ET61X251_DEBUG | 101 | #ifdef ET61X251_DEBUG |
94 | static unsigned short debug = ET61X251_DEBUG_LEVEL; | 102 | static unsigned short debug = ET61X251_DEBUG_LEVEL; |
95 | module_param(debug, ushort, 0644); | 103 | module_param(debug, ushort, 0644); |
@@ -111,8 +119,8 @@ static u32 | |||
111 | et61x251_request_buffers(struct et61x251_device* cam, u32 count, | 119 | et61x251_request_buffers(struct et61x251_device* cam, u32 count, |
112 | enum et61x251_io_method io) | 120 | enum et61x251_io_method io) |
113 | { | 121 | { |
114 | struct v4l2_pix_format* p = &(cam->sensor->pix_format); | 122 | struct v4l2_pix_format* p = &(cam->sensor.pix_format); |
115 | struct v4l2_rect* r = &(cam->sensor->cropcap.bounds); | 123 | struct v4l2_rect* r = &(cam->sensor.cropcap.bounds); |
116 | const size_t imagesize = cam->module_param.force_munmap || | 124 | const size_t imagesize = cam->module_param.force_munmap || |
117 | io == IO_READ ? | 125 | io == IO_READ ? |
118 | (p->width * p->height * p->priv) / 8 : | 126 | (p->width * p->height * p->priv) / 8 : |
@@ -268,8 +276,8 @@ et61x251_i2c_try_read(struct et61x251_device* cam, | |||
268 | int err = 0, res; | 276 | int err = 0, res; |
269 | 277 | ||
270 | data[0] = address; | 278 | data[0] = address; |
271 | data[1] = cam->sensor->i2c_slave_id; | 279 | data[1] = cam->sensor.i2c_slave_id; |
272 | data[2] = cam->sensor->rsta | 0x10; | 280 | data[2] = cam->sensor.rsta | 0x10; |
273 | data[3] = !(et61x251_read_reg(cam, 0x8b) & 0x02); | 281 | data[3] = !(et61x251_read_reg(cam, 0x8b) & 0x02); |
274 | res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41, | 282 | res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41, |
275 | 0, 0x88, data, 4, ET61X251_CTRL_TIMEOUT); | 283 | 0, 0x88, data, 4, ET61X251_CTRL_TIMEOUT); |
@@ -301,8 +309,8 @@ et61x251_i2c_try_write(struct et61x251_device* cam, | |||
301 | int err = 0, res; | 309 | int err = 0, res; |
302 | 310 | ||
303 | data[0] = address; | 311 | data[0] = address; |
304 | data[1] = cam->sensor->i2c_slave_id; | 312 | data[1] = cam->sensor.i2c_slave_id; |
305 | data[2] = cam->sensor->rsta | 0x12; | 313 | data[2] = cam->sensor.rsta | 0x12; |
306 | res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41, | 314 | res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41, |
307 | 0, 0x88, data, 3, ET61X251_CTRL_TIMEOUT); | 315 | 0, 0x88, data, 3, ET61X251_CTRL_TIMEOUT); |
308 | if (res < 0) | 316 | if (res < 0) |
@@ -334,9 +342,6 @@ et61x251_i2c_raw_write(struct et61x251_device* cam, u8 n, u8 data1, u8 data2, | |||
334 | u8* data = cam->control_buffer; | 342 | u8* data = cam->control_buffer; |
335 | int err = 0, res; | 343 | int err = 0, res; |
336 | 344 | ||
337 | if (!cam->sensor) | ||
338 | return -1; | ||
339 | |||
340 | data[0] = data2; | 345 | data[0] = data2; |
341 | data[1] = data3; | 346 | data[1] = data3; |
342 | data[2] = data4; | 347 | data[2] = data4; |
@@ -350,8 +355,8 @@ et61x251_i2c_raw_write(struct et61x251_device* cam, u8 n, u8 data1, u8 data2, | |||
350 | err += res; | 355 | err += res; |
351 | 356 | ||
352 | data[0] = address; | 357 | data[0] = address; |
353 | data[1] = cam->sensor->i2c_slave_id; | 358 | data[1] = cam->sensor.i2c_slave_id; |
354 | data[2] = cam->sensor->rsta | 0x02 | (n << 4); | 359 | data[2] = cam->sensor.rsta | 0x02 | (n << 4); |
355 | res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41, | 360 | res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41, |
356 | 0, 0x88, data, 3, ET61X251_CTRL_TIMEOUT); | 361 | 0, 0x88, data, 3, ET61X251_CTRL_TIMEOUT); |
357 | if (res < 0) | 362 | if (res < 0) |
@@ -364,11 +369,11 @@ et61x251_i2c_raw_write(struct et61x251_device* cam, u8 n, u8 data1, u8 data2, | |||
364 | if (res < 0) | 369 | if (res < 0) |
365 | err += res; | 370 | err += res; |
366 | 371 | ||
367 | err += et61x251_i2c_wait(cam, cam->sensor); | 372 | err += et61x251_i2c_wait(cam, &cam->sensor); |
368 | 373 | ||
369 | if (err) | 374 | if (err) |
370 | DBG(3, "I2C raw write failed for %s image sensor", | 375 | DBG(3, "I2C raw write failed for %s image sensor", |
371 | cam->sensor->name); | 376 | cam->sensor.name); |
372 | 377 | ||
373 | PDBGG("I2C raw write: %u bytes, address = 0x%02X, data1 = 0x%02X, " | 378 | PDBGG("I2C raw write: %u bytes, address = 0x%02X, data1 = 0x%02X, " |
374 | "data2 = 0x%02X, data3 = 0x%02X, data4 = 0x%02X, data5 = 0x%02X," | 379 | "data2 = 0x%02X, data3 = 0x%02X, data4 = 0x%02X, data5 = 0x%02X," |
@@ -382,19 +387,13 @@ et61x251_i2c_raw_write(struct et61x251_device* cam, u8 n, u8 data1, u8 data2, | |||
382 | 387 | ||
383 | int et61x251_i2c_read(struct et61x251_device* cam, u8 address) | 388 | int et61x251_i2c_read(struct et61x251_device* cam, u8 address) |
384 | { | 389 | { |
385 | if (!cam->sensor) | 390 | return et61x251_i2c_try_read(cam, &cam->sensor, address); |
386 | return -1; | ||
387 | |||
388 | return et61x251_i2c_try_read(cam, cam->sensor, address); | ||
389 | } | 391 | } |
390 | 392 | ||
391 | 393 | ||
392 | int et61x251_i2c_write(struct et61x251_device* cam, u8 address, u8 value) | 394 | int et61x251_i2c_write(struct et61x251_device* cam, u8 address, u8 value) |
393 | { | 395 | { |
394 | if (!cam->sensor) | 396 | return et61x251_i2c_try_write(cam, &cam->sensor, address, value); |
395 | return -1; | ||
396 | |||
397 | return et61x251_i2c_try_write(cam, cam->sensor, address, value); | ||
398 | } | 397 | } |
399 | 398 | ||
400 | /*****************************************************************************/ | 399 | /*****************************************************************************/ |
@@ -417,7 +416,7 @@ static void et61x251_urb_complete(struct urb *urb, struct pt_regs* regs) | |||
417 | if ((*f)) | 416 | if ((*f)) |
418 | (*f)->state = F_QUEUED; | 417 | (*f)->state = F_QUEUED; |
419 | DBG(3, "Stream interrupted"); | 418 | DBG(3, "Stream interrupted"); |
420 | wake_up_interruptible(&cam->wait_stream); | 419 | wake_up(&cam->wait_stream); |
421 | } | 420 | } |
422 | 421 | ||
423 | if (cam->state & DEV_DISCONNECTED) | 422 | if (cam->state & DEV_DISCONNECTED) |
@@ -435,9 +434,9 @@ static void et61x251_urb_complete(struct urb *urb, struct pt_regs* regs) | |||
435 | (*f) = list_entry(cam->inqueue.next, struct et61x251_frame_t, | 434 | (*f) = list_entry(cam->inqueue.next, struct et61x251_frame_t, |
436 | frame); | 435 | frame); |
437 | 436 | ||
438 | imagesize = (cam->sensor->pix_format.width * | 437 | imagesize = (cam->sensor.pix_format.width * |
439 | cam->sensor->pix_format.height * | 438 | cam->sensor.pix_format.height * |
440 | cam->sensor->pix_format.priv) / 8; | 439 | cam->sensor.pix_format.priv) / 8; |
441 | 440 | ||
442 | for (i = 0; i < urb->number_of_packets; i++) { | 441 | for (i = 0; i < urb->number_of_packets; i++) { |
443 | unsigned int len, status; | 442 | unsigned int len, status; |
@@ -476,7 +475,7 @@ start_of_frame: | |||
476 | 475 | ||
477 | if ((*f)->state == F_GRABBING) { | 476 | if ((*f)->state == F_GRABBING) { |
478 | if (sof && (*f)->buf.bytesused) { | 477 | if (sof && (*f)->buf.bytesused) { |
479 | if (cam->sensor->pix_format.pixelformat == | 478 | if (cam->sensor.pix_format.pixelformat == |
480 | V4L2_PIX_FMT_ET61X251) | 479 | V4L2_PIX_FMT_ET61X251) |
481 | goto end_of_frame; | 480 | goto end_of_frame; |
482 | else { | 481 | else { |
@@ -521,7 +520,7 @@ end_of_frame: | |||
521 | goto resubmit_urb; | 520 | goto resubmit_urb; |
522 | 521 | ||
523 | if (sof && | 522 | if (sof && |
524 | cam->sensor->pix_format.pixelformat == | 523 | cam->sensor.pix_format.pixelformat == |
525 | V4L2_PIX_FMT_ET61X251) | 524 | V4L2_PIX_FMT_ET61X251) |
526 | goto start_of_frame; | 525 | goto start_of_frame; |
527 | } | 526 | } |
@@ -650,21 +649,21 @@ static int et61x251_stop_transfer(struct et61x251_device* cam) | |||
650 | 649 | ||
651 | static int et61x251_stream_interrupt(struct et61x251_device* cam) | 650 | static int et61x251_stream_interrupt(struct et61x251_device* cam) |
652 | { | 651 | { |
653 | int err = 0; | 652 | long timeout; |
654 | 653 | ||
655 | cam->stream = STREAM_INTERRUPT; | 654 | cam->stream = STREAM_INTERRUPT; |
656 | err = wait_event_timeout(cam->wait_stream, | 655 | timeout = wait_event_timeout(cam->wait_stream, |
657 | (cam->stream == STREAM_OFF) || | 656 | (cam->stream == STREAM_OFF) || |
658 | (cam->state & DEV_DISCONNECTED), | 657 | (cam->state & DEV_DISCONNECTED), |
659 | ET61X251_URB_TIMEOUT); | 658 | ET61X251_URB_TIMEOUT); |
660 | if (cam->state & DEV_DISCONNECTED) | 659 | if (cam->state & DEV_DISCONNECTED) |
661 | return -ENODEV; | 660 | return -ENODEV; |
662 | else if (err) { | 661 | else if (cam->stream != STREAM_OFF) { |
663 | cam->state |= DEV_MISCONFIGURED; | 662 | cam->state |= DEV_MISCONFIGURED; |
664 | DBG(1, "URB timeout reached. The camera is misconfigured. To " | 663 | DBG(1, "URB timeout reached. The camera is misconfigured. To " |
665 | "use it, close and open /dev/video%d again.", | 664 | "use it, close and open /dev/video%d again.", |
666 | cam->v4ldev->minor); | 665 | cam->v4ldev->minor); |
667 | return err; | 666 | return -EIO; |
668 | } | 667 | } |
669 | 668 | ||
670 | return 0; | 669 | return 0; |
@@ -709,18 +708,18 @@ static ssize_t et61x251_show_reg(struct class_device* cd, char* buf) | |||
709 | struct et61x251_device* cam; | 708 | struct et61x251_device* cam; |
710 | ssize_t count; | 709 | ssize_t count; |
711 | 710 | ||
712 | if (down_interruptible(&et61x251_sysfs_lock)) | 711 | if (mutex_lock_interruptible(&et61x251_sysfs_lock)) |
713 | return -ERESTARTSYS; | 712 | return -ERESTARTSYS; |
714 | 713 | ||
715 | cam = video_get_drvdata(to_video_device(cd)); | 714 | cam = video_get_drvdata(to_video_device(cd)); |
716 | if (!cam) { | 715 | if (!cam) { |
717 | up(&et61x251_sysfs_lock); | 716 | mutex_unlock(&et61x251_sysfs_lock); |
718 | return -ENODEV; | 717 | return -ENODEV; |
719 | } | 718 | } |
720 | 719 | ||
721 | count = sprintf(buf, "%u\n", cam->sysfs.reg); | 720 | count = sprintf(buf, "%u\n", cam->sysfs.reg); |
722 | 721 | ||
723 | up(&et61x251_sysfs_lock); | 722 | mutex_unlock(&et61x251_sysfs_lock); |
724 | 723 | ||
725 | return count; | 724 | return count; |
726 | } | 725 | } |
@@ -733,18 +732,18 @@ et61x251_store_reg(struct class_device* cd, const char* buf, size_t len) | |||
733 | u8 index; | 732 | u8 index; |
734 | ssize_t count; | 733 | ssize_t count; |
735 | 734 | ||
736 | if (down_interruptible(&et61x251_sysfs_lock)) | 735 | if (mutex_lock_interruptible(&et61x251_sysfs_lock)) |
737 | return -ERESTARTSYS; | 736 | return -ERESTARTSYS; |
738 | 737 | ||
739 | cam = video_get_drvdata(to_video_device(cd)); | 738 | cam = video_get_drvdata(to_video_device(cd)); |
740 | if (!cam) { | 739 | if (!cam) { |
741 | up(&et61x251_sysfs_lock); | 740 | mutex_unlock(&et61x251_sysfs_lock); |
742 | return -ENODEV; | 741 | return -ENODEV; |
743 | } | 742 | } |
744 | 743 | ||
745 | index = et61x251_strtou8(buf, len, &count); | 744 | index = et61x251_strtou8(buf, len, &count); |
746 | if (index > 0x8e || !count) { | 745 | if (index > 0x8e || !count) { |
747 | up(&et61x251_sysfs_lock); | 746 | mutex_unlock(&et61x251_sysfs_lock); |
748 | return -EINVAL; | 747 | return -EINVAL; |
749 | } | 748 | } |
750 | 749 | ||
@@ -753,7 +752,7 @@ et61x251_store_reg(struct class_device* cd, const char* buf, size_t len) | |||
753 | DBG(2, "Moved ET61X[12]51 register index to 0x%02X", cam->sysfs.reg); | 752 | DBG(2, "Moved ET61X[12]51 register index to 0x%02X", cam->sysfs.reg); |
754 | DBG(3, "Written bytes: %zd", count); | 753 | DBG(3, "Written bytes: %zd", count); |
755 | 754 | ||
756 | up(&et61x251_sysfs_lock); | 755 | mutex_unlock(&et61x251_sysfs_lock); |
757 | 756 | ||
758 | return count; | 757 | return count; |
759 | } | 758 | } |
@@ -765,17 +764,17 @@ static ssize_t et61x251_show_val(struct class_device* cd, char* buf) | |||
765 | ssize_t count; | 764 | ssize_t count; |
766 | int val; | 765 | int val; |
767 | 766 | ||
768 | if (down_interruptible(&et61x251_sysfs_lock)) | 767 | if (mutex_lock_interruptible(&et61x251_sysfs_lock)) |
769 | return -ERESTARTSYS; | 768 | return -ERESTARTSYS; |
770 | 769 | ||
771 | cam = video_get_drvdata(to_video_device(cd)); | 770 | cam = video_get_drvdata(to_video_device(cd)); |
772 | if (!cam) { | 771 | if (!cam) { |
773 | up(&et61x251_sysfs_lock); | 772 | mutex_unlock(&et61x251_sysfs_lock); |
774 | return -ENODEV; | 773 | return -ENODEV; |
775 | } | 774 | } |
776 | 775 | ||
777 | if ((val = et61x251_read_reg(cam, cam->sysfs.reg)) < 0) { | 776 | if ((val = et61x251_read_reg(cam, cam->sysfs.reg)) < 0) { |
778 | up(&et61x251_sysfs_lock); | 777 | mutex_unlock(&et61x251_sysfs_lock); |
779 | return -EIO; | 778 | return -EIO; |
780 | } | 779 | } |
781 | 780 | ||
@@ -783,7 +782,7 @@ static ssize_t et61x251_show_val(struct class_device* cd, char* buf) | |||
783 | 782 | ||
784 | DBG(3, "Read bytes: %zd", count); | 783 | DBG(3, "Read bytes: %zd", count); |
785 | 784 | ||
786 | up(&et61x251_sysfs_lock); | 785 | mutex_unlock(&et61x251_sysfs_lock); |
787 | 786 | ||
788 | return count; | 787 | return count; |
789 | } | 788 | } |
@@ -797,24 +796,24 @@ et61x251_store_val(struct class_device* cd, const char* buf, size_t len) | |||
797 | ssize_t count; | 796 | ssize_t count; |
798 | int err; | 797 | int err; |
799 | 798 | ||
800 | if (down_interruptible(&et61x251_sysfs_lock)) | 799 | if (mutex_lock_interruptible(&et61x251_sysfs_lock)) |
801 | return -ERESTARTSYS; | 800 | return -ERESTARTSYS; |
802 | 801 | ||
803 | cam = video_get_drvdata(to_video_device(cd)); | 802 | cam = video_get_drvdata(to_video_device(cd)); |
804 | if (!cam) { | 803 | if (!cam) { |
805 | up(&et61x251_sysfs_lock); | 804 | mutex_unlock(&et61x251_sysfs_lock); |
806 | return -ENODEV; | 805 | return -ENODEV; |
807 | } | 806 | } |
808 | 807 | ||
809 | value = et61x251_strtou8(buf, len, &count); | 808 | value = et61x251_strtou8(buf, len, &count); |
810 | if (!count) { | 809 | if (!count) { |
811 | up(&et61x251_sysfs_lock); | 810 | mutex_unlock(&et61x251_sysfs_lock); |
812 | return -EINVAL; | 811 | return -EINVAL; |
813 | } | 812 | } |
814 | 813 | ||
815 | err = et61x251_write_reg(cam, value, cam->sysfs.reg); | 814 | err = et61x251_write_reg(cam, value, cam->sysfs.reg); |
816 | if (err) { | 815 | if (err) { |
817 | up(&et61x251_sysfs_lock); | 816 | mutex_unlock(&et61x251_sysfs_lock); |
818 | return -EIO; | 817 | return -EIO; |
819 | } | 818 | } |
820 | 819 | ||
@@ -822,7 +821,7 @@ et61x251_store_val(struct class_device* cd, const char* buf, size_t len) | |||
822 | cam->sysfs.reg, value); | 821 | cam->sysfs.reg, value); |
823 | DBG(3, "Written bytes: %zd", count); | 822 | DBG(3, "Written bytes: %zd", count); |
824 | 823 | ||
825 | up(&et61x251_sysfs_lock); | 824 | mutex_unlock(&et61x251_sysfs_lock); |
826 | 825 | ||
827 | return count; | 826 | return count; |
828 | } | 827 | } |
@@ -833,12 +832,12 @@ static ssize_t et61x251_show_i2c_reg(struct class_device* cd, char* buf) | |||
833 | struct et61x251_device* cam; | 832 | struct et61x251_device* cam; |
834 | ssize_t count; | 833 | ssize_t count; |
835 | 834 | ||
836 | if (down_interruptible(&et61x251_sysfs_lock)) | 835 | if (mutex_lock_interruptible(&et61x251_sysfs_lock)) |
837 | return -ERESTARTSYS; | 836 | return -ERESTARTSYS; |
838 | 837 | ||
839 | cam = video_get_drvdata(to_video_device(cd)); | 838 | cam = video_get_drvdata(to_video_device(cd)); |
840 | if (!cam) { | 839 | if (!cam) { |
841 | up(&et61x251_sysfs_lock); | 840 | mutex_unlock(&et61x251_sysfs_lock); |
842 | return -ENODEV; | 841 | return -ENODEV; |
843 | } | 842 | } |
844 | 843 | ||
@@ -846,7 +845,7 @@ static ssize_t et61x251_show_i2c_reg(struct class_device* cd, char* buf) | |||
846 | 845 | ||
847 | DBG(3, "Read bytes: %zd", count); | 846 | DBG(3, "Read bytes: %zd", count); |
848 | 847 | ||
849 | up(&et61x251_sysfs_lock); | 848 | mutex_unlock(&et61x251_sysfs_lock); |
850 | 849 | ||
851 | return count; | 850 | return count; |
852 | } | 851 | } |
@@ -859,18 +858,18 @@ et61x251_store_i2c_reg(struct class_device* cd, const char* buf, size_t len) | |||
859 | u8 index; | 858 | u8 index; |
860 | ssize_t count; | 859 | ssize_t count; |
861 | 860 | ||
862 | if (down_interruptible(&et61x251_sysfs_lock)) | 861 | if (mutex_lock_interruptible(&et61x251_sysfs_lock)) |
863 | return -ERESTARTSYS; | 862 | return -ERESTARTSYS; |
864 | 863 | ||
865 | cam = video_get_drvdata(to_video_device(cd)); | 864 | cam = video_get_drvdata(to_video_device(cd)); |
866 | if (!cam) { | 865 | if (!cam) { |
867 | up(&et61x251_sysfs_lock); | 866 | mutex_unlock(&et61x251_sysfs_lock); |
868 | return -ENODEV; | 867 | return -ENODEV; |
869 | } | 868 | } |
870 | 869 | ||
871 | index = et61x251_strtou8(buf, len, &count); | 870 | index = et61x251_strtou8(buf, len, &count); |
872 | if (!count) { | 871 | if (!count) { |
873 | up(&et61x251_sysfs_lock); | 872 | mutex_unlock(&et61x251_sysfs_lock); |
874 | return -EINVAL; | 873 | return -EINVAL; |
875 | } | 874 | } |
876 | 875 | ||
@@ -879,7 +878,7 @@ et61x251_store_i2c_reg(struct class_device* cd, const char* buf, size_t len) | |||
879 | DBG(2, "Moved sensor register index to 0x%02X", cam->sysfs.i2c_reg); | 878 | DBG(2, "Moved sensor register index to 0x%02X", cam->sysfs.i2c_reg); |
880 | DBG(3, "Written bytes: %zd", count); | 879 | DBG(3, "Written bytes: %zd", count); |
881 | 880 | ||
882 | up(&et61x251_sysfs_lock); | 881 | mutex_unlock(&et61x251_sysfs_lock); |
883 | 882 | ||
884 | return count; | 883 | return count; |
885 | } | 884 | } |
@@ -891,22 +890,22 @@ static ssize_t et61x251_show_i2c_val(struct class_device* cd, char* buf) | |||
891 | ssize_t count; | 890 | ssize_t count; |
892 | int val; | 891 | int val; |
893 | 892 | ||
894 | if (down_interruptible(&et61x251_sysfs_lock)) | 893 | if (mutex_lock_interruptible(&et61x251_sysfs_lock)) |
895 | return -ERESTARTSYS; | 894 | return -ERESTARTSYS; |
896 | 895 | ||
897 | cam = video_get_drvdata(to_video_device(cd)); | 896 | cam = video_get_drvdata(to_video_device(cd)); |
898 | if (!cam) { | 897 | if (!cam) { |
899 | up(&et61x251_sysfs_lock); | 898 | mutex_unlock(&et61x251_sysfs_lock); |
900 | return -ENODEV; | 899 | return -ENODEV; |
901 | } | 900 | } |
902 | 901 | ||
903 | if (!(cam->sensor->sysfs_ops & ET61X251_I2C_READ)) { | 902 | if (!(cam->sensor.sysfs_ops & ET61X251_I2C_READ)) { |
904 | up(&et61x251_sysfs_lock); | 903 | mutex_unlock(&et61x251_sysfs_lock); |
905 | return -ENOSYS; | 904 | return -ENOSYS; |
906 | } | 905 | } |
907 | 906 | ||
908 | if ((val = et61x251_i2c_read(cam, cam->sysfs.i2c_reg)) < 0) { | 907 | if ((val = et61x251_i2c_read(cam, cam->sysfs.i2c_reg)) < 0) { |
909 | up(&et61x251_sysfs_lock); | 908 | mutex_unlock(&et61x251_sysfs_lock); |
910 | return -EIO; | 909 | return -EIO; |
911 | } | 910 | } |
912 | 911 | ||
@@ -914,7 +913,7 @@ static ssize_t et61x251_show_i2c_val(struct class_device* cd, char* buf) | |||
914 | 913 | ||
915 | DBG(3, "Read bytes: %zd", count); | 914 | DBG(3, "Read bytes: %zd", count); |
916 | 915 | ||
917 | up(&et61x251_sysfs_lock); | 916 | mutex_unlock(&et61x251_sysfs_lock); |
918 | 917 | ||
919 | return count; | 918 | return count; |
920 | } | 919 | } |
@@ -928,29 +927,29 @@ et61x251_store_i2c_val(struct class_device* cd, const char* buf, size_t len) | |||
928 | ssize_t count; | 927 | ssize_t count; |
929 | int err; | 928 | int err; |
930 | 929 | ||
931 | if (down_interruptible(&et61x251_sysfs_lock)) | 930 | if (mutex_lock_interruptible(&et61x251_sysfs_lock)) |
932 | return -ERESTARTSYS; | 931 | return -ERESTARTSYS; |
933 | 932 | ||
934 | cam = video_get_drvdata(to_video_device(cd)); | 933 | cam = video_get_drvdata(to_video_device(cd)); |
935 | if (!cam) { | 934 | if (!cam) { |
936 | up(&et61x251_sysfs_lock); | 935 | mutex_unlock(&et61x251_sysfs_lock); |
937 | return -ENODEV; | 936 | return -ENODEV; |
938 | } | 937 | } |
939 | 938 | ||
940 | if (!(cam->sensor->sysfs_ops & ET61X251_I2C_READ)) { | 939 | if (!(cam->sensor.sysfs_ops & ET61X251_I2C_READ)) { |
941 | up(&et61x251_sysfs_lock); | 940 | mutex_unlock(&et61x251_sysfs_lock); |
942 | return -ENOSYS; | 941 | return -ENOSYS; |
943 | } | 942 | } |
944 | 943 | ||
945 | value = et61x251_strtou8(buf, len, &count); | 944 | value = et61x251_strtou8(buf, len, &count); |
946 | if (!count) { | 945 | if (!count) { |
947 | up(&et61x251_sysfs_lock); | 946 | mutex_unlock(&et61x251_sysfs_lock); |
948 | return -EINVAL; | 947 | return -EINVAL; |
949 | } | 948 | } |
950 | 949 | ||
951 | err = et61x251_i2c_write(cam, cam->sysfs.i2c_reg, value); | 950 | err = et61x251_i2c_write(cam, cam->sysfs.i2c_reg, value); |
952 | if (err) { | 951 | if (err) { |
953 | up(&et61x251_sysfs_lock); | 952 | mutex_unlock(&et61x251_sysfs_lock); |
954 | return -EIO; | 953 | return -EIO; |
955 | } | 954 | } |
956 | 955 | ||
@@ -958,7 +957,7 @@ et61x251_store_i2c_val(struct class_device* cd, const char* buf, size_t len) | |||
958 | cam->sysfs.i2c_reg, value); | 957 | cam->sysfs.i2c_reg, value); |
959 | DBG(3, "Written bytes: %zd", count); | 958 | DBG(3, "Written bytes: %zd", count); |
960 | 959 | ||
961 | up(&et61x251_sysfs_lock); | 960 | mutex_unlock(&et61x251_sysfs_lock); |
962 | 961 | ||
963 | return count; | 962 | return count; |
964 | } | 963 | } |
@@ -980,7 +979,7 @@ static void et61x251_create_sysfs(struct et61x251_device* cam) | |||
980 | 979 | ||
981 | video_device_create_file(v4ldev, &class_device_attr_reg); | 980 | video_device_create_file(v4ldev, &class_device_attr_reg); |
982 | video_device_create_file(v4ldev, &class_device_attr_val); | 981 | video_device_create_file(v4ldev, &class_device_attr_val); |
983 | if (cam->sensor && cam->sensor->sysfs_ops) { | 982 | if (cam->sensor.sysfs_ops) { |
984 | video_device_create_file(v4ldev, &class_device_attr_i2c_reg); | 983 | video_device_create_file(v4ldev, &class_device_attr_i2c_reg); |
985 | video_device_create_file(v4ldev, &class_device_attr_i2c_val); | 984 | video_device_create_file(v4ldev, &class_device_attr_i2c_val); |
986 | } | 985 | } |
@@ -1048,7 +1047,7 @@ static int et61x251_set_scale(struct et61x251_device* cam, u8 scale) | |||
1048 | static int | 1047 | static int |
1049 | et61x251_set_crop(struct et61x251_device* cam, struct v4l2_rect* rect) | 1048 | et61x251_set_crop(struct et61x251_device* cam, struct v4l2_rect* rect) |
1050 | { | 1049 | { |
1051 | struct et61x251_sensor* s = cam->sensor; | 1050 | struct et61x251_sensor* s = &cam->sensor; |
1052 | u16 fmw_sx = (u16)(rect->left - s->cropcap.bounds.left + | 1051 | u16 fmw_sx = (u16)(rect->left - s->cropcap.bounds.left + |
1053 | s->active_pixel.left), | 1052 | s->active_pixel.left), |
1054 | fmw_sy = (u16)(rect->top - s->cropcap.bounds.top + | 1053 | fmw_sy = (u16)(rect->top - s->cropcap.bounds.top + |
@@ -1076,7 +1075,7 @@ et61x251_set_crop(struct et61x251_device* cam, struct v4l2_rect* rect) | |||
1076 | 1075 | ||
1077 | static int et61x251_init(struct et61x251_device* cam) | 1076 | static int et61x251_init(struct et61x251_device* cam) |
1078 | { | 1077 | { |
1079 | struct et61x251_sensor* s = cam->sensor; | 1078 | struct et61x251_sensor* s = &cam->sensor; |
1080 | struct v4l2_control ctrl; | 1079 | struct v4l2_control ctrl; |
1081 | struct v4l2_queryctrl *qctrl; | 1080 | struct v4l2_queryctrl *qctrl; |
1082 | struct v4l2_rect* rect; | 1081 | struct v4l2_rect* rect; |
@@ -1143,7 +1142,7 @@ static int et61x251_init(struct et61x251_device* cam) | |||
1143 | } | 1142 | } |
1144 | 1143 | ||
1145 | if (!(cam->state & DEV_INITIALIZED)) { | 1144 | if (!(cam->state & DEV_INITIALIZED)) { |
1146 | init_MUTEX(&cam->fileop_sem); | 1145 | mutex_init(&cam->fileop_mutex); |
1147 | spin_lock_init(&cam->queue_lock); | 1146 | spin_lock_init(&cam->queue_lock); |
1148 | init_waitqueue_head(&cam->wait_frame); | 1147 | init_waitqueue_head(&cam->wait_frame); |
1149 | init_waitqueue_head(&cam->wait_stream); | 1148 | init_waitqueue_head(&cam->wait_stream); |
@@ -1161,13 +1160,15 @@ static int et61x251_init(struct et61x251_device* cam) | |||
1161 | 1160 | ||
1162 | static void et61x251_release_resources(struct et61x251_device* cam) | 1161 | static void et61x251_release_resources(struct et61x251_device* cam) |
1163 | { | 1162 | { |
1164 | down(&et61x251_sysfs_lock); | 1163 | mutex_lock(&et61x251_sysfs_lock); |
1165 | 1164 | ||
1166 | DBG(2, "V4L2 device /dev/video%d deregistered", cam->v4ldev->minor); | 1165 | DBG(2, "V4L2 device /dev/video%d deregistered", cam->v4ldev->minor); |
1167 | video_set_drvdata(cam->v4ldev, NULL); | 1166 | video_set_drvdata(cam->v4ldev, NULL); |
1168 | video_unregister_device(cam->v4ldev); | 1167 | video_unregister_device(cam->v4ldev); |
1169 | 1168 | ||
1170 | up(&et61x251_sysfs_lock); | 1169 | usb_put_dev(cam->usbdev); |
1170 | |||
1171 | mutex_unlock(&et61x251_sysfs_lock); | ||
1171 | 1172 | ||
1172 | kfree(cam->control_buffer); | 1173 | kfree(cam->control_buffer); |
1173 | } | 1174 | } |
@@ -1188,7 +1189,7 @@ static int et61x251_open(struct inode* inode, struct file* filp) | |||
1188 | 1189 | ||
1189 | cam = video_get_drvdata(video_devdata(filp)); | 1190 | cam = video_get_drvdata(video_devdata(filp)); |
1190 | 1191 | ||
1191 | if (down_interruptible(&cam->dev_sem)) { | 1192 | if (mutex_lock_interruptible(&cam->dev_mutex)) { |
1192 | up_read(&et61x251_disconnect); | 1193 | up_read(&et61x251_disconnect); |
1193 | return -ERESTARTSYS; | 1194 | return -ERESTARTSYS; |
1194 | } | 1195 | } |
@@ -1200,7 +1201,7 @@ static int et61x251_open(struct inode* inode, struct file* filp) | |||
1200 | err = -EWOULDBLOCK; | 1201 | err = -EWOULDBLOCK; |
1201 | goto out; | 1202 | goto out; |
1202 | } | 1203 | } |
1203 | up(&cam->dev_sem); | 1204 | mutex_unlock(&cam->dev_mutex); |
1204 | err = wait_event_interruptible_exclusive(cam->open, | 1205 | err = wait_event_interruptible_exclusive(cam->open, |
1205 | cam->state & DEV_DISCONNECTED | 1206 | cam->state & DEV_DISCONNECTED |
1206 | || !cam->users); | 1207 | || !cam->users); |
@@ -1212,7 +1213,7 @@ static int et61x251_open(struct inode* inode, struct file* filp) | |||
1212 | up_read(&et61x251_disconnect); | 1213 | up_read(&et61x251_disconnect); |
1213 | return -ENODEV; | 1214 | return -ENODEV; |
1214 | } | 1215 | } |
1215 | down(&cam->dev_sem); | 1216 | mutex_lock(&cam->dev_mutex); |
1216 | } | 1217 | } |
1217 | 1218 | ||
1218 | 1219 | ||
@@ -1240,7 +1241,7 @@ static int et61x251_open(struct inode* inode, struct file* filp) | |||
1240 | DBG(3, "Video device /dev/video%d is open", cam->v4ldev->minor); | 1241 | DBG(3, "Video device /dev/video%d is open", cam->v4ldev->minor); |
1241 | 1242 | ||
1242 | out: | 1243 | out: |
1243 | up(&cam->dev_sem); | 1244 | mutex_unlock(&cam->dev_mutex); |
1244 | up_read(&et61x251_disconnect); | 1245 | up_read(&et61x251_disconnect); |
1245 | return err; | 1246 | return err; |
1246 | } | 1247 | } |
@@ -1250,7 +1251,7 @@ static int et61x251_release(struct inode* inode, struct file* filp) | |||
1250 | { | 1251 | { |
1251 | struct et61x251_device* cam = video_get_drvdata(video_devdata(filp)); | 1252 | struct et61x251_device* cam = video_get_drvdata(video_devdata(filp)); |
1252 | 1253 | ||
1253 | down(&cam->dev_sem); /* prevent disconnect() to be called */ | 1254 | mutex_lock(&cam->dev_mutex); /* prevent disconnect() to be called */ |
1254 | 1255 | ||
1255 | et61x251_stop_transfer(cam); | 1256 | et61x251_stop_transfer(cam); |
1256 | 1257 | ||
@@ -1258,7 +1259,7 @@ static int et61x251_release(struct inode* inode, struct file* filp) | |||
1258 | 1259 | ||
1259 | if (cam->state & DEV_DISCONNECTED) { | 1260 | if (cam->state & DEV_DISCONNECTED) { |
1260 | et61x251_release_resources(cam); | 1261 | et61x251_release_resources(cam); |
1261 | up(&cam->dev_sem); | 1262 | mutex_unlock(&cam->dev_mutex); |
1262 | kfree(cam); | 1263 | kfree(cam); |
1263 | return 0; | 1264 | return 0; |
1264 | } | 1265 | } |
@@ -1268,7 +1269,7 @@ static int et61x251_release(struct inode* inode, struct file* filp) | |||
1268 | 1269 | ||
1269 | DBG(3, "Video device /dev/video%d closed", cam->v4ldev->minor); | 1270 | DBG(3, "Video device /dev/video%d closed", cam->v4ldev->minor); |
1270 | 1271 | ||
1271 | up(&cam->dev_sem); | 1272 | mutex_unlock(&cam->dev_mutex); |
1272 | 1273 | ||
1273 | return 0; | 1274 | return 0; |
1274 | } | 1275 | } |
@@ -1281,28 +1282,29 @@ et61x251_read(struct file* filp, char __user * buf, | |||
1281 | struct et61x251_device* cam = video_get_drvdata(video_devdata(filp)); | 1282 | struct et61x251_device* cam = video_get_drvdata(video_devdata(filp)); |
1282 | struct et61x251_frame_t* f, * i; | 1283 | struct et61x251_frame_t* f, * i; |
1283 | unsigned long lock_flags; | 1284 | unsigned long lock_flags; |
1285 | long timeout; | ||
1284 | int err = 0; | 1286 | int err = 0; |
1285 | 1287 | ||
1286 | if (down_interruptible(&cam->fileop_sem)) | 1288 | if (mutex_lock_interruptible(&cam->fileop_mutex)) |
1287 | return -ERESTARTSYS; | 1289 | return -ERESTARTSYS; |
1288 | 1290 | ||
1289 | if (cam->state & DEV_DISCONNECTED) { | 1291 | if (cam->state & DEV_DISCONNECTED) { |
1290 | DBG(1, "Device not present"); | 1292 | DBG(1, "Device not present"); |
1291 | up(&cam->fileop_sem); | 1293 | mutex_unlock(&cam->fileop_mutex); |
1292 | return -ENODEV; | 1294 | return -ENODEV; |
1293 | } | 1295 | } |
1294 | 1296 | ||
1295 | if (cam->state & DEV_MISCONFIGURED) { | 1297 | if (cam->state & DEV_MISCONFIGURED) { |
1296 | DBG(1, "The camera is misconfigured. Close and open it " | 1298 | DBG(1, "The camera is misconfigured. Close and open it " |
1297 | "again."); | 1299 | "again."); |
1298 | up(&cam->fileop_sem); | 1300 | mutex_unlock(&cam->fileop_mutex); |
1299 | return -EIO; | 1301 | return -EIO; |
1300 | } | 1302 | } |
1301 | 1303 | ||
1302 | if (cam->io == IO_MMAP) { | 1304 | if (cam->io == IO_MMAP) { |
1303 | DBG(3, "Close and open the device again to choose the read " | 1305 | DBG(3, "Close and open the device again to choose the read " |
1304 | "method"); | 1306 | "method"); |
1305 | up(&cam->fileop_sem); | 1307 | mutex_unlock(&cam->fileop_mutex); |
1306 | return -EINVAL; | 1308 | return -EINVAL; |
1307 | } | 1309 | } |
1308 | 1310 | ||
@@ -1310,7 +1312,7 @@ et61x251_read(struct file* filp, char __user * buf, | |||
1310 | if (!et61x251_request_buffers(cam, cam->nreadbuffers, | 1312 | if (!et61x251_request_buffers(cam, cam->nreadbuffers, |
1311 | IO_READ)) { | 1313 | IO_READ)) { |
1312 | DBG(1, "read() failed, not enough memory"); | 1314 | DBG(1, "read() failed, not enough memory"); |
1313 | up(&cam->fileop_sem); | 1315 | mutex_unlock(&cam->fileop_mutex); |
1314 | return -ENOMEM; | 1316 | return -ENOMEM; |
1315 | } | 1317 | } |
1316 | cam->io = IO_READ; | 1318 | cam->io = IO_READ; |
@@ -1324,30 +1326,32 @@ et61x251_read(struct file* filp, char __user * buf, | |||
1324 | } | 1326 | } |
1325 | 1327 | ||
1326 | if (!count) { | 1328 | if (!count) { |
1327 | up(&cam->fileop_sem); | 1329 | mutex_unlock(&cam->fileop_mutex); |
1328 | return 0; | 1330 | return 0; |
1329 | } | 1331 | } |
1330 | 1332 | ||
1331 | if (list_empty(&cam->outqueue)) { | 1333 | if (list_empty(&cam->outqueue)) { |
1332 | if (filp->f_flags & O_NONBLOCK) { | 1334 | if (filp->f_flags & O_NONBLOCK) { |
1333 | up(&cam->fileop_sem); | 1335 | mutex_unlock(&cam->fileop_mutex); |
1334 | return -EAGAIN; | 1336 | return -EAGAIN; |
1335 | } | 1337 | } |
1336 | err = wait_event_interruptible | 1338 | timeout = wait_event_interruptible_timeout |
1337 | ( cam->wait_frame, | 1339 | ( cam->wait_frame, |
1338 | (!list_empty(&cam->outqueue)) || | 1340 | (!list_empty(&cam->outqueue)) || |
1339 | (cam->state & DEV_DISCONNECTED) || | 1341 | (cam->state & DEV_DISCONNECTED) || |
1340 | (cam->state & DEV_MISCONFIGURED) ); | 1342 | (cam->state & DEV_MISCONFIGURED), |
1341 | if (err) { | 1343 | cam->module_param.frame_timeout * |
1342 | up(&cam->fileop_sem); | 1344 | 1000 * msecs_to_jiffies(1) ); |
1343 | return err; | 1345 | if (timeout < 0) { |
1346 | mutex_unlock(&cam->fileop_mutex); | ||
1347 | return timeout; | ||
1344 | } | 1348 | } |
1345 | if (cam->state & DEV_DISCONNECTED) { | 1349 | if (cam->state & DEV_DISCONNECTED) { |
1346 | up(&cam->fileop_sem); | 1350 | mutex_unlock(&cam->fileop_mutex); |
1347 | return -ENODEV; | 1351 | return -ENODEV; |
1348 | } | 1352 | } |
1349 | if (cam->state & DEV_MISCONFIGURED) { | 1353 | if (!timeout || (cam->state & DEV_MISCONFIGURED)) { |
1350 | up(&cam->fileop_sem); | 1354 | mutex_unlock(&cam->fileop_mutex); |
1351 | return -EIO; | 1355 | return -EIO; |
1352 | } | 1356 | } |
1353 | } | 1357 | } |
@@ -1375,7 +1379,7 @@ exit: | |||
1375 | PDBGG("Frame #%lu, bytes read: %zu", | 1379 | PDBGG("Frame #%lu, bytes read: %zu", |
1376 | (unsigned long)f->buf.index, count); | 1380 | (unsigned long)f->buf.index, count); |
1377 | 1381 | ||
1378 | up(&cam->fileop_sem); | 1382 | mutex_unlock(&cam->fileop_mutex); |
1379 | 1383 | ||
1380 | return err ? err : count; | 1384 | return err ? err : count; |
1381 | } | 1385 | } |
@@ -1388,7 +1392,7 @@ static unsigned int et61x251_poll(struct file *filp, poll_table *wait) | |||
1388 | unsigned long lock_flags; | 1392 | unsigned long lock_flags; |
1389 | unsigned int mask = 0; | 1393 | unsigned int mask = 0; |
1390 | 1394 | ||
1391 | if (down_interruptible(&cam->fileop_sem)) | 1395 | if (mutex_lock_interruptible(&cam->fileop_mutex)) |
1392 | return POLLERR; | 1396 | return POLLERR; |
1393 | 1397 | ||
1394 | if (cam->state & DEV_DISCONNECTED) { | 1398 | if (cam->state & DEV_DISCONNECTED) { |
@@ -1426,12 +1430,12 @@ static unsigned int et61x251_poll(struct file *filp, poll_table *wait) | |||
1426 | if (!list_empty(&cam->outqueue)) | 1430 | if (!list_empty(&cam->outqueue)) |
1427 | mask |= POLLIN | POLLRDNORM; | 1431 | mask |= POLLIN | POLLRDNORM; |
1428 | 1432 | ||
1429 | up(&cam->fileop_sem); | 1433 | mutex_unlock(&cam->fileop_mutex); |
1430 | 1434 | ||
1431 | return mask; | 1435 | return mask; |
1432 | 1436 | ||
1433 | error: | 1437 | error: |
1434 | up(&cam->fileop_sem); | 1438 | mutex_unlock(&cam->fileop_mutex); |
1435 | return POLLERR; | 1439 | return POLLERR; |
1436 | } | 1440 | } |
1437 | 1441 | ||
@@ -1465,25 +1469,25 @@ static int et61x251_mmap(struct file* filp, struct vm_area_struct *vma) | |||
1465 | void *pos; | 1469 | void *pos; |
1466 | u32 i; | 1470 | u32 i; |
1467 | 1471 | ||
1468 | if (down_interruptible(&cam->fileop_sem)) | 1472 | if (mutex_lock_interruptible(&cam->fileop_mutex)) |
1469 | return -ERESTARTSYS; | 1473 | return -ERESTARTSYS; |
1470 | 1474 | ||
1471 | if (cam->state & DEV_DISCONNECTED) { | 1475 | if (cam->state & DEV_DISCONNECTED) { |
1472 | DBG(1, "Device not present"); | 1476 | DBG(1, "Device not present"); |
1473 | up(&cam->fileop_sem); | 1477 | mutex_unlock(&cam->fileop_mutex); |
1474 | return -ENODEV; | 1478 | return -ENODEV; |
1475 | } | 1479 | } |
1476 | 1480 | ||
1477 | if (cam->state & DEV_MISCONFIGURED) { | 1481 | if (cam->state & DEV_MISCONFIGURED) { |
1478 | DBG(1, "The camera is misconfigured. Close and open it " | 1482 | DBG(1, "The camera is misconfigured. Close and open it " |
1479 | "again."); | 1483 | "again."); |
1480 | up(&cam->fileop_sem); | 1484 | mutex_unlock(&cam->fileop_mutex); |
1481 | return -EIO; | 1485 | return -EIO; |
1482 | } | 1486 | } |
1483 | 1487 | ||
1484 | if (cam->io != IO_MMAP || !(vma->vm_flags & VM_WRITE) || | 1488 | if (cam->io != IO_MMAP || !(vma->vm_flags & VM_WRITE) || |
1485 | size != PAGE_ALIGN(cam->frame[0].buf.length)) { | 1489 | size != PAGE_ALIGN(cam->frame[0].buf.length)) { |
1486 | up(&cam->fileop_sem); | 1490 | mutex_unlock(&cam->fileop_mutex); |
1487 | return -EINVAL; | 1491 | return -EINVAL; |
1488 | } | 1492 | } |
1489 | 1493 | ||
@@ -1492,7 +1496,7 @@ static int et61x251_mmap(struct file* filp, struct vm_area_struct *vma) | |||
1492 | break; | 1496 | break; |
1493 | } | 1497 | } |
1494 | if (i == cam->nbuffers) { | 1498 | if (i == cam->nbuffers) { |
1495 | up(&cam->fileop_sem); | 1499 | mutex_unlock(&cam->fileop_mutex); |
1496 | return -EINVAL; | 1500 | return -EINVAL; |
1497 | } | 1501 | } |
1498 | 1502 | ||
@@ -1502,7 +1506,7 @@ static int et61x251_mmap(struct file* filp, struct vm_area_struct *vma) | |||
1502 | pos = cam->frame[i].bufmem; | 1506 | pos = cam->frame[i].bufmem; |
1503 | while (size > 0) { /* size is page-aligned */ | 1507 | while (size > 0) { /* size is page-aligned */ |
1504 | if (vm_insert_page(vma, start, vmalloc_to_page(pos))) { | 1508 | if (vm_insert_page(vma, start, vmalloc_to_page(pos))) { |
1505 | up(&cam->fileop_sem); | 1509 | mutex_unlock(&cam->fileop_mutex); |
1506 | return -EAGAIN; | 1510 | return -EAGAIN; |
1507 | } | 1511 | } |
1508 | start += PAGE_SIZE; | 1512 | start += PAGE_SIZE; |
@@ -1515,7 +1519,7 @@ static int et61x251_mmap(struct file* filp, struct vm_area_struct *vma) | |||
1515 | 1519 | ||
1516 | et61x251_vm_open(vma); | 1520 | et61x251_vm_open(vma); |
1517 | 1521 | ||
1518 | up(&cam->fileop_sem); | 1522 | mutex_unlock(&cam->fileop_mutex); |
1519 | 1523 | ||
1520 | return 0; | 1524 | return 0; |
1521 | } | 1525 | } |
@@ -1557,6 +1561,7 @@ et61x251_vidioc_enuminput(struct et61x251_device* cam, void __user * arg) | |||
1557 | 1561 | ||
1558 | memset(&i, 0, sizeof(i)); | 1562 | memset(&i, 0, sizeof(i)); |
1559 | strcpy(i.name, "Camera"); | 1563 | strcpy(i.name, "Camera"); |
1564 | i.type = V4L2_INPUT_TYPE_CAMERA; | ||
1560 | 1565 | ||
1561 | if (copy_to_user(arg, &i, sizeof(i))) | 1566 | if (copy_to_user(arg, &i, sizeof(i))) |
1562 | return -EFAULT; | 1567 | return -EFAULT; |
@@ -1566,7 +1571,19 @@ et61x251_vidioc_enuminput(struct et61x251_device* cam, void __user * arg) | |||
1566 | 1571 | ||
1567 | 1572 | ||
1568 | static int | 1573 | static int |
1569 | et61x251_vidioc_gs_input(struct et61x251_device* cam, void __user * arg) | 1574 | et61x251_vidioc_g_input(struct et61x251_device* cam, void __user * arg) |
1575 | { | ||
1576 | int index = 0; | ||
1577 | |||
1578 | if (copy_to_user(arg, &index, sizeof(index))) | ||
1579 | return -EFAULT; | ||
1580 | |||
1581 | return 0; | ||
1582 | } | ||
1583 | |||
1584 | |||
1585 | static int | ||
1586 | et61x251_vidioc_s_input(struct et61x251_device* cam, void __user * arg) | ||
1570 | { | 1587 | { |
1571 | int index; | 1588 | int index; |
1572 | 1589 | ||
@@ -1583,7 +1600,7 @@ et61x251_vidioc_gs_input(struct et61x251_device* cam, void __user * arg) | |||
1583 | static int | 1600 | static int |
1584 | et61x251_vidioc_query_ctrl(struct et61x251_device* cam, void __user * arg) | 1601 | et61x251_vidioc_query_ctrl(struct et61x251_device* cam, void __user * arg) |
1585 | { | 1602 | { |
1586 | struct et61x251_sensor* s = cam->sensor; | 1603 | struct et61x251_sensor* s = &cam->sensor; |
1587 | struct v4l2_queryctrl qc; | 1604 | struct v4l2_queryctrl qc; |
1588 | u8 i; | 1605 | u8 i; |
1589 | 1606 | ||
@@ -1605,7 +1622,7 @@ et61x251_vidioc_query_ctrl(struct et61x251_device* cam, void __user * arg) | |||
1605 | static int | 1622 | static int |
1606 | et61x251_vidioc_g_ctrl(struct et61x251_device* cam, void __user * arg) | 1623 | et61x251_vidioc_g_ctrl(struct et61x251_device* cam, void __user * arg) |
1607 | { | 1624 | { |
1608 | struct et61x251_sensor* s = cam->sensor; | 1625 | struct et61x251_sensor* s = &cam->sensor; |
1609 | struct v4l2_control ctrl; | 1626 | struct v4l2_control ctrl; |
1610 | int err = 0; | 1627 | int err = 0; |
1611 | u8 i; | 1628 | u8 i; |
@@ -1637,7 +1654,7 @@ exit: | |||
1637 | static int | 1654 | static int |
1638 | et61x251_vidioc_s_ctrl(struct et61x251_device* cam, void __user * arg) | 1655 | et61x251_vidioc_s_ctrl(struct et61x251_device* cam, void __user * arg) |
1639 | { | 1656 | { |
1640 | struct et61x251_sensor* s = cam->sensor; | 1657 | struct et61x251_sensor* s = &cam->sensor; |
1641 | struct v4l2_control ctrl; | 1658 | struct v4l2_control ctrl; |
1642 | u8 i; | 1659 | u8 i; |
1643 | int err = 0; | 1660 | int err = 0; |
@@ -1650,6 +1667,8 @@ et61x251_vidioc_s_ctrl(struct et61x251_device* cam, void __user * arg) | |||
1650 | 1667 | ||
1651 | for (i = 0; i < ARRAY_SIZE(s->qctrl); i++) | 1668 | for (i = 0; i < ARRAY_SIZE(s->qctrl); i++) |
1652 | if (ctrl.id == s->qctrl[i].id) { | 1669 | if (ctrl.id == s->qctrl[i].id) { |
1670 | if (s->qctrl[i].flags & V4L2_CTRL_FLAG_DISABLED) | ||
1671 | return -EINVAL; | ||
1653 | if (ctrl.value < s->qctrl[i].minimum || | 1672 | if (ctrl.value < s->qctrl[i].minimum || |
1654 | ctrl.value > s->qctrl[i].maximum) | 1673 | ctrl.value > s->qctrl[i].maximum) |
1655 | return -ERANGE; | 1674 | return -ERANGE; |
@@ -1669,7 +1688,7 @@ et61x251_vidioc_s_ctrl(struct et61x251_device* cam, void __user * arg) | |||
1669 | static int | 1688 | static int |
1670 | et61x251_vidioc_cropcap(struct et61x251_device* cam, void __user * arg) | 1689 | et61x251_vidioc_cropcap(struct et61x251_device* cam, void __user * arg) |
1671 | { | 1690 | { |
1672 | struct v4l2_cropcap* cc = &(cam->sensor->cropcap); | 1691 | struct v4l2_cropcap* cc = &(cam->sensor.cropcap); |
1673 | 1692 | ||
1674 | cc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 1693 | cc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
1675 | cc->pixelaspect.numerator = 1; | 1694 | cc->pixelaspect.numerator = 1; |
@@ -1685,7 +1704,7 @@ et61x251_vidioc_cropcap(struct et61x251_device* cam, void __user * arg) | |||
1685 | static int | 1704 | static int |
1686 | et61x251_vidioc_g_crop(struct et61x251_device* cam, void __user * arg) | 1705 | et61x251_vidioc_g_crop(struct et61x251_device* cam, void __user * arg) |
1687 | { | 1706 | { |
1688 | struct et61x251_sensor* s = cam->sensor; | 1707 | struct et61x251_sensor* s = &cam->sensor; |
1689 | struct v4l2_crop crop = { | 1708 | struct v4l2_crop crop = { |
1690 | .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, | 1709 | .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, |
1691 | }; | 1710 | }; |
@@ -1702,7 +1721,7 @@ et61x251_vidioc_g_crop(struct et61x251_device* cam, void __user * arg) | |||
1702 | static int | 1721 | static int |
1703 | et61x251_vidioc_s_crop(struct et61x251_device* cam, void __user * arg) | 1722 | et61x251_vidioc_s_crop(struct et61x251_device* cam, void __user * arg) |
1704 | { | 1723 | { |
1705 | struct et61x251_sensor* s = cam->sensor; | 1724 | struct et61x251_sensor* s = &cam->sensor; |
1706 | struct v4l2_crop crop; | 1725 | struct v4l2_crop crop; |
1707 | struct v4l2_rect* rect; | 1726 | struct v4l2_rect* rect; |
1708 | struct v4l2_rect* bounds = &(s->cropcap.bounds); | 1727 | struct v4l2_rect* bounds = &(s->cropcap.bounds); |
@@ -1843,7 +1862,7 @@ static int | |||
1843 | et61x251_vidioc_g_fmt(struct et61x251_device* cam, void __user * arg) | 1862 | et61x251_vidioc_g_fmt(struct et61x251_device* cam, void __user * arg) |
1844 | { | 1863 | { |
1845 | struct v4l2_format format; | 1864 | struct v4l2_format format; |
1846 | struct v4l2_pix_format* pfmt = &(cam->sensor->pix_format); | 1865 | struct v4l2_pix_format* pfmt = &(cam->sensor.pix_format); |
1847 | 1866 | ||
1848 | if (copy_from_user(&format, arg, sizeof(format))) | 1867 | if (copy_from_user(&format, arg, sizeof(format))) |
1849 | return -EFAULT; | 1868 | return -EFAULT; |
@@ -1868,7 +1887,7 @@ static int | |||
1868 | et61x251_vidioc_try_s_fmt(struct et61x251_device* cam, unsigned int cmd, | 1887 | et61x251_vidioc_try_s_fmt(struct et61x251_device* cam, unsigned int cmd, |
1869 | void __user * arg) | 1888 | void __user * arg) |
1870 | { | 1889 | { |
1871 | struct et61x251_sensor* s = cam->sensor; | 1890 | struct et61x251_sensor* s = &cam->sensor; |
1872 | struct v4l2_format format; | 1891 | struct v4l2_format format; |
1873 | struct v4l2_pix_format* pix; | 1892 | struct v4l2_pix_format* pix; |
1874 | struct v4l2_pix_format* pfmt = &(s->pix_format); | 1893 | struct v4l2_pix_format* pfmt = &(s->pix_format); |
@@ -2155,7 +2174,7 @@ et61x251_vidioc_dqbuf(struct et61x251_device* cam, struct file* filp, | |||
2155 | struct v4l2_buffer b; | 2174 | struct v4l2_buffer b; |
2156 | struct et61x251_frame_t *f; | 2175 | struct et61x251_frame_t *f; |
2157 | unsigned long lock_flags; | 2176 | unsigned long lock_flags; |
2158 | int err = 0; | 2177 | long timeout; |
2159 | 2178 | ||
2160 | if (copy_from_user(&b, arg, sizeof(b))) | 2179 | if (copy_from_user(&b, arg, sizeof(b))) |
2161 | return -EFAULT; | 2180 | return -EFAULT; |
@@ -2168,16 +2187,18 @@ et61x251_vidioc_dqbuf(struct et61x251_device* cam, struct file* filp, | |||
2168 | return -EINVAL; | 2187 | return -EINVAL; |
2169 | if (filp->f_flags & O_NONBLOCK) | 2188 | if (filp->f_flags & O_NONBLOCK) |
2170 | return -EAGAIN; | 2189 | return -EAGAIN; |
2171 | err = wait_event_interruptible | 2190 | timeout = wait_event_interruptible_timeout |
2172 | ( cam->wait_frame, | 2191 | ( cam->wait_frame, |
2173 | (!list_empty(&cam->outqueue)) || | 2192 | (!list_empty(&cam->outqueue)) || |
2174 | (cam->state & DEV_DISCONNECTED) || | 2193 | (cam->state & DEV_DISCONNECTED) || |
2175 | (cam->state & DEV_MISCONFIGURED) ); | 2194 | (cam->state & DEV_MISCONFIGURED), |
2176 | if (err) | 2195 | cam->module_param.frame_timeout * |
2177 | return err; | 2196 | 1000 * msecs_to_jiffies(1) ); |
2197 | if (timeout < 0) | ||
2198 | return timeout; | ||
2178 | if (cam->state & DEV_DISCONNECTED) | 2199 | if (cam->state & DEV_DISCONNECTED) |
2179 | return -ENODEV; | 2200 | return -ENODEV; |
2180 | if (cam->state & DEV_MISCONFIGURED) | 2201 | if (!timeout || (cam->state & DEV_MISCONFIGURED)) |
2181 | return -EIO; | 2202 | return -EIO; |
2182 | } | 2203 | } |
2183 | 2204 | ||
@@ -2309,8 +2330,10 @@ static int et61x251_ioctl_v4l2(struct inode* inode, struct file* filp, | |||
2309 | return et61x251_vidioc_enuminput(cam, arg); | 2330 | return et61x251_vidioc_enuminput(cam, arg); |
2310 | 2331 | ||
2311 | case VIDIOC_G_INPUT: | 2332 | case VIDIOC_G_INPUT: |
2333 | return et61x251_vidioc_g_input(cam, arg); | ||
2334 | |||
2312 | case VIDIOC_S_INPUT: | 2335 | case VIDIOC_S_INPUT: |
2313 | return et61x251_vidioc_gs_input(cam, arg); | 2336 | return et61x251_vidioc_s_input(cam, arg); |
2314 | 2337 | ||
2315 | case VIDIOC_QUERYCTRL: | 2338 | case VIDIOC_QUERYCTRL: |
2316 | return et61x251_vidioc_query_ctrl(cam, arg); | 2339 | return et61x251_vidioc_query_ctrl(cam, arg); |
@@ -2393,19 +2416,19 @@ static int et61x251_ioctl(struct inode* inode, struct file* filp, | |||
2393 | struct et61x251_device* cam = video_get_drvdata(video_devdata(filp)); | 2416 | struct et61x251_device* cam = video_get_drvdata(video_devdata(filp)); |
2394 | int err = 0; | 2417 | int err = 0; |
2395 | 2418 | ||
2396 | if (down_interruptible(&cam->fileop_sem)) | 2419 | if (mutex_lock_interruptible(&cam->fileop_mutex)) |
2397 | return -ERESTARTSYS; | 2420 | return -ERESTARTSYS; |
2398 | 2421 | ||
2399 | if (cam->state & DEV_DISCONNECTED) { | 2422 | if (cam->state & DEV_DISCONNECTED) { |
2400 | DBG(1, "Device not present"); | 2423 | DBG(1, "Device not present"); |
2401 | up(&cam->fileop_sem); | 2424 | mutex_unlock(&cam->fileop_mutex); |
2402 | return -ENODEV; | 2425 | return -ENODEV; |
2403 | } | 2426 | } |
2404 | 2427 | ||
2405 | if (cam->state & DEV_MISCONFIGURED) { | 2428 | if (cam->state & DEV_MISCONFIGURED) { |
2406 | DBG(1, "The camera is misconfigured. Close and open it " | 2429 | DBG(1, "The camera is misconfigured. Close and open it " |
2407 | "again."); | 2430 | "again."); |
2408 | up(&cam->fileop_sem); | 2431 | mutex_unlock(&cam->fileop_mutex); |
2409 | return -EIO; | 2432 | return -EIO; |
2410 | } | 2433 | } |
2411 | 2434 | ||
@@ -2413,7 +2436,7 @@ static int et61x251_ioctl(struct inode* inode, struct file* filp, | |||
2413 | 2436 | ||
2414 | err = et61x251_ioctl_v4l2(inode, filp, cmd, (void __user *)arg); | 2437 | err = et61x251_ioctl_v4l2(inode, filp, cmd, (void __user *)arg); |
2415 | 2438 | ||
2416 | up(&cam->fileop_sem); | 2439 | mutex_unlock(&cam->fileop_mutex); |
2417 | 2440 | ||
2418 | return err; | 2441 | return err; |
2419 | } | 2442 | } |
@@ -2459,7 +2482,7 @@ et61x251_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) | |||
2459 | goto fail; | 2482 | goto fail; |
2460 | } | 2483 | } |
2461 | 2484 | ||
2462 | init_MUTEX(&cam->dev_sem); | 2485 | mutex_init(&cam->dev_mutex); |
2463 | 2486 | ||
2464 | DBG(2, "ET61X[12]51 PC Camera Controller detected " | 2487 | DBG(2, "ET61X[12]51 PC Camera Controller detected " |
2465 | "(vid/pid 0x%04X/0x%04X)",id->idVendor, id->idProduct); | 2488 | "(vid/pid 0x%04X/0x%04X)",id->idVendor, id->idProduct); |
@@ -2470,8 +2493,8 @@ et61x251_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) | |||
2470 | break; | 2493 | break; |
2471 | } | 2494 | } |
2472 | 2495 | ||
2473 | if (!err && cam->sensor) | 2496 | if (!err) |
2474 | DBG(2, "%s image sensor detected", cam->sensor->name); | 2497 | DBG(2, "%s image sensor detected", cam->sensor.name); |
2475 | else { | 2498 | else { |
2476 | DBG(1, "No supported image sensor detected"); | 2499 | DBG(1, "No supported image sensor detected"); |
2477 | err = -ENODEV; | 2500 | err = -ENODEV; |
@@ -2492,7 +2515,7 @@ et61x251_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) | |||
2492 | cam->v4ldev->release = video_device_release; | 2515 | cam->v4ldev->release = video_device_release; |
2493 | video_set_drvdata(cam->v4ldev, cam); | 2516 | video_set_drvdata(cam->v4ldev, cam); |
2494 | 2517 | ||
2495 | down(&cam->dev_sem); | 2518 | mutex_lock(&cam->dev_mutex); |
2496 | 2519 | ||
2497 | err = video_register_device(cam->v4ldev, VFL_TYPE_GRABBER, | 2520 | err = video_register_device(cam->v4ldev, VFL_TYPE_GRABBER, |
2498 | video_nr[dev_nr]); | 2521 | video_nr[dev_nr]); |
@@ -2502,13 +2525,14 @@ et61x251_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) | |||
2502 | DBG(1, "Free /dev/videoX node not found"); | 2525 | DBG(1, "Free /dev/videoX node not found"); |
2503 | video_nr[dev_nr] = -1; | 2526 | video_nr[dev_nr] = -1; |
2504 | dev_nr = (dev_nr < ET61X251_MAX_DEVICES-1) ? dev_nr+1 : 0; | 2527 | dev_nr = (dev_nr < ET61X251_MAX_DEVICES-1) ? dev_nr+1 : 0; |
2505 | up(&cam->dev_sem); | 2528 | mutex_unlock(&cam->dev_mutex); |
2506 | goto fail; | 2529 | goto fail; |
2507 | } | 2530 | } |
2508 | 2531 | ||
2509 | DBG(2, "V4L2 device registered as /dev/video%d", cam->v4ldev->minor); | 2532 | DBG(2, "V4L2 device registered as /dev/video%d", cam->v4ldev->minor); |
2510 | 2533 | ||
2511 | cam->module_param.force_munmap = force_munmap[dev_nr]; | 2534 | cam->module_param.force_munmap = force_munmap[dev_nr]; |
2535 | cam->module_param.frame_timeout = frame_timeout[dev_nr]; | ||
2512 | 2536 | ||
2513 | dev_nr = (dev_nr < ET61X251_MAX_DEVICES-1) ? dev_nr+1 : 0; | 2537 | dev_nr = (dev_nr < ET61X251_MAX_DEVICES-1) ? dev_nr+1 : 0; |
2514 | 2538 | ||
@@ -2519,7 +2543,7 @@ et61x251_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) | |||
2519 | 2543 | ||
2520 | usb_set_intfdata(intf, cam); | 2544 | usb_set_intfdata(intf, cam); |
2521 | 2545 | ||
2522 | up(&cam->dev_sem); | 2546 | mutex_unlock(&cam->dev_mutex); |
2523 | 2547 | ||
2524 | return 0; | 2548 | return 0; |
2525 | 2549 | ||
@@ -2543,7 +2567,7 @@ static void et61x251_usb_disconnect(struct usb_interface* intf) | |||
2543 | 2567 | ||
2544 | down_write(&et61x251_disconnect); | 2568 | down_write(&et61x251_disconnect); |
2545 | 2569 | ||
2546 | down(&cam->dev_sem); | 2570 | mutex_lock(&cam->dev_mutex); |
2547 | 2571 | ||
2548 | DBG(2, "Disconnecting %s...", cam->v4ldev->name); | 2572 | DBG(2, "Disconnecting %s...", cam->v4ldev->name); |
2549 | 2573 | ||
@@ -2557,13 +2581,14 @@ static void et61x251_usb_disconnect(struct usb_interface* intf) | |||
2557 | et61x251_stop_transfer(cam); | 2581 | et61x251_stop_transfer(cam); |
2558 | cam->state |= DEV_DISCONNECTED; | 2582 | cam->state |= DEV_DISCONNECTED; |
2559 | wake_up_interruptible(&cam->wait_frame); | 2583 | wake_up_interruptible(&cam->wait_frame); |
2560 | wake_up_interruptible(&cam->wait_stream); | 2584 | wake_up(&cam->wait_stream); |
2585 | usb_get_dev(cam->usbdev); | ||
2561 | } else { | 2586 | } else { |
2562 | cam->state |= DEV_DISCONNECTED; | 2587 | cam->state |= DEV_DISCONNECTED; |
2563 | et61x251_release_resources(cam); | 2588 | et61x251_release_resources(cam); |
2564 | } | 2589 | } |
2565 | 2590 | ||
2566 | up(&cam->dev_sem); | 2591 | mutex_unlock(&cam->dev_mutex); |
2567 | 2592 | ||
2568 | if (!cam->users) | 2593 | if (!cam->users) |
2569 | kfree(cam); | 2594 | kfree(cam); |
diff --git a/drivers/usb/media/et61x251_sensor.h b/drivers/usb/media/et61x251_sensor.h index b9df91062fc0..56841ae8a207 100644 --- a/drivers/usb/media/et61x251_sensor.h +++ b/drivers/usb/media/et61x251_sensor.h | |||
@@ -42,6 +42,9 @@ static int (*et61x251_sensor_table[])(struct et61x251_device*) = { \ | |||
42 | NULL, \ | 42 | NULL, \ |
43 | }; | 43 | }; |
44 | 44 | ||
45 | extern struct et61x251_device* | ||
46 | et61x251_match_id(struct et61x251_device* cam, const struct usb_device_id *id); | ||
47 | |||
45 | extern void | 48 | extern void |
46 | et61x251_attach_sensor(struct et61x251_device* cam, | 49 | et61x251_attach_sensor(struct et61x251_device* cam, |
47 | struct et61x251_sensor* sensor); | 50 | struct et61x251_sensor* sensor); |
@@ -105,8 +108,6 @@ struct et61x251_sensor { | |||
105 | int (*set_pix_format)(struct et61x251_device* cam, | 108 | int (*set_pix_format)(struct et61x251_device* cam, |
106 | const struct v4l2_pix_format* pix); | 109 | const struct v4l2_pix_format* pix); |
107 | 110 | ||
108 | const struct usb_device* usbdev; | ||
109 | |||
110 | /* Private */ | 111 | /* Private */ |
111 | struct v4l2_queryctrl _qctrl[ET61X251_MAX_CTRLS]; | 112 | struct v4l2_queryctrl _qctrl[ET61X251_MAX_CTRLS]; |
112 | struct v4l2_rect _rect; | 113 | struct v4l2_rect _rect; |
diff --git a/drivers/usb/media/et61x251_tas5130d1b.c b/drivers/usb/media/et61x251_tas5130d1b.c index 65f1ae9cf2b3..3998d76a307a 100644 --- a/drivers/usb/media/et61x251_tas5130d1b.c +++ b/drivers/usb/media/et61x251_tas5130d1b.c | |||
@@ -126,12 +126,16 @@ static struct et61x251_sensor tas5130d1b = { | |||
126 | 126 | ||
127 | int et61x251_probe_tas5130d1b(struct et61x251_device* cam) | 127 | int et61x251_probe_tas5130d1b(struct et61x251_device* cam) |
128 | { | 128 | { |
129 | /* This sensor has no identifiers, so let's attach it anyway */ | 129 | const struct usb_device_id tas5130d1b_id_table[] = { |
130 | et61x251_attach_sensor(cam, &tas5130d1b); | 130 | { USB_DEVICE(0x102c, 0x6251), }, |
131 | { } | ||
132 | }; | ||
131 | 133 | ||
132 | /* Sensor detection is based on USB pid/vid */ | 134 | /* Sensor detection is based on USB pid/vid */ |
133 | if (le16_to_cpu(tas5130d1b.usbdev->descriptor.idProduct) != 0x6251) | 135 | if (!et61x251_match_id(cam, tas5130d1b_id_table)) |
134 | return -ENODEV; | 136 | return -ENODEV; |
135 | 137 | ||
138 | et61x251_attach_sensor(cam, &tas5130d1b); | ||
139 | |||
136 | return 0; | 140 | return 0; |
137 | } | 141 | } |