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