]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/blame - drivers/media/usb/gspca/spca561.c
Merge tag 'ecryptfs-3.10-rc1-ablkcipher' of git://git.kernel.org/pub/scm/linux/kernel...
[mirror_ubuntu-hirsute-kernel.git] / drivers / media / usb / gspca / spca561.c
CommitLineData
6a7eba24
JFM
1/*
2 * Sunplus spca561 subdriver
3 *
4 * Copyright (C) 2004 Michel Xhaard mxhaard@magic.fr
5 *
6 * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
133a9fe9
JP
23#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
24
6a7eba24
JFM
25#define MODULE_NAME "spca561"
26
436c2c53 27#include <linux/input.h>
6a7eba24
JFM
28#include "gspca.h"
29
6a7eba24
JFM
30MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
31MODULE_DESCRIPTION("GSPCA/SPCA561 USB Camera Driver");
32MODULE_LICENSE("GPL");
33
3fa24bf5
HV
34#define EXPOSURE_MAX (2047 + 325)
35
6a7eba24
JFM
36/* specific webcam descriptor */
37struct sd {
38 struct gspca_dev gspca_dev; /* !! must be the first item */
39
3fa24bf5
HV
40 struct { /* hue/contrast control cluster */
41 struct v4l2_ctrl *contrast;
42 struct v4l2_ctrl *hue;
43 };
44 struct v4l2_ctrl *autogain;
6a7eba24 45
d698dc6b
JFM
46#define EXPO12A_DEF 3
47 __u8 expo12a; /* expo/gain? for rev 12a */
48
6a7eba24 49 __u8 chip_revision;
7879d459
JFM
50#define Rev012A 0
51#define Rev072A 1
52
6a7eba24
JFM
53 signed char ag_cnt;
54#define AG_CNT_START 13
55};
56
cc611b8a 57static const struct v4l2_pix_format sif_012a_mode[] = {
c2446b3e
JFM
58 {160, 120, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
59 .bytesperline = 160,
60 .sizeimage = 160 * 120,
61 .colorspace = V4L2_COLORSPACE_SRGB,
62 .priv = 3},
63 {176, 144, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
64 .bytesperline = 176,
65 .sizeimage = 176 * 144,
66 .colorspace = V4L2_COLORSPACE_SRGB,
67 .priv = 2},
68 {320, 240, V4L2_PIX_FMT_SPCA561, V4L2_FIELD_NONE,
69 .bytesperline = 320,
70 .sizeimage = 320 * 240 * 4 / 8,
71 .colorspace = V4L2_COLORSPACE_SRGB,
72 .priv = 1},
73 {352, 288, V4L2_PIX_FMT_SPCA561, V4L2_FIELD_NONE,
74 .bytesperline = 352,
75 .sizeimage = 352 * 288 * 4 / 8,
76 .colorspace = V4L2_COLORSPACE_SRGB,
77 .priv = 0},
6a7eba24
JFM
78};
79
cc611b8a 80static const struct v4l2_pix_format sif_072a_mode[] = {
b77c0046
JFM
81 {160, 120, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
82 .bytesperline = 160,
83 .sizeimage = 160 * 120,
84 .colorspace = V4L2_COLORSPACE_SRGB,
85 .priv = 3},
86 {176, 144, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
87 .bytesperline = 176,
88 .sizeimage = 176 * 144,
89 .colorspace = V4L2_COLORSPACE_SRGB,
90 .priv = 2},
91 {320, 240, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
92 .bytesperline = 320,
93 .sizeimage = 320 * 240,
94 .colorspace = V4L2_COLORSPACE_SRGB,
95 .priv = 1},
96 {352, 288, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
97 .bytesperline = 352,
98 .sizeimage = 352 * 288,
99 .colorspace = V4L2_COLORSPACE_SRGB,
100 .priv = 0},
101};
102
6a7eba24
JFM
103/*
104 * Initialization data
105 * I'm not very sure how to split initialization from open data
106 * chunks. For now, we'll consider everything as initialization
107 */
108/* Frame packet header offsets for the spca561 */
109#define SPCA561_OFFSET_SNAP 1
110#define SPCA561_OFFSET_TYPE 2
111#define SPCA561_OFFSET_COMPRESS 3
112#define SPCA561_OFFSET_FRAMSEQ 4
113#define SPCA561_OFFSET_GPIO 5
114#define SPCA561_OFFSET_USBBUFF 6
115#define SPCA561_OFFSET_WIN2GRAVE 7
116#define SPCA561_OFFSET_WIN2RAVE 8
117#define SPCA561_OFFSET_WIN2BAVE 9
118#define SPCA561_OFFSET_WIN2GBAVE 10
119#define SPCA561_OFFSET_WIN1GRAVE 11
120#define SPCA561_OFFSET_WIN1RAVE 12
121#define SPCA561_OFFSET_WIN1BAVE 13
122#define SPCA561_OFFSET_WIN1GBAVE 14
123#define SPCA561_OFFSET_FREQ 15
124#define SPCA561_OFFSET_VSYNC 16
6a7eba24
JFM
125#define SPCA561_INDEX_I2C_BASE 0x8800
126#define SPCA561_SNAPBIT 0x20
127#define SPCA561_SNAPCTRL 0x40
6a7eba24 128
0dbc2c16 129static const u16 rev72a_reset[][2] = {
6a7eba24
JFM
130 {0x0000, 0x8114}, /* Software GPIO output data */
131 {0x0001, 0x8114}, /* Software GPIO output data */
132 {0x0000, 0x8112}, /* Some kind of reset */
0dbc2c16
JFM
133 {}
134};
135static const __u16 rev72a_init_data1[][2] = {
6a7eba24
JFM
136 {0x0003, 0x8701}, /* PCLK clock delay adjustment */
137 {0x0001, 0x8703}, /* HSYNC from cmos inverted */
138 {0x0011, 0x8118}, /* Enable and conf sensor */
139 {0x0001, 0x8118}, /* Conf sensor */
140 {0x0092, 0x8804}, /* I know nothing about these */
141 {0x0010, 0x8802}, /* 0x88xx registers, so I won't */
f8a04a6f
JFM
142 {}
143};
0dbc2c16
JFM
144static const u16 rev72a_init_sensor1[][2] = {
145 {0x0001, 0x000d},
146 {0x0002, 0x0018},
147 {0x0004, 0x0165},
148 {0x0005, 0x0021},
149 {0x0007, 0x00aa},
150 {0x0020, 0x1504},
151 {0x0039, 0x0002},
152 {0x0035, 0x0010},
153 {0x0009, 0x1049},
154 {0x0028, 0x000b},
155 {0x003b, 0x000f},
156 {0x003c, 0x0000},
f8a04a6f
JFM
157 {}
158};
159static const __u16 rev72a_init_data2[][2] = {
6a7eba24
JFM
160 {0x0018, 0x8601}, /* Pixel/line selection for color separation */
161 {0x0000, 0x8602}, /* Optical black level for user setting */
162 {0x0060, 0x8604}, /* Optical black horizontal offset */
163 {0x0002, 0x8605}, /* Optical black vertical offset */
164 {0x0000, 0x8603}, /* Non-automatic optical black level */
165 {0x0002, 0x865b}, /* Horizontal offset for valid pixels */
166 {0x0000, 0x865f}, /* Vertical valid pixels window (x2) */
167 {0x00b0, 0x865d}, /* Horizontal valid pixels window (x2) */
168 {0x0090, 0x865e}, /* Vertical valid lines window (x2) */
169 {0x00e0, 0x8406}, /* Memory buffer threshold */
170 {0x0000, 0x8660}, /* Compensation memory stuff */
171 {0x0002, 0x8201}, /* Output address for r/w serial EEPROM */
172 {0x0008, 0x8200}, /* Clear valid bit for serial EEPROM */
173 {0x0001, 0x8200}, /* OprMode to be executed by hardware */
0dbc2c16
JFM
174/* from ms-win */
175 {0x0000, 0x8611}, /* R offset for white balance */
176 {0x00fd, 0x8612}, /* Gr offset for white balance */
177 {0x0003, 0x8613}, /* B offset for white balance */
6a7eba24 178 {0x0000, 0x8614}, /* Gb offset for white balance */
5b7ed28e
JFM
179/* from ms-win */
180 {0x0035, 0x8651}, /* R gain for white balance */
181 {0x0040, 0x8652}, /* Gr gain for white balance */
182 {0x005f, 0x8653}, /* B gain for white balance */
183 {0x0040, 0x8654}, /* Gb gain for white balance */
6a7eba24 184 {0x0002, 0x8502}, /* Maximum average bit rate stuff */
6a7eba24 185 {0x0011, 0x8802},
0dbc2c16 186
6a7eba24
JFM
187 {0x0087, 0x8700}, /* Set master clock (96Mhz????) */
188 {0x0081, 0x8702}, /* Master clock output enable */
189
190 {0x0000, 0x8500}, /* Set image type (352x288 no compression) */
191 /* Originally was 0x0010 (352x288 compression) */
192
193 {0x0002, 0x865b}, /* Horizontal offset for valid pixels */
194 {0x0003, 0x865c}, /* Vertical offset for valid lines */
f8a04a6f
JFM
195 {}
196};
0dbc2c16
JFM
197static const u16 rev72a_init_sensor2[][2] = {
198 {0x0003, 0x0121},
199 {0x0004, 0x0165},
200 {0x0005, 0x002f}, /* blanking control column */
201 {0x0006, 0x0000}, /* blanking mode row*/
202 {0x000a, 0x0002},
203 {0x0009, 0x1061}, /* setexposure times && pixel clock
6a7eba24 204 * 0001 0 | 000 0110 0001 */
0dbc2c16 205 {0x0035, 0x0014},
6a7eba24
JFM
206 {}
207};
208
6a7eba24 209/******************** QC Express etch2 stuff ********************/
a5ae2062 210static const __u16 Pb100_1map8300[][2] = {
6a7eba24
JFM
211 /* reg, value */
212 {0x8320, 0x3304},
213
214 {0x8303, 0x0125}, /* image area */
215 {0x8304, 0x0169},
216 {0x8328, 0x000b},
7879d459 217 {0x833c, 0x0001}, /*fixme: win:07*/
6a7eba24 218
7879d459 219 {0x832f, 0x1904}, /*fixme: was 0419*/
6a7eba24
JFM
220 {0x8307, 0x00aa},
221 {0x8301, 0x0003},
222 {0x8302, 0x000e},
223 {}
224};
a5ae2062 225static const __u16 Pb100_2map8300[][2] = {
6a7eba24
JFM
226 /* reg, value */
227 {0x8339, 0x0000},
228 {0x8307, 0x00aa},
229 {}
230};
231
a5ae2062 232static const __u16 spca561_161rev12A_data1[][2] = {
6b33e5e7
HG
233 {0x29, 0x8118}, /* Control register (various enable bits) */
234 {0x08, 0x8114}, /* GPIO: Led off */
235 {0x0e, 0x8112}, /* 0x0e stream off 0x3e stream on */
6c9d3c59 236 {0x00, 0x8102}, /* white balance - new */
6a7eba24
JFM
237 {0x92, 0x8804},
238 {0x04, 0x8802}, /* windows uses 08 */
239 {}
240};
a5ae2062 241static const __u16 spca561_161rev12A_data2[][2] = {
6a7eba24
JFM
242 {0x21, 0x8118},
243 {0x10, 0x8500},
244 {0x07, 0x8601},
245 {0x07, 0x8602},
246 {0x04, 0x8501},
6a7eba24
JFM
247
248 {0x07, 0x8201}, /* windows uses 02 */
249 {0x08, 0x8200},
250 {0x01, 0x8200},
251
6a7eba24
JFM
252 {0x90, 0x8604},
253 {0x00, 0x8605},
254 {0xb0, 0x8603},
255
256 /* sensor gains */
6c9d3c59
JFM
257 {0x07, 0x8601}, /* white balance - new */
258 {0x07, 0x8602}, /* white balance - new */
6a7eba24
JFM
259 {0x00, 0x8610}, /* *red */
260 {0x00, 0x8611}, /* 3f *green */
261 {0x00, 0x8612}, /* green *blue */
262 {0x00, 0x8613}, /* blue *green */
6c9d3c59
JFM
263 {0x43, 0x8614}, /* green *red - white balance - was 0x35 */
264 {0x40, 0x8615}, /* 40 *green - white balance - was 0x35 */
265 {0x71, 0x8616}, /* 7a *blue - white balance - was 0x35 */
266 {0x40, 0x8617}, /* 40 *green - white balance - was 0x35 */
6a7eba24
JFM
267
268 {0x0c, 0x8620}, /* 0c */
269 {0xc8, 0x8631}, /* c8 */
270 {0xc8, 0x8634}, /* c8 */
271 {0x23, 0x8635}, /* 23 */
272 {0x1f, 0x8636}, /* 1f */
273 {0xdd, 0x8637}, /* dd */
274 {0xe1, 0x8638}, /* e1 */
275 {0x1d, 0x8639}, /* 1d */
276 {0x21, 0x863a}, /* 21 */
277 {0xe3, 0x863b}, /* e3 */
278 {0xdf, 0x863c}, /* df */
279 {0xf0, 0x8505},
280 {0x32, 0x850a},
7879d459 281/* {0x99, 0x8700}, * - white balance - new (removed) */
6b33e5e7
HG
282 /* HDG we used to do this in stop0, making the init state and the state
283 after a start / stop different, so do this here instead. */
284 {0x29, 0x8118},
6a7eba24
JFM
285 {}
286};
287
c93396e1 288static void reg_w_val(struct gspca_dev *gspca_dev, __u16 index, __u8 value)
35dc1b4c
JFM
289{
290 int ret;
c93396e1 291 struct usb_device *dev = gspca_dev->dev;
35dc1b4c
JFM
292
293 ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
294 0, /* request */
295 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
296 value, index, NULL, 0, 500);
297 PDEBUG(D_USBO, "reg write: 0x%02x:0x%02x", index, value);
298 if (ret < 0)
133a9fe9 299 pr_err("reg write: error %d\n", ret);
35dc1b4c
JFM
300}
301
302static void write_vector(struct gspca_dev *gspca_dev,
303 const __u16 data[][2])
6a7eba24 304{
35dc1b4c 305 int i;
6a7eba24 306
35dc1b4c
JFM
307 i = 0;
308 while (data[i][1] != 0) {
c93396e1 309 reg_w_val(gspca_dev, data[i][1], data[i][0]);
6a7eba24
JFM
310 i++;
311 }
312}
35dc1b4c
JFM
313
314/* read 'len' bytes to gspca_dev->usb_buf */
315static void reg_r(struct gspca_dev *gspca_dev,
316 __u16 index, __u16 length)
317{
318 usb_control_msg(gspca_dev->dev,
319 usb_rcvctrlpipe(gspca_dev->dev, 0),
320 0, /* request */
321 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
322 0, /* value */
323 index, gspca_dev->usb_buf, length, 500);
324}
325
326/* write 'len' bytes from gspca_dev->usb_buf */
327static void reg_w_buf(struct gspca_dev *gspca_dev,
328 __u16 index, __u16 len)
329{
330 usb_control_msg(gspca_dev->dev,
331 usb_sndctrlpipe(gspca_dev->dev, 0),
332 0, /* request */
333 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
334 0, /* value */
335 index, gspca_dev->usb_buf, len, 500);
336}
337
338static void i2c_write(struct gspca_dev *gspca_dev, __u16 value, __u16 reg)
339{
340 int retry = 60;
341
c93396e1
TK
342 reg_w_val(gspca_dev, 0x8801, reg);
343 reg_w_val(gspca_dev, 0x8805, value);
344 reg_w_val(gspca_dev, 0x8800, value >> 8);
35dc1b4c
JFM
345 do {
346 reg_r(gspca_dev, 0x8803, 1);
347 if (!gspca_dev->usb_buf[0])
348 return;
0dbc2c16 349 msleep(10);
35dc1b4c
JFM
350 } while (--retry);
351}
352
353static int i2c_read(struct gspca_dev *gspca_dev, __u16 reg, __u8 mode)
354{
355 int retry = 60;
356 __u8 value;
357
c93396e1
TK
358 reg_w_val(gspca_dev, 0x8804, 0x92);
359 reg_w_val(gspca_dev, 0x8801, reg);
360 reg_w_val(gspca_dev, 0x8802, mode | 0x01);
35dc1b4c
JFM
361 do {
362 reg_r(gspca_dev, 0x8803, 1);
363 if (!gspca_dev->usb_buf[0]) {
364 reg_r(gspca_dev, 0x8800, 1);
365 value = gspca_dev->usb_buf[0];
366 reg_r(gspca_dev, 0x8805, 1);
367 return ((int) value << 8) | gspca_dev->usb_buf[0];
368 }
0dbc2c16 369 msleep(10);
35dc1b4c
JFM
370 } while (--retry);
371 return -1;
372}
373
374static void sensor_mapwrite(struct gspca_dev *gspca_dev,
375 const __u16 (*sensormap)[2])
376{
377 while ((*sensormap)[0]) {
378 gspca_dev->usb_buf[0] = (*sensormap)[1];
379 gspca_dev->usb_buf[1] = (*sensormap)[1] >> 8;
380 reg_w_buf(gspca_dev, (*sensormap)[0], 2);
381 sensormap++;
382 }
383}
384
f8a04a6f
JFM
385static void write_sensor_72a(struct gspca_dev *gspca_dev,
386 const __u16 (*sensor)[2])
387{
388 while ((*sensor)[0]) {
389 i2c_write(gspca_dev, (*sensor)[1], (*sensor)[0]);
390 sensor++;
391 }
392}
393
6a7eba24
JFM
394static void init_161rev12A(struct gspca_dev *gspca_dev)
395{
6a7eba24
JFM
396 write_vector(gspca_dev, spca561_161rev12A_data1);
397 sensor_mapwrite(gspca_dev, Pb100_1map8300);
7879d459 398/*fixme: should be in sd_start*/
6a7eba24
JFM
399 write_vector(gspca_dev, spca561_161rev12A_data2);
400 sensor_mapwrite(gspca_dev, Pb100_2map8300);
401}
402
403/* this function is called at probe time */
404static int sd_config(struct gspca_dev *gspca_dev,
405 const struct usb_device_id *id)
406{
407 struct sd *sd = (struct sd *) gspca_dev;
6a7eba24
JFM
408 struct cam *cam;
409 __u16 vendor, product;
410 __u8 data1, data2;
411
412 /* Read frm global register the USB product and vendor IDs, just to
413 * prove that we can communicate with the device. This works, which
414 * confirms at we are communicating properly and that the device
415 * is a 561. */
739570bb
JFM
416 reg_r(gspca_dev, 0x8104, 1);
417 data1 = gspca_dev->usb_buf[0];
418 reg_r(gspca_dev, 0x8105, 1);
419 data2 = gspca_dev->usb_buf[0];
6a7eba24 420 vendor = (data2 << 8) | data1;
739570bb
JFM
421 reg_r(gspca_dev, 0x8106, 1);
422 data1 = gspca_dev->usb_buf[0];
423 reg_r(gspca_dev, 0x8107, 1);
424 data2 = gspca_dev->usb_buf[0];
6a7eba24
JFM
425 product = (data2 << 8) | data1;
426 if (vendor != id->idVendor || product != id->idProduct) {
427 PDEBUG(D_PROBE, "Bad vendor / product from device");
428 return -EINVAL;
429 }
9d64fdb1 430
6a7eba24 431 cam = &gspca_dev->cam;
eb3fb7c9 432 cam->needs_full_bandwidth = 1;
9d64fdb1
JFM
433
434 sd->chip_revision = id->driver_info;
b77c0046
JFM
435 if (sd->chip_revision == Rev012A) {
436 cam->cam_mode = sif_012a_mode;
437 cam->nmodes = ARRAY_SIZE(sif_012a_mode);
438 } else {
439 cam->cam_mode = sif_072a_mode;
440 cam->nmodes = ARRAY_SIZE(sif_072a_mode);
441 }
d698dc6b 442 sd->expo12a = EXPO12A_DEF;
6a7eba24
JFM
443 return 0;
444}
445
012d6b02
JFM
446/* this function is called at probe and resume time */
447static int sd_init_12a(struct gspca_dev *gspca_dev)
6a7eba24 448{
7879d459
JFM
449 PDEBUG(D_STREAM, "Chip revision: 012a");
450 init_161rev12A(gspca_dev);
451 return 0;
452}
012d6b02 453static int sd_init_72a(struct gspca_dev *gspca_dev)
7879d459
JFM
454{
455 PDEBUG(D_STREAM, "Chip revision: 072a");
0dbc2c16
JFM
456 write_vector(gspca_dev, rev72a_reset);
457 msleep(200);
f8a04a6f
JFM
458 write_vector(gspca_dev, rev72a_init_data1);
459 write_sensor_72a(gspca_dev, rev72a_init_sensor1);
460 write_vector(gspca_dev, rev72a_init_data2);
461 write_sensor_72a(gspca_dev, rev72a_init_sensor2);
c93396e1 462 reg_w_val(gspca_dev, 0x8112, 0x30);
6a7eba24
JFM
463 return 0;
464}
465
3fa24bf5 466static void setbrightness(struct gspca_dev *gspca_dev, s32 val)
6a7eba24 467{
a8931d59 468 struct sd *sd = (struct sd *) gspca_dev;
a8931d59 469 __u16 reg;
5b7ed28e 470
a8931d59
HG
471 if (sd->chip_revision == Rev012A)
472 reg = 0x8610;
473 else
474 reg = 0x8611;
475
c93396e1
TK
476 reg_w_val(gspca_dev, reg + 0, val); /* R */
477 reg_w_val(gspca_dev, reg + 1, val); /* Gr */
478 reg_w_val(gspca_dev, reg + 2, val); /* B */
479 reg_w_val(gspca_dev, reg + 3, val); /* Gb */
6a7eba24
JFM
480}
481
3fa24bf5 482static void setwhite(struct gspca_dev *gspca_dev, s32 white, s32 contrast)
6c9d3c59
JFM
483{
484 struct sd *sd = (struct sd *) gspca_dev;
5b7ed28e
JFM
485 __u8 blue, red;
486 __u16 reg;
6c9d3c59 487
7879d459 488 /* try to emulate MS-win as possible */
5b7ed28e
JFM
489 red = 0x20 + white * 3 / 8;
490 blue = 0x90 - white * 5 / 8;
491 if (sd->chip_revision == Rev012A) {
492 reg = 0x8614;
493 } else {
494 reg = 0x8651;
3fa24bf5
HV
495 red += contrast - 0x20;
496 blue += contrast - 0x20;
c93396e1
TK
497 reg_w_val(gspca_dev, 0x8652, contrast + 0x20); /* Gr */
498 reg_w_val(gspca_dev, 0x8654, contrast + 0x20); /* Gb */
5b7ed28e 499 }
c93396e1
TK
500 reg_w_val(gspca_dev, reg, red);
501 reg_w_val(gspca_dev, reg + 2, blue);
7879d459
JFM
502}
503
504/* rev 12a only */
3fa24bf5 505static void setexposure(struct gspca_dev *gspca_dev, s32 val)
7879d459 506{
d0848eb2 507 int i, expo = 0;
7879d459 508
0fc23d20
HG
509 /* Register 0x8309 controls exposure for the spca561,
510 the basic exposure setting goes from 1-2047, where 1 is completely
511 dark and 2047 is very bright. It not only influences exposure but
512 also the framerate (to allow for longer exposure) from 1 - 300 it
513 only raises the exposure time then from 300 - 600 it halves the
514 framerate to be able to further raise the exposure time and for every
515 300 more it halves the framerate again. This allows for a maximum
516 exposure time of circa 0.2 - 0.25 seconds (30 / (2000/3000) fps).
517 Sometimes this is not enough, the 1-2047 uses bits 0-10, bits 11-12
518 configure a divider for the base framerate which us used at the
519 exposure setting of 1-300. These bits configure the base framerate
520 according to the following formula: fps = 60 / (value + 2) */
d0848eb2
HG
521
522 /* We choose to use the high bits setting the fixed framerate divisor
523 asap, as setting high basic exposure setting without the fixed
524 divider in combination with high gains makes the cam stop */
525 int table[] = { 0, 450, 550, 625, EXPOSURE_MAX };
526
527 for (i = 0; i < ARRAY_SIZE(table) - 1; i++) {
3fa24bf5
HV
528 if (val <= table[i + 1]) {
529 expo = val - table[i];
d0848eb2
HG
530 if (i)
531 expo += 300;
532 expo |= i << 11;
533 break;
534 }
0fc23d20 535 }
d0848eb2 536
35dc1b4c
JFM
537 gspca_dev->usb_buf[0] = expo;
538 gspca_dev->usb_buf[1] = expo >> 8;
539 reg_w_buf(gspca_dev, 0x8309, 2);
7879d459
JFM
540}
541
542/* rev 12a only */
3fa24bf5 543static void setgain(struct gspca_dev *gspca_dev, s32 val)
7879d459 544{
d0848eb2
HG
545 /* gain reg low 6 bits 0-63 gain, bit 6 and 7, both double the
546 sensitivity when set, so 31 + one of them set == 63, and 15
547 with both of them set == 63 */
3fa24bf5
HV
548 if (val < 64)
549 gspca_dev->usb_buf[0] = val;
550 else if (val < 128)
551 gspca_dev->usb_buf[0] = (val / 2) | 0x40;
d0848eb2 552 else
3fa24bf5 553 gspca_dev->usb_buf[0] = (val / 4) | 0xc0;
d0848eb2 554
35dc1b4c
JFM
555 gspca_dev->usb_buf[1] = 0;
556 reg_w_buf(gspca_dev, 0x8335, 2);
6c9d3c59
JFM
557}
558
3fa24bf5 559static void setautogain(struct gspca_dev *gspca_dev, s32 val)
cebf3b67
JFM
560{
561 struct sd *sd = (struct sd *) gspca_dev;
562
3fa24bf5 563 if (val)
d698dc6b
JFM
564 sd->ag_cnt = AG_CNT_START;
565 else
566 sd->ag_cnt = -1;
cebf3b67
JFM
567}
568
72ab97ce 569static int sd_start_12a(struct gspca_dev *gspca_dev)
6a7eba24 570{
6a7eba24 571 int mode;
5b7ed28e
JFM
572 static const __u8 Reg8391[8] =
573 {0x92, 0x30, 0x20, 0x00, 0x0c, 0x00, 0x00, 0x00};
6a7eba24 574
c2446b3e 575 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
7879d459
JFM
576 if (mode <= 1) {
577 /* Use compression on 320x240 and above */
c93396e1 578 reg_w_val(gspca_dev, 0x8500, 0x10 | mode);
7879d459
JFM
579 } else {
580 /* I couldn't get the compression to work below 320x240
581 * Fortunately at these resolutions the bandwidth
582 * is sufficient to push raw frames at ~20fps */
c93396e1 583 reg_w_val(gspca_dev, 0x8500, mode);
7879d459 584 } /* -- qq@kuku.eu.org */
35dc1b4c 585
5b7ed28e
JFM
586 gspca_dev->usb_buf[0] = 0xaa;
587 gspca_dev->usb_buf[1] = 0x00;
588 reg_w_buf(gspca_dev, 0x8307, 2);
589 /* clock - lower 0x8X values lead to fps > 30 */
c93396e1 590 reg_w_val(gspca_dev, 0x8700, 0x8a);
7879d459 591 /* 0x8f 0x85 0x27 clock */
c93396e1
TK
592 reg_w_val(gspca_dev, 0x8112, 0x1e | 0x20);
593 reg_w_val(gspca_dev, 0x850b, 0x03);
5b7ed28e
JFM
594 memcpy(gspca_dev->usb_buf, Reg8391, 8);
595 reg_w_buf(gspca_dev, 0x8391, 8);
596 reg_w_buf(gspca_dev, 0x8390, 8);
6b33e5e7
HG
597
598 /* Led ON (bit 3 -> 0 */
c93396e1 599 reg_w_val(gspca_dev, 0x8114, 0x00);
72ab97ce 600 return 0;
7879d459 601}
72ab97ce 602static int sd_start_72a(struct gspca_dev *gspca_dev)
7879d459 603{
3fa24bf5 604 struct sd *sd = (struct sd *) gspca_dev;
7879d459
JFM
605 int Clck;
606 int mode;
607
0dbc2c16
JFM
608 write_vector(gspca_dev, rev72a_reset);
609 msleep(200);
610 write_vector(gspca_dev, rev72a_init_data1);
611 write_sensor_72a(gspca_dev, rev72a_init_sensor1);
612
7879d459
JFM
613 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
614 switch (mode) {
615 default:
a48196a2
JFM
616 case 0:
617 Clck = 0x27; /* ms-win 0x87 */
618 break;
619 case 1:
7879d459
JFM
620 Clck = 0x25;
621 break;
622 case 2:
623 Clck = 0x22;
624 break;
625 case 3:
626 Clck = 0x21;
6a7eba24
JFM
627 break;
628 }
c93396e1
TK
629 reg_w_val(gspca_dev, 0x8700, Clck); /* 0x27 clock */
630 reg_w_val(gspca_dev, 0x8702, 0x81);
631 reg_w_val(gspca_dev, 0x8500, mode); /* mode */
0dbc2c16 632 write_sensor_72a(gspca_dev, rev72a_init_sensor2);
3fa24bf5
HV
633 setwhite(gspca_dev, v4l2_ctrl_g_ctrl(sd->hue),
634 v4l2_ctrl_g_ctrl(sd->contrast));
5b7ed28e 635/* setbrightness(gspca_dev); * fixme: bad values */
3fa24bf5 636 setautogain(gspca_dev, v4l2_ctrl_g_ctrl(sd->autogain));
c93396e1 637 reg_w_val(gspca_dev, 0x8112, 0x10 | 0x20);
72ab97ce 638 return 0;
6a7eba24
JFM
639}
640
641static void sd_stopN(struct gspca_dev *gspca_dev)
642{
d698dc6b
JFM
643 struct sd *sd = (struct sd *) gspca_dev;
644
645 if (sd->chip_revision == Rev012A) {
c93396e1 646 reg_w_val(gspca_dev, 0x8112, 0x0e);
6b33e5e7 647 /* Led Off (bit 3 -> 1 */
c93396e1 648 reg_w_val(gspca_dev, 0x8114, 0x08);
d698dc6b 649 } else {
c93396e1
TK
650 reg_w_val(gspca_dev, 0x8112, 0x20);
651/* reg_w_val(gspca_dev, 0x8102, 0x00); ?? */
d698dc6b 652 }
6a7eba24
JFM
653}
654
cebf3b67 655static void do_autogain(struct gspca_dev *gspca_dev)
6a7eba24
JFM
656{
657 struct sd *sd = (struct sd *) gspca_dev;
cebf3b67
JFM
658 int expotimes;
659 int pixelclk;
660 int gainG;
6a7eba24
JFM
661 __u8 R, Gr, Gb, B;
662 int y;
663 __u8 luma_mean = 110;
664 __u8 luma_delta = 20;
665 __u8 spring = 4;
666
cebf3b67
JFM
667 if (sd->ag_cnt < 0)
668 return;
669 if (--sd->ag_cnt >= 0)
670 return;
671 sd->ag_cnt = AG_CNT_START;
672
6a7eba24
JFM
673 switch (sd->chip_revision) {
674 case Rev072A:
739570bb
JFM
675 reg_r(gspca_dev, 0x8621, 1);
676 Gr = gspca_dev->usb_buf[0];
677 reg_r(gspca_dev, 0x8622, 1);
678 R = gspca_dev->usb_buf[0];
679 reg_r(gspca_dev, 0x8623, 1);
680 B = gspca_dev->usb_buf[0];
681 reg_r(gspca_dev, 0x8624, 1);
682 Gb = gspca_dev->usb_buf[0];
6a7eba24
JFM
683 y = (77 * R + 75 * (Gr + Gb) + 29 * B) >> 8;
684 /* u= (128*B-(43*(Gr+Gb+R))) >> 8; */
685 /* v= (128*R-(53*(Gr+Gb))-21*B) >> 8; */
686 /* PDEBUG(D_CONF,"reading Y %d U %d V %d ",y,u,v); */
687
688 if (y < luma_mean - luma_delta ||
689 y > luma_mean + luma_delta) {
690 expotimes = i2c_read(gspca_dev, 0x09, 0x10);
691 pixelclk = 0x0800;
692 expotimes = expotimes & 0x07ff;
693 /* PDEBUG(D_PACK,
694 "Exposition Times 0x%03X Clock 0x%04X ",
695 expotimes,pixelclk); */
696 gainG = i2c_read(gspca_dev, 0x35, 0x10);
697 /* PDEBUG(D_PACK,
698 "reading Gain register %d", gainG); */
699
700 expotimes += (luma_mean - y) >> spring;
701 gainG += (luma_mean - y) / 50;
702 /* PDEBUG(D_PACK,
703 "compute expotimes %d gain %d",
704 expotimes,gainG); */
705
706 if (gainG > 0x3f)
707 gainG = 0x3f;
35dc1b4c 708 else if (gainG < 3)
6a7eba24
JFM
709 gainG = 3;
710 i2c_write(gspca_dev, gainG, 0x35);
711
35dc1b4c 712 if (expotimes > 0x0256)
6a7eba24 713 expotimes = 0x0256;
35dc1b4c 714 else if (expotimes < 3)
6a7eba24
JFM
715 expotimes = 3;
716 i2c_write(gspca_dev, expotimes | pixelclk, 0x09);
717 }
718 break;
6a7eba24
JFM
719 }
720}
721
722static void sd_pkt_scan(struct gspca_dev *gspca_dev,
76dd272b 723 u8 *data, /* isoc packet */
6a7eba24
JFM
724 int len) /* iso packet length */
725{
0fc23d20
HG
726 struct sd *sd = (struct sd *) gspca_dev;
727
576ed7b5
JFM
728 len--;
729 switch (*data++) { /* sequence number */
35dc1b4c 730 case 0: /* start of frame */
76dd272b 731 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
436c2c53
HG
732
733 /* This should never happen */
734 if (len < 2) {
c93396e1 735 PERR("Short SOF packet, ignoring");
436c2c53
HG
736 gspca_dev->last_packet_type = DISCARD_PACKET;
737 return;
738 }
739
60d21563 740#if IS_ENABLED(CONFIG_INPUT)
436c2c53
HG
741 if (data[0] & 0x20) {
742 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
743 input_sync(gspca_dev->input_dev);
744 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
745 input_sync(gspca_dev->input_dev);
746 }
747#endif
748
6a7eba24
JFM
749 if (data[1] & 0x10) {
750 /* compressed bayer */
76dd272b 751 gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
6a7eba24 752 } else {
54ab92ca 753 /* raw bayer (with a header, which we skip) */
0fc23d20
HG
754 if (sd->chip_revision == Rev012A) {
755 data += 20;
756 len -= 20;
757 } else {
758 data += 16;
759 len -= 16;
760 }
76dd272b 761 gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
6a7eba24
JFM
762 }
763 return;
35dc1b4c 764 case 0xff: /* drop (empty mpackets) */
6a7eba24
JFM
765 return;
766 }
76dd272b 767 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
6a7eba24
JFM
768}
769
3fa24bf5 770static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
6a7eba24 771{
3fa24bf5
HV
772 struct gspca_dev *gspca_dev =
773 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
774 struct sd *sd = (struct sd *)gspca_dev;
6a7eba24 775
3fa24bf5 776 gspca_dev->usb_err = 0;
6a7eba24 777
3fa24bf5
HV
778 if (!gspca_dev->streaming)
779 return 0;
6a7eba24 780
3fa24bf5
HV
781 switch (ctrl->id) {
782 case V4L2_CID_BRIGHTNESS:
783 setbrightness(gspca_dev, ctrl->val);
784 break;
785 case V4L2_CID_CONTRAST:
786 /* hue/contrast control cluster for 72a */
787 setwhite(gspca_dev, sd->hue->val, ctrl->val);
788 break;
789 case V4L2_CID_HUE:
790 /* just plain hue control for 12a */
791 setwhite(gspca_dev, ctrl->val, 0);
792 break;
793 case V4L2_CID_EXPOSURE:
794 setexposure(gspca_dev, ctrl->val);
795 break;
796 case V4L2_CID_GAIN:
797 setgain(gspca_dev, ctrl->val);
798 break;
799 case V4L2_CID_AUTOGAIN:
800 setautogain(gspca_dev, ctrl->val);
801 break;
802 }
803 return gspca_dev->usb_err;
6c9d3c59
JFM
804}
805
3fa24bf5
HV
806static const struct v4l2_ctrl_ops sd_ctrl_ops = {
807 .s_ctrl = sd_s_ctrl,
808};
6c9d3c59 809
3fa24bf5 810static int sd_init_controls_12a(struct gspca_dev *gspca_dev)
7879d459 811{
3fa24bf5 812 struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
7879d459 813
3fa24bf5
HV
814 gspca_dev->vdev.ctrl_handler = hdl;
815 v4l2_ctrl_handler_init(hdl, 3);
816 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
817 V4L2_CID_HUE, 1, 0x7f, 1, 0x40);
a8931d59
HG
818 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
819 V4L2_CID_BRIGHTNESS, -128, 127, 1, 0);
3fa24bf5
HV
820 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
821 V4L2_CID_EXPOSURE, 1, EXPOSURE_MAX, 1, 700);
822 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
823 V4L2_CID_GAIN, 0, 255, 1, 63);
7879d459 824
3fa24bf5
HV
825 if (hdl->error) {
826 pr_err("Could not initialize controls\n");
827 return hdl->error;
828 }
7879d459
JFM
829 return 0;
830}
831
3fa24bf5 832static int sd_init_controls_72a(struct gspca_dev *gspca_dev)
7879d459 833{
3fa24bf5
HV
834 struct sd *sd = (struct sd *)gspca_dev;
835 struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
7879d459 836
3fa24bf5
HV
837 gspca_dev->vdev.ctrl_handler = hdl;
838 v4l2_ctrl_handler_init(hdl, 4);
839 sd->contrast = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
840 V4L2_CID_CONTRAST, 0, 0x3f, 1, 0x20);
841 sd->hue = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
842 V4L2_CID_HUE, 1, 0x7f, 1, 0x40);
843 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
844 V4L2_CID_BRIGHTNESS, 0, 0x3f, 1, 0x20);
845 sd->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
846 V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
7879d459 847
3fa24bf5
HV
848 if (hdl->error) {
849 pr_err("Could not initialize controls\n");
850 return hdl->error;
851 }
852 v4l2_ctrl_cluster(2, &sd->contrast);
7879d459
JFM
853 return 0;
854}
855
6a7eba24 856/* sub-driver description */
7879d459 857static const struct sd_desc sd_desc_12a = {
6a7eba24 858 .name = MODULE_NAME,
3fa24bf5 859 .init_controls = sd_init_controls_12a,
6a7eba24 860 .config = sd_config,
012d6b02 861 .init = sd_init_12a,
7879d459
JFM
862 .start = sd_start_12a,
863 .stopN = sd_stopN,
7879d459 864 .pkt_scan = sd_pkt_scan,
60d21563 865#if IS_ENABLED(CONFIG_INPUT)
436c2c53
HG
866 .other_input = 1,
867#endif
7879d459
JFM
868};
869static const struct sd_desc sd_desc_72a = {
870 .name = MODULE_NAME,
3fa24bf5 871 .init_controls = sd_init_controls_72a,
7879d459 872 .config = sd_config,
012d6b02 873 .init = sd_init_72a,
7879d459 874 .start = sd_start_72a,
6a7eba24 875 .stopN = sd_stopN,
6a7eba24 876 .pkt_scan = sd_pkt_scan,
cebf3b67 877 .dq_callback = do_autogain,
60d21563 878#if IS_ENABLED(CONFIG_INPUT)
436c2c53
HG
879 .other_input = 1,
880#endif
6a7eba24 881};
7879d459
JFM
882static const struct sd_desc *sd_desc[2] = {
883 &sd_desc_12a,
884 &sd_desc_72a
885};
6a7eba24
JFM
886
887/* -- module initialisation -- */
95c967c1 888static const struct usb_device_id device_table[] = {
87581aa5
JFM
889 {USB_DEVICE(0x041e, 0x401a), .driver_info = Rev072A},
890 {USB_DEVICE(0x041e, 0x403b), .driver_info = Rev012A},
891 {USB_DEVICE(0x0458, 0x7004), .driver_info = Rev072A},
f8f73d01 892 {USB_DEVICE(0x0461, 0x0815), .driver_info = Rev072A},
87581aa5
JFM
893 {USB_DEVICE(0x046d, 0x0928), .driver_info = Rev012A},
894 {USB_DEVICE(0x046d, 0x0929), .driver_info = Rev012A},
895 {USB_DEVICE(0x046d, 0x092a), .driver_info = Rev012A},
896 {USB_DEVICE(0x046d, 0x092b), .driver_info = Rev012A},
897 {USB_DEVICE(0x046d, 0x092c), .driver_info = Rev012A},
898 {USB_DEVICE(0x046d, 0x092d), .driver_info = Rev012A},
899 {USB_DEVICE(0x046d, 0x092e), .driver_info = Rev012A},
900 {USB_DEVICE(0x046d, 0x092f), .driver_info = Rev012A},
901 {USB_DEVICE(0x04fc, 0x0561), .driver_info = Rev072A},
902 {USB_DEVICE(0x060b, 0xa001), .driver_info = Rev072A},
903 {USB_DEVICE(0x10fd, 0x7e50), .driver_info = Rev072A},
904 {USB_DEVICE(0xabcd, 0xcdee), .driver_info = Rev072A},
6a7eba24
JFM
905 {}
906};
907
908MODULE_DEVICE_TABLE(usb, device_table);
909
910/* -- device connect -- */
911static int sd_probe(struct usb_interface *intf,
912 const struct usb_device_id *id)
913{
7879d459
JFM
914 return gspca_dev_probe(intf, id,
915 sd_desc[id->driver_info],
916 sizeof(struct sd),
6a7eba24
JFM
917 THIS_MODULE);
918}
919
920static struct usb_driver sd_driver = {
921 .name = MODULE_NAME,
922 .id_table = device_table,
923 .probe = sd_probe,
924 .disconnect = gspca_disconnect,
6a709749
JFM
925#ifdef CONFIG_PM
926 .suspend = gspca_suspend,
927 .resume = gspca_resume,
8bb58964 928 .reset_resume = gspca_resume,
6a709749 929#endif
6a7eba24
JFM
930};
931
ecb3b2b3 932module_usb_driver(sd_driver);