aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/usb/sn9c102.txt86
-rw-r--r--drivers/usb/media/sn9c102.h31
-rw-r--r--drivers/usb/media/sn9c102_core.c1593
-rw-r--r--drivers/usb/media/sn9c102_hv7131d.c2
-rw-r--r--drivers/usb/media/sn9c102_mi0343.c2
-rw-r--r--drivers/usb/media/sn9c102_ov7630.c8
-rw-r--r--drivers/usb/media/sn9c102_pas106b.c2
-rw-r--r--drivers/usb/media/sn9c102_sensor.h69
-rw-r--r--drivers/usb/media/sn9c102_tas5110c1b.c2
-rw-r--r--drivers/usb/media/sn9c102_tas5130d1b.c2
10 files changed, 1006 insertions, 791 deletions
diff --git a/Documentation/usb/sn9c102.txt b/Documentation/usb/sn9c102.txt
index 3f8a119db31b..541b17fd27f6 100644
--- a/Documentation/usb/sn9c102.txt
+++ b/Documentation/usb/sn9c102.txt
@@ -17,16 +17,15 @@ Index
177. Module parameters 177. Module parameters
188. Optional device control through "sysfs" 188. Optional device control through "sysfs"
199. Supported devices 199. Supported devices
2010. How to add plug-in's for new image sensors 2010. Notes for V4L2 application developers
2111. Notes for V4L2 application developers 2111. Video frame formats
2212. Video frame formats 2212. Contact information
2313. Contact information 2313. Credits
2414. Credits
25 24
26 25
271. Copyright 261. Copyright
28============ 27============
29Copyright (C) 2004-2005 by Luca Risolia <luca.risolia@studio.unibo.it> 28Copyright (C) 2004-2006 by Luca Risolia <luca.risolia@studio.unibo.it>
30 29
31 30
322. Disclaimer 312. Disclaimer
@@ -54,9 +53,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
54 53
554. Overview and features 544. Overview and features
56======================== 55========================
57This driver attempts to support the video and audio streaming capabilities of 56This driver attempts to support the video interface of the devices mounting the
58the devices mounting the SONiX SN9C101, SN9C102 and SN9C103 PC Camera 57SONiX SN9C101, SN9C102 and SN9C103 PC Camera Controllers.
59Controllers.
60 58
61It's worth to note that SONiX has never collaborated with the author during the 59It's worth to note that SONiX has never collaborated with the author during the
62development of this project, despite several requests for enough detailed 60development of this project, despite several requests for enough detailed
@@ -78,6 +76,7 @@ Some of the features of the driver are:
78- available mmap or read/poll methods for video streaming through isochronous 76- available mmap or read/poll methods for video streaming through isochronous
79 data transfers; 77 data transfers;
80- automatic detection of image sensor; 78- automatic detection of image sensor;
79- support for built-in microphone interface;
81- support for any window resolutions and optional panning within the maximum 80- support for any window resolutions and optional panning within the maximum
82 pixel area of image sensor; 81 pixel area of image sensor;
83- image downscaling with arbitrary scaling factors from 1, 2 and 4 in both 82- image downscaling with arbitrary scaling factors from 1, 2 and 4 in both
@@ -96,7 +95,7 @@ Some of the features of the driver are:
96 parameters" paragraph); 95 parameters" paragraph);
97- up to 64 cameras can be handled at the same time; they can be connected and 96- up to 64 cameras can be handled at the same time; they can be connected and
98 disconnected from the host many times without turning off the computer, if 97 disconnected from the host many times without turning off the computer, if
99 your system supports hotplugging; 98 the system supports hotplugging;
100- no known bugs. 99- no known bugs.
101 100
102 101
@@ -125,6 +124,21 @@ necessary:
125 CONFIG_USB_UHCI_HCD=m 124 CONFIG_USB_UHCI_HCD=m
126 CONFIG_USB_OHCI_HCD=m 125 CONFIG_USB_OHCI_HCD=m
127 126
127The SN9C103 controller also provides a built-in microphone interface. It is
128supported by the USB Audio driver thanks to the ALSA API:
129
130 # Sound
131 #
132 CONFIG_SOUND=y
133
134 # Advanced Linux Sound Architecture
135 #
136 CONFIG_SND=m
137
138 # USB devices
139 #
140 CONFIG_SND_USB_AUDIO=m
141
128And finally: 142And finally:
129 143
130 # USB Multimedia devices 144 # USB Multimedia devices
@@ -153,7 +167,7 @@ analyze kernel messages and verify that the loading process has gone well:
153Module parameters are listed below: 167Module parameters are listed below:
154------------------------------------------------------------------------------- 168-------------------------------------------------------------------------------
155Name: video_nr 169Name: video_nr
156Type: int array (min = 0, max = 64) 170Type: short array (min = 0, max = 64)
157Syntax: <-1|n[,...]> 171Syntax: <-1|n[,...]>
158Description: Specify V4L2 minor mode number: 172Description: Specify V4L2 minor mode number:
159 -1 = use next available 173 -1 = use next available
@@ -165,19 +179,19 @@ Description: Specify V4L2 minor mode number:
165 other camera. 179 other camera.
166Default: -1 180Default: -1
167------------------------------------------------------------------------------- 181-------------------------------------------------------------------------------
168Name: force_munmap; 182Name: force_munmap
169Type: bool array (min = 0, max = 64) 183Type: bool array (min = 0, max = 64)
170Syntax: <0|1[,...]> 184Syntax: <0|1[,...]>
171Description: Force the application to unmap previously mapped buffer memory 185Description: Force the application to unmap previously mapped buffer memory
172 before calling any VIDIOC_S_CROP or VIDIOC_S_FMT ioctl's. Not 186 before calling any VIDIOC_S_CROP or VIDIOC_S_FMT ioctl's. Not
173 all the applications support this feature. This parameter is 187 all the applications support this feature. This parameter is
174 specific for each detected camera. 188 specific for each detected camera.
175 0 = do not force memory unmapping" 189 0 = do not force memory unmapping
176 1 = force memory unmapping (save memory)" 190 1 = force memory unmapping (save memory)
177Default: 0 191Default: 0
178------------------------------------------------------------------------------- 192-------------------------------------------------------------------------------
179Name: debug 193Name: debug
180Type: int 194Type: ushort
181Syntax: <n> 195Syntax: <n>
182Description: Debugging information level, from 0 to 3: 196Description: Debugging information level, from 0 to 3:
183 0 = none (use carefully) 197 0 = none (use carefully)
@@ -187,7 +201,7 @@ Description: Debugging information level, from 0 to 3:
187 Level 3 is useful for testing only, when only one device 201 Level 3 is useful for testing only, when only one device
188 is used. It also shows some more informations about the 202 is used. It also shows some more informations about the
189 hardware being detected. This parameter can be changed at 203 hardware being detected. This parameter can be changed at
190 runtime thanks to the /sys filesystem. 204 runtime thanks to the /sys filesystem interface.
191Default: 2 205Default: 2
192------------------------------------------------------------------------------- 206-------------------------------------------------------------------------------
193 207
@@ -236,7 +250,7 @@ serialized.
236 250
237The sysfs interface also provides the "frame_header" entry, which exports the 251The sysfs interface also provides the "frame_header" entry, which exports the
238frame header of the most recent requested and captured video frame. The header 252frame header of the most recent requested and captured video frame. The header
239is 12-bytes long and is appended to every video frame by the SN9C10x 253is always 18-bytes long and is appended to every video frame by the SN9C10x
240controllers. As an example, this additional information can be used by the user 254controllers. As an example, this additional information can be used by the user
241application for implementing auto-exposure features via software. 255application for implementing auto-exposure features via software.
242 256
@@ -250,7 +264,8 @@ Byte # Value Description
2500x03 0xC4 Frame synchronisation pattern. 2640x03 0xC4 Frame synchronisation pattern.
2510x04 0xC4 Frame synchronisation pattern. 2650x04 0xC4 Frame synchronisation pattern.
2520x05 0x96 Frame synchronisation pattern. 2660x05 0x96 Frame synchronisation pattern.
2530x06 0x00 or 0x01 Unknown meaning. The exact value depends on the chip. 2670x06 0xXX Unknown meaning. The exact value depends on the chip;
268 possible values are 0x00, 0x01 and 0x20.
2540x07 0xXX Variable value, whose bits are ff00uzzc, where ff is a 2690x07 0xXX Variable value, whose bits are ff00uzzc, where ff is a
255 frame counter, u is unknown, zz is a size indicator 270 frame counter, u is unknown, zz is a size indicator
256 (00 = VGA, 01 = SIF, 10 = QSIF) and c stands for 271 (00 = VGA, 01 = SIF, 10 = QSIF) and c stands for
@@ -267,12 +282,23 @@ Byte # Value Description
267 times the area outside of the specified AE area. For 282 times the area outside of the specified AE area. For
268 images that are not pure white, the value scales down 283 images that are not pure white, the value scales down
269 according to relative whiteness. 284 according to relative whiteness.
285 according to relative whiteness.
286
287The following bytes are used by the SN9C103 bridge only:
288
2890x0C 0xXX Unknown meaning
2900x0D 0xXX Unknown meaning
2910x0E 0xXX Unknown meaning
2920x0F 0xXX Unknown meaning
2930x10 0xXX Unknown meaning
2940x11 0xXX Unknown meaning
270 295
271The AE area (sx, sy, ex, ey) in the active window can be set by programming the 296The AE area (sx, sy, ex, ey) in the active window can be set by programming the
272registers 0x1c, 0x1d, 0x1e and 0x1f of the SN9C10x controllers, where one unit 297registers 0x1c, 0x1d, 0x1e and 0x1f of the SN9C10x controllers, where one unit
273corresponds to 32 pixels. 298corresponds to 32 pixels.
274 299
275[1] The frame header has been documented by Bertrik Sikken. 300[1] Part of the meaning of the frame header has been documented by Bertrik
301 Sikken.
276 302
277 303
2789. Supported devices 3049. Supported devices
@@ -298,6 +324,7 @@ Vendor ID Product ID
2980x0c45 0x602b 3240x0c45 0x602b
2990x0c45 0x602c 3250x0c45 0x602c
3000x0c45 0x602d 3260x0c45 0x602d
3270x0c45 0x602e
3010x0c45 0x6030 3280x0c45 0x6030
3020x0c45 0x6080 3290x0c45 0x6080
3030x0c45 0x6082 3300x0c45 0x6082
@@ -348,18 +375,7 @@ appreciated. Non-available hardware will not be supported by the author of this
348driver. 375driver.
349 376
350 377
35110. How to add plug-in's for new image sensors 37810. Notes for V4L2 application developers
352==============================================
353It should be easy to write plug-in's for new sensors by using the small API
354that has been created for this purpose, which is present in "sn9c102_sensor.h"
355(documentation is included there). As an example, have a look at the code in
356"sn9c102_pas106b.c", which uses the mentioned interface.
357
358At the moment, possible unsupported image sensors are: CIS-VF10 (VGA),
359OV7620 (VGA), OV7630 (VGA).
360
361
36211. Notes for V4L2 application developers
363========================================= 379=========================================
364This driver follows the V4L2 API specifications. In particular, it enforces two 380This driver follows the V4L2 API specifications. In particular, it enforces two
365rules: 381rules:
@@ -394,7 +410,7 @@ initialized (as described in the documentation of the API for the image sensors
394supplied by this driver). 410supplied by this driver).
395 411
396 412
39712. Video frame formats [1] 41311. Video frame formats [1]
398======================= 414=======================
399The SN9C10x PC Camera Controllers can send images in two possible video 415The SN9C10x PC Camera Controllers can send images in two possible video
400formats over the USB: either native "Sequential RGB Bayer" or Huffman 416formats over the USB: either native "Sequential RGB Bayer" or Huffman
@@ -455,7 +471,7 @@ The following Huffman codes have been found:
455 documented by Bertrik Sikken. 471 documented by Bertrik Sikken.
456 472
457 473
45813. Contact information 47412. Contact information
459======================= 475=======================
460The author may be contacted by e-mail at <luca.risolia@studio.unibo.it>. 476The author may be contacted by e-mail at <luca.risolia@studio.unibo.it>.
461 477
@@ -464,7 +480,7 @@ GPG/PGP encrypted e-mail's are accepted. The GPG key ID of the author is
464the fingerprint is: '88E8 F32F 7244 68BA 3958 5D40 99DA 5D2A FCE6 35A4'. 480the fingerprint is: '88E8 F32F 7244 68BA 3958 5D40 99DA 5D2A FCE6 35A4'.
465 481
466 482
46714. Credits 48313. Credits
468=========== 484===========
469Many thanks to following persons for their contribute (listed in alphabetical 485Many thanks to following persons for their contribute (listed in alphabetical
470order): 486order):
@@ -480,5 +496,5 @@ order):
480- Bertrik Sikken, who reverse-engineered and documented the Huffman compression 496- Bertrik Sikken, who reverse-engineered and documented the Huffman compression
481 algorithm used in the SN9C10x controllers and implemented the first decoder; 497 algorithm used in the SN9C10x controllers and implemented the first decoder;
482- Mizuno Takafumi for the donation of a webcam; 498- Mizuno Takafumi for the donation of a webcam;
483- An "anonymous" donator (who didn't want his name to be revealed) for the 499- an "anonymous" donator (who didn't want his name to be revealed) for the
484 donation of a webcam. 500 donation of a webcam.
diff --git a/drivers/usb/media/sn9c102.h b/drivers/usb/media/sn9c102.h
index e5cea0e2eb57..967c6b6bc0fa 100644
--- a/drivers/usb/media/sn9c102.h
+++ b/drivers/usb/media/sn9c102.h
@@ -1,7 +1,7 @@
1/*************************************************************************** 1/***************************************************************************
2 * V4L2 driver for SN9C10x PC Camera Controllers * 2 * V4L2 driver for SN9C10x PC Camera Controllers *
3 * * 3 * *
4 * Copyright (C) 2004-2005 by Luca Risolia <luca.risolia@studio.unibo.it> * 4 * Copyright (C) 2004-2006 by Luca Risolia <luca.risolia@studio.unibo.it> *
5 * * 5 * *
6 * This program is free software; you can redistribute it and/or modify * 6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by * 7 * it under the terms of the GNU General Public License as published by *
@@ -53,11 +53,11 @@
53/*****************************************************************************/ 53/*****************************************************************************/
54 54
55#define SN9C102_MODULE_NAME "V4L2 driver for SN9C10x PC Camera Controllers" 55#define SN9C102_MODULE_NAME "V4L2 driver for SN9C10x PC Camera Controllers"
56#define SN9C102_MODULE_AUTHOR "(C) 2004-2005 Luca Risolia" 56#define SN9C102_MODULE_AUTHOR "(C) 2004-2006 Luca Risolia"
57#define SN9C102_AUTHOR_EMAIL "<luca.risolia@studio.unibo.it>" 57#define SN9C102_AUTHOR_EMAIL "<luca.risolia@studio.unibo.it>"
58#define SN9C102_MODULE_LICENSE "GPL" 58#define SN9C102_MODULE_LICENSE "GPL"
59#define SN9C102_MODULE_VERSION "1:1.24a" 59#define SN9C102_MODULE_VERSION "1:1.25"
60#define SN9C102_MODULE_VERSION_CODE KERNEL_VERSION(1, 0, 24) 60#define SN9C102_MODULE_VERSION_CODE KERNEL_VERSION(1, 0, 25)
61 61
62enum sn9c102_bridge { 62enum sn9c102_bridge {
63 BRIDGE_SN9C101 = 0x01, 63 BRIDGE_SN9C101 = 0x01,
@@ -102,12 +102,13 @@ enum sn9c102_stream_state {
102 STREAM_ON, 102 STREAM_ON,
103}; 103};
104 104
105typedef char sn9c103_sof_header_t[18];
105typedef char sn9c102_sof_header_t[12]; 106typedef char sn9c102_sof_header_t[12];
106typedef char sn9c102_eof_header_t[4]; 107typedef char sn9c102_eof_header_t[4];
107 108
108struct sn9c102_sysfs_attr { 109struct sn9c102_sysfs_attr {
109 u8 reg, i2c_reg; 110 u8 reg, i2c_reg;
110 sn9c102_sof_header_t frame_header; 111 sn9c103_sof_header_t frame_header;
111}; 112};
112 113
113struct sn9c102_module_param { 114struct sn9c102_module_param {
@@ -140,8 +141,8 @@ struct sn9c102_device {
140 struct v4l2_jpegcompression compression; 141 struct v4l2_jpegcompression compression;
141 142
142 struct sn9c102_sysfs_attr sysfs; 143 struct sn9c102_sysfs_attr sysfs;
143 sn9c102_sof_header_t sof_header; 144 sn9c103_sof_header_t sof_header;
144 u16 reg[32]; 145 u16 reg[63];
145 146
146 struct sn9c102_module_param module_param; 147 struct sn9c102_module_param module_param;
147 148
@@ -170,7 +171,7 @@ sn9c102_attach_sensor(struct sn9c102_device* cam,
170#undef KDBG 171#undef KDBG
171#ifdef SN9C102_DEBUG 172#ifdef SN9C102_DEBUG
172# define DBG(level, fmt, args...) \ 173# define DBG(level, fmt, args...) \
173{ \ 174do { \
174 if (debug >= (level)) { \ 175 if (debug >= (level)) { \
175 if ((level) == 1) \ 176 if ((level) == 1) \
176 dev_err(&cam->dev, fmt "\n", ## args); \ 177 dev_err(&cam->dev, fmt "\n", ## args); \
@@ -180,9 +181,9 @@ sn9c102_attach_sensor(struct sn9c102_device* cam,
180 dev_info(&cam->dev, "[%s:%d] " fmt "\n", \ 181 dev_info(&cam->dev, "[%s:%d] " fmt "\n", \
181 __FUNCTION__, __LINE__ , ## args); \ 182 __FUNCTION__, __LINE__ , ## args); \
182 } \ 183 } \
183} 184} while (0)
184# define KDBG(level, fmt, args...) \ 185# define KDBG(level, fmt, args...) \
185{ \ 186do { \
186 if (debug >= (level)) { \ 187 if (debug >= (level)) { \
187 if ((level) == 1 || (level) == 2) \ 188 if ((level) == 1 || (level) == 2) \
188 pr_info("sn9c102: " fmt "\n", ## args); \ 189 pr_info("sn9c102: " fmt "\n", ## args); \
@@ -190,17 +191,17 @@ sn9c102_attach_sensor(struct sn9c102_device* cam,
190 pr_debug("sn9c102: [%s:%d] " fmt "\n", __FUNCTION__, \ 191 pr_debug("sn9c102: [%s:%d] " fmt "\n", __FUNCTION__, \
191 __LINE__ , ## args); \ 192 __LINE__ , ## args); \
192 } \ 193 } \
193} 194} while (0)
194#else 195#else
195# define KDBG(level, fmt, args...) do {;} while(0); 196# define KDBG(level, fmt, args...) do {;} while(0)
196# define DBG(level, fmt, args...) do {;} while(0); 197# define DBG(level, fmt, args...) do {;} while(0)
197#endif 198#endif
198 199
199#undef PDBG 200#undef PDBG
200#define PDBG(fmt, args...) \ 201#define PDBG(fmt, args...) \
201dev_info(&cam->dev, "[%s:%d] " fmt "\n", __FUNCTION__, __LINE__ , ## args); 202dev_info(&cam->dev, "[%s:%d] " fmt "\n", __FUNCTION__, __LINE__ , ## args)
202 203
203#undef PDBGG 204#undef PDBGG
204#define PDBGG(fmt, args...) do {;} while(0); /* placeholder */ 205#define PDBGG(fmt, args...) do {;} while(0) /* placeholder */
205 206
206#endif /* _SN9C102_H_ */ 207#endif /* _SN9C102_H_ */
diff --git a/drivers/usb/media/sn9c102_core.c b/drivers/usb/media/sn9c102_core.c
index 8d1a1c357d5a..6090439663ee 100644
--- a/drivers/usb/media/sn9c102_core.c
+++ b/drivers/usb/media/sn9c102_core.c
@@ -1,7 +1,7 @@
1/*************************************************************************** 1/***************************************************************************
2 * V4L2 driver for SN9C10x PC Camera Controllers * 2 * V4L2 driver for SN9C10x PC Camera Controllers *
3 * * 3 * *
4 * Copyright (C) 2004-2005 by Luca Risolia <luca.risolia@studio.unibo.it> * 4 * Copyright (C) 2004-2006 by Luca Risolia <luca.risolia@studio.unibo.it> *
5 * * 5 * *
6 * This program is free software; you can redistribute it and/or modify * 6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by * 7 * it under the terms of the GNU General Public License as published by *
@@ -70,10 +70,10 @@ static short force_munmap[] = {[0 ... SN9C102_MAX_DEVICES-1] =
70 SN9C102_FORCE_MUNMAP}; 70 SN9C102_FORCE_MUNMAP};
71module_param_array(force_munmap, bool, NULL, 0444); 71module_param_array(force_munmap, bool, NULL, 0444);
72MODULE_PARM_DESC(force_munmap, 72MODULE_PARM_DESC(force_munmap,
73 "\n<0|1[,...]> Force the application to unmap previously " 73 "\n<0|1[,...]> Force the application to unmap previously"
74 "\nmapped buffer memory before calling any VIDIOC_S_CROP or " 74 "\nmapped buffer memory before calling any VIDIOC_S_CROP or"
75 "\nVIDIOC_S_FMT ioctl's. Not all the applications support " 75 "\nVIDIOC_S_FMT ioctl's. Not all the applications support"
76 "\nthis feature. This parameter is specific for each " 76 "\nthis feature. This parameter is specific for each"
77 "\ndetected camera." 77 "\ndetected camera."
78 "\n 0 = do not force memory unmapping" 78 "\n 0 = do not force memory unmapping"
79 "\n 1 = force memory unmapping (save memory)" 79 "\n 1 = force memory unmapping (save memory)"
@@ -102,6 +102,9 @@ static sn9c102_sof_header_t sn9c102_sof_header[] = {
102 {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96, 0x01}, 102 {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96, 0x01},
103}; 103};
104 104
105static sn9c103_sof_header_t sn9c103_sof_header[] = {
106 {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96, 0x20},
107};
105 108
106static sn9c102_eof_header_t sn9c102_eof_header[] = { 109static sn9c102_eof_header_t sn9c102_eof_header[] = {
107 {0x00, 0x00, 0x00, 0x00}, 110 {0x00, 0x00, 0x00, 0x00},
@@ -202,6 +205,7 @@ static void sn9c102_release_buffers(struct sn9c102_device* cam)
202 cam->nbuffers * PAGE_ALIGN(cam->frame[0].buf.length)); 205 cam->nbuffers * PAGE_ALIGN(cam->frame[0].buf.length));
203 cam->nbuffers = 0; 206 cam->nbuffers = 0;
204 } 207 }
208 cam->frame_current = NULL;
205} 209}
206 210
207 211
@@ -219,6 +223,19 @@ static void sn9c102_empty_framequeues(struct sn9c102_device* cam)
219} 223}
220 224
221 225
226static void sn9c102_requeue_outqueue(struct sn9c102_device* cam)
227{
228 struct sn9c102_frame_t *i;
229
230 list_for_each_entry(i, &cam->outqueue, frame) {
231 i->state = F_QUEUED;
232 list_add(&i->frame, &cam->inqueue);
233 }
234
235 INIT_LIST_HEAD(&cam->outqueue);
236}
237
238
222static void sn9c102_queue_unusedframes(struct sn9c102_device* cam) 239static void sn9c102_queue_unusedframes(struct sn9c102_device* cam)
223{ 240{
224 unsigned long lock_flags; 241 unsigned long lock_flags;
@@ -235,19 +252,46 @@ static void sn9c102_queue_unusedframes(struct sn9c102_device* cam)
235 252
236/*****************************************************************************/ 253/*****************************************************************************/
237 254
255int sn9c102_write_regs(struct sn9c102_device* cam, u8* buff, u16 index)
256{
257 struct usb_device* udev = cam->usbdev;
258 int i, res;
259
260 if (index + sizeof(buff) >= ARRAY_SIZE(cam->reg))
261 return -1;
262
263 res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x08, 0x41,
264 index, 0, buff, sizeof(buff),
265 SN9C102_CTRL_TIMEOUT*sizeof(buff));
266 if (res < 0) {
267 DBG(3, "Failed to write registers (index 0x%02X, error %d)",
268 index, res);
269 return -1;
270 }
271
272 for (i = 0; i < sizeof(buff); i++)
273 cam->reg[index+i] = buff[i];
274
275 return 0;
276}
277
278
238int sn9c102_write_reg(struct sn9c102_device* cam, u8 value, u16 index) 279int sn9c102_write_reg(struct sn9c102_device* cam, u8 value, u16 index)
239{ 280{
240 struct usb_device* udev = cam->usbdev; 281 struct usb_device* udev = cam->usbdev;
241 u8* buff = cam->control_buffer; 282 u8* buff = cam->control_buffer;
242 int res; 283 int res;
243 284
285 if (index >= ARRAY_SIZE(cam->reg))
286 return -1;
287
244 *buff = value; 288 *buff = value;
245 289
246 res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x08, 0x41, 290 res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x08, 0x41,
247 index, 0, buff, 1, SN9C102_CTRL_TIMEOUT); 291 index, 0, buff, 1, SN9C102_CTRL_TIMEOUT);
248 if (res < 0) { 292 if (res < 0) {
249 DBG(3, "Failed to write a register (value 0x%02X, index " 293 DBG(3, "Failed to write a register (value 0x%02X, index "
250 "0x%02X, error %d)", value, index, res) 294 "0x%02X, error %d)", value, index, res);
251 return -1; 295 return -1;
252 } 296 }
253 297
@@ -268,7 +312,7 @@ static int sn9c102_read_reg(struct sn9c102_device* cam, u16 index)
268 index, 0, buff, 1, SN9C102_CTRL_TIMEOUT); 312 index, 0, buff, 1, SN9C102_CTRL_TIMEOUT);
269 if (res < 0) 313 if (res < 0)
270 DBG(3, "Failed to read a register (index 0x%02X, error %d)", 314 DBG(3, "Failed to read a register (index 0x%02X, error %d)",
271 index, res) 315 index, res);
272 316
273 return (res >= 0) ? (int)(*buff) : -1; 317 return (res >= 0) ? (int)(*buff) : -1;
274} 318}
@@ -276,8 +320,8 @@ static int sn9c102_read_reg(struct sn9c102_device* cam, u16 index)
276 320
277int sn9c102_pread_reg(struct sn9c102_device* cam, u16 index) 321int sn9c102_pread_reg(struct sn9c102_device* cam, u16 index)
278{ 322{
279 if (index > 0x1f) 323 if (index >= ARRAY_SIZE(cam->reg))
280 return -EINVAL; 324 return -1;
281 325
282 return cam->reg[index]; 326 return cam->reg[index];
283} 327}
@@ -367,10 +411,10 @@ sn9c102_i2c_try_raw_read(struct sn9c102_device* cam,
367 err += sn9c102_i2c_detect_read_error(cam, sensor); 411 err += sn9c102_i2c_detect_read_error(cam, sensor);
368 412
369 PDBGG("I2C read: address 0x%02X, first read byte: 0x%02X", data1, 413 PDBGG("I2C read: address 0x%02X, first read byte: 0x%02X", data1,
370 data[4]) 414 data[4]);
371 415
372 if (err) { 416 if (err) {
373 DBG(3, "I2C read failed for %s image sensor", sensor->name) 417 DBG(3, "I2C read failed for %s image sensor", sensor->name);
374 return -1; 418 return -1;
375 } 419 }
376 420
@@ -410,11 +454,11 @@ sn9c102_i2c_try_raw_write(struct sn9c102_device* cam,
410 err += sn9c102_i2c_detect_write_error(cam, sensor); 454 err += sn9c102_i2c_detect_write_error(cam, sensor);
411 455
412 if (err) 456 if (err)
413 DBG(3, "I2C write failed for %s image sensor", sensor->name) 457 DBG(3, "I2C write failed for %s image sensor", sensor->name);
414 458
415 PDBGG("I2C raw write: %u bytes, data0 = 0x%02X, data1 = 0x%02X, " 459 PDBGG("I2C raw write: %u bytes, data0 = 0x%02X, data1 = 0x%02X, "
416 "data2 = 0x%02X, data3 = 0x%02X, data4 = 0x%02X, data5 = 0x%02X", 460 "data2 = 0x%02X, data3 = 0x%02X, data4 = 0x%02X, data5 = 0x%02X",
417 n, data0, data1, data2, data3, data4, data5) 461 n, data0, data1, data2, data3, data4, data5);
418 462
419 return err ? -1 : 0; 463 return err ? -1 : 0;
420} 464}
@@ -461,13 +505,27 @@ int sn9c102_i2c_write(struct sn9c102_device* cam, u8 address, u8 value)
461static void* 505static void*
462sn9c102_find_sof_header(struct sn9c102_device* cam, void* mem, size_t len) 506sn9c102_find_sof_header(struct sn9c102_device* cam, void* mem, size_t len)
463{ 507{
464 size_t soflen = sizeof(sn9c102_sof_header_t), i; 508 size_t soflen = 0, i;
465 u8 j, n = sizeof(sn9c102_sof_header) / soflen; 509 u8 j, n = 0;
510
511 switch (cam->bridge) {
512 case BRIDGE_SN9C101:
513 case BRIDGE_SN9C102:
514 soflen = sizeof(sn9c102_sof_header_t);
515 n = sizeof(sn9c102_sof_header) / soflen;
516 break;
517 case BRIDGE_SN9C103:
518 soflen = sizeof(sn9c103_sof_header_t);
519 n = sizeof(sn9c103_sof_header) / soflen;
520 }
466 521
467 for (i = 0; (len >= soflen) && (i <= len - soflen); i++) 522 for (i = 0; (len >= soflen) && (i <= len - soflen); i++)
468 for (j = 0; j < n; j++) 523 for (j = 0; j < n; j++)
469 /* It's enough to compare 7 bytes */ 524 /* The invariable part of the header is 6 bytes long */
470 if (!memcmp(mem + i, sn9c102_sof_header[j], 7)) { 525 if ((cam->bridge != BRIDGE_SN9C103 &&
526 !memcmp(mem + i, sn9c102_sof_header[j], 6)) ||
527 (cam->bridge == BRIDGE_SN9C103 &&
528 !memcmp(mem + i, sn9c103_sof_header[j], 6))) {
471 memcpy(cam->sof_header, mem + i, soflen); 529 memcpy(cam->sof_header, mem + i, soflen);
472 /* Skip the header */ 530 /* Skip the header */
473 return mem + i + soflen; 531 return mem + i + soflen;
@@ -499,8 +557,7 @@ static void sn9c102_urb_complete(struct urb *urb, struct pt_regs* regs)
499{ 557{
500 struct sn9c102_device* cam = urb->context; 558 struct sn9c102_device* cam = urb->context;
501 struct sn9c102_frame_t** f; 559 struct sn9c102_frame_t** f;
502 size_t imagesize; 560 size_t imagesize, soflen;
503 unsigned long lock_flags;
504 u8 i; 561 u8 i;
505 int err = 0; 562 int err = 0;
506 563
@@ -513,7 +570,7 @@ static void sn9c102_urb_complete(struct urb *urb, struct pt_regs* regs)
513 cam->stream = STREAM_OFF; 570 cam->stream = STREAM_OFF;
514 if ((*f)) 571 if ((*f))
515 (*f)->state = F_QUEUED; 572 (*f)->state = F_QUEUED;
516 DBG(3, "Stream interrupted") 573 DBG(3, "Stream interrupted");
517 wake_up_interruptible(&cam->wait_stream); 574 wake_up_interruptible(&cam->wait_stream);
518 } 575 }
519 576
@@ -536,6 +593,10 @@ static void sn9c102_urb_complete(struct urb *urb, struct pt_regs* regs)
536 cam->sensor->pix_format.height * 593 cam->sensor->pix_format.height *
537 cam->sensor->pix_format.priv) / 8; 594 cam->sensor->pix_format.priv) / 8;
538 595
596 soflen = (cam->bridge) == BRIDGE_SN9C103 ?
597 sizeof(sn9c103_sof_header_t) :
598 sizeof(sn9c102_sof_header_t);
599
539 for (i = 0; i < urb->number_of_packets; i++) { 600 for (i = 0; i < urb->number_of_packets; i++) {
540 unsigned int img, len, status; 601 unsigned int img, len, status;
541 void *pos, *sof, *eof; 602 void *pos, *sof, *eof;
@@ -545,19 +606,12 @@ static void sn9c102_urb_complete(struct urb *urb, struct pt_regs* regs)
545 pos = urb->iso_frame_desc[i].offset + urb->transfer_buffer; 606 pos = urb->iso_frame_desc[i].offset + urb->transfer_buffer;
546 607
547 if (status) { 608 if (status) {
548 DBG(3, "Error in isochronous frame") 609 DBG(3, "Error in isochronous frame");
549 (*f)->state = F_ERROR; 610 (*f)->state = F_ERROR;
550 continue; 611 continue;
551 } 612 }
552 613
553 PDBGG("Isochrnous frame: length %u, #%u i", len, i) 614 PDBGG("Isochrnous frame: length %u, #%u i", len, i);
554
555 /*
556 NOTE: It is probably correct to assume that SOF and EOF
557 headers do not occur between two consecutive packets,
558 but who knows..Whatever is the truth, this assumption
559 doesn't introduce bugs.
560 */
561 615
562redo: 616redo:
563 sof = sn9c102_find_sof_header(cam, pos, len); 617 sof = sn9c102_find_sof_header(cam, pos, len);
@@ -575,10 +629,10 @@ end_of_frame:
575 imagesize; 629 imagesize;
576 img = imagesize - (*f)->buf.bytesused; 630 img = imagesize - (*f)->buf.bytesused;
577 DBG(3, "Expected EOF not found: " 631 DBG(3, "Expected EOF not found: "
578 "video frame cut") 632 "video frame cut");
579 if (eof) 633 if (eof)
580 DBG(3, "Exceeded limit: +%u " 634 DBG(3, "Exceeded limit: +%u "
581 "bytes", (unsigned)(b)) 635 "bytes", (unsigned)(b));
582 } 636 }
583 637
584 memcpy((*f)->bufmem + (*f)->buf.bytesused, pos, 638 memcpy((*f)->bufmem + (*f)->buf.bytesused, pos,
@@ -595,8 +649,7 @@ end_of_frame:
595 u32 b = (*f)->buf.bytesused; 649 u32 b = (*f)->buf.bytesused;
596 (*f)->state = F_DONE; 650 (*f)->state = F_DONE;
597 (*f)->buf.sequence= ++cam->frame_count; 651 (*f)->buf.sequence= ++cam->frame_count;
598 spin_lock_irqsave(&cam->queue_lock, 652 spin_lock(&cam->queue_lock);
599 lock_flags);
600 list_move_tail(&(*f)->frame, 653 list_move_tail(&(*f)->frame,
601 &cam->outqueue); 654 &cam->outqueue);
602 if (!list_empty(&cam->inqueue)) 655 if (!list_empty(&cam->inqueue))
@@ -606,13 +659,11 @@ end_of_frame:
606 frame ); 659 frame );
607 else 660 else
608 (*f) = NULL; 661 (*f) = NULL;
609 spin_unlock_irqrestore(&cam->queue_lock 662 spin_unlock(&cam->queue_lock);
610 , lock_flags);
611 memcpy(cam->sysfs.frame_header, 663 memcpy(cam->sysfs.frame_header,
612 cam->sof_header, 664 cam->sof_header, soflen);
613 sizeof(sn9c102_sof_header_t)); 665 DBG(3, "Video frame captured: %lu "
614 DBG(3, "Video frame captured: " 666 "bytes", (unsigned long)(b));
615 "%lu bytes", (unsigned long)(b))
616 667
617 if (!(*f)) 668 if (!(*f))
618 goto resubmit_urb; 669 goto resubmit_urb;
@@ -621,18 +672,19 @@ end_of_frame:
621 (*f)->state = F_ERROR; 672 (*f)->state = F_ERROR;
622 DBG(3, "Not expected EOF after %lu " 673 DBG(3, "Not expected EOF after %lu "
623 "bytes of image data", 674 "bytes of image data",
624 (unsigned long)((*f)->buf.bytesused)) 675 (unsigned long)
676 ((*f)->buf.bytesused));
625 } 677 }
626 678
627 if (sof) /* (1) */ 679 if (sof) /* (1) */
628 goto start_of_frame; 680 goto start_of_frame;
629 681
630 } else if (eof) { 682 } else if (eof) {
631 DBG(3, "EOF without SOF") 683 DBG(3, "EOF without SOF");
632 continue; 684 continue;
633 685
634 } else { 686 } else {
635 PDBGG("Ignoring pointless isochronous frame") 687 PDBGG("Ignoring pointless isochronous frame");
636 continue; 688 continue;
637 } 689 }
638 690
@@ -642,7 +694,7 @@ start_of_frame:
642 (*f)->buf.bytesused = 0; 694 (*f)->buf.bytesused = 0;
643 len -= (sof - pos); 695 len -= (sof - pos);
644 pos = sof; 696 pos = sof;
645 DBG(3, "SOF detected: new video frame") 697 DBG(3, "SOF detected: new video frame");
646 if (len) 698 if (len)
647 goto redo; 699 goto redo;
648 700
@@ -653,12 +705,13 @@ start_of_frame:
653 else { 705 else {
654 if (cam->sensor->pix_format.pixelformat == 706 if (cam->sensor->pix_format.pixelformat ==
655 V4L2_PIX_FMT_SN9C10X) { 707 V4L2_PIX_FMT_SN9C10X) {
656 eof = sof-sizeof(sn9c102_sof_header_t); 708 eof = sof - soflen;
657 goto end_of_frame; 709 goto end_of_frame;
658 } else { 710 } else {
659 DBG(3, "SOF before expected EOF after " 711 DBG(3, "SOF before expected EOF after "
660 "%lu bytes of image data", 712 "%lu bytes of image data",
661 (unsigned long)((*f)->buf.bytesused)) 713 (unsigned long)
714 ((*f)->buf.bytesused));
662 goto start_of_frame; 715 goto start_of_frame;
663 } 716 }
664 } 717 }
@@ -670,7 +723,7 @@ resubmit_urb:
670 err = usb_submit_urb(urb, GFP_ATOMIC); 723 err = usb_submit_urb(urb, GFP_ATOMIC);
671 if (err < 0 && err != -EPERM) { 724 if (err < 0 && err != -EPERM) {
672 cam->state |= DEV_MISCONFIGURED; 725 cam->state |= DEV_MISCONFIGURED;
673 DBG(1, "usb_submit_urb() failed") 726 DBG(1, "usb_submit_urb() failed");
674 } 727 }
675 728
676 wake_up_interruptible(&cam->wait_frame); 729 wake_up_interruptible(&cam->wait_frame);
@@ -681,9 +734,13 @@ static int sn9c102_start_transfer(struct sn9c102_device* cam)
681{ 734{
682 struct usb_device *udev = cam->usbdev; 735 struct usb_device *udev = cam->usbdev;
683 struct urb* urb; 736 struct urb* urb;
684 const unsigned int wMaxPacketSize[] = {0, 128, 256, 384, 512, 737 const unsigned int sn9c102_wMaxPacketSize[] = {0, 128, 256, 384, 512,
685 680, 800, 900, 1023}; 738 680, 800, 900, 1023};
686 const unsigned int psz = wMaxPacketSize[SN9C102_ALTERNATE_SETTING]; 739 const unsigned int sn9c103_wMaxPacketSize[] = {0, 128, 256, 384, 512,
740 680, 800, 900, 1003};
741 const unsigned int psz = (cam->bridge == BRIDGE_SN9C103) ?
742 sn9c103_wMaxPacketSize[SN9C102_ALTERNATE_SETTING] :
743 sn9c102_wMaxPacketSize[SN9C102_ALTERNATE_SETTING];
687 s8 i, j; 744 s8 i, j;
688 int err = 0; 745 int err = 0;
689 746
@@ -692,7 +749,7 @@ static int sn9c102_start_transfer(struct sn9c102_device* cam)
692 GFP_KERNEL); 749 GFP_KERNEL);
693 if (!cam->transfer_buffer[i]) { 750 if (!cam->transfer_buffer[i]) {
694 err = -ENOMEM; 751 err = -ENOMEM;
695 DBG(1, "Not enough memory") 752 DBG(1, "Not enough memory");
696 goto free_buffers; 753 goto free_buffers;
697 } 754 }
698 } 755 }
@@ -702,7 +759,7 @@ static int sn9c102_start_transfer(struct sn9c102_device* cam)
702 cam->urb[i] = urb; 759 cam->urb[i] = urb;
703 if (!urb) { 760 if (!urb) {
704 err = -ENOMEM; 761 err = -ENOMEM;
705 DBG(1, "usb_alloc_urb() failed") 762 DBG(1, "usb_alloc_urb() failed");
706 goto free_urbs; 763 goto free_urbs;
707 } 764 }
708 urb->dev = udev; 765 urb->dev = udev;
@@ -725,14 +782,14 @@ static int sn9c102_start_transfer(struct sn9c102_device* cam)
725 err = sn9c102_write_reg(cam, cam->reg[0x01] | 0x04, 0x01); 782 err = sn9c102_write_reg(cam, cam->reg[0x01] | 0x04, 0x01);
726 if (err) { 783 if (err) {
727 err = -EIO; 784 err = -EIO;
728 DBG(1, "I/O hardware error") 785 DBG(1, "I/O hardware error");
729 goto free_urbs; 786 goto free_urbs;
730 } 787 }
731 } 788 }
732 789
733 err = usb_set_interface(udev, 0, SN9C102_ALTERNATE_SETTING); 790 err = usb_set_interface(udev, 0, SN9C102_ALTERNATE_SETTING);
734 if (err) { 791 if (err) {
735 DBG(1, "usb_set_interface() failed") 792 DBG(1, "usb_set_interface() failed");
736 goto free_urbs; 793 goto free_urbs;
737 } 794 }
738 795
@@ -743,7 +800,7 @@ static int sn9c102_start_transfer(struct sn9c102_device* cam)
743 if (err) { 800 if (err) {
744 for (j = i-1; j >= 0; j--) 801 for (j = i-1; j >= 0; j--)
745 usb_kill_urb(cam->urb[j]); 802 usb_kill_urb(cam->urb[j]);
746 DBG(1, "usb_submit_urb() failed, error %d", err) 803 DBG(1, "usb_submit_urb() failed, error %d", err);
747 goto free_urbs; 804 goto free_urbs;
748 } 805 }
749 } 806 }
@@ -779,7 +836,7 @@ static int sn9c102_stop_transfer(struct sn9c102_device* cam)
779 836
780 err = usb_set_interface(udev, 0, 0); /* 0 Mb/s */ 837 err = usb_set_interface(udev, 0, 0); /* 0 Mb/s */
781 if (err) 838 if (err)
782 DBG(3, "usb_set_interface() failed") 839 DBG(3, "usb_set_interface() failed");
783 840
784 return err; 841 return err;
785} 842}
@@ -799,7 +856,7 @@ static int sn9c102_stream_interrupt(struct sn9c102_device* cam)
799 else if (err) { 856 else if (err) {
800 cam->state |= DEV_MISCONFIGURED; 857 cam->state |= DEV_MISCONFIGURED;
801 DBG(1, "The camera is misconfigured. To use it, close and " 858 DBG(1, "The camera is misconfigured. To use it, close and "
802 "open /dev/video%d again.", cam->v4ldev->minor) 859 "open /dev/video%d again.", cam->v4ldev->minor);
803 return err; 860 return err;
804 } 861 }
805 862
@@ -885,8 +942,8 @@ sn9c102_store_reg(struct class_device* cd, const char* buf, size_t len)
885 942
886 cam->sysfs.reg = index; 943 cam->sysfs.reg = index;
887 944
888 DBG(2, "Moved SN9C10X register index to 0x%02X", cam->sysfs.reg) 945 DBG(2, "Moved SN9C10X register index to 0x%02X", cam->sysfs.reg);
889 DBG(3, "Written bytes: %zd", count) 946 DBG(3, "Written bytes: %zd", count);
890 947
891 up(&sn9c102_sysfs_lock); 948 up(&sn9c102_sysfs_lock);
892 949
@@ -916,7 +973,7 @@ static ssize_t sn9c102_show_val(struct class_device* cd, char* buf)
916 973
917 count = sprintf(buf, "%d\n", val); 974 count = sprintf(buf, "%d\n", val);
918 975
919 DBG(3, "Read bytes: %zd", count) 976 DBG(3, "Read bytes: %zd", count);
920 977
921 up(&sn9c102_sysfs_lock); 978 up(&sn9c102_sysfs_lock);
922 979
@@ -954,8 +1011,8 @@ sn9c102_store_val(struct class_device* cd, const char* buf, size_t len)
954 } 1011 }
955 1012
956 DBG(2, "Written SN9C10X reg. 0x%02X, val. 0x%02X", 1013 DBG(2, "Written SN9C10X reg. 0x%02X, val. 0x%02X",
957 cam->sysfs.reg, value) 1014 cam->sysfs.reg, value);
958 DBG(3, "Written bytes: %zd", count) 1015 DBG(3, "Written bytes: %zd", count);
959 1016
960 up(&sn9c102_sysfs_lock); 1017 up(&sn9c102_sysfs_lock);
961 1018
@@ -979,7 +1036,7 @@ static ssize_t sn9c102_show_i2c_reg(struct class_device* cd, char* buf)
979 1036
980 count = sprintf(buf, "%u\n", cam->sysfs.i2c_reg); 1037 count = sprintf(buf, "%u\n", cam->sysfs.i2c_reg);
981 1038
982 DBG(3, "Read bytes: %zd", count) 1039 DBG(3, "Read bytes: %zd", count);
983 1040
984 up(&sn9c102_sysfs_lock); 1041 up(&sn9c102_sysfs_lock);
985 1042
@@ -1011,8 +1068,8 @@ sn9c102_store_i2c_reg(struct class_device* cd, const char* buf, size_t len)
1011 1068
1012 cam->sysfs.i2c_reg = index; 1069 cam->sysfs.i2c_reg = index;
1013 1070
1014 DBG(2, "Moved sensor register index to 0x%02X", cam->sysfs.i2c_reg) 1071 DBG(2, "Moved sensor register index to 0x%02X", cam->sysfs.i2c_reg);
1015 DBG(3, "Written bytes: %zd", count) 1072 DBG(3, "Written bytes: %zd", count);
1016 1073
1017 up(&sn9c102_sysfs_lock); 1074 up(&sn9c102_sysfs_lock);
1018 1075
@@ -1047,7 +1104,7 @@ static ssize_t sn9c102_show_i2c_val(struct class_device* cd, char* buf)
1047 1104
1048 count = sprintf(buf, "%d\n", val); 1105 count = sprintf(buf, "%d\n", val);
1049 1106
1050 DBG(3, "Read bytes: %zd", count) 1107 DBG(3, "Read bytes: %zd", count);
1051 1108
1052 up(&sn9c102_sysfs_lock); 1109 up(&sn9c102_sysfs_lock);
1053 1110
@@ -1090,8 +1147,8 @@ sn9c102_store_i2c_val(struct class_device* cd, const char* buf, size_t len)
1090 } 1147 }
1091 1148
1092 DBG(2, "Written sensor reg. 0x%02X, val. 0x%02X", 1149 DBG(2, "Written sensor reg. 0x%02X, val. 0x%02X",
1093 cam->sysfs.i2c_reg, value) 1150 cam->sysfs.i2c_reg, value);
1094 DBG(3, "Written bytes: %zd", count) 1151 DBG(3, "Written bytes: %zd", count);
1095 1152
1096 up(&sn9c102_sysfs_lock); 1153 up(&sn9c102_sysfs_lock);
1097 1154
@@ -1193,7 +1250,7 @@ static ssize_t sn9c102_show_frame_header(struct class_device* cd, char* buf)
1193 count = sizeof(cam->sysfs.frame_header); 1250 count = sizeof(cam->sysfs.frame_header);
1194 memcpy(buf, cam->sysfs.frame_header, count); 1251 memcpy(buf, cam->sysfs.frame_header, count);
1195 1252
1196 DBG(3, "Frame header, read bytes: %zd", count) 1253 DBG(3, "Frame header, read bytes: %zd", count);
1197 1254
1198 return count; 1255 return count;
1199} 1256}
@@ -1227,7 +1284,7 @@ static void sn9c102_create_sysfs(struct sn9c102_device* cam)
1227 video_device_create_file(v4ldev, &class_device_attr_blue); 1284 video_device_create_file(v4ldev, &class_device_attr_blue);
1228 video_device_create_file(v4ldev, &class_device_attr_red); 1285 video_device_create_file(v4ldev, &class_device_attr_red);
1229 } 1286 }
1230 if (cam->sensor->sysfs_ops) { 1287 if (cam->sensor && cam->sensor->sysfs_ops) {
1231 video_device_create_file(v4ldev, &class_device_attr_i2c_reg); 1288 video_device_create_file(v4ldev, &class_device_attr_i2c_reg);
1232 video_device_create_file(v4ldev, &class_device_attr_i2c_val); 1289 video_device_create_file(v4ldev, &class_device_attr_i2c_val);
1233 } 1290 }
@@ -1281,7 +1338,7 @@ static int sn9c102_set_scale(struct sn9c102_device* cam, u8 scale)
1281 if (err) 1338 if (err)
1282 return -EIO; 1339 return -EIO;
1283 1340
1284 PDBGG("Scaling factor: %u", scale) 1341 PDBGG("Scaling factor: %u", scale);
1285 1342
1286 return 0; 1343 return 0;
1287} 1344}
@@ -1304,7 +1361,7 @@ static int sn9c102_set_crop(struct sn9c102_device* cam, struct v4l2_rect* rect)
1304 return -EIO; 1361 return -EIO;
1305 1362
1306 PDBGG("h_start, v_start, h_size, v_size, ho_size, vo_size " 1363 PDBGG("h_start, v_start, h_size, v_size, ho_size, vo_size "
1307 "%u %u %u %u", h_start, v_start, h_size, v_size) 1364 "%u %u %u %u", h_start, v_start, h_size, v_size);
1308 1365
1309 return 0; 1366 return 0;
1310} 1367}
@@ -1336,7 +1393,7 @@ static int sn9c102_init(struct sn9c102_device* cam)
1336 if (s->init) { 1393 if (s->init) {
1337 err = s->init(cam); 1394 err = s->init(cam);
1338 if (err) { 1395 if (err) {
1339 DBG(3, "Sensor initialization failed") 1396 DBG(3, "Sensor initialization failed");
1340 return err; 1397 return err;
1341 } 1398 }
1342 } 1399 }
@@ -1353,13 +1410,13 @@ static int sn9c102_init(struct sn9c102_device* cam)
1353 1410
1354 if (s->pix_format.pixelformat == V4L2_PIX_FMT_SN9C10X) 1411 if (s->pix_format.pixelformat == V4L2_PIX_FMT_SN9C10X)
1355 DBG(3, "Compressed video format is active, quality %d", 1412 DBG(3, "Compressed video format is active, quality %d",
1356 cam->compression.quality) 1413 cam->compression.quality);
1357 else 1414 else
1358 DBG(3, "Uncompressed video format is active") 1415 DBG(3, "Uncompressed video format is active");
1359 1416
1360 if (s->set_crop) 1417 if (s->set_crop)
1361 if ((err = s->set_crop(cam, rect))) { 1418 if ((err = s->set_crop(cam, rect))) {
1362 DBG(3, "set_crop() failed") 1419 DBG(3, "set_crop() failed");
1363 return err; 1420 return err;
1364 } 1421 }
1365 1422
@@ -1372,11 +1429,11 @@ static int sn9c102_init(struct sn9c102_device* cam)
1372 err = s->set_ctrl(cam, &ctrl); 1429 err = s->set_ctrl(cam, &ctrl);
1373 if (err) { 1430 if (err) {
1374 DBG(3, "Set %s control failed", 1431 DBG(3, "Set %s control failed",
1375 s->qctrl[i].name) 1432 s->qctrl[i].name);
1376 return err; 1433 return err;
1377 } 1434 }
1378 DBG(3, "Image sensor supports '%s' control", 1435 DBG(3, "Image sensor supports '%s' control",
1379 s->qctrl[i].name) 1436 s->qctrl[i].name);
1380 } 1437 }
1381 } 1438 }
1382 1439
@@ -1392,7 +1449,7 @@ static int sn9c102_init(struct sn9c102_device* cam)
1392 cam->state |= DEV_INITIALIZED; 1449 cam->state |= DEV_INITIALIZED;
1393 } 1450 }
1394 1451
1395 DBG(2, "Initialization succeeded") 1452 DBG(2, "Initialization succeeded");
1396 return 0; 1453 return 0;
1397} 1454}
1398 1455
@@ -1401,7 +1458,7 @@ static void sn9c102_release_resources(struct sn9c102_device* cam)
1401{ 1458{
1402 down(&sn9c102_sysfs_lock); 1459 down(&sn9c102_sysfs_lock);
1403 1460
1404 DBG(2, "V4L2 device /dev/video%d deregistered", cam->v4ldev->minor) 1461 DBG(2, "V4L2 device /dev/video%d deregistered", cam->v4ldev->minor);
1405 video_set_drvdata(cam->v4ldev, NULL); 1462 video_set_drvdata(cam->v4ldev, NULL);
1406 video_unregister_device(cam->v4ldev); 1463 video_unregister_device(cam->v4ldev);
1407 1464
@@ -1432,7 +1489,7 @@ static int sn9c102_open(struct inode* inode, struct file* filp)
1432 } 1489 }
1433 1490
1434 if (cam->users) { 1491 if (cam->users) {
1435 DBG(2, "Device /dev/video%d is busy...", cam->v4ldev->minor) 1492 DBG(2, "Device /dev/video%d is busy...", cam->v4ldev->minor);
1436 if ((filp->f_flags & O_NONBLOCK) || 1493 if ((filp->f_flags & O_NONBLOCK) ||
1437 (filp->f_flags & O_NDELAY)) { 1494 (filp->f_flags & O_NDELAY)) {
1438 err = -EWOULDBLOCK; 1495 err = -EWOULDBLOCK;
@@ -1458,7 +1515,7 @@ static int sn9c102_open(struct inode* inode, struct file* filp)
1458 err = sn9c102_init(cam); 1515 err = sn9c102_init(cam);
1459 if (err) { 1516 if (err) {
1460 DBG(1, "Initialization failed again. " 1517 DBG(1, "Initialization failed again. "
1461 "I will retry on next open().") 1518 "I will retry on next open().");
1462 goto out; 1519 goto out;
1463 } 1520 }
1464 cam->state &= ~DEV_MISCONFIGURED; 1521 cam->state &= ~DEV_MISCONFIGURED;
@@ -1475,7 +1532,7 @@ static int sn9c102_open(struct inode* inode, struct file* filp)
1475 cam->frame_count = 0; 1532 cam->frame_count = 0;
1476 sn9c102_empty_framequeues(cam); 1533 sn9c102_empty_framequeues(cam);
1477 1534
1478 DBG(3, "Video device /dev/video%d is open", cam->v4ldev->minor) 1535 DBG(3, "Video device /dev/video%d is open", cam->v4ldev->minor);
1479 1536
1480out: 1537out:
1481 up(&cam->dev_sem); 1538 up(&cam->dev_sem);
@@ -1504,7 +1561,7 @@ static int sn9c102_release(struct inode* inode, struct file* filp)
1504 cam->users--; 1561 cam->users--;
1505 wake_up_interruptible_nr(&cam->open, 1); 1562 wake_up_interruptible_nr(&cam->open, 1);
1506 1563
1507 DBG(3, "Video device /dev/video%d closed", cam->v4ldev->minor) 1564 DBG(3, "Video device /dev/video%d closed", cam->v4ldev->minor);
1508 1565
1509 up(&cam->dev_sem); 1566 up(&cam->dev_sem);
1510 1567
@@ -1524,32 +1581,38 @@ sn9c102_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos)
1524 return -ERESTARTSYS; 1581 return -ERESTARTSYS;
1525 1582
1526 if (cam->state & DEV_DISCONNECTED) { 1583 if (cam->state & DEV_DISCONNECTED) {
1527 DBG(1, "Device not present") 1584 DBG(1, "Device not present");
1528 up(&cam->fileop_sem); 1585 up(&cam->fileop_sem);
1529 return -ENODEV; 1586 return -ENODEV;
1530 } 1587 }
1531 1588
1532 if (cam->state & DEV_MISCONFIGURED) { 1589 if (cam->state & DEV_MISCONFIGURED) {
1533 DBG(1, "The camera is misconfigured. Close and open it again.") 1590 DBG(1, "The camera is misconfigured. Close and open it "
1591 "again.");
1534 up(&cam->fileop_sem); 1592 up(&cam->fileop_sem);
1535 return -EIO; 1593 return -EIO;
1536 } 1594 }
1537 1595
1538 if (cam->io == IO_MMAP) { 1596 if (cam->io == IO_MMAP) {
1539 DBG(3, "Close and open the device again to choose " 1597 DBG(3, "Close and open the device again to choose "
1540 "the read method") 1598 "the read method");
1541 up(&cam->fileop_sem); 1599 up(&cam->fileop_sem);
1542 return -EINVAL; 1600 return -EINVAL;
1543 } 1601 }
1544 1602
1545 if (cam->io == IO_NONE) { 1603 if (cam->io == IO_NONE) {
1546 if (!sn9c102_request_buffers(cam,cam->nreadbuffers, IO_READ)) { 1604 if (!sn9c102_request_buffers(cam,cam->nreadbuffers, IO_READ)) {
1547 DBG(1, "read() failed, not enough memory") 1605 DBG(1, "read() failed, not enough memory");
1548 up(&cam->fileop_sem); 1606 up(&cam->fileop_sem);
1549 return -ENOMEM; 1607 return -ENOMEM;
1550 } 1608 }
1551 cam->io = IO_READ; 1609 cam->io = IO_READ;
1552 cam->stream = STREAM_ON; 1610 cam->stream = STREAM_ON;
1611 }
1612
1613 if (list_empty(&cam->inqueue)) {
1614 if (!list_empty(&cam->outqueue))
1615 sn9c102_empty_framequeues(cam);
1553 sn9c102_queue_unusedframes(cam); 1616 sn9c102_queue_unusedframes(cam);
1554 } 1617 }
1555 1618
@@ -1584,6 +1647,16 @@ sn9c102_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos)
1584 1647
1585 f = list_entry(cam->outqueue.prev, struct sn9c102_frame_t, frame); 1648 f = list_entry(cam->outqueue.prev, struct sn9c102_frame_t, frame);
1586 1649
1650 if (count > f->buf.bytesused)
1651 count = f->buf.bytesused;
1652
1653 if (copy_to_user(buf, f->bufmem, count)) {
1654 err = -EFAULT;
1655 goto exit;
1656 }
1657 *f_pos += count;
1658
1659exit:
1587 spin_lock_irqsave(&cam->queue_lock, lock_flags); 1660 spin_lock_irqsave(&cam->queue_lock, lock_flags);
1588 list_for_each_entry(i, &cam->outqueue, frame) 1661 list_for_each_entry(i, &cam->outqueue, frame)
1589 i->state = F_UNUSED; 1662 i->state = F_UNUSED;
@@ -1592,16 +1665,8 @@ sn9c102_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos)
1592 1665
1593 sn9c102_queue_unusedframes(cam); 1666 sn9c102_queue_unusedframes(cam);
1594 1667
1595 if (count > f->buf.bytesused) 1668 PDBGG("Frame #%lu, bytes read: %zu",
1596 count = f->buf.bytesused; 1669 (unsigned long)f->buf.index, count);
1597
1598 if (copy_to_user(buf, f->bufmem, count)) {
1599 up(&cam->fileop_sem);
1600 return -EFAULT;
1601 }
1602 *f_pos += count;
1603
1604 PDBGG("Frame #%lu, bytes read: %zu", (unsigned long)f->buf.index,count)
1605 1670
1606 up(&cam->fileop_sem); 1671 up(&cam->fileop_sem);
1607 1672
@@ -1612,33 +1677,42 @@ sn9c102_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos)
1612static unsigned int sn9c102_poll(struct file *filp, poll_table *wait) 1677static unsigned int sn9c102_poll(struct file *filp, poll_table *wait)
1613{ 1678{
1614 struct sn9c102_device* cam = video_get_drvdata(video_devdata(filp)); 1679 struct sn9c102_device* cam = video_get_drvdata(video_devdata(filp));
1680 struct sn9c102_frame_t* f;
1681 unsigned long lock_flags;
1615 unsigned int mask = 0; 1682 unsigned int mask = 0;
1616 1683
1617 if (down_interruptible(&cam->fileop_sem)) 1684 if (down_interruptible(&cam->fileop_sem))
1618 return POLLERR; 1685 return POLLERR;
1619 1686
1620 if (cam->state & DEV_DISCONNECTED) { 1687 if (cam->state & DEV_DISCONNECTED) {
1621 DBG(1, "Device not present") 1688 DBG(1, "Device not present");
1622 goto error; 1689 goto error;
1623 } 1690 }
1624 1691
1625 if (cam->state & DEV_MISCONFIGURED) { 1692 if (cam->state & DEV_MISCONFIGURED) {
1626 DBG(1, "The camera is misconfigured. Close and open it again.") 1693 DBG(1, "The camera is misconfigured. Close and open it "
1694 "again.");
1627 goto error; 1695 goto error;
1628 } 1696 }
1629 1697
1630 if (cam->io == IO_NONE) { 1698 if (cam->io == IO_NONE) {
1631 if (!sn9c102_request_buffers(cam, cam->nreadbuffers, 1699 if (!sn9c102_request_buffers(cam, cam->nreadbuffers,
1632 IO_READ)) { 1700 IO_READ)) {
1633 DBG(1, "poll() failed, not enough memory") 1701 DBG(1, "poll() failed, not enough memory");
1634 goto error; 1702 goto error;
1635 } 1703 }
1636 cam->io = IO_READ; 1704 cam->io = IO_READ;
1637 cam->stream = STREAM_ON; 1705 cam->stream = STREAM_ON;
1638 } 1706 }
1639 1707
1640 if (cam->io == IO_READ) 1708 if (cam->io == IO_READ) {
1709 spin_lock_irqsave(&cam->queue_lock, lock_flags);
1710 list_for_each_entry(f, &cam->outqueue, frame)
1711 f->state = F_UNUSED;
1712 INIT_LIST_HEAD(&cam->outqueue);
1713 spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
1641 sn9c102_queue_unusedframes(cam); 1714 sn9c102_queue_unusedframes(cam);
1715 }
1642 1716
1643 poll_wait(filp, &cam->wait_frame, wait); 1717 poll_wait(filp, &cam->wait_frame, wait);
1644 1718
@@ -1689,13 +1763,14 @@ static int sn9c102_mmap(struct file* filp, struct vm_area_struct *vma)
1689 return -ERESTARTSYS; 1763 return -ERESTARTSYS;
1690 1764
1691 if (cam->state & DEV_DISCONNECTED) { 1765 if (cam->state & DEV_DISCONNECTED) {
1692 DBG(1, "Device not present") 1766 DBG(1, "Device not present");
1693 up(&cam->fileop_sem); 1767 up(&cam->fileop_sem);
1694 return -ENODEV; 1768 return -ENODEV;
1695 } 1769 }
1696 1770
1697 if (cam->state & DEV_MISCONFIGURED) { 1771 if (cam->state & DEV_MISCONFIGURED) {
1698 DBG(1, "The camera is misconfigured. Close and open it again.") 1772 DBG(1, "The camera is misconfigured. Close and open it "
1773 "again.");
1699 up(&cam->fileop_sem); 1774 up(&cam->fileop_sem);
1700 return -EIO; 1775 return -EIO;
1701 } 1776 }
@@ -1742,738 +1817,860 @@ static int sn9c102_mmap(struct file* filp, struct vm_area_struct *vma)
1742 return 0; 1817 return 0;
1743} 1818}
1744 1819
1820/*****************************************************************************/
1745 1821
1746static int sn9c102_ioctl_v4l2(struct inode* inode, struct file* filp, 1822static int
1747 unsigned int cmd, void __user * arg) 1823sn9c102_vidioc_querycap(struct sn9c102_device* cam, void __user * arg)
1748{ 1824{
1749 struct sn9c102_device* cam = video_get_drvdata(video_devdata(filp)); 1825 struct v4l2_capability cap = {
1826 .driver = "sn9c102",
1827 .version = SN9C102_MODULE_VERSION_CODE,
1828 .capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
1829 V4L2_CAP_STREAMING,
1830 };
1831
1832 strlcpy(cap.card, cam->v4ldev->name, sizeof(cap.card));
1833 if (usb_make_path(cam->usbdev, cap.bus_info, sizeof(cap.bus_info)) < 0)
1834 strlcpy(cap.bus_info, cam->dev.bus_id, sizeof(cap.bus_info));
1835
1836 if (copy_to_user(arg, &cap, sizeof(cap)))
1837 return -EFAULT;
1750 1838
1751 switch (cmd) { 1839 return 0;
1840}
1752 1841
1753 case VIDIOC_QUERYCAP:
1754 {
1755 struct v4l2_capability cap = {
1756 .driver = "sn9c102",
1757 .version = SN9C102_MODULE_VERSION_CODE,
1758 .capabilities = V4L2_CAP_VIDEO_CAPTURE |
1759 V4L2_CAP_READWRITE |
1760 V4L2_CAP_STREAMING,
1761 };
1762
1763 strlcpy(cap.card, cam->v4ldev->name, sizeof(cap.card));
1764 if (usb_make_path(cam->usbdev, cap.bus_info,
1765 sizeof(cap.bus_info)) < 0)
1766 strlcpy(cap.bus_info, cam->dev.bus_id,
1767 sizeof(cap.bus_info));
1768
1769 if (copy_to_user(arg, &cap, sizeof(cap)))
1770 return -EFAULT;
1771 1842
1772 return 0; 1843static int
1773 } 1844sn9c102_vidioc_enuminput(struct sn9c102_device* cam, void __user * arg)
1845{
1846 struct v4l2_input i;
1774 1847
1775 case VIDIOC_ENUMINPUT: 1848 if (copy_from_user(&i, arg, sizeof(i)))
1776 { 1849 return -EFAULT;
1777 struct v4l2_input i;
1778 1850
1779 if (copy_from_user(&i, arg, sizeof(i))) 1851 if (i.index)
1780 return -EFAULT; 1852 return -EINVAL;
1781 1853
1782 if (i.index) 1854 memset(&i, 0, sizeof(i));
1783 return -EINVAL; 1855 strcpy(i.name, "USB");
1784 1856
1785 memset(&i, 0, sizeof(i)); 1857 if (copy_to_user(arg, &i, sizeof(i)))
1786 strcpy(i.name, "USB"); 1858 return -EFAULT;
1787 1859
1788 if (copy_to_user(arg, &i, sizeof(i))) 1860 return 0;
1789 return -EFAULT; 1861}
1790 1862
1791 return 0;
1792 }
1793 1863
1794 case VIDIOC_G_INPUT: 1864static int
1795 case VIDIOC_S_INPUT: 1865sn9c102_vidioc_gs_input(struct sn9c102_device* cam, void __user * arg)
1796 { 1866{
1797 int index; 1867 int index;
1798 1868
1799 if (copy_from_user(&index, arg, sizeof(index))) 1869 if (copy_from_user(&index, arg, sizeof(index)))
1800 return -EFAULT; 1870 return -EFAULT;
1801 1871
1802 if (index != 0) 1872 if (index != 0)
1803 return -EINVAL; 1873 return -EINVAL;
1804 1874
1805 return 0; 1875 return 0;
1806 } 1876}
1807 1877
1808 case VIDIOC_QUERYCTRL:
1809 {
1810 struct sn9c102_sensor* s = cam->sensor;
1811 struct v4l2_queryctrl qc;
1812 u8 i;
1813 1878
1814 if (copy_from_user(&qc, arg, sizeof(qc))) 1879static int
1815 return -EFAULT; 1880sn9c102_vidioc_query_ctrl(struct sn9c102_device* cam, void __user * arg)
1881{
1882 struct sn9c102_sensor* s = cam->sensor;
1883 struct v4l2_queryctrl qc;
1884 u8 i;
1885
1886 if (copy_from_user(&qc, arg, sizeof(qc)))
1887 return -EFAULT;
1888
1889 for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
1890 if (qc.id && qc.id == s->qctrl[i].id) {
1891 memcpy(&qc, &(s->qctrl[i]), sizeof(qc));
1892 if (copy_to_user(arg, &qc, sizeof(qc)))
1893 return -EFAULT;
1894 return 0;
1895 }
1896
1897 return -EINVAL;
1898}
1899
1900
1901static int
1902sn9c102_vidioc_g_ctrl(struct sn9c102_device* cam, void __user * arg)
1903{
1904 struct sn9c102_sensor* s = cam->sensor;
1905 struct v4l2_control ctrl;
1906 int err = 0;
1907 u8 i;
1908
1909 if (!s->get_ctrl && !s->set_ctrl)
1910 return -EINVAL;
1816 1911
1912 if (copy_from_user(&ctrl, arg, sizeof(ctrl)))
1913 return -EFAULT;
1914
1915 if (!s->get_ctrl) {
1817 for (i = 0; i < ARRAY_SIZE(s->qctrl); i++) 1916 for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
1818 if (qc.id && qc.id == s->qctrl[i].id) { 1917 if (ctrl.id && ctrl.id == s->qctrl[i].id) {
1819 memcpy(&qc, &(s->qctrl[i]), sizeof(qc)); 1918 ctrl.value = s->_qctrl[i].default_value;
1820 if (copy_to_user(arg, &qc, sizeof(qc))) 1919 goto exit;
1821 return -EFAULT;
1822 return 0;
1823 } 1920 }
1824
1825 return -EINVAL; 1921 return -EINVAL;
1826 } 1922 } else
1923 err = s->get_ctrl(cam, &ctrl);
1827 1924
1828 case VIDIOC_G_CTRL: 1925exit:
1829 { 1926 if (copy_to_user(arg, &ctrl, sizeof(ctrl)))
1830 struct sn9c102_sensor* s = cam->sensor; 1927 return -EFAULT;
1831 struct v4l2_control ctrl;
1832 int err = 0;
1833 1928
1834 if (!s->get_ctrl) 1929 return err;
1835 return -EINVAL; 1930}
1836 1931
1837 if (copy_from_user(&ctrl, arg, sizeof(ctrl)))
1838 return -EFAULT;
1839 1932
1840 err = s->get_ctrl(cam, &ctrl); 1933static int
1934sn9c102_vidioc_s_ctrl(struct sn9c102_device* cam, void __user * arg)
1935{
1936 struct sn9c102_sensor* s = cam->sensor;
1937 struct v4l2_control ctrl;
1938 u8 i;
1939 int err = 0;
1841 1940
1842 if (copy_to_user(arg, &ctrl, sizeof(ctrl))) 1941 if (!s->set_ctrl)
1843 return -EFAULT; 1942 return -EINVAL;
1844 1943
1944 if (copy_from_user(&ctrl, arg, sizeof(ctrl)))
1945 return -EFAULT;
1946
1947 for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
1948 if (ctrl.id == s->qctrl[i].id) {
1949 if (ctrl.value < s->qctrl[i].minimum ||
1950 ctrl.value > s->qctrl[i].maximum)
1951 return -ERANGE;
1952 ctrl.value -= ctrl.value % s->qctrl[i].step;
1953 break;
1954 }
1955
1956 if ((err = s->set_ctrl(cam, &ctrl)))
1845 return err; 1957 return err;
1846 }
1847 1958
1848 case VIDIOC_S_CTRL_OLD: 1959 s->_qctrl[i].default_value = ctrl.value;
1849 case VIDIOC_S_CTRL:
1850 {
1851 struct sn9c102_sensor* s = cam->sensor;
1852 struct v4l2_control ctrl;
1853 u8 i;
1854 int err = 0;
1855 1960
1856 if (!s->set_ctrl) 1961 PDBGG("VIDIOC_S_CTRL: id %lu, value %lu",
1857 return -EINVAL; 1962 (unsigned long)ctrl.id, (unsigned long)ctrl.value);
1858 1963
1859 if (copy_from_user(&ctrl, arg, sizeof(ctrl))) 1964 return 0;
1860 return -EFAULT; 1965}
1861 1966
1862 for (i = 0; i < ARRAY_SIZE(s->qctrl); i++) 1967
1863 if (ctrl.id == s->qctrl[i].id) { 1968static int
1864 if (ctrl.value < s->qctrl[i].minimum || 1969sn9c102_vidioc_cropcap(struct sn9c102_device* cam, void __user * arg)
1865 ctrl.value > s->qctrl[i].maximum) 1970{
1866 return -ERANGE; 1971 struct v4l2_cropcap* cc = &(cam->sensor->cropcap);
1867 ctrl.value -= ctrl.value % s->qctrl[i].step; 1972
1868 break; 1973 cc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1974 cc->pixelaspect.numerator = 1;
1975 cc->pixelaspect.denominator = 1;
1976
1977 if (copy_to_user(arg, cc, sizeof(*cc)))
1978 return -EFAULT;
1979
1980 return 0;
1981}
1982
1983
1984static int
1985sn9c102_vidioc_g_crop(struct sn9c102_device* cam, void __user * arg)
1986{
1987 struct sn9c102_sensor* s = cam->sensor;
1988 struct v4l2_crop crop = {
1989 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
1990 };
1991
1992 memcpy(&(crop.c), &(s->_rect), sizeof(struct v4l2_rect));
1993
1994 if (copy_to_user(arg, &crop, sizeof(crop)))
1995 return -EFAULT;
1996
1997 return 0;
1998}
1999
2000
2001static int
2002sn9c102_vidioc_s_crop(struct sn9c102_device* cam, void __user * arg)
2003{
2004 struct sn9c102_sensor* s = cam->sensor;
2005 struct v4l2_crop crop;
2006 struct v4l2_rect* rect;
2007 struct v4l2_rect* bounds = &(s->cropcap.bounds);
2008 struct v4l2_pix_format* pix_format = &(s->pix_format);
2009 u8 scale;
2010 const enum sn9c102_stream_state stream = cam->stream;
2011 const u32 nbuffers = cam->nbuffers;
2012 u32 i;
2013 int err = 0;
2014
2015 if (copy_from_user(&crop, arg, sizeof(crop)))
2016 return -EFAULT;
2017
2018 rect = &(crop.c);
2019
2020 if (crop.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
2021 return -EINVAL;
2022
2023 if (cam->module_param.force_munmap)
2024 for (i = 0; i < cam->nbuffers; i++)
2025 if (cam->frame[i].vma_use_count) {
2026 DBG(3, "VIDIOC_S_CROP failed. "
2027 "Unmap the buffers first.");
2028 return -EINVAL;
1869 } 2029 }
1870 2030
1871 if ((err = s->set_ctrl(cam, &ctrl))) 2031 /* Preserve R,G or B origin */
2032 rect->left = (s->_rect.left & 1L) ? rect->left | 1L : rect->left & ~1L;
2033 rect->top = (s->_rect.top & 1L) ? rect->top | 1L : rect->top & ~1L;
2034
2035 if (rect->width < 16)
2036 rect->width = 16;
2037 if (rect->height < 16)
2038 rect->height = 16;
2039 if (rect->width > bounds->width)
2040 rect->width = bounds->width;
2041 if (rect->height > bounds->height)
2042 rect->height = bounds->height;
2043 if (rect->left < bounds->left)
2044 rect->left = bounds->left;
2045 if (rect->top < bounds->top)
2046 rect->top = bounds->top;
2047 if (rect->left + rect->width > bounds->left + bounds->width)
2048 rect->left = bounds->left+bounds->width - rect->width;
2049 if (rect->top + rect->height > bounds->top + bounds->height)
2050 rect->top = bounds->top+bounds->height - rect->height;
2051
2052 rect->width &= ~15L;
2053 rect->height &= ~15L;
2054
2055 if (SN9C102_PRESERVE_IMGSCALE) {
2056 /* Calculate the actual scaling factor */
2057 u32 a, b;
2058 a = rect->width * rect->height;
2059 b = pix_format->width * pix_format->height;
2060 scale = b ? (u8)((a / b) < 4 ? 1 : ((a / b) < 16 ? 2 : 4)) : 1;
2061 } else
2062 scale = 1;
2063
2064 if (cam->stream == STREAM_ON)
2065 if ((err = sn9c102_stream_interrupt(cam)))
1872 return err; 2066 return err;
1873 2067
1874 s->_qctrl[i].default_value = ctrl.value; 2068 if (copy_to_user(arg, &crop, sizeof(crop))) {
2069 cam->stream = stream;
2070 return -EFAULT;
2071 }
1875 2072
1876 PDBGG("VIDIOC_S_CTRL: id %lu, value %lu", 2073 if (cam->module_param.force_munmap || cam->io == IO_READ)
1877 (unsigned long)ctrl.id, (unsigned long)ctrl.value) 2074 sn9c102_release_buffers(cam);
1878 2075
1879 return 0; 2076 err = sn9c102_set_crop(cam, rect);
2077 if (s->set_crop)
2078 err += s->set_crop(cam, rect);
2079 err += sn9c102_set_scale(cam, scale);
2080
2081 if (err) { /* atomic, no rollback in ioctl() */
2082 cam->state |= DEV_MISCONFIGURED;
2083 DBG(1, "VIDIOC_S_CROP failed because of hardware problems. To "
2084 "use the camera, close and open /dev/video%d again.",
2085 cam->v4ldev->minor);
2086 return -EIO;
1880 } 2087 }
1881 2088
1882 case VIDIOC_CROPCAP: 2089 s->pix_format.width = rect->width/scale;
1883 { 2090 s->pix_format.height = rect->height/scale;
1884 struct v4l2_cropcap* cc = &(cam->sensor->cropcap); 2091 memcpy(&(s->_rect), rect, sizeof(*rect));
1885 2092
1886 cc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 2093 if ((cam->module_param.force_munmap || cam->io == IO_READ) &&
1887 cc->pixelaspect.numerator = 1; 2094 nbuffers != sn9c102_request_buffers(cam, nbuffers, cam->io)) {
1888 cc->pixelaspect.denominator = 1; 2095 cam->state |= DEV_MISCONFIGURED;
2096 DBG(1, "VIDIOC_S_CROP failed because of not enough memory. To "
2097 "use the camera, close and open /dev/video%d again.",
2098 cam->v4ldev->minor);
2099 return -ENOMEM;
2100 }
1889 2101
1890 if (copy_to_user(arg, cc, sizeof(*cc))) 2102 if (cam->io == IO_READ)
1891 return -EFAULT; 2103 sn9c102_empty_framequeues(cam);
2104 else if (cam->module_param.force_munmap)
2105 sn9c102_requeue_outqueue(cam);
1892 2106
1893 return 0; 2107 cam->stream = stream;
1894 }
1895 2108
1896 case VIDIOC_G_CROP: 2109 return 0;
1897 { 2110}
1898 struct sn9c102_sensor* s = cam->sensor;
1899 struct v4l2_crop crop = {
1900 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
1901 };
1902 2111
1903 memcpy(&(crop.c), &(s->_rect), sizeof(struct v4l2_rect));
1904 2112
1905 if (copy_to_user(arg, &crop, sizeof(crop))) 2113static int
1906 return -EFAULT; 2114sn9c102_vidioc_enum_fmt(struct sn9c102_device* cam, void __user * arg)
2115{
2116 struct v4l2_fmtdesc fmtd;
1907 2117
1908 return 0; 2118 if (copy_from_user(&fmtd, arg, sizeof(fmtd)))
1909 } 2119 return -EFAULT;
1910 2120
1911 case VIDIOC_S_CROP: 2121 if (fmtd.index == 0) {
1912 { 2122 strcpy(fmtd.description, "bayer rgb");
1913 struct sn9c102_sensor* s = cam->sensor; 2123 fmtd.pixelformat = V4L2_PIX_FMT_SBGGR8;
1914 struct v4l2_crop crop; 2124 } else if (fmtd.index == 1) {
1915 struct v4l2_rect* rect; 2125 strcpy(fmtd.description, "compressed");
1916 struct v4l2_rect* bounds = &(s->cropcap.bounds); 2126 fmtd.pixelformat = V4L2_PIX_FMT_SN9C10X;
1917 struct v4l2_pix_format* pix_format = &(s->pix_format); 2127 fmtd.flags = V4L2_FMT_FLAG_COMPRESSED;
1918 u8 scale; 2128 } else
1919 const enum sn9c102_stream_state stream = cam->stream; 2129 return -EINVAL;
1920 const u32 nbuffers = cam->nbuffers;
1921 u32 i;
1922 int err = 0;
1923
1924 if (copy_from_user(&crop, arg, sizeof(crop)))
1925 return -EFAULT;
1926 2130
1927 rect = &(crop.c); 2131 fmtd.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2132 memset(&fmtd.reserved, 0, sizeof(fmtd.reserved));
1928 2133
1929 if (crop.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 2134 if (copy_to_user(arg, &fmtd, sizeof(fmtd)))
1930 return -EINVAL; 2135 return -EFAULT;
1931 2136
1932 if (cam->module_param.force_munmap) 2137 return 0;
1933 for (i = 0; i < cam->nbuffers; i++) 2138}
1934 if (cam->frame[i].vma_use_count) {
1935 DBG(3, "VIDIOC_S_CROP failed. "
1936 "Unmap the buffers first.")
1937 return -EINVAL;
1938 }
1939 2139
1940 /* Preserve R,G or B origin */
1941 rect->left = (s->_rect.left & 1L) ?
1942 rect->left | 1L : rect->left & ~1L;
1943 rect->top = (s->_rect.top & 1L) ?
1944 rect->top | 1L : rect->top & ~1L;
1945
1946 if (rect->width < 16)
1947 rect->width = 16;
1948 if (rect->height < 16)
1949 rect->height = 16;
1950 if (rect->width > bounds->width)
1951 rect->width = bounds->width;
1952 if (rect->height > bounds->height)
1953 rect->height = bounds->height;
1954 if (rect->left < bounds->left)
1955 rect->left = bounds->left;
1956 if (rect->top < bounds->top)
1957 rect->top = bounds->top;
1958 if (rect->left + rect->width > bounds->left + bounds->width)
1959 rect->left = bounds->left+bounds->width - rect->width;
1960 if (rect->top + rect->height > bounds->top + bounds->height)
1961 rect->top = bounds->top+bounds->height - rect->height;
1962
1963 rect->width &= ~15L;
1964 rect->height &= ~15L;
1965
1966 if (SN9C102_PRESERVE_IMGSCALE) {
1967 /* Calculate the actual scaling factor */
1968 u32 a, b;
1969 a = rect->width * rect->height;
1970 b = pix_format->width * pix_format->height;
1971 scale = b ? (u8)((a / b) < 4 ? 1 :
1972 ((a / b) < 16 ? 2 : 4)) : 1;
1973 } else
1974 scale = 1;
1975
1976 if (cam->stream == STREAM_ON)
1977 if ((err = sn9c102_stream_interrupt(cam)))
1978 return err;
1979
1980 if (copy_to_user(arg, &crop, sizeof(crop))) {
1981 cam->stream = stream;
1982 return -EFAULT;
1983 }
1984 2140
1985 if (cam->module_param.force_munmap || cam->io == IO_READ) 2141static int
1986 sn9c102_release_buffers(cam); 2142sn9c102_vidioc_g_fmt(struct sn9c102_device* cam, void __user * arg)
2143{
2144 struct v4l2_format format;
2145 struct v4l2_pix_format* pfmt = &(cam->sensor->pix_format);
1987 2146
1988 err = sn9c102_set_crop(cam, rect); 2147 if (copy_from_user(&format, arg, sizeof(format)))
1989 if (s->set_crop) 2148 return -EFAULT;
1990 err += s->set_crop(cam, rect);
1991 err += sn9c102_set_scale(cam, scale);
1992 2149
1993 if (err) { /* atomic, no rollback in ioctl() */ 2150 if (format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1994 cam->state |= DEV_MISCONFIGURED; 2151 return -EINVAL;
1995 DBG(1, "VIDIOC_S_CROP failed because of hardware "
1996 "problems. To use the camera, close and open "
1997 "/dev/video%d again.", cam->v4ldev->minor)
1998 return -EIO;
1999 }
2000 2152
2001 s->pix_format.width = rect->width/scale; 2153 pfmt->bytesperline = (pfmt->pixelformat==V4L2_PIX_FMT_SN9C10X)
2002 s->pix_format.height = rect->height/scale; 2154 ? 0 : (pfmt->width * pfmt->priv) / 8;
2003 memcpy(&(s->_rect), rect, sizeof(*rect)); 2155 pfmt->sizeimage = pfmt->height * ((pfmt->width*pfmt->priv)/8);
2004 2156 pfmt->field = V4L2_FIELD_NONE;
2005 if ((cam->module_param.force_munmap || cam->io == IO_READ) && 2157 memcpy(&(format.fmt.pix), pfmt, sizeof(*pfmt));
2006 nbuffers != sn9c102_request_buffers(cam, nbuffers,
2007 cam->io)) {
2008 cam->state |= DEV_MISCONFIGURED;
2009 DBG(1, "VIDIOC_S_CROP failed because of not enough "
2010 "memory. To use the camera, close and open "
2011 "/dev/video%d again.", cam->v4ldev->minor)
2012 return -ENOMEM;
2013 }
2014 2158
2015 cam->stream = stream; 2159 if (copy_to_user(arg, &format, sizeof(format)))
2160 return -EFAULT;
2016 2161
2017 return 0; 2162 return 0;
2018 } 2163}
2019 2164
2020 case VIDIOC_ENUM_FMT:
2021 {
2022 struct v4l2_fmtdesc fmtd;
2023 2165
2024 if (copy_from_user(&fmtd, arg, sizeof(fmtd))) 2166static int
2025 return -EFAULT; 2167sn9c102_vidioc_try_s_fmt(struct sn9c102_device* cam, unsigned int cmd,
2168 void __user * arg)
2169{
2170 struct sn9c102_sensor* s = cam->sensor;
2171 struct v4l2_format format;
2172 struct v4l2_pix_format* pix;
2173 struct v4l2_pix_format* pfmt = &(s->pix_format);
2174 struct v4l2_rect* bounds = &(s->cropcap.bounds);
2175 struct v4l2_rect rect;
2176 u8 scale;
2177 const enum sn9c102_stream_state stream = cam->stream;
2178 const u32 nbuffers = cam->nbuffers;
2179 u32 i;
2180 int err = 0;
2026 2181
2027 if (fmtd.index == 0) { 2182 if (copy_from_user(&format, arg, sizeof(format)))
2028 strcpy(fmtd.description, "bayer rgb"); 2183 return -EFAULT;
2029 fmtd.pixelformat = V4L2_PIX_FMT_SBGGR8;
2030 } else if (fmtd.index == 1) {
2031 strcpy(fmtd.description, "compressed");
2032 fmtd.pixelformat = V4L2_PIX_FMT_SN9C10X;
2033 fmtd.flags = V4L2_FMT_FLAG_COMPRESSED;
2034 } else
2035 return -EINVAL;
2036 2184
2037 fmtd.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 2185 pix = &(format.fmt.pix);
2038 memset(&fmtd.reserved, 0, sizeof(fmtd.reserved));
2039 2186
2040 if (copy_to_user(arg, &fmtd, sizeof(fmtd))) 2187 if (format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
2041 return -EFAULT; 2188 return -EINVAL;
2042 2189
2043 return 0; 2190 memcpy(&rect, &(s->_rect), sizeof(rect));
2191
2192 { /* calculate the actual scaling factor */
2193 u32 a, b;
2194 a = rect.width * rect.height;
2195 b = pix->width * pix->height;
2196 scale = b ? (u8)((a / b) < 4 ? 1 : ((a / b) < 16 ? 2 : 4)) : 1;
2044 } 2197 }
2045 2198
2046 case VIDIOC_G_FMT: 2199 rect.width = scale * pix->width;
2047 { 2200 rect.height = scale * pix->height;
2048 struct v4l2_format format;
2049 struct v4l2_pix_format* pfmt = &(cam->sensor->pix_format);
2050 2201
2051 if (copy_from_user(&format, arg, sizeof(format))) 2202 if (rect.width < 16)
2052 return -EFAULT; 2203 rect.width = 16;
2204 if (rect.height < 16)
2205 rect.height = 16;
2206 if (rect.width > bounds->left + bounds->width - rect.left)
2207 rect.width = bounds->left + bounds->width - rect.left;
2208 if (rect.height > bounds->top + bounds->height - rect.top)
2209 rect.height = bounds->top + bounds->height - rect.top;
2053 2210
2054 if (format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 2211 rect.width &= ~15L;
2055 return -EINVAL; 2212 rect.height &= ~15L;
2213
2214 { /* adjust the scaling factor */
2215 u32 a, b;
2216 a = rect.width * rect.height;
2217 b = pix->width * pix->height;
2218 scale = b ? (u8)((a / b) < 4 ? 1 : ((a / b) < 16 ? 2 : 4)) : 1;
2219 }
2220
2221 pix->width = rect.width / scale;
2222 pix->height = rect.height / scale;
2056 2223
2057 pfmt->bytesperline = (pfmt->pixelformat==V4L2_PIX_FMT_SN9C10X) 2224 if (pix->pixelformat != V4L2_PIX_FMT_SN9C10X &&
2058 ? 0 : (pfmt->width * pfmt->priv) / 8; 2225 pix->pixelformat != V4L2_PIX_FMT_SBGGR8)
2059 pfmt->sizeimage = pfmt->height * ((pfmt->width*pfmt->priv)/8); 2226 pix->pixelformat = pfmt->pixelformat;
2060 pfmt->field = V4L2_FIELD_NONE; 2227 pix->priv = pfmt->priv; /* bpp */
2061 memcpy(&(format.fmt.pix), pfmt, sizeof(*pfmt)); 2228 pix->colorspace = pfmt->colorspace;
2229 pix->bytesperline = (pix->pixelformat == V4L2_PIX_FMT_SN9C10X)
2230 ? 0 : (pix->width * pix->priv) / 8;
2231 pix->sizeimage = pix->height * ((pix->width * pix->priv) / 8);
2232 pix->field = V4L2_FIELD_NONE;
2062 2233
2234 if (cmd == VIDIOC_TRY_FMT) {
2063 if (copy_to_user(arg, &format, sizeof(format))) 2235 if (copy_to_user(arg, &format, sizeof(format)))
2064 return -EFAULT; 2236 return -EFAULT;
2065
2066 return 0; 2237 return 0;
2067 } 2238 }
2068 2239
2069 case VIDIOC_TRY_FMT: 2240 if (cam->module_param.force_munmap)
2070 case VIDIOC_S_FMT: 2241 for (i = 0; i < cam->nbuffers; i++)
2071 { 2242 if (cam->frame[i].vma_use_count) {
2072 struct sn9c102_sensor* s = cam->sensor; 2243 DBG(3, "VIDIOC_S_FMT failed. Unmap the "
2073 struct v4l2_format format; 2244 "buffers first.");
2074 struct v4l2_pix_format* pix; 2245 return -EINVAL;
2075 struct v4l2_pix_format* pfmt = &(s->pix_format); 2246 }
2076 struct v4l2_rect* bounds = &(s->cropcap.bounds);
2077 struct v4l2_rect rect;
2078 u8 scale;
2079 const enum sn9c102_stream_state stream = cam->stream;
2080 const u32 nbuffers = cam->nbuffers;
2081 u32 i;
2082 int err = 0;
2083
2084 if (copy_from_user(&format, arg, sizeof(format)))
2085 return -EFAULT;
2086 2247
2087 pix = &(format.fmt.pix); 2248 if (cam->stream == STREAM_ON)
2249 if ((err = sn9c102_stream_interrupt(cam)))
2250 return err;
2088 2251
2089 if (format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 2252 if (copy_to_user(arg, &format, sizeof(format))) {
2090 return -EINVAL; 2253 cam->stream = stream;
2254 return -EFAULT;
2255 }
2091 2256
2092 memcpy(&rect, &(s->_rect), sizeof(rect)); 2257 if (cam->module_param.force_munmap || cam->io == IO_READ)
2258 sn9c102_release_buffers(cam);
2093 2259
2094 { /* calculate the actual scaling factor */ 2260 err += sn9c102_set_pix_format(cam, pix);
2095 u32 a, b; 2261 err += sn9c102_set_crop(cam, &rect);
2096 a = rect.width * rect.height; 2262 if (s->set_pix_format)
2097 b = pix->width * pix->height; 2263 err += s->set_pix_format(cam, pix);
2098 scale = b ? (u8)((a / b) < 4 ? 1 : 2264 if (s->set_crop)
2099 ((a / b) < 16 ? 2 : 4)) : 1; 2265 err += s->set_crop(cam, &rect);
2100 } 2266 err += sn9c102_set_scale(cam, scale);
2101 2267
2102 rect.width = scale * pix->width; 2268 if (err) { /* atomic, no rollback in ioctl() */
2103 rect.height = scale * pix->height; 2269 cam->state |= DEV_MISCONFIGURED;
2104 2270 DBG(1, "VIDIOC_S_FMT failed because of hardware problems. To "
2105 if (rect.width < 16) 2271 "use the camera, close and open /dev/video%d again.",
2106 rect.width = 16; 2272 cam->v4ldev->minor);
2107 if (rect.height < 16) 2273 return -EIO;
2108 rect.height = 16; 2274 }
2109 if (rect.width > bounds->left + bounds->width - rect.left)
2110 rect.width = bounds->left + bounds->width - rect.left;
2111 if (rect.height > bounds->top + bounds->height - rect.top)
2112 rect.height = bounds->top + bounds->height - rect.top;
2113
2114 rect.width &= ~15L;
2115 rect.height &= ~15L;
2116
2117 { /* adjust the scaling factor */
2118 u32 a, b;
2119 a = rect.width * rect.height;
2120 b = pix->width * pix->height;
2121 scale = b ? (u8)((a / b) < 4 ? 1 :
2122 ((a / b) < 16 ? 2 : 4)) : 1;
2123 }
2124 2275
2125 pix->width = rect.width / scale; 2276 memcpy(pfmt, pix, sizeof(*pix));
2126 pix->height = rect.height / scale; 2277 memcpy(&(s->_rect), &rect, sizeof(rect));
2127
2128 if (pix->pixelformat != V4L2_PIX_FMT_SN9C10X &&
2129 pix->pixelformat != V4L2_PIX_FMT_SBGGR8)
2130 pix->pixelformat = pfmt->pixelformat;
2131 pix->priv = pfmt->priv; /* bpp */
2132 pix->colorspace = pfmt->colorspace;
2133 pix->bytesperline = (pix->pixelformat == V4L2_PIX_FMT_SN9C10X)
2134 ? 0 : (pix->width * pix->priv) / 8;
2135 pix->sizeimage = pix->height * ((pix->width * pix->priv) / 8);
2136 pix->field = V4L2_FIELD_NONE;
2137
2138 if (cmd == VIDIOC_TRY_FMT) {
2139 if (copy_to_user(arg, &format, sizeof(format)))
2140 return -EFAULT;
2141 return 0;
2142 }
2143 2278
2144 if (cam->module_param.force_munmap) 2279 if ((cam->module_param.force_munmap || cam->io == IO_READ) &&
2145 for (i = 0; i < cam->nbuffers; i++) 2280 nbuffers != sn9c102_request_buffers(cam, nbuffers, cam->io)) {
2146 if (cam->frame[i].vma_use_count) { 2281 cam->state |= DEV_MISCONFIGURED;
2147 DBG(3, "VIDIOC_S_FMT failed. " 2282 DBG(1, "VIDIOC_S_FMT failed because of not enough memory. To "
2148 "Unmap the buffers first.") 2283 "use the camera, close and open /dev/video%d again.",
2149 return -EINVAL; 2284 cam->v4ldev->minor);
2150 } 2285 return -ENOMEM;
2286 }
2151 2287
2152 if (cam->stream == STREAM_ON) 2288 if (cam->io == IO_READ)
2153 if ((err = sn9c102_stream_interrupt(cam))) 2289 sn9c102_empty_framequeues(cam);
2154 return err; 2290 else if (cam->module_param.force_munmap)
2291 sn9c102_requeue_outqueue(cam);
2155 2292
2156 if (copy_to_user(arg, &format, sizeof(format))) { 2293 cam->stream = stream;
2157 cam->stream = stream;
2158 return -EFAULT;
2159 }
2160 2294
2161 if (cam->module_param.force_munmap || cam->io == IO_READ) 2295 return 0;
2162 sn9c102_release_buffers(cam); 2296}
2163
2164 err += sn9c102_set_pix_format(cam, pix);
2165 err += sn9c102_set_crop(cam, &rect);
2166 if (s->set_pix_format)
2167 err += s->set_pix_format(cam, pix);
2168 if (s->set_crop)
2169 err += s->set_crop(cam, &rect);
2170 err += sn9c102_set_scale(cam, scale);
2171
2172 if (err) { /* atomic, no rollback in ioctl() */
2173 cam->state |= DEV_MISCONFIGURED;
2174 DBG(1, "VIDIOC_S_FMT failed because of hardware "
2175 "problems. To use the camera, close and open "
2176 "/dev/video%d again.", cam->v4ldev->minor)
2177 return -EIO;
2178 }
2179 2297
2180 memcpy(pfmt, pix, sizeof(*pix));
2181 memcpy(&(s->_rect), &rect, sizeof(rect));
2182 2298
2183 if ((cam->module_param.force_munmap || cam->io == IO_READ) && 2299static int
2184 nbuffers != sn9c102_request_buffers(cam, nbuffers, 2300sn9c102_vidioc_g_jpegcomp(struct sn9c102_device* cam, void __user * arg)
2185 cam->io)) { 2301{
2186 cam->state |= DEV_MISCONFIGURED; 2302 if (copy_to_user(arg, &cam->compression,
2187 DBG(1, "VIDIOC_S_FMT failed because of not enough " 2303 sizeof(cam->compression)))
2188 "memory. To use the camera, close and open " 2304 return -EFAULT;
2189 "/dev/video%d again.", cam->v4ldev->minor)
2190 return -ENOMEM;
2191 }
2192 2305
2193 cam->stream = stream; 2306 return 0;
2307}
2194 2308
2195 return 0;
2196 }
2197 2309
2198 case VIDIOC_G_JPEGCOMP: 2310static int
2199 { 2311sn9c102_vidioc_s_jpegcomp(struct sn9c102_device* cam, void __user * arg)
2200 if (copy_to_user(arg, &cam->compression, 2312{
2201 sizeof(cam->compression))) 2313 struct v4l2_jpegcompression jc;
2202 return -EFAULT; 2314 const enum sn9c102_stream_state stream = cam->stream;
2315 int err = 0;
2203 2316
2204 return 0; 2317 if (copy_from_user(&jc, arg, sizeof(jc)))
2205 } 2318 return -EFAULT;
2206 2319
2207 case VIDIOC_S_JPEGCOMP: 2320 if (jc.quality != 0 && jc.quality != 1)
2208 { 2321 return -EINVAL;
2209 struct v4l2_jpegcompression jc;
2210 const enum sn9c102_stream_state stream = cam->stream;
2211 int err = 0;
2212 2322
2213 if (copy_from_user(&jc, arg, sizeof(jc))) 2323 if (cam->stream == STREAM_ON)
2214 return -EFAULT; 2324 if ((err = sn9c102_stream_interrupt(cam)))
2325 return err;
2215 2326
2216 if (jc.quality != 0 && jc.quality != 1) 2327 err += sn9c102_set_compression(cam, &jc);
2217 return -EINVAL; 2328 if (err) { /* atomic, no rollback in ioctl() */
2329 cam->state |= DEV_MISCONFIGURED;
2330 DBG(1, "VIDIOC_S_JPEGCOMP failed because of hardware "
2331 "problems. To use the camera, close and open "
2332 "/dev/video%d again.", cam->v4ldev->minor);
2333 return -EIO;
2334 }
2218 2335
2219 if (cam->stream == STREAM_ON) 2336 cam->compression.quality = jc.quality;
2220 if ((err = sn9c102_stream_interrupt(cam)))
2221 return err;
2222 2337
2223 err += sn9c102_set_compression(cam, &jc); 2338 cam->stream = stream;
2224 if (err) { /* atomic, no rollback in ioctl() */
2225 cam->state |= DEV_MISCONFIGURED;
2226 DBG(1, "VIDIOC_S_JPEGCOMP failed because of hardware "
2227 "problems. To use the camera, close and open "
2228 "/dev/video%d again.", cam->v4ldev->minor)
2229 return -EIO;
2230 }
2231 2339
2232 cam->compression.quality = jc.quality; 2340 return 0;
2341}
2233 2342
2234 cam->stream = stream;
2235 2343
2236 return 0; 2344static int
2237 } 2345sn9c102_vidioc_reqbufs(struct sn9c102_device* cam, void __user * arg)
2346{
2347 struct v4l2_requestbuffers rb;
2348 u32 i;
2349 int err;
2238 2350
2239 case VIDIOC_REQBUFS: 2351 if (copy_from_user(&rb, arg, sizeof(rb)))
2240 { 2352 return -EFAULT;
2241 struct v4l2_requestbuffers rb;
2242 u32 i;
2243 int err;
2244 2353
2245 if (copy_from_user(&rb, arg, sizeof(rb))) 2354 if (rb.type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
2246 return -EFAULT; 2355 rb.memory != V4L2_MEMORY_MMAP)
2356 return -EINVAL;
2247 2357
2248 if (rb.type != V4L2_BUF_TYPE_VIDEO_CAPTURE || 2358 if (cam->io == IO_READ) {
2249 rb.memory != V4L2_MEMORY_MMAP) 2359 DBG(3, "Close and open the device again to choose the mmap "
2250 return -EINVAL; 2360 "I/O method");
2361 return -EINVAL;
2362 }
2251 2363
2252 if (cam->io == IO_READ) { 2364 for (i = 0; i < cam->nbuffers; i++)
2253 DBG(3, "Close and open the device again to choose " 2365 if (cam->frame[i].vma_use_count) {
2254 "the mmap I/O method") 2366 DBG(3, "VIDIOC_REQBUFS failed. Previous buffers are "
2367 "still mapped.");
2255 return -EINVAL; 2368 return -EINVAL;
2256 } 2369 }
2257 2370
2258 for (i = 0; i < cam->nbuffers; i++) 2371 if (cam->stream == STREAM_ON)
2259 if (cam->frame[i].vma_use_count) { 2372 if ((err = sn9c102_stream_interrupt(cam)))
2260 DBG(3, "VIDIOC_REQBUFS failed. " 2373 return err;
2261 "Previous buffers are still mapped.")
2262 return -EINVAL;
2263 }
2264 2374
2265 if (cam->stream == STREAM_ON) 2375 sn9c102_empty_framequeues(cam);
2266 if ((err = sn9c102_stream_interrupt(cam)))
2267 return err;
2268 2376
2269 sn9c102_empty_framequeues(cam); 2377 sn9c102_release_buffers(cam);
2378 if (rb.count)
2379 rb.count = sn9c102_request_buffers(cam, rb.count, IO_MMAP);
2270 2380
2381 if (copy_to_user(arg, &rb, sizeof(rb))) {
2271 sn9c102_release_buffers(cam); 2382 sn9c102_release_buffers(cam);
2272 if (rb.count) 2383 cam->io = IO_NONE;
2273 rb.count = sn9c102_request_buffers(cam, rb.count, 2384 return -EFAULT;
2274 IO_MMAP); 2385 }
2275 2386
2276 if (copy_to_user(arg, &rb, sizeof(rb))) { 2387 cam->io = rb.count ? IO_MMAP : IO_NONE;
2277 sn9c102_release_buffers(cam);
2278 cam->io = IO_NONE;
2279 return -EFAULT;
2280 }
2281 2388
2282 cam->io = rb.count ? IO_MMAP : IO_NONE; 2389 return 0;
2390}
2283 2391
2284 return 0;
2285 }
2286 2392
2287 case VIDIOC_QUERYBUF: 2393static int
2288 { 2394sn9c102_vidioc_querybuf(struct sn9c102_device* cam, void __user * arg)
2289 struct v4l2_buffer b; 2395{
2396 struct v4l2_buffer b;
2290 2397
2291 if (copy_from_user(&b, arg, sizeof(b))) 2398 if (copy_from_user(&b, arg, sizeof(b)))
2292 return -EFAULT; 2399 return -EFAULT;
2293 2400
2294 if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE || 2401 if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
2295 b.index >= cam->nbuffers || cam->io != IO_MMAP) 2402 b.index >= cam->nbuffers || cam->io != IO_MMAP)
2296 return -EINVAL; 2403 return -EINVAL;
2297 2404
2298 memcpy(&b, &cam->frame[b.index].buf, sizeof(b)); 2405 memcpy(&b, &cam->frame[b.index].buf, sizeof(b));
2299 2406
2300 if (cam->frame[b.index].vma_use_count) 2407 if (cam->frame[b.index].vma_use_count)
2301 b.flags |= V4L2_BUF_FLAG_MAPPED; 2408 b.flags |= V4L2_BUF_FLAG_MAPPED;
2302 2409
2303 if (cam->frame[b.index].state == F_DONE) 2410 if (cam->frame[b.index].state == F_DONE)
2304 b.flags |= V4L2_BUF_FLAG_DONE; 2411 b.flags |= V4L2_BUF_FLAG_DONE;
2305 else if (cam->frame[b.index].state != F_UNUSED) 2412 else if (cam->frame[b.index].state != F_UNUSED)
2306 b.flags |= V4L2_BUF_FLAG_QUEUED; 2413 b.flags |= V4L2_BUF_FLAG_QUEUED;
2307 2414
2308 if (copy_to_user(arg, &b, sizeof(b))) 2415 if (copy_to_user(arg, &b, sizeof(b)))
2309 return -EFAULT; 2416 return -EFAULT;
2310 2417
2311 return 0; 2418 return 0;
2312 } 2419}
2313 2420
2314 case VIDIOC_QBUF:
2315 {
2316 struct v4l2_buffer b;
2317 unsigned long lock_flags;
2318 2421
2319 if (copy_from_user(&b, arg, sizeof(b))) 2422static int
2320 return -EFAULT; 2423sn9c102_vidioc_qbuf(struct sn9c102_device* cam, void __user * arg)
2424{
2425 struct v4l2_buffer b;
2426 unsigned long lock_flags;
2321 2427
2322 if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE || 2428 if (copy_from_user(&b, arg, sizeof(b)))
2323 b.index >= cam->nbuffers || cam->io != IO_MMAP) 2429 return -EFAULT;
2324 return -EINVAL;
2325 2430
2326 if (cam->frame[b.index].state != F_UNUSED) 2431 if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
2327 return -EINVAL; 2432 b.index >= cam->nbuffers || cam->io != IO_MMAP)
2433 return -EINVAL;
2328 2434
2329 cam->frame[b.index].state = F_QUEUED; 2435 if (cam->frame[b.index].state != F_UNUSED)
2436 return -EINVAL;
2330 2437
2331 spin_lock_irqsave(&cam->queue_lock, lock_flags); 2438 cam->frame[b.index].state = F_QUEUED;
2332 list_add_tail(&cam->frame[b.index].frame, &cam->inqueue);
2333 spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
2334 2439
2335 PDBGG("Frame #%lu queued", (unsigned long)b.index) 2440 spin_lock_irqsave(&cam->queue_lock, lock_flags);
2441 list_add_tail(&cam->frame[b.index].frame, &cam->inqueue);
2442 spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
2336 2443
2337 return 0; 2444 PDBGG("Frame #%lu queued", (unsigned long)b.index);
2338 }
2339 2445
2340 case VIDIOC_DQBUF: 2446 return 0;
2341 { 2447}
2342 struct v4l2_buffer b;
2343 struct sn9c102_frame_t *f;
2344 unsigned long lock_flags;
2345 int err = 0;
2346 2448
2347 if (copy_from_user(&b, arg, sizeof(b)))
2348 return -EFAULT;
2349 2449
2350 if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io!= IO_MMAP) 2450static int
2451sn9c102_vidioc_dqbuf(struct sn9c102_device* cam, struct file* filp,
2452 void __user * arg)
2453{
2454 struct v4l2_buffer b;
2455 struct sn9c102_frame_t *f;
2456 unsigned long lock_flags;
2457 int err = 0;
2458
2459 if (copy_from_user(&b, arg, sizeof(b)))
2460 return -EFAULT;
2461
2462 if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP)
2463 return -EINVAL;
2464
2465 if (list_empty(&cam->outqueue)) {
2466 if (cam->stream == STREAM_OFF)
2351 return -EINVAL; 2467 return -EINVAL;
2468 if (filp->f_flags & O_NONBLOCK)
2469 return -EAGAIN;
2470 err = wait_event_interruptible
2471 ( cam->wait_frame,
2472 (!list_empty(&cam->outqueue)) ||
2473 (cam->state & DEV_DISCONNECTED) ||
2474 (cam->state & DEV_MISCONFIGURED) );
2475 if (err)
2476 return err;
2477 if (cam->state & DEV_DISCONNECTED)
2478 return -ENODEV;
2479 if (cam->state & DEV_MISCONFIGURED)
2480 return -EIO;
2481 }
2352 2482
2353 if (list_empty(&cam->outqueue)) { 2483 spin_lock_irqsave(&cam->queue_lock, lock_flags);
2354 if (cam->stream == STREAM_OFF) 2484 f = list_entry(cam->outqueue.next, struct sn9c102_frame_t, frame);
2355 return -EINVAL; 2485 list_del(cam->outqueue.next);
2356 if (filp->f_flags & O_NONBLOCK) 2486 spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
2357 return -EAGAIN;
2358 err = wait_event_interruptible
2359 ( cam->wait_frame,
2360 (!list_empty(&cam->outqueue)) ||
2361 (cam->state & DEV_DISCONNECTED) ||
2362 (cam->state & DEV_MISCONFIGURED) );
2363 if (err)
2364 return err;
2365 if (cam->state & DEV_DISCONNECTED)
2366 return -ENODEV;
2367 if (cam->state & DEV_MISCONFIGURED)
2368 return -EIO;
2369 }
2370 2487
2371 spin_lock_irqsave(&cam->queue_lock, lock_flags); 2488 f->state = F_UNUSED;
2372 f = list_entry(cam->outqueue.next, struct sn9c102_frame_t,
2373 frame);
2374 list_del(cam->outqueue.next);
2375 spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
2376 2489
2377 f->state = F_UNUSED; 2490 memcpy(&b, &f->buf, sizeof(b));
2491 if (f->vma_use_count)
2492 b.flags |= V4L2_BUF_FLAG_MAPPED;
2378 2493
2379 memcpy(&b, &f->buf, sizeof(b)); 2494 if (copy_to_user(arg, &b, sizeof(b)))
2380 if (f->vma_use_count) 2495 return -EFAULT;
2381 b.flags |= V4L2_BUF_FLAG_MAPPED;
2382 2496
2383 if (copy_to_user(arg, &b, sizeof(b))) 2497 PDBGG("Frame #%lu dequeued", (unsigned long)f->buf.index);
2384 return -EFAULT;
2385 2498
2386 PDBGG("Frame #%lu dequeued", (unsigned long)f->buf.index) 2499 return 0;
2500}
2387 2501
2388 return 0;
2389 }
2390 2502
2391 case VIDIOC_STREAMON: 2503static int
2392 { 2504sn9c102_vidioc_streamon(struct sn9c102_device* cam, void __user * arg)
2393 int type; 2505{
2506 int type;
2394 2507
2395 if (copy_from_user(&type, arg, sizeof(type))) 2508 if (copy_from_user(&type, arg, sizeof(type)))
2396 return -EFAULT; 2509 return -EFAULT;
2397 2510
2398 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP) 2511 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP)
2399 return -EINVAL; 2512 return -EINVAL;
2400 2513
2401 if (list_empty(&cam->inqueue)) 2514 if (list_empty(&cam->inqueue))
2402 return -EINVAL; 2515 return -EINVAL;
2403 2516
2404 cam->stream = STREAM_ON; 2517 cam->stream = STREAM_ON;
2405 2518
2406 DBG(3, "Stream on") 2519 DBG(3, "Stream on");
2407 2520
2408 return 0; 2521 return 0;
2409 } 2522}
2410 2523
2411 case VIDIOC_STREAMOFF:
2412 {
2413 int type, err;
2414 2524
2415 if (copy_from_user(&type, arg, sizeof(type))) 2525static int
2416 return -EFAULT; 2526sn9c102_vidioc_streamoff(struct sn9c102_device* cam, void __user * arg)
2527{
2528 int type, err;
2417 2529
2418 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP) 2530 if (copy_from_user(&type, arg, sizeof(type)))
2419 return -EINVAL; 2531 return -EFAULT;
2420 2532
2421 if (cam->stream == STREAM_ON) 2533 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP)
2422 if ((err = sn9c102_stream_interrupt(cam))) 2534 return -EINVAL;
2423 return err;
2424 2535
2425 sn9c102_empty_framequeues(cam); 2536 if (cam->stream == STREAM_ON)
2537 if ((err = sn9c102_stream_interrupt(cam)))
2538 return err;
2426 2539
2427 DBG(3, "Stream off") 2540 sn9c102_empty_framequeues(cam);
2428 2541
2429 return 0; 2542 DBG(3, "Stream off");
2430 }
2431 2543
2432 case VIDIOC_G_PARM: 2544 return 0;
2433 { 2545}
2434 struct v4l2_streamparm sp;
2435 2546
2436 if (copy_from_user(&sp, arg, sizeof(sp)))
2437 return -EFAULT;
2438 2547
2439 if (sp.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 2548static int
2440 return -EINVAL; 2549sn9c102_vidioc_g_parm(struct sn9c102_device* cam, void __user * arg)
2550{
2551 struct v4l2_streamparm sp;
2552
2553 if (copy_from_user(&sp, arg, sizeof(sp)))
2554 return -EFAULT;
2555
2556 if (sp.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
2557 return -EINVAL;
2558
2559 sp.parm.capture.extendedmode = 0;
2560 sp.parm.capture.readbuffers = cam->nreadbuffers;
2561
2562 if (copy_to_user(arg, &sp, sizeof(sp)))
2563 return -EFAULT;
2564
2565 return 0;
2566}
2567
2568
2569static int
2570sn9c102_vidioc_s_parm(struct sn9c102_device* cam, void __user * arg)
2571{
2572 struct v4l2_streamparm sp;
2573
2574 if (copy_from_user(&sp, arg, sizeof(sp)))
2575 return -EFAULT;
2576
2577 if (sp.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
2578 return -EINVAL;
2579
2580 sp.parm.capture.extendedmode = 0;
2441 2581
2442 sp.parm.capture.extendedmode = 0; 2582 if (sp.parm.capture.readbuffers == 0)
2443 sp.parm.capture.readbuffers = cam->nreadbuffers; 2583 sp.parm.capture.readbuffers = cam->nreadbuffers;
2444 2584
2445 if (copy_to_user(arg, &sp, sizeof(sp))) 2585 if (sp.parm.capture.readbuffers > SN9C102_MAX_FRAMES)
2446 return -EFAULT; 2586 sp.parm.capture.readbuffers = SN9C102_MAX_FRAMES;
2447 2587
2448 return 0; 2588 if (copy_to_user(arg, &sp, sizeof(sp)))
2449 } 2589 return -EFAULT;
2450 2590
2451 case VIDIOC_S_PARM_OLD: 2591 cam->nreadbuffers = sp.parm.capture.readbuffers;
2452 case VIDIOC_S_PARM:
2453 {
2454 struct v4l2_streamparm sp;
2455 2592
2456 if (copy_from_user(&sp, arg, sizeof(sp))) 2593 return 0;
2457 return -EFAULT; 2594}
2458 2595
2459 if (sp.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
2460 return -EINVAL;
2461 2596
2462 sp.parm.capture.extendedmode = 0; 2597static int sn9c102_ioctl_v4l2(struct inode* inode, struct file* filp,
2598 unsigned int cmd, void __user * arg)
2599{
2600 struct sn9c102_device* cam = video_get_drvdata(video_devdata(filp));
2463 2601
2464 if (sp.parm.capture.readbuffers == 0) 2602 switch (cmd) {
2465 sp.parm.capture.readbuffers = cam->nreadbuffers;
2466 2603
2467 if (sp.parm.capture.readbuffers > SN9C102_MAX_FRAMES) 2604 case VIDIOC_QUERYCAP:
2468 sp.parm.capture.readbuffers = SN9C102_MAX_FRAMES; 2605 return sn9c102_vidioc_querycap(cam, arg);
2469 2606
2470 if (copy_to_user(arg, &sp, sizeof(sp))) 2607 case VIDIOC_ENUMINPUT:
2471 return -EFAULT; 2608 return sn9c102_vidioc_enuminput(cam, arg);
2472 2609
2473 cam->nreadbuffers = sp.parm.capture.readbuffers; 2610 case VIDIOC_G_INPUT:
2611 case VIDIOC_S_INPUT:
2612 return sn9c102_vidioc_gs_input(cam, arg);
2474 2613
2475 return 0; 2614 case VIDIOC_QUERYCTRL:
2476 } 2615 return sn9c102_vidioc_query_ctrl(cam, arg);
2616
2617 case VIDIOC_G_CTRL:
2618 return sn9c102_vidioc_g_ctrl(cam, arg);
2619
2620 case VIDIOC_S_CTRL_OLD:
2621 case VIDIOC_S_CTRL:
2622 return sn9c102_vidioc_s_ctrl(cam, arg);
2623
2624 case VIDIOC_CROPCAP_OLD:
2625 case VIDIOC_CROPCAP:
2626 return sn9c102_vidioc_cropcap(cam, arg);
2627
2628 case VIDIOC_G_CROP:
2629 return sn9c102_vidioc_g_crop(cam, arg);
2630
2631 case VIDIOC_S_CROP:
2632 return sn9c102_vidioc_s_crop(cam, arg);
2633
2634 case VIDIOC_ENUM_FMT:
2635 return sn9c102_vidioc_enum_fmt(cam, arg);
2636
2637 case VIDIOC_G_FMT:
2638 return sn9c102_vidioc_g_fmt(cam, arg);
2639
2640 case VIDIOC_TRY_FMT:
2641 case VIDIOC_S_FMT:
2642 return sn9c102_vidioc_try_s_fmt(cam, cmd, arg);
2643
2644 case VIDIOC_G_JPEGCOMP:
2645 return sn9c102_vidioc_g_jpegcomp(cam, arg);
2646
2647 case VIDIOC_S_JPEGCOMP:
2648 return sn9c102_vidioc_s_jpegcomp(cam, arg);
2649
2650 case VIDIOC_REQBUFS:
2651 return sn9c102_vidioc_reqbufs(cam, arg);
2652
2653 case VIDIOC_QUERYBUF:
2654 return sn9c102_vidioc_querybuf(cam, arg);
2655
2656 case VIDIOC_QBUF:
2657 return sn9c102_vidioc_qbuf(cam, arg);
2658
2659 case VIDIOC_DQBUF:
2660 return sn9c102_vidioc_dqbuf(cam, filp, arg);
2661
2662 case VIDIOC_STREAMON:
2663 return sn9c102_vidioc_streamon(cam, arg);
2664
2665 case VIDIOC_STREAMOFF:
2666 return sn9c102_vidioc_streamoff(cam, arg);
2667
2668 case VIDIOC_G_PARM:
2669 return sn9c102_vidioc_g_parm(cam, arg);
2670
2671 case VIDIOC_S_PARM_OLD:
2672 case VIDIOC_S_PARM:
2673 return sn9c102_vidioc_s_parm(cam, arg);
2477 2674
2478 case VIDIOC_G_STD: 2675 case VIDIOC_G_STD:
2479 case VIDIOC_S_STD: 2676 case VIDIOC_S_STD:
@@ -2499,13 +2696,14 @@ static int sn9c102_ioctl(struct inode* inode, struct file* filp,
2499 return -ERESTARTSYS; 2696 return -ERESTARTSYS;
2500 2697
2501 if (cam->state & DEV_DISCONNECTED) { 2698 if (cam->state & DEV_DISCONNECTED) {
2502 DBG(1, "Device not present") 2699 DBG(1, "Device not present");
2503 up(&cam->fileop_sem); 2700 up(&cam->fileop_sem);
2504 return -ENODEV; 2701 return -ENODEV;
2505 } 2702 }
2506 2703
2507 if (cam->state & DEV_MISCONFIGURED) { 2704 if (cam->state & DEV_MISCONFIGURED) {
2508 DBG(1, "The camera is misconfigured. Close and open it again.") 2705 DBG(1, "The camera is misconfigured. Close and open it "
2706 "again.");
2509 up(&cam->fileop_sem); 2707 up(&cam->fileop_sem);
2510 return -EIO; 2708 return -EIO;
2511 } 2709 }
@@ -2517,9 +2715,10 @@ static int sn9c102_ioctl(struct inode* inode, struct file* filp,
2517 return err; 2715 return err;
2518} 2716}
2519 2717
2718/*****************************************************************************/
2520 2719
2521static struct file_operations sn9c102_fops = { 2720static struct file_operations sn9c102_fops = {
2522 .owner = THIS_MODULE, 2721 .owner = THIS_MODULE,
2523 .open = sn9c102_open, 2722 .open = sn9c102_open,
2524 .release = sn9c102_release, 2723 .release = sn9c102_release,
2525 .ioctl = sn9c102_ioctl, 2724 .ioctl = sn9c102_ioctl,
@@ -2538,36 +2737,23 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
2538 struct usb_device *udev = interface_to_usbdev(intf); 2737 struct usb_device *udev = interface_to_usbdev(intf);
2539 struct sn9c102_device* cam; 2738 struct sn9c102_device* cam;
2540 static unsigned int dev_nr = 0; 2739 static unsigned int dev_nr = 0;
2541 unsigned int i, n; 2740 unsigned int i;
2542 int err = 0, r; 2741 int err = 0, r;
2543 2742
2544 n = ARRAY_SIZE(sn9c102_id_table);
2545 for (i = 0; i < n-1; i++)
2546 if (le16_to_cpu(udev->descriptor.idVendor) ==
2547 sn9c102_id_table[i].idVendor &&
2548 le16_to_cpu(udev->descriptor.idProduct) ==
2549 sn9c102_id_table[i].idProduct)
2550 break;
2551 if (i == n-1)
2552 return -ENODEV;
2553
2554 if (!(cam = kmalloc(sizeof(struct sn9c102_device), GFP_KERNEL))) 2743 if (!(cam = kmalloc(sizeof(struct sn9c102_device), GFP_KERNEL)))
2555 return -ENOMEM; 2744 return -ENOMEM;
2556 memset(cam, 0, sizeof(*cam));
2557 2745
2558 cam->usbdev = udev; 2746 cam->usbdev = udev;
2559
2560 memcpy(&cam->dev, &udev->dev, sizeof(struct device)); 2747 memcpy(&cam->dev, &udev->dev, sizeof(struct device));
2561 2748
2562 if (!(cam->control_buffer = kmalloc(8, GFP_KERNEL))) { 2749 if (!(cam->control_buffer = kmalloc(8, GFP_KERNEL))) {
2563 DBG(1, "kmalloc() failed") 2750 DBG(1, "kmalloc() failed");
2564 err = -ENOMEM; 2751 err = -ENOMEM;
2565 goto fail; 2752 goto fail;
2566 } 2753 }
2567 memset(cam->control_buffer, 0, 8);
2568 2754
2569 if (!(cam->v4ldev = video_device_alloc())) { 2755 if (!(cam->v4ldev = video_device_alloc())) {
2570 DBG(1, "video_device_alloc() failed") 2756 DBG(1, "video_device_alloc() failed");
2571 err = -ENOMEM; 2757 err = -ENOMEM;
2572 goto fail; 2758 goto fail;
2573 } 2759 }
@@ -2577,25 +2763,22 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
2577 r = sn9c102_read_reg(cam, 0x00); 2763 r = sn9c102_read_reg(cam, 0x00);
2578 if (r < 0 || r != 0x10) { 2764 if (r < 0 || r != 0x10) {
2579 DBG(1, "Sorry, this is not a SN9C10x based camera " 2765 DBG(1, "Sorry, this is not a SN9C10x based camera "
2580 "(vid/pid 0x%04X/0x%04X)", 2766 "(vid/pid 0x%04X/0x%04X)", id->idVendor, id->idProduct);
2581 sn9c102_id_table[i].idVendor,sn9c102_id_table[i].idProduct)
2582 err = -ENODEV; 2767 err = -ENODEV;
2583 goto fail; 2768 goto fail;
2584 } 2769 }
2585 2770
2586 cam->bridge = (sn9c102_id_table[i].idProduct & 0xffc0) == 0x6080 ? 2771 cam->bridge = (id->idProduct & 0xffc0) == 0x6080 ?
2587 BRIDGE_SN9C103 : BRIDGE_SN9C102; 2772 BRIDGE_SN9C103 : BRIDGE_SN9C102;
2588 switch (cam->bridge) { 2773 switch (cam->bridge) {
2589 case BRIDGE_SN9C101: 2774 case BRIDGE_SN9C101:
2590 case BRIDGE_SN9C102: 2775 case BRIDGE_SN9C102:
2591 DBG(2, "SN9C10[12] PC Camera Controller detected " 2776 DBG(2, "SN9C10[12] PC Camera Controller detected "
2592 "(vid/pid 0x%04X/0x%04X)", sn9c102_id_table[i].idVendor, 2777 "(vid/pid 0x%04X/0x%04X)", id->idVendor, id->idProduct);
2593 sn9c102_id_table[i].idProduct)
2594 break; 2778 break;
2595 case BRIDGE_SN9C103: 2779 case BRIDGE_SN9C103:
2596 DBG(2, "SN9C103 PC Camera Controller detected " 2780 DBG(2, "SN9C103 PC Camera Controller detected "
2597 "(vid/pid 0x%04X/0x%04X)", sn9c102_id_table[i].idVendor, 2781 "(vid/pid 0x%04X/0x%04X)", id->idVendor, id->idProduct);
2598 sn9c102_id_table[i].idProduct)
2599 break; 2782 break;
2600 } 2783 }
2601 2784
@@ -2606,17 +2789,17 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
2606 } 2789 }
2607 2790
2608 if (!err && cam->sensor) { 2791 if (!err && cam->sensor) {
2609 DBG(2, "%s image sensor detected", cam->sensor->name) 2792 DBG(2, "%s image sensor detected", cam->sensor->name);
2610 DBG(3, "Support for %s maintained by %s", 2793 DBG(3, "Support for %s maintained by %s",
2611 cam->sensor->name, cam->sensor->maintainer) 2794 cam->sensor->name, cam->sensor->maintainer);
2612 } else { 2795 } else {
2613 DBG(1, "No supported image sensor detected") 2796 DBG(1, "No supported image sensor detected");
2614 err = -ENODEV; 2797 err = -ENODEV;
2615 goto fail; 2798 goto fail;
2616 } 2799 }
2617 2800
2618 if (sn9c102_init(cam)) { 2801 if (sn9c102_init(cam)) {
2619 DBG(1, "Initialization failed. I will retry on open().") 2802 DBG(1, "Initialization failed. I will retry on open().");
2620 cam->state |= DEV_MISCONFIGURED; 2803 cam->state |= DEV_MISCONFIGURED;
2621 } 2804 }
2622 2805
@@ -2634,23 +2817,23 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
2634 err = video_register_device(cam->v4ldev, VFL_TYPE_GRABBER, 2817 err = video_register_device(cam->v4ldev, VFL_TYPE_GRABBER,
2635 video_nr[dev_nr]); 2818 video_nr[dev_nr]);
2636 if (err) { 2819 if (err) {
2637 DBG(1, "V4L2 device registration failed") 2820 DBG(1, "V4L2 device registration failed");
2638 if (err == -ENFILE && video_nr[dev_nr] == -1) 2821 if (err == -ENFILE && video_nr[dev_nr] == -1)
2639 DBG(1, "Free /dev/videoX node not found") 2822 DBG(1, "Free /dev/videoX node not found");
2640 video_nr[dev_nr] = -1; 2823 video_nr[dev_nr] = -1;
2641 dev_nr = (dev_nr < SN9C102_MAX_DEVICES-1) ? dev_nr+1 : 0; 2824 dev_nr = (dev_nr < SN9C102_MAX_DEVICES-1) ? dev_nr+1 : 0;
2642 up(&cam->dev_sem); 2825 up(&cam->dev_sem);
2643 goto fail; 2826 goto fail;
2644 } 2827 }
2645 2828
2646 DBG(2, "V4L2 device registered as /dev/video%d", cam->v4ldev->minor) 2829 DBG(2, "V4L2 device registered as /dev/video%d", cam->v4ldev->minor);
2647 2830
2648 cam->module_param.force_munmap = force_munmap[dev_nr]; 2831 cam->module_param.force_munmap = force_munmap[dev_nr];
2649 2832
2650 dev_nr = (dev_nr < SN9C102_MAX_DEVICES-1) ? dev_nr+1 : 0; 2833 dev_nr = (dev_nr < SN9C102_MAX_DEVICES-1) ? dev_nr+1 : 0;
2651 2834
2652 sn9c102_create_sysfs(cam); 2835 sn9c102_create_sysfs(cam);
2653 DBG(2, "Optional device control through 'sysfs' interface ready") 2836 DBG(2, "Optional device control through 'sysfs' interface ready");
2654 2837
2655 usb_set_intfdata(intf, cam); 2838 usb_set_intfdata(intf, cam);
2656 2839
@@ -2680,14 +2863,14 @@ static void sn9c102_usb_disconnect(struct usb_interface* intf)
2680 2863
2681 down(&cam->dev_sem); 2864 down(&cam->dev_sem);
2682 2865
2683 DBG(2, "Disconnecting %s...", cam->v4ldev->name) 2866 DBG(2, "Disconnecting %s...", cam->v4ldev->name);
2684 2867
2685 wake_up_interruptible_all(&cam->open); 2868 wake_up_interruptible_all(&cam->open);
2686 2869
2687 if (cam->users) { 2870 if (cam->users) {
2688 DBG(2, "Device /dev/video%d is open! Deregistration and " 2871 DBG(2, "Device /dev/video%d is open! Deregistration and "
2689 "memory deallocation are deferred on close.", 2872 "memory deallocation are deferred on close.",
2690 cam->v4ldev->minor) 2873 cam->v4ldev->minor);
2691 cam->state |= DEV_MISCONFIGURED; 2874 cam->state |= DEV_MISCONFIGURED;
2692 sn9c102_stop_transfer(cam); 2875 sn9c102_stop_transfer(cam);
2693 cam->state |= DEV_DISCONNECTED; 2876 cam->state |= DEV_DISCONNECTED;
@@ -2720,11 +2903,11 @@ static int __init sn9c102_module_init(void)
2720{ 2903{
2721 int err = 0; 2904 int err = 0;
2722 2905
2723 KDBG(2, SN9C102_MODULE_NAME " v" SN9C102_MODULE_VERSION) 2906 KDBG(2, SN9C102_MODULE_NAME " v" SN9C102_MODULE_VERSION);
2724 KDBG(3, SN9C102_MODULE_AUTHOR) 2907 KDBG(3, SN9C102_MODULE_AUTHOR);
2725 2908
2726 if ((err = usb_register(&sn9c102_usb_driver))) 2909 if ((err = usb_register(&sn9c102_usb_driver)))
2727 KDBG(1, "usb_register() failed") 2910 KDBG(1, "usb_register() failed");
2728 2911
2729 return err; 2912 return err;
2730} 2913}
diff --git a/drivers/usb/media/sn9c102_hv7131d.c b/drivers/usb/media/sn9c102_hv7131d.c
index 18070d5333cf..46c12ec3ca62 100644
--- a/drivers/usb/media/sn9c102_hv7131d.c
+++ b/drivers/usb/media/sn9c102_hv7131d.c
@@ -2,7 +2,7 @@
2 * Plug-in for HV7131D image sensor connected to the SN9C10x PC Camera * 2 * Plug-in for HV7131D image sensor connected to the SN9C10x PC Camera *
3 * Controllers * 3 * Controllers *
4 * * 4 * *
5 * Copyright (C) 2004-2005 by Luca Risolia <luca.risolia@studio.unibo.it> * 5 * Copyright (C) 2004-2006 by Luca Risolia <luca.risolia@studio.unibo.it> *
6 * * 6 * *
7 * This program is free software; you can redistribute it and/or modify * 7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by * 8 * it under the terms of the GNU General Public License as published by *
diff --git a/drivers/usb/media/sn9c102_mi0343.c b/drivers/usb/media/sn9c102_mi0343.c
index 86676abf3547..d9aa7a61095d 100644
--- a/drivers/usb/media/sn9c102_mi0343.c
+++ b/drivers/usb/media/sn9c102_mi0343.c
@@ -2,7 +2,7 @@
2 * Plug-in for MI-0343 image sensor connected to the SN9C10x PC Camera * 2 * Plug-in for MI-0343 image sensor connected to the SN9C10x PC Camera *
3 * Controllers * 3 * Controllers *
4 * * 4 * *
5 * Copyright (C) 2004-2005 by Luca Risolia <luca.risolia@studio.unibo.it> * 5 * Copyright (C) 2004-2006 by Luca Risolia <luca.risolia@studio.unibo.it> *
6 * * 6 * *
7 * This program is free software; you can redistribute it and/or modify * 7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by * 8 * it under the terms of the GNU General Public License as published by *
diff --git a/drivers/usb/media/sn9c102_ov7630.c b/drivers/usb/media/sn9c102_ov7630.c
index d27c5aedeaf8..4a36519b5af4 100644
--- a/drivers/usb/media/sn9c102_ov7630.c
+++ b/drivers/usb/media/sn9c102_ov7630.c
@@ -2,7 +2,7 @@
2 * Plug-in for OV7630 image sensor connected to the SN9C10x PC Camera * 2 * Plug-in for OV7630 image sensor connected to the SN9C10x PC Camera *
3 * Controllers * 3 * Controllers *
4 * * 4 * *
5 * Copyright (C) 2005 by Luca Risolia <luca.risolia@studio.unibo.it> * 5 * Copyright (C) 2005-2006 by Luca Risolia <luca.risolia@studio.unibo.it> *
6 * * 6 * *
7 * This program is free software; you can redistribute it and/or modify * 7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by * 8 * it under the terms of the GNU General Public License as published by *
@@ -375,8 +375,10 @@ int sn9c102_probe_ov7630(struct sn9c102_device* cam)
375 375
376 sn9c102_attach_sensor(cam, &ov7630); 376 sn9c102_attach_sensor(cam, &ov7630);
377 377
378 if (le16_to_cpu(ov7630.usbdev->descriptor.idProduct) != 0x608f && 378 if (le16_to_cpu(ov7630.usbdev->descriptor.idProduct) != 0x602c &&
379 le16_to_cpu(ov7630.usbdev->descriptor.idProduct) != 0x602c) 379 le16_to_cpu(ov7630.usbdev->descriptor.idProduct) != 0x602d &&
380 le16_to_cpu(ov7630.usbdev->descriptor.idProduct) != 0x608f &&
381 le16_to_cpu(ov7630.usbdev->descriptor.idProduct) != 0x60b0)
380 return -ENODEV; 382 return -ENODEV;
381 383
382 err += sn9c102_write_reg(cam, 0x01, 0x01); 384 err += sn9c102_write_reg(cam, 0x01, 0x01);
diff --git a/drivers/usb/media/sn9c102_pas106b.c b/drivers/usb/media/sn9c102_pas106b.c
index 48e3ec39d4e2..b1dee78abe04 100644
--- a/drivers/usb/media/sn9c102_pas106b.c
+++ b/drivers/usb/media/sn9c102_pas106b.c
@@ -2,7 +2,7 @@
2 * Plug-in for PAS106B image sensor connected to the SN9C10x PC Camera * 2 * Plug-in for PAS106B image sensor connected to the SN9C10x PC Camera *
3 * Controllers * 3 * Controllers *
4 * * 4 * *
5 * Copyright (C) 2004-2005 by Luca Risolia <luca.risolia@studio.unibo.it> * 5 * Copyright (C) 2004-2006 by Luca Risolia <luca.risolia@studio.unibo.it> *
6 * * 6 * *
7 * This program is free software; you can redistribute it and/or modify * 7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by * 8 * it under the terms of the GNU General Public License as published by *
diff --git a/drivers/usb/media/sn9c102_sensor.h b/drivers/usb/media/sn9c102_sensor.h
index a45166c3488c..a0e561b2c852 100644
--- a/drivers/usb/media/sn9c102_sensor.h
+++ b/drivers/usb/media/sn9c102_sensor.h
@@ -1,7 +1,7 @@
1/*************************************************************************** 1/***************************************************************************
2 * API for image sensors connected to the SN9C10x PC Camera Controllers * 2 * API for image sensors connected to the SN9C10x PC Camera Controllers *
3 * * 3 * *
4 * Copyright (C) 2004-2005 by Luca Risolia <luca.risolia@studio.unibo.it> * 4 * Copyright (C) 2004-2006 by Luca Risolia <luca.risolia@studio.unibo.it> *
5 * * 5 * *
6 * This program is free software; you can redistribute it and/or modify * 6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by * 7 * it under the terms of the GNU General Public License as published by *
@@ -92,7 +92,18 @@ extern void
92sn9c102_attach_sensor(struct sn9c102_device* cam, 92sn9c102_attach_sensor(struct sn9c102_device* cam,
93 struct sn9c102_sensor* sensor); 93 struct sn9c102_sensor* sensor);
94 94
95/* Each SN9C10X camera has proper PID/VID identifiers. Add them here in case.*/ 95/*
96 Each SN9C10x camera has proper PID/VID identifiers.
97 SN9C103 supports multiple interfaces, but we only handle the video class
98 interface.
99*/
100#define SN9C102_USB_DEVICE(vend, prod, intclass) \
101 .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \
102 USB_DEVICE_ID_MATCH_INT_CLASS, \
103 .idVendor = (vend), \
104 .idProduct = (prod), \
105 .bInterfaceClass = (intclass)
106
96#define SN9C102_ID_TABLE \ 107#define SN9C102_ID_TABLE \
97static const struct usb_device_id sn9c102_id_table[] = { \ 108static const struct usb_device_id sn9c102_id_table[] = { \
98 { USB_DEVICE(0x0c45, 0x6001), }, /* TAS5110C1B */ \ 109 { USB_DEVICE(0x0c45, 0x6001), }, /* TAS5110C1B */ \
@@ -107,33 +118,34 @@ static const struct usb_device_id sn9c102_id_table[] = { \
107 { USB_DEVICE(0x0c45, 0x602b), }, /* MI-0343 */ \ 118 { USB_DEVICE(0x0c45, 0x602b), }, /* MI-0343 */ \
108 { USB_DEVICE(0x0c45, 0x602c), }, /* OV7630 */ \ 119 { USB_DEVICE(0x0c45, 0x602c), }, /* OV7630 */ \
109 { USB_DEVICE(0x0c45, 0x602d), }, \ 120 { USB_DEVICE(0x0c45, 0x602d), }, \
121 { USB_DEVICE(0x0c45, 0x602e), }, /* OV7630 */ \
110 { USB_DEVICE(0x0c45, 0x6030), }, /* MI03x */ \ 122 { USB_DEVICE(0x0c45, 0x6030), }, /* MI03x */ \
111 { USB_DEVICE(0x0c45, 0x6080), }, \ 123 { SN9C102_USB_DEVICE(0x0c45, 0x6080, 0xff), }, \
112 { USB_DEVICE(0x0c45, 0x6082), }, /* MI0343 and MI0360 */ \ 124 { SN9C102_USB_DEVICE(0x0c45, 0x6082, 0xff), }, /* MI0343 & MI0360 */ \
113 { USB_DEVICE(0x0c45, 0x6083), }, /* HV7131[D|E1] */ \ 125 { SN9C102_USB_DEVICE(0x0c45, 0x6083, 0xff), }, /* HV7131[D|E1] */ \
114 { USB_DEVICE(0x0c45, 0x6088), }, \ 126 { SN9C102_USB_DEVICE(0x0c45, 0x6088, 0xff), }, \
115 { USB_DEVICE(0x0c45, 0x608a), }, \ 127 { SN9C102_USB_DEVICE(0x0c45, 0x608a, 0xff), }, \
116 { USB_DEVICE(0x0c45, 0x608b), }, \ 128 { SN9C102_USB_DEVICE(0x0c45, 0x608b, 0xff), }, \
117 { USB_DEVICE(0x0c45, 0x608c), }, /* HV7131x */ \ 129 { SN9C102_USB_DEVICE(0x0c45, 0x608c, 0xff), }, /* HV7131x */ \
118 { USB_DEVICE(0x0c45, 0x608e), }, /* CIS-VF10 */ \ 130 { SN9C102_USB_DEVICE(0x0c45, 0x608e, 0xff), }, /* CIS-VF10 */ \
119 { USB_DEVICE(0x0c45, 0x608f), }, /* OV7630 */ \ 131 { SN9C102_USB_DEVICE(0x0c45, 0x608f, 0xff), }, /* OV7630 */ \
120 { USB_DEVICE(0x0c45, 0x60a0), }, \ 132 { SN9C102_USB_DEVICE(0x0c45, 0x60a0, 0xff), }, \
121 { USB_DEVICE(0x0c45, 0x60a2), }, \ 133 { SN9C102_USB_DEVICE(0x0c45, 0x60a2, 0xff), }, \
122 { USB_DEVICE(0x0c45, 0x60a3), }, \ 134 { SN9C102_USB_DEVICE(0x0c45, 0x60a3, 0xff), }, \
123 { USB_DEVICE(0x0c45, 0x60a8), }, /* PAS106B */ \ 135 { SN9C102_USB_DEVICE(0x0c45, 0x60a8, 0xff), }, /* PAS106B */ \
124 { USB_DEVICE(0x0c45, 0x60aa), }, /* TAS5130D1B */ \ 136 { SN9C102_USB_DEVICE(0x0c45, 0x60aa, 0xff), }, /* TAS5130D1B */ \
125 { USB_DEVICE(0x0c45, 0x60ab), }, /* TAS5110C1B */ \ 137 { SN9C102_USB_DEVICE(0x0c45, 0x60ab, 0xff), }, /* TAS5110C1B */ \
126 { USB_DEVICE(0x0c45, 0x60ac), }, \ 138 { SN9C102_USB_DEVICE(0x0c45, 0x60ac, 0xff), }, \
127 { USB_DEVICE(0x0c45, 0x60ae), }, \ 139 { SN9C102_USB_DEVICE(0x0c45, 0x60ae, 0xff), }, \
128 { USB_DEVICE(0x0c45, 0x60af), }, /* PAS202BCB */ \ 140 { SN9C102_USB_DEVICE(0x0c45, 0x60af, 0xff), }, /* PAS202BCB */ \
129 { USB_DEVICE(0x0c45, 0x60b0), }, \ 141 { SN9C102_USB_DEVICE(0x0c45, 0x60b0, 0xff), }, /* OV7630 (?) */ \
130 { USB_DEVICE(0x0c45, 0x60b2), }, \ 142 { SN9C102_USB_DEVICE(0x0c45, 0x60b2, 0xff), }, \
131 { USB_DEVICE(0x0c45, 0x60b3), }, \ 143 { SN9C102_USB_DEVICE(0x0c45, 0x60b3, 0xff), }, \
132 { USB_DEVICE(0x0c45, 0x60b8), }, \ 144 { SN9C102_USB_DEVICE(0x0c45, 0x60b8, 0xff), }, \
133 { USB_DEVICE(0x0c45, 0x60ba), }, \ 145 { SN9C102_USB_DEVICE(0x0c45, 0x60ba, 0xff), }, \
134 { USB_DEVICE(0x0c45, 0x60bb), }, \ 146 { SN9C102_USB_DEVICE(0x0c45, 0x60bb, 0xff), }, \
135 { USB_DEVICE(0x0c45, 0x60bc), }, \ 147 { SN9C102_USB_DEVICE(0x0c45, 0x60bc, 0xff), }, \
136 { USB_DEVICE(0x0c45, 0x60be), }, \ 148 { SN9C102_USB_DEVICE(0x0c45, 0x60be, 0xff), }, \
137 { } \ 149 { } \
138}; 150};
139 151
@@ -177,6 +189,7 @@ extern int sn9c102_i2c_write(struct sn9c102_device*, u8 address, u8 value);
177extern int sn9c102_i2c_read(struct sn9c102_device*, u8 address); 189extern int sn9c102_i2c_read(struct sn9c102_device*, u8 address);
178 190
179/* I/O on registers in the bridge. Could be used by the sensor methods too */ 191/* I/O on registers in the bridge. Could be used by the sensor methods too */
192extern int sn9c102_write_regs(struct sn9c102_device*, u8* buff, u16 index);
180extern int sn9c102_write_reg(struct sn9c102_device*, u8 value, u16 index); 193extern int sn9c102_write_reg(struct sn9c102_device*, u8 value, u16 index);
181extern int sn9c102_pread_reg(struct sn9c102_device*, u16 index); 194extern int sn9c102_pread_reg(struct sn9c102_device*, u16 index);
182 195
diff --git a/drivers/usb/media/sn9c102_tas5110c1b.c b/drivers/usb/media/sn9c102_tas5110c1b.c
index 8775999b5aff..32ddf236cafe 100644
--- a/drivers/usb/media/sn9c102_tas5110c1b.c
+++ b/drivers/usb/media/sn9c102_tas5110c1b.c
@@ -2,7 +2,7 @@
2 * Plug-in for TAS5110C1B image sensor connected to the SN9C10x PC Camera * 2 * Plug-in for TAS5110C1B image sensor connected to the SN9C10x PC Camera *
3 * Controllers * 3 * Controllers *
4 * * 4 * *
5 * Copyright (C) 2004-2005 by Luca Risolia <luca.risolia@studio.unibo.it> * 5 * Copyright (C) 2004-2006 by Luca Risolia <luca.risolia@studio.unibo.it> *
6 * * 6 * *
7 * This program is free software; you can redistribute it and/or modify * 7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by * 8 * it under the terms of the GNU General Public License as published by *
diff --git a/drivers/usb/media/sn9c102_tas5130d1b.c b/drivers/usb/media/sn9c102_tas5130d1b.c
index 927eafdd8c73..a0728f0ae00c 100644
--- a/drivers/usb/media/sn9c102_tas5130d1b.c
+++ b/drivers/usb/media/sn9c102_tas5130d1b.c
@@ -2,7 +2,7 @@
2 * Plug-in for TAS5130D1B image sensor connected to the SN9C10x PC Camera * 2 * Plug-in for TAS5130D1B image sensor connected to the SN9C10x PC Camera *
3 * Controllers * 3 * Controllers *
4 * * 4 * *
5 * Copyright (C) 2004-2005 by Luca Risolia <luca.risolia@studio.unibo.it> * 5 * Copyright (C) 2004-2006 by Luca Risolia <luca.risolia@studio.unibo.it> *
6 * * 6 * *
7 * This program is free software; you can redistribute it and/or modify * 7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by * 8 * it under the terms of the GNU General Public License as published by *