d77ec9791bfe24f93688ab226fd4c5029726c316
[pandora-kernel.git] / drivers / media / video / gspca / m5602 / m5602_ov9650.c
1 /*
2  * Driver for the ov9650 sensor
3  *
4  * Copyright (C) 2008 Erik AndrĂ©n
5  * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
6  * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
7  *
8  * Portions of code to USB interface and ALi driver software,
9  * Copyright (c) 2006 Willem Duinker
10  * v4l2 interface modeled after the V4L2 driver
11  * for SN9C10x PC Camera Controllers
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License as
15  * published by the Free Software Foundation, version 2.
16  *
17  */
18
19 #include "m5602_ov9650.h"
20
21 static int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
22 static int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
23 static int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
24 static int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val);
25 static int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val);
26 static int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val);
27 static int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val);
28 static int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val);
29 static int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
30 static int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
31 static int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
32 static int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
33 static int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev,
34                                          __s32 *val);
35 static int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev,
36                                          __s32 val);
37 static int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val);
38 static int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val);
39 static int ov9650_get_auto_exposure(struct gspca_dev *gspca_dev, __s32 *val);
40 static int ov9650_set_auto_exposure(struct gspca_dev *gspca_dev, __s32 val);
41
42 /* Vertically and horizontally flips the image if matched, needed for machines
43    where the sensor is mounted upside down */
44 static
45     const
46         struct dmi_system_id ov9650_flip_dmi_table[] = {
47         {
48                 .ident = "ASUS A6VC",
49                 .matches = {
50                         DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
51                         DMI_MATCH(DMI_PRODUCT_NAME, "A6VC")
52                 }
53         },
54         {
55                 .ident = "ASUS A6VM",
56                 .matches = {
57                         DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
58                         DMI_MATCH(DMI_PRODUCT_NAME, "A6VM")
59                 }
60         },
61         {
62                 .ident = "ASUS A6JC",
63                 .matches = {
64                         DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
65                         DMI_MATCH(DMI_PRODUCT_NAME, "A6JC")
66                 }
67         },
68         {
69                 .ident = "ASUS A6Ja",
70                 .matches = {
71                         DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
72                         DMI_MATCH(DMI_PRODUCT_NAME, "A6J")
73                 }
74         },
75         {
76                 .ident = "ASUS A6Kt",
77                 .matches = {
78                         DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
79                         DMI_MATCH(DMI_PRODUCT_NAME, "A6Kt")
80                 }
81         },
82         {
83                 .ident = "Alienware Aurora m9700",
84                 .matches = {
85                         DMI_MATCH(DMI_SYS_VENDOR, "alienware"),
86                         DMI_MATCH(DMI_PRODUCT_NAME, "Aurora m9700")
87                 }
88         },
89         {}
90 };
91
92 const static struct ctrl ov9650_ctrls[] = {
93 #define EXPOSURE_IDX 0
94         {
95                 {
96                         .id             = V4L2_CID_EXPOSURE,
97                         .type           = V4L2_CTRL_TYPE_INTEGER,
98                         .name           = "exposure",
99                         .minimum        = 0x00,
100                         .maximum        = 0x1ff,
101                         .step           = 0x4,
102                         .default_value  = EXPOSURE_DEFAULT,
103                         .flags          = V4L2_CTRL_FLAG_SLIDER
104                 },
105                 .set = ov9650_set_exposure,
106                 .get = ov9650_get_exposure
107         },
108 #define GAIN_IDX 1
109         {
110                 {
111                         .id             = V4L2_CID_GAIN,
112                         .type           = V4L2_CTRL_TYPE_INTEGER,
113                         .name           = "gain",
114                         .minimum        = 0x00,
115                         .maximum        = 0x3ff,
116                         .step           = 0x1,
117                         .default_value  = GAIN_DEFAULT,
118                         .flags          = V4L2_CTRL_FLAG_SLIDER
119                 },
120                 .set = ov9650_set_gain,
121                 .get = ov9650_get_gain
122         },
123 #define RED_BALANCE_IDX 2
124         {
125                 {
126                         .type           = V4L2_CTRL_TYPE_INTEGER,
127                         .name           = "red balance",
128                         .minimum        = 0x00,
129                         .maximum        = 0xff,
130                         .step           = 0x1,
131                         .default_value  = RED_GAIN_DEFAULT,
132                         .flags          = V4L2_CTRL_FLAG_SLIDER
133                 },
134                 .set = ov9650_set_red_balance,
135                 .get = ov9650_get_red_balance
136         },
137 #define BLUE_BALANCE_IDX 3
138         {
139                 {
140                         .type           = V4L2_CTRL_TYPE_INTEGER,
141                         .name           = "blue balance",
142                         .minimum        = 0x00,
143                         .maximum        = 0xff,
144                         .step           = 0x1,
145                         .default_value  = BLUE_GAIN_DEFAULT,
146                         .flags          = V4L2_CTRL_FLAG_SLIDER
147                 },
148                 .set = ov9650_set_blue_balance,
149                 .get = ov9650_get_blue_balance
150         },
151 #define HFLIP_IDX 4
152         {
153                 {
154                         .id             = V4L2_CID_HFLIP,
155                         .type           = V4L2_CTRL_TYPE_BOOLEAN,
156                         .name           = "horizontal flip",
157                         .minimum        = 0,
158                         .maximum        = 1,
159                         .step           = 1,
160                         .default_value  = 0
161                 },
162                 .set = ov9650_set_hflip,
163                 .get = ov9650_get_hflip
164         },
165 #define VFLIP_IDX 5
166         {
167                 {
168                         .id             = V4L2_CID_VFLIP,
169                         .type           = V4L2_CTRL_TYPE_BOOLEAN,
170                         .name           = "vertical flip",
171                         .minimum        = 0,
172                         .maximum        = 1,
173                         .step           = 1,
174                         .default_value  = 0
175                 },
176                 .set = ov9650_set_vflip,
177                 .get = ov9650_get_vflip
178         },
179 #define AUTO_WHITE_BALANCE_IDX 6
180         {
181                 {
182                         .id             = V4L2_CID_AUTO_WHITE_BALANCE,
183                         .type           = V4L2_CTRL_TYPE_BOOLEAN,
184                         .name           = "auto white balance",
185                         .minimum        = 0,
186                         .maximum        = 1,
187                         .step           = 1,
188                         .default_value  = 1
189                 },
190                 .set = ov9650_set_auto_white_balance,
191                 .get = ov9650_get_auto_white_balance
192         },
193 #define AUTO_GAIN_CTRL_IDX 7
194         {
195                 {
196                         .id             = V4L2_CID_AUTOGAIN,
197                         .type           = V4L2_CTRL_TYPE_BOOLEAN,
198                         .name           = "auto gain control",
199                         .minimum        = 0,
200                         .maximum        = 1,
201                         .step           = 1,
202                         .default_value  = 1
203                 },
204                 .set = ov9650_set_auto_gain,
205                 .get = ov9650_get_auto_gain
206         },
207 #define AUTO_EXPOSURE_IDX 8
208         {
209                 {
210                         .id             = V4L2_CID_EXPOSURE_AUTO,
211                         .type           = V4L2_CTRL_TYPE_BOOLEAN,
212                         .name           = "auto exposure",
213                         .minimum        = 0,
214                         .maximum        = 1,
215                         .step           = 1,
216                         .default_value  = 1
217                 },
218                 .set = ov9650_set_auto_exposure,
219                 .get = ov9650_get_auto_exposure
220         }
221
222 };
223
224 static struct v4l2_pix_format ov9650_modes[] = {
225         {
226                 176,
227                 144,
228                 V4L2_PIX_FMT_SBGGR8,
229                 V4L2_FIELD_NONE,
230                 .sizeimage =
231                         176 * 144,
232                 .bytesperline = 176,
233                 .colorspace = V4L2_COLORSPACE_SRGB,
234                 .priv = 9
235         }, {
236                 320,
237                 240,
238                 V4L2_PIX_FMT_SBGGR8,
239                 V4L2_FIELD_NONE,
240                 .sizeimage =
241                         320 * 240,
242                 .bytesperline = 320,
243                 .colorspace = V4L2_COLORSPACE_SRGB,
244                 .priv = 8
245         }, {
246                 352,
247                 288,
248                 V4L2_PIX_FMT_SBGGR8,
249                 V4L2_FIELD_NONE,
250                 .sizeimage =
251                         352 * 288,
252                 .bytesperline = 352,
253                 .colorspace = V4L2_COLORSPACE_SRGB,
254                 .priv = 9
255         }, {
256                 640,
257                 480,
258                 V4L2_PIX_FMT_SBGGR8,
259                 V4L2_FIELD_NONE,
260                 .sizeimage =
261                         640 * 480,
262                 .bytesperline = 640,
263                 .colorspace = V4L2_COLORSPACE_SRGB,
264                 .priv = 9
265         }
266 };
267
268 static void ov9650_dump_registers(struct sd *sd);
269
270 int ov9650_probe(struct sd *sd)
271 {
272         int err = 0;
273         u8 prod_id = 0, ver_id = 0, i;
274         s32 *sensor_settings;
275
276         if (force_sensor) {
277                 if (force_sensor == OV9650_SENSOR) {
278                         info("Forcing an %s sensor", ov9650.name);
279                         goto sensor_found;
280                 }
281                 /* If we want to force another sensor,
282                    don't try to probe this one */
283                 return -ENODEV;
284         }
285
286         info("Probing for an ov9650 sensor");
287
288         /* Run the pre-init before probing the sensor */
289         for (i = 0; i < ARRAY_SIZE(preinit_ov9650) && !err; i++) {
290                 u8 data = preinit_ov9650[i][2];
291                 if (preinit_ov9650[i][0] == SENSOR)
292                         err = m5602_write_sensor(sd,
293                                 preinit_ov9650[i][1], &data, 1);
294                 else
295                         err = m5602_write_bridge(sd,
296                                 preinit_ov9650[i][1], data);
297         }
298
299         if (err < 0)
300                 return err;
301
302         if (m5602_read_sensor(sd, OV9650_PID, &prod_id, 1))
303                 return -ENODEV;
304
305         if (m5602_read_sensor(sd, OV9650_VER, &ver_id, 1))
306                 return -ENODEV;
307
308         if ((prod_id == 0x96) && (ver_id == 0x52)) {
309                 info("Detected an ov9650 sensor");
310                 goto sensor_found;
311         }
312         return -ENODEV;
313
314 sensor_found:
315         sensor_settings = kmalloc(
316                 ARRAY_SIZE(ov9650_ctrls) * sizeof(s32), GFP_KERNEL);
317         if (!sensor_settings)
318                 return -ENOMEM;
319
320         sd->gspca_dev.cam.cam_mode = ov9650_modes;
321         sd->gspca_dev.cam.nmodes = ARRAY_SIZE(ov9650_modes);
322         sd->desc->ctrls = ov9650_ctrls;
323         sd->desc->nctrls = ARRAY_SIZE(ov9650_ctrls);
324
325         for (i = 0; i < ARRAY_SIZE(ov9650_ctrls); i++)
326                 sensor_settings[i] = ov9650_ctrls[i].qctrl.default_value;
327         sd->sensor_priv = sensor_settings;
328         return 0;
329 }
330
331 int ov9650_init(struct sd *sd)
332 {
333         int i, err = 0;
334         u8 data;
335         s32 *sensor_settings = sd->sensor_priv;
336
337         if (dump_sensor)
338                 ov9650_dump_registers(sd);
339
340         for (i = 0; i < ARRAY_SIZE(init_ov9650) && !err; i++) {
341                 data = init_ov9650[i][2];
342                 if (init_ov9650[i][0] == SENSOR)
343                         err = m5602_write_sensor(sd, init_ov9650[i][1],
344                                                   &data, 1);
345                 else
346                         err = m5602_write_bridge(sd, init_ov9650[i][1], data);
347         }
348
349         err = ov9650_set_exposure(&sd->gspca_dev,
350                                    sensor_settings[EXPOSURE_IDX]);
351         if (err < 0)
352                 return err;
353
354         err = ov9650_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]);
355         if (err < 0)
356                 return err;
357
358         err = ov9650_set_red_balance(&sd->gspca_dev,
359                                       sensor_settings[RED_BALANCE_IDX]);
360         if (err < 0)
361                 return err;
362
363         err = ov9650_set_blue_balance(&sd->gspca_dev,
364                                        sensor_settings[BLUE_BALANCE_IDX]);
365         if (err < 0)
366                 return err;
367
368         err = ov9650_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]);
369         if (err < 0)
370                 return err;
371
372         err = ov9650_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]);
373         if (err < 0)
374                 return err;
375
376         err = ov9650_set_auto_exposure(&sd->gspca_dev,
377                                 sensor_settings[AUTO_EXPOSURE_IDX]);
378         if (err < 0)
379                 return err;
380
381         err = ov9650_set_auto_white_balance(&sd->gspca_dev,
382                                 sensor_settings[AUTO_WHITE_BALANCE_IDX]);
383         if (err < 0)
384                 return err;
385
386         err = ov9650_set_auto_gain(&sd->gspca_dev,
387                                 sensor_settings[AUTO_GAIN_CTRL_IDX]);
388         return err;
389 }
390
391 int ov9650_start(struct sd *sd)
392 {
393         u8 data;
394         int i, err = 0;
395         struct cam *cam = &sd->gspca_dev.cam;
396         s32 *sensor_settings = sd->sensor_priv;
397
398         int width = cam->cam_mode[sd->gspca_dev.curr_mode].width;
399         int height = cam->cam_mode[sd->gspca_dev.curr_mode].height;
400         int ver_offs = cam->cam_mode[sd->gspca_dev.curr_mode].priv;
401         int hor_offs = OV9650_LEFT_OFFSET;
402
403         if ((!dmi_check_system(ov9650_flip_dmi_table) &&
404                 sensor_settings[VFLIP_IDX]) ||
405                 (dmi_check_system(ov9650_flip_dmi_table) &&
406                 !sensor_settings[VFLIP_IDX]))
407                 ver_offs--;
408
409         if (width <= 320)
410                 hor_offs /= 2;
411
412         /* Synthesize the vsync/hsync setup */
413         for (i = 0; i < ARRAY_SIZE(res_init_ov9650) && !err; i++) {
414                 if (res_init_ov9650[i][0] == BRIDGE)
415                         err = m5602_write_bridge(sd, res_init_ov9650[i][1],
416                                 res_init_ov9650[i][2]);
417                 else if (res_init_ov9650[i][0] == SENSOR) {
418                         u8 data = res_init_ov9650[i][2];
419                         err = m5602_write_sensor(sd,
420                                 res_init_ov9650[i][1], &data, 1);
421                 }
422         }
423         if (err < 0)
424                 return err;
425
426         err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA,
427                                  ((ver_offs >> 8) & 0xff));
428         if (err < 0)
429                 return err;
430
431         err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (ver_offs & 0xff));
432         if (err < 0)
433                 return err;
434
435         err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0);
436         if (err < 0)
437                 return err;
438
439         err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height >> 8) & 0xff);
440         if (err < 0)
441                 return err;
442
443         err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height & 0xff));
444         if (err < 0)
445                 return err;
446
447         for (i = 0; i < 2 && !err; i++)
448                 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0);
449         if (err < 0)
450                 return err;
451
452         err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0);
453         if (err < 0)
454                 return err;
455
456         err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 2);
457         if (err < 0)
458                 return err;
459
460         err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA,
461                                  (hor_offs >> 8) & 0xff);
462         if (err < 0)
463                 return err;
464
465         err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, hor_offs & 0xff);
466         if (err < 0)
467                 return err;
468
469         err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA,
470                                  ((width + hor_offs) >> 8) & 0xff);
471         if (err < 0)
472                 return err;
473
474         err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA,
475                                  ((width + hor_offs) & 0xff));
476         if (err < 0)
477                 return err;
478
479         err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0);
480         if (err < 0)
481                 return err;
482
483         switch (width) {
484         case 640:
485                 PDEBUG(D_V4L2, "Configuring camera for VGA mode");
486
487                 data = OV9650_VGA_SELECT | OV9650_RGB_SELECT |
488                        OV9650_RAW_RGB_SELECT;
489                 err = m5602_write_sensor(sd, OV9650_COM7, &data, 1);
490                 break;
491
492         case 352:
493                 PDEBUG(D_V4L2, "Configuring camera for CIF mode");
494
495                 data = OV9650_CIF_SELECT | OV9650_RGB_SELECT |
496                                 OV9650_RAW_RGB_SELECT;
497                 err = m5602_write_sensor(sd, OV9650_COM7, &data, 1);
498                 break;
499
500         case 320:
501                 PDEBUG(D_V4L2, "Configuring camera for QVGA mode");
502
503                 data = OV9650_QVGA_SELECT | OV9650_RGB_SELECT |
504                                 OV9650_RAW_RGB_SELECT;
505                 err = m5602_write_sensor(sd, OV9650_COM7, &data, 1);
506                 break;
507
508         case 176:
509                 PDEBUG(D_V4L2, "Configuring camera for QCIF mode");
510
511                 data = OV9650_QCIF_SELECT | OV9650_RGB_SELECT |
512                         OV9650_RAW_RGB_SELECT;
513                 err = m5602_write_sensor(sd, OV9650_COM7, &data, 1);
514                 break;
515         }
516         return err;
517 }
518
519 int ov9650_stop(struct sd *sd)
520 {
521         u8 data = OV9650_SOFT_SLEEP | OV9650_OUTPUT_DRIVE_2X;
522         return m5602_write_sensor(sd, OV9650_COM2, &data, 1);
523 }
524
525 void ov9650_disconnect(struct sd *sd)
526 {
527         ov9650_stop(sd);
528
529         sd->sensor = NULL;
530         kfree(sd->sensor_priv);
531 }
532
533 static int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
534 {
535         struct sd *sd = (struct sd *) gspca_dev;
536         s32 *sensor_settings = sd->sensor_priv;
537
538         *val = sensor_settings[EXPOSURE_IDX];
539         PDEBUG(D_V4L2, "Read exposure %d", *val);
540         return 0;
541 }
542
543 static int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
544 {
545         struct sd *sd = (struct sd *) gspca_dev;
546         s32 *sensor_settings = sd->sensor_priv;
547         u8 i2c_data;
548         int err;
549
550         PDEBUG(D_V4L2, "Set exposure to %d", val);
551
552         sensor_settings[EXPOSURE_IDX] = val;
553         /* The 6 MSBs */
554         i2c_data = (val >> 10) & 0x3f;
555         err = m5602_write_sensor(sd, OV9650_AECHM,
556                                   &i2c_data, 1);
557         if (err < 0)
558                 return err;
559
560         /* The 8 middle bits */
561         i2c_data = (val >> 2) & 0xff;
562         err = m5602_write_sensor(sd, OV9650_AECH,
563                                   &i2c_data, 1);
564         if (err < 0)
565                 return err;
566
567         /* The 2 LSBs */
568         i2c_data = val & 0x03;
569         err = m5602_write_sensor(sd, OV9650_COM1, &i2c_data, 1);
570         return err;
571 }
572
573 static int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
574 {
575         struct sd *sd = (struct sd *) gspca_dev;
576         s32 *sensor_settings = sd->sensor_priv;
577
578         *val = sensor_settings[GAIN_IDX];
579         PDEBUG(D_V4L2, "Read gain %d", *val);
580         return 0;
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         s32 *sensor_settings = sd->sensor_priv;
589
590         PDEBUG(D_V4L2, "Setting gain to %d", val);
591
592         sensor_settings[GAIN_IDX] = val;
593
594         /* The 2 MSB */
595         /* Read the OV9650_VREF register first to avoid
596            corrupting the VREF high and low bits */
597         err = m5602_read_sensor(sd, OV9650_VREF, &i2c_data, 1);
598         if (err < 0)
599                 return err;
600
601         /* Mask away all uninteresting bits */
602         i2c_data = ((val & 0x0300) >> 2) |
603                         (i2c_data & 0x3F);
604         err = m5602_write_sensor(sd, OV9650_VREF, &i2c_data, 1);
605         if (err < 0)
606                 return err;
607
608         /* The 8 LSBs */
609         i2c_data = val & 0xff;
610         err = m5602_write_sensor(sd, OV9650_GAIN, &i2c_data, 1);
611         return err;
612 }
613
614 static int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
615 {
616         struct sd *sd = (struct sd *) gspca_dev;
617         s32 *sensor_settings = sd->sensor_priv;
618
619         *val = sensor_settings[RED_BALANCE_IDX];
620         PDEBUG(D_V4L2, "Read red gain %d", *val);
621         return 0;
622 }
623
624 static int ov9650_set_red_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         s32 *sensor_settings = sd->sensor_priv;
630
631         PDEBUG(D_V4L2, "Set red gain to %d", val);
632
633         sensor_settings[RED_BALANCE_IDX] = val;
634
635         i2c_data = val & 0xff;
636         err = m5602_write_sensor(sd, OV9650_RED, &i2c_data, 1);
637         return err;
638 }
639
640 static int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
641 {
642         struct sd *sd = (struct sd *) gspca_dev;
643         s32 *sensor_settings = sd->sensor_priv;
644
645         *val = sensor_settings[BLUE_BALANCE_IDX];
646         PDEBUG(D_V4L2, "Read blue gain %d", *val);
647
648         return 0;
649 }
650
651 static int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
652 {
653         int err;
654         u8 i2c_data;
655         struct sd *sd = (struct sd *) gspca_dev;
656         s32 *sensor_settings = sd->sensor_priv;
657
658         PDEBUG(D_V4L2, "Set blue gain to %d", val);
659
660         sensor_settings[BLUE_BALANCE_IDX] = val;
661
662         i2c_data = val & 0xff;
663         err = m5602_write_sensor(sd, OV9650_BLUE, &i2c_data, 1);
664         return err;
665 }
666
667 static int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
668 {
669         struct sd *sd = (struct sd *) gspca_dev;
670         s32 *sensor_settings = sd->sensor_priv;
671
672         *val = sensor_settings[HFLIP_IDX];
673         PDEBUG(D_V4L2, "Read horizontal flip %d", *val);
674         return 0;
675 }
676
677 static int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
678 {
679         int err;
680         u8 i2c_data;
681         struct sd *sd = (struct sd *) gspca_dev;
682         s32 *sensor_settings = sd->sensor_priv;
683
684         PDEBUG(D_V4L2, "Set horizontal flip to %d", val);
685
686         sensor_settings[HFLIP_IDX] = val;
687
688         if (!dmi_check_system(ov9650_flip_dmi_table))
689                 i2c_data = ((val & 0x01) << 5) |
690                                 (sensor_settings[VFLIP_IDX] << 4);
691         else
692                 i2c_data = ((val & 0x01) << 5) |
693                                 (!sensor_settings[VFLIP_IDX] << 4);
694
695         err = m5602_write_sensor(sd, OV9650_MVFP, &i2c_data, 1);
696
697         return err;
698 }
699
700 static int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
701 {
702         struct sd *sd = (struct sd *) gspca_dev;
703         s32 *sensor_settings = sd->sensor_priv;
704
705         *val = sensor_settings[VFLIP_IDX];
706         PDEBUG(D_V4L2, "Read vertical flip %d", *val);
707
708         return 0;
709 }
710
711 static int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
712 {
713         int err;
714         u8 i2c_data;
715         struct sd *sd = (struct sd *) gspca_dev;
716         s32 *sensor_settings = sd->sensor_priv;
717
718         PDEBUG(D_V4L2, "Set vertical flip to %d", val);
719         sensor_settings[VFLIP_IDX] = val;
720
721         if (dmi_check_system(ov9650_flip_dmi_table))
722                 val = !val;
723
724         i2c_data = ((val & 0x01) << 4) | (sensor_settings[VFLIP_IDX] << 5);
725         err = m5602_write_sensor(sd, OV9650_MVFP, &i2c_data, 1);
726         if (err < 0)
727                 return err;
728
729         /* When vflip is toggled we need to readjust the bridge hsync/vsync */
730         if (gspca_dev->streaming)
731                 err = ov9650_start(sd);
732
733         return err;
734 }
735
736 static int ov9650_get_auto_exposure(struct gspca_dev *gspca_dev, __s32 *val)
737 {
738         struct sd *sd = (struct sd *) gspca_dev;
739         s32 *sensor_settings = sd->sensor_priv;
740
741         *val = sensor_settings[AUTO_EXPOSURE_IDX];
742         PDEBUG(D_V4L2, "Read auto exposure control %d", *val);
743         return 0;
744 }
745
746 static int ov9650_set_auto_exposure(struct gspca_dev *gspca_dev,
747                                     __s32 val)
748 {
749         int err;
750         u8 i2c_data;
751         struct sd *sd = (struct sd *) gspca_dev;
752         s32 *sensor_settings = sd->sensor_priv;
753
754         PDEBUG(D_V4L2, "Set auto exposure control to %d", val);
755
756         sensor_settings[AUTO_EXPOSURE_IDX] = val;
757         err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1);
758         if (err < 0)
759                 return err;
760
761         i2c_data = ((i2c_data & 0xfe) | ((val & 0x01) << 0));
762
763         return m5602_write_sensor(sd, OV9650_COM8, &i2c_data, 1);
764 }
765
766 static int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev,
767                                          __s32 *val)
768 {
769         struct sd *sd = (struct sd *) gspca_dev;
770         s32 *sensor_settings = sd->sensor_priv;
771
772         *val = sensor_settings[AUTO_WHITE_BALANCE_IDX];
773         return 0;
774 }
775
776 static int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev,
777                                          __s32 val)
778 {
779         int err;
780         u8 i2c_data;
781         struct sd *sd = (struct sd *) gspca_dev;
782         s32 *sensor_settings = sd->sensor_priv;
783
784         PDEBUG(D_V4L2, "Set auto white balance to %d", val);
785
786         sensor_settings[AUTO_WHITE_BALANCE_IDX] = val;
787         err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1);
788         if (err < 0)
789                 return err;
790
791         i2c_data = ((i2c_data & 0xfd) | ((val & 0x01) << 1));
792         err = m5602_write_sensor(sd, OV9650_COM8, &i2c_data, 1);
793
794         return err;
795 }
796
797 static int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val)
798 {
799         struct sd *sd = (struct sd *) gspca_dev;
800         s32 *sensor_settings = sd->sensor_priv;
801
802         *val = sensor_settings[AUTO_GAIN_CTRL_IDX];
803         PDEBUG(D_V4L2, "Read auto gain control %d", *val);
804         return 0;
805 }
806
807 static int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val)
808 {
809         int err;
810         u8 i2c_data;
811         struct sd *sd = (struct sd *) gspca_dev;
812         s32 *sensor_settings = sd->sensor_priv;
813
814         PDEBUG(D_V4L2, "Set auto gain control to %d", val);
815
816         sensor_settings[AUTO_GAIN_CTRL_IDX] = val;
817         err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1);
818         if (err < 0)
819                 return err;
820
821         i2c_data = ((i2c_data & 0xfb) | ((val & 0x01) << 2));
822
823         return m5602_write_sensor(sd, OV9650_COM8, &i2c_data, 1);
824 }
825
826 static void ov9650_dump_registers(struct sd *sd)
827 {
828         int address;
829         info("Dumping the ov9650 register state");
830         for (address = 0; address < 0xa9; address++) {
831                 u8 value;
832                 m5602_read_sensor(sd, address, &value, 1);
833                 info("register 0x%x contains 0x%x",
834                      address, value);
835         }
836
837         info("ov9650 register state dump complete");
838
839         info("Probing for which registers that are read/write");
840         for (address = 0; address < 0xff; address++) {
841                 u8 old_value, ctrl_value;
842                 u8 test_value[2] = {0xff, 0xff};
843
844                 m5602_read_sensor(sd, address, &old_value, 1);
845                 m5602_write_sensor(sd, address, test_value, 1);
846                 m5602_read_sensor(sd, address, &ctrl_value, 1);
847
848                 if (ctrl_value == test_value[0])
849                         info("register 0x%x is writeable", address);
850                 else
851                         info("register 0x%x is read only", address);
852
853                 /* Restore original value */
854                 m5602_write_sensor(sd, address, &old_value, 1);
855         }
856 }