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 <linux/slab.h>
21 #include "m5602_s5k83a.h"
23 static int s5k83a_set_gain(struct gspca_dev
*gspca_dev
, __s32 val
);
24 static int s5k83a_get_gain(struct gspca_dev
*gspca_dev
, __s32
*val
);
25 static int s5k83a_set_brightness(struct gspca_dev
*gspca_dev
, __s32 val
);
26 static int s5k83a_get_brightness(struct gspca_dev
*gspca_dev
, __s32
*val
);
27 static int s5k83a_set_exposure(struct gspca_dev
*gspca_dev
, __s32 val
);
28 static int s5k83a_get_exposure(struct gspca_dev
*gspca_dev
, __s32
*val
);
29 static int s5k83a_get_vflip(struct gspca_dev
*gspca_dev
, __s32
*val
);
30 static int s5k83a_set_vflip(struct gspca_dev
*gspca_dev
, __s32 val
);
31 static int s5k83a_get_hflip(struct gspca_dev
*gspca_dev
, __s32
*val
);
32 static int s5k83a_set_hflip(struct gspca_dev
*gspca_dev
, __s32 val
);
34 static struct v4l2_pix_format s5k83a_modes
[] = {
43 .colorspace
= V4L2_COLORSPACE_SRGB
,
48 static const struct ctrl s5k83a_ctrls
[] = {
53 .type
= V4L2_CTRL_TYPE_INTEGER
,
58 .default_value
= S5K83A_DEFAULT_GAIN
,
59 .flags
= V4L2_CTRL_FLAG_SLIDER
61 .set
= s5k83a_set_gain
,
62 .get
= s5k83a_get_gain
65 #define BRIGHTNESS_IDX 1
68 .id
= V4L2_CID_BRIGHTNESS
,
69 .type
= V4L2_CTRL_TYPE_INTEGER
,
74 .default_value
= S5K83A_DEFAULT_BRIGHTNESS
,
75 .flags
= V4L2_CTRL_FLAG_SLIDER
77 .set
= s5k83a_set_brightness
,
78 .get
= s5k83a_get_brightness
,
80 #define EXPOSURE_IDX 2
83 .id
= V4L2_CID_EXPOSURE
,
84 .type
= V4L2_CTRL_TYPE_INTEGER
,
87 .maximum
= S5K83A_MAXIMUM_EXPOSURE
,
89 .default_value
= S5K83A_DEFAULT_EXPOSURE
,
90 .flags
= V4L2_CTRL_FLAG_SLIDER
92 .set
= s5k83a_set_exposure
,
93 .get
= s5k83a_get_exposure
99 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
100 .name
= "horizontal flip",
106 .set
= s5k83a_set_hflip
,
107 .get
= s5k83a_get_hflip
112 .id
= V4L2_CID_VFLIP
,
113 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
114 .name
= "vertical flip",
120 .set
= s5k83a_set_vflip
,
121 .get
= s5k83a_get_vflip
125 static void s5k83a_dump_registers(struct sd
*sd
);
126 static int s5k83a_get_rotation(struct sd
*sd
, u8
*reg_data
);
127 static int s5k83a_set_led_indication(struct sd
*sd
, u8 val
);
128 static int s5k83a_set_flip_real(struct gspca_dev
*gspca_dev
,
129 __s32 vflip
, __s32 hflip
);
131 int s5k83a_probe(struct sd
*sd
)
133 struct s5k83a_priv
*sens_priv
;
134 u8 prod_id
= 0, ver_id
= 0;
138 if (force_sensor
== S5K83A_SENSOR
) {
139 info("Forcing a %s sensor", s5k83a
.name
);
142 /* If we want to force another sensor, don't try to probe this
147 PDEBUG(D_PROBE
, "Probing for a s5k83a sensor");
149 /* Preinit the sensor */
150 for (i
= 0; i
< ARRAY_SIZE(preinit_s5k83a
) && !err
; i
++) {
151 u8 data
[2] = {preinit_s5k83a
[i
][2], preinit_s5k83a
[i
][3]};
152 if (preinit_s5k83a
[i
][0] == SENSOR
)
153 err
= m5602_write_sensor(sd
, preinit_s5k83a
[i
][1],
156 err
= m5602_write_bridge(sd
, preinit_s5k83a
[i
][1],
160 /* We don't know what register (if any) that contain the product id
161 * Just pick the first addresses that seem to produce the same results
162 * on multiple machines */
163 if (m5602_read_sensor(sd
, 0x00, &prod_id
, 1))
166 if (m5602_read_sensor(sd
, 0x01, &ver_id
, 1))
169 if ((prod_id
== 0xff) || (ver_id
== 0xff))
172 info("Detected a s5k83a sensor");
176 sizeof(struct s5k83a_priv
), GFP_KERNEL
);
180 sens_priv
->settings
=
181 kmalloc(sizeof(s32
)*ARRAY_SIZE(s5k83a_ctrls
), GFP_KERNEL
);
182 if (!sens_priv
->settings
) {
187 sd
->gspca_dev
.cam
.cam_mode
= s5k83a_modes
;
188 sd
->gspca_dev
.cam
.nmodes
= ARRAY_SIZE(s5k83a_modes
);
189 sd
->desc
->ctrls
= s5k83a_ctrls
;
190 sd
->desc
->nctrls
= ARRAY_SIZE(s5k83a_ctrls
);
192 /* null the pointer! thread is't running now */
193 sens_priv
->rotation_thread
= NULL
;
195 for (i
= 0; i
< ARRAY_SIZE(s5k83a_ctrls
); i
++)
196 sens_priv
->settings
[i
] = s5k83a_ctrls
[i
].qctrl
.default_value
;
198 sd
->sensor_priv
= sens_priv
;
202 int s5k83a_init(struct sd
*sd
)
205 s32
*sensor_settings
=
206 ((struct s5k83a_priv
*) sd
->sensor_priv
)->settings
;
208 for (i
= 0; i
< ARRAY_SIZE(init_s5k83a
) && !err
; i
++) {
209 u8 data
[2] = {0x00, 0x00};
211 switch (init_s5k83a
[i
][0]) {
213 err
= m5602_write_bridge(sd
,
219 data
[0] = init_s5k83a
[i
][2];
220 err
= m5602_write_sensor(sd
,
221 init_s5k83a
[i
][1], data
, 1);
225 data
[0] = init_s5k83a
[i
][2];
226 data
[1] = init_s5k83a
[i
][3];
227 err
= m5602_write_sensor(sd
,
228 init_s5k83a
[i
][1], data
, 2);
231 info("Invalid stream command, exiting init");
237 s5k83a_dump_registers(sd
);
239 err
= s5k83a_set_gain(&sd
->gspca_dev
, sensor_settings
[GAIN_IDX
]);
243 err
= s5k83a_set_brightness(&sd
->gspca_dev
,
244 sensor_settings
[BRIGHTNESS_IDX
]);
248 err
= s5k83a_set_exposure(&sd
->gspca_dev
,
249 sensor_settings
[EXPOSURE_IDX
]);
253 err
= s5k83a_set_hflip(&sd
->gspca_dev
, sensor_settings
[HFLIP_IDX
]);
257 err
= s5k83a_set_vflip(&sd
->gspca_dev
, sensor_settings
[VFLIP_IDX
]);
262 static int rotation_thread_function(void *data
)
264 struct sd
*sd
= (struct sd
*) data
;
265 struct s5k83a_priv
*sens_priv
= sd
->sensor_priv
;
266 u8 reg
, previous_rotation
= 0;
269 set_current_state(TASK_INTERRUPTIBLE
);
270 while (!schedule_timeout(100)) {
271 if (mutex_lock_interruptible(&sd
->gspca_dev
.usb_lock
))
274 s5k83a_get_rotation(sd
, ®
);
275 if (previous_rotation
!= reg
) {
276 previous_rotation
= reg
;
277 info("Camera was flipped");
279 s5k83a_get_vflip((struct gspca_dev
*) sd
, &vflip
);
280 s5k83a_get_hflip((struct gspca_dev
*) sd
, &hflip
);
286 s5k83a_set_flip_real((struct gspca_dev
*) sd
,
290 mutex_unlock(&sd
->gspca_dev
.usb_lock
);
291 set_current_state(TASK_INTERRUPTIBLE
);
294 /* return to "front" flip */
295 if (previous_rotation
) {
296 s5k83a_get_vflip((struct gspca_dev
*) sd
, &vflip
);
297 s5k83a_get_hflip((struct gspca_dev
*) sd
, &hflip
);
298 s5k83a_set_flip_real((struct gspca_dev
*) sd
, vflip
, hflip
);
301 sens_priv
->rotation_thread
= NULL
;
305 int s5k83a_start(struct sd
*sd
)
308 struct s5k83a_priv
*sens_priv
= sd
->sensor_priv
;
310 /* Create another thread, polling the GPIO ports of the camera to check
311 if it got rotated. This is how the windows driver does it so we have
312 to assume that there is no better way of accomplishing this */
313 sens_priv
->rotation_thread
= kthread_create(rotation_thread_function
,
314 sd
, "rotation thread");
315 wake_up_process(sens_priv
->rotation_thread
);
317 /* Preinit the sensor */
318 for (i
= 0; i
< ARRAY_SIZE(start_s5k83a
) && !err
; i
++) {
319 u8 data
[2] = {start_s5k83a
[i
][2], start_s5k83a
[i
][3]};
320 if (start_s5k83a
[i
][0] == SENSOR
)
321 err
= m5602_write_sensor(sd
, start_s5k83a
[i
][1],
324 err
= m5602_write_bridge(sd
, start_s5k83a
[i
][1],
330 return s5k83a_set_led_indication(sd
, 1);
333 int s5k83a_stop(struct sd
*sd
)
335 struct s5k83a_priv
*sens_priv
= sd
->sensor_priv
;
337 if (sens_priv
->rotation_thread
)
338 kthread_stop(sens_priv
->rotation_thread
);
340 return s5k83a_set_led_indication(sd
, 0);
343 void s5k83a_disconnect(struct sd
*sd
)
345 struct s5k83a_priv
*sens_priv
= sd
->sensor_priv
;
350 kfree(sens_priv
->settings
);
354 static int s5k83a_get_gain(struct gspca_dev
*gspca_dev
, __s32
*val
)
356 struct sd
*sd
= (struct sd
*) gspca_dev
;
357 struct s5k83a_priv
*sens_priv
= sd
->sensor_priv
;
359 *val
= sens_priv
->settings
[GAIN_IDX
];
363 static int s5k83a_set_gain(struct gspca_dev
*gspca_dev
, __s32 val
)
367 struct sd
*sd
= (struct sd
*) gspca_dev
;
368 struct s5k83a_priv
*sens_priv
= sd
->sensor_priv
;
370 sens_priv
->settings
[GAIN_IDX
] = val
;
374 err
= m5602_write_sensor(sd
, 0x14, data
, 2);
380 err
= m5602_write_sensor(sd
, 0x0d, data
, 2);
384 /* FIXME: This is not sane, we need to figure out the composition
385 of these registers */
386 data
[0] = val
>> 3; /* gain, high 5 bits */
387 data
[1] = val
>> 1; /* gain, high 7 bits */
388 err
= m5602_write_sensor(sd
, S5K83A_GAIN
, data
, 2);
393 static int s5k83a_get_brightness(struct gspca_dev
*gspca_dev
, __s32
*val
)
395 struct sd
*sd
= (struct sd
*) gspca_dev
;
396 struct s5k83a_priv
*sens_priv
= sd
->sensor_priv
;
398 *val
= sens_priv
->settings
[BRIGHTNESS_IDX
];
402 static int s5k83a_set_brightness(struct gspca_dev
*gspca_dev
, __s32 val
)
406 struct sd
*sd
= (struct sd
*) gspca_dev
;
407 struct s5k83a_priv
*sens_priv
= sd
->sensor_priv
;
409 sens_priv
->settings
[BRIGHTNESS_IDX
] = val
;
411 err
= m5602_write_sensor(sd
, S5K83A_BRIGHTNESS
, data
, 1);
415 static int s5k83a_get_exposure(struct gspca_dev
*gspca_dev
, __s32
*val
)
417 struct sd
*sd
= (struct sd
*) gspca_dev
;
418 struct s5k83a_priv
*sens_priv
= sd
->sensor_priv
;
420 *val
= sens_priv
->settings
[EXPOSURE_IDX
];
424 static int s5k83a_set_exposure(struct gspca_dev
*gspca_dev
, __s32 val
)
428 struct sd
*sd
= (struct sd
*) gspca_dev
;
429 struct s5k83a_priv
*sens_priv
= sd
->sensor_priv
;
431 sens_priv
->settings
[EXPOSURE_IDX
] = val
;
434 err
= m5602_write_sensor(sd
, S5K83A_EXPOSURE
, data
, 2);
438 static int s5k83a_get_vflip(struct gspca_dev
*gspca_dev
, __s32
*val
)
440 struct sd
*sd
= (struct sd
*) gspca_dev
;
441 struct s5k83a_priv
*sens_priv
= sd
->sensor_priv
;
443 *val
= sens_priv
->settings
[VFLIP_IDX
];
447 static int s5k83a_set_flip_real(struct gspca_dev
*gspca_dev
,
448 __s32 vflip
, __s32 hflip
)
452 struct sd
*sd
= (struct sd
*) gspca_dev
;
455 err
= m5602_write_sensor(sd
, S5K83A_PAGE_MAP
, data
, 1);
459 /* six bit is vflip, seven is hflip */
460 data
[0] = S5K83A_FLIP_MASK
;
461 data
[0] = (vflip
) ? data
[0] | 0x40 : data
[0];
462 data
[0] = (hflip
) ? data
[0] | 0x80 : data
[0];
464 err
= m5602_write_sensor(sd
, S5K83A_FLIP
, data
, 1);
468 data
[0] = (vflip
) ? 0x0b : 0x0a;
469 err
= m5602_write_sensor(sd
, S5K83A_VFLIP_TUNE
, data
, 1);
473 data
[0] = (hflip
) ? 0x0a : 0x0b;
474 err
= m5602_write_sensor(sd
, S5K83A_HFLIP_TUNE
, data
, 1);
478 static int s5k83a_set_vflip(struct gspca_dev
*gspca_dev
, __s32 val
)
483 struct sd
*sd
= (struct sd
*) gspca_dev
;
484 struct s5k83a_priv
*sens_priv
= sd
->sensor_priv
;
486 sens_priv
->settings
[VFLIP_IDX
] = val
;
488 s5k83a_get_hflip(gspca_dev
, &hflip
);
490 err
= s5k83a_get_rotation(sd
, ®
);
498 err
= s5k83a_set_flip_real(gspca_dev
, val
, hflip
);
502 static int s5k83a_get_hflip(struct gspca_dev
*gspca_dev
, __s32
*val
)
504 struct sd
*sd
= (struct sd
*) gspca_dev
;
505 struct s5k83a_priv
*sens_priv
= sd
->sensor_priv
;
507 *val
= sens_priv
->settings
[HFLIP_IDX
];
511 static int s5k83a_set_hflip(struct gspca_dev
*gspca_dev
, __s32 val
)
516 struct sd
*sd
= (struct sd
*) gspca_dev
;
517 struct s5k83a_priv
*sens_priv
= sd
->sensor_priv
;
519 sens_priv
->settings
[HFLIP_IDX
] = val
;
521 s5k83a_get_vflip(gspca_dev
, &vflip
);
523 err
= s5k83a_get_rotation(sd
, ®
);
531 err
= s5k83a_set_flip_real(gspca_dev
, vflip
, val
);
535 static int s5k83a_set_led_indication(struct sd
*sd
, u8 val
)
540 err
= m5602_read_bridge(sd
, M5602_XB_GPIO_DAT
, data
);
545 data
[0] = data
[0] | S5K83A_GPIO_LED_MASK
;
547 data
[0] = data
[0] & ~S5K83A_GPIO_LED_MASK
;
549 err
= m5602_write_bridge(sd
, M5602_XB_GPIO_DAT
, data
[0]);
554 /* Get camera rotation on Acer notebooks */
555 static int s5k83a_get_rotation(struct sd
*sd
, u8
*reg_data
)
557 int err
= m5602_read_bridge(sd
, M5602_XB_GPIO_DAT
, reg_data
);
558 *reg_data
= (*reg_data
& S5K83A_GPIO_ROTATION_MASK
) ? 0 : 1;
562 static void s5k83a_dump_registers(struct sd
*sd
)
566 m5602_read_sensor(sd
, S5K83A_PAGE_MAP
, &old_page
, 1);
568 for (page
= 0; page
< 16; page
++) {
569 m5602_write_sensor(sd
, S5K83A_PAGE_MAP
, &page
, 1);
570 info("Dumping the s5k83a register state for page 0x%x", page
);
571 for (address
= 0; address
<= 0xff; address
++) {
573 m5602_read_sensor(sd
, address
, &val
, 1);
574 info("register 0x%x contains 0x%x",
578 info("s5k83a register state dump complete");
580 for (page
= 0; page
< 16; page
++) {
581 m5602_write_sensor(sd
, S5K83A_PAGE_MAP
, &page
, 1);
582 info("Probing for which registers that are read/write "
583 "for page 0x%x", page
);
584 for (address
= 0; address
<= 0xff; address
++) {
585 u8 old_val
, ctrl_val
, test_val
= 0xff;
587 m5602_read_sensor(sd
, address
, &old_val
, 1);
588 m5602_write_sensor(sd
, address
, &test_val
, 1);
589 m5602_read_sensor(sd
, address
, &ctrl_val
, 1);
591 if (ctrl_val
== test_val
)
592 info("register 0x%x is writeable", address
);
594 info("register 0x%x is read only", address
);
596 /* Restore original val */
597 m5602_write_sensor(sd
, address
, &old_val
, 1);
600 info("Read/write register probing complete");
601 m5602_write_sensor(sd
, S5K83A_PAGE_MAP
, &old_page
, 1);