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
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
21
#include <linux/kthread.h>
22
#include "m5602_s5k83a.h"
24
static int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val);
25
static int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
26
static int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val);
27
static int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val);
28
static int s5k83a_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
29
static int s5k83a_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
30
static int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
31
static int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
32
static int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
33
static int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
35
static struct v4l2_pix_format s5k83a_modes[] = {
44
.colorspace = V4L2_COLORSPACE_SRGB,
49
static const struct ctrl s5k83a_ctrls[] = {
54
.type = V4L2_CTRL_TYPE_INTEGER,
59
.default_value = S5K83A_DEFAULT_GAIN,
60
.flags = V4L2_CTRL_FLAG_SLIDER
62
.set = s5k83a_set_gain,
63
.get = s5k83a_get_gain
66
#define BRIGHTNESS_IDX 1
69
.id = V4L2_CID_BRIGHTNESS,
70
.type = V4L2_CTRL_TYPE_INTEGER,
75
.default_value = S5K83A_DEFAULT_BRIGHTNESS,
76
.flags = V4L2_CTRL_FLAG_SLIDER
78
.set = s5k83a_set_brightness,
79
.get = s5k83a_get_brightness,
81
#define EXPOSURE_IDX 2
84
.id = V4L2_CID_EXPOSURE,
85
.type = V4L2_CTRL_TYPE_INTEGER,
88
.maximum = S5K83A_MAXIMUM_EXPOSURE,
90
.default_value = S5K83A_DEFAULT_EXPOSURE,
91
.flags = V4L2_CTRL_FLAG_SLIDER
93
.set = s5k83a_set_exposure,
94
.get = s5k83a_get_exposure
100
.type = V4L2_CTRL_TYPE_BOOLEAN,
101
.name = "horizontal flip",
107
.set = s5k83a_set_hflip,
108
.get = s5k83a_get_hflip
113
.id = V4L2_CID_VFLIP,
114
.type = V4L2_CTRL_TYPE_BOOLEAN,
115
.name = "vertical flip",
121
.set = s5k83a_set_vflip,
122
.get = s5k83a_get_vflip
126
static void s5k83a_dump_registers(struct sd *sd);
127
static int s5k83a_get_rotation(struct sd *sd, u8 *reg_data);
128
static int s5k83a_set_led_indication(struct sd *sd, u8 val);
129
static int s5k83a_set_flip_real(struct gspca_dev *gspca_dev,
130
__s32 vflip, __s32 hflip);
132
int s5k83a_probe(struct sd *sd)
134
struct s5k83a_priv *sens_priv;
135
u8 prod_id = 0, ver_id = 0;
139
if (force_sensor == S5K83A_SENSOR) {
140
pr_info("Forcing a %s sensor\n", s5k83a.name);
143
/* If we want to force another sensor, don't try to probe this
148
PDEBUG(D_PROBE, "Probing for a s5k83a sensor");
150
/* Preinit the sensor */
151
for (i = 0; i < ARRAY_SIZE(preinit_s5k83a) && !err; i++) {
152
u8 data[2] = {preinit_s5k83a[i][2], preinit_s5k83a[i][3]};
153
if (preinit_s5k83a[i][0] == SENSOR)
154
err = m5602_write_sensor(sd, preinit_s5k83a[i][1],
157
err = m5602_write_bridge(sd, preinit_s5k83a[i][1],
161
/* We don't know what register (if any) that contain the product id
162
* Just pick the first addresses that seem to produce the same results
163
* on multiple machines */
164
if (m5602_read_sensor(sd, 0x00, &prod_id, 1))
167
if (m5602_read_sensor(sd, 0x01, &ver_id, 1))
170
if ((prod_id == 0xff) || (ver_id == 0xff))
173
pr_info("Detected a s5k83a sensor\n");
177
sizeof(struct s5k83a_priv), GFP_KERNEL);
181
sens_priv->settings =
182
kmalloc(sizeof(s32)*ARRAY_SIZE(s5k83a_ctrls), GFP_KERNEL);
183
if (!sens_priv->settings) {
188
sd->gspca_dev.cam.cam_mode = s5k83a_modes;
189
sd->gspca_dev.cam.nmodes = ARRAY_SIZE(s5k83a_modes);
190
sd->desc->ctrls = s5k83a_ctrls;
191
sd->desc->nctrls = ARRAY_SIZE(s5k83a_ctrls);
193
/* null the pointer! thread is't running now */
194
sens_priv->rotation_thread = NULL;
196
for (i = 0; i < ARRAY_SIZE(s5k83a_ctrls); i++)
197
sens_priv->settings[i] = s5k83a_ctrls[i].qctrl.default_value;
199
sd->sensor_priv = sens_priv;
203
int s5k83a_init(struct sd *sd)
206
s32 *sensor_settings =
207
((struct s5k83a_priv *) sd->sensor_priv)->settings;
209
for (i = 0; i < ARRAY_SIZE(init_s5k83a) && !err; i++) {
210
u8 data[2] = {0x00, 0x00};
212
switch (init_s5k83a[i][0]) {
214
err = m5602_write_bridge(sd,
220
data[0] = init_s5k83a[i][2];
221
err = m5602_write_sensor(sd,
222
init_s5k83a[i][1], data, 1);
226
data[0] = init_s5k83a[i][2];
227
data[1] = init_s5k83a[i][3];
228
err = m5602_write_sensor(sd,
229
init_s5k83a[i][1], data, 2);
232
pr_info("Invalid stream command, exiting init\n");
238
s5k83a_dump_registers(sd);
240
err = s5k83a_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]);
244
err = s5k83a_set_brightness(&sd->gspca_dev,
245
sensor_settings[BRIGHTNESS_IDX]);
249
err = s5k83a_set_exposure(&sd->gspca_dev,
250
sensor_settings[EXPOSURE_IDX]);
254
err = s5k83a_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]);
258
err = s5k83a_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]);
263
static int rotation_thread_function(void *data)
265
struct sd *sd = (struct sd *) data;
266
struct s5k83a_priv *sens_priv = sd->sensor_priv;
267
u8 reg, previous_rotation = 0;
270
set_current_state(TASK_INTERRUPTIBLE);
271
while (!schedule_timeout(100)) {
272
if (mutex_lock_interruptible(&sd->gspca_dev.usb_lock))
275
s5k83a_get_rotation(sd, ®);
276
if (previous_rotation != reg) {
277
previous_rotation = reg;
278
pr_info("Camera was flipped\n");
280
s5k83a_get_vflip((struct gspca_dev *) sd, &vflip);
281
s5k83a_get_hflip((struct gspca_dev *) sd, &hflip);
287
s5k83a_set_flip_real((struct gspca_dev *) sd,
291
mutex_unlock(&sd->gspca_dev.usb_lock);
292
set_current_state(TASK_INTERRUPTIBLE);
295
/* return to "front" flip */
296
if (previous_rotation) {
297
s5k83a_get_vflip((struct gspca_dev *) sd, &vflip);
298
s5k83a_get_hflip((struct gspca_dev *) sd, &hflip);
299
s5k83a_set_flip_real((struct gspca_dev *) sd, vflip, hflip);
302
sens_priv->rotation_thread = NULL;
306
int s5k83a_start(struct sd *sd)
309
struct s5k83a_priv *sens_priv = sd->sensor_priv;
311
/* Create another thread, polling the GPIO ports of the camera to check
312
if it got rotated. This is how the windows driver does it so we have
313
to assume that there is no better way of accomplishing this */
314
sens_priv->rotation_thread = kthread_create(rotation_thread_function,
315
sd, "rotation thread");
316
wake_up_process(sens_priv->rotation_thread);
318
/* Preinit the sensor */
319
for (i = 0; i < ARRAY_SIZE(start_s5k83a) && !err; i++) {
320
u8 data[2] = {start_s5k83a[i][2], start_s5k83a[i][3]};
321
if (start_s5k83a[i][0] == SENSOR)
322
err = m5602_write_sensor(sd, start_s5k83a[i][1],
325
err = m5602_write_bridge(sd, start_s5k83a[i][1],
331
return s5k83a_set_led_indication(sd, 1);
334
int s5k83a_stop(struct sd *sd)
336
struct s5k83a_priv *sens_priv = sd->sensor_priv;
338
if (sens_priv->rotation_thread)
339
kthread_stop(sens_priv->rotation_thread);
341
return s5k83a_set_led_indication(sd, 0);
344
void s5k83a_disconnect(struct sd *sd)
346
struct s5k83a_priv *sens_priv = sd->sensor_priv;
351
kfree(sens_priv->settings);
355
static int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
357
struct sd *sd = (struct sd *) gspca_dev;
358
struct s5k83a_priv *sens_priv = sd->sensor_priv;
360
*val = sens_priv->settings[GAIN_IDX];
364
static int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val)
368
struct sd *sd = (struct sd *) gspca_dev;
369
struct s5k83a_priv *sens_priv = sd->sensor_priv;
371
sens_priv->settings[GAIN_IDX] = val;
375
err = m5602_write_sensor(sd, 0x14, data, 2);
381
err = m5602_write_sensor(sd, 0x0d, data, 2);
385
/* FIXME: This is not sane, we need to figure out the composition
386
of these registers */
387
data[0] = val >> 3; /* gain, high 5 bits */
388
data[1] = val >> 1; /* gain, high 7 bits */
389
err = m5602_write_sensor(sd, S5K83A_GAIN, data, 2);
394
static int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val)
396
struct sd *sd = (struct sd *) gspca_dev;
397
struct s5k83a_priv *sens_priv = sd->sensor_priv;
399
*val = sens_priv->settings[BRIGHTNESS_IDX];
403
static int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val)
407
struct sd *sd = (struct sd *) gspca_dev;
408
struct s5k83a_priv *sens_priv = sd->sensor_priv;
410
sens_priv->settings[BRIGHTNESS_IDX] = val;
412
err = m5602_write_sensor(sd, S5K83A_BRIGHTNESS, data, 1);
416
static int s5k83a_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
418
struct sd *sd = (struct sd *) gspca_dev;
419
struct s5k83a_priv *sens_priv = sd->sensor_priv;
421
*val = sens_priv->settings[EXPOSURE_IDX];
425
static int s5k83a_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
429
struct sd *sd = (struct sd *) gspca_dev;
430
struct s5k83a_priv *sens_priv = sd->sensor_priv;
432
sens_priv->settings[EXPOSURE_IDX] = val;
435
err = m5602_write_sensor(sd, S5K83A_EXPOSURE, data, 2);
439
static int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
441
struct sd *sd = (struct sd *) gspca_dev;
442
struct s5k83a_priv *sens_priv = sd->sensor_priv;
444
*val = sens_priv->settings[VFLIP_IDX];
448
static int s5k83a_set_flip_real(struct gspca_dev *gspca_dev,
449
__s32 vflip, __s32 hflip)
453
struct sd *sd = (struct sd *) gspca_dev;
456
err = m5602_write_sensor(sd, S5K83A_PAGE_MAP, data, 1);
460
/* six bit is vflip, seven is hflip */
461
data[0] = S5K83A_FLIP_MASK;
462
data[0] = (vflip) ? data[0] | 0x40 : data[0];
463
data[0] = (hflip) ? data[0] | 0x80 : data[0];
465
err = m5602_write_sensor(sd, S5K83A_FLIP, data, 1);
469
data[0] = (vflip) ? 0x0b : 0x0a;
470
err = m5602_write_sensor(sd, S5K83A_VFLIP_TUNE, data, 1);
474
data[0] = (hflip) ? 0x0a : 0x0b;
475
err = m5602_write_sensor(sd, S5K83A_HFLIP_TUNE, data, 1);
479
static int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
484
struct sd *sd = (struct sd *) gspca_dev;
485
struct s5k83a_priv *sens_priv = sd->sensor_priv;
487
sens_priv->settings[VFLIP_IDX] = val;
489
s5k83a_get_hflip(gspca_dev, &hflip);
491
err = s5k83a_get_rotation(sd, ®);
499
err = s5k83a_set_flip_real(gspca_dev, val, hflip);
503
static int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
505
struct sd *sd = (struct sd *) gspca_dev;
506
struct s5k83a_priv *sens_priv = sd->sensor_priv;
508
*val = sens_priv->settings[HFLIP_IDX];
512
static int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
517
struct sd *sd = (struct sd *) gspca_dev;
518
struct s5k83a_priv *sens_priv = sd->sensor_priv;
520
sens_priv->settings[HFLIP_IDX] = val;
522
s5k83a_get_vflip(gspca_dev, &vflip);
524
err = s5k83a_get_rotation(sd, ®);
532
err = s5k83a_set_flip_real(gspca_dev, vflip, val);
536
static int s5k83a_set_led_indication(struct sd *sd, u8 val)
541
err = m5602_read_bridge(sd, M5602_XB_GPIO_DAT, data);
546
data[0] = data[0] | S5K83A_GPIO_LED_MASK;
548
data[0] = data[0] & ~S5K83A_GPIO_LED_MASK;
550
err = m5602_write_bridge(sd, M5602_XB_GPIO_DAT, data[0]);
555
/* Get camera rotation on Acer notebooks */
556
static int s5k83a_get_rotation(struct sd *sd, u8 *reg_data)
558
int err = m5602_read_bridge(sd, M5602_XB_GPIO_DAT, reg_data);
559
*reg_data = (*reg_data & S5K83A_GPIO_ROTATION_MASK) ? 0 : 1;
563
static void s5k83a_dump_registers(struct sd *sd)
567
m5602_read_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1);
569
for (page = 0; page < 16; page++) {
570
m5602_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1);
571
pr_info("Dumping the s5k83a register state for page 0x%x\n",
573
for (address = 0; address <= 0xff; address++) {
575
m5602_read_sensor(sd, address, &val, 1);
576
pr_info("register 0x%x contains 0x%x\n", address, val);
579
pr_info("s5k83a register state dump complete\n");
581
for (page = 0; page < 16; page++) {
582
m5602_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1);
583
pr_info("Probing for which registers that are read/write for page 0x%x\n",
585
for (address = 0; address <= 0xff; address++) {
586
u8 old_val, ctrl_val, test_val = 0xff;
588
m5602_read_sensor(sd, address, &old_val, 1);
589
m5602_write_sensor(sd, address, &test_val, 1);
590
m5602_read_sensor(sd, address, &ctrl_val, 1);
592
if (ctrl_val == test_val)
593
pr_info("register 0x%x is writeable\n",
596
pr_info("register 0x%x is read only\n",
599
/* Restore original val */
600
m5602_write_sensor(sd, address, &old_val, 1);
603
pr_info("Read/write register probing complete\n");
604
m5602_write_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1);