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