1 // SPDX-License-Identifier: GPL-2.0-only
3 * Driver for the s5k83a sensor
5 * Copyright (C) 2008 Erik Andrén
6 * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
7 * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
9 * Portions of code to USB interface and ALi driver software,
10 * Copyright (c) 2006 Willem Duinker
11 * v4l2 interface modeled after the V4L2 driver
12 * for SN9C10x PC Camera Controllers
15 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
17 #include <linux/kthread.h>
18 #include "m5602_s5k83a.h"
20 static int s5k83a_s_ctrl(struct v4l2_ctrl
*ctrl
);
22 static const struct v4l2_ctrl_ops s5k83a_ctrl_ops
= {
23 .s_ctrl
= s5k83a_s_ctrl
,
26 static struct v4l2_pix_format s5k83a_modes
[] = {
35 .colorspace
= V4L2_COLORSPACE_SRGB
,
40 static const unsigned char preinit_s5k83a
[][4] = {
41 {BRIDGE
, M5602_XB_MCU_CLK_DIV
, 0x02, 0x00},
42 {BRIDGE
, M5602_XB_MCU_CLK_CTRL
, 0xb0, 0x00},
43 {BRIDGE
, M5602_XB_SEN_CLK_DIV
, 0x00, 0x00},
44 {BRIDGE
, M5602_XB_SEN_CLK_CTRL
, 0xb0, 0x00},
45 {BRIDGE
, M5602_XB_ADC_CTRL
, 0xc0, 0x00},
46 {BRIDGE
, M5602_XB_SENSOR_TYPE
, 0x0d, 0x00},
47 {BRIDGE
, M5602_XB_SENSOR_CTRL
, 0x00, 0x00},
49 {BRIDGE
, M5602_XB_SIG_INI
, 0x00, 0x00},
50 {BRIDGE
, M5602_XB_GPIO_DIR
, 0x1d, 0x00},
51 {BRIDGE
, M5602_XB_GPIO_DAT
, 0x08, 0x00},
52 {BRIDGE
, M5602_XB_GPIO_EN_H
, 0x3f, 0x00},
53 {BRIDGE
, M5602_XB_GPIO_DIR_H
, 0x3f, 0x00},
54 {BRIDGE
, M5602_XB_GPIO_DAT_H
, 0x00, 0x00},
55 {BRIDGE
, M5602_XB_GPIO_EN_L
, 0xff, 0x00},
56 {BRIDGE
, M5602_XB_GPIO_DIR_L
, 0xff, 0x00},
57 {BRIDGE
, M5602_XB_GPIO_DAT_L
, 0x00, 0x00},
58 {BRIDGE
, M5602_XB_SEN_CLK_DIV
, 0xb0, 0x00},
59 {BRIDGE
, M5602_XB_SEN_CLK_CTRL
, 0x80, 0x00},
60 {BRIDGE
, M5602_XB_SEN_CLK_DIV
, 0x00, 0x00},
61 {BRIDGE
, M5602_XB_SEN_CLK_CTRL
, 0xb0, 0x00},
62 {BRIDGE
, M5602_XB_ADC_CTRL
, 0xc0, 0x00},
63 {BRIDGE
, M5602_XB_SENSOR_TYPE
, 0x09, 0x00},
64 {BRIDGE
, M5602_XB_MCU_CLK_DIV
, 0x02, 0x00},
65 {BRIDGE
, M5602_XB_MCU_CLK_CTRL
, 0xb0, 0x00},
66 {BRIDGE
, M5602_XB_SEN_CLK_DIV
, 0x00, 0x00},
67 {BRIDGE
, M5602_XB_SEN_CLK_CTRL
, 0xf0, 0x00},
68 {BRIDGE
, M5602_XB_GPIO_DIR
, 0x1d, 0x00},
69 {BRIDGE
, M5602_XB_GPIO_DAT
, 0x1c, 0x00},
70 {BRIDGE
, M5602_XB_GPIO_EN_H
, 0x06, 0x00},
71 {BRIDGE
, M5602_XB_GPIO_DIR_H
, 0x06, 0x00},
72 {BRIDGE
, M5602_XB_GPIO_DAT_H
, 0x00, 0x00},
73 {BRIDGE
, M5602_XB_GPIO_EN_L
, 0x00, 0x00},
74 {BRIDGE
, M5602_XB_I2C_CLK_DIV
, 0x20, 0x00},
77 /* This could probably be considerably shortened.
78 I don't have the hardware to experiment with it, patches welcome
80 static const unsigned char init_s5k83a
[][4] = {
81 /* The following sequence is useless after a clean boot
82 but is necessary after resume from suspend */
83 {BRIDGE
, M5602_XB_GPIO_DIR
, 0x1d, 0x00},
84 {BRIDGE
, M5602_XB_GPIO_DAT
, 0x08, 0x00},
85 {BRIDGE
, M5602_XB_GPIO_EN_H
, 0x3f, 0x00},
86 {BRIDGE
, M5602_XB_GPIO_DIR_H
, 0x3f, 0x00},
87 {BRIDGE
, M5602_XB_GPIO_DAT_H
, 0x00, 0x00},
88 {BRIDGE
, M5602_XB_GPIO_EN_L
, 0xff, 0x00},
89 {BRIDGE
, M5602_XB_GPIO_DIR_L
, 0xff, 0x00},
90 {BRIDGE
, M5602_XB_GPIO_DAT_L
, 0x00, 0x00},
91 {BRIDGE
, M5602_XB_SEN_CLK_DIV
, 0xb0, 0x00},
92 {BRIDGE
, M5602_XB_SEN_CLK_CTRL
, 0x80, 0x00},
93 {BRIDGE
, M5602_XB_SEN_CLK_DIV
, 0x00, 0x00},
94 {BRIDGE
, M5602_XB_SEN_CLK_CTRL
, 0xb0, 0x00},
95 {BRIDGE
, M5602_XB_ADC_CTRL
, 0xc0, 0x00},
96 {BRIDGE
, M5602_XB_SENSOR_TYPE
, 0x09, 0x00},
97 {BRIDGE
, M5602_XB_MCU_CLK_DIV
, 0x02, 0x00},
98 {BRIDGE
, M5602_XB_MCU_CLK_CTRL
, 0xb0, 0x00},
99 {BRIDGE
, M5602_XB_SEN_CLK_DIV
, 0x00, 0x00},
100 {BRIDGE
, M5602_XB_SEN_CLK_CTRL
, 0xf0, 0x00},
101 {BRIDGE
, M5602_XB_GPIO_DIR
, 0x1d, 0x00},
102 {BRIDGE
, M5602_XB_GPIO_DAT
, 0x08, 0x00},
103 {BRIDGE
, M5602_XB_GPIO_EN_H
, 0x06, 0x00},
104 {BRIDGE
, M5602_XB_GPIO_DIR_H
, 0x06, 0x00},
105 {BRIDGE
, M5602_XB_GPIO_DAT_H
, 0x00, 0x00},
106 {BRIDGE
, M5602_XB_GPIO_EN_L
, 0x00, 0x00},
107 {BRIDGE
, M5602_XB_I2C_CLK_DIV
, 0x20, 0x00},
109 {SENSOR
, S5K83A_PAGE_MAP
, 0x04, 0x00},
110 {SENSOR
, 0xaf, 0x01, 0x00},
111 {SENSOR
, S5K83A_PAGE_MAP
, 0x00, 0x00},
112 {SENSOR
, 0x7b, 0xff, 0x00},
113 {SENSOR
, S5K83A_PAGE_MAP
, 0x05, 0x00},
114 {SENSOR
, 0x01, 0x50, 0x00},
115 {SENSOR
, 0x12, 0x20, 0x00},
116 {SENSOR
, 0x17, 0x40, 0x00},
117 {SENSOR
, 0x1c, 0x00, 0x00},
118 {SENSOR
, 0x02, 0x70, 0x00},
119 {SENSOR
, 0x03, 0x0b, 0x00},
120 {SENSOR
, 0x04, 0xf0, 0x00},
121 {SENSOR
, 0x05, 0x0b, 0x00},
122 {SENSOR
, 0x06, 0x71, 0x00},
123 {SENSOR
, 0x07, 0xe8, 0x00}, /* 488 */
124 {SENSOR
, 0x08, 0x02, 0x00},
125 {SENSOR
, 0x09, 0x88, 0x00}, /* 648 */
126 {SENSOR
, 0x14, 0x00, 0x00},
127 {SENSOR
, 0x15, 0x20, 0x00}, /* 32 */
128 {SENSOR
, 0x19, 0x00, 0x00},
129 {SENSOR
, 0x1a, 0x98, 0x00}, /* 152 */
130 {SENSOR
, 0x0f, 0x02, 0x00},
131 {SENSOR
, 0x10, 0xe5, 0x00}, /* 741 */
133 (this is value after boot, but after tries can be different) */
134 {SENSOR
, 0x00, 0x06, 0x00},
137 static const unsigned char start_s5k83a
[][4] = {
138 {BRIDGE
, M5602_XB_SEN_CLK_DIV
, 0x06, 0x00},
139 {BRIDGE
, M5602_XB_SEN_CLK_CTRL
, 0xb0, 0x00},
140 {BRIDGE
, M5602_XB_ADC_CTRL
, 0xc0, 0x00},
141 {BRIDGE
, M5602_XB_SENSOR_TYPE
, 0x09, 0x00},
142 {BRIDGE
, M5602_XB_LINE_OF_FRAME_H
, 0x81, 0x00},
143 {BRIDGE
, M5602_XB_PIX_OF_LINE_H
, 0x82, 0x00},
144 {BRIDGE
, M5602_XB_SIG_INI
, 0x01, 0x00},
145 {BRIDGE
, M5602_XB_VSYNC_PARA
, 0x00, 0x00},
146 {BRIDGE
, M5602_XB_VSYNC_PARA
, 0x00, 0x00},
147 {BRIDGE
, M5602_XB_VSYNC_PARA
, 0x00, 0x00},
148 {BRIDGE
, M5602_XB_VSYNC_PARA
, 0x00, 0x00},
149 {BRIDGE
, M5602_XB_VSYNC_PARA
, 0x01, 0x00},
150 {BRIDGE
, M5602_XB_VSYNC_PARA
, 0xe4, 0x00}, /* 484 */
151 {BRIDGE
, M5602_XB_VSYNC_PARA
, 0x00, 0x00},
152 {BRIDGE
, M5602_XB_VSYNC_PARA
, 0x00, 0x00},
153 {BRIDGE
, M5602_XB_SIG_INI
, 0x00, 0x00},
154 {BRIDGE
, M5602_XB_SIG_INI
, 0x02, 0x00},
155 {BRIDGE
, M5602_XB_HSYNC_PARA
, 0x00, 0x00},
156 {BRIDGE
, M5602_XB_HSYNC_PARA
, 0x00, 0x00},
157 {BRIDGE
, M5602_XB_HSYNC_PARA
, 0x02, 0x00},
158 {BRIDGE
, M5602_XB_HSYNC_PARA
, 0x7f, 0x00}, /* 639 */
159 {BRIDGE
, M5602_XB_SIG_INI
, 0x00, 0x00},
160 {BRIDGE
, M5602_XB_SEN_CLK_DIV
, 0x00, 0x00},
161 {BRIDGE
, M5602_XB_SEN_CLK_CTRL
, 0xb0, 0x00},
164 static void s5k83a_dump_registers(struct sd
*sd
);
165 static int s5k83a_get_rotation(struct sd
*sd
, u8
*reg_data
);
166 static int s5k83a_set_led_indication(struct sd
*sd
, u8 val
);
167 static int s5k83a_set_flip_real(struct gspca_dev
*gspca_dev
,
168 __s32 vflip
, __s32 hflip
);
170 int s5k83a_probe(struct sd
*sd
)
172 u8 prod_id
= 0, ver_id
= 0;
174 struct gspca_dev
*gspca_dev
= (struct gspca_dev
*)sd
;
177 if (force_sensor
== S5K83A_SENSOR
) {
178 pr_info("Forcing a %s sensor\n", s5k83a
.name
);
181 /* If we want to force another sensor, don't try to probe this
186 gspca_dbg(gspca_dev
, D_PROBE
, "Probing for a s5k83a sensor\n");
188 /* Preinit the sensor */
189 for (i
= 0; i
< ARRAY_SIZE(preinit_s5k83a
) && !err
; i
++) {
190 u8 data
[2] = {preinit_s5k83a
[i
][2], preinit_s5k83a
[i
][3]};
191 if (preinit_s5k83a
[i
][0] == SENSOR
)
192 err
= m5602_write_sensor(sd
, preinit_s5k83a
[i
][1],
195 err
= m5602_write_bridge(sd
, preinit_s5k83a
[i
][1],
199 /* We don't know what register (if any) that contain the product id
200 * Just pick the first addresses that seem to produce the same results
201 * on multiple machines */
202 if (m5602_read_sensor(sd
, 0x00, &prod_id
, 1))
205 if (m5602_read_sensor(sd
, 0x01, &ver_id
, 1))
208 if ((prod_id
== 0xff) || (ver_id
== 0xff))
211 pr_info("Detected a s5k83a sensor\n");
214 sd
->gspca_dev
.cam
.cam_mode
= s5k83a_modes
;
215 sd
->gspca_dev
.cam
.nmodes
= ARRAY_SIZE(s5k83a_modes
);
217 /* null the pointer! thread is't running now */
218 sd
->rotation_thread
= NULL
;
223 int s5k83a_init(struct sd
*sd
)
227 for (i
= 0; i
< ARRAY_SIZE(init_s5k83a
) && !err
; i
++) {
228 u8 data
[2] = {0x00, 0x00};
230 switch (init_s5k83a
[i
][0]) {
232 err
= m5602_write_bridge(sd
,
238 data
[0] = init_s5k83a
[i
][2];
239 err
= m5602_write_sensor(sd
,
240 init_s5k83a
[i
][1], data
, 1);
244 data
[0] = init_s5k83a
[i
][2];
245 data
[1] = init_s5k83a
[i
][3];
246 err
= m5602_write_sensor(sd
,
247 init_s5k83a
[i
][1], data
, 2);
250 pr_info("Invalid stream command, exiting init\n");
256 s5k83a_dump_registers(sd
);
261 int s5k83a_init_controls(struct sd
*sd
)
263 struct v4l2_ctrl_handler
*hdl
= &sd
->gspca_dev
.ctrl_handler
;
265 sd
->gspca_dev
.vdev
.ctrl_handler
= hdl
;
266 v4l2_ctrl_handler_init(hdl
, 6);
268 v4l2_ctrl_new_std(hdl
, &s5k83a_ctrl_ops
, V4L2_CID_BRIGHTNESS
,
269 0, 255, 1, S5K83A_DEFAULT_BRIGHTNESS
);
271 v4l2_ctrl_new_std(hdl
, &s5k83a_ctrl_ops
, V4L2_CID_EXPOSURE
,
272 0, S5K83A_MAXIMUM_EXPOSURE
, 1,
273 S5K83A_DEFAULT_EXPOSURE
);
275 v4l2_ctrl_new_std(hdl
, &s5k83a_ctrl_ops
, V4L2_CID_GAIN
,
276 0, 255, 1, S5K83A_DEFAULT_GAIN
);
278 sd
->hflip
= v4l2_ctrl_new_std(hdl
, &s5k83a_ctrl_ops
, V4L2_CID_HFLIP
,
280 sd
->vflip
= v4l2_ctrl_new_std(hdl
, &s5k83a_ctrl_ops
, V4L2_CID_VFLIP
,
284 pr_err("Could not initialize controls\n");
288 v4l2_ctrl_cluster(2, &sd
->hflip
);
293 static int rotation_thread_function(void *data
)
295 struct sd
*sd
= (struct sd
*) data
;
296 u8 reg
, previous_rotation
= 0;
299 set_current_state(TASK_INTERRUPTIBLE
);
300 while (!schedule_timeout(msecs_to_jiffies(100))) {
301 if (mutex_lock_interruptible(&sd
->gspca_dev
.usb_lock
))
304 s5k83a_get_rotation(sd
, ®
);
305 if (previous_rotation
!= reg
) {
306 previous_rotation
= reg
;
307 pr_info("Camera was flipped\n");
309 hflip
= sd
->hflip
->val
;
310 vflip
= sd
->vflip
->val
;
316 s5k83a_set_flip_real((struct gspca_dev
*) sd
,
320 mutex_unlock(&sd
->gspca_dev
.usb_lock
);
321 set_current_state(TASK_INTERRUPTIBLE
);
324 /* return to "front" flip */
325 if (previous_rotation
) {
326 hflip
= sd
->hflip
->val
;
327 vflip
= sd
->vflip
->val
;
328 s5k83a_set_flip_real((struct gspca_dev
*) sd
, vflip
, hflip
);
331 sd
->rotation_thread
= NULL
;
335 int s5k83a_start(struct sd
*sd
)
339 /* Create another thread, polling the GPIO ports of the camera to check
340 if it got rotated. This is how the windows driver does it so we have
341 to assume that there is no better way of accomplishing this */
342 sd
->rotation_thread
= kthread_run(rotation_thread_function
,
343 sd
, "rotation thread");
344 if (IS_ERR(sd
->rotation_thread
)) {
345 err
= PTR_ERR(sd
->rotation_thread
);
346 sd
->rotation_thread
= NULL
;
350 /* Preinit the sensor */
351 for (i
= 0; i
< ARRAY_SIZE(start_s5k83a
) && !err
; i
++) {
352 u8 data
[2] = {start_s5k83a
[i
][2], start_s5k83a
[i
][3]};
353 if (start_s5k83a
[i
][0] == SENSOR
)
354 err
= m5602_write_sensor(sd
, start_s5k83a
[i
][1],
357 err
= m5602_write_bridge(sd
, start_s5k83a
[i
][1],
363 return s5k83a_set_led_indication(sd
, 1);
366 int s5k83a_stop(struct sd
*sd
)
368 if (sd
->rotation_thread
)
369 kthread_stop(sd
->rotation_thread
);
371 return s5k83a_set_led_indication(sd
, 0);
374 void s5k83a_disconnect(struct sd
*sd
)
381 static int s5k83a_set_gain(struct gspca_dev
*gspca_dev
, __s32 val
)
385 struct sd
*sd
= (struct sd
*) gspca_dev
;
389 err
= m5602_write_sensor(sd
, 0x14, data
, 2);
395 err
= m5602_write_sensor(sd
, 0x0d, data
, 2);
399 /* FIXME: This is not sane, we need to figure out the composition
400 of these registers */
401 data
[0] = val
>> 3; /* gain, high 5 bits */
402 data
[1] = val
>> 1; /* gain, high 7 bits */
403 err
= m5602_write_sensor(sd
, S5K83A_GAIN
, data
, 2);
408 static int s5k83a_set_brightness(struct gspca_dev
*gspca_dev
, __s32 val
)
411 struct sd
*sd
= (struct sd
*) gspca_dev
;
414 return m5602_write_sensor(sd
, S5K83A_BRIGHTNESS
, data
, 1);
417 static int s5k83a_set_exposure(struct gspca_dev
*gspca_dev
, __s32 val
)
420 struct sd
*sd
= (struct sd
*) gspca_dev
;
424 return m5602_write_sensor(sd
, S5K83A_EXPOSURE
, data
, 2);
427 static int s5k83a_set_flip_real(struct gspca_dev
*gspca_dev
,
428 __s32 vflip
, __s32 hflip
)
432 struct sd
*sd
= (struct sd
*) gspca_dev
;
435 err
= m5602_write_sensor(sd
, S5K83A_PAGE_MAP
, data
, 1);
439 /* six bit is vflip, seven is hflip */
440 data
[0] = S5K83A_FLIP_MASK
;
441 data
[0] = (vflip
) ? data
[0] | 0x40 : data
[0];
442 data
[0] = (hflip
) ? data
[0] | 0x80 : data
[0];
444 err
= m5602_write_sensor(sd
, S5K83A_FLIP
, data
, 1);
448 data
[0] = (vflip
) ? 0x0b : 0x0a;
449 err
= m5602_write_sensor(sd
, S5K83A_VFLIP_TUNE
, data
, 1);
453 data
[0] = (hflip
) ? 0x0a : 0x0b;
454 err
= m5602_write_sensor(sd
, S5K83A_HFLIP_TUNE
, data
, 1);
458 static int s5k83a_set_hvflip(struct gspca_dev
*gspca_dev
)
462 struct sd
*sd
= (struct sd
*) gspca_dev
;
463 int hflip
= sd
->hflip
->val
;
464 int vflip
= sd
->vflip
->val
;
466 err
= s5k83a_get_rotation(sd
, ®
);
474 err
= s5k83a_set_flip_real(gspca_dev
, vflip
, hflip
);
478 static int s5k83a_s_ctrl(struct v4l2_ctrl
*ctrl
)
480 struct gspca_dev
*gspca_dev
=
481 container_of(ctrl
->handler
, struct gspca_dev
, ctrl_handler
);
484 if (!gspca_dev
->streaming
)
488 case V4L2_CID_BRIGHTNESS
:
489 err
= s5k83a_set_brightness(gspca_dev
, ctrl
->val
);
491 case V4L2_CID_EXPOSURE
:
492 err
= s5k83a_set_exposure(gspca_dev
, ctrl
->val
);
495 err
= s5k83a_set_gain(gspca_dev
, ctrl
->val
);
498 err
= s5k83a_set_hvflip(gspca_dev
);
507 static int s5k83a_set_led_indication(struct sd
*sd
, u8 val
)
512 err
= m5602_read_bridge(sd
, M5602_XB_GPIO_DAT
, data
);
517 data
[0] = data
[0] | S5K83A_GPIO_LED_MASK
;
519 data
[0] = data
[0] & ~S5K83A_GPIO_LED_MASK
;
521 err
= m5602_write_bridge(sd
, M5602_XB_GPIO_DAT
, data
[0]);
526 /* Get camera rotation on Acer notebooks */
527 static int s5k83a_get_rotation(struct sd
*sd
, u8
*reg_data
)
529 int err
= m5602_read_bridge(sd
, M5602_XB_GPIO_DAT
, reg_data
);
530 *reg_data
= (*reg_data
& S5K83A_GPIO_ROTATION_MASK
) ? 0 : 1;
534 static void s5k83a_dump_registers(struct sd
*sd
)
538 m5602_read_sensor(sd
, S5K83A_PAGE_MAP
, &old_page
, 1);
540 for (page
= 0; page
< 16; page
++) {
541 m5602_write_sensor(sd
, S5K83A_PAGE_MAP
, &page
, 1);
542 pr_info("Dumping the s5k83a register state for page 0x%x\n",
544 for (address
= 0; address
<= 0xff; address
++) {
546 m5602_read_sensor(sd
, address
, &val
, 1);
547 pr_info("register 0x%x contains 0x%x\n", address
, val
);
550 pr_info("s5k83a register state dump complete\n");
552 for (page
= 0; page
< 16; page
++) {
553 m5602_write_sensor(sd
, S5K83A_PAGE_MAP
, &page
, 1);
554 pr_info("Probing for which registers that are read/write for page 0x%x\n",
556 for (address
= 0; address
<= 0xff; address
++) {
557 u8 old_val
, ctrl_val
, test_val
= 0xff;
559 m5602_read_sensor(sd
, address
, &old_val
, 1);
560 m5602_write_sensor(sd
, address
, &test_val
, 1);
561 m5602_read_sensor(sd
, address
, &ctrl_val
, 1);
563 if (ctrl_val
== test_val
)
564 pr_info("register 0x%x is writeable\n",
567 pr_info("register 0x%x is read only\n",
570 /* Restore original val */
571 m5602_write_sensor(sd
, address
, &old_val
, 1);
574 pr_info("Read/write register probing complete\n");
575 m5602_write_sensor(sd
, S5K83A_PAGE_MAP
, &old_page
, 1);