1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
20
21#include <linux/kthread.h>
22#include "m5602_s5k83a.h"
23
24static int s5k83a_s_ctrl(struct v4l2_ctrl *ctrl);
25
26static const struct v4l2_ctrl_ops s5k83a_ctrl_ops = {
27 .s_ctrl = s5k83a_s_ctrl,
28};
29
30static struct v4l2_pix_format s5k83a_modes[] = {
31 {
32 640,
33 480,
34 V4L2_PIX_FMT_SBGGR8,
35 V4L2_FIELD_NONE,
36 .sizeimage =
37 640 * 480,
38 .bytesperline = 640,
39 .colorspace = V4L2_COLORSPACE_SRGB,
40 .priv = 0
41 }
42};
43
44static const unsigned char preinit_s5k83a[][4] = {
45 {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00},
46 {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00},
47 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
48 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
49 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
50 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d, 0x00},
51 {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00, 0x00},
52
53 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
54 {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
55 {BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00},
56 {BRIDGE, M5602_XB_GPIO_EN_H, 0x3f, 0x00},
57 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3f, 0x00},
58 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00},
59 {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00},
60 {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00},
61 {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00},
62 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0xb0, 0x00},
63 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0x80, 0x00},
64 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
65 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
66 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
67 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
68 {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00},
69 {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00},
70 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
71 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xf0, 0x00},
72 {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
73 {BRIDGE, M5602_XB_GPIO_DAT, 0x1c, 0x00},
74 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
75 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06, 0x00},
76 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00},
77 {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
78 {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x20, 0x00},
79};
80
81
82
83
84static const unsigned char init_s5k83a[][4] = {
85
86
87 {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
88 {BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00},
89 {BRIDGE, M5602_XB_GPIO_EN_H, 0x3f, 0x00},
90 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3f, 0x00},
91 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00},
92 {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00},
93 {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00},
94 {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00},
95 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0xb0, 0x00},
96 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0x80, 0x00},
97 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
98 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
99 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
100 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
101 {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00},
102 {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00},
103 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
104 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xf0, 0x00},
105 {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
106 {BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00},
107 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
108 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06, 0x00},
109 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00},
110 {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
111 {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x20, 0x00},
112
113 {SENSOR, S5K83A_PAGE_MAP, 0x04, 0x00},
114 {SENSOR, 0xaf, 0x01, 0x00},
115 {SENSOR, S5K83A_PAGE_MAP, 0x00, 0x00},
116 {SENSOR, 0x7b, 0xff, 0x00},
117 {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
118 {SENSOR, 0x01, 0x50, 0x00},
119 {SENSOR, 0x12, 0x20, 0x00},
120 {SENSOR, 0x17, 0x40, 0x00},
121 {SENSOR, 0x1c, 0x00, 0x00},
122 {SENSOR, 0x02, 0x70, 0x00},
123 {SENSOR, 0x03, 0x0b, 0x00},
124 {SENSOR, 0x04, 0xf0, 0x00},
125 {SENSOR, 0x05, 0x0b, 0x00},
126 {SENSOR, 0x06, 0x71, 0x00},
127 {SENSOR, 0x07, 0xe8, 0x00},
128 {SENSOR, 0x08, 0x02, 0x00},
129 {SENSOR, 0x09, 0x88, 0x00},
130 {SENSOR, 0x14, 0x00, 0x00},
131 {SENSOR, 0x15, 0x20, 0x00},
132 {SENSOR, 0x19, 0x00, 0x00},
133 {SENSOR, 0x1a, 0x98, 0x00},
134 {SENSOR, 0x0f, 0x02, 0x00},
135 {SENSOR, 0x10, 0xe5, 0x00},
136
137
138 {SENSOR, 0x00, 0x06, 0x00},
139};
140
141static const unsigned char start_s5k83a[][4] = {
142 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
143 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
144 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
145 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
146 {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00},
147 {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00},
148 {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00},
149 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
150 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
151 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
152 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
153 {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00},
154 {BRIDGE, M5602_XB_VSYNC_PARA, 0xe4, 0x00},
155 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
156 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
157 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
158 {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00},
159 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
160 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
161 {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00},
162 {BRIDGE, M5602_XB_HSYNC_PARA, 0x7f, 0x00},
163 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
164 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
165 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
166};
167
168static void s5k83a_dump_registers(struct sd *sd);
169static int s5k83a_get_rotation(struct sd *sd, u8 *reg_data);
170static int s5k83a_set_led_indication(struct sd *sd, u8 val);
171static int s5k83a_set_flip_real(struct gspca_dev *gspca_dev,
172 __s32 vflip, __s32 hflip);
173
174int s5k83a_probe(struct sd *sd)
175{
176 u8 prod_id = 0, ver_id = 0;
177 int i, err = 0;
178 struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
179
180 if (force_sensor) {
181 if (force_sensor == S5K83A_SENSOR) {
182 pr_info("Forcing a %s sensor\n", s5k83a.name);
183 goto sensor_found;
184 }
185
186
187 return -ENODEV;
188 }
189
190 gspca_dbg(gspca_dev, D_PROBE, "Probing for a s5k83a sensor\n");
191
192
193 for (i = 0; i < ARRAY_SIZE(preinit_s5k83a) && !err; i++) {
194 u8 data[2] = {preinit_s5k83a[i][2], preinit_s5k83a[i][3]};
195 if (preinit_s5k83a[i][0] == SENSOR)
196 err = m5602_write_sensor(sd, preinit_s5k83a[i][1],
197 data, 2);
198 else
199 err = m5602_write_bridge(sd, preinit_s5k83a[i][1],
200 data[0]);
201 }
202
203
204
205
206 if (m5602_read_sensor(sd, 0x00, &prod_id, 1))
207 return -ENODEV;
208
209 if (m5602_read_sensor(sd, 0x01, &ver_id, 1))
210 return -ENODEV;
211
212 if ((prod_id == 0xff) || (ver_id == 0xff))
213 return -ENODEV;
214 else
215 pr_info("Detected a s5k83a sensor\n");
216
217sensor_found:
218 sd->gspca_dev.cam.cam_mode = s5k83a_modes;
219 sd->gspca_dev.cam.nmodes = ARRAY_SIZE(s5k83a_modes);
220
221
222 sd->rotation_thread = NULL;
223
224 return 0;
225}
226
227int s5k83a_init(struct sd *sd)
228{
229 int i, err = 0;
230
231 for (i = 0; i < ARRAY_SIZE(init_s5k83a) && !err; i++) {
232 u8 data[2] = {0x00, 0x00};
233
234 switch (init_s5k83a[i][0]) {
235 case BRIDGE:
236 err = m5602_write_bridge(sd,
237 init_s5k83a[i][1],
238 init_s5k83a[i][2]);
239 break;
240
241 case SENSOR:
242 data[0] = init_s5k83a[i][2];
243 err = m5602_write_sensor(sd,
244 init_s5k83a[i][1], data, 1);
245 break;
246
247 case SENSOR_LONG:
248 data[0] = init_s5k83a[i][2];
249 data[1] = init_s5k83a[i][3];
250 err = m5602_write_sensor(sd,
251 init_s5k83a[i][1], data, 2);
252 break;
253 default:
254 pr_info("Invalid stream command, exiting init\n");
255 return -EINVAL;
256 }
257 }
258
259 if (dump_sensor)
260 s5k83a_dump_registers(sd);
261
262 return err;
263}
264
265int s5k83a_init_controls(struct sd *sd)
266{
267 struct v4l2_ctrl_handler *hdl = &sd->gspca_dev.ctrl_handler;
268
269 sd->gspca_dev.vdev.ctrl_handler = hdl;
270 v4l2_ctrl_handler_init(hdl, 6);
271
272 v4l2_ctrl_new_std(hdl, &s5k83a_ctrl_ops, V4L2_CID_BRIGHTNESS,
273 0, 255, 1, S5K83A_DEFAULT_BRIGHTNESS);
274
275 v4l2_ctrl_new_std(hdl, &s5k83a_ctrl_ops, V4L2_CID_EXPOSURE,
276 0, S5K83A_MAXIMUM_EXPOSURE, 1,
277 S5K83A_DEFAULT_EXPOSURE);
278
279 v4l2_ctrl_new_std(hdl, &s5k83a_ctrl_ops, V4L2_CID_GAIN,
280 0, 255, 1, S5K83A_DEFAULT_GAIN);
281
282 sd->hflip = v4l2_ctrl_new_std(hdl, &s5k83a_ctrl_ops, V4L2_CID_HFLIP,
283 0, 1, 1, 0);
284 sd->vflip = v4l2_ctrl_new_std(hdl, &s5k83a_ctrl_ops, V4L2_CID_VFLIP,
285 0, 1, 1, 0);
286
287 if (hdl->error) {
288 pr_err("Could not initialize controls\n");
289 return hdl->error;
290 }
291
292 v4l2_ctrl_cluster(2, &sd->hflip);
293
294 return 0;
295}
296
297static int rotation_thread_function(void *data)
298{
299 struct sd *sd = (struct sd *) data;
300 u8 reg, previous_rotation = 0;
301 __s32 vflip, hflip;
302
303 set_current_state(TASK_INTERRUPTIBLE);
304 while (!schedule_timeout(msecs_to_jiffies(100))) {
305 if (mutex_lock_interruptible(&sd->gspca_dev.usb_lock))
306 break;
307
308 s5k83a_get_rotation(sd, ®);
309 if (previous_rotation != reg) {
310 previous_rotation = reg;
311 pr_info("Camera was flipped\n");
312
313 hflip = sd->hflip->val;
314 vflip = sd->vflip->val;
315
316 if (reg) {
317 vflip = !vflip;
318 hflip = !hflip;
319 }
320 s5k83a_set_flip_real((struct gspca_dev *) sd,
321 vflip, hflip);
322 }
323
324 mutex_unlock(&sd->gspca_dev.usb_lock);
325 set_current_state(TASK_INTERRUPTIBLE);
326 }
327
328
329 if (previous_rotation) {
330 hflip = sd->hflip->val;
331 vflip = sd->vflip->val;
332 s5k83a_set_flip_real((struct gspca_dev *) sd, vflip, hflip);
333 }
334
335 sd->rotation_thread = NULL;
336 return 0;
337}
338
339int s5k83a_start(struct sd *sd)
340{
341 int i, err = 0;
342
343
344
345
346 sd->rotation_thread = kthread_create(rotation_thread_function,
347 sd, "rotation thread");
348 if (IS_ERR(sd->rotation_thread)) {
349 err = PTR_ERR(sd->rotation_thread);
350 sd->rotation_thread = NULL;
351 return err;
352 }
353 wake_up_process(sd->rotation_thread);
354
355
356 for (i = 0; i < ARRAY_SIZE(start_s5k83a) && !err; i++) {
357 u8 data[2] = {start_s5k83a[i][2], start_s5k83a[i][3]};
358 if (start_s5k83a[i][0] == SENSOR)
359 err = m5602_write_sensor(sd, start_s5k83a[i][1],
360 data, 2);
361 else
362 err = m5602_write_bridge(sd, start_s5k83a[i][1],
363 data[0]);
364 }
365 if (err < 0)
366 return err;
367
368 return s5k83a_set_led_indication(sd, 1);
369}
370
371int s5k83a_stop(struct sd *sd)
372{
373 if (sd->rotation_thread)
374 kthread_stop(sd->rotation_thread);
375
376 return s5k83a_set_led_indication(sd, 0);
377}
378
379void s5k83a_disconnect(struct sd *sd)
380{
381 s5k83a_stop(sd);
382
383 sd->sensor = NULL;
384}
385
386static int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val)
387{
388 int err;
389 u8 data[2];
390 struct sd *sd = (struct sd *) gspca_dev;
391
392 data[0] = 0x00;
393 data[1] = 0x20;
394 err = m5602_write_sensor(sd, 0x14, data, 2);
395 if (err < 0)
396 return err;
397
398 data[0] = 0x01;
399 data[1] = 0x00;
400 err = m5602_write_sensor(sd, 0x0d, data, 2);
401 if (err < 0)
402 return err;
403
404
405
406 data[0] = val >> 3;
407 data[1] = val >> 1;
408 err = m5602_write_sensor(sd, S5K83A_GAIN, data, 2);
409
410 return err;
411}
412
413static int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val)
414{
415 int err;
416 u8 data[1];
417 struct sd *sd = (struct sd *) gspca_dev;
418
419 data[0] = val;
420 err = m5602_write_sensor(sd, S5K83A_BRIGHTNESS, data, 1);
421 return err;
422}
423
424static int s5k83a_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
425{
426 int err;
427 u8 data[2];
428 struct sd *sd = (struct sd *) gspca_dev;
429
430 data[0] = 0;
431 data[1] = val;
432 err = m5602_write_sensor(sd, S5K83A_EXPOSURE, data, 2);
433 return err;
434}
435
436static int s5k83a_set_flip_real(struct gspca_dev *gspca_dev,
437 __s32 vflip, __s32 hflip)
438{
439 int err;
440 u8 data[1];
441 struct sd *sd = (struct sd *) gspca_dev;
442
443 data[0] = 0x05;
444 err = m5602_write_sensor(sd, S5K83A_PAGE_MAP, data, 1);
445 if (err < 0)
446 return err;
447
448
449 data[0] = S5K83A_FLIP_MASK;
450 data[0] = (vflip) ? data[0] | 0x40 : data[0];
451 data[0] = (hflip) ? data[0] | 0x80 : data[0];
452
453 err = m5602_write_sensor(sd, S5K83A_FLIP, data, 1);
454 if (err < 0)
455 return err;
456
457 data[0] = (vflip) ? 0x0b : 0x0a;
458 err = m5602_write_sensor(sd, S5K83A_VFLIP_TUNE, data, 1);
459 if (err < 0)
460 return err;
461
462 data[0] = (hflip) ? 0x0a : 0x0b;
463 err = m5602_write_sensor(sd, S5K83A_HFLIP_TUNE, data, 1);
464 return err;
465}
466
467static int s5k83a_set_hvflip(struct gspca_dev *gspca_dev)
468{
469 int err;
470 u8 reg;
471 struct sd *sd = (struct sd *) gspca_dev;
472 int hflip = sd->hflip->val;
473 int vflip = sd->vflip->val;
474
475 err = s5k83a_get_rotation(sd, ®);
476 if (err < 0)
477 return err;
478 if (reg) {
479 hflip = !hflip;
480 vflip = !vflip;
481 }
482
483 err = s5k83a_set_flip_real(gspca_dev, vflip, hflip);
484 return err;
485}
486
487static int s5k83a_s_ctrl(struct v4l2_ctrl *ctrl)
488{
489 struct gspca_dev *gspca_dev =
490 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
491 int err;
492
493 if (!gspca_dev->streaming)
494 return 0;
495
496 switch (ctrl->id) {
497 case V4L2_CID_BRIGHTNESS:
498 err = s5k83a_set_brightness(gspca_dev, ctrl->val);
499 break;
500 case V4L2_CID_EXPOSURE:
501 err = s5k83a_set_exposure(gspca_dev, ctrl->val);
502 break;
503 case V4L2_CID_GAIN:
504 err = s5k83a_set_gain(gspca_dev, ctrl->val);
505 break;
506 case V4L2_CID_HFLIP:
507 err = s5k83a_set_hvflip(gspca_dev);
508 break;
509 default:
510 return -EINVAL;
511 }
512
513 return err;
514}
515
516static int s5k83a_set_led_indication(struct sd *sd, u8 val)
517{
518 int err = 0;
519 u8 data[1];
520
521 err = m5602_read_bridge(sd, M5602_XB_GPIO_DAT, data);
522 if (err < 0)
523 return err;
524
525 if (val)
526 data[0] = data[0] | S5K83A_GPIO_LED_MASK;
527 else
528 data[0] = data[0] & ~S5K83A_GPIO_LED_MASK;
529
530 err = m5602_write_bridge(sd, M5602_XB_GPIO_DAT, data[0]);
531
532 return err;
533}
534
535
536static int s5k83a_get_rotation(struct sd *sd, u8 *reg_data)
537{
538 int err = m5602_read_bridge(sd, M5602_XB_GPIO_DAT, reg_data);
539 *reg_data = (*reg_data & S5K83A_GPIO_ROTATION_MASK) ? 0 : 1;
540 return err;
541}
542
543static void s5k83a_dump_registers(struct sd *sd)
544{
545 int address;
546 u8 page, old_page;
547 m5602_read_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1);
548
549 for (page = 0; page < 16; page++) {
550 m5602_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1);
551 pr_info("Dumping the s5k83a register state for page 0x%x\n",
552 page);
553 for (address = 0; address <= 0xff; address++) {
554 u8 val = 0;
555 m5602_read_sensor(sd, address, &val, 1);
556 pr_info("register 0x%x contains 0x%x\n", address, val);
557 }
558 }
559 pr_info("s5k83a register state dump complete\n");
560
561 for (page = 0; page < 16; page++) {
562 m5602_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1);
563 pr_info("Probing for which registers that are read/write for page 0x%x\n",
564 page);
565 for (address = 0; address <= 0xff; address++) {
566 u8 old_val, ctrl_val, test_val = 0xff;
567
568 m5602_read_sensor(sd, address, &old_val, 1);
569 m5602_write_sensor(sd, address, &test_val, 1);
570 m5602_read_sensor(sd, address, &ctrl_val, 1);
571
572 if (ctrl_val == test_val)
573 pr_info("register 0x%x is writeable\n",
574 address);
575 else
576 pr_info("register 0x%x is read only\n",
577 address);
578
579
580 m5602_write_sensor(sd, address, &old_val, 1);
581 }
582 }
583 pr_info("Read/write register probing complete\n");
584 m5602_write_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1);
585}
586