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