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_hflip(struct gspca_dev *gspca_dev, __s32 *val);
30 static int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
31 static int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
32 static int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
33 static int po1030_set_auto_white_balance(struct gspca_dev *gspca_dev,
35 static int po1030_get_auto_white_balance(struct gspca_dev *gspca_dev,
38 static struct v4l2_pix_format po1030_modes[] = {
44 .sizeimage = 640 * 480,
46 .colorspace = V4L2_COLORSPACE_SRGB,
51 const static struct ctrl po1030_ctrls[] = {
56 .type = V4L2_CTRL_TYPE_INTEGER,
61 .default_value = PO1030_GLOBAL_GAIN_DEFAULT,
62 .flags = V4L2_CTRL_FLAG_SLIDER
64 .set = po1030_set_gain,
65 .get = po1030_get_gain
67 #define EXPOSURE_IDX 1
70 .id = V4L2_CID_EXPOSURE,
71 .type = V4L2_CTRL_TYPE_INTEGER,
76 .default_value = PO1030_EXPOSURE_DEFAULT,
77 .flags = V4L2_CTRL_FLAG_SLIDER
79 .set = po1030_set_exposure,
80 .get = po1030_get_exposure
82 #define RED_BALANCE_IDX 2
85 .id = V4L2_CID_RED_BALANCE,
86 .type = V4L2_CTRL_TYPE_INTEGER,
87 .name = "red balance",
91 .default_value = PO1030_RED_GAIN_DEFAULT,
92 .flags = V4L2_CTRL_FLAG_SLIDER
94 .set = po1030_set_red_balance,
95 .get = po1030_get_red_balance
97 #define BLUE_BALANCE_IDX 3
100 .id = V4L2_CID_BLUE_BALANCE,
101 .type = V4L2_CTRL_TYPE_INTEGER,
102 .name = "blue balance",
106 .default_value = PO1030_BLUE_GAIN_DEFAULT,
107 .flags = V4L2_CTRL_FLAG_SLIDER
109 .set = po1030_set_blue_balance,
110 .get = po1030_get_blue_balance
115 .id = V4L2_CID_HFLIP,
116 .type = V4L2_CTRL_TYPE_BOOLEAN,
117 .name = "horizontal flip",
123 .set = po1030_set_hflip,
124 .get = po1030_get_hflip
129 .id = V4L2_CID_VFLIP,
130 .type = V4L2_CTRL_TYPE_BOOLEAN,
131 .name = "vertical flip",
137 .set = po1030_set_vflip,
138 .get = po1030_get_vflip
140 #define AUTO_WHITE_BALANCE_IDX 6
143 .id = V4L2_CID_AUTO_WHITE_BALANCE,
144 .type = V4L2_CTRL_TYPE_BOOLEAN,
145 .name = "auto white balance",
151 .set = po1030_set_auto_white_balance,
152 .get = po1030_get_auto_white_balance
156 static void po1030_dump_registers(struct sd *sd);
158 int po1030_probe(struct sd *sd)
160 u8 dev_id_h = 0, dev_id_l = 0, i;
161 s32 *sensor_settings;
164 if (force_sensor == PO1030_SENSOR) {
165 info("Forcing a %s sensor", po1030.name);
168 /* If we want to force another sensor, don't try to probe this
173 info("Probing for a po1030 sensor");
175 /* Run the pre-init to actually probe the unit */
176 for (i = 0; i < ARRAY_SIZE(preinit_po1030); i++) {
177 u8 data = preinit_po1030[i][2];
178 if (preinit_po1030[i][0] == SENSOR)
179 m5602_write_sensor(sd,
180 preinit_po1030[i][1], &data, 1);
182 m5602_write_bridge(sd, preinit_po1030[i][1], data);
185 if (m5602_read_sensor(sd, PO1030_DEVID_H, &dev_id_h, 1))
188 if (m5602_read_sensor(sd, PO1030_DEVID_L, &dev_id_l, 1))
191 if ((dev_id_h == 0x10) && (dev_id_l == 0x30)) {
192 info("Detected a po1030 sensor");
198 sensor_settings = kmalloc(
199 ARRAY_SIZE(po1030_ctrls) * sizeof(s32), GFP_KERNEL);
200 if (!sensor_settings)
203 sd->gspca_dev.cam.cam_mode = po1030_modes;
204 sd->gspca_dev.cam.nmodes = ARRAY_SIZE(po1030_modes);
205 sd->desc->ctrls = po1030_ctrls;
206 sd->desc->nctrls = ARRAY_SIZE(po1030_ctrls);
208 for (i = 0; i < ARRAY_SIZE(po1030_ctrls); i++)
209 sensor_settings[i] = po1030_ctrls[i].qctrl.default_value;
210 sd->sensor_priv = sensor_settings;
213 po1030_dump_registers(sd);
218 int po1030_init(struct sd *sd)
220 s32 *sensor_settings = sd->sensor_priv;
223 /* Init the sensor */
224 for (i = 0; i < ARRAY_SIZE(init_po1030) && !err; i++) {
225 u8 data[2] = {0x00, 0x00};
227 switch (init_po1030[i][0]) {
229 err = m5602_write_bridge(sd,
235 data[0] = init_po1030[i][2];
236 err = m5602_write_sensor(sd,
237 init_po1030[i][1], data, 1);
241 info("Invalid stream command, exiting init");
248 err = po1030_set_exposure(&sd->gspca_dev,
249 sensor_settings[EXPOSURE_IDX]);
253 err = po1030_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]);
257 err = po1030_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]);
261 err = po1030_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]);
265 err = po1030_set_red_balance(&sd->gspca_dev,
266 sensor_settings[RED_BALANCE_IDX]);
270 err = po1030_set_red_balance(&sd->gspca_dev,
271 sensor_settings[BLUE_BALANCE_IDX]);
275 err = po1030_set_auto_white_balance(&sd->gspca_dev,
276 sensor_settings[AUTO_WHITE_BALANCE_IDX]);
280 int po1030_start(struct sd *sd)
283 /* Synthesize the vsync/hsync setup */
284 for (i = 0; i < ARRAY_SIZE(start_po1030) && !err; i++) {
285 if (start_po1030[i][0] == BRIDGE)
286 err = m5602_write_bridge(sd, start_po1030[i][1],
288 else if (start_po1030[i][0] == SENSOR) {
289 u8 data = start_po1030[i][2];
290 err = m5602_write_sensor(sd,
291 start_po1030[i][1], &data, 1);
297 static int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
299 struct sd *sd = (struct sd *) gspca_dev;
300 s32 *sensor_settings = sd->sensor_priv;
302 *val = sensor_settings[EXPOSURE_IDX];
303 PDEBUG(D_V4L2, "Exposure read as %d", *val);
307 static int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
309 struct sd *sd = (struct sd *) gspca_dev;
310 s32 *sensor_settings = sd->sensor_priv;
314 sensor_settings[EXPOSURE_IDX] = val;
315 PDEBUG(D_V4L2, "Set exposure to %d", val & 0xffff);
317 i2c_data = ((val & 0xff00) >> 8);
318 PDEBUG(D_V4L2, "Set exposure to high byte to 0x%x",
321 err = m5602_write_sensor(sd, PO1030_INTEGLINES_H,
326 i2c_data = (val & 0xff);
327 PDEBUG(D_V4L2, "Set exposure to low byte to 0x%x",
329 err = m5602_write_sensor(sd, PO1030_INTEGLINES_M,
335 static int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
337 struct sd *sd = (struct sd *) gspca_dev;
338 s32 *sensor_settings = sd->sensor_priv;
340 *val = sensor_settings[GAIN_IDX];
341 PDEBUG(D_V4L2, "Read global gain %d", *val);
345 static int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val)
347 struct sd *sd = (struct sd *) gspca_dev;
348 s32 *sensor_settings = sd->sensor_priv;
352 sensor_settings[GAIN_IDX] = val;
354 i2c_data = val & 0xff;
355 PDEBUG(D_V4L2, "Set global gain to %d", i2c_data);
356 err = m5602_write_sensor(sd, PO1030_GLOBALGAIN,
361 static int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
363 struct sd *sd = (struct sd *) gspca_dev;
364 s32 *sensor_settings = sd->sensor_priv;
366 *val = sensor_settings[HFLIP_IDX];
367 PDEBUG(D_V4L2, "Read hflip %d", *val);
372 static int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
374 struct sd *sd = (struct sd *) gspca_dev;
375 s32 *sensor_settings = sd->sensor_priv;
379 sensor_settings[HFLIP_IDX] = val;
381 PDEBUG(D_V4L2, "Set hflip %d", val);
382 err = m5602_read_sensor(sd, PO1030_CONTROL2, &i2c_data, 1);
386 i2c_data = (0x7f & i2c_data) | ((val & 0x01) << 7);
388 err = m5602_write_sensor(sd, PO1030_CONTROL2,
394 static int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
396 struct sd *sd = (struct sd *) gspca_dev;
397 s32 *sensor_settings = sd->sensor_priv;
399 *val = sensor_settings[VFLIP_IDX];
400 PDEBUG(D_V4L2, "Read vflip %d", *val);
405 static int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
407 struct sd *sd = (struct sd *) gspca_dev;
408 s32 *sensor_settings = sd->sensor_priv;
412 sensor_settings[VFLIP_IDX] = val;
414 PDEBUG(D_V4L2, "Set vflip %d", val);
415 err = m5602_read_sensor(sd, PO1030_CONTROL2, &i2c_data, 1);
419 i2c_data = (i2c_data & 0xbf) | ((val & 0x01) << 6);
421 err = m5602_write_sensor(sd, PO1030_CONTROL2,
427 static int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
429 struct sd *sd = (struct sd *) gspca_dev;
430 s32 *sensor_settings = sd->sensor_priv;
432 *val = sensor_settings[RED_BALANCE_IDX];
433 PDEBUG(D_V4L2, "Read red gain %d", *val);
437 static int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
439 struct sd *sd = (struct sd *) gspca_dev;
440 s32 *sensor_settings = sd->sensor_priv;
444 sensor_settings[RED_BALANCE_IDX] = val;
446 i2c_data = val & 0xff;
447 PDEBUG(D_V4L2, "Set red gain to %d", i2c_data);
448 err = m5602_write_sensor(sd, PO1030_RED_GAIN,
453 static int po1030_get_blue_balance(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[BLUE_BALANCE_IDX];
459 PDEBUG(D_V4L2, "Read blue gain %d", *val);
464 static int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
466 struct sd *sd = (struct sd *) gspca_dev;
467 s32 *sensor_settings = sd->sensor_priv;
471 sensor_settings[BLUE_BALANCE_IDX] = val;
473 i2c_data = val & 0xff;
474 PDEBUG(D_V4L2, "Set blue gain to %d", i2c_data);
475 err = m5602_write_sensor(sd, PO1030_BLUE_GAIN,
481 static int po1030_get_auto_white_balance(struct gspca_dev *gspca_dev,
484 struct sd *sd = (struct sd *) gspca_dev;
485 s32 *sensor_settings = sd->sensor_priv;
487 *val = sensor_settings[AUTO_WHITE_BALANCE_IDX];
488 PDEBUG(D_V4L2, "Auto white balancing is %d", *val);
493 static int po1030_set_auto_white_balance(struct gspca_dev *gspca_dev,
496 struct sd *sd = (struct sd *) gspca_dev;
497 s32 *sensor_settings = sd->sensor_priv;
501 sensor_settings[AUTO_WHITE_BALANCE_IDX] = val;
503 err = m5602_read_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1);
507 i2c_data = (i2c_data & 0xfe) | (val & 0x01);
508 err = m5602_write_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1);
512 void po1030_disconnect(struct sd *sd)
515 kfree(sd->sensor_priv);
518 static void po1030_dump_registers(struct sd *sd)
523 info("Dumping the po1030 sensor core registers");
524 for (address = 0; address < 0x7f; address++) {
525 m5602_read_sensor(sd, address, &value, 1);
526 info("register 0x%x contains 0x%x",
530 info("po1030 register state dump complete");
532 info("Probing for which registers that are read/write");
533 for (address = 0; address < 0xff; address++) {
534 u8 old_value, ctrl_value;
535 u8 test_value[2] = {0xff, 0xff};
537 m5602_read_sensor(sd, address, &old_value, 1);
538 m5602_write_sensor(sd, address, test_value, 1);
539 m5602_read_sensor(sd, address, &ctrl_value, 1);
541 if (ctrl_value == test_value[0])
542 info("register 0x%x is writeable", address);
544 info("register 0x%x is read only", address);
546 /* Restore original value */
547 m5602_write_sensor(sd, address, &old_value, 1);