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 PDEBUG(D_PROBE
, "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
) {
186 sd
->gspca_dev
.cam
.cam_mode
= s5k83a_modes
;
187 sd
->gspca_dev
.cam
.nmodes
= ARRAY_SIZE(s5k83a_modes
);
188 sd
->desc
->ctrls
= s5k83a_ctrls
;
189 sd
->desc
->nctrls
= ARRAY_SIZE(s5k83a_ctrls
);
191 /* null the pointer! thread is't running now */
192 sens_priv
->rotation_thread
= NULL
;
194 for (i
= 0; i
< ARRAY_SIZE(s5k83a_ctrls
); i
++)
195 sens_priv
->settings
[i
] = s5k83a_ctrls
[i
].qctrl
.default_value
;
197 sd
->sensor_priv
= sens_priv
;
201 int s5k83a_init(struct sd
*sd
)
204 s32
*sensor_settings
=
205 ((struct s5k83a_priv
*) sd
->sensor_priv
)->settings
;
207 for (i
= 0; i
< ARRAY_SIZE(init_s5k83a
) && !err
; i
++) {
208 u8 data
[2] = {0x00, 0x00};
210 switch (init_s5k83a
[i
][0]) {
212 err
= m5602_write_bridge(sd
,
218 data
[0] = init_s5k83a
[i
][2];
219 err
= m5602_write_sensor(sd
,
220 init_s5k83a
[i
][1], data
, 1);
224 data
[0] = init_s5k83a
[i
][2];
225 data
[1] = init_s5k83a
[i
][3];
226 err
= m5602_write_sensor(sd
,
227 init_s5k83a
[i
][1], data
, 2);
230 info("Invalid stream command, exiting init");
236 s5k83a_dump_registers(sd
);
238 err
= s5k83a_set_gain(&sd
->gspca_dev
, sensor_settings
[GAIN_IDX
]);
242 err
= s5k83a_set_brightness(&sd
->gspca_dev
,
243 sensor_settings
[BRIGHTNESS_IDX
]);
247 err
= s5k83a_set_exposure(&sd
->gspca_dev
,
248 sensor_settings
[EXPOSURE_IDX
]);
252 err
= s5k83a_set_hflip(&sd
->gspca_dev
, sensor_settings
[HFLIP_IDX
]);
256 err
= s5k83a_set_vflip(&sd
->gspca_dev
, sensor_settings
[VFLIP_IDX
]);
261 static int rotation_thread_function(void *data
)
263 struct sd
*sd
= (struct sd
*) data
;
264 struct s5k83a_priv
*sens_priv
= sd
->sensor_priv
;
265 u8 reg
, previous_rotation
= 0;
268 set_current_state(TASK_INTERRUPTIBLE
);
269 while (!schedule_timeout(100)) {
270 if (mutex_lock_interruptible(&sd
->gspca_dev
.usb_lock
))
273 s5k83a_get_rotation(sd
, ®
);
274 if (previous_rotation
!= reg
) {
275 previous_rotation
= reg
;
276 info("Camera was flipped");
278 s5k83a_get_vflip((struct gspca_dev
*) sd
, &vflip
);
279 s5k83a_get_hflip((struct gspca_dev
*) sd
, &hflip
);
285 s5k83a_set_flip_real((struct gspca_dev
*) sd
,
289 mutex_unlock(&sd
->gspca_dev
.usb_lock
);
290 set_current_state(TASK_INTERRUPTIBLE
);
293 /* return to "front" flip */
294 if (previous_rotation
) {
295 s5k83a_get_vflip((struct gspca_dev
*) sd
, &vflip
);
296 s5k83a_get_hflip((struct gspca_dev
*) sd
, &hflip
);
297 s5k83a_set_flip_real((struct gspca_dev
*) sd
, vflip
, hflip
);
300 sens_priv
->rotation_thread
= NULL
;
304 int s5k83a_start(struct sd
*sd
)
307 struct s5k83a_priv
*sens_priv
= sd
->sensor_priv
;
309 /* Create another thread, polling the GPIO ports of the camera to check
310 if it got rotated. This is how the windows driver does it so we have
311 to assume that there is no better way of accomplishing this */
312 sens_priv
->rotation_thread
= kthread_create(rotation_thread_function
,
313 sd
, "rotation thread");
314 wake_up_process(sens_priv
->rotation_thread
);
316 /* Preinit the sensor */
317 for (i
= 0; i
< ARRAY_SIZE(start_s5k83a
) && !err
; i
++) {
318 u8 data
[2] = {start_s5k83a
[i
][2], start_s5k83a
[i
][3]};
319 if (start_s5k83a
[i
][0] == SENSOR
)
320 err
= m5602_write_sensor(sd
, start_s5k83a
[i
][1],
323 err
= m5602_write_bridge(sd
, start_s5k83a
[i
][1],
329 return s5k83a_set_led_indication(sd
, 1);
332 int s5k83a_stop(struct sd
*sd
)
334 struct s5k83a_priv
*sens_priv
= sd
->sensor_priv
;
336 if (sens_priv
->rotation_thread
)
337 kthread_stop(sens_priv
->rotation_thread
);
339 return s5k83a_set_led_indication(sd
, 0);
342 void s5k83a_disconnect(struct sd
*sd
)
344 struct s5k83a_priv
*sens_priv
= sd
->sensor_priv
;
349 kfree(sens_priv
->settings
);
353 static int s5k83a_get_gain(struct gspca_dev
*gspca_dev
, __s32
*val
)
355 struct sd
*sd
= (struct sd
*) gspca_dev
;
356 struct s5k83a_priv
*sens_priv
= sd
->sensor_priv
;
358 *val
= sens_priv
->settings
[GAIN_IDX
];
362 static int s5k83a_set_gain(struct gspca_dev
*gspca_dev
, __s32 val
)
366 struct sd
*sd
= (struct sd
*) gspca_dev
;
367 struct s5k83a_priv
*sens_priv
= sd
->sensor_priv
;
369 sens_priv
->settings
[GAIN_IDX
] = val
;
373 err
= m5602_write_sensor(sd
, 0x14, data
, 2);
379 err
= m5602_write_sensor(sd
, 0x0d, data
, 2);
383 /* FIXME: This is not sane, we need to figure out the composition
384 of these registers */
385 data
[0] = val
>> 3; /* gain, high 5 bits */
386 data
[1] = val
>> 1; /* gain, high 7 bits */
387 err
= m5602_write_sensor(sd
, S5K83A_GAIN
, data
, 2);
392 static int s5k83a_get_brightness(struct gspca_dev
*gspca_dev
, __s32
*val
)
394 struct sd
*sd
= (struct sd
*) gspca_dev
;
395 struct s5k83a_priv
*sens_priv
= sd
->sensor_priv
;
397 *val
= sens_priv
->settings
[BRIGHTNESS_IDX
];
401 static int s5k83a_set_brightness(struct gspca_dev
*gspca_dev
, __s32 val
)
405 struct sd
*sd
= (struct sd
*) gspca_dev
;
406 struct s5k83a_priv
*sens_priv
= sd
->sensor_priv
;
408 sens_priv
->settings
[BRIGHTNESS_IDX
] = val
;
410 err
= m5602_write_sensor(sd
, S5K83A_BRIGHTNESS
, data
, 1);
414 static int s5k83a_get_exposure(struct gspca_dev
*gspca_dev
, __s32
*val
)
416 struct sd
*sd
= (struct sd
*) gspca_dev
;
417 struct s5k83a_priv
*sens_priv
= sd
->sensor_priv
;
419 *val
= sens_priv
->settings
[EXPOSURE_IDX
];
423 static int s5k83a_set_exposure(struct gspca_dev
*gspca_dev
, __s32 val
)
427 struct sd
*sd
= (struct sd
*) gspca_dev
;
428 struct s5k83a_priv
*sens_priv
= sd
->sensor_priv
;
430 sens_priv
->settings
[EXPOSURE_IDX
] = val
;
433 err
= m5602_write_sensor(sd
, S5K83A_EXPOSURE
, data
, 2);
437 static int s5k83a_get_vflip(struct gspca_dev
*gspca_dev
, __s32
*val
)
439 struct sd
*sd
= (struct sd
*) gspca_dev
;
440 struct s5k83a_priv
*sens_priv
= sd
->sensor_priv
;
442 *val
= sens_priv
->settings
[VFLIP_IDX
];
446 static int s5k83a_set_flip_real(struct gspca_dev
*gspca_dev
,
447 __s32 vflip
, __s32 hflip
)
451 struct sd
*sd
= (struct sd
*) gspca_dev
;
454 err
= m5602_write_sensor(sd
, S5K83A_PAGE_MAP
, data
, 1);
458 /* six bit is vflip, seven is hflip */
459 data
[0] = S5K83A_FLIP_MASK
;
460 data
[0] = (vflip
) ? data
[0] | 0x40 : data
[0];
461 data
[0] = (hflip
) ? data
[0] | 0x80 : data
[0];
463 err
= m5602_write_sensor(sd
, S5K83A_FLIP
, data
, 1);
467 data
[0] = (vflip
) ? 0x0b : 0x0a;
468 err
= m5602_write_sensor(sd
, S5K83A_VFLIP_TUNE
, data
, 1);
472 data
[0] = (hflip
) ? 0x0a : 0x0b;
473 err
= m5602_write_sensor(sd
, S5K83A_HFLIP_TUNE
, data
, 1);
477 static int s5k83a_set_vflip(struct gspca_dev
*gspca_dev
, __s32 val
)
482 struct sd
*sd
= (struct sd
*) gspca_dev
;
483 struct s5k83a_priv
*sens_priv
= sd
->sensor_priv
;
485 sens_priv
->settings
[VFLIP_IDX
] = val
;
487 s5k83a_get_hflip(gspca_dev
, &hflip
);
489 err
= s5k83a_get_rotation(sd
, ®
);
497 err
= s5k83a_set_flip_real(gspca_dev
, val
, hflip
);
501 static int s5k83a_get_hflip(struct gspca_dev
*gspca_dev
, __s32
*val
)
503 struct sd
*sd
= (struct sd
*) gspca_dev
;
504 struct s5k83a_priv
*sens_priv
= sd
->sensor_priv
;
506 *val
= sens_priv
->settings
[HFLIP_IDX
];
510 static int s5k83a_set_hflip(struct gspca_dev
*gspca_dev
, __s32 val
)
515 struct sd
*sd
= (struct sd
*) gspca_dev
;
516 struct s5k83a_priv
*sens_priv
= sd
->sensor_priv
;
518 sens_priv
->settings
[HFLIP_IDX
] = val
;
520 s5k83a_get_vflip(gspca_dev
, &vflip
);
522 err
= s5k83a_get_rotation(sd
, ®
);
530 err
= s5k83a_set_flip_real(gspca_dev
, vflip
, val
);
534 static int s5k83a_set_led_indication(struct sd
*sd
, u8 val
)
539 err
= m5602_read_bridge(sd
, M5602_XB_GPIO_DAT
, data
);
544 data
[0] = data
[0] | S5K83A_GPIO_LED_MASK
;
546 data
[0] = data
[0] & ~S5K83A_GPIO_LED_MASK
;
548 err
= m5602_write_bridge(sd
, M5602_XB_GPIO_DAT
, data
[0]);
553 /* Get camera rotation on Acer notebooks */
554 static int s5k83a_get_rotation(struct sd
*sd
, u8
*reg_data
)
556 int err
= m5602_read_bridge(sd
, M5602_XB_GPIO_DAT
, reg_data
);
557 *reg_data
= (*reg_data
& S5K83A_GPIO_ROTATION_MASK
) ? 0 : 1;
561 static void s5k83a_dump_registers(struct sd
*sd
)
565 m5602_read_sensor(sd
, S5K83A_PAGE_MAP
, &old_page
, 1);
567 for (page
= 0; page
< 16; page
++) {
568 m5602_write_sensor(sd
, S5K83A_PAGE_MAP
, &page
, 1);
569 info("Dumping the s5k83a register state for page 0x%x", page
);
570 for (address
= 0; address
<= 0xff; address
++) {
572 m5602_read_sensor(sd
, address
, &val
, 1);
573 info("register 0x%x contains 0x%x",
577 info("s5k83a register state dump complete");
579 for (page
= 0; page
< 16; page
++) {
580 m5602_write_sensor(sd
, S5K83A_PAGE_MAP
, &page
, 1);
581 info("Probing for which registers that are read/write "
582 "for page 0x%x", page
);
583 for (address
= 0; address
<= 0xff; address
++) {
584 u8 old_val
, ctrl_val
, test_val
= 0xff;
586 m5602_read_sensor(sd
, address
, &old_val
, 1);
587 m5602_write_sensor(sd
, address
, &test_val
, 1);
588 m5602_read_sensor(sd
, address
, &ctrl_val
, 1);
590 if (ctrl_val
== test_val
)
591 info("register 0x%x is writeable", address
);
593 info("register 0x%x is read only", address
);
595 /* Restore original val */
596 m5602_write_sensor(sd
, address
, &old_val
, 1);
599 info("Read/write register probing complete");
600 m5602_write_sensor(sd
, S5K83A_PAGE_MAP
, &old_page
, 1);