diff options
author | Luca Risolia <luca.risolia@studio.unibo.it> | 2005-06-25 10:30:24 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2005-07-12 14:52:56 -0400 |
commit | b9df978f1974fea373741367b5d79a2ed3b7dcf9 (patch) | |
tree | e1eea703ac8af72697dc1e7c6df3ea61043ec590 | |
parent | 8fd6db47b90c7ecac32e3211f771849e148bdb07 (diff) |
[PATCH] USB: SN9C10x driver updates
SN9C10x driver updates.
Changes: + new, - removed, * cleanup, @ bugfix
@ Remove bad get_ctrl()'s
* Documentation updates
+ Add 0x0c45/0x602d to the list of SN9C10x based devices
+ Add support for OV7630 image sensors
Signed-off-by: Luca Risolia <luca.risolia@studio.unibo.it>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | Documentation/usb/sn9c102.txt | 4 | ||||
-rw-r--r-- | drivers/usb/media/Makefile | 2 | ||||
-rw-r--r-- | drivers/usb/media/sn9c102.h | 2 | ||||
-rw-r--r-- | drivers/usb/media/sn9c102_core.c | 2 | ||||
-rw-r--r-- | drivers/usb/media/sn9c102_ov7630.c | 394 | ||||
-rw-r--r-- | drivers/usb/media/sn9c102_sensor.h | 16 | ||||
-rw-r--r-- | drivers/usb/media/sn9c102_tas5110c1b.c | 21 | ||||
-rw-r--r-- | drivers/usb/media/sn9c102_tas5130d1b.c | 27 |
8 files changed, 417 insertions, 51 deletions
diff --git a/Documentation/usb/sn9c102.txt b/Documentation/usb/sn9c102.txt index cf9a1187edce..3f8a119db31b 100644 --- a/Documentation/usb/sn9c102.txt +++ b/Documentation/usb/sn9c102.txt | |||
@@ -297,6 +297,7 @@ Vendor ID Product ID | |||
297 | 0x0c45 0x602a | 297 | 0x0c45 0x602a |
298 | 0x0c45 0x602b | 298 | 0x0c45 0x602b |
299 | 0x0c45 0x602c | 299 | 0x0c45 0x602c |
300 | 0x0c45 0x602d | ||
300 | 0x0c45 0x6030 | 301 | 0x0c45 0x6030 |
301 | 0x0c45 0x6080 | 302 | 0x0c45 0x6080 |
302 | 0x0c45 0x6082 | 303 | 0x0c45 0x6082 |
@@ -333,6 +334,7 @@ Model Manufacturer | |||
333 | ----- ------------ | 334 | ----- ------------ |
334 | HV7131D Hynix Semiconductor, Inc. | 335 | HV7131D Hynix Semiconductor, Inc. |
335 | MI-0343 Micron Technology, Inc. | 336 | MI-0343 Micron Technology, Inc. |
337 | OV7630 OmniVision Technologies, Inc. | ||
336 | PAS106B PixArt Imaging, Inc. | 338 | PAS106B PixArt Imaging, Inc. |
337 | PAS202BCB PixArt Imaging, Inc. | 339 | PAS202BCB PixArt Imaging, Inc. |
338 | TAS5110C1B Taiwan Advanced Sensor Corporation | 340 | TAS5110C1B Taiwan Advanced Sensor Corporation |
@@ -470,9 +472,11 @@ order): | |||
470 | - Luca Capello for the donation of a webcam; | 472 | - Luca Capello for the donation of a webcam; |
471 | - Joao Rodrigo Fuzaro, Joao Limirio, Claudio Filho and Caio Begotti for the | 473 | - Joao Rodrigo Fuzaro, Joao Limirio, Claudio Filho and Caio Begotti for the |
472 | donation of a webcam; | 474 | donation of a webcam; |
475 | - Jon Hollstrom for the donation of a webcam; | ||
473 | - Carlos Eduardo Medaglia Dyonisio, who added the support for the PAS202BCB | 476 | - Carlos Eduardo Medaglia Dyonisio, who added the support for the PAS202BCB |
474 | image sensor; | 477 | image sensor; |
475 | - Stefano Mozzi, who donated 45 EU; | 478 | - Stefano Mozzi, who donated 45 EU; |
479 | - Andrew Pearce for the donation of a webcam; | ||
476 | - Bertrik Sikken, who reverse-engineered and documented the Huffman compression | 480 | - Bertrik Sikken, who reverse-engineered and documented the Huffman compression |
477 | algorithm used in the SN9C10x controllers and implemented the first decoder; | 481 | algorithm used in the SN9C10x controllers and implemented the first decoder; |
478 | - Mizuno Takafumi for the donation of a webcam; | 482 | - Mizuno Takafumi for the donation of a webcam; |
diff --git a/drivers/usb/media/Makefile b/drivers/usb/media/Makefile index 2b76df7005fe..d83adffa925f 100644 --- a/drivers/usb/media/Makefile +++ b/drivers/usb/media/Makefile | |||
@@ -2,7 +2,7 @@ | |||
2 | # Makefile for USB Media drivers | 2 | # Makefile for USB Media drivers |
3 | # | 3 | # |
4 | 4 | ||
5 | sn9c102-objs := sn9c102_core.o sn9c102_hv7131d.o sn9c102_mi0343.o sn9c102_pas106b.o sn9c102_pas202bcb.o sn9c102_tas5110c1b.o sn9c102_tas5130d1b.o | 5 | sn9c102-objs := sn9c102_core.o sn9c102_hv7131d.o sn9c102_mi0343.o sn9c102_ov7630.o sn9c102_pas106b.o sn9c102_pas202bcb.o sn9c102_tas5110c1b.o sn9c102_tas5130d1b.o |
6 | 6 | ||
7 | obj-$(CONFIG_USB_DABUSB) += dabusb.o | 7 | obj-$(CONFIG_USB_DABUSB) += dabusb.o |
8 | obj-$(CONFIG_USB_DSBR) += dsbr100.o | 8 | obj-$(CONFIG_USB_DSBR) += dsbr100.o |
diff --git a/drivers/usb/media/sn9c102.h b/drivers/usb/media/sn9c102.h index 8b8a4c8743f8..e5cea0e2eb57 100644 --- a/drivers/usb/media/sn9c102.h +++ b/drivers/usb/media/sn9c102.h | |||
@@ -56,7 +56,7 @@ | |||
56 | #define SN9C102_MODULE_AUTHOR "(C) 2004-2005 Luca Risolia" | 56 | #define SN9C102_MODULE_AUTHOR "(C) 2004-2005 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.24" | 59 | #define SN9C102_MODULE_VERSION "1:1.24a" |
60 | #define SN9C102_MODULE_VERSION_CODE KERNEL_VERSION(1, 0, 24) | 60 | #define SN9C102_MODULE_VERSION_CODE KERNEL_VERSION(1, 0, 24) |
61 | 61 | ||
62 | enum sn9c102_bridge { | 62 | enum sn9c102_bridge { |
diff --git a/drivers/usb/media/sn9c102_core.c b/drivers/usb/media/sn9c102_core.c index 31d57400d5be..cf8cfbabefde 100644 --- a/drivers/usb/media/sn9c102_core.c +++ b/drivers/usb/media/sn9c102_core.c | |||
@@ -429,7 +429,7 @@ sn9c102_i2c_try_read(struct sn9c102_device* cam, | |||
429 | } | 429 | } |
430 | 430 | ||
431 | 431 | ||
432 | static int | 432 | int |
433 | sn9c102_i2c_try_write(struct sn9c102_device* cam, | 433 | sn9c102_i2c_try_write(struct sn9c102_device* cam, |
434 | struct sn9c102_sensor* sensor, u8 address, u8 value) | 434 | struct sn9c102_sensor* sensor, u8 address, u8 value) |
435 | { | 435 | { |
diff --git a/drivers/usb/media/sn9c102_ov7630.c b/drivers/usb/media/sn9c102_ov7630.c new file mode 100644 index 000000000000..d27c5aedeaf8 --- /dev/null +++ b/drivers/usb/media/sn9c102_ov7630.c | |||
@@ -0,0 +1,394 @@ | |||
1 | /*************************************************************************** | ||
2 | * Plug-in for OV7630 image sensor connected to the SN9C10x PC Camera * | ||
3 | * Controllers * | ||
4 | * * | ||
5 | * Copyright (C) 2005 by Luca Risolia <luca.risolia@studio.unibo.it> * | ||
6 | * * | ||
7 | * This program is free software; you can redistribute it and/or modify * | ||
8 | * it under the terms of the GNU General Public License as published by * | ||
9 | * the Free Software Foundation; either version 2 of the License, or * | ||
10 | * (at your option) any later version. * | ||
11 | * * | ||
12 | * This program is distributed in the hope that it will be useful, * | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | ||
15 | * GNU General Public License for more details. * | ||
16 | * * | ||
17 | * You should have received a copy of the GNU General Public License * | ||
18 | * along with this program; if not, write to the Free Software * | ||
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * | ||
20 | ***************************************************************************/ | ||
21 | |||
22 | #include "sn9c102_sensor.h" | ||
23 | |||
24 | |||
25 | static struct sn9c102_sensor ov7630; | ||
26 | |||
27 | |||
28 | static int ov7630_init(struct sn9c102_device* cam) | ||
29 | { | ||
30 | int err = 0; | ||
31 | |||
32 | err += sn9c102_write_reg(cam, 0x00, 0x14); | ||
33 | err += sn9c102_write_reg(cam, 0x60, 0x17); | ||
34 | err += sn9c102_write_reg(cam, 0x0f, 0x18); | ||
35 | err += sn9c102_write_reg(cam, 0x50, 0x19); | ||
36 | |||
37 | err += sn9c102_i2c_write(cam, 0x12, 0x8d); | ||
38 | err += sn9c102_i2c_write(cam, 0x11, 0x00); | ||
39 | err += sn9c102_i2c_write(cam, 0x15, 0x34); | ||
40 | err += sn9c102_i2c_write(cam, 0x16, 0x03); | ||
41 | err += sn9c102_i2c_write(cam, 0x17, 0x1c); | ||
42 | err += sn9c102_i2c_write(cam, 0x18, 0xbd); | ||
43 | err += sn9c102_i2c_write(cam, 0x19, 0x06); | ||
44 | err += sn9c102_i2c_write(cam, 0x1a, 0xf6); | ||
45 | err += sn9c102_i2c_write(cam, 0x1b, 0x04); | ||
46 | err += sn9c102_i2c_write(cam, 0x20, 0x44); | ||
47 | err += sn9c102_i2c_write(cam, 0x23, 0xee); | ||
48 | err += sn9c102_i2c_write(cam, 0x26, 0xa0); | ||
49 | err += sn9c102_i2c_write(cam, 0x27, 0x9a); | ||
50 | err += sn9c102_i2c_write(cam, 0x28, 0x20); | ||
51 | err += sn9c102_i2c_write(cam, 0x29, 0x30); | ||
52 | err += sn9c102_i2c_write(cam, 0x2f, 0x3d); | ||
53 | err += sn9c102_i2c_write(cam, 0x30, 0x24); | ||
54 | err += sn9c102_i2c_write(cam, 0x32, 0x86); | ||
55 | err += sn9c102_i2c_write(cam, 0x60, 0xa9); | ||
56 | err += sn9c102_i2c_write(cam, 0x61, 0x42); | ||
57 | err += sn9c102_i2c_write(cam, 0x65, 0x00); | ||
58 | err += sn9c102_i2c_write(cam, 0x69, 0x38); | ||
59 | err += sn9c102_i2c_write(cam, 0x6f, 0x88); | ||
60 | err += sn9c102_i2c_write(cam, 0x70, 0x0b); | ||
61 | err += sn9c102_i2c_write(cam, 0x71, 0x00); | ||
62 | err += sn9c102_i2c_write(cam, 0x74, 0x21); | ||
63 | err += sn9c102_i2c_write(cam, 0x7d, 0xf7); | ||
64 | |||
65 | return err; | ||
66 | } | ||
67 | |||
68 | |||
69 | static int ov7630_set_ctrl(struct sn9c102_device* cam, | ||
70 | const struct v4l2_control* ctrl) | ||
71 | { | ||
72 | int err = 0; | ||
73 | |||
74 | switch (ctrl->id) { | ||
75 | case V4L2_CID_EXPOSURE: | ||
76 | err += sn9c102_i2c_write(cam, 0x10, ctrl->value >> 2); | ||
77 | err += sn9c102_i2c_write(cam, 0x76, ctrl->value & 0x03); | ||
78 | break; | ||
79 | case V4L2_CID_RED_BALANCE: | ||
80 | err += sn9c102_i2c_write(cam, 0x02, ctrl->value); | ||
81 | break; | ||
82 | case V4L2_CID_BLUE_BALANCE: | ||
83 | err += sn9c102_i2c_write(cam, 0x03, ctrl->value); | ||
84 | break; | ||
85 | case V4L2_CID_GAIN: | ||
86 | err += sn9c102_i2c_write(cam, 0x00, ctrl->value); | ||
87 | break; | ||
88 | case V4L2_CID_CONTRAST: | ||
89 | err += ctrl->value ? sn9c102_i2c_write(cam, 0x05, | ||
90 | (ctrl->value-1) | 0x20) | ||
91 | : sn9c102_i2c_write(cam, 0x05, 0x00); | ||
92 | break; | ||
93 | case V4L2_CID_BRIGHTNESS: | ||
94 | err += sn9c102_i2c_write(cam, 0x06, ctrl->value); | ||
95 | break; | ||
96 | case V4L2_CID_SATURATION: | ||
97 | err += sn9c102_i2c_write(cam, 0x03, ctrl->value << 4); | ||
98 | break; | ||
99 | case V4L2_CID_HUE: | ||
100 | err += ctrl->value ? sn9c102_i2c_write(cam, 0x04, | ||
101 | (ctrl->value-1) | 0x20) | ||
102 | : sn9c102_i2c_write(cam, 0x04, 0x00); | ||
103 | break; | ||
104 | case V4L2_CID_DO_WHITE_BALANCE: | ||
105 | err += sn9c102_i2c_write(cam, 0x0c, ctrl->value); | ||
106 | break; | ||
107 | case V4L2_CID_WHITENESS: | ||
108 | err += sn9c102_i2c_write(cam, 0x0d, ctrl->value); | ||
109 | break; | ||
110 | case V4L2_CID_AUTO_WHITE_BALANCE: | ||
111 | err += sn9c102_i2c_write(cam, 0x12, (ctrl->value << 2) | 0x09); | ||
112 | break; | ||
113 | case V4L2_CID_AUTOGAIN: | ||
114 | err += sn9c102_i2c_write(cam, 0x13, ctrl->value); | ||
115 | break; | ||
116 | case V4L2_CID_VFLIP: | ||
117 | err += sn9c102_i2c_write(cam, 0x75, 0x0e | (ctrl->value << 7)); | ||
118 | break; | ||
119 | case V4L2_CID_BLACK_LEVEL: | ||
120 | err += sn9c102_i2c_write(cam, 0x25, ctrl->value); | ||
121 | break; | ||
122 | case SN9C102_V4L2_CID_BRIGHT_LEVEL: | ||
123 | err += sn9c102_i2c_write(cam, 0x24, ctrl->value); | ||
124 | break; | ||
125 | case SN9C102_V4L2_CID_GAMMA: | ||
126 | err += sn9c102_i2c_write(cam, 0x14, (ctrl->value << 2) | 0x80); | ||
127 | break; | ||
128 | case SN9C102_V4L2_CID_BAND_FILTER: | ||
129 | err += sn9c102_i2c_write(cam, 0x2d, ctrl->value << 2); | ||
130 | break; | ||
131 | default: | ||
132 | return -EINVAL; | ||
133 | } | ||
134 | |||
135 | return err ? -EIO : 0; | ||
136 | } | ||
137 | |||
138 | |||
139 | static int ov7630_set_crop(struct sn9c102_device* cam, | ||
140 | const struct v4l2_rect* rect) | ||
141 | { | ||
142 | struct sn9c102_sensor* s = &ov7630; | ||
143 | int err = 0; | ||
144 | u8 v_start = (u8)(rect->top - s->cropcap.bounds.top) + 1; | ||
145 | |||
146 | err += sn9c102_write_reg(cam, v_start, 0x13); | ||
147 | |||
148 | return err; | ||
149 | } | ||
150 | |||
151 | |||
152 | static int ov7630_set_pix_format(struct sn9c102_device* cam, | ||
153 | const struct v4l2_pix_format* pix) | ||
154 | { | ||
155 | int err = 0; | ||
156 | |||
157 | if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X) | ||
158 | err += sn9c102_write_reg(cam, 0x20, 0x19); | ||
159 | else | ||
160 | err += sn9c102_write_reg(cam, 0x50, 0x19); | ||
161 | |||
162 | return err; | ||
163 | } | ||
164 | |||
165 | |||
166 | static struct sn9c102_sensor ov7630 = { | ||
167 | .name = "OV7630", | ||
168 | .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>", | ||
169 | .sysfs_ops = SN9C102_I2C_WRITE, | ||
170 | .frequency = SN9C102_I2C_100KHZ, | ||
171 | .interface = SN9C102_I2C_2WIRES, | ||
172 | .i2c_slave_id = 0x21, | ||
173 | .init = &ov7630_init, | ||
174 | .qctrl = { | ||
175 | { | ||
176 | .id = V4L2_CID_GAIN, | ||
177 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
178 | .name = "global gain", | ||
179 | .minimum = 0x00, | ||
180 | .maximum = 0x3f, | ||
181 | .step = 0x01, | ||
182 | .default_value = 0x14, | ||
183 | .flags = 0, | ||
184 | }, | ||
185 | { | ||
186 | .id = V4L2_CID_HUE, | ||
187 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
188 | .name = "hue", | ||
189 | .minimum = 0x00, | ||
190 | .maximum = 0x1f+1, | ||
191 | .step = 0x01, | ||
192 | .default_value = 0x00, | ||
193 | .flags = 0, | ||
194 | }, | ||
195 | { | ||
196 | .id = V4L2_CID_SATURATION, | ||
197 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
198 | .name = "saturation", | ||
199 | .minimum = 0x00, | ||
200 | .maximum = 0x0f, | ||
201 | .step = 0x01, | ||
202 | .default_value = 0x08, | ||
203 | .flags = 0, | ||
204 | }, | ||
205 | { | ||
206 | .id = V4L2_CID_CONTRAST, | ||
207 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
208 | .name = "contrast", | ||
209 | .minimum = 0x00, | ||
210 | .maximum = 0x1f+1, | ||
211 | .step = 0x01, | ||
212 | .default_value = 0x00, | ||
213 | .flags = 0, | ||
214 | }, | ||
215 | { | ||
216 | .id = V4L2_CID_EXPOSURE, | ||
217 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
218 | .name = "exposure", | ||
219 | .minimum = 0x000, | ||
220 | .maximum = 0x3ff, | ||
221 | .step = 0x001, | ||
222 | .default_value = 0x83<<2, | ||
223 | .flags = 0, | ||
224 | }, | ||
225 | { | ||
226 | .id = V4L2_CID_RED_BALANCE, | ||
227 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
228 | .name = "red balance", | ||
229 | .minimum = 0x00, | ||
230 | .maximum = 0xff, | ||
231 | .step = 0x01, | ||
232 | .default_value = 0x3a, | ||
233 | .flags = 0, | ||
234 | }, | ||
235 | { | ||
236 | .id = V4L2_CID_BLUE_BALANCE, | ||
237 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
238 | .name = "blue balance", | ||
239 | .minimum = 0x00, | ||
240 | .maximum = 0xff, | ||
241 | .step = 0x01, | ||
242 | .default_value = 0x77, | ||
243 | .flags = 0, | ||
244 | }, | ||
245 | { | ||
246 | .id = V4L2_CID_BRIGHTNESS, | ||
247 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
248 | .name = "brightness", | ||
249 | .minimum = 0x00, | ||
250 | .maximum = 0xff, | ||
251 | .step = 0x01, | ||
252 | .default_value = 0xa0, | ||
253 | .flags = 0, | ||
254 | }, | ||
255 | { | ||
256 | .id = V4L2_CID_DO_WHITE_BALANCE, | ||
257 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
258 | .name = "white balance background: blue", | ||
259 | .minimum = 0x00, | ||
260 | .maximum = 0x3f, | ||
261 | .step = 0x01, | ||
262 | .default_value = 0x20, | ||
263 | .flags = 0, | ||
264 | }, | ||
265 | { | ||
266 | .id = V4L2_CID_WHITENESS, | ||
267 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
268 | .name = "white balance background: red", | ||
269 | .minimum = 0x00, | ||
270 | .maximum = 0x3f, | ||
271 | .step = 0x01, | ||
272 | .default_value = 0x20, | ||
273 | .flags = 0, | ||
274 | }, | ||
275 | { | ||
276 | .id = V4L2_CID_AUTO_WHITE_BALANCE, | ||
277 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
278 | .name = "auto white balance", | ||
279 | .minimum = 0x00, | ||
280 | .maximum = 0x01, | ||
281 | .step = 0x01, | ||
282 | .default_value = 0x01, | ||
283 | .flags = 0, | ||
284 | }, | ||
285 | { | ||
286 | .id = V4L2_CID_AUTOGAIN, | ||
287 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
288 | .name = "gain & exposure mode", | ||
289 | .minimum = 0x00, | ||
290 | .maximum = 0x03, | ||
291 | .step = 0x01, | ||
292 | .default_value = 0x00, | ||
293 | .flags = 0, | ||
294 | }, | ||
295 | { | ||
296 | .id = V4L2_CID_VFLIP, | ||
297 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
298 | .name = "vertical flip", | ||
299 | .minimum = 0x00, | ||
300 | .maximum = 0x01, | ||
301 | .step = 0x01, | ||
302 | .default_value = 0x01, | ||
303 | .flags = 0, | ||
304 | }, | ||
305 | { | ||
306 | .id = V4L2_CID_BLACK_LEVEL, | ||
307 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
308 | .name = "black pixel ratio", | ||
309 | .minimum = 0x01, | ||
310 | .maximum = 0x9a, | ||
311 | .step = 0x01, | ||
312 | .default_value = 0x8a, | ||
313 | .flags = 0, | ||
314 | }, | ||
315 | { | ||
316 | .id = SN9C102_V4L2_CID_BRIGHT_LEVEL, | ||
317 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
318 | .name = "bright pixel ratio", | ||
319 | .minimum = 0x01, | ||
320 | .maximum = 0x9a, | ||
321 | .step = 0x01, | ||
322 | .default_value = 0x10, | ||
323 | .flags = 0, | ||
324 | }, | ||
325 | { | ||
326 | .id = SN9C102_V4L2_CID_BAND_FILTER, | ||
327 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
328 | .name = "band filter", | ||
329 | .minimum = 0x00, | ||
330 | .maximum = 0x01, | ||
331 | .step = 0x01, | ||
332 | .default_value = 0x00, | ||
333 | .flags = 0, | ||
334 | }, | ||
335 | { | ||
336 | .id = SN9C102_V4L2_CID_GAMMA, | ||
337 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
338 | .name = "rgb gamma", | ||
339 | .minimum = 0x00, | ||
340 | .maximum = 0x01, | ||
341 | .step = 0x01, | ||
342 | .default_value = 0x00, | ||
343 | .flags = 0, | ||
344 | }, | ||
345 | }, | ||
346 | .set_ctrl = &ov7630_set_ctrl, | ||
347 | .cropcap = { | ||
348 | .bounds = { | ||
349 | .left = 0, | ||
350 | .top = 0, | ||
351 | .width = 640, | ||
352 | .height = 480, | ||
353 | }, | ||
354 | .defrect = { | ||
355 | .left = 0, | ||
356 | .top = 0, | ||
357 | .width = 640, | ||
358 | .height = 480, | ||
359 | }, | ||
360 | }, | ||
361 | .set_crop = &ov7630_set_crop, | ||
362 | .pix_format = { | ||
363 | .width = 640, | ||
364 | .height = 480, | ||
365 | .pixelformat = V4L2_PIX_FMT_SBGGR8, | ||
366 | .priv = 8, | ||
367 | }, | ||
368 | .set_pix_format = &ov7630_set_pix_format | ||
369 | }; | ||
370 | |||
371 | |||
372 | int sn9c102_probe_ov7630(struct sn9c102_device* cam) | ||
373 | { | ||
374 | int err = 0; | ||
375 | |||
376 | sn9c102_attach_sensor(cam, &ov7630); | ||
377 | |||
378 | if (le16_to_cpu(ov7630.usbdev->descriptor.idProduct) != 0x608f && | ||
379 | le16_to_cpu(ov7630.usbdev->descriptor.idProduct) != 0x602c) | ||
380 | return -ENODEV; | ||
381 | |||
382 | err += sn9c102_write_reg(cam, 0x01, 0x01); | ||
383 | err += sn9c102_write_reg(cam, 0x00, 0x01); | ||
384 | err += sn9c102_write_reg(cam, 0x28, 0x17); | ||
385 | |||
386 | if (err) | ||
387 | return -EIO; | ||
388 | |||
389 | err += sn9c102_i2c_write(cam, 0x0b, 0); | ||
390 | if (err) | ||
391 | return -ENODEV; | ||
392 | |||
393 | return 0; | ||
394 | } | ||
diff --git a/drivers/usb/media/sn9c102_sensor.h b/drivers/usb/media/sn9c102_sensor.h index 6a7adebcb4bf..a45166c3488c 100644 --- a/drivers/usb/media/sn9c102_sensor.h +++ b/drivers/usb/media/sn9c102_sensor.h | |||
@@ -64,6 +64,7 @@ struct sn9c102_sensor; | |||
64 | */ | 64 | */ |
65 | extern int sn9c102_probe_hv7131d(struct sn9c102_device* cam); | 65 | extern int sn9c102_probe_hv7131d(struct sn9c102_device* cam); |
66 | extern int sn9c102_probe_mi0343(struct sn9c102_device* cam); | 66 | extern int sn9c102_probe_mi0343(struct sn9c102_device* cam); |
67 | extern int sn9c102_probe_ov7630(struct sn9c102_device* cam); | ||
67 | extern int sn9c102_probe_pas106b(struct sn9c102_device* cam); | 68 | extern int sn9c102_probe_pas106b(struct sn9c102_device* cam); |
68 | extern int sn9c102_probe_pas202bcb(struct sn9c102_device* cam); | 69 | extern int sn9c102_probe_pas202bcb(struct sn9c102_device* cam); |
69 | extern int sn9c102_probe_tas5110c1b(struct sn9c102_device* cam); | 70 | extern int sn9c102_probe_tas5110c1b(struct sn9c102_device* cam); |
@@ -80,6 +81,7 @@ static int (*sn9c102_sensor_table[])(struct sn9c102_device*) = { \ | |||
80 | &sn9c102_probe_pas106b, /* strong detection based on SENSOR ids */ \ | 81 | &sn9c102_probe_pas106b, /* strong detection based on SENSOR ids */ \ |
81 | &sn9c102_probe_pas202bcb, /* strong detection based on SENSOR ids */ \ | 82 | &sn9c102_probe_pas202bcb, /* strong detection based on SENSOR ids */ \ |
82 | &sn9c102_probe_hv7131d, /* strong detection based on SENSOR ids */ \ | 83 | &sn9c102_probe_hv7131d, /* strong detection based on SENSOR ids */ \ |
84 | &sn9c102_probe_ov7630, /* detection mostly based on USB pid/vid */ \ | ||
83 | &sn9c102_probe_tas5110c1b, /* detection based on USB pid/vid */ \ | 85 | &sn9c102_probe_tas5110c1b, /* detection based on USB pid/vid */ \ |
84 | &sn9c102_probe_tas5130d1b, /* detection based on USB pid/vid */ \ | 86 | &sn9c102_probe_tas5130d1b, /* detection based on USB pid/vid */ \ |
85 | NULL, \ | 87 | NULL, \ |
@@ -103,7 +105,8 @@ static const struct usb_device_id sn9c102_id_table[] = { \ | |||
103 | { USB_DEVICE(0x0c45, 0x6029), }, /* PAS106B */ \ | 105 | { USB_DEVICE(0x0c45, 0x6029), }, /* PAS106B */ \ |
104 | { USB_DEVICE(0x0c45, 0x602a), }, /* HV7131D */ \ | 106 | { USB_DEVICE(0x0c45, 0x602a), }, /* HV7131D */ \ |
105 | { USB_DEVICE(0x0c45, 0x602b), }, /* MI-0343 */ \ | 107 | { USB_DEVICE(0x0c45, 0x602b), }, /* MI-0343 */ \ |
106 | { USB_DEVICE(0x0c45, 0x602c), }, /* OV7620 */ \ | 108 | { USB_DEVICE(0x0c45, 0x602c), }, /* OV7630 */ \ |
109 | { USB_DEVICE(0x0c45, 0x602d), }, \ | ||
107 | { USB_DEVICE(0x0c45, 0x6030), }, /* MI03x */ \ | 110 | { USB_DEVICE(0x0c45, 0x6030), }, /* MI03x */ \ |
108 | { USB_DEVICE(0x0c45, 0x6080), }, \ | 111 | { USB_DEVICE(0x0c45, 0x6080), }, \ |
109 | { USB_DEVICE(0x0c45, 0x6082), }, /* MI0343 and MI0360 */ \ | 112 | { USB_DEVICE(0x0c45, 0x6082), }, /* MI0343 and MI0360 */ \ |
@@ -145,6 +148,8 @@ static const struct usb_device_id sn9c102_id_table[] = { \ | |||
145 | */ | 148 | */ |
146 | 149 | ||
147 | /* The "try" I2C I/O versions are used when probing the sensor */ | 150 | /* The "try" I2C I/O versions are used when probing the sensor */ |
151 | extern int sn9c102_i2c_try_write(struct sn9c102_device*,struct sn9c102_sensor*, | ||
152 | u8 address, u8 value); | ||
148 | extern int sn9c102_i2c_try_read(struct sn9c102_device*,struct sn9c102_sensor*, | 153 | extern int sn9c102_i2c_try_read(struct sn9c102_device*,struct sn9c102_sensor*, |
149 | u8 address); | 154 | u8 address); |
150 | 155 | ||
@@ -201,6 +206,8 @@ enum sn9c102_i2c_interface { | |||
201 | SN9C102_I2C_3WIRES, | 206 | SN9C102_I2C_3WIRES, |
202 | }; | 207 | }; |
203 | 208 | ||
209 | #define SN9C102_MAX_CTRLS V4L2_CID_LASTP1-V4L2_CID_BASE+10 | ||
210 | |||
204 | struct sn9c102_sensor { | 211 | struct sn9c102_sensor { |
205 | char name[32], /* sensor name */ | 212 | char name[32], /* sensor name */ |
206 | maintainer[64]; /* name of the mantainer <email> */ | 213 | maintainer[64]; /* name of the mantainer <email> */ |
@@ -243,7 +250,7 @@ struct sn9c102_sensor { | |||
243 | sensor according to the default configuration structures below. | 250 | sensor according to the default configuration structures below. |
244 | */ | 251 | */ |
245 | 252 | ||
246 | struct v4l2_queryctrl qctrl[V4L2_CID_LASTP1-V4L2_CID_BASE]; | 253 | struct v4l2_queryctrl qctrl[SN9C102_MAX_CTRLS]; |
247 | /* | 254 | /* |
248 | Optional list of default controls, defined as indicated in the | 255 | Optional list of default controls, defined as indicated in the |
249 | V4L2 API. Menu type controls are not handled by this interface. | 256 | V4L2 API. Menu type controls are not handled by this interface. |
@@ -356,7 +363,7 @@ struct sn9c102_sensor { | |||
356 | core module to store successfully updated values of the above | 363 | core module to store successfully updated values of the above |
357 | settings, for rollbacks..etc..in case of errors during atomic I/O | 364 | settings, for rollbacks..etc..in case of errors during atomic I/O |
358 | */ | 365 | */ |
359 | struct v4l2_queryctrl _qctrl[V4L2_CID_LASTP1-V4L2_CID_BASE]; | 366 | struct v4l2_queryctrl _qctrl[SN9C102_MAX_CTRLS]; |
360 | struct v4l2_rect _rect; | 367 | struct v4l2_rect _rect; |
361 | }; | 368 | }; |
362 | 369 | ||
@@ -367,5 +374,8 @@ struct sn9c102_sensor { | |||
367 | #define SN9C102_V4L2_CID_GREEN_BALANCE V4L2_CID_PRIVATE_BASE + 1 | 374 | #define SN9C102_V4L2_CID_GREEN_BALANCE V4L2_CID_PRIVATE_BASE + 1 |
368 | #define SN9C102_V4L2_CID_RESET_LEVEL V4L2_CID_PRIVATE_BASE + 2 | 375 | #define SN9C102_V4L2_CID_RESET_LEVEL V4L2_CID_PRIVATE_BASE + 2 |
369 | #define SN9C102_V4L2_CID_PIXEL_BIAS_VOLTAGE V4L2_CID_PRIVATE_BASE + 3 | 376 | #define SN9C102_V4L2_CID_PIXEL_BIAS_VOLTAGE V4L2_CID_PRIVATE_BASE + 3 |
377 | #define SN9C102_V4L2_CID_GAMMA V4L2_CID_PRIVATE_BASE + 4 | ||
378 | #define SN9C102_V4L2_CID_BAND_FILTER V4L2_CID_PRIVATE_BASE + 5 | ||
379 | #define SN9C102_V4L2_CID_BRIGHT_LEVEL V4L2_CID_PRIVATE_BASE + 6 | ||
370 | 380 | ||
371 | #endif /* _SN9C102_SENSOR_H_ */ | 381 | #endif /* _SN9C102_SENSOR_H_ */ |
diff --git a/drivers/usb/media/sn9c102_tas5110c1b.c b/drivers/usb/media/sn9c102_tas5110c1b.c index 690d62192273..8775999b5aff 100644 --- a/drivers/usb/media/sn9c102_tas5110c1b.c +++ b/drivers/usb/media/sn9c102_tas5110c1b.c | |||
@@ -24,8 +24,6 @@ | |||
24 | 24 | ||
25 | static struct sn9c102_sensor tas5110c1b; | 25 | static struct sn9c102_sensor tas5110c1b; |
26 | 26 | ||
27 | static struct v4l2_control tas5110c1b_gain; | ||
28 | |||
29 | 27 | ||
30 | static int tas5110c1b_init(struct sn9c102_device* cam) | 28 | static int tas5110c1b_init(struct sn9c102_device* cam) |
31 | { | 29 | { |
@@ -46,21 +44,6 @@ static int tas5110c1b_init(struct sn9c102_device* cam) | |||
46 | } | 44 | } |
47 | 45 | ||
48 | 46 | ||
49 | static int tas5110c1b_get_ctrl(struct sn9c102_device* cam, | ||
50 | struct v4l2_control* ctrl) | ||
51 | { | ||
52 | switch (ctrl->id) { | ||
53 | case V4L2_CID_GAIN: | ||
54 | ctrl->value = tas5110c1b_gain.value; | ||
55 | break; | ||
56 | default: | ||
57 | return -EINVAL; | ||
58 | } | ||
59 | |||
60 | return 0; | ||
61 | } | ||
62 | |||
63 | |||
64 | static int tas5110c1b_set_ctrl(struct sn9c102_device* cam, | 47 | static int tas5110c1b_set_ctrl(struct sn9c102_device* cam, |
65 | const struct v4l2_control* ctrl) | 48 | const struct v4l2_control* ctrl) |
66 | { | 49 | { |
@@ -68,8 +51,7 @@ static int tas5110c1b_set_ctrl(struct sn9c102_device* cam, | |||
68 | 51 | ||
69 | switch (ctrl->id) { | 52 | switch (ctrl->id) { |
70 | case V4L2_CID_GAIN: | 53 | case V4L2_CID_GAIN: |
71 | if (!(err += sn9c102_i2c_write(cam, 0x20, 0xf6 - ctrl->value))) | 54 | err += sn9c102_i2c_write(cam, 0x20, 0xf6 - ctrl->value); |
72 | tas5110c1b_gain.value = ctrl->value; | ||
73 | break; | 55 | break; |
74 | default: | 56 | default: |
75 | return -EINVAL; | 57 | return -EINVAL; |
@@ -147,7 +129,6 @@ static struct sn9c102_sensor tas5110c1b = { | |||
147 | .height = 288, | 129 | .height = 288, |
148 | }, | 130 | }, |
149 | }, | 131 | }, |
150 | .get_ctrl = &tas5110c1b_get_ctrl, | ||
151 | .set_crop = &tas5110c1b_set_crop, | 132 | .set_crop = &tas5110c1b_set_crop, |
152 | .pix_format = { | 133 | .pix_format = { |
153 | .width = 352, | 134 | .width = 352, |
diff --git a/drivers/usb/media/sn9c102_tas5130d1b.c b/drivers/usb/media/sn9c102_tas5130d1b.c index b378e941bbe8..927eafdd8c73 100644 --- a/drivers/usb/media/sn9c102_tas5130d1b.c +++ b/drivers/usb/media/sn9c102_tas5130d1b.c | |||
@@ -24,8 +24,6 @@ | |||
24 | 24 | ||
25 | static struct sn9c102_sensor tas5130d1b; | 25 | static struct sn9c102_sensor tas5130d1b; |
26 | 26 | ||
27 | static struct v4l2_control tas5130d1b_gain, tas5130d1b_exposure; | ||
28 | |||
29 | 27 | ||
30 | static int tas5130d1b_init(struct sn9c102_device* cam) | 28 | static int tas5130d1b_init(struct sn9c102_device* cam) |
31 | { | 29 | { |
@@ -44,24 +42,6 @@ static int tas5130d1b_init(struct sn9c102_device* cam) | |||
44 | } | 42 | } |
45 | 43 | ||
46 | 44 | ||
47 | static int tas5130d1b_get_ctrl(struct sn9c102_device* cam, | ||
48 | struct v4l2_control* ctrl) | ||
49 | { | ||
50 | switch (ctrl->id) { | ||
51 | case V4L2_CID_GAIN: | ||
52 | ctrl->value = tas5130d1b_gain.value; | ||
53 | break; | ||
54 | case V4L2_CID_EXPOSURE: | ||
55 | ctrl->value = tas5130d1b_exposure.value; | ||
56 | break; | ||
57 | default: | ||
58 | return -EINVAL; | ||
59 | } | ||
60 | |||
61 | return 0; | ||
62 | } | ||
63 | |||
64 | |||
65 | static int tas5130d1b_set_ctrl(struct sn9c102_device* cam, | 45 | static int tas5130d1b_set_ctrl(struct sn9c102_device* cam, |
66 | const struct v4l2_control* ctrl) | 46 | const struct v4l2_control* ctrl) |
67 | { | 47 | { |
@@ -69,12 +49,10 @@ static int tas5130d1b_set_ctrl(struct sn9c102_device* cam, | |||
69 | 49 | ||
70 | switch (ctrl->id) { | 50 | switch (ctrl->id) { |
71 | case V4L2_CID_GAIN: | 51 | case V4L2_CID_GAIN: |
72 | if (!(err += sn9c102_i2c_write(cam, 0x20, 0xf6 - ctrl->value))) | 52 | err += sn9c102_i2c_write(cam, 0x20, 0xf6 - ctrl->value); |
73 | tas5130d1b_gain.value = ctrl->value; | ||
74 | break; | 53 | break; |
75 | case V4L2_CID_EXPOSURE: | 54 | case V4L2_CID_EXPOSURE: |
76 | if (!(err += sn9c102_i2c_write(cam, 0x40, 0x47 - ctrl->value))) | 55 | err += sn9c102_i2c_write(cam, 0x40, 0x47 - ctrl->value); |
77 | tas5130d1b_exposure.value = ctrl->value; | ||
78 | break; | 56 | break; |
79 | default: | 57 | default: |
80 | return -EINVAL; | 58 | return -EINVAL; |
@@ -147,7 +125,6 @@ static struct sn9c102_sensor tas5130d1b = { | |||
147 | .flags = 0, | 125 | .flags = 0, |
148 | }, | 126 | }, |
149 | }, | 127 | }, |
150 | .get_ctrl = &tas5130d1b_get_ctrl, | ||
151 | .set_ctrl = &tas5130d1b_set_ctrl, | 128 | .set_ctrl = &tas5130d1b_set_ctrl, |
152 | .cropcap = { | 129 | .cropcap = { |
153 | .bounds = { | 130 | .bounds = { |