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