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);