V4L/DVB (11456): gspca - m5602-po1030: Rename register defines, add missing ones.
[pandora-kernel.git] / drivers / media / video / gspca / m5602 / m5602_po1030.c
1 /*
2  * Driver for the po1030 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_po1030.h"
20
21 static struct v4l2_pix_format po1030_modes[] = {
22         {
23                 640,
24                 480,
25                 V4L2_PIX_FMT_SBGGR8,
26                 V4L2_FIELD_NONE,
27                 .sizeimage = 640 * 480,
28                 .bytesperline = 640,
29                 .colorspace = V4L2_COLORSPACE_SRGB,
30                 .priv = 0
31         }
32 };
33
34 const static struct ctrl po1030_ctrls[] = {
35 #define GAIN_IDX 0
36         {
37                 {
38                         .id             = V4L2_CID_GAIN,
39                         .type           = V4L2_CTRL_TYPE_INTEGER,
40                         .name           = "gain",
41                         .minimum        = 0x00,
42                         .maximum        = 0x4f,
43                         .step           = 0x1,
44                         .default_value  = PO1030_GLOBAL_GAIN_DEFAULT,
45                         .flags          = V4L2_CTRL_FLAG_SLIDER
46                 },
47                 .set = po1030_set_gain,
48                 .get = po1030_get_gain
49         },
50 #define EXPOSURE_IDX 1
51         {
52                 {
53                         .id             = V4L2_CID_EXPOSURE,
54                         .type           = V4L2_CTRL_TYPE_INTEGER,
55                         .name           = "exposure",
56                         .minimum        = 0x00,
57                         .maximum        = 0x02ff,
58                         .step           = 0x1,
59                         .default_value  = PO1030_EXPOSURE_DEFAULT,
60                         .flags          = V4L2_CTRL_FLAG_SLIDER
61                 },
62                 .set = po1030_set_exposure,
63                 .get = po1030_get_exposure
64         },
65 #define RED_BALANCE_IDX 2
66         {
67                 {
68                         .id             = V4L2_CID_RED_BALANCE,
69                         .type           = V4L2_CTRL_TYPE_INTEGER,
70                         .name           = "red balance",
71                         .minimum        = 0x00,
72                         .maximum        = 0xff,
73                         .step           = 0x1,
74                         .default_value  = PO1030_RED_GAIN_DEFAULT,
75                         .flags          = V4L2_CTRL_FLAG_SLIDER
76                 },
77                 .set = po1030_set_red_balance,
78                 .get = po1030_get_red_balance
79         },
80 #define BLUE_BALANCE_IDX 3
81         {
82                 {
83                         .id             = V4L2_CID_BLUE_BALANCE,
84                         .type           = V4L2_CTRL_TYPE_INTEGER,
85                         .name           = "blue balance",
86                         .minimum        = 0x00,
87                         .maximum        = 0xff,
88                         .step           = 0x1,
89                         .default_value  = PO1030_BLUE_GAIN_DEFAULT,
90                         .flags          = V4L2_CTRL_FLAG_SLIDER
91                 },
92                 .set = po1030_set_blue_balance,
93                 .get = po1030_get_blue_balance
94         },
95 #define HFLIP_IDX 4
96         {
97                 {
98                         .id             = V4L2_CID_HFLIP,
99                         .type           = V4L2_CTRL_TYPE_BOOLEAN,
100                         .name           = "horizontal flip",
101                         .minimum        = 0,
102                         .maximum        = 1,
103                         .step           = 1,
104                         .default_value  = 0,
105                 },
106                 .set = po1030_set_hflip,
107                 .get = po1030_get_hflip
108         },
109 #define VFLIP_IDX 5
110         {
111                 {
112                         .id             = V4L2_CID_VFLIP,
113                         .type           = V4L2_CTRL_TYPE_BOOLEAN,
114                         .name           = "vertical flip",
115                         .minimum        = 0,
116                         .maximum        = 1,
117                         .step           = 1,
118                         .default_value  = 0,
119                 },
120                 .set = po1030_set_vflip,
121                 .get = po1030_get_vflip
122         }
123 };
124
125 static void po1030_dump_registers(struct sd *sd);
126
127 int po1030_probe(struct sd *sd)
128 {
129         u8 prod_id = 0, ver_id = 0, i;
130         s32 *sensor_settings = sd->sensor_priv;
131
132         if (force_sensor) {
133                 if (force_sensor == PO1030_SENSOR) {
134                         info("Forcing a %s sensor", po1030.name);
135                         goto sensor_found;
136                 }
137                 /* If we want to force another sensor, don't try to probe this
138                  * one */
139                 return -ENODEV;
140         }
141
142         info("Probing for a po1030 sensor");
143
144         /* Run the pre-init to actually probe the unit */
145         for (i = 0; i < ARRAY_SIZE(preinit_po1030); i++) {
146                 u8 data = preinit_po1030[i][2];
147                 if (preinit_po1030[i][0] == SENSOR)
148                         m5602_write_sensor(sd,
149                                 preinit_po1030[i][1], &data, 1);
150                 else
151                         m5602_write_bridge(sd, preinit_po1030[i][1], data);
152         }
153
154         if (m5602_read_sensor(sd, 0x3, &prod_id, 1))
155                 return -ENODEV;
156
157         if (m5602_read_sensor(sd, 0x4, &ver_id, 1))
158                 return -ENODEV;
159
160         if ((prod_id == 0x02) && (ver_id == 0xef)) {
161                 info("Detected a po1030 sensor");
162                 goto sensor_found;
163         }
164         return -ENODEV;
165
166 sensor_found:
167         sensor_settings = kmalloc(
168                 ARRAY_SIZE(po1030_ctrls) * sizeof(s32), GFP_KERNEL);
169         if (!sensor_settings)
170                 return -ENOMEM;
171
172         sd->gspca_dev.cam.cam_mode = po1030_modes;
173         sd->gspca_dev.cam.nmodes = ARRAY_SIZE(po1030_modes);
174         sd->desc->ctrls = po1030_ctrls;
175         sd->desc->nctrls = ARRAY_SIZE(po1030_ctrls);
176
177         for (i = 0; i < ARRAY_SIZE(po1030_ctrls); i++)
178                 sensor_settings[i] = po1030_ctrls[i].qctrl.default_value;
179         sd->sensor_priv = sensor_settings;
180         return 0;
181 }
182
183 int po1030_init(struct sd *sd)
184 {
185         int i, err = 0;
186
187         /* Init the sensor */
188         for (i = 0; i < ARRAY_SIZE(init_po1030) && !err; i++) {
189                 u8 data[2] = {0x00, 0x00};
190
191                 switch (init_po1030[i][0]) {
192                 case BRIDGE:
193                         err = m5602_write_bridge(sd,
194                                 init_po1030[i][1],
195                                 init_po1030[i][2]);
196                         break;
197
198                 case SENSOR:
199                         data[0] = init_po1030[i][2];
200                         err = m5602_write_sensor(sd,
201                                 init_po1030[i][1], data, 1);
202                         break;
203
204                 default:
205                         info("Invalid stream command, exiting init");
206                         return -EINVAL;
207                 }
208         }
209
210         if (dump_sensor)
211                 po1030_dump_registers(sd);
212
213         return err;
214 }
215
216 int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
217 {
218         struct sd *sd = (struct sd *) gspca_dev;
219         s32 *sensor_settings = sd->sensor_priv;
220
221         *val = sensor_settings[EXPOSURE_IDX];
222         PDEBUG(D_V4L2, "Exposure read as %d", *val);
223         return 0;
224 }
225
226 int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
227 {
228         struct sd *sd = (struct sd *) gspca_dev;
229         s32 *sensor_settings = sd->sensor_priv;
230         u8 i2c_data;
231         int err;
232
233         sensor_settings[EXPOSURE_IDX] = val;
234         PDEBUG(D_V4L2, "Set exposure to %d", val & 0xffff);
235
236         i2c_data = ((val & 0xff00) >> 8);
237         PDEBUG(D_V4L2, "Set exposure to high byte to 0x%x",
238                i2c_data);
239
240         err = m5602_write_sensor(sd, PO1030_INTEGLINES_H,
241                                   &i2c_data, 1);
242         if (err < 0)
243                 return err;
244
245         i2c_data = (val & 0xff);
246         PDEBUG(D_V4L2, "Set exposure to low byte to 0x%x",
247                i2c_data);
248         err = m5602_write_sensor(sd, PO1030_INTEGLINES_M,
249                                   &i2c_data, 1);
250
251         return err;
252 }
253
254 int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
255 {
256         struct sd *sd = (struct sd *) gspca_dev;
257         s32 *sensor_settings = sd->sensor_priv;
258
259         *val = sensor_settings[GAIN_IDX];
260         PDEBUG(D_V4L2, "Read global gain %d", *val);
261         return 0;
262 }
263
264 int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val)
265 {
266         struct sd *sd = (struct sd *) gspca_dev;
267         s32 *sensor_settings = sd->sensor_priv;
268         u8 i2c_data;
269         int err;
270
271         sensor_settings[GAIN_IDX] = val;
272
273         i2c_data = val & 0xff;
274         PDEBUG(D_V4L2, "Set global gain to %d", i2c_data);
275         err = m5602_write_sensor(sd, PO1030_GLOBALGAIN,
276                                  &i2c_data, 1);
277         return err;
278 }
279
280 int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
281 {
282         struct sd *sd = (struct sd *) gspca_dev;
283         s32 *sensor_settings = sd->sensor_priv;
284
285         *val = sensor_settings[HFLIP_IDX];
286         PDEBUG(D_V4L2, "Read hflip %d", *val);
287
288         return 0;
289 }
290
291 int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
292 {
293         struct sd *sd = (struct sd *) gspca_dev;
294         s32 *sensor_settings = sd->sensor_priv;
295         u8 i2c_data;
296         int err;
297
298         sensor_settings[HFLIP_IDX] = val;
299
300         PDEBUG(D_V4L2, "Set hflip %d", val);
301         err = m5602_read_sensor(sd, PO1030_CONTROL2, &i2c_data, 1);
302         if (err < 0)
303                 return err;
304
305         i2c_data = (0x7f & i2c_data) | ((val & 0x01) << 7);
306
307         err = m5602_write_sensor(sd, PO1030_CONTROL2,
308                                  &i2c_data, 1);
309
310         return err;
311 }
312
313 int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
314 {
315         struct sd *sd = (struct sd *) gspca_dev;
316         s32 *sensor_settings = sd->sensor_priv;
317
318         *val= sensor_settings[VFLIP_IDX];
319         PDEBUG(D_V4L2, "Read vflip %d", *val);
320
321         return 0;
322 }
323
324 int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
325 {
326         struct sd *sd = (struct sd *) gspca_dev;
327         s32 *sensor_settings = sd->sensor_priv;
328         u8 i2c_data;
329         int err;
330
331         sensor_settings[VFLIP_IDX] = val;
332
333         PDEBUG(D_V4L2, "Set vflip %d", val);
334         err = m5602_read_sensor(sd, PO1030_CONTROL2, &i2c_data, 1);
335         if (err < 0)
336                 return err;
337
338         i2c_data = (i2c_data & 0xbf) | ((val & 0x01) << 6);
339
340         err = m5602_write_sensor(sd, PO1030_CONTROL2,
341                                  &i2c_data, 1);
342
343         return err;
344 }
345
346 int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
347 {
348         struct sd *sd = (struct sd *) gspca_dev;
349         s32 *sensor_settings = sd->sensor_priv;
350
351         *val = sensor_settings[RED_BALANCE_IDX];
352         PDEBUG(D_V4L2, "Read red gain %d", *val);
353         return 0;
354 }
355
356 int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
357 {
358         struct sd *sd = (struct sd *) gspca_dev;
359         s32 *sensor_settings = sd->sensor_priv;
360         u8 i2c_data;
361         int err;
362
363         sensor_settings[RED_BALANCE_IDX] = val;
364
365         i2c_data = val & 0xff;
366         PDEBUG(D_V4L2, "Set red gain to %d", i2c_data);
367         err = m5602_write_sensor(sd, PO1030_RED_GAIN,
368                                   &i2c_data, 1);
369         return err;
370 }
371
372 int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
373 {
374         struct sd *sd = (struct sd *) gspca_dev;
375         s32 *sensor_settings = sd->sensor_priv;
376
377         *val = sensor_settings[BLUE_BALANCE_IDX];
378         PDEBUG(D_V4L2, "Read blue gain %d", *val);
379
380         return 0;
381 }
382
383 int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
384 {
385         struct sd *sd = (struct sd *) gspca_dev;
386         s32 *sensor_settings = sd->sensor_priv;
387         u8 i2c_data;
388         int err;
389
390         sensor_settings[BLUE_BALANCE_IDX] = val;
391
392         i2c_data = val & 0xff;
393         PDEBUG(D_V4L2, "Set blue gain to %d", i2c_data);
394         err = m5602_write_sensor(sd, PO1030_BLUE_GAIN,
395                                   &i2c_data, 1);
396
397         return err;
398 }
399
400 void po1030_disconnect(struct sd *sd)
401 {
402         sd->sensor = NULL;
403         kfree(sd->sensor_priv);
404 }
405
406 static void po1030_dump_registers(struct sd *sd)
407 {
408         int address;
409         u8 value = 0;
410
411         info("Dumping the po1030 sensor core registers");
412         for (address = 0; address < 0x7f; address++) {
413                 m5602_read_sensor(sd, address, &value, 1);
414                 info("register 0x%x contains 0x%x",
415                      address, value);
416         }
417
418         info("po1030 register state dump complete");
419
420         info("Probing for which registers that are read/write");
421         for (address = 0; address < 0xff; address++) {
422                 u8 old_value, ctrl_value;
423                 u8 test_value[2] = {0xff, 0xff};
424
425                 m5602_read_sensor(sd, address, &old_value, 1);
426                 m5602_write_sensor(sd, address, test_value, 1);
427                 m5602_read_sensor(sd, address, &ctrl_value, 1);
428
429                 if (ctrl_value == test_value[0])
430                         info("register 0x%x is writeable", address);
431                 else
432                         info("register 0x%x is read only", address);
433
434                 /* Restore original value */
435                 m5602_write_sensor(sd, address, &old_value, 1);
436         }
437 }