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