Merge tag 'soc-ep93xx-dt-6.12' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc
[linux-2.6-block.git] / drivers / media / usb / gspca / pac7302.c
CommitLineData
fd9871f7 1// SPDX-License-Identifier: GPL-2.0-or-later
1408b847 2/*
ae251e6b 3 * Pixart PAC7302 driver
1408b847 4 *
ae251e6b
JFM
5 * Copyright (C) 2008-2012 Jean-Francois Moine <http://moinejf.free.fr>
6 * Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li
1408b847 7 *
cc2f82c2 8 * Separated from Pixart PAC7311 library by Márton Németh
aed6f1b5
MN
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>
1408b847
MN
11 */
12
895d464d
HG
13/*
14 * Some documentation about various registers as determined by trial and error.
15 *
b1a19c01
FS
16 * Register page 0:
17 *
18 * Address Description
6f9b3312
FS
19 * 0x01 Red balance control
20 * 0x02 Green balance control
21 * 0x03 Blue balance control
780d6170
FS
22 * The Windows driver uses a quadratic approach to map
23 * the settable values (0-200) on register values:
6f9b3312
FS
24 * min=0x20, default=0x40, max=0x80
25 * 0x0f-0x20 Color and saturation control
780d6170 26 * 0xa2-0xab Brightness, contrast and gamma control
b1a19c01
FS
27 * 0xb6 Sharpness control (bits 0-4)
28 *
895d464d
HG
29 * Register page 1:
30 *
31 * Address Description
32 * 0x78 Global control, bit 6 controls the LED (inverted)
48bb7315
HG
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
895d464d
HG
41 *
42 * Register page 3:
43 *
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
48bb7315
HG
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
895d464d 57 * 0x21 Bitfield: 0-1 unused, 2-3 vflip/hflip, 4-5 unknown, 6-7 unused
48bb7315
HG
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
895d464d
HG
62 *
63 * The registers are accessed in the following functions:
64 *
65 * Page | Register | Function
66 * -----+------------+---------------------------------------------------
2b34e9d1
FS
67 * 0 | 0x01 | setredbalance()
68 * 0 | 0x03 | setbluebalance()
895d464d
HG
69 * 0 | 0x0f..0x20 | setcolors()
70 * 0 | 0xa2..0xab | setbrightcont()
b1a19c01 71 * 0 | 0xb6 | setsharpness()
895d464d 72 * 0 | 0xc6 | setwhitebalance()
895d464d
HG
73 * 0 | 0xdc | setbrightcont(), setcolors()
74 * 3 | 0x02 | setexposure()
df8b9853 75 * 3 | 0x10, 0x12 | setgain()
895d464d
HG
76 * 3 | 0x11 | setcolors(), setgain(), setexposure(), sethvflip()
77 * 3 | 0x21 | sethvflip()
78 */
1408b847 79
133a9fe9
JP
80#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
81
aed6f1b5 82#include <linux/input.h>
1408b847 83#include "gspca.h"
ac399cd3
JFM
84/* Include pac common sof detection functions */
85#include "pac_common.h"
1408b847 86
2b34e9d1
FS
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 */
74233cd7 94
1ddc9f75 95MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>, Thomas Kaiser thomas@kaiser-linux.li");
1408b847
MN
96MODULE_DESCRIPTION("Pixart PAC7302");
97MODULE_LICENSE("GPL");
98
1408b847
MN
99struct sd {
100 struct gspca_dev gspca_dev; /* !! must be the first item */
101
74233cd7
HG
102 struct { /* brightness / contrast cluster */
103 struct v4l2_ctrl *brightness;
104 struct v4l2_ctrl *contrast;
105 };
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;
113 };
b1a19c01 114 struct v4l2_ctrl *sharpness;
fe2b6032
JFM
115 u8 flags;
116#define FL_HFLIP 0x01 /* mirrored by default */
117#define FL_VFLIP 0x02 /* vertical flipped by default */
1408b847
MN
118
119 u8 sof_read;
ac399cd3 120 s8 autogain_ignore_frames;
1408b847
MN
121
122 atomic_t avg_lum;
123};
124
1408b847
MN
125static 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,
ae251e6b 130 },
1408b847
MN
131};
132
133#define LOAD_PAGE3 255
1408b847
MN
134#define END_OF_SEQUENCE 0
135
ae251e6b 136static const u8 init_7302[] = {
1408b847
MN
137/* index,value */
138 0xff, 0x01, /* page 1 */
139 0x78, 0x00, /* deactivate */
140 0xff, 0x01,
141 0x78, 0x40, /* led off */
142};
ae251e6b 143static const u8 start_7302[] = {
1408b847
MN
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,
ae251e6b 158 0x62, 4, 0x10, 0x1e, 0x1e, 0x18,
1408b847
MN
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 */
205};
206
207#define SKIP 0xaa
208/* page 3 - the value SKIP says skip the index - see reg_w_page() */
ae251e6b 209static const u8 page3_7302[] = {
5fb2dde2 210 0x90, 0x40, 0x03, 0x00, 0xc0, 0x01, 0x14, 0x16,
1408b847
MN
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,
cdf955cd 219 SKIP, 0x00, 0x00, 0xc0, 0xc0, 0x10, 0x00, 0x00,
1408b847
MN
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
230};
231
be927bef 232static void reg_w_buf(struct gspca_dev *gspca_dev,
ae251e6b 233 u8 index,
0aeb5ec7 234 const u8 *buffer, int len)
1408b847 235{
4f7309e2
MN
236 int ret;
237
be927bef
JFM
238 if (gspca_dev->usb_err < 0)
239 return;
1408b847 240 memcpy(gspca_dev->usb_buf, buffer, len);
4f7309e2 241 ret = usb_control_msg(gspca_dev->dev,
1408b847 242 usb_sndctrlpipe(gspca_dev->dev, 0),
a1317135 243 0, /* request */
1408b847
MN
244 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
245 0, /* value */
246 index, gspca_dev->usb_buf, len,
247 500);
be927bef 248 if (ret < 0) {
ae251e6b 249 pr_err("reg_w_buf failed i: %02x error %d\n",
133a9fe9 250 index, ret);
be927bef
JFM
251 gspca_dev->usb_err = ret;
252 }
1408b847
MN
253}
254
255
be927bef 256static void reg_w(struct gspca_dev *gspca_dev,
ae251e6b
JFM
257 u8 index,
258 u8 value)
1408b847 259{
4f7309e2
MN
260 int ret;
261
be927bef
JFM
262 if (gspca_dev->usb_err < 0)
263 return;
1408b847 264 gspca_dev->usb_buf[0] = value;
4f7309e2 265 ret = usb_control_msg(gspca_dev->dev,
1408b847
MN
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);
be927bef 271 if (ret < 0) {
ae251e6b 272 pr_err("reg_w() failed i: %02x v: %02x error %d\n",
133a9fe9 273 index, value, ret);
be927bef
JFM
274 gspca_dev->usb_err = ret;
275 }
1408b847
MN
276}
277
be927bef 278static void reg_w_seq(struct gspca_dev *gspca_dev,
ae251e6b 279 const u8 *seq, int len)
1408b847
MN
280{
281 while (--len >= 0) {
be927bef 282 reg_w(gspca_dev, seq[0], seq[1]);
1408b847
MN
283 seq += 2;
284 }
285}
286
287/* load the beginning of a page */
be927bef 288static void reg_w_page(struct gspca_dev *gspca_dev,
ae251e6b 289 const u8 *page, int len)
1408b847
MN
290{
291 int index;
b1784b33 292 int ret = 0;
1408b847 293
be927bef
JFM
294 if (gspca_dev->usb_err < 0)
295 return;
1408b847
MN
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];
4f7309e2 300 ret = usb_control_msg(gspca_dev->dev,
1408b847
MN
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);
b1784b33 306 if (ret < 0) {
ae251e6b 307 pr_err("reg_w_page() failed i: %02x v: %02x error %d\n",
133a9fe9 308 index, page[index], ret);
be927bef 309 gspca_dev->usb_err = ret;
b1784b33
MN
310 break;
311 }
1408b847
MN
312 }
313}
314
315/* output a variable sequence */
be927bef 316static void reg_w_var(struct gspca_dev *gspca_dev,
ae251e6b
JFM
317 const u8 *seq,
318 const u8 *page3, unsigned int page3_len)
1408b847
MN
319{
320 int index, len;
321
322 for (;;) {
323 index = *seq++;
324 len = *seq++;
325 switch (len) {
326 case END_OF_SEQUENCE:
be927bef 327 return;
1408b847 328 case LOAD_PAGE3:
be927bef 329 reg_w_page(gspca_dev, page3, page3_len);
1408b847
MN
330 break;
331 default:
332 if (len > USB_BUF_SZ) {
52173c5f 333 gspca_err(gspca_dev, "Incorrect variable sequence\n");
be927bef 334 return;
1408b847
MN
335 }
336 while (len > 0) {
337 if (len < 8) {
be927bef 338 reg_w_buf(gspca_dev,
b1784b33 339 index, seq, len);
1408b847
MN
340 seq += len;
341 break;
342 }
be927bef 343 reg_w_buf(gspca_dev, index, seq, 8);
1408b847
MN
344 seq += 8;
345 index += 8;
346 len -= 8;
347 }
348 }
349 }
350 /* not reached */
351}
352
353/* this function is called at probe time for pac7302 */
354static int sd_config(struct gspca_dev *gspca_dev,
355 const struct usb_device_id *id)
356{
357 struct sd *sd = (struct sd *) gspca_dev;
358 struct cam *cam;
359
360 cam = &gspca_dev->cam;
361
1408b847
MN
362 cam->cam_mode = vga_mode; /* only 640x480 */
363 cam->nmodes = ARRAY_SIZE(vga_mode);
364
fe2b6032 365 sd->flags = id->driver_info;
1408b847
MN
366 return 0;
367}
368
be927bef 369static void setbrightcont(struct gspca_dev *gspca_dev)
1408b847
MN
370{
371 struct sd *sd = (struct sd *) gspca_dev;
372 int i, v;
ae251e6b 373 static const u8 max[10] =
1408b847
MN
374 {0x29, 0x33, 0x42, 0x5a, 0x6e, 0x80, 0x9f, 0xbb,
375 0xd4, 0xec};
ae251e6b 376 static const u8 delta[10] =
1408b847
MN
377 {0x35, 0x33, 0x33, 0x2f, 0x2a, 0x25, 0x1e, 0x17,
378 0x11, 0x0b};
379
be927bef 380 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
1408b847
MN
381 for (i = 0; i < 10; i++) {
382 v = max[i];
0d5e8c43
HV
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;
1408b847
MN
386 if (v < 0)
387 v = 0;
388 else if (v > 0xff)
389 v = 0xff;
be927bef 390 reg_w(gspca_dev, 0xa2 + i, v);
1408b847 391 }
be927bef 392 reg_w(gspca_dev, 0xdc, 0x01);
1408b847
MN
393}
394
be927bef 395static void setcolors(struct gspca_dev *gspca_dev)
1408b847
MN
396{
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};
403
be927bef
JFM
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 */
1408b847 407 for (i = 0; i < 9; i++) {
0d5e8c43 408 v = a[i] * sd->saturation->val / (s32)sd->saturation->maximum;
74233cd7 409 v += b[i];
be927bef
JFM
410 reg_w(gspca_dev, 0x0f + 2 * i, (v >> 8) & 0x07);
411 reg_w(gspca_dev, 0x0f + 2 * i + 1, v);
1408b847 412 }
be927bef 413 reg_w(gspca_dev, 0xdc, 0x01);
1408b847
MN
414}
415
be927bef 416static void setwhitebalance(struct gspca_dev *gspca_dev)
23fbee6f
MN
417{
418 struct sd *sd = (struct sd *) gspca_dev;
23fbee6f 419
be927bef 420 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
74233cd7 421 reg_w(gspca_dev, 0xc6, sd->white_balance->val);
23fbee6f 422
be927bef 423 reg_w(gspca_dev, 0xdc, 0x01);
23fbee6f
MN
424}
425
2b34e9d1
FS
426static u8 rgbbalance_ctrl_to_reg_value(s32 rgb_ctrl_val)
427{
428 const unsigned int k = 1000; /* precision factor */
429 unsigned int norm;
430
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 */
438
439 /* NOTE: for full value range (0x00-0xff) use
440 * Y = 254*X*X + X
441 * => 254 * norm * norm / (k*k) + 1 * norm / k */
442}
443
be927bef 444static void setredbalance(struct gspca_dev *gspca_dev)
265a8098
MN
445{
446 struct sd *sd = (struct sd *) gspca_dev;
265a8098 447
2b34e9d1
FS
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));
265a8098 451
be927bef 452 reg_w(gspca_dev, 0xdc, 0x01);
265a8098
MN
453}
454
be927bef 455static void setbluebalance(struct gspca_dev *gspca_dev)
265a8098
MN
456{
457 struct sd *sd = (struct sd *) gspca_dev;
265a8098 458
be927bef 459 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
2b34e9d1
FS
460 reg_w(gspca_dev, 0x03,
461 rgbbalance_ctrl_to_reg_value(sd->blue_balance->val));
265a8098 462
be927bef 463 reg_w(gspca_dev, 0xdc, 0x01);
265a8098
MN
464}
465
be927bef 466static void setgain(struct gspca_dev *gspca_dev)
1408b847 467{
df8b9853
HG
468 u8 reg10, reg12;
469
74233cd7
HG
470 if (gspca_dev->gain->val < 32) {
471 reg10 = gspca_dev->gain->val;
df8b9853
HG
472 reg12 = 0;
473 } else {
474 reg10 = 31;
74233cd7 475 reg12 = gspca_dev->gain->val - 31;
df8b9853 476 }
1408b847 477
be927bef 478 reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
df8b9853
HG
479 reg_w(gspca_dev, 0x10, reg10);
480 reg_w(gspca_dev, 0x12, reg12);
1408b847
MN
481
482 /* load registers to sensor (Bit 0, auto clear) */
be927bef 483 reg_w(gspca_dev, 0x11, 0x01);
1408b847
MN
484}
485
be927bef 486static void setexposure(struct gspca_dev *gspca_dev)
1408b847 487{
ae251e6b
JFM
488 u8 clockdiv;
489 u16 exposure;
5fb2dde2 490
895d464d
HG
491 /*
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.
495 */
74233cd7 496 clockdiv = (90 * gspca_dev->exposure->val + 1999) / 2000;
5fb2dde2 497
895d464d
HG
498 /*
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.
503 */
5fb2dde2
HG
504 if (clockdiv < 6)
505 clockdiv = 6;
506 else if (clockdiv > 63)
507 clockdiv = 63;
508
895d464d
HG
509 /*
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.
513 */
5fb2dde2
HG
514 if (clockdiv < 6 || clockdiv > 12)
515 clockdiv = ((clockdiv + 2) / 3) * 3;
516
895d464d
HG
517 /*
518 * frame exposure time in ms = 1000 * clockdiv / 90 ->
519 * exposure = (sd->exposure / 2) * 448 / (1000 * clockdiv / 90)
520 */
74233cd7 521 exposure = (gspca_dev->exposure->val * 45 * 448) / (1000 * clockdiv);
5fb2dde2
HG
522 /* 0 = use full frametime, 448 = no exposure, reverse it */
523 exposure = 448 - exposure;
524
be927bef 525 reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
5fb2dde2
HG
526 reg_w(gspca_dev, 0x02, clockdiv);
527 reg_w(gspca_dev, 0x0e, exposure & 0xff);
528 reg_w(gspca_dev, 0x0f, exposure >> 8);
1408b847
MN
529
530 /* load registers to sensor (Bit 0, auto clear) */
be927bef 531 reg_w(gspca_dev, 0x11, 0x01);
1408b847
MN
532}
533
be927bef 534static void sethvflip(struct gspca_dev *gspca_dev)
1408b847
MN
535{
536 struct sd *sd = (struct sd *) gspca_dev;
fe2b6032
JFM
537 u8 data, hflip, vflip;
538
74233cd7 539 hflip = sd->hflip->val;
fe2b6032
JFM
540 if (sd->flags & FL_HFLIP)
541 hflip = !hflip;
74233cd7 542 vflip = sd->vflip->val;
fe2b6032
JFM
543 if (sd->flags & FL_VFLIP)
544 vflip = !vflip;
1408b847 545
be927bef 546 reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
fe2b6032 547 data = (hflip ? 0x08 : 0x00) | (vflip ? 0x04 : 0x00);
be927bef
JFM
548 reg_w(gspca_dev, 0x21, data);
549
1408b847 550 /* load registers to sensor (Bit 0, auto clear) */
be927bef 551 reg_w(gspca_dev, 0x11, 0x01);
1408b847
MN
552}
553
b1a19c01
FS
554static void setsharpness(struct gspca_dev *gspca_dev)
555{
556 struct sd *sd = (struct sd *) gspca_dev;
557
558 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
559 reg_w(gspca_dev, 0xb6, sd->sharpness->val);
560
561 reg_w(gspca_dev, 0xdc, 0x01);
562}
563
1408b847
MN
564/* this function is called at probe and resume time for pac7302 */
565static int sd_init(struct gspca_dev *gspca_dev)
566{
be927bef
JFM
567 reg_w_seq(gspca_dev, init_7302, sizeof(init_7302)/2);
568 return gspca_dev->usb_err;
1408b847
MN
569}
570
74233cd7
HG
571static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
572{
573 struct gspca_dev *gspca_dev =
574 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
575 struct sd *sd = (struct sd *)gspca_dev;
576
577 gspca_dev->usb_err = 0;
578
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;
587 }
588
589 if (!gspca_dev->streaming)
590 return 0;
591
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;
b1a19c01
FS
617 case V4L2_CID_SHARPNESS:
618 setsharpness(gspca_dev);
619 break;
74233cd7
HG
620 default:
621 return -EINVAL;
622 }
623 return gspca_dev->usb_err;
624}
625
626static const struct v4l2_ctrl_ops sd_ctrl_ops = {
627 .s_ctrl = sd_s_ctrl,
628};
629
630/* this function is called at probe time */
631static int sd_init_controls(struct gspca_dev *gspca_dev)
632{
633 struct sd *sd = (struct sd *) gspca_dev;
634 struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
635
636 gspca_dev->vdev.ctrl_handler = hdl;
b1a19c01 637 v4l2_ctrl_handler_init(hdl, 12);
74233cd7
HG
638
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);
643
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,
f58e5cdf 648 0, 255, 1, 55);
74233cd7 649 sd->red_balance = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
2b34e9d1
FS
650 V4L2_CID_RED_BALANCE,
651 PAC7302_RGB_BALANCE_MIN,
652 PAC7302_RGB_BALANCE_MAX,
653 1, PAC7302_RGB_BALANCE_DEFAULT);
74233cd7 654 sd->blue_balance = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
2b34e9d1
FS
655 V4L2_CID_BLUE_BALANCE,
656 PAC7302_RGB_BALANCE_MIN,
657 PAC7302_RGB_BALANCE_MAX,
658 1, PAC7302_RGB_BALANCE_DEFAULT);
74233cd7
HG
659
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);
668
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);
673
b1a19c01
FS
674 sd->sharpness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
675 V4L2_CID_SHARPNESS, 0, 15, 1, 8);
676
74233cd7
HG
677 if (hdl->error) {
678 pr_err("Could not initialize controls\n");
679 return hdl->error;
680 }
681
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;
686}
687
688/* -- start the camera -- */
1408b847
MN
689static int sd_start(struct gspca_dev *gspca_dev)
690{
691 struct sd *sd = (struct sd *) gspca_dev;
692
be927bef 693 reg_w_var(gspca_dev, start_7302,
23a5de20 694 page3_7302, sizeof(page3_7302));
1408b847 695
1408b847 696 sd->sof_read = 0;
74233cd7
HG
697 sd->autogain_ignore_frames = 0;
698 atomic_set(&sd->avg_lum, 270 + sd->brightness->val);
1408b847
MN
699
700 /* start stream */
be927bef
JFM
701 reg_w(gspca_dev, 0xff, 0x01);
702 reg_w(gspca_dev, 0x78, 0x01);
1408b847 703
be927bef 704 return gspca_dev->usb_err;
1408b847
MN
705}
706
707static void sd_stopN(struct gspca_dev *gspca_dev)
708{
b1784b33 709
67c98f72 710 /* stop stream */
be927bef
JFM
711 reg_w(gspca_dev, 0xff, 0x01);
712 reg_w(gspca_dev, 0x78, 0x00);
1408b847
MN
713}
714
715/* called on streamoff with alt 0 and on disconnect for pac7302 */
716static void sd_stop0(struct gspca_dev *gspca_dev)
717{
718 if (!gspca_dev->present)
719 return;
be927bef
JFM
720 reg_w(gspca_dev, 0xff, 0x01);
721 reg_w(gspca_dev, 0x78, 0x40);
1408b847
MN
722}
723
1408b847
MN
724static void do_autogain(struct gspca_dev *gspca_dev)
725{
726 struct sd *sd = (struct sd *) gspca_dev;
727 int avg_lum = atomic_read(&sd->avg_lum);
5fb2dde2
HG
728 int desired_lum;
729 const int deadzone = 30;
1408b847 730
ac399cd3 731 if (sd->autogain_ignore_frames < 0)
1408b847
MN
732 return;
733
ac399cd3 734 if (sd->autogain_ignore_frames > 0) {
1408b847 735 sd->autogain_ignore_frames--;
ac399cd3 736 } else {
74233cd7 737 desired_lum = 270 + sd->brightness->val;
ac399cd3 738
74233cd7
HG
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;
ac399cd3 744 }
1408b847
MN
745}
746
7532e815
JFM
747/* JPEG header */
748static const u8 jpeg_header[] = {
749 0xff, 0xd8, /* SOI: Start of Image */
750
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 */
760
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 */
1408b847
MN
769};
770
1408b847
MN
771/* this function is run at interrupt level */
772static void sd_pkt_scan(struct gspca_dev *gspca_dev,
76dd272b 773 u8 *data, /* isoc packet */
1408b847
MN
774 int len) /* iso packet length */
775{
776 struct sd *sd = (struct sd *) gspca_dev;
b192ca98 777 u8 *image;
ae251e6b 778 u8 *sof;
1408b847 779
c93396e1 780 sof = pac_find_sof(gspca_dev, &sd->sof_read, data, len);
1408b847
MN
781 if (sof) {
782 int n, lum_offset, footer_length;
783
895d464d
HG
784 /*
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.
789 */
1408b847
MN
790 lum_offset = 61 + sizeof pac_sof_marker;
791 footer_length = 74;
792
793 /* Finish decoding current frame */
794 n = (sof - data) - (footer_length + sizeof pac_sof_marker);
795 if (n < 0) {
b192ca98 796 gspca_dev->image_len += n;
b192ca98
JFM
797 } else {
798 gspca_frame_add(gspca_dev, INTER_PACKET, data, n);
1408b847 799 }
f7059eaa
JFM
800
801 image = gspca_dev->image;
802 if (image != NULL
b192ca98
JFM
803 && image[gspca_dev->image_len - 2] == 0xff
804 && image[gspca_dev->image_len - 1] == 0xd9)
805 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
1408b847
MN
806
807 n = sof - data;
808 len -= n;
809 data = sof;
810
811 /* Get average lumination */
812 if (gspca_dev->last_packet_type == LAST_PACKET &&
813 n >= lum_offset)
814 atomic_set(&sd->avg_lum, data[-lum_offset] +
815 data[-lum_offset + 1]);
1408b847
MN
816
817 /* Start the new frame with the jpeg header */
818 /* The PAC7302 has the image rotated 90 degrees */
7532e815
JFM
819 gspca_frame_add(gspca_dev, FIRST_PACKET,
820 jpeg_header, sizeof jpeg_header);
1408b847 821 }
76dd272b 822 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
1408b847
MN
823}
824
6763cc0e
MN
825#ifdef CONFIG_VIDEO_ADV_DEBUG
826static int sd_dbg_s_register(struct gspca_dev *gspca_dev,
977ba3b1 827 const struct v4l2_dbg_register *reg)
6763cc0e 828{
ae251e6b
JFM
829 u8 index;
830 u8 value;
6763cc0e 831
895d464d
HG
832 /*
833 * reg->reg: bit0..15: reserved for register index (wIndex is 16bit
834 * long on the USB bus)
835 */
b1c85cc0 836 if (reg->match.addr == 0 &&
6763cc0e
MN
837 (reg->reg < 0x000000ff) &&
838 (reg->val <= 0x000000ff)
839 ) {
840 /* Currently writing to page 0 is only supported. */
841 /* reg_w() only supports 8bit index */
ae251e6b
JFM
842 index = reg->reg;
843 value = reg->val;
6763cc0e 844
895d464d
HG
845 /*
846 * Note that there shall be no access to other page
847 * by any other function between the page switch and
848 * the actual register write.
849 */
be927bef
JFM
850 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
851 reg_w(gspca_dev, index, value);
6763cc0e 852
be927bef 853 reg_w(gspca_dev, 0xdc, 0x01);
6763cc0e 854 }
be927bef 855 return gspca_dev->usb_err;
6763cc0e 856}
6763cc0e
MN
857#endif
858
ae814c08 859#if IS_ENABLED(CONFIG_INPUT)
aed6f1b5
MN
860static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
861 u8 *data, /* interrupt packet data */
39c1cb2b 862 int len) /* interrupt packet length */
aed6f1b5
MN
863{
864 int ret = -EINVAL;
865 u8 data0, data1;
866
867 if (len == 2) {
868 data0 = data[0];
869 data1 = data[1];
870 if ((data0 == 0x00 && data1 == 0x11) ||
871 (data0 == 0x22 && data1 == 0x33) ||
872 (data0 == 0x44 && data1 == 0x55) ||
873 (data0 == 0x66 && data1 == 0x77) ||
874 (data0 == 0x88 && data1 == 0x99) ||
875 (data0 == 0xaa && data1 == 0xbb) ||
876 (data0 == 0xcc && data1 == 0xdd) ||
877 (data0 == 0xee && data1 == 0xff)) {
878 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
879 input_sync(gspca_dev->input_dev);
880 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
881 input_sync(gspca_dev->input_dev);
882 ret = 0;
883 }
884 }
885
886 return ret;
887}
888#endif
889
1408b847 890/* sub-driver description for pac7302 */
aabcdfb6 891static const struct sd_desc sd_desc = {
ae251e6b 892 .name = KBUILD_MODNAME,
1408b847
MN
893 .config = sd_config,
894 .init = sd_init,
74233cd7 895 .init_controls = sd_init_controls,
1408b847
MN
896 .start = sd_start,
897 .stopN = sd_stopN,
898 .stop0 = sd_stop0,
899 .pkt_scan = sd_pkt_scan,
900 .dq_callback = do_autogain,
6763cc0e
MN
901#ifdef CONFIG_VIDEO_ADV_DEBUG
902 .set_register = sd_dbg_s_register,
6763cc0e 903#endif
ae814c08 904#if IS_ENABLED(CONFIG_INPUT)
aed6f1b5
MN
905 .int_pkt_scan = sd_int_pkt_scan,
906#endif
1408b847
MN
907};
908
909/* -- module initialisation -- */
95c967c1 910static const struct usb_device_id device_table[] = {
1408b847 911 {USB_DEVICE(0x06f8, 0x3009)},
dd32f981 912 {USB_DEVICE(0x06f8, 0x301b)},
1408b847
MN
913 {USB_DEVICE(0x093a, 0x2620)},
914 {USB_DEVICE(0x093a, 0x2621)},
fe2b6032 915 {USB_DEVICE(0x093a, 0x2622), .driver_info = FL_VFLIP},
242841d3 916 {USB_DEVICE(0x093a, 0x2623), .driver_info = FL_VFLIP},
fe2b6032 917 {USB_DEVICE(0x093a, 0x2624), .driver_info = FL_VFLIP},
4e6aeefe 918 {USB_DEVICE(0x093a, 0x2625)},
1408b847 919 {USB_DEVICE(0x093a, 0x2626)},
5b84325a 920 {USB_DEVICE(0x093a, 0x2627), .driver_info = FL_VFLIP},
1408b847 921 {USB_DEVICE(0x093a, 0x2628)},
c4322bfc 922 {USB_DEVICE(0x093a, 0x2629), .driver_info = FL_VFLIP},
1408b847
MN
923 {USB_DEVICE(0x093a, 0x262a)},
924 {USB_DEVICE(0x093a, 0x262c)},
4d6454db 925 {USB_DEVICE(0x145f, 0x013c)},
97d2fbf5 926 {USB_DEVICE(0x1ae7, 0x2001)}, /* SpeedLink Snappy Mic SL-6825-SBK */
1408b847
MN
927 {}
928};
929MODULE_DEVICE_TABLE(usb, device_table);
930
931/* -- device connect -- */
95c967c1 932static int sd_probe(struct usb_interface *intf,
1408b847
MN
933 const struct usb_device_id *id)
934{
935 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
936 THIS_MODULE);
937}
938
939static struct usb_driver sd_driver = {
ae251e6b 940 .name = KBUILD_MODNAME,
1408b847
MN
941 .id_table = device_table,
942 .probe = sd_probe,
943 .disconnect = gspca_disconnect,
944#ifdef CONFIG_PM
945 .suspend = gspca_suspend,
946 .resume = gspca_resume,
8bb58964 947 .reset_resume = gspca_resume,
1408b847
MN
948#endif
949};
950
ecb3b2b3 951module_usb_driver(sd_driver);