]> bbs.cooldavid.org Git - net-next-2.6.git/blob - drivers/media/video/gspca/m5602/m5602_s5k83a.c
V4L/DVB (11654): gspca - m5602: Storage class should be before const qualifier
[net-next-2.6.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 <linux/kthread.h>
20 #include "m5602_s5k83a.h"
21
22 static int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val);
23 static int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
24 static int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val);
25 static int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val);
26 static int s5k83a_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
27 static int s5k83a_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
28 static int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
29 static int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
30 static int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
31 static int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
32
33 static struct v4l2_pix_format s5k83a_modes[] = {
34         {
35                 640,
36                 480,
37                 V4L2_PIX_FMT_SBGGR8,
38                 V4L2_FIELD_NONE,
39                 .sizeimage =
40                         640 * 480,
41                 .bytesperline = 640,
42                 .colorspace = V4L2_COLORSPACE_SRGB,
43                 .priv = 0
44         }
45 };
46
47 static const struct ctrl s5k83a_ctrls[] = {
48 #define GAIN_IDX 0
49         {
50                 {
51                         .id = V4L2_CID_GAIN,
52                         .type = V4L2_CTRL_TYPE_INTEGER,
53                         .name = "gain",
54                         .minimum = 0x00,
55                         .maximum = 0xff,
56                         .step = 0x01,
57                         .default_value = S5K83A_DEFAULT_GAIN,
58                         .flags = V4L2_CTRL_FLAG_SLIDER
59                 },
60                         .set = s5k83a_set_gain,
61                         .get = s5k83a_get_gain
62
63         },
64 #define BRIGHTNESS_IDX 1
65         {
66                 {
67                         .id = V4L2_CID_BRIGHTNESS,
68                         .type = V4L2_CTRL_TYPE_INTEGER,
69                         .name = "brightness",
70                         .minimum = 0x00,
71                         .maximum = 0xff,
72                         .step = 0x01,
73                         .default_value = S5K83A_DEFAULT_BRIGHTNESS,
74                         .flags = V4L2_CTRL_FLAG_SLIDER
75                 },
76                         .set = s5k83a_set_brightness,
77                         .get = s5k83a_get_brightness,
78         },
79 #define EXPOSURE_IDX 2
80         {
81                 {
82                         .id = V4L2_CID_EXPOSURE,
83                         .type = V4L2_CTRL_TYPE_INTEGER,
84                         .name = "exposure",
85                         .minimum = 0x00,
86                         .maximum = S5K83A_MAXIMUM_EXPOSURE,
87                         .step = 0x01,
88                         .default_value = S5K83A_DEFAULT_EXPOSURE,
89                         .flags = V4L2_CTRL_FLAG_SLIDER
90                 },
91                         .set = s5k83a_set_exposure,
92                         .get = s5k83a_get_exposure
93         },
94 #define HFLIP_IDX 3
95         {
96                 {
97                         .id = V4L2_CID_HFLIP,
98                         .type = V4L2_CTRL_TYPE_BOOLEAN,
99                         .name = "horizontal flip",
100                         .minimum = 0,
101                         .maximum = 1,
102                         .step = 1,
103                         .default_value = 0
104                 },
105                         .set = s5k83a_set_hflip,
106                         .get = s5k83a_get_hflip
107         },
108 #define VFLIP_IDX 4
109         {
110                 {
111                         .id = V4L2_CID_VFLIP,
112                         .type = V4L2_CTRL_TYPE_BOOLEAN,
113                         .name = "vertical flip",
114                         .minimum = 0,
115                         .maximum = 1,
116                         .step = 1,
117                         .default_value = 0
118                 },
119                 .set = s5k83a_set_vflip,
120                 .get = s5k83a_get_vflip
121         }
122 };
123
124 static void s5k83a_dump_registers(struct sd *sd);
125 static int s5k83a_get_rotation(struct sd *sd, u8 *reg_data);
126 static int s5k83a_set_led_indication(struct sd *sd, u8 val);
127 static int s5k83a_set_flip_real(struct gspca_dev *gspca_dev,
128                                 __s32 vflip, __s32 hflip);
129
130 int s5k83a_probe(struct sd *sd)
131 {
132         struct s5k83a_priv *sens_priv;
133         u8 prod_id = 0, ver_id = 0;
134         int i, err = 0;
135
136         if (force_sensor) {
137                 if (force_sensor == S5K83A_SENSOR) {
138                         info("Forcing a %s sensor", s5k83a.name);
139                         goto sensor_found;
140                 }
141                 /* If we want to force another sensor, don't try to probe this
142                  * one */
143                 return -ENODEV;
144         }
145
146         info("Probing for a s5k83a sensor");
147
148         /* Preinit the sensor */
149         for (i = 0; i < ARRAY_SIZE(preinit_s5k83a) && !err; i++) {
150                 u8 data[2] = {preinit_s5k83a[i][2], preinit_s5k83a[i][3]};
151                 if (preinit_s5k83a[i][0] == SENSOR)
152                         err = m5602_write_sensor(sd, preinit_s5k83a[i][1],
153                                 data, 2);
154                 else
155                         err = m5602_write_bridge(sd, preinit_s5k83a[i][1],
156                                 data[0]);
157         }
158
159         /* We don't know what register (if any) that contain the product id
160          * Just pick the first addresses that seem to produce the same results
161          * on multiple machines */
162         if (m5602_read_sensor(sd, 0x00, &prod_id, 1))
163                 return -ENODEV;
164
165         if (m5602_read_sensor(sd, 0x01, &ver_id, 1))
166                 return -ENODEV;
167
168         if ((prod_id == 0xff) || (ver_id == 0xff))
169                 return -ENODEV;
170         else
171                 info("Detected a s5k83a sensor");
172
173 sensor_found:
174         sens_priv = kmalloc(
175                 sizeof(struct s5k83a_priv), GFP_KERNEL);
176         if (!sens_priv)
177                 return -ENOMEM;
178
179         sens_priv->settings =
180         kmalloc(sizeof(s32)*ARRAY_SIZE(s5k83a_ctrls), GFP_KERNEL);
181         if (!sens_priv->settings)
182                 return -ENOMEM;
183
184         sd->gspca_dev.cam.cam_mode = s5k83a_modes;
185         sd->gspca_dev.cam.nmodes = ARRAY_SIZE(s5k83a_modes);
186         sd->desc->ctrls = s5k83a_ctrls;
187         sd->desc->nctrls = ARRAY_SIZE(s5k83a_ctrls);
188
189         /* null the pointer! thread is't running now */
190         sens_priv->rotation_thread = NULL;
191
192         for (i = 0; i < ARRAY_SIZE(s5k83a_ctrls); i++)
193                 sens_priv->settings[i] = s5k83a_ctrls[i].qctrl.default_value;
194
195         sd->sensor_priv = sens_priv;
196         return 0;
197 }
198
199 int s5k83a_init(struct sd *sd)
200 {
201         int i, err = 0;
202         s32 *sensor_settings =
203                         ((struct s5k83a_priv *) sd->sensor_priv)->settings;
204
205         for (i = 0; i < ARRAY_SIZE(init_s5k83a) && !err; i++) {
206                 u8 data[2] = {0x00, 0x00};
207
208                 switch (init_s5k83a[i][0]) {
209                 case BRIDGE:
210                         err = m5602_write_bridge(sd,
211                                         init_s5k83a[i][1],
212                                         init_s5k83a[i][2]);
213                         break;
214
215                 case SENSOR:
216                         data[0] = init_s5k83a[i][2];
217                         err = m5602_write_sensor(sd,
218                                 init_s5k83a[i][1], data, 1);
219                         break;
220
221                 case SENSOR_LONG:
222                         data[0] = init_s5k83a[i][2];
223                         data[1] = init_s5k83a[i][3];
224                         err = m5602_write_sensor(sd,
225                                 init_s5k83a[i][1], data, 2);
226                         break;
227                 default:
228                         info("Invalid stream command, exiting init");
229                         return -EINVAL;
230                 }
231         }
232
233         if (dump_sensor)
234                 s5k83a_dump_registers(sd);
235
236         err = s5k83a_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]);
237         if (err < 0)
238                 return err;
239
240         err = s5k83a_set_brightness(&sd->gspca_dev,
241                                      sensor_settings[BRIGHTNESS_IDX]);
242         if (err < 0)
243                 return err;
244
245         err = s5k83a_set_exposure(&sd->gspca_dev,
246                                    sensor_settings[EXPOSURE_IDX]);
247         if (err < 0)
248                 return err;
249
250         err = s5k83a_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]);
251         if (err < 0)
252                 return err;
253
254         err = s5k83a_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]);
255
256         return err;
257 }
258
259 static int rotation_thread_function(void *data)
260 {
261         struct sd *sd = (struct sd *) data;
262         struct s5k83a_priv *sens_priv = sd->sensor_priv;
263         u8 reg, previous_rotation = 0;
264         __s32 vflip, hflip;
265
266         set_current_state(TASK_INTERRUPTIBLE);
267         while (!schedule_timeout(100)) {
268                 if (mutex_lock_interruptible(&sd->gspca_dev.usb_lock))
269                         break;
270
271                 s5k83a_get_rotation(sd, &reg);
272                 if (previous_rotation != reg) {
273                         previous_rotation = reg;
274                         info("Camera was flipped");
275
276                         s5k83a_get_vflip((struct gspca_dev *) sd, &vflip);
277                         s5k83a_get_hflip((struct gspca_dev *) sd, &hflip);
278
279                         if (reg) {
280                                 vflip = !vflip;
281                                 hflip = !hflip;
282                         }
283                         s5k83a_set_flip_real((struct gspca_dev *) sd, vflip, hflip);
284                 }
285
286                 mutex_unlock(&sd->gspca_dev.usb_lock);
287                 set_current_state(TASK_INTERRUPTIBLE);
288         }
289
290         /* return to "front" flip */
291         if (previous_rotation) {
292                 s5k83a_get_vflip((struct gspca_dev *) sd, &vflip);
293                 s5k83a_get_hflip((struct gspca_dev *) sd, &hflip);
294                 s5k83a_set_flip_real((struct gspca_dev *) sd, vflip, hflip);
295         }
296
297         sens_priv->rotation_thread = NULL;
298         return 0;
299 }
300
301 int s5k83a_start(struct sd *sd)
302 {
303         int i, err = 0;
304         struct s5k83a_priv *sens_priv = sd->sensor_priv;
305
306         /* Create another thread, polling the GPIO ports of the camera to check
307            if it got rotated. This is how the windows driver does it so we have
308            to assume that there is no better way of accomplishing this */
309         sens_priv->rotation_thread = kthread_create(rotation_thread_function,
310                                                     sd, "rotation thread");
311         wake_up_process(sens_priv->rotation_thread);
312
313         /* Preinit the sensor */
314         for (i = 0; i < ARRAY_SIZE(start_s5k83a) && !err; i++) {
315                 u8 data[2] = {start_s5k83a[i][2], start_s5k83a[i][3]};
316                 if (start_s5k83a[i][0] == SENSOR)
317                         err = m5602_write_sensor(sd, start_s5k83a[i][1],
318                                 data, 2);
319                 else
320                         err = m5602_write_bridge(sd, start_s5k83a[i][1],
321                                 data[0]);
322         }
323         if (err < 0)
324                 return err;
325
326         return s5k83a_set_led_indication(sd, 1);
327 }
328
329 int s5k83a_stop(struct sd *sd)
330 {
331         struct s5k83a_priv *sens_priv = sd->sensor_priv;
332
333         if (sens_priv->rotation_thread)
334                 kthread_stop(sens_priv->rotation_thread);
335
336         return s5k83a_set_led_indication(sd, 0);
337 }
338
339 void s5k83a_disconnect(struct sd *sd)
340 {
341         struct s5k83a_priv *sens_priv = sd->sensor_priv;
342
343         s5k83a_stop(sd);
344
345         sd->sensor = NULL;
346         kfree(sens_priv->settings);
347         kfree(sens_priv);
348 }
349
350 static int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
351 {
352         struct sd *sd = (struct sd *) gspca_dev;
353         struct s5k83a_priv *sens_priv = sd->sensor_priv;
354
355         *val = sens_priv->settings[GAIN_IDX];
356         return 0;
357 }
358
359 static int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val)
360 {
361         int err;
362         u8 data[2];
363         struct sd *sd = (struct sd *) gspca_dev;
364         struct s5k83a_priv *sens_priv = sd->sensor_priv;
365
366         sens_priv->settings[GAIN_IDX] = val;
367
368         data[0] = 0x00;
369         data[1] = 0x20;
370         err = m5602_write_sensor(sd, 0x14, data, 2);
371         if (err < 0)
372                 return err;
373
374         data[0] = 0x01;
375         data[1] = 0x00;
376         err = m5602_write_sensor(sd, 0x0d, data, 2);
377         if (err < 0)
378                 return err;
379
380         /* FIXME: This is not sane, we need to figure out the composition
381                   of these registers */
382         data[0] = val >> 3; /* gain, high 5 bits */
383         data[1] = val >> 1; /* gain, high 7 bits */
384         err = m5602_write_sensor(sd, S5K83A_GAIN, data, 2);
385
386         return err;
387 }
388
389 static int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val)
390 {
391         struct sd *sd = (struct sd *) gspca_dev;
392         struct s5k83a_priv *sens_priv = sd->sensor_priv;
393
394         *val = sens_priv->settings[BRIGHTNESS_IDX];
395         return 0;
396 }
397
398 static int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val)
399 {
400         int err;
401         u8 data[1];
402         struct sd *sd = (struct sd *) gspca_dev;
403         struct s5k83a_priv *sens_priv = sd->sensor_priv;
404
405         sens_priv->settings[BRIGHTNESS_IDX] = val;
406         data[0] = val;
407         err = m5602_write_sensor(sd, S5K83A_BRIGHTNESS, data, 1);
408         return err;
409 }
410
411 static int s5k83a_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
412 {
413         struct sd *sd = (struct sd *) gspca_dev;
414         struct s5k83a_priv *sens_priv = sd->sensor_priv;
415
416         *val = sens_priv->settings[EXPOSURE_IDX];
417         return 0;
418 }
419
420 static int s5k83a_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
421 {
422         int err;
423         u8 data[2];
424         struct sd *sd = (struct sd *) gspca_dev;
425         struct s5k83a_priv *sens_priv = sd->sensor_priv;
426
427         sens_priv->settings[EXPOSURE_IDX] = val;
428         data[0] = 0;
429         data[1] = val;
430         err = m5602_write_sensor(sd, S5K83A_EXPOSURE, data, 2);
431         return err;
432 }
433
434 static int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
435 {
436         struct sd *sd = (struct sd *) gspca_dev;
437         struct s5k83a_priv *sens_priv = sd->sensor_priv;
438
439         *val = sens_priv->settings[VFLIP_IDX];
440         return 0;
441 }
442
443 static int s5k83a_set_flip_real(struct gspca_dev *gspca_dev,
444                                 __s32 vflip, __s32 hflip)
445 {
446         int err;
447         u8 data[1];
448         struct sd *sd = (struct sd *) gspca_dev;
449
450         data[0] = 0x05;
451         err = m5602_write_sensor(sd, S5K83A_PAGE_MAP, data, 1);
452         if (err < 0)
453                 return err;
454
455         /* six bit is vflip, seven is hflip */
456         data[0] = S5K83A_FLIP_MASK;
457         data[0] = (vflip) ? data[0] | 0x40 : data[0];
458         data[0] = (hflip) ? data[0] | 0x80 : data[0];
459
460         err = m5602_write_sensor(sd, S5K83A_FLIP, data, 1);
461         if (err < 0)
462                 return err;
463
464         data[0] = (vflip) ? 0x0b : 0x0a;
465         err = m5602_write_sensor(sd, S5K83A_VFLIP_TUNE, data, 1);
466         if (err < 0)
467                 return err;
468
469         data[0] = (hflip) ? 0x0a : 0x0b;
470         err = m5602_write_sensor(sd, S5K83A_HFLIP_TUNE, data, 1);
471         return err;
472 }
473
474 static int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
475 {
476         int err;
477         u8 reg;
478         __s32 hflip;
479         struct sd *sd = (struct sd *) gspca_dev;
480         struct s5k83a_priv *sens_priv = sd->sensor_priv;
481
482         sens_priv->settings[VFLIP_IDX] = val;
483
484         s5k83a_get_hflip(gspca_dev, &hflip);
485
486         err = s5k83a_get_rotation(sd, &reg);
487         if (err < 0)
488                 return err;
489         if (reg) {
490                 val = !val;
491                 hflip = !hflip;
492         }
493
494         err = s5k83a_set_flip_real(gspca_dev, val, hflip);
495         return err;
496 }
497
498 static int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
499 {
500         struct sd *sd = (struct sd *) gspca_dev;
501         struct s5k83a_priv *sens_priv = sd->sensor_priv;
502
503         *val = sens_priv->settings[HFLIP_IDX];
504         return 0;
505 }
506
507 static int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
508 {
509         int err;
510         u8 reg;
511         __s32 vflip;
512         struct sd *sd = (struct sd *) gspca_dev;
513         struct s5k83a_priv *sens_priv = sd->sensor_priv;
514
515         sens_priv->settings[HFLIP_IDX] = val;
516
517         s5k83a_get_vflip(gspca_dev, &vflip);
518
519         err = s5k83a_get_rotation(sd, &reg);
520         if (err < 0)
521                 return err;
522         if (reg) {
523                 val = !val;
524                 vflip = !vflip;
525         }
526
527         err = s5k83a_set_flip_real(gspca_dev, vflip, val);
528         return err;
529 }
530
531 static int s5k83a_set_led_indication(struct sd *sd, u8 val)
532 {
533         int err = 0;
534         u8 data[1];
535
536         err = m5602_read_bridge(sd, M5602_XB_GPIO_DAT, data);
537         if (err < 0)
538                 return err;
539
540         if (val)
541                 data[0] = data[0] | S5K83A_GPIO_LED_MASK;
542         else
543                 data[0] = data[0] & ~S5K83A_GPIO_LED_MASK;
544
545         err = m5602_write_bridge(sd, M5602_XB_GPIO_DAT, data[0]);
546
547         return err;
548 }
549
550 /* Get camera rotation on Acer notebooks */
551 static int s5k83a_get_rotation(struct sd *sd, u8 *reg_data)
552 {
553         int err = m5602_read_bridge(sd, M5602_XB_GPIO_DAT, reg_data);
554         *reg_data = (*reg_data & S5K83A_GPIO_ROTATION_MASK) ? 0 : 1;
555         return err;
556 }
557
558 static void s5k83a_dump_registers(struct sd *sd)
559 {
560         int address;
561         u8 page, old_page;
562         m5602_read_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1);
563
564         for (page = 0; page < 16; page++) {
565                 m5602_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1);
566                 info("Dumping the s5k83a register state for page 0x%x", page);
567                 for (address = 0; address <= 0xff; address++) {
568                         u8 val = 0;
569                         m5602_read_sensor(sd, address, &val, 1);
570                         info("register 0x%x contains 0x%x",
571                              address, val);
572                 }
573         }
574         info("s5k83a register state dump complete");
575
576         for (page = 0; page < 16; page++) {
577                 m5602_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1);
578                 info("Probing for which registers that are read/write "
579                                 "for page 0x%x", page);
580                 for (address = 0; address <= 0xff; address++) {
581                         u8 old_val, ctrl_val, test_val = 0xff;
582
583                         m5602_read_sensor(sd, address, &old_val, 1);
584                         m5602_write_sensor(sd, address, &test_val, 1);
585                         m5602_read_sensor(sd, address, &ctrl_val, 1);
586
587                         if (ctrl_val == test_val)
588                                 info("register 0x%x is writeable", address);
589                         else
590                                 info("register 0x%x is read only", address);
591
592                         /* Restore original val */
593                         m5602_write_sensor(sd, address, &old_val, 1);
594                 }
595         }
596         info("Read/write register probing complete");
597         m5602_write_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1);
598 }