GNU Linux-libre 6.7.9-gnu
[releases.git] / drivers / media / usb / gspca / m5602 / m5602_ov9650.c
1 // SPDX-License-Identifier: GPL-2.0-only
2
3 /*
4  * Driver for the ov9650 sensor
5  *
6  * Copyright (C) 2008 Erik AndrĂ©n
7  * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
8  * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
9  *
10  * Portions of code to USB interface and ALi driver software,
11  * Copyright (c) 2006 Willem Duinker
12  * v4l2 interface modeled after the V4L2 driver
13  * for SN9C10x PC Camera Controllers
14  */
15
16 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
17
18 #include "m5602_ov9650.h"
19
20 static int ov9650_s_ctrl(struct v4l2_ctrl *ctrl);
21 static void ov9650_dump_registers(struct sd *sd);
22
23 static const unsigned char preinit_ov9650[][3] = {
24         /* [INITCAM] */
25         {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02},
26         {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0},
27         {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
28         {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
29         {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
30         {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00},
31
32         {BRIDGE, M5602_XB_SENSOR_TYPE, 0x08},
33         {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
34         {BRIDGE, M5602_XB_GPIO_DAT, 0x04},
35         {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
36         {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
37         {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
38         {BRIDGE, M5602_XB_GPIO_DAT, 0x00},
39         {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a},
40         /* Reset chip */
41         {SENSOR, OV9650_COM7, OV9650_REGISTER_RESET},
42         /* Enable double clock */
43         {SENSOR, OV9650_CLKRC, 0x80},
44         /* Do something out of spec with the power */
45         {SENSOR, OV9650_OFON, 0x40}
46 };
47
48 static const unsigned char init_ov9650[][3] = {
49         /* [INITCAM] */
50         {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02},
51         {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0},
52         {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
53         {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
54         {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
55         {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00},
56
57         {BRIDGE, M5602_XB_SENSOR_TYPE, 0x08},
58         {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
59         {BRIDGE, M5602_XB_GPIO_DAT, 0x04},
60         {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
61         {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
62         {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
63         {BRIDGE, M5602_XB_GPIO_DAT, 0x00},
64         {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a},
65
66         /* Reset chip */
67         {SENSOR, OV9650_COM7, OV9650_REGISTER_RESET},
68         /* One extra reset is needed in order to make the sensor behave
69            properly when resuming from ram, could be a timing issue */
70         {SENSOR, OV9650_COM7, OV9650_REGISTER_RESET},
71
72         /* Enable double clock */
73         {SENSOR, OV9650_CLKRC, 0x80},
74         /* Do something out of spec with the power */
75         {SENSOR, OV9650_OFON, 0x40},
76
77         /* Set fast AGC/AEC algorithm with unlimited step size */
78         {SENSOR, OV9650_COM8, OV9650_FAST_AGC_AEC |
79                               OV9650_AEC_UNLIM_STEP_SIZE},
80
81         {SENSOR, OV9650_CHLF, 0x10},
82         {SENSOR, OV9650_ARBLM, 0xbf},
83         {SENSOR, OV9650_ACOM38, 0x81},
84         /* Turn off color matrix coefficient double option */
85         {SENSOR, OV9650_COM16, 0x00},
86         /* Enable color matrix for RGB/YUV, Delay Y channel,
87         set output Y/UV delay to 1 */
88         {SENSOR, OV9650_COM13, 0x19},
89         /* Enable digital BLC, Set output mode to U Y V Y */
90         {SENSOR, OV9650_TSLB, 0x0c},
91         /* Limit the AGC/AEC stable upper region */
92         {SENSOR, OV9650_COM24, 0x00},
93         /* Enable HREF and some out of spec things */
94         {SENSOR, OV9650_COM12, 0x73},
95         /* Set all DBLC offset signs to positive and
96         do some out of spec stuff */
97         {SENSOR, OV9650_DBLC1, 0xdf},
98         {SENSOR, OV9650_COM21, 0x06},
99         {SENSOR, OV9650_RSVD35, 0x91},
100         /* Necessary, no camera stream without it */
101         {SENSOR, OV9650_RSVD16, 0x06},
102         {SENSOR, OV9650_RSVD94, 0x99},
103         {SENSOR, OV9650_RSVD95, 0x99},
104         {SENSOR, OV9650_RSVD96, 0x04},
105         /* Enable full range output */
106         {SENSOR, OV9650_COM15, 0x0},
107         /* Enable HREF at optical black, enable ADBLC bias,
108         enable ADBLC, reset timings at format change */
109         {SENSOR, OV9650_COM6, 0x4b},
110         /* Subtract 32 from the B channel bias */
111         {SENSOR, OV9650_BBIAS, 0xa0},
112         /* Subtract 32 from the Gb channel bias */
113         {SENSOR, OV9650_GbBIAS, 0xa0},
114         /* Do not bypass the analog BLC and to some out of spec stuff */
115         {SENSOR, OV9650_Gr_COM, 0x00},
116         /* Subtract 32 from the R channel bias */
117         {SENSOR, OV9650_RBIAS, 0xa0},
118         /* Subtract 32 from the R channel bias */
119         {SENSOR, OV9650_RBIAS, 0x0},
120         {SENSOR, OV9650_COM26, 0x80},
121         {SENSOR, OV9650_ACOMA9, 0x98},
122         /* Set the AGC/AEC stable region upper limit */
123         {SENSOR, OV9650_AEW, 0x68},
124         /* Set the AGC/AEC stable region lower limit */
125         {SENSOR, OV9650_AEB, 0x5c},
126         /* Set the high and low limit nibbles to 3 */
127         {SENSOR, OV9650_VPT, 0xc3},
128         /* Set the Automatic Gain Ceiling (AGC) to 128x,
129         drop VSYNC at frame drop,
130         limit exposure timing,
131         drop frame when the AEC step is larger than the exposure gap */
132         {SENSOR, OV9650_COM9, 0x6e},
133         /* Set VSYNC negative, Set RESET to SLHS (slave mode horizontal sync)
134         and set PWDN to SLVS (slave mode vertical sync) */
135         {SENSOR, OV9650_COM10, 0x42},
136         /* Set horizontal column start high to default value */
137         {SENSOR, OV9650_HSTART, 0x1a}, /* 210 */
138         /* Set horizontal column end */
139         {SENSOR, OV9650_HSTOP, 0xbf}, /* 1534 */
140         /* Complementing register to the two writes above */
141         {SENSOR, OV9650_HREF, 0xb2},
142         /* Set vertical row start high bits */
143         {SENSOR, OV9650_VSTRT, 0x02},
144         /* Set vertical row end low bits */
145         {SENSOR, OV9650_VSTOP, 0x7e},
146         /* Set complementing vertical frame control */
147         {SENSOR, OV9650_VREF, 0x10},
148         {SENSOR, OV9650_ADC, 0x04},
149         {SENSOR, OV9650_HV, 0x40},
150
151         /* Enable denoise, and white-pixel erase */
152         {SENSOR, OV9650_COM22, OV9650_DENOISE_ENABLE |
153                  OV9650_WHITE_PIXEL_ENABLE |
154                  OV9650_WHITE_PIXEL_OPTION},
155
156         /* Enable VARIOPIXEL */
157         {SENSOR, OV9650_COM3, OV9650_VARIOPIXEL},
158         {SENSOR, OV9650_COM4, OV9650_QVGA_VARIOPIXEL},
159
160         /* Put the sensor in soft sleep mode */
161         {SENSOR, OV9650_COM2, OV9650_SOFT_SLEEP | OV9650_OUTPUT_DRIVE_2X},
162 };
163
164 static const unsigned char res_init_ov9650[][3] = {
165         {SENSOR, OV9650_COM2, OV9650_OUTPUT_DRIVE_2X},
166
167         {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x82},
168         {BRIDGE, M5602_XB_LINE_OF_FRAME_L, 0x00},
169         {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82},
170         {BRIDGE, M5602_XB_PIX_OF_LINE_L, 0x00},
171         {BRIDGE, M5602_XB_SIG_INI, 0x01}
172 };
173
174 /* Vertically and horizontally flips the image if matched, needed for machines
175    where the sensor is mounted upside down */
176 static
177     const
178         struct dmi_system_id ov9650_flip_dmi_table[] = {
179         {
180                 .ident = "ASUS A6Ja",
181                 .matches = {
182                         DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
183                         DMI_MATCH(DMI_PRODUCT_NAME, "A6J")
184                 }
185         },
186         {
187                 .ident = "ASUS A6JC",
188                 .matches = {
189                         DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
190                         DMI_MATCH(DMI_PRODUCT_NAME, "A6JC")
191                 }
192         },
193         {
194                 .ident = "ASUS A6K",
195                 .matches = {
196                         DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
197                         DMI_MATCH(DMI_PRODUCT_NAME, "A6K")
198                 }
199         },
200         {
201                 .ident = "ASUS A6Kt",
202                 .matches = {
203                         DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
204                         DMI_MATCH(DMI_PRODUCT_NAME, "A6Kt")
205                 }
206         },
207         {
208                 .ident = "ASUS A6VA",
209                 .matches = {
210                         DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
211                         DMI_MATCH(DMI_PRODUCT_NAME, "A6VA")
212                 }
213         },
214         {
215
216                 .ident = "ASUS A6VC",
217                 .matches = {
218                         DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
219                         DMI_MATCH(DMI_PRODUCT_NAME, "A6VC")
220                 }
221         },
222         {
223                 .ident = "ASUS A6VM",
224                 .matches = {
225                         DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
226                         DMI_MATCH(DMI_PRODUCT_NAME, "A6VM")
227                 }
228         },
229         {
230                 .ident = "ASUS A7V",
231                 .matches = {
232                         DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
233                         DMI_MATCH(DMI_PRODUCT_NAME, "A7V")
234                 }
235         },
236         {
237                 .ident = "Alienware Aurora m9700",
238                 .matches = {
239                         DMI_MATCH(DMI_SYS_VENDOR, "alienware"),
240                         DMI_MATCH(DMI_PRODUCT_NAME, "Aurora m9700")
241                 }
242         },
243         {}
244 };
245
246 static struct v4l2_pix_format ov9650_modes[] = {
247         {
248                 176,
249                 144,
250                 V4L2_PIX_FMT_SBGGR8,
251                 V4L2_FIELD_NONE,
252                 .sizeimage =
253                         176 * 144,
254                 .bytesperline = 176,
255                 .colorspace = V4L2_COLORSPACE_SRGB,
256                 .priv = 9
257         }, {
258                 320,
259                 240,
260                 V4L2_PIX_FMT_SBGGR8,
261                 V4L2_FIELD_NONE,
262                 .sizeimage =
263                         320 * 240,
264                 .bytesperline = 320,
265                 .colorspace = V4L2_COLORSPACE_SRGB,
266                 .priv = 8
267         }, {
268                 352,
269                 288,
270                 V4L2_PIX_FMT_SBGGR8,
271                 V4L2_FIELD_NONE,
272                 .sizeimage =
273                         352 * 288,
274                 .bytesperline = 352,
275                 .colorspace = V4L2_COLORSPACE_SRGB,
276                 .priv = 9
277         }, {
278                 640,
279                 480,
280                 V4L2_PIX_FMT_SBGGR8,
281                 V4L2_FIELD_NONE,
282                 .sizeimage =
283                         640 * 480,
284                 .bytesperline = 640,
285                 .colorspace = V4L2_COLORSPACE_SRGB,
286                 .priv = 9
287         }
288 };
289
290 static const struct v4l2_ctrl_ops ov9650_ctrl_ops = {
291         .s_ctrl = ov9650_s_ctrl,
292 };
293
294 int ov9650_probe(struct sd *sd)
295 {
296         int err = 0;
297         u8 prod_id = 0, ver_id = 0, i;
298         struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
299
300         if (force_sensor) {
301                 if (force_sensor == OV9650_SENSOR) {
302                         pr_info("Forcing an %s sensor\n", ov9650.name);
303                         goto sensor_found;
304                 }
305                 /* If we want to force another sensor,
306                    don't try to probe this one */
307                 return -ENODEV;
308         }
309
310         gspca_dbg(gspca_dev, D_PROBE, "Probing for an ov9650 sensor\n");
311
312         /* Run the pre-init before probing the sensor */
313         for (i = 0; i < ARRAY_SIZE(preinit_ov9650) && !err; i++) {
314                 u8 data = preinit_ov9650[i][2];
315                 if (preinit_ov9650[i][0] == SENSOR)
316                         err = m5602_write_sensor(sd,
317                                 preinit_ov9650[i][1], &data, 1);
318                 else
319                         err = m5602_write_bridge(sd,
320                                 preinit_ov9650[i][1], data);
321         }
322
323         if (err < 0)
324                 return err;
325
326         if (m5602_read_sensor(sd, OV9650_PID, &prod_id, 1))
327                 return -ENODEV;
328
329         if (m5602_read_sensor(sd, OV9650_VER, &ver_id, 1))
330                 return -ENODEV;
331
332         if ((prod_id == 0x96) && (ver_id == 0x52)) {
333                 pr_info("Detected an ov9650 sensor\n");
334                 goto sensor_found;
335         }
336         return -ENODEV;
337
338 sensor_found:
339         sd->gspca_dev.cam.cam_mode = ov9650_modes;
340         sd->gspca_dev.cam.nmodes = ARRAY_SIZE(ov9650_modes);
341
342         return 0;
343 }
344
345 int ov9650_init(struct sd *sd)
346 {
347         int i, err = 0;
348         u8 data;
349
350         if (dump_sensor)
351                 ov9650_dump_registers(sd);
352
353         for (i = 0; i < ARRAY_SIZE(init_ov9650) && !err; i++) {
354                 data = init_ov9650[i][2];
355                 if (init_ov9650[i][0] == SENSOR)
356                         err = m5602_write_sensor(sd, init_ov9650[i][1],
357                                                   &data, 1);
358                 else
359                         err = m5602_write_bridge(sd, init_ov9650[i][1], data);
360         }
361
362         return 0;
363 }
364
365 int ov9650_init_controls(struct sd *sd)
366 {
367         struct v4l2_ctrl_handler *hdl = &sd->gspca_dev.ctrl_handler;
368
369         sd->gspca_dev.vdev.ctrl_handler = hdl;
370         v4l2_ctrl_handler_init(hdl, 9);
371
372         sd->auto_white_bal = v4l2_ctrl_new_std(hdl, &ov9650_ctrl_ops,
373                                                V4L2_CID_AUTO_WHITE_BALANCE,
374                                                0, 1, 1, 1);
375         sd->red_bal = v4l2_ctrl_new_std(hdl, &ov9650_ctrl_ops,
376                                         V4L2_CID_RED_BALANCE, 0, 255, 1,
377                                         RED_GAIN_DEFAULT);
378         sd->blue_bal = v4l2_ctrl_new_std(hdl, &ov9650_ctrl_ops,
379                                         V4L2_CID_BLUE_BALANCE, 0, 255, 1,
380                                         BLUE_GAIN_DEFAULT);
381
382         sd->autoexpo = v4l2_ctrl_new_std_menu(hdl, &ov9650_ctrl_ops,
383                           V4L2_CID_EXPOSURE_AUTO, 1, 0, V4L2_EXPOSURE_AUTO);
384         sd->expo = v4l2_ctrl_new_std(hdl, &ov9650_ctrl_ops, V4L2_CID_EXPOSURE,
385                           0, 0x1ff, 4, EXPOSURE_DEFAULT);
386
387         sd->autogain = v4l2_ctrl_new_std(hdl, &ov9650_ctrl_ops,
388                                          V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
389         sd->gain = v4l2_ctrl_new_std(hdl, &ov9650_ctrl_ops, V4L2_CID_GAIN, 0,
390                                      0x3ff, 1, GAIN_DEFAULT);
391
392         sd->hflip = v4l2_ctrl_new_std(hdl, &ov9650_ctrl_ops, V4L2_CID_HFLIP,
393                                       0, 1, 1, 0);
394         sd->vflip = v4l2_ctrl_new_std(hdl, &ov9650_ctrl_ops, V4L2_CID_VFLIP,
395                                       0, 1, 1, 0);
396
397         if (hdl->error) {
398                 pr_err("Could not initialize controls\n");
399                 return hdl->error;
400         }
401
402         v4l2_ctrl_auto_cluster(3, &sd->auto_white_bal, 0, false);
403         v4l2_ctrl_auto_cluster(2, &sd->autoexpo, 0, false);
404         v4l2_ctrl_auto_cluster(2, &sd->autogain, 0, false);
405         v4l2_ctrl_cluster(2, &sd->hflip);
406
407         return 0;
408 }
409
410 int ov9650_start(struct sd *sd)
411 {
412         u8 data;
413         int i, err = 0;
414         struct cam *cam = &sd->gspca_dev.cam;
415
416         int width = cam->cam_mode[sd->gspca_dev.curr_mode].width;
417         int height = cam->cam_mode[sd->gspca_dev.curr_mode].height;
418         int ver_offs = cam->cam_mode[sd->gspca_dev.curr_mode].priv;
419         int hor_offs = OV9650_LEFT_OFFSET;
420         struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
421
422         if ((!dmi_check_system(ov9650_flip_dmi_table) &&
423                 sd->vflip->val) ||
424                 (dmi_check_system(ov9650_flip_dmi_table) &&
425                 !sd->vflip->val))
426                 ver_offs--;
427
428         if (width <= 320)
429                 hor_offs /= 2;
430
431         /* Synthesize the vsync/hsync setup */
432         for (i = 0; i < ARRAY_SIZE(res_init_ov9650) && !err; i++) {
433                 if (res_init_ov9650[i][0] == BRIDGE)
434                         err = m5602_write_bridge(sd, res_init_ov9650[i][1],
435                                 res_init_ov9650[i][2]);
436                 else if (res_init_ov9650[i][0] == SENSOR) {
437                         data = res_init_ov9650[i][2];
438                         err = m5602_write_sensor(sd,
439                                 res_init_ov9650[i][1], &data, 1);
440                 }
441         }
442         if (err < 0)
443                 return err;
444
445         err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA,
446                                  ((ver_offs >> 8) & 0xff));
447         if (err < 0)
448                 return err;
449
450         err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (ver_offs & 0xff));
451         if (err < 0)
452                 return err;
453
454         err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0);
455         if (err < 0)
456                 return err;
457
458         err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height >> 8) & 0xff);
459         if (err < 0)
460                 return err;
461
462         err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height & 0xff));
463         if (err < 0)
464                 return err;
465
466         for (i = 0; i < 2 && !err; i++)
467                 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0);
468         if (err < 0)
469                 return err;
470
471         err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0);
472         if (err < 0)
473                 return err;
474
475         err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 2);
476         if (err < 0)
477                 return err;
478
479         err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA,
480                                  (hor_offs >> 8) & 0xff);
481         if (err < 0)
482                 return err;
483
484         err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, hor_offs & 0xff);
485         if (err < 0)
486                 return err;
487
488         err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA,
489                                  ((width + hor_offs) >> 8) & 0xff);
490         if (err < 0)
491                 return err;
492
493         err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA,
494                                  ((width + hor_offs) & 0xff));
495         if (err < 0)
496                 return err;
497
498         err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0);
499         if (err < 0)
500                 return err;
501
502         switch (width) {
503         case 640:
504                 gspca_dbg(gspca_dev, D_CONF, "Configuring camera for VGA mode\n");
505
506                 data = OV9650_VGA_SELECT | OV9650_RGB_SELECT |
507                        OV9650_RAW_RGB_SELECT;
508                 err = m5602_write_sensor(sd, OV9650_COM7, &data, 1);
509                 break;
510
511         case 352:
512                 gspca_dbg(gspca_dev, D_CONF, "Configuring camera for CIF mode\n");
513
514                 data = OV9650_CIF_SELECT | OV9650_RGB_SELECT |
515                                 OV9650_RAW_RGB_SELECT;
516                 err = m5602_write_sensor(sd, OV9650_COM7, &data, 1);
517                 break;
518
519         case 320:
520                 gspca_dbg(gspca_dev, D_CONF, "Configuring camera for QVGA mode\n");
521
522                 data = OV9650_QVGA_SELECT | OV9650_RGB_SELECT |
523                                 OV9650_RAW_RGB_SELECT;
524                 err = m5602_write_sensor(sd, OV9650_COM7, &data, 1);
525                 break;
526
527         case 176:
528                 gspca_dbg(gspca_dev, D_CONF, "Configuring camera for QCIF mode\n");
529
530                 data = OV9650_QCIF_SELECT | OV9650_RGB_SELECT |
531                         OV9650_RAW_RGB_SELECT;
532                 err = m5602_write_sensor(sd, OV9650_COM7, &data, 1);
533                 break;
534         }
535         return err;
536 }
537
538 int ov9650_stop(struct sd *sd)
539 {
540         u8 data = OV9650_SOFT_SLEEP | OV9650_OUTPUT_DRIVE_2X;
541         return m5602_write_sensor(sd, OV9650_COM2, &data, 1);
542 }
543
544 void ov9650_disconnect(struct sd *sd)
545 {
546         ov9650_stop(sd);
547
548         sd->sensor = NULL;
549 }
550
551 static int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
552 {
553         struct sd *sd = (struct sd *) gspca_dev;
554         u8 i2c_data;
555         int err;
556
557         gspca_dbg(gspca_dev, D_CONF, "Set exposure to %d\n", val);
558
559         /* The 6 MSBs */
560         i2c_data = (val >> 10) & 0x3f;
561         err = m5602_write_sensor(sd, OV9650_AECHM,
562                                   &i2c_data, 1);
563         if (err < 0)
564                 return err;
565
566         /* The 8 middle bits */
567         i2c_data = (val >> 2) & 0xff;
568         err = m5602_write_sensor(sd, OV9650_AECH,
569                                   &i2c_data, 1);
570         if (err < 0)
571                 return err;
572
573         /* The 2 LSBs */
574         i2c_data = val & 0x03;
575         err = m5602_write_sensor(sd, OV9650_COM1, &i2c_data, 1);
576         return err;
577 }
578
579 static int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val)
580 {
581         int err;
582         u8 i2c_data;
583         struct sd *sd = (struct sd *) gspca_dev;
584
585         gspca_dbg(gspca_dev, D_CONF, "Setting gain to %d\n", val);
586
587         /* The 2 MSB */
588         /* Read the OV9650_VREF register first to avoid
589            corrupting the VREF high and low bits */
590         err = m5602_read_sensor(sd, OV9650_VREF, &i2c_data, 1);
591         if (err < 0)
592                 return err;
593
594         /* Mask away all uninteresting bits */
595         i2c_data = ((val & 0x0300) >> 2) |
596                         (i2c_data & 0x3f);
597         err = m5602_write_sensor(sd, OV9650_VREF, &i2c_data, 1);
598         if (err < 0)
599                 return err;
600
601         /* The 8 LSBs */
602         i2c_data = val & 0xff;
603         err = m5602_write_sensor(sd, OV9650_GAIN, &i2c_data, 1);
604         return err;
605 }
606
607 static int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
608 {
609         int err;
610         u8 i2c_data;
611         struct sd *sd = (struct sd *) gspca_dev;
612
613         gspca_dbg(gspca_dev, D_CONF, "Set red gain to %d\n", val);
614
615         i2c_data = val & 0xff;
616         err = m5602_write_sensor(sd, OV9650_RED, &i2c_data, 1);
617         return err;
618 }
619
620 static int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
621 {
622         int err;
623         u8 i2c_data;
624         struct sd *sd = (struct sd *) gspca_dev;
625
626         gspca_dbg(gspca_dev, D_CONF, "Set blue gain to %d\n", val);
627
628         i2c_data = val & 0xff;
629         err = m5602_write_sensor(sd, OV9650_BLUE, &i2c_data, 1);
630         return err;
631 }
632
633 static int ov9650_set_hvflip(struct gspca_dev *gspca_dev)
634 {
635         int err;
636         u8 i2c_data;
637         struct sd *sd = (struct sd *) gspca_dev;
638         int hflip = sd->hflip->val;
639         int vflip = sd->vflip->val;
640
641         gspca_dbg(gspca_dev, D_CONF, "Set hvflip to %d %d\n", hflip, vflip);
642
643         if (dmi_check_system(ov9650_flip_dmi_table))
644                 vflip = !vflip;
645
646         i2c_data = (hflip << 5) | (vflip << 4);
647         err = m5602_write_sensor(sd, OV9650_MVFP, &i2c_data, 1);
648         if (err < 0)
649                 return err;
650
651         /* When vflip is toggled we need to readjust the bridge hsync/vsync */
652         if (gspca_dev->streaming)
653                 err = ov9650_start(sd);
654
655         return err;
656 }
657
658 static int ov9650_set_auto_exposure(struct gspca_dev *gspca_dev,
659                                     __s32 val)
660 {
661         int err;
662         u8 i2c_data;
663         struct sd *sd = (struct sd *) gspca_dev;
664
665         gspca_dbg(gspca_dev, D_CONF, "Set auto exposure control to %d\n", val);
666
667         err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1);
668         if (err < 0)
669                 return err;
670
671         val = (val == V4L2_EXPOSURE_AUTO);
672         i2c_data = ((i2c_data & 0xfe) | ((val & 0x01) << 0));
673
674         return m5602_write_sensor(sd, OV9650_COM8, &i2c_data, 1);
675 }
676
677 static int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev,
678                                          __s32 val)
679 {
680         int err;
681         u8 i2c_data;
682         struct sd *sd = (struct sd *) gspca_dev;
683
684         gspca_dbg(gspca_dev, D_CONF, "Set auto white balance to %d\n", val);
685
686         err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1);
687         if (err < 0)
688                 return err;
689
690         i2c_data = ((i2c_data & 0xfd) | ((val & 0x01) << 1));
691         err = m5602_write_sensor(sd, OV9650_COM8, &i2c_data, 1);
692
693         return err;
694 }
695
696 static int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val)
697 {
698         int err;
699         u8 i2c_data;
700         struct sd *sd = (struct sd *) gspca_dev;
701
702         gspca_dbg(gspca_dev, D_CONF, "Set auto gain control to %d\n", val);
703
704         err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1);
705         if (err < 0)
706                 return err;
707
708         i2c_data = ((i2c_data & 0xfb) | ((val & 0x01) << 2));
709
710         return m5602_write_sensor(sd, OV9650_COM8, &i2c_data, 1);
711 }
712
713 static int ov9650_s_ctrl(struct v4l2_ctrl *ctrl)
714 {
715         struct gspca_dev *gspca_dev =
716                 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
717         struct sd *sd = (struct sd *) gspca_dev;
718         int err;
719
720         if (!gspca_dev->streaming)
721                 return 0;
722
723         switch (ctrl->id) {
724         case V4L2_CID_AUTO_WHITE_BALANCE:
725                 err = ov9650_set_auto_white_balance(gspca_dev, ctrl->val);
726                 if (err || ctrl->val)
727                         return err;
728                 err = ov9650_set_red_balance(gspca_dev, sd->red_bal->val);
729                 if (err)
730                         return err;
731                 err = ov9650_set_blue_balance(gspca_dev, sd->blue_bal->val);
732                 break;
733         case V4L2_CID_EXPOSURE_AUTO:
734                 err = ov9650_set_auto_exposure(gspca_dev, ctrl->val);
735                 if (err || ctrl->val == V4L2_EXPOSURE_AUTO)
736                         return err;
737                 err = ov9650_set_exposure(gspca_dev, sd->expo->val);
738                 break;
739         case V4L2_CID_AUTOGAIN:
740                 err = ov9650_set_auto_gain(gspca_dev, ctrl->val);
741                 if (err || ctrl->val)
742                         return err;
743                 err = ov9650_set_gain(gspca_dev, sd->gain->val);
744                 break;
745         case V4L2_CID_HFLIP:
746                 err = ov9650_set_hvflip(gspca_dev);
747                 break;
748         default:
749                 return -EINVAL;
750         }
751
752         return err;
753 }
754
755 static void ov9650_dump_registers(struct sd *sd)
756 {
757         int address;
758         pr_info("Dumping the ov9650 register state\n");
759         for (address = 0; address < 0xa9; address++) {
760                 u8 value;
761                 m5602_read_sensor(sd, address, &value, 1);
762                 pr_info("register 0x%x contains 0x%x\n", address, value);
763         }
764
765         pr_info("ov9650 register state dump complete\n");
766
767         pr_info("Probing for which registers that are read/write\n");
768         for (address = 0; address < 0xff; address++) {
769                 u8 old_value, ctrl_value;
770                 u8 test_value[2] = {0xff, 0xff};
771
772                 m5602_read_sensor(sd, address, &old_value, 1);
773                 m5602_write_sensor(sd, address, test_value, 1);
774                 m5602_read_sensor(sd, address, &ctrl_value, 1);
775
776                 if (ctrl_value == test_value[0])
777                         pr_info("register 0x%x is writeable\n", address);
778                 else
779                         pr_info("register 0x%x is read only\n", address);
780
781                 /* Restore original value */
782                 m5602_write_sensor(sd, address, &old_value, 1);
783         }
784 }