packaging: release out (3.8.3)
[profile/ivi/kernel-adaptation-intel-automotive.git] / drivers / media / usb / gspca / m5602 / m5602_ov7660.c
1 /*
2  * Driver for the ov7660 sensor
3  *
4  * Copyright (C) 2009 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 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
20
21 #include "m5602_ov7660.h"
22
23 static int ov7660_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
24 static int ov7660_set_gain(struct gspca_dev *gspca_dev, __s32 val);
25 static int ov7660_get_auto_white_balance(struct gspca_dev *gspca_dev,
26                                          __s32 *val);
27 static int ov7660_set_auto_white_balance(struct gspca_dev *gspca_dev,
28                                          __s32 val);
29 static int ov7660_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val);
30 static int ov7660_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val);
31 static int ov7660_get_auto_exposure(struct gspca_dev *gspca_dev, __s32 *val);
32 static int ov7660_set_auto_exposure(struct gspca_dev *gspca_dev, __s32 val);
33 static int ov7660_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
34 static int ov7660_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
35 static int ov7660_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
36 static int ov7660_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
37
38 static const struct ctrl ov7660_ctrls[] = {
39 #define GAIN_IDX 1
40         {
41                 {
42                         .id             = V4L2_CID_GAIN,
43                         .type           = V4L2_CTRL_TYPE_INTEGER,
44                         .name           = "gain",
45                         .minimum        = 0x00,
46                         .maximum        = 0xff,
47                         .step           = 0x1,
48                         .default_value  = OV7660_DEFAULT_GAIN,
49                         .flags          = V4L2_CTRL_FLAG_SLIDER
50                 },
51                 .set = ov7660_set_gain,
52                 .get = ov7660_get_gain
53         },
54 #define BLUE_BALANCE_IDX 2
55 #define RED_BALANCE_IDX 3
56 #define AUTO_WHITE_BALANCE_IDX 4
57         {
58                 {
59                         .id             = V4L2_CID_AUTO_WHITE_BALANCE,
60                         .type           = V4L2_CTRL_TYPE_BOOLEAN,
61                         .name           = "auto white balance",
62                         .minimum        = 0,
63                         .maximum        = 1,
64                         .step           = 1,
65                         .default_value  = 1
66                 },
67                 .set = ov7660_set_auto_white_balance,
68                 .get = ov7660_get_auto_white_balance
69         },
70 #define AUTO_GAIN_CTRL_IDX 5
71         {
72                 {
73                         .id             = V4L2_CID_AUTOGAIN,
74                         .type           = V4L2_CTRL_TYPE_BOOLEAN,
75                         .name           = "auto gain control",
76                         .minimum        = 0,
77                         .maximum        = 1,
78                         .step           = 1,
79                         .default_value  = 1
80                 },
81                 .set = ov7660_set_auto_gain,
82                 .get = ov7660_get_auto_gain
83         },
84 #define AUTO_EXPOSURE_IDX 6
85         {
86                 {
87                         .id             = V4L2_CID_EXPOSURE_AUTO,
88                         .type           = V4L2_CTRL_TYPE_BOOLEAN,
89                         .name           = "auto exposure",
90                         .minimum        = 0,
91                         .maximum        = 1,
92                         .step           = 1,
93                         .default_value  = 1
94                 },
95                 .set = ov7660_set_auto_exposure,
96                 .get = ov7660_get_auto_exposure
97         },
98 #define HFLIP_IDX 7
99         {
100                 {
101                         .id             = V4L2_CID_HFLIP,
102                         .type           = V4L2_CTRL_TYPE_BOOLEAN,
103                         .name           = "horizontal flip",
104                         .minimum        = 0,
105                         .maximum        = 1,
106                         .step           = 1,
107                         .default_value  = 0
108                 },
109                 .set = ov7660_set_hflip,
110                 .get = ov7660_get_hflip
111         },
112 #define VFLIP_IDX 8
113         {
114                 {
115                         .id             = V4L2_CID_VFLIP,
116                         .type           = V4L2_CTRL_TYPE_BOOLEAN,
117                         .name           = "vertical flip",
118                         .minimum        = 0,
119                         .maximum        = 1,
120                         .step           = 1,
121                         .default_value  = 0
122                 },
123                 .set = ov7660_set_vflip,
124                 .get = ov7660_get_vflip
125         },
126
127 };
128
129 static struct v4l2_pix_format ov7660_modes[] = {
130         {
131                 640,
132                 480,
133                 V4L2_PIX_FMT_SBGGR8,
134                 V4L2_FIELD_NONE,
135                 .sizeimage =
136                         640 * 480,
137                 .bytesperline = 640,
138                 .colorspace = V4L2_COLORSPACE_SRGB,
139                 .priv = 0
140         }
141 };
142
143 static void ov7660_dump_registers(struct sd *sd);
144
145 int ov7660_probe(struct sd *sd)
146 {
147         int err = 0, i;
148         u8 prod_id = 0, ver_id = 0;
149
150         s32 *sensor_settings;
151
152         if (force_sensor) {
153                 if (force_sensor == OV7660_SENSOR) {
154                         pr_info("Forcing an %s sensor\n", ov7660.name);
155                         goto sensor_found;
156                 }
157                 /* If we want to force another sensor,
158                 don't try to probe this one */
159                 return -ENODEV;
160         }
161
162         /* Do the preinit */
163         for (i = 0; i < ARRAY_SIZE(preinit_ov7660) && !err; i++) {
164                 u8 data[2];
165
166                 if (preinit_ov7660[i][0] == BRIDGE) {
167                         err = m5602_write_bridge(sd,
168                                 preinit_ov7660[i][1],
169                                 preinit_ov7660[i][2]);
170                 } else {
171                         data[0] = preinit_ov7660[i][2];
172                         err = m5602_write_sensor(sd,
173                                 preinit_ov7660[i][1], data, 1);
174                 }
175         }
176         if (err < 0)
177                 return err;
178
179         if (m5602_read_sensor(sd, OV7660_PID, &prod_id, 1))
180                 return -ENODEV;
181
182         if (m5602_read_sensor(sd, OV7660_VER, &ver_id, 1))
183                 return -ENODEV;
184
185         pr_info("Sensor reported 0x%x%x\n", prod_id, ver_id);
186
187         if ((prod_id == 0x76) && (ver_id == 0x60)) {
188                 pr_info("Detected a ov7660 sensor\n");
189                 goto sensor_found;
190         }
191         return -ENODEV;
192
193 sensor_found:
194         sensor_settings = kmalloc(
195                 ARRAY_SIZE(ov7660_ctrls) * sizeof(s32), GFP_KERNEL);
196         if (!sensor_settings)
197                 return -ENOMEM;
198
199         sd->gspca_dev.cam.cam_mode = ov7660_modes;
200         sd->gspca_dev.cam.nmodes = ARRAY_SIZE(ov7660_modes);
201         sd->desc->ctrls = ov7660_ctrls;
202         sd->desc->nctrls = ARRAY_SIZE(ov7660_ctrls);
203
204         for (i = 0; i < ARRAY_SIZE(ov7660_ctrls); i++)
205                 sensor_settings[i] = ov7660_ctrls[i].qctrl.default_value;
206         sd->sensor_priv = sensor_settings;
207
208         return 0;
209 }
210
211 int ov7660_init(struct sd *sd)
212 {
213         int i, err = 0;
214         s32 *sensor_settings = sd->sensor_priv;
215
216         /* Init the sensor */
217         for (i = 0; i < ARRAY_SIZE(init_ov7660); i++) {
218                 u8 data[2];
219
220                 if (init_ov7660[i][0] == BRIDGE) {
221                         err = m5602_write_bridge(sd,
222                                 init_ov7660[i][1],
223                                 init_ov7660[i][2]);
224                 } else {
225                         data[0] = init_ov7660[i][2];
226                         err = m5602_write_sensor(sd,
227                                 init_ov7660[i][1], data, 1);
228                 }
229         }
230
231         if (dump_sensor)
232                 ov7660_dump_registers(sd);
233
234         err = ov7660_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]);
235         if (err < 0)
236                 return err;
237
238         err = ov7660_set_auto_white_balance(&sd->gspca_dev,
239                 sensor_settings[AUTO_WHITE_BALANCE_IDX]);
240         if (err < 0)
241                 return err;
242
243         err = ov7660_set_auto_gain(&sd->gspca_dev,
244                 sensor_settings[AUTO_GAIN_CTRL_IDX]);
245         if (err < 0)
246                 return err;
247
248         err = ov7660_set_auto_exposure(&sd->gspca_dev,
249                 sensor_settings[AUTO_EXPOSURE_IDX]);
250         if (err < 0)
251                 return err;
252         err = ov7660_set_hflip(&sd->gspca_dev,
253                 sensor_settings[HFLIP_IDX]);
254         if (err < 0)
255                 return err;
256
257         err = ov7660_set_vflip(&sd->gspca_dev,
258                 sensor_settings[VFLIP_IDX]);
259
260         return err;
261 }
262
263 int ov7660_start(struct sd *sd)
264 {
265         return 0;
266 }
267
268 int ov7660_stop(struct sd *sd)
269 {
270         return 0;
271 }
272
273 void ov7660_disconnect(struct sd *sd)
274 {
275         ov7660_stop(sd);
276
277         sd->sensor = NULL;
278         kfree(sd->sensor_priv);
279 }
280
281 static int ov7660_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
282 {
283         struct sd *sd = (struct sd *) gspca_dev;
284         s32 *sensor_settings = sd->sensor_priv;
285
286         *val = sensor_settings[GAIN_IDX];
287         PDEBUG(D_V4L2, "Read gain %d", *val);
288         return 0;
289 }
290
291 static int ov7660_set_gain(struct gspca_dev *gspca_dev, __s32 val)
292 {
293         int err;
294         u8 i2c_data;
295         struct sd *sd = (struct sd *) gspca_dev;
296         s32 *sensor_settings = sd->sensor_priv;
297
298         PDEBUG(D_V4L2, "Setting gain to %d", val);
299
300         sensor_settings[GAIN_IDX] = val;
301
302         err = m5602_write_sensor(sd, OV7660_GAIN, &i2c_data, 1);
303         return err;
304 }
305
306
307 static int ov7660_get_auto_white_balance(struct gspca_dev *gspca_dev,
308                                          __s32 *val)
309 {
310         struct sd *sd = (struct sd *) gspca_dev;
311         s32 *sensor_settings = sd->sensor_priv;
312
313         *val = sensor_settings[AUTO_WHITE_BALANCE_IDX];
314         return 0;
315 }
316
317 static int ov7660_set_auto_white_balance(struct gspca_dev *gspca_dev,
318                                          __s32 val)
319 {
320         int err;
321         u8 i2c_data;
322         struct sd *sd = (struct sd *) gspca_dev;
323         s32 *sensor_settings = sd->sensor_priv;
324
325         PDEBUG(D_V4L2, "Set auto white balance to %d", val);
326
327         sensor_settings[AUTO_WHITE_BALANCE_IDX] = val;
328         err = m5602_read_sensor(sd, OV7660_COM8, &i2c_data, 1);
329         if (err < 0)
330                 return err;
331
332         i2c_data = ((i2c_data & 0xfd) | ((val & 0x01) << 1));
333         err = m5602_write_sensor(sd, OV7660_COM8, &i2c_data, 1);
334
335         return err;
336 }
337
338 static int ov7660_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val)
339 {
340         struct sd *sd = (struct sd *) gspca_dev;
341         s32 *sensor_settings = sd->sensor_priv;
342
343         *val = sensor_settings[AUTO_GAIN_CTRL_IDX];
344         PDEBUG(D_V4L2, "Read auto gain control %d", *val);
345         return 0;
346 }
347
348 static int ov7660_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val)
349 {
350         int err;
351         u8 i2c_data;
352         struct sd *sd = (struct sd *) gspca_dev;
353         s32 *sensor_settings = sd->sensor_priv;
354
355         PDEBUG(D_V4L2, "Set auto gain control to %d", val);
356
357         sensor_settings[AUTO_GAIN_CTRL_IDX] = val;
358         err = m5602_read_sensor(sd, OV7660_COM8, &i2c_data, 1);
359         if (err < 0)
360                 return err;
361
362         i2c_data = ((i2c_data & 0xfb) | ((val & 0x01) << 2));
363
364         return m5602_write_sensor(sd, OV7660_COM8, &i2c_data, 1);
365 }
366
367 static int ov7660_get_auto_exposure(struct gspca_dev *gspca_dev, __s32 *val)
368 {
369         struct sd *sd = (struct sd *) gspca_dev;
370         s32 *sensor_settings = sd->sensor_priv;
371
372         *val = sensor_settings[AUTO_EXPOSURE_IDX];
373         PDEBUG(D_V4L2, "Read auto exposure control %d", *val);
374         return 0;
375 }
376
377 static int ov7660_set_auto_exposure(struct gspca_dev *gspca_dev,
378                                     __s32 val)
379 {
380         int err;
381         u8 i2c_data;
382         struct sd *sd = (struct sd *) gspca_dev;
383         s32 *sensor_settings = sd->sensor_priv;
384
385         PDEBUG(D_V4L2, "Set auto exposure control to %d", val);
386
387         sensor_settings[AUTO_EXPOSURE_IDX] = val;
388         err = m5602_read_sensor(sd, OV7660_COM8, &i2c_data, 1);
389         if (err < 0)
390                 return err;
391
392         i2c_data = ((i2c_data & 0xfe) | ((val & 0x01) << 0));
393
394         return m5602_write_sensor(sd, OV7660_COM8, &i2c_data, 1);
395 }
396
397 static int ov7660_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
398 {
399         struct sd *sd = (struct sd *) gspca_dev;
400         s32 *sensor_settings = sd->sensor_priv;
401
402         *val = sensor_settings[HFLIP_IDX];
403         PDEBUG(D_V4L2, "Read horizontal flip %d", *val);
404         return 0;
405 }
406
407 static int ov7660_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
408 {
409         int err;
410         u8 i2c_data;
411         struct sd *sd = (struct sd *) gspca_dev;
412         s32 *sensor_settings = sd->sensor_priv;
413
414         PDEBUG(D_V4L2, "Set horizontal flip to %d", val);
415
416         sensor_settings[HFLIP_IDX] = val;
417
418         i2c_data = ((val & 0x01) << 5) |
419                 (sensor_settings[VFLIP_IDX] << 4);
420
421         err = m5602_write_sensor(sd, OV7660_MVFP, &i2c_data, 1);
422
423         return err;
424 }
425
426 static int ov7660_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
427 {
428         struct sd *sd = (struct sd *) gspca_dev;
429         s32 *sensor_settings = sd->sensor_priv;
430
431         *val = sensor_settings[VFLIP_IDX];
432         PDEBUG(D_V4L2, "Read vertical flip %d", *val);
433
434         return 0;
435 }
436
437 static int ov7660_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
438 {
439         int err;
440         u8 i2c_data;
441         struct sd *sd = (struct sd *) gspca_dev;
442         s32 *sensor_settings = sd->sensor_priv;
443
444         PDEBUG(D_V4L2, "Set vertical flip to %d", val);
445         sensor_settings[VFLIP_IDX] = val;
446
447         i2c_data = ((val & 0x01) << 4) | (sensor_settings[VFLIP_IDX] << 5);
448         err = m5602_write_sensor(sd, OV7660_MVFP, &i2c_data, 1);
449         if (err < 0)
450                 return err;
451
452         /* When vflip is toggled we need to readjust the bridge hsync/vsync */
453         if (gspca_dev->streaming)
454                 err = ov7660_start(sd);
455
456         return err;
457 }
458
459 static void ov7660_dump_registers(struct sd *sd)
460 {
461         int address;
462         pr_info("Dumping the ov7660 register state\n");
463         for (address = 0; address < 0xa9; address++) {
464                 u8 value;
465                 m5602_read_sensor(sd, address, &value, 1);
466                 pr_info("register 0x%x contains 0x%x\n", address, value);
467         }
468
469         pr_info("ov7660 register state dump complete\n");
470
471         pr_info("Probing for which registers that are read/write\n");
472         for (address = 0; address < 0xff; address++) {
473                 u8 old_value, ctrl_value;
474                 u8 test_value[2] = {0xff, 0xff};
475
476                 m5602_read_sensor(sd, address, &old_value, 1);
477                 m5602_write_sensor(sd, address, test_value, 1);
478                 m5602_read_sensor(sd, address, &ctrl_value, 1);
479
480                 if (ctrl_value == test_value[0])
481                         pr_info("register 0x%x is writeable\n", address);
482                 else
483                         pr_info("register 0x%x is read only\n", address);
484
485                 /* Restore original value */
486                 m5602_write_sensor(sd, address, &old_value, 1);
487         }
488 }