Driver Core: devtmpfs - kernel-maintained tmpfs-based /dev
[linux/fpc-iii.git] / drivers / media / video / gspca / m5602 / m5602_s5k83a.c
blob7127321ace8cbe35e893dd40025bbb901e60ee51
1 /*
2 * Driver for the s5k83a sensor
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>
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
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.
19 #include <linux/kthread.h>
20 #include "m5602_s5k83a.h"
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);
33 static struct v4l2_pix_format s5k83a_modes[] = {
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
47 static const struct ctrl s5k83a_ctrls[] = {
48 #define GAIN_IDX 0
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
60 .set = s5k83a_set_gain,
61 .get = s5k83a_get_gain
64 #define BRIGHTNESS_IDX 1
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
76 .set = s5k83a_set_brightness,
77 .get = s5k83a_get_brightness,
79 #define EXPOSURE_IDX 2
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
91 .set = s5k83a_set_exposure,
92 .get = s5k83a_get_exposure
94 #define HFLIP_IDX 3
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
105 .set = s5k83a_set_hflip,
106 .get = s5k83a_get_hflip
108 #define VFLIP_IDX 4
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
119 .set = s5k83a_set_vflip,
120 .get = s5k83a_get_vflip
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);
130 int s5k83a_probe(struct sd *sd)
132 struct s5k83a_priv *sens_priv;
133 u8 prod_id = 0, ver_id = 0;
134 int i, err = 0;
136 if (force_sensor) {
137 if (force_sensor == S5K83A_SENSOR) {
138 info("Forcing a %s sensor", s5k83a.name);
139 goto sensor_found;
141 /* If we want to force another sensor, don't try to probe this
142 * one */
143 return -ENODEV;
146 info("Probing for a s5k83a sensor");
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]);
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;
165 if (m5602_read_sensor(sd, 0x01, &ver_id, 1))
166 return -ENODEV;
168 if ((prod_id == 0xff) || (ver_id == 0xff))
169 return -ENODEV;
170 else
171 info("Detected a s5k83a sensor");
173 sensor_found:
174 sens_priv = kmalloc(
175 sizeof(struct s5k83a_priv), GFP_KERNEL);
176 if (!sens_priv)
177 return -ENOMEM;
179 sens_priv->settings =
180 kmalloc(sizeof(s32)*ARRAY_SIZE(s5k83a_ctrls), GFP_KERNEL);
181 if (!sens_priv->settings)
182 return -ENOMEM;
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);
189 /* null the pointer! thread is't running now */
190 sens_priv->rotation_thread = NULL;
192 for (i = 0; i < ARRAY_SIZE(s5k83a_ctrls); i++)
193 sens_priv->settings[i] = s5k83a_ctrls[i].qctrl.default_value;
195 sd->sensor_priv = sens_priv;
196 return 0;
199 int s5k83a_init(struct sd *sd)
201 int i, err = 0;
202 s32 *sensor_settings =
203 ((struct s5k83a_priv *) sd->sensor_priv)->settings;
205 for (i = 0; i < ARRAY_SIZE(init_s5k83a) && !err; i++) {
206 u8 data[2] = {0x00, 0x00};
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;
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;
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;
233 if (dump_sensor)
234 s5k83a_dump_registers(sd);
236 err = s5k83a_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]);
237 if (err < 0)
238 return err;
240 err = s5k83a_set_brightness(&sd->gspca_dev,
241 sensor_settings[BRIGHTNESS_IDX]);
242 if (err < 0)
243 return err;
245 err = s5k83a_set_exposure(&sd->gspca_dev,
246 sensor_settings[EXPOSURE_IDX]);
247 if (err < 0)
248 return err;
250 err = s5k83a_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]);
251 if (err < 0)
252 return err;
254 err = s5k83a_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]);
256 return err;
259 static int rotation_thread_function(void *data)
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;
266 set_current_state(TASK_INTERRUPTIBLE);
267 while (!schedule_timeout(100)) {
268 if (mutex_lock_interruptible(&sd->gspca_dev.usb_lock))
269 break;
271 s5k83a_get_rotation(sd, &reg);
272 if (previous_rotation != reg) {
273 previous_rotation = reg;
274 info("Camera was flipped");
276 s5k83a_get_vflip((struct gspca_dev *) sd, &vflip);
277 s5k83a_get_hflip((struct gspca_dev *) sd, &hflip);
279 if (reg) {
280 vflip = !vflip;
281 hflip = !hflip;
283 s5k83a_set_flip_real((struct gspca_dev *) sd,
284 vflip, hflip);
287 mutex_unlock(&sd->gspca_dev.usb_lock);
288 set_current_state(TASK_INTERRUPTIBLE);
291 /* return to "front" flip */
292 if (previous_rotation) {
293 s5k83a_get_vflip((struct gspca_dev *) sd, &vflip);
294 s5k83a_get_hflip((struct gspca_dev *) sd, &hflip);
295 s5k83a_set_flip_real((struct gspca_dev *) sd, vflip, hflip);
298 sens_priv->rotation_thread = NULL;
299 return 0;
302 int s5k83a_start(struct sd *sd)
304 int i, err = 0;
305 struct s5k83a_priv *sens_priv = sd->sensor_priv;
307 /* Create another thread, polling the GPIO ports of the camera to check
308 if it got rotated. This is how the windows driver does it so we have
309 to assume that there is no better way of accomplishing this */
310 sens_priv->rotation_thread = kthread_create(rotation_thread_function,
311 sd, "rotation thread");
312 wake_up_process(sens_priv->rotation_thread);
314 /* Preinit the sensor */
315 for (i = 0; i < ARRAY_SIZE(start_s5k83a) && !err; i++) {
316 u8 data[2] = {start_s5k83a[i][2], start_s5k83a[i][3]};
317 if (start_s5k83a[i][0] == SENSOR)
318 err = m5602_write_sensor(sd, start_s5k83a[i][1],
319 data, 2);
320 else
321 err = m5602_write_bridge(sd, start_s5k83a[i][1],
322 data[0]);
324 if (err < 0)
325 return err;
327 return s5k83a_set_led_indication(sd, 1);
330 int s5k83a_stop(struct sd *sd)
332 struct s5k83a_priv *sens_priv = sd->sensor_priv;
334 if (sens_priv->rotation_thread)
335 kthread_stop(sens_priv->rotation_thread);
337 return s5k83a_set_led_indication(sd, 0);
340 void s5k83a_disconnect(struct sd *sd)
342 struct s5k83a_priv *sens_priv = sd->sensor_priv;
344 s5k83a_stop(sd);
346 sd->sensor = NULL;
347 kfree(sens_priv->settings);
348 kfree(sens_priv);
351 static int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
353 struct sd *sd = (struct sd *) gspca_dev;
354 struct s5k83a_priv *sens_priv = sd->sensor_priv;
356 *val = sens_priv->settings[GAIN_IDX];
357 return 0;
360 static int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val)
362 int err;
363 u8 data[2];
364 struct sd *sd = (struct sd *) gspca_dev;
365 struct s5k83a_priv *sens_priv = sd->sensor_priv;
367 sens_priv->settings[GAIN_IDX] = val;
369 data[0] = 0x00;
370 data[1] = 0x20;
371 err = m5602_write_sensor(sd, 0x14, data, 2);
372 if (err < 0)
373 return err;
375 data[0] = 0x01;
376 data[1] = 0x00;
377 err = m5602_write_sensor(sd, 0x0d, data, 2);
378 if (err < 0)
379 return err;
381 /* FIXME: This is not sane, we need to figure out the composition
382 of these registers */
383 data[0] = val >> 3; /* gain, high 5 bits */
384 data[1] = val >> 1; /* gain, high 7 bits */
385 err = m5602_write_sensor(sd, S5K83A_GAIN, data, 2);
387 return err;
390 static int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val)
392 struct sd *sd = (struct sd *) gspca_dev;
393 struct s5k83a_priv *sens_priv = sd->sensor_priv;
395 *val = sens_priv->settings[BRIGHTNESS_IDX];
396 return 0;
399 static int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val)
401 int err;
402 u8 data[1];
403 struct sd *sd = (struct sd *) gspca_dev;
404 struct s5k83a_priv *sens_priv = sd->sensor_priv;
406 sens_priv->settings[BRIGHTNESS_IDX] = val;
407 data[0] = val;
408 err = m5602_write_sensor(sd, S5K83A_BRIGHTNESS, data, 1);
409 return err;
412 static int s5k83a_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
414 struct sd *sd = (struct sd *) gspca_dev;
415 struct s5k83a_priv *sens_priv = sd->sensor_priv;
417 *val = sens_priv->settings[EXPOSURE_IDX];
418 return 0;
421 static int s5k83a_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
423 int err;
424 u8 data[2];
425 struct sd *sd = (struct sd *) gspca_dev;
426 struct s5k83a_priv *sens_priv = sd->sensor_priv;
428 sens_priv->settings[EXPOSURE_IDX] = val;
429 data[0] = 0;
430 data[1] = val;
431 err = m5602_write_sensor(sd, S5K83A_EXPOSURE, data, 2);
432 return err;
435 static int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
437 struct sd *sd = (struct sd *) gspca_dev;
438 struct s5k83a_priv *sens_priv = sd->sensor_priv;
440 *val = sens_priv->settings[VFLIP_IDX];
441 return 0;
444 static int s5k83a_set_flip_real(struct gspca_dev *gspca_dev,
445 __s32 vflip, __s32 hflip)
447 int err;
448 u8 data[1];
449 struct sd *sd = (struct sd *) gspca_dev;
451 data[0] = 0x05;
452 err = m5602_write_sensor(sd, S5K83A_PAGE_MAP, data, 1);
453 if (err < 0)
454 return err;
456 /* six bit is vflip, seven is hflip */
457 data[0] = S5K83A_FLIP_MASK;
458 data[0] = (vflip) ? data[0] | 0x40 : data[0];
459 data[0] = (hflip) ? data[0] | 0x80 : data[0];
461 err = m5602_write_sensor(sd, S5K83A_FLIP, data, 1);
462 if (err < 0)
463 return err;
465 data[0] = (vflip) ? 0x0b : 0x0a;
466 err = m5602_write_sensor(sd, S5K83A_VFLIP_TUNE, data, 1);
467 if (err < 0)
468 return err;
470 data[0] = (hflip) ? 0x0a : 0x0b;
471 err = m5602_write_sensor(sd, S5K83A_HFLIP_TUNE, data, 1);
472 return err;
475 static int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
477 int err;
478 u8 reg;
479 __s32 hflip;
480 struct sd *sd = (struct sd *) gspca_dev;
481 struct s5k83a_priv *sens_priv = sd->sensor_priv;
483 sens_priv->settings[VFLIP_IDX] = val;
485 s5k83a_get_hflip(gspca_dev, &hflip);
487 err = s5k83a_get_rotation(sd, &reg);
488 if (err < 0)
489 return err;
490 if (reg) {
491 val = !val;
492 hflip = !hflip;
495 err = s5k83a_set_flip_real(gspca_dev, val, hflip);
496 return err;
499 static int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
501 struct sd *sd = (struct sd *) gspca_dev;
502 struct s5k83a_priv *sens_priv = sd->sensor_priv;
504 *val = sens_priv->settings[HFLIP_IDX];
505 return 0;
508 static int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
510 int err;
511 u8 reg;
512 __s32 vflip;
513 struct sd *sd = (struct sd *) gspca_dev;
514 struct s5k83a_priv *sens_priv = sd->sensor_priv;
516 sens_priv->settings[HFLIP_IDX] = val;
518 s5k83a_get_vflip(gspca_dev, &vflip);
520 err = s5k83a_get_rotation(sd, &reg);
521 if (err < 0)
522 return err;
523 if (reg) {
524 val = !val;
525 vflip = !vflip;
528 err = s5k83a_set_flip_real(gspca_dev, vflip, val);
529 return err;
532 static int s5k83a_set_led_indication(struct sd *sd, u8 val)
534 int err = 0;
535 u8 data[1];
537 err = m5602_read_bridge(sd, M5602_XB_GPIO_DAT, data);
538 if (err < 0)
539 return err;
541 if (val)
542 data[0] = data[0] | S5K83A_GPIO_LED_MASK;
543 else
544 data[0] = data[0] & ~S5K83A_GPIO_LED_MASK;
546 err = m5602_write_bridge(sd, M5602_XB_GPIO_DAT, data[0]);
548 return err;
551 /* Get camera rotation on Acer notebooks */
552 static int s5k83a_get_rotation(struct sd *sd, u8 *reg_data)
554 int err = m5602_read_bridge(sd, M5602_XB_GPIO_DAT, reg_data);
555 *reg_data = (*reg_data & S5K83A_GPIO_ROTATION_MASK) ? 0 : 1;
556 return err;
559 static void s5k83a_dump_registers(struct sd *sd)
561 int address;
562 u8 page, old_page;
563 m5602_read_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1);
565 for (page = 0; page < 16; page++) {
566 m5602_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1);
567 info("Dumping the s5k83a register state for page 0x%x", page);
568 for (address = 0; address <= 0xff; address++) {
569 u8 val = 0;
570 m5602_read_sensor(sd, address, &val, 1);
571 info("register 0x%x contains 0x%x",
572 address, val);
575 info("s5k83a register state dump complete");
577 for (page = 0; page < 16; page++) {
578 m5602_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1);
579 info("Probing for which registers that are read/write "
580 "for page 0x%x", page);
581 for (address = 0; address <= 0xff; address++) {
582 u8 old_val, ctrl_val, test_val = 0xff;
584 m5602_read_sensor(sd, address, &old_val, 1);
585 m5602_write_sensor(sd, address, &test_val, 1);
586 m5602_read_sensor(sd, address, &ctrl_val, 1);
588 if (ctrl_val == test_val)
589 info("register 0x%x is writeable", address);
590 else
591 info("register 0x%x is read only", address);
593 /* Restore original val */
594 m5602_write_sensor(sd, address, &old_val, 1);
597 info("Read/write register probing complete");
598 m5602_write_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1);