Merge branch 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc
[pandora-kernel.git] / drivers / media / video / gspca / m5602 / m5602_s5k83a.c
1 /*
2  * Driver for the s5k83a 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_s5k83a.h"
20
21 static struct v4l2_pix_format s5k83a_modes[] = {
22         {
23                 640,
24                 480,
25                 V4L2_PIX_FMT_SBGGR8,
26                 V4L2_FIELD_NONE,
27                 .sizeimage =
28                         640 * 480,
29                 .bytesperline = 640,
30                 .colorspace = V4L2_COLORSPACE_SRGB,
31                 .priv = 0
32         }
33 };
34
35 const static struct ctrl s5k83a_ctrls[] = {
36         {
37                 {
38                         .id = V4L2_CID_BRIGHTNESS,
39                         .type = V4L2_CTRL_TYPE_INTEGER,
40                         .name = "brightness",
41                         .minimum = 0x00,
42                         .maximum = 0xff,
43                         .step = 0x01,
44                         .default_value = S5K83A_DEFAULT_BRIGHTNESS,
45                         .flags = V4L2_CTRL_FLAG_SLIDER
46                 },
47                         .set = s5k83a_set_brightness,
48                         .get = s5k83a_get_brightness
49
50         }, {
51                 {
52                         .id = V4L2_CID_WHITENESS,
53                         .type = V4L2_CTRL_TYPE_INTEGER,
54                         .name = "whiteness",
55                         .minimum = 0x00,
56                         .maximum = 0xff,
57                         .step = 0x01,
58                         .default_value = S5K83A_DEFAULT_WHITENESS,
59                         .flags = V4L2_CTRL_FLAG_SLIDER
60                 },
61                         .set = s5k83a_set_whiteness,
62                         .get = s5k83a_get_whiteness,
63         }, {
64                 {
65                         .id = V4L2_CID_GAIN,
66                         .type = V4L2_CTRL_TYPE_INTEGER,
67                         .name = "gain",
68                         .minimum = 0x00,
69                         .maximum = S5K83A_MAXIMUM_GAIN,
70                         .step = 0x01,
71                         .default_value = S5K83A_DEFAULT_GAIN,
72                         .flags = V4L2_CTRL_FLAG_SLIDER
73                 },
74                         .set = s5k83a_set_gain,
75                         .get = s5k83a_get_gain
76         }, {
77                 {
78                         .id         = V4L2_CID_HFLIP,
79                         .type       = V4L2_CTRL_TYPE_BOOLEAN,
80                         .name       = "horizontal flip",
81                         .minimum    = 0,
82                         .maximum    = 1,
83                         .step       = 1,
84                         .default_value  = 0
85                 },
86                         .set = s5k83a_set_hflip,
87                         .get = s5k83a_get_hflip
88         }, {
89                 {
90                  .id         = V4L2_CID_VFLIP,
91                 .type       = V4L2_CTRL_TYPE_BOOLEAN,
92                 .name       = "vertical flip",
93                 .minimum    = 0,
94                 .maximum    = 1,
95                 .step       = 1,
96                 .default_value  = 0
97                 },
98                 .set = s5k83a_set_vflip,
99                 .get = s5k83a_get_vflip
100         }
101 };
102
103 static void s5k83a_dump_registers(struct sd *sd);
104
105 int s5k83a_probe(struct sd *sd)
106 {
107         u8 prod_id = 0, ver_id = 0;
108         int i, err = 0;
109
110         if (force_sensor) {
111                 if (force_sensor == S5K83A_SENSOR) {
112                         info("Forcing a %s sensor", s5k83a.name);
113                         goto sensor_found;
114                 }
115                 /* If we want to force another sensor, don't try to probe this
116                  * one */
117                 return -ENODEV;
118         }
119
120         info("Probing for a s5k83a sensor");
121
122         /* Preinit the sensor */
123         for (i = 0; i < ARRAY_SIZE(preinit_s5k83a) && !err; i++) {
124                 u8 data[2] = {preinit_s5k83a[i][2], preinit_s5k83a[i][3]};
125                 if (preinit_s5k83a[i][0] == SENSOR)
126                         err = m5602_write_sensor(sd, preinit_s5k83a[i][1],
127                                 data, 2);
128                 else
129                         err = m5602_write_bridge(sd, preinit_s5k83a[i][1],
130                                 data[0]);
131         }
132
133         /* We don't know what register (if any) that contain the product id
134          * Just pick the first addresses that seem to produce the same results
135          * on multiple machines */
136         if (m5602_read_sensor(sd, 0x00, &prod_id, 1))
137                 return -ENODEV;
138
139         if (m5602_read_sensor(sd, 0x01, &ver_id, 1))
140                 return -ENODEV;
141
142         if ((prod_id == 0xff) || (ver_id == 0xff))
143                 return -ENODEV;
144         else
145                 info("Detected a s5k83a sensor");
146
147 sensor_found:
148         sd->gspca_dev.cam.cam_mode = s5k83a_modes;
149         sd->gspca_dev.cam.nmodes = ARRAY_SIZE(s5k83a_modes);
150         sd->desc->ctrls = s5k83a_ctrls;
151         sd->desc->nctrls = ARRAY_SIZE(s5k83a_ctrls);
152         return 0;
153 }
154
155 int s5k83a_init(struct sd *sd)
156 {
157         int i, err = 0;
158
159         for (i = 0; i < ARRAY_SIZE(init_s5k83a) && !err; i++) {
160                 u8 data[2] = {0x00, 0x00};
161
162                 switch (init_s5k83a[i][0]) {
163                 case BRIDGE:
164                         err = m5602_write_bridge(sd,
165                                         init_s5k83a[i][1],
166                                         init_s5k83a[i][2]);
167                         break;
168
169                 case SENSOR:
170                         data[0] = init_s5k83a[i][2];
171                         err = m5602_write_sensor(sd,
172                                 init_s5k83a[i][1], data, 1);
173                         break;
174
175                 case SENSOR_LONG:
176                         data[0] = init_s5k83a[i][2];
177                         data[1] = init_s5k83a[i][3];
178                         err = m5602_write_sensor(sd,
179                                 init_s5k83a[i][1], data, 2);
180                         break;
181                 default:
182                         info("Invalid stream command, exiting init");
183                         return -EINVAL;
184                 }
185         }
186
187         if (dump_sensor)
188                 s5k83a_dump_registers(sd);
189
190         return (err < 0) ? err : 0;
191 }
192
193 int s5k83a_start(struct sd *sd)
194 {
195         return s5k83a_set_led_indication(sd, 1);
196 }
197
198 int s5k83a_stop(struct sd *sd)
199 {
200         return s5k83a_set_led_indication(sd, 0);
201 }
202
203 int s5k83a_power_down(struct sd *sd)
204 {
205         return 0;
206 }
207
208 static void s5k83a_dump_registers(struct sd *sd)
209 {
210         int address;
211         u8 page, old_page;
212         m5602_read_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1);
213
214         for (page = 0; page < 16; page++) {
215                 m5602_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1);
216                 info("Dumping the s5k83a register state for page 0x%x", page);
217                 for (address = 0; address <= 0xff; address++) {
218                         u8 val = 0;
219                         m5602_read_sensor(sd, address, &val, 1);
220                         info("register 0x%x contains 0x%x",
221                              address, val);
222                 }
223         }
224         info("s5k83a register state dump complete");
225
226         for (page = 0; page < 16; page++) {
227                 m5602_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1);
228                 info("Probing for which registers that are read/write "
229                       "for page 0x%x", page);
230                 for (address = 0; address <= 0xff; address++) {
231                         u8 old_val, ctrl_val, test_val = 0xff;
232
233                         m5602_read_sensor(sd, address, &old_val, 1);
234                         m5602_write_sensor(sd, address, &test_val, 1);
235                         m5602_read_sensor(sd, address, &ctrl_val, 1);
236
237                         if (ctrl_val == test_val)
238                                 info("register 0x%x is writeable", address);
239                         else
240                                 info("register 0x%x is read only", address);
241
242                         /* Restore original val */
243                         m5602_write_sensor(sd, address, &old_val, 1);
244                 }
245         }
246         info("Read/write register probing complete");
247         m5602_write_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1);
248 }
249
250 int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val)
251 {
252         int err;
253         u8 data[2];
254         struct sd *sd = (struct sd *) gspca_dev;
255
256         err = m5602_read_sensor(sd, S5K83A_BRIGHTNESS, data, 2);
257         if (err < 0)
258                 return err;
259
260         data[1] = data[1] << 1;
261         *val = data[1];
262
263         return err;
264 }
265
266 int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val)
267 {
268         int err;
269         u8 data[2];
270         struct sd *sd = (struct sd *) gspca_dev;
271
272         data[0] = 0x00;
273         data[1] = 0x20;
274         err = m5602_write_sensor(sd, 0x14, data, 2);
275         if (err < 0)
276                 return err;
277
278         data[0] = 0x01;
279         data[1] = 0x00;
280         err = m5602_write_sensor(sd, 0x0d, data, 2);
281         if (err < 0)
282                 return err;
283
284         /* FIXME: This is not sane, we need to figure out the composition
285                   of these registers */
286         data[0] = val >> 3; /* brightness, high 5 bits */
287         data[1] = val >> 1; /* brightness, high 7 bits */
288         err = m5602_write_sensor(sd, S5K83A_BRIGHTNESS, data, 2);
289
290         return err;
291 }
292
293 int s5k83a_get_whiteness(struct gspca_dev *gspca_dev, __s32 *val)
294 {
295         int err;
296         u8 data;
297         struct sd *sd = (struct sd *) gspca_dev;
298
299         err = m5602_read_sensor(sd, S5K83A_WHITENESS, &data, 1);
300         if (err < 0)
301                 return err;
302
303         *val = data;
304
305         return err;
306 }
307
308 int s5k83a_set_whiteness(struct gspca_dev *gspca_dev, __s32 val)
309 {
310         int err;
311         u8 data[1];
312         struct sd *sd = (struct sd *) gspca_dev;
313
314         data[0] = val;
315         err = m5602_write_sensor(sd, S5K83A_WHITENESS, data, 1);
316
317         return err;
318 }
319
320 int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
321 {
322         int err;
323         u8 data[2];
324         struct sd *sd = (struct sd *) gspca_dev;
325
326         err = m5602_read_sensor(sd, S5K83A_GAIN, data, 2);
327         if (err < 0)
328                 return err;
329
330         data[1] = data[1] & 0x3f;
331         if (data[1] > S5K83A_MAXIMUM_GAIN)
332                 data[1] = S5K83A_MAXIMUM_GAIN;
333
334         *val = data[1];
335
336         return err;
337 }
338
339 int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val)
340 {
341         int err;
342         u8 data[2];
343         struct sd *sd = (struct sd *) gspca_dev;
344
345         data[0] = 0;
346         data[1] = val;
347         err = m5602_write_sensor(sd, S5K83A_GAIN, data, 2);
348         return err;
349 }
350
351 int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
352 {
353         int err;
354         u8 data[1];
355         struct sd *sd = (struct sd *) gspca_dev;
356
357         data[0] = 0x05;
358         err = m5602_write_sensor(sd, S5K83A_PAGE_MAP, data, 1);
359         if (err < 0)
360                 return err;
361
362         err = m5602_read_sensor(sd, S5K83A_FLIP, data, 1);
363         *val = (data[0] | 0x40) ? 1 : 0;
364
365         return err;
366 }
367
368 int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
369 {
370         int err;
371         u8 data[1];
372         struct sd *sd = (struct sd *) gspca_dev;
373
374         data[0] = 0x05;
375         err = m5602_write_sensor(sd, S5K83A_PAGE_MAP, data, 1);
376         if (err < 0)
377                 return err;
378
379         err = m5602_read_sensor(sd, S5K83A_FLIP, data, 1);
380         if (err < 0)
381                 return err;
382
383         /* set or zero six bit, seven is hflip */
384         data[0] = (val) ? (data[0] & 0x80) | 0x40 | S5K83A_FLIP_MASK
385                         : (data[0] & 0x80) | S5K83A_FLIP_MASK;
386         err = m5602_write_sensor(sd, S5K83A_FLIP, data, 1);
387         if (err < 0)
388                 return err;
389
390         data[0] = (val) ? 0x0b : 0x0a;
391         err = m5602_write_sensor(sd, S5K83A_VFLIP_TUNE, data, 1);
392
393         return err;
394 }
395
396 int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
397 {
398         int err;
399         u8 data[1];
400         struct sd *sd = (struct sd *) gspca_dev;
401
402         data[0] = 0x05;
403         err = m5602_write_sensor(sd, S5K83A_PAGE_MAP, data, 1);
404         if (err < 0)
405                 return err;
406
407         err = m5602_read_sensor(sd, S5K83A_FLIP, data, 1);
408         *val = (data[0] | 0x80) ? 1 : 0;
409
410         return err;
411 }
412
413 int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
414 {
415         int err;
416         u8 data[1];
417         struct sd *sd = (struct sd *) gspca_dev;
418
419         data[0] = 0x05;
420         err = m5602_write_sensor(sd, S5K83A_PAGE_MAP, data, 1);
421         if (err < 0)
422                 return err;
423
424         err = m5602_read_sensor(sd, S5K83A_FLIP, data, 1);
425         if (err < 0)
426                 return err;
427
428         /* set or zero seven bit, six is vflip */
429         data[0] = (val) ? (data[0] & 0x40) | 0x80 | S5K83A_FLIP_MASK
430                         : (data[0] & 0x40) | S5K83A_FLIP_MASK;
431         err = m5602_write_sensor(sd, S5K83A_FLIP, data, 1);
432         if (err < 0)
433                 return err;
434
435         data[0] = (val) ? 0x0a : 0x0b;
436         err = m5602_write_sensor(sd, S5K83A_HFLIP_TUNE, data, 1);
437
438         return err;
439 }
440
441 int s5k83a_set_led_indication(struct sd *sd, u8 val)
442 {
443         int err = 0;
444         u8 data[1];
445
446         err = m5602_read_bridge(sd, M5602_XB_GPIO_DAT, data);
447         if (err < 0)
448                 return err;
449
450         if (val)
451                 data[0] = data[0] | S5K83A_GPIO_LED_MASK;
452         else
453                 data[0] = data[0] & ~S5K83A_GPIO_LED_MASK;
454
455         err = m5602_write_bridge(sd, M5602_XB_GPIO_DAT, data[0]);
456
457         return (err < 0) ? err : 0;
458 }