2 * Driver for the po1030 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 "m5602_po1030.h"
21 static int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
22 static int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
23 static int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
24 static int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val);
25 static int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val);
26 static int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val);
27 static int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val);
28 static int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val);
29 static int po1030_get_green_balance(struct gspca_dev *gspca_dev, __s32 *val);
30 static int po1030_set_green_balance(struct gspca_dev *gspca_dev, __s32 val);
31 static int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
32 static int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
33 static int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
34 static int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
35 static int po1030_set_auto_white_balance(struct gspca_dev *gspca_dev,
37 static int po1030_get_auto_white_balance(struct gspca_dev *gspca_dev,
39 static int po1030_set_auto_exposure(struct gspca_dev *gspca_dev,
41 static int po1030_get_auto_exposure(struct gspca_dev *gspca_dev,
44 static struct v4l2_pix_format po1030_modes[] = {
50 .sizeimage = 320 * 240,
52 .colorspace = V4L2_COLORSPACE_SRGB,
59 .sizeimage = 640 * 480,
61 .colorspace = V4L2_COLORSPACE_SRGB,
66 const static struct ctrl po1030_ctrls[] = {
71 .type = V4L2_CTRL_TYPE_INTEGER,
76 .default_value = PO1030_GLOBAL_GAIN_DEFAULT,
77 .flags = V4L2_CTRL_FLAG_SLIDER
79 .set = po1030_set_gain,
80 .get = po1030_get_gain
82 #define EXPOSURE_IDX 1
85 .id = V4L2_CID_EXPOSURE,
86 .type = V4L2_CTRL_TYPE_INTEGER,
91 .default_value = PO1030_EXPOSURE_DEFAULT,
92 .flags = V4L2_CTRL_FLAG_SLIDER
94 .set = po1030_set_exposure,
95 .get = po1030_get_exposure
97 #define RED_BALANCE_IDX 2
100 .id = V4L2_CID_RED_BALANCE,
101 .type = V4L2_CTRL_TYPE_INTEGER,
102 .name = "red balance",
106 .default_value = PO1030_RED_GAIN_DEFAULT,
107 .flags = V4L2_CTRL_FLAG_SLIDER
109 .set = po1030_set_red_balance,
110 .get = po1030_get_red_balance
112 #define BLUE_BALANCE_IDX 3
115 .id = V4L2_CID_BLUE_BALANCE,
116 .type = V4L2_CTRL_TYPE_INTEGER,
117 .name = "blue balance",
121 .default_value = PO1030_BLUE_GAIN_DEFAULT,
122 .flags = V4L2_CTRL_FLAG_SLIDER
124 .set = po1030_set_blue_balance,
125 .get = po1030_get_blue_balance
130 .id = V4L2_CID_HFLIP,
131 .type = V4L2_CTRL_TYPE_BOOLEAN,
132 .name = "horizontal flip",
138 .set = po1030_set_hflip,
139 .get = po1030_get_hflip
144 .id = V4L2_CID_VFLIP,
145 .type = V4L2_CTRL_TYPE_BOOLEAN,
146 .name = "vertical flip",
152 .set = po1030_set_vflip,
153 .get = po1030_get_vflip
155 #define AUTO_WHITE_BALANCE_IDX 6
158 .id = V4L2_CID_AUTO_WHITE_BALANCE,
159 .type = V4L2_CTRL_TYPE_BOOLEAN,
160 .name = "auto white balance",
166 .set = po1030_set_auto_white_balance,
167 .get = po1030_get_auto_white_balance
169 #define AUTO_EXPOSURE_IDX 7
172 .id = V4L2_CID_EXPOSURE_AUTO,
173 .type = V4L2_CTRL_TYPE_BOOLEAN,
174 .name = "auto exposure",
180 .set = po1030_set_auto_exposure,
181 .get = po1030_get_auto_exposure
183 #define GREEN_BALANCE_IDX 8
186 .id = M5602_V4L2_CID_GREEN_BALANCE,
187 .type = V4L2_CTRL_TYPE_INTEGER,
188 .name = "green balance",
192 .default_value = PO1030_GREEN_GAIN_DEFAULT,
193 .flags = V4L2_CTRL_FLAG_SLIDER
195 .set = po1030_set_green_balance,
196 .get = po1030_get_green_balance
200 static void po1030_dump_registers(struct sd *sd);
202 int po1030_probe(struct sd *sd)
205 s32 *sensor_settings;
208 if (force_sensor == PO1030_SENSOR) {
209 info("Forcing a %s sensor", po1030.name);
212 /* If we want to force another sensor, don't try to probe this
217 info("Probing for a po1030 sensor");
219 /* Run the pre-init to actually probe the unit */
220 for (i = 0; i < ARRAY_SIZE(preinit_po1030); i++) {
221 u8 data = preinit_po1030[i][2];
222 if (preinit_po1030[i][0] == SENSOR)
223 m5602_write_sensor(sd,
224 preinit_po1030[i][1], &data, 1);
226 m5602_write_bridge(sd, preinit_po1030[i][1], data);
229 if (m5602_read_sensor(sd, PO1030_DEVID_H, &dev_id_h, 1))
232 if (dev_id_h == 0x30) {
233 info("Detected a po1030 sensor");
239 sensor_settings = kmalloc(
240 ARRAY_SIZE(po1030_ctrls) * sizeof(s32), GFP_KERNEL);
241 if (!sensor_settings)
244 sd->gspca_dev.cam.cam_mode = po1030_modes;
245 sd->gspca_dev.cam.nmodes = ARRAY_SIZE(po1030_modes);
246 sd->desc->ctrls = po1030_ctrls;
247 sd->desc->nctrls = ARRAY_SIZE(po1030_ctrls);
249 for (i = 0; i < ARRAY_SIZE(po1030_ctrls); i++)
250 sensor_settings[i] = po1030_ctrls[i].qctrl.default_value;
251 sd->sensor_priv = sensor_settings;
256 int po1030_init(struct sd *sd)
258 s32 *sensor_settings = sd->sensor_priv;
261 /* Init the sensor */
262 for (i = 0; i < ARRAY_SIZE(init_po1030) && !err; i++) {
263 u8 data[2] = {0x00, 0x00};
265 switch (init_po1030[i][0]) {
267 err = m5602_write_bridge(sd,
273 data[0] = init_po1030[i][2];
274 err = m5602_write_sensor(sd,
275 init_po1030[i][1], data, 1);
279 info("Invalid stream command, exiting init");
287 po1030_dump_registers(sd);
289 err = po1030_set_exposure(&sd->gspca_dev,
290 sensor_settings[EXPOSURE_IDX]);
294 err = po1030_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]);
298 err = po1030_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]);
302 err = po1030_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]);
306 err = po1030_set_red_balance(&sd->gspca_dev,
307 sensor_settings[RED_BALANCE_IDX]);
311 err = po1030_set_blue_balance(&sd->gspca_dev,
312 sensor_settings[BLUE_BALANCE_IDX]);
316 err = po1030_set_green_balance(&sd->gspca_dev,
317 sensor_settings[GREEN_BALANCE_IDX]);
321 err = po1030_set_auto_white_balance(&sd->gspca_dev,
322 sensor_settings[AUTO_WHITE_BALANCE_IDX]);
326 err = po1030_set_auto_exposure(&sd->gspca_dev,
327 sensor_settings[AUTO_EXPOSURE_IDX]);
331 int po1030_start(struct sd *sd)
333 struct cam *cam = &sd->gspca_dev.cam;
335 int width = cam->cam_mode[sd->gspca_dev.curr_mode].width;
336 int height = cam->cam_mode[sd->gspca_dev.curr_mode].height;
337 int ver_offs = cam->cam_mode[sd->gspca_dev.curr_mode].priv;
342 data = PO1030_SUBSAMPLING;
343 err = m5602_write_sensor(sd, PO1030_CONTROL3, &data, 1);
347 data = ((width + 3) >> 8) & 0xff;
348 err = m5602_write_sensor(sd, PO1030_WINDOWWIDTH_H, &data, 1);
352 data = (width + 3) & 0xff;
353 err = m5602_write_sensor(sd, PO1030_WINDOWWIDTH_L, &data, 1);
357 data = ((height + 1) >> 8) & 0xff;
358 err = m5602_write_sensor(sd, PO1030_WINDOWHEIGHT_H, &data, 1);
362 data = (height + 1) & 0xff;
363 err = m5602_write_sensor(sd, PO1030_WINDOWHEIGHT_L, &data, 1);
370 data = ((width + 7) >> 8) & 0xff;
371 err = m5602_write_sensor(sd, PO1030_WINDOWWIDTH_H, &data, 1);
375 data = (width + 7) & 0xff;
376 err = m5602_write_sensor(sd, PO1030_WINDOWWIDTH_L, &data, 1);
380 data = ((height + 3) >> 8) & 0xff;
381 err = m5602_write_sensor(sd, PO1030_WINDOWHEIGHT_H, &data, 1);
385 data = (height + 3) & 0xff;
386 err = m5602_write_sensor(sd, PO1030_WINDOWHEIGHT_L, &data, 1);
392 err = m5602_write_bridge(sd, M5602_XB_SENSOR_TYPE, 0x0c);
396 err = m5602_write_bridge(sd, M5602_XB_LINE_OF_FRAME_H, 0x81);
400 err = m5602_write_bridge(sd, M5602_XB_PIX_OF_LINE_H, 0x82);
404 err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0x01);
408 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA,
409 ((ver_offs >> 8) & 0xff));
413 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (ver_offs & 0xff));
417 for (i = 0; i < 2 && !err; i++)
418 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0);
422 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height >> 8) & 0xff);
426 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height & 0xff));
430 for (i = 0; i < 2 && !err; i++)
431 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0);
433 for (i = 0; i < 2 && !err; i++)
434 err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0);
436 for (i = 0; i < 2 && !err; i++)
437 err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, 0);
441 err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, (width >> 8) & 0xff);
445 err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, (width & 0xff));
449 err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0);
453 static int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
455 struct sd *sd = (struct sd *) gspca_dev;
456 s32 *sensor_settings = sd->sensor_priv;
458 *val = sensor_settings[EXPOSURE_IDX];
459 PDEBUG(D_V4L2, "Exposure read as %d", *val);
463 static int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
465 struct sd *sd = (struct sd *) gspca_dev;
466 s32 *sensor_settings = sd->sensor_priv;
470 sensor_settings[EXPOSURE_IDX] = val;
471 PDEBUG(D_V4L2, "Set exposure to %d", val & 0xffff);
473 i2c_data = ((val & 0xff00) >> 8);
474 PDEBUG(D_V4L2, "Set exposure to high byte to 0x%x",
477 err = m5602_write_sensor(sd, PO1030_INTEGLINES_H,
482 i2c_data = (val & 0xff);
483 PDEBUG(D_V4L2, "Set exposure to low byte to 0x%x",
485 err = m5602_write_sensor(sd, PO1030_INTEGLINES_M,
491 static int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
493 struct sd *sd = (struct sd *) gspca_dev;
494 s32 *sensor_settings = sd->sensor_priv;
496 *val = sensor_settings[GAIN_IDX];
497 PDEBUG(D_V4L2, "Read global gain %d", *val);
501 static int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val)
503 struct sd *sd = (struct sd *) gspca_dev;
504 s32 *sensor_settings = sd->sensor_priv;
508 sensor_settings[GAIN_IDX] = val;
510 i2c_data = val & 0xff;
511 PDEBUG(D_V4L2, "Set global gain to %d", i2c_data);
512 err = m5602_write_sensor(sd, PO1030_GLOBALGAIN,
517 static int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
519 struct sd *sd = (struct sd *) gspca_dev;
520 s32 *sensor_settings = sd->sensor_priv;
522 *val = sensor_settings[HFLIP_IDX];
523 PDEBUG(D_V4L2, "Read hflip %d", *val);
528 static int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
530 struct sd *sd = (struct sd *) gspca_dev;
531 s32 *sensor_settings = sd->sensor_priv;
535 sensor_settings[HFLIP_IDX] = val;
537 PDEBUG(D_V4L2, "Set hflip %d", val);
538 err = m5602_read_sensor(sd, PO1030_CONTROL2, &i2c_data, 1);
542 i2c_data = (0x7f & i2c_data) | ((val & 0x01) << 7);
544 err = m5602_write_sensor(sd, PO1030_CONTROL2,
550 static int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
552 struct sd *sd = (struct sd *) gspca_dev;
553 s32 *sensor_settings = sd->sensor_priv;
555 *val = sensor_settings[VFLIP_IDX];
556 PDEBUG(D_V4L2, "Read vflip %d", *val);
561 static int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
563 struct sd *sd = (struct sd *) gspca_dev;
564 s32 *sensor_settings = sd->sensor_priv;
568 sensor_settings[VFLIP_IDX] = val;
570 PDEBUG(D_V4L2, "Set vflip %d", val);
571 err = m5602_read_sensor(sd, PO1030_CONTROL2, &i2c_data, 1);
575 i2c_data = (i2c_data & 0xbf) | ((val & 0x01) << 6);
577 err = m5602_write_sensor(sd, PO1030_CONTROL2,
583 static int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
585 struct sd *sd = (struct sd *) gspca_dev;
586 s32 *sensor_settings = sd->sensor_priv;
588 *val = sensor_settings[RED_BALANCE_IDX];
589 PDEBUG(D_V4L2, "Read red gain %d", *val);
593 static int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
595 struct sd *sd = (struct sd *) gspca_dev;
596 s32 *sensor_settings = sd->sensor_priv;
600 sensor_settings[RED_BALANCE_IDX] = val;
602 i2c_data = val & 0xff;
603 PDEBUG(D_V4L2, "Set red gain to %d", i2c_data);
604 err = m5602_write_sensor(sd, PO1030_RED_GAIN,
609 static int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
611 struct sd *sd = (struct sd *) gspca_dev;
612 s32 *sensor_settings = sd->sensor_priv;
614 *val = sensor_settings[BLUE_BALANCE_IDX];
615 PDEBUG(D_V4L2, "Read blue gain %d", *val);
620 static int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
622 struct sd *sd = (struct sd *) gspca_dev;
623 s32 *sensor_settings = sd->sensor_priv;
627 sensor_settings[BLUE_BALANCE_IDX] = val;
629 i2c_data = val & 0xff;
630 PDEBUG(D_V4L2, "Set blue gain to %d", i2c_data);
631 err = m5602_write_sensor(sd, PO1030_BLUE_GAIN,
637 static int po1030_get_green_balance(struct gspca_dev *gspca_dev, __s32 *val)
639 struct sd *sd = (struct sd *) gspca_dev;
640 s32 *sensor_settings = sd->sensor_priv;
642 *val = sensor_settings[GREEN_BALANCE_IDX];
643 PDEBUG(D_V4L2, "Read green gain %d", *val);
648 static int po1030_set_green_balance(struct gspca_dev *gspca_dev, __s32 val)
650 struct sd *sd = (struct sd *) gspca_dev;
651 s32 *sensor_settings = sd->sensor_priv;
655 sensor_settings[GREEN_BALANCE_IDX] = val;
656 i2c_data = val & 0xff;
657 PDEBUG(D_V4L2, "Set green gain to %d", i2c_data);
659 err = m5602_write_sensor(sd, PO1030_GREEN_1_GAIN,
664 return m5602_write_sensor(sd, PO1030_GREEN_2_GAIN,
668 static int po1030_get_auto_white_balance(struct gspca_dev *gspca_dev,
671 struct sd *sd = (struct sd *) gspca_dev;
672 s32 *sensor_settings = sd->sensor_priv;
674 *val = sensor_settings[AUTO_WHITE_BALANCE_IDX];
675 PDEBUG(D_V4L2, "Auto white balancing is %d", *val);
680 static int po1030_set_auto_white_balance(struct gspca_dev *gspca_dev,
683 struct sd *sd = (struct sd *) gspca_dev;
684 s32 *sensor_settings = sd->sensor_priv;
688 sensor_settings[AUTO_WHITE_BALANCE_IDX] = val;
690 err = m5602_read_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1);
694 PDEBUG(D_V4L2, "Set auto white balance to %d", val);
695 i2c_data = (i2c_data & 0xfe) | (val & 0x01);
696 err = m5602_write_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1);
700 static int po1030_get_auto_exposure(struct gspca_dev *gspca_dev,
703 struct sd *sd = (struct sd *) gspca_dev;
704 s32 *sensor_settings = sd->sensor_priv;
706 *val = sensor_settings[AUTO_EXPOSURE_IDX];
707 PDEBUG(D_V4L2, "Auto exposure is %d", *val);
711 static int po1030_set_auto_exposure(struct gspca_dev *gspca_dev,
714 struct sd *sd = (struct sd *) gspca_dev;
715 s32 *sensor_settings = sd->sensor_priv;
719 sensor_settings[AUTO_EXPOSURE_IDX] = val;
720 err = m5602_read_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1);
724 PDEBUG(D_V4L2, "Set auto exposure to %d", val);
725 i2c_data = (i2c_data & 0xfd) | ((val & 0x01) << 1);
726 return m5602_write_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1);
729 void po1030_disconnect(struct sd *sd)
732 kfree(sd->sensor_priv);
735 static void po1030_dump_registers(struct sd *sd)
740 info("Dumping the po1030 sensor core registers");
741 for (address = 0; address < 0x7f; address++) {
742 m5602_read_sensor(sd, address, &value, 1);
743 info("register 0x%x contains 0x%x",
747 info("po1030 register state dump complete");
749 info("Probing for which registers that are read/write");
750 for (address = 0; address < 0xff; address++) {
751 u8 old_value, ctrl_value;
752 u8 test_value[2] = {0xff, 0xff};
754 m5602_read_sensor(sd, address, &old_value, 1);
755 m5602_write_sensor(sd, address, test_value, 1);
756 m5602_read_sensor(sd, address, &ctrl_value, 1);
758 if (ctrl_value == test_value[0])
759 info("register 0x%x is writeable", address);
761 info("register 0x%x is read only", address);
763 /* Restore original value */
764 m5602_write_sensor(sd, address, &old_value, 1);