WIP FPC-III support
[linux/fpc-iii.git] / drivers / media / usb / gspca / pac7302.c
blob2e8c3ef51ca3623ba8e108d4b5eb3b11f1ea758d
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Pixart PAC7302 driver
5 * Copyright (C) 2008-2012 Jean-Francois Moine <http://moinejf.free.fr>
6 * Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li
8 * Separated from Pixart PAC7311 library by Márton Németh
9 * Camera button input handling by Márton Németh <nm127@freemail.hu>
10 * Copyright (C) 2009-2010 Márton Németh <nm127@freemail.hu>
14 * Some documentation about various registers as determined by trial and error.
16 * Register page 0:
18 * Address Description
19 * 0x01 Red balance control
20 * 0x02 Green balance control
21 * 0x03 Blue balance control
22 * The Windows driver uses a quadratic approach to map
23 * the settable values (0-200) on register values:
24 * min=0x20, default=0x40, max=0x80
25 * 0x0f-0x20 Color and saturation control
26 * 0xa2-0xab Brightness, contrast and gamma control
27 * 0xb6 Sharpness control (bits 0-4)
29 * Register page 1:
31 * Address Description
32 * 0x78 Global control, bit 6 controls the LED (inverted)
33 * 0x80 Compression balance, 2 interesting settings:
34 * 0x0f Default
35 * 0x50 Values >= this switch the camera to a lower compression,
36 * using the same table for both luminance and chrominance.
37 * This gives a sharper picture. Only usable when running
38 * at < 15 fps! Note currently the driver does not use this
39 * as the quality gain is small and the generated JPG-s are
40 * only understood by v4l-utils >= 0.8.9
42 * Register page 3:
44 * Address Description
45 * 0x02 Clock divider 3-63, fps = 90 / val. Must be a multiple of 3 on
46 * the 7302, so one of 3, 6, 9, ..., except when between 6 and 12?
47 * 0x03 Variable framerate ctrl reg2==3: 0 -> ~30 fps, 255 -> ~22fps
48 * 0x04 Another var framerate ctrl reg2==3, reg3==0: 0 -> ~30 fps,
49 * 63 -> ~27 fps, the 2 msb's must always be 1 !!
50 * 0x05 Another var framerate ctrl reg2==3, reg3==0, reg4==0xc0:
51 * 1 -> ~30 fps, 2 -> ~20 fps
52 * 0x0e Exposure bits 0-7, 0-448, 0 = use full frame time
53 * 0x0f Exposure bit 8, 0-448, 448 = no exposure at all
54 * 0x10 Gain 0-31
55 * 0x12 Another gain 0-31, unlike 0x10 this one seems to start with an
56 * amplification value of 1 rather then 0 at its lowest setting
57 * 0x21 Bitfield: 0-1 unused, 2-3 vflip/hflip, 4-5 unknown, 6-7 unused
58 * 0x80 Another framerate control, best left at 1, moving it from 1 to
59 * 2 causes the framerate to become 3/4th of what it was, and
60 * also seems to cause pixel averaging, resulting in an effective
61 * resolution of 320x240 and thus a much blockier image
63 * The registers are accessed in the following functions:
65 * Page | Register | Function
66 * -----+------------+---------------------------------------------------
67 * 0 | 0x01 | setredbalance()
68 * 0 | 0x03 | setbluebalance()
69 * 0 | 0x0f..0x20 | setcolors()
70 * 0 | 0xa2..0xab | setbrightcont()
71 * 0 | 0xb6 | setsharpness()
72 * 0 | 0xc6 | setwhitebalance()
73 * 0 | 0xdc | setbrightcont(), setcolors()
74 * 3 | 0x02 | setexposure()
75 * 3 | 0x10, 0x12 | setgain()
76 * 3 | 0x11 | setcolors(), setgain(), setexposure(), sethvflip()
77 * 3 | 0x21 | sethvflip()
80 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
82 #include <linux/input.h>
83 #include "gspca.h"
84 /* Include pac common sof detection functions */
85 #include "pac_common.h"
87 #define PAC7302_RGB_BALANCE_MIN 0
88 #define PAC7302_RGB_BALANCE_MAX 200
89 #define PAC7302_RGB_BALANCE_DEFAULT 100
90 #define PAC7302_GAIN_DEFAULT 15
91 #define PAC7302_GAIN_KNEE 42
92 #define PAC7302_EXPOSURE_DEFAULT 66 /* 33 ms / 30 fps */
93 #define PAC7302_EXPOSURE_KNEE 133 /* 66 ms / 15 fps */
95 MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>, Thomas Kaiser thomas@kaiser-linux.li");
96 MODULE_DESCRIPTION("Pixart PAC7302");
97 MODULE_LICENSE("GPL");
99 struct sd {
100 struct gspca_dev gspca_dev; /* !! must be the first item */
102 struct { /* brightness / contrast cluster */
103 struct v4l2_ctrl *brightness;
104 struct v4l2_ctrl *contrast;
106 struct v4l2_ctrl *saturation;
107 struct v4l2_ctrl *white_balance;
108 struct v4l2_ctrl *red_balance;
109 struct v4l2_ctrl *blue_balance;
110 struct { /* flip cluster */
111 struct v4l2_ctrl *hflip;
112 struct v4l2_ctrl *vflip;
114 struct v4l2_ctrl *sharpness;
115 u8 flags;
116 #define FL_HFLIP 0x01 /* mirrored by default */
117 #define FL_VFLIP 0x02 /* vertical flipped by default */
119 u8 sof_read;
120 s8 autogain_ignore_frames;
122 atomic_t avg_lum;
125 static const struct v4l2_pix_format vga_mode[] = {
126 {640, 480, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
127 .bytesperline = 640,
128 .sizeimage = 640 * 480 * 3 / 8 + 590,
129 .colorspace = V4L2_COLORSPACE_JPEG,
133 #define LOAD_PAGE3 255
134 #define END_OF_SEQUENCE 0
136 static const u8 init_7302[] = {
137 /* index,value */
138 0xff, 0x01, /* page 1 */
139 0x78, 0x00, /* deactivate */
140 0xff, 0x01,
141 0x78, 0x40, /* led off */
143 static const u8 start_7302[] = {
144 /* index, len, [value]* */
145 0xff, 1, 0x00, /* page 0 */
146 0x00, 12, 0x01, 0x40, 0x40, 0x40, 0x01, 0xe0, 0x02, 0x80,
147 0x00, 0x00, 0x00, 0x00,
148 0x0d, 24, 0x03, 0x01, 0x00, 0xb5, 0x07, 0xcb, 0x00, 0x00,
149 0x07, 0xc8, 0x00, 0xea, 0x07, 0xcf, 0x07, 0xf7,
150 0x07, 0x7e, 0x01, 0x0b, 0x00, 0x00, 0x00, 0x11,
151 0x26, 2, 0xaa, 0xaa,
152 0x2e, 1, 0x31,
153 0x38, 1, 0x01,
154 0x3a, 3, 0x14, 0xff, 0x5a,
155 0x43, 11, 0x00, 0x0a, 0x18, 0x11, 0x01, 0x2c, 0x88, 0x11,
156 0x00, 0x54, 0x11,
157 0x55, 1, 0x00,
158 0x62, 4, 0x10, 0x1e, 0x1e, 0x18,
159 0x6b, 1, 0x00,
160 0x6e, 3, 0x08, 0x06, 0x00,
161 0x72, 3, 0x00, 0xff, 0x00,
162 0x7d, 23, 0x01, 0x01, 0x58, 0x46, 0x50, 0x3c, 0x50, 0x3c,
163 0x54, 0x46, 0x54, 0x56, 0x52, 0x50, 0x52, 0x50,
164 0x56, 0x64, 0xa4, 0x00, 0xda, 0x00, 0x00,
165 0xa2, 10, 0x22, 0x2c, 0x3c, 0x54, 0x69, 0x7c, 0x9c, 0xb9,
166 0xd2, 0xeb,
167 0xaf, 1, 0x02,
168 0xb5, 2, 0x08, 0x08,
169 0xb8, 2, 0x08, 0x88,
170 0xc4, 4, 0xae, 0x01, 0x04, 0x01,
171 0xcc, 1, 0x00,
172 0xd1, 11, 0x01, 0x30, 0x49, 0x5e, 0x6f, 0x7f, 0x8e, 0xa9,
173 0xc1, 0xd7, 0xec,
174 0xdc, 1, 0x01,
175 0xff, 1, 0x01, /* page 1 */
176 0x12, 3, 0x02, 0x00, 0x01,
177 0x3e, 2, 0x00, 0x00,
178 0x76, 5, 0x01, 0x20, 0x40, 0x00, 0xf2,
179 0x7c, 1, 0x00,
180 0x7f, 10, 0x4b, 0x0f, 0x01, 0x2c, 0x02, 0x58, 0x03, 0x20,
181 0x02, 0x00,
182 0x96, 5, 0x01, 0x10, 0x04, 0x01, 0x04,
183 0xc8, 14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
184 0x07, 0x00, 0x01, 0x07, 0x04, 0x01,
185 0xd8, 1, 0x01,
186 0xdb, 2, 0x00, 0x01,
187 0xde, 7, 0x00, 0x01, 0x04, 0x04, 0x00, 0x00, 0x00,
188 0xe6, 4, 0x00, 0x00, 0x00, 0x01,
189 0xeb, 1, 0x00,
190 0xff, 1, 0x02, /* page 2 */
191 0x22, 1, 0x00,
192 0xff, 1, 0x03, /* page 3 */
193 0, LOAD_PAGE3, /* load the page 3 */
194 0x11, 1, 0x01,
195 0xff, 1, 0x02, /* page 2 */
196 0x13, 1, 0x00,
197 0x22, 4, 0x1f, 0xa4, 0xf0, 0x96,
198 0x27, 2, 0x14, 0x0c,
199 0x2a, 5, 0xc8, 0x00, 0x18, 0x12, 0x22,
200 0x64, 8, 0x00, 0x00, 0xf0, 0x01, 0x14, 0x44, 0x44, 0x44,
201 0x6e, 1, 0x08,
202 0xff, 1, 0x01, /* page 1 */
203 0x78, 1, 0x00,
204 0, END_OF_SEQUENCE /* end of sequence */
207 #define SKIP 0xaa
208 /* page 3 - the value SKIP says skip the index - see reg_w_page() */
209 static const u8 page3_7302[] = {
210 0x90, 0x40, 0x03, 0x00, 0xc0, 0x01, 0x14, 0x16,
211 0x14, 0x12, 0x00, 0x00, 0x00, 0x02, 0x33, 0x00,
212 0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
213 0x00, 0x00, 0x00, 0x47, 0x01, 0xb3, 0x01, 0x00,
214 0x00, 0x08, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x21,
215 0x00, 0x00, 0x00, 0x54, 0xf4, 0x02, 0x52, 0x54,
216 0xa4, 0xb8, 0xe0, 0x2a, 0xf6, 0x00, 0x00, 0x00,
217 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
218 0x00, 0xfc, 0x00, 0xf2, 0x1f, 0x04, 0x00, 0x00,
219 SKIP, 0x00, 0x00, 0xc0, 0xc0, 0x10, 0x00, 0x00,
220 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
221 0x00, 0x40, 0xff, 0x03, 0x19, 0x00, 0x00, 0x00,
222 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
223 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xc8, 0xc8,
224 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
225 0x08, 0x10, 0x24, 0x40, 0x00, 0x00, 0x00, 0x00,
226 0x01, 0x00, 0x02, 0x47, 0x00, 0x00, 0x00, 0x00,
227 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
228 0x00, 0x02, 0xfa, 0x00, 0x64, 0x5a, 0x28, 0x00,
229 0x00
232 static void reg_w_buf(struct gspca_dev *gspca_dev,
233 u8 index,
234 const u8 *buffer, int len)
236 int ret;
238 if (gspca_dev->usb_err < 0)
239 return;
240 memcpy(gspca_dev->usb_buf, buffer, len);
241 ret = usb_control_msg(gspca_dev->dev,
242 usb_sndctrlpipe(gspca_dev->dev, 0),
243 0, /* request */
244 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
245 0, /* value */
246 index, gspca_dev->usb_buf, len,
247 500);
248 if (ret < 0) {
249 pr_err("reg_w_buf failed i: %02x error %d\n",
250 index, ret);
251 gspca_dev->usb_err = ret;
256 static void reg_w(struct gspca_dev *gspca_dev,
257 u8 index,
258 u8 value)
260 int ret;
262 if (gspca_dev->usb_err < 0)
263 return;
264 gspca_dev->usb_buf[0] = value;
265 ret = usb_control_msg(gspca_dev->dev,
266 usb_sndctrlpipe(gspca_dev->dev, 0),
267 0, /* request */
268 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
269 0, index, gspca_dev->usb_buf, 1,
270 500);
271 if (ret < 0) {
272 pr_err("reg_w() failed i: %02x v: %02x error %d\n",
273 index, value, ret);
274 gspca_dev->usb_err = ret;
278 static void reg_w_seq(struct gspca_dev *gspca_dev,
279 const u8 *seq, int len)
281 while (--len >= 0) {
282 reg_w(gspca_dev, seq[0], seq[1]);
283 seq += 2;
287 /* load the beginning of a page */
288 static void reg_w_page(struct gspca_dev *gspca_dev,
289 const u8 *page, int len)
291 int index;
292 int ret = 0;
294 if (gspca_dev->usb_err < 0)
295 return;
296 for (index = 0; index < len; index++) {
297 if (page[index] == SKIP) /* skip this index */
298 continue;
299 gspca_dev->usb_buf[0] = page[index];
300 ret = usb_control_msg(gspca_dev->dev,
301 usb_sndctrlpipe(gspca_dev->dev, 0),
302 0, /* request */
303 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
304 0, index, gspca_dev->usb_buf, 1,
305 500);
306 if (ret < 0) {
307 pr_err("reg_w_page() failed i: %02x v: %02x error %d\n",
308 index, page[index], ret);
309 gspca_dev->usb_err = ret;
310 break;
315 /* output a variable sequence */
316 static void reg_w_var(struct gspca_dev *gspca_dev,
317 const u8 *seq,
318 const u8 *page3, unsigned int page3_len)
320 int index, len;
322 for (;;) {
323 index = *seq++;
324 len = *seq++;
325 switch (len) {
326 case END_OF_SEQUENCE:
327 return;
328 case LOAD_PAGE3:
329 reg_w_page(gspca_dev, page3, page3_len);
330 break;
331 default:
332 if (len > USB_BUF_SZ) {
333 gspca_err(gspca_dev, "Incorrect variable sequence\n");
334 return;
336 while (len > 0) {
337 if (len < 8) {
338 reg_w_buf(gspca_dev,
339 index, seq, len);
340 seq += len;
341 break;
343 reg_w_buf(gspca_dev, index, seq, 8);
344 seq += 8;
345 index += 8;
346 len -= 8;
350 /* not reached */
353 /* this function is called at probe time for pac7302 */
354 static int sd_config(struct gspca_dev *gspca_dev,
355 const struct usb_device_id *id)
357 struct sd *sd = (struct sd *) gspca_dev;
358 struct cam *cam;
360 cam = &gspca_dev->cam;
362 cam->cam_mode = vga_mode; /* only 640x480 */
363 cam->nmodes = ARRAY_SIZE(vga_mode);
365 sd->flags = id->driver_info;
366 return 0;
369 static void setbrightcont(struct gspca_dev *gspca_dev)
371 struct sd *sd = (struct sd *) gspca_dev;
372 int i, v;
373 static const u8 max[10] =
374 {0x29, 0x33, 0x42, 0x5a, 0x6e, 0x80, 0x9f, 0xbb,
375 0xd4, 0xec};
376 static const u8 delta[10] =
377 {0x35, 0x33, 0x33, 0x2f, 0x2a, 0x25, 0x1e, 0x17,
378 0x11, 0x0b};
380 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
381 for (i = 0; i < 10; i++) {
382 v = max[i];
383 v += (sd->brightness->val - (s32)sd->brightness->maximum)
384 * 150 / (s32)sd->brightness->maximum; /* 200 ? */
385 v -= delta[i] * sd->contrast->val / (s32)sd->contrast->maximum;
386 if (v < 0)
387 v = 0;
388 else if (v > 0xff)
389 v = 0xff;
390 reg_w(gspca_dev, 0xa2 + i, v);
392 reg_w(gspca_dev, 0xdc, 0x01);
395 static void setcolors(struct gspca_dev *gspca_dev)
397 struct sd *sd = (struct sd *) gspca_dev;
398 int i, v;
399 static const int a[9] =
400 {217, -212, 0, -101, 170, -67, -38, -315, 355};
401 static const int b[9] =
402 {19, 106, 0, 19, 106, 1, 19, 106, 1};
404 reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
405 reg_w(gspca_dev, 0x11, 0x01);
406 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
407 for (i = 0; i < 9; i++) {
408 v = a[i] * sd->saturation->val / (s32)sd->saturation->maximum;
409 v += b[i];
410 reg_w(gspca_dev, 0x0f + 2 * i, (v >> 8) & 0x07);
411 reg_w(gspca_dev, 0x0f + 2 * i + 1, v);
413 reg_w(gspca_dev, 0xdc, 0x01);
416 static void setwhitebalance(struct gspca_dev *gspca_dev)
418 struct sd *sd = (struct sd *) gspca_dev;
420 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
421 reg_w(gspca_dev, 0xc6, sd->white_balance->val);
423 reg_w(gspca_dev, 0xdc, 0x01);
426 static u8 rgbbalance_ctrl_to_reg_value(s32 rgb_ctrl_val)
428 const unsigned int k = 1000; /* precision factor */
429 unsigned int norm;
431 /* Normed value [0...k] */
432 norm = k * (rgb_ctrl_val - PAC7302_RGB_BALANCE_MIN)
433 / (PAC7302_RGB_BALANCE_MAX - PAC7302_RGB_BALANCE_MIN);
434 /* Qudratic apporach improves control at small (register) values: */
435 return 64 * norm * norm / (k*k) + 32 * norm / k + 32;
436 /* Y = 64*X*X + 32*X + 32
437 * => register values 0x20-0x80; Windows driver uses these limits */
439 /* NOTE: for full value range (0x00-0xff) use
440 * Y = 254*X*X + X
441 * => 254 * norm * norm / (k*k) + 1 * norm / k */
444 static void setredbalance(struct gspca_dev *gspca_dev)
446 struct sd *sd = (struct sd *) gspca_dev;
448 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
449 reg_w(gspca_dev, 0x01,
450 rgbbalance_ctrl_to_reg_value(sd->red_balance->val));
452 reg_w(gspca_dev, 0xdc, 0x01);
455 static void setbluebalance(struct gspca_dev *gspca_dev)
457 struct sd *sd = (struct sd *) gspca_dev;
459 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
460 reg_w(gspca_dev, 0x03,
461 rgbbalance_ctrl_to_reg_value(sd->blue_balance->val));
463 reg_w(gspca_dev, 0xdc, 0x01);
466 static void setgain(struct gspca_dev *gspca_dev)
468 u8 reg10, reg12;
470 if (gspca_dev->gain->val < 32) {
471 reg10 = gspca_dev->gain->val;
472 reg12 = 0;
473 } else {
474 reg10 = 31;
475 reg12 = gspca_dev->gain->val - 31;
478 reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
479 reg_w(gspca_dev, 0x10, reg10);
480 reg_w(gspca_dev, 0x12, reg12);
482 /* load registers to sensor (Bit 0, auto clear) */
483 reg_w(gspca_dev, 0x11, 0x01);
486 static void setexposure(struct gspca_dev *gspca_dev)
488 u8 clockdiv;
489 u16 exposure;
492 * Register 2 of frame 3 contains the clock divider configuring the
493 * no fps according to the formula: 90 / reg. sd->exposure is the
494 * desired exposure time in 0.5 ms.
496 clockdiv = (90 * gspca_dev->exposure->val + 1999) / 2000;
499 * Note clockdiv = 3 also works, but when running at 30 fps, depending
500 * on the scene being recorded, the camera switches to another
501 * quantization table for certain JPEG blocks, and we don't know how
502 * to decompress these blocks. So we cap the framerate at 15 fps.
504 if (clockdiv < 6)
505 clockdiv = 6;
506 else if (clockdiv > 63)
507 clockdiv = 63;
510 * Register 2 MUST be a multiple of 3, except when between 6 and 12?
511 * Always round up, otherwise we cannot get the desired frametime
512 * using the partial frame time exposure control.
514 if (clockdiv < 6 || clockdiv > 12)
515 clockdiv = ((clockdiv + 2) / 3) * 3;
518 * frame exposure time in ms = 1000 * clockdiv / 90 ->
519 * exposure = (sd->exposure / 2) * 448 / (1000 * clockdiv / 90)
521 exposure = (gspca_dev->exposure->val * 45 * 448) / (1000 * clockdiv);
522 /* 0 = use full frametime, 448 = no exposure, reverse it */
523 exposure = 448 - exposure;
525 reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
526 reg_w(gspca_dev, 0x02, clockdiv);
527 reg_w(gspca_dev, 0x0e, exposure & 0xff);
528 reg_w(gspca_dev, 0x0f, exposure >> 8);
530 /* load registers to sensor (Bit 0, auto clear) */
531 reg_w(gspca_dev, 0x11, 0x01);
534 static void sethvflip(struct gspca_dev *gspca_dev)
536 struct sd *sd = (struct sd *) gspca_dev;
537 u8 data, hflip, vflip;
539 hflip = sd->hflip->val;
540 if (sd->flags & FL_HFLIP)
541 hflip = !hflip;
542 vflip = sd->vflip->val;
543 if (sd->flags & FL_VFLIP)
544 vflip = !vflip;
546 reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
547 data = (hflip ? 0x08 : 0x00) | (vflip ? 0x04 : 0x00);
548 reg_w(gspca_dev, 0x21, data);
550 /* load registers to sensor (Bit 0, auto clear) */
551 reg_w(gspca_dev, 0x11, 0x01);
554 static void setsharpness(struct gspca_dev *gspca_dev)
556 struct sd *sd = (struct sd *) gspca_dev;
558 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
559 reg_w(gspca_dev, 0xb6, sd->sharpness->val);
561 reg_w(gspca_dev, 0xdc, 0x01);
564 /* this function is called at probe and resume time for pac7302 */
565 static int sd_init(struct gspca_dev *gspca_dev)
567 reg_w_seq(gspca_dev, init_7302, sizeof(init_7302)/2);
568 return gspca_dev->usb_err;
571 static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
573 struct gspca_dev *gspca_dev =
574 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
575 struct sd *sd = (struct sd *)gspca_dev;
577 gspca_dev->usb_err = 0;
579 if (ctrl->id == V4L2_CID_AUTOGAIN && ctrl->is_new && ctrl->val) {
580 /* when switching to autogain set defaults to make sure
581 we are on a valid point of the autogain gain /
582 exposure knee graph, and give this change time to
583 take effect before doing autogain. */
584 gspca_dev->exposure->val = PAC7302_EXPOSURE_DEFAULT;
585 gspca_dev->gain->val = PAC7302_GAIN_DEFAULT;
586 sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES;
589 if (!gspca_dev->streaming)
590 return 0;
592 switch (ctrl->id) {
593 case V4L2_CID_BRIGHTNESS:
594 setbrightcont(gspca_dev);
595 break;
596 case V4L2_CID_SATURATION:
597 setcolors(gspca_dev);
598 break;
599 case V4L2_CID_WHITE_BALANCE_TEMPERATURE:
600 setwhitebalance(gspca_dev);
601 break;
602 case V4L2_CID_RED_BALANCE:
603 setredbalance(gspca_dev);
604 break;
605 case V4L2_CID_BLUE_BALANCE:
606 setbluebalance(gspca_dev);
607 break;
608 case V4L2_CID_AUTOGAIN:
609 if (gspca_dev->exposure->is_new || (ctrl->is_new && ctrl->val))
610 setexposure(gspca_dev);
611 if (gspca_dev->gain->is_new || (ctrl->is_new && ctrl->val))
612 setgain(gspca_dev);
613 break;
614 case V4L2_CID_HFLIP:
615 sethvflip(gspca_dev);
616 break;
617 case V4L2_CID_SHARPNESS:
618 setsharpness(gspca_dev);
619 break;
620 default:
621 return -EINVAL;
623 return gspca_dev->usb_err;
626 static const struct v4l2_ctrl_ops sd_ctrl_ops = {
627 .s_ctrl = sd_s_ctrl,
630 /* this function is called at probe time */
631 static int sd_init_controls(struct gspca_dev *gspca_dev)
633 struct sd *sd = (struct sd *) gspca_dev;
634 struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
636 gspca_dev->vdev.ctrl_handler = hdl;
637 v4l2_ctrl_handler_init(hdl, 12);
639 sd->brightness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
640 V4L2_CID_BRIGHTNESS, 0, 32, 1, 16);
641 sd->contrast = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
642 V4L2_CID_CONTRAST, 0, 255, 1, 127);
644 sd->saturation = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
645 V4L2_CID_SATURATION, 0, 255, 1, 127);
646 sd->white_balance = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
647 V4L2_CID_WHITE_BALANCE_TEMPERATURE,
648 0, 255, 1, 55);
649 sd->red_balance = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
650 V4L2_CID_RED_BALANCE,
651 PAC7302_RGB_BALANCE_MIN,
652 PAC7302_RGB_BALANCE_MAX,
653 1, PAC7302_RGB_BALANCE_DEFAULT);
654 sd->blue_balance = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
655 V4L2_CID_BLUE_BALANCE,
656 PAC7302_RGB_BALANCE_MIN,
657 PAC7302_RGB_BALANCE_MAX,
658 1, PAC7302_RGB_BALANCE_DEFAULT);
660 gspca_dev->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
661 V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
662 gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
663 V4L2_CID_EXPOSURE, 0, 1023, 1,
664 PAC7302_EXPOSURE_DEFAULT);
665 gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
666 V4L2_CID_GAIN, 0, 62, 1,
667 PAC7302_GAIN_DEFAULT);
669 sd->hflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
670 V4L2_CID_HFLIP, 0, 1, 1, 0);
671 sd->vflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
672 V4L2_CID_VFLIP, 0, 1, 1, 0);
674 sd->sharpness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
675 V4L2_CID_SHARPNESS, 0, 15, 1, 8);
677 if (hdl->error) {
678 pr_err("Could not initialize controls\n");
679 return hdl->error;
682 v4l2_ctrl_cluster(2, &sd->brightness);
683 v4l2_ctrl_auto_cluster(3, &gspca_dev->autogain, 0, false);
684 v4l2_ctrl_cluster(2, &sd->hflip);
685 return 0;
688 /* -- start the camera -- */
689 static int sd_start(struct gspca_dev *gspca_dev)
691 struct sd *sd = (struct sd *) gspca_dev;
693 reg_w_var(gspca_dev, start_7302,
694 page3_7302, sizeof(page3_7302));
696 sd->sof_read = 0;
697 sd->autogain_ignore_frames = 0;
698 atomic_set(&sd->avg_lum, 270 + sd->brightness->val);
700 /* start stream */
701 reg_w(gspca_dev, 0xff, 0x01);
702 reg_w(gspca_dev, 0x78, 0x01);
704 return gspca_dev->usb_err;
707 static void sd_stopN(struct gspca_dev *gspca_dev)
710 /* stop stream */
711 reg_w(gspca_dev, 0xff, 0x01);
712 reg_w(gspca_dev, 0x78, 0x00);
715 /* called on streamoff with alt 0 and on disconnect for pac7302 */
716 static void sd_stop0(struct gspca_dev *gspca_dev)
718 if (!gspca_dev->present)
719 return;
720 reg_w(gspca_dev, 0xff, 0x01);
721 reg_w(gspca_dev, 0x78, 0x40);
724 static void do_autogain(struct gspca_dev *gspca_dev)
726 struct sd *sd = (struct sd *) gspca_dev;
727 int avg_lum = atomic_read(&sd->avg_lum);
728 int desired_lum;
729 const int deadzone = 30;
731 if (sd->autogain_ignore_frames < 0)
732 return;
734 if (sd->autogain_ignore_frames > 0) {
735 sd->autogain_ignore_frames--;
736 } else {
737 desired_lum = 270 + sd->brightness->val;
739 if (gspca_expo_autogain(gspca_dev, avg_lum, desired_lum,
740 deadzone, PAC7302_GAIN_KNEE,
741 PAC7302_EXPOSURE_KNEE))
742 sd->autogain_ignore_frames =
743 PAC_AUTOGAIN_IGNORE_FRAMES;
747 /* JPEG header */
748 static const u8 jpeg_header[] = {
749 0xff, 0xd8, /* SOI: Start of Image */
751 0xff, 0xc0, /* SOF0: Start of Frame (Baseline DCT) */
752 0x00, 0x11, /* length = 17 bytes (including this length field) */
753 0x08, /* Precision: 8 */
754 0x02, 0x80, /* height = 640 (image rotated) */
755 0x01, 0xe0, /* width = 480 */
756 0x03, /* Number of image components: 3 */
757 0x01, 0x21, 0x00, /* ID=1, Subsampling 1x1, Quantization table: 0 */
758 0x02, 0x11, 0x01, /* ID=2, Subsampling 2x1, Quantization table: 1 */
759 0x03, 0x11, 0x01, /* ID=3, Subsampling 2x1, Quantization table: 1 */
761 0xff, 0xda, /* SOS: Start Of Scan */
762 0x00, 0x0c, /* length = 12 bytes (including this length field) */
763 0x03, /* number of components: 3 */
764 0x01, 0x00, /* selector 1, table 0x00 */
765 0x02, 0x11, /* selector 2, table 0x11 */
766 0x03, 0x11, /* selector 3, table 0x11 */
767 0x00, 0x3f, /* Spectral selection: 0 .. 63 */
768 0x00 /* Successive approximation: 0 */
771 /* this function is run at interrupt level */
772 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
773 u8 *data, /* isoc packet */
774 int len) /* iso packet length */
776 struct sd *sd = (struct sd *) gspca_dev;
777 u8 *image;
778 u8 *sof;
780 sof = pac_find_sof(gspca_dev, &sd->sof_read, data, len);
781 if (sof) {
782 int n, lum_offset, footer_length;
785 * 6 bytes after the FF D9 EOF marker a number of lumination
786 * bytes are send corresponding to different parts of the
787 * image, the 14th and 15th byte after the EOF seem to
788 * correspond to the center of the image.
790 lum_offset = 61 + sizeof pac_sof_marker;
791 footer_length = 74;
793 /* Finish decoding current frame */
794 n = (sof - data) - (footer_length + sizeof pac_sof_marker);
795 if (n < 0) {
796 gspca_dev->image_len += n;
797 n = 0;
798 } else {
799 gspca_frame_add(gspca_dev, INTER_PACKET, data, n);
802 image = gspca_dev->image;
803 if (image != NULL
804 && image[gspca_dev->image_len - 2] == 0xff
805 && image[gspca_dev->image_len - 1] == 0xd9)
806 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
808 n = sof - data;
809 len -= n;
810 data = sof;
812 /* Get average lumination */
813 if (gspca_dev->last_packet_type == LAST_PACKET &&
814 n >= lum_offset)
815 atomic_set(&sd->avg_lum, data[-lum_offset] +
816 data[-lum_offset + 1]);
818 /* Start the new frame with the jpeg header */
819 /* The PAC7302 has the image rotated 90 degrees */
820 gspca_frame_add(gspca_dev, FIRST_PACKET,
821 jpeg_header, sizeof jpeg_header);
823 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
826 #ifdef CONFIG_VIDEO_ADV_DEBUG
827 static int sd_dbg_s_register(struct gspca_dev *gspca_dev,
828 const struct v4l2_dbg_register *reg)
830 u8 index;
831 u8 value;
834 * reg->reg: bit0..15: reserved for register index (wIndex is 16bit
835 * long on the USB bus)
837 if (reg->match.addr == 0 &&
838 (reg->reg < 0x000000ff) &&
839 (reg->val <= 0x000000ff)
841 /* Currently writing to page 0 is only supported. */
842 /* reg_w() only supports 8bit index */
843 index = reg->reg;
844 value = reg->val;
847 * Note that there shall be no access to other page
848 * by any other function between the page switch and
849 * the actual register write.
851 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
852 reg_w(gspca_dev, index, value);
854 reg_w(gspca_dev, 0xdc, 0x01);
856 return gspca_dev->usb_err;
858 #endif
860 #if IS_ENABLED(CONFIG_INPUT)
861 static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
862 u8 *data, /* interrupt packet data */
863 int len) /* interrupt packet length */
865 int ret = -EINVAL;
866 u8 data0, data1;
868 if (len == 2) {
869 data0 = data[0];
870 data1 = data[1];
871 if ((data0 == 0x00 && data1 == 0x11) ||
872 (data0 == 0x22 && data1 == 0x33) ||
873 (data0 == 0x44 && data1 == 0x55) ||
874 (data0 == 0x66 && data1 == 0x77) ||
875 (data0 == 0x88 && data1 == 0x99) ||
876 (data0 == 0xaa && data1 == 0xbb) ||
877 (data0 == 0xcc && data1 == 0xdd) ||
878 (data0 == 0xee && data1 == 0xff)) {
879 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
880 input_sync(gspca_dev->input_dev);
881 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
882 input_sync(gspca_dev->input_dev);
883 ret = 0;
887 return ret;
889 #endif
891 /* sub-driver description for pac7302 */
892 static const struct sd_desc sd_desc = {
893 .name = KBUILD_MODNAME,
894 .config = sd_config,
895 .init = sd_init,
896 .init_controls = sd_init_controls,
897 .start = sd_start,
898 .stopN = sd_stopN,
899 .stop0 = sd_stop0,
900 .pkt_scan = sd_pkt_scan,
901 .dq_callback = do_autogain,
902 #ifdef CONFIG_VIDEO_ADV_DEBUG
903 .set_register = sd_dbg_s_register,
904 #endif
905 #if IS_ENABLED(CONFIG_INPUT)
906 .int_pkt_scan = sd_int_pkt_scan,
907 #endif
910 /* -- module initialisation -- */
911 static const struct usb_device_id device_table[] = {
912 {USB_DEVICE(0x06f8, 0x3009)},
913 {USB_DEVICE(0x06f8, 0x301b)},
914 {USB_DEVICE(0x093a, 0x2620)},
915 {USB_DEVICE(0x093a, 0x2621)},
916 {USB_DEVICE(0x093a, 0x2622), .driver_info = FL_VFLIP},
917 {USB_DEVICE(0x093a, 0x2623), .driver_info = FL_VFLIP},
918 {USB_DEVICE(0x093a, 0x2624), .driver_info = FL_VFLIP},
919 {USB_DEVICE(0x093a, 0x2625)},
920 {USB_DEVICE(0x093a, 0x2626)},
921 {USB_DEVICE(0x093a, 0x2627), .driver_info = FL_VFLIP},
922 {USB_DEVICE(0x093a, 0x2628)},
923 {USB_DEVICE(0x093a, 0x2629), .driver_info = FL_VFLIP},
924 {USB_DEVICE(0x093a, 0x262a)},
925 {USB_DEVICE(0x093a, 0x262c)},
926 {USB_DEVICE(0x145f, 0x013c)},
927 {USB_DEVICE(0x1ae7, 0x2001)}, /* SpeedLink Snappy Mic SL-6825-SBK */
930 MODULE_DEVICE_TABLE(usb, device_table);
932 /* -- device connect -- */
933 static int sd_probe(struct usb_interface *intf,
934 const struct usb_device_id *id)
936 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
937 THIS_MODULE);
940 static struct usb_driver sd_driver = {
941 .name = KBUILD_MODNAME,
942 .id_table = device_table,
943 .probe = sd_probe,
944 .disconnect = gspca_disconnect,
945 #ifdef CONFIG_PM
946 .suspend = gspca_suspend,
947 .resume = gspca_resume,
948 .reset_resume = gspca_resume,
949 #endif
952 module_usb_driver(sd_driver);