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[] = {
42 .colorspace = V4L2_COLORSPACE_SRGB,
47 static const struct ctrl s5k83a_ctrls[] = {
52 .type = V4L2_CTRL_TYPE_INTEGER,
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,
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,
86 .maximum = S5K83A_MAXIMUM_EXPOSURE,
88 .default_value = S5K83A_DEFAULT_EXPOSURE,
89 .flags = V4L2_CTRL_FLAG_SLIDER
91 .set = s5k83a_set_exposure,
92 .get = s5k83a_get_exposure
98 .type = V4L2_CTRL_TYPE_BOOLEAN,
99 .name = "horizontal flip",
105 .set = s5k83a_set_hflip,
106 .get = s5k83a_get_hflip
111 .id = V4L2_CID_VFLIP,
112 .type = V4L2_CTRL_TYPE_BOOLEAN,
113 .name = "vertical flip",
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;
137 if (force_sensor == S5K83A_SENSOR) {
138 info("Forcing a %s sensor", s5k83a.name);
141 /* If we want to force another sensor, don't try to probe this
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],
155 err = m5602_write_bridge(sd, preinit_s5k83a[i][1],
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))
165 if (m5602_read_sensor(sd, 0x01, &ver_id, 1))
168 if ((prod_id == 0xff) || (ver_id == 0xff))
171 info("Detected a s5k83a sensor");
175 sizeof(struct s5k83a_priv), GFP_KERNEL);
179 sens_priv->settings =
180 kmalloc(sizeof(s32)*ARRAY_SIZE(s5k83a_ctrls), GFP_KERNEL);
181 if (!sens_priv->settings)
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;
199 int s5k83a_init(struct sd *sd)
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]) {
210 err = m5602_write_bridge(sd,
216 data[0] = init_s5k83a[i][2];
217 err = m5602_write_sensor(sd,
218 init_s5k83a[i][1], data, 1);
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);
228 info("Invalid stream command, exiting init");
234 s5k83a_dump_registers(sd);
236 err = s5k83a_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]);
240 err = s5k83a_set_brightness(&sd->gspca_dev,
241 sensor_settings[BRIGHTNESS_IDX]);
245 err = s5k83a_set_exposure(&sd->gspca_dev,
246 sensor_settings[EXPOSURE_IDX]);
250 err = s5k83a_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]);
254 err = s5k83a_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]);
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;
266 set_current_state(TASK_INTERRUPTIBLE);
267 while (!schedule_timeout(100)) {
268 if (mutex_lock_interruptible(&sd->gspca_dev.usb_lock))
271 s5k83a_get_rotation(sd, ®);
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);
283 s5k83a_set_flip_real((struct gspca_dev *) sd, vflip, hflip);
286 mutex_unlock(&sd->gspca_dev.usb_lock);
287 set_current_state(TASK_INTERRUPTIBLE);
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);
297 sens_priv->rotation_thread = NULL;
301 int s5k83a_start(struct sd *sd)
304 struct s5k83a_priv *sens_priv = sd->sensor_priv;
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);
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],
320 err = m5602_write_bridge(sd, start_s5k83a[i][1],
326 return s5k83a_set_led_indication(sd, 1);
329 int s5k83a_stop(struct sd *sd)
331 struct s5k83a_priv *sens_priv = sd->sensor_priv;
333 if (sens_priv->rotation_thread)
334 kthread_stop(sens_priv->rotation_thread);
336 return s5k83a_set_led_indication(sd, 0);
339 void s5k83a_disconnect(struct sd *sd)
341 struct s5k83a_priv *sens_priv = sd->sensor_priv;
346 kfree(sens_priv->settings);
350 static int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
352 struct sd *sd = (struct sd *) gspca_dev;
353 struct s5k83a_priv *sens_priv = sd->sensor_priv;
355 *val = sens_priv->settings[GAIN_IDX];
359 static int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val)
363 struct sd *sd = (struct sd *) gspca_dev;
364 struct s5k83a_priv *sens_priv = sd->sensor_priv;
366 sens_priv->settings[GAIN_IDX] = val;
370 err = m5602_write_sensor(sd, 0x14, data, 2);
376 err = m5602_write_sensor(sd, 0x0d, data, 2);
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);
389 static int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val)
391 struct sd *sd = (struct sd *) gspca_dev;
392 struct s5k83a_priv *sens_priv = sd->sensor_priv;
394 *val = sens_priv->settings[BRIGHTNESS_IDX];
398 static int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val)
402 struct sd *sd = (struct sd *) gspca_dev;
403 struct s5k83a_priv *sens_priv = sd->sensor_priv;
405 sens_priv->settings[BRIGHTNESS_IDX] = val;
407 err = m5602_write_sensor(sd, S5K83A_BRIGHTNESS, data, 1);
411 static int s5k83a_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
413 struct sd *sd = (struct sd *) gspca_dev;
414 struct s5k83a_priv *sens_priv = sd->sensor_priv;
416 *val = sens_priv->settings[EXPOSURE_IDX];
420 static int s5k83a_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
424 struct sd *sd = (struct sd *) gspca_dev;
425 struct s5k83a_priv *sens_priv = sd->sensor_priv;
427 sens_priv->settings[EXPOSURE_IDX] = val;
430 err = m5602_write_sensor(sd, S5K83A_EXPOSURE, data, 2);
434 static int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
436 struct sd *sd = (struct sd *) gspca_dev;
437 struct s5k83a_priv *sens_priv = sd->sensor_priv;
439 *val = sens_priv->settings[VFLIP_IDX];
443 static int s5k83a_set_flip_real(struct gspca_dev *gspca_dev,
444 __s32 vflip, __s32 hflip)
448 struct sd *sd = (struct sd *) gspca_dev;
451 err = m5602_write_sensor(sd, S5K83A_PAGE_MAP, data, 1);
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];
460 err = m5602_write_sensor(sd, S5K83A_FLIP, data, 1);
464 data[0] = (vflip) ? 0x0b : 0x0a;
465 err = m5602_write_sensor(sd, S5K83A_VFLIP_TUNE, data, 1);
469 data[0] = (hflip) ? 0x0a : 0x0b;
470 err = m5602_write_sensor(sd, S5K83A_HFLIP_TUNE, data, 1);
474 static int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
479 struct sd *sd = (struct sd *) gspca_dev;
480 struct s5k83a_priv *sens_priv = sd->sensor_priv;
482 sens_priv->settings[VFLIP_IDX] = val;
484 s5k83a_get_hflip(gspca_dev, &hflip);
486 err = s5k83a_get_rotation(sd, ®);
494 err = s5k83a_set_flip_real(gspca_dev, val, hflip);
498 static int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
500 struct sd *sd = (struct sd *) gspca_dev;
501 struct s5k83a_priv *sens_priv = sd->sensor_priv;
503 *val = sens_priv->settings[HFLIP_IDX];
507 static int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
512 struct sd *sd = (struct sd *) gspca_dev;
513 struct s5k83a_priv *sens_priv = sd->sensor_priv;
515 sens_priv->settings[HFLIP_IDX] = val;
517 s5k83a_get_vflip(gspca_dev, &vflip);
519 err = s5k83a_get_rotation(sd, ®);
527 err = s5k83a_set_flip_real(gspca_dev, vflip, val);
531 static int s5k83a_set_led_indication(struct sd *sd, u8 val)
536 err = m5602_read_bridge(sd, M5602_XB_GPIO_DAT, data);
541 data[0] = data[0] | S5K83A_GPIO_LED_MASK;
543 data[0] = data[0] & ~S5K83A_GPIO_LED_MASK;
545 err = m5602_write_bridge(sd, M5602_XB_GPIO_DAT, data[0]);
550 /* Get camera rotation on Acer notebooks */
551 static int s5k83a_get_rotation(struct sd *sd, u8 *reg_data)
553 int err = m5602_read_bridge(sd, M5602_XB_GPIO_DAT, reg_data);
554 *reg_data = (*reg_data & S5K83A_GPIO_ROTATION_MASK) ? 0 : 1;
558 static void s5k83a_dump_registers(struct sd *sd)
562 m5602_read_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1);
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++) {
569 m5602_read_sensor(sd, address, &val, 1);
570 info("register 0x%x contains 0x%x",
574 info("s5k83a register state dump complete");
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;
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);
587 if (ctrl_val == test_val)
588 info("register 0x%x is writeable", address);
590 info("register 0x%x is read only", address);
592 /* Restore original val */
593 m5602_write_sensor(sd, address, &old_val, 1);
596 info("Read/write register probing complete");
597 m5602_write_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1);