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 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
21 #include "m5602_po1030.h"
23 static int po1030_s_ctrl(struct v4l2_ctrl
*ctrl
);
24 static void po1030_dump_registers(struct sd
*sd
);
26 static struct v4l2_pix_format po1030_modes
[] = {
32 .sizeimage
= 640 * 480,
34 .colorspace
= V4L2_COLORSPACE_SRGB
,
39 static const struct v4l2_ctrl_ops po1030_ctrl_ops
= {
40 .s_ctrl
= po1030_s_ctrl
,
43 static const struct v4l2_ctrl_config po1030_greenbal_cfg
= {
44 .ops
= &po1030_ctrl_ops
,
45 .id
= M5602_V4L2_CID_GREEN_BALANCE
,
46 .name
= "Green Balance",
47 .type
= V4L2_CTRL_TYPE_INTEGER
,
51 .def
= PO1030_GREEN_GAIN_DEFAULT
,
52 .flags
= V4L2_CTRL_FLAG_SLIDER
,
55 int po1030_probe(struct sd
*sd
)
58 struct gspca_dev
*gspca_dev
= (struct gspca_dev
*)sd
;
61 if (force_sensor
== PO1030_SENSOR
) {
62 pr_info("Forcing a %s sensor\n", po1030
.name
);
65 /* If we want to force another sensor, don't try to probe this
70 PDEBUG(D_PROBE
, "Probing for a po1030 sensor");
72 /* Run the pre-init to actually probe the unit */
73 for (i
= 0; i
< ARRAY_SIZE(preinit_po1030
); i
++) {
74 u8 data
= preinit_po1030
[i
][2];
75 if (preinit_po1030
[i
][0] == SENSOR
)
76 m5602_write_sensor(sd
,
77 preinit_po1030
[i
][1], &data
, 1);
79 m5602_write_bridge(sd
, preinit_po1030
[i
][1], data
);
82 if (m5602_read_sensor(sd
, PO1030_DEVID_H
, &dev_id_h
, 1))
85 if (dev_id_h
== 0x30) {
86 pr_info("Detected a po1030 sensor\n");
92 sd
->gspca_dev
.cam
.cam_mode
= po1030_modes
;
93 sd
->gspca_dev
.cam
.nmodes
= ARRAY_SIZE(po1030_modes
);
98 int po1030_init(struct sd
*sd
)
102 /* Init the sensor */
103 for (i
= 0; i
< ARRAY_SIZE(init_po1030
) && !err
; i
++) {
104 u8 data
[2] = {0x00, 0x00};
106 switch (init_po1030
[i
][0]) {
108 err
= m5602_write_bridge(sd
,
114 data
[0] = init_po1030
[i
][2];
115 err
= m5602_write_sensor(sd
,
116 init_po1030
[i
][1], data
, 1);
120 pr_info("Invalid stream command, exiting init\n");
128 po1030_dump_registers(sd
);
133 int po1030_init_controls(struct sd
*sd
)
135 struct v4l2_ctrl_handler
*hdl
= &sd
->gspca_dev
.ctrl_handler
;
137 sd
->gspca_dev
.vdev
.ctrl_handler
= hdl
;
138 v4l2_ctrl_handler_init(hdl
, 9);
140 sd
->auto_white_bal
= v4l2_ctrl_new_std(hdl
, &po1030_ctrl_ops
,
141 V4L2_CID_AUTO_WHITE_BALANCE
,
143 sd
->green_bal
= v4l2_ctrl_new_custom(hdl
, &po1030_greenbal_cfg
, NULL
);
144 sd
->red_bal
= v4l2_ctrl_new_std(hdl
, &po1030_ctrl_ops
,
145 V4L2_CID_RED_BALANCE
, 0, 255, 1,
146 PO1030_RED_GAIN_DEFAULT
);
147 sd
->blue_bal
= v4l2_ctrl_new_std(hdl
, &po1030_ctrl_ops
,
148 V4L2_CID_BLUE_BALANCE
, 0, 255, 1,
149 PO1030_BLUE_GAIN_DEFAULT
);
151 sd
->autoexpo
= v4l2_ctrl_new_std_menu(hdl
, &po1030_ctrl_ops
,
152 V4L2_CID_EXPOSURE_AUTO
, 1, 0, V4L2_EXPOSURE_MANUAL
);
153 sd
->expo
= v4l2_ctrl_new_std(hdl
, &po1030_ctrl_ops
, V4L2_CID_EXPOSURE
,
154 0, 0x2ff, 1, PO1030_EXPOSURE_DEFAULT
);
156 sd
->gain
= v4l2_ctrl_new_std(hdl
, &po1030_ctrl_ops
, V4L2_CID_GAIN
, 0,
157 0x4f, 1, PO1030_GLOBAL_GAIN_DEFAULT
);
159 sd
->hflip
= v4l2_ctrl_new_std(hdl
, &po1030_ctrl_ops
, V4L2_CID_HFLIP
,
161 sd
->vflip
= v4l2_ctrl_new_std(hdl
, &po1030_ctrl_ops
, V4L2_CID_VFLIP
,
165 pr_err("Could not initialize controls\n");
169 v4l2_ctrl_auto_cluster(4, &sd
->auto_white_bal
, 0, false);
170 v4l2_ctrl_auto_cluster(2, &sd
->autoexpo
, 0, false);
171 v4l2_ctrl_cluster(2, &sd
->hflip
);
176 int po1030_start(struct sd
*sd
)
178 struct cam
*cam
= &sd
->gspca_dev
.cam
;
180 int width
= cam
->cam_mode
[sd
->gspca_dev
.curr_mode
].width
;
181 int height
= cam
->cam_mode
[sd
->gspca_dev
.curr_mode
].height
;
182 int ver_offs
= cam
->cam_mode
[sd
->gspca_dev
.curr_mode
].priv
;
187 data
= PO1030_SUBSAMPLING
;
188 err
= m5602_write_sensor(sd
, PO1030_CONTROL3
, &data
, 1);
192 data
= ((width
+ 3) >> 8) & 0xff;
193 err
= m5602_write_sensor(sd
, PO1030_WINDOWWIDTH_H
, &data
, 1);
197 data
= (width
+ 3) & 0xff;
198 err
= m5602_write_sensor(sd
, PO1030_WINDOWWIDTH_L
, &data
, 1);
202 data
= ((height
+ 1) >> 8) & 0xff;
203 err
= m5602_write_sensor(sd
, PO1030_WINDOWHEIGHT_H
, &data
, 1);
207 data
= (height
+ 1) & 0xff;
208 err
= m5602_write_sensor(sd
, PO1030_WINDOWHEIGHT_L
, &data
, 1);
216 err
= m5602_write_sensor(sd
, PO1030_CONTROL3
, &data
, 1);
220 data
= ((width
+ 7) >> 8) & 0xff;
221 err
= m5602_write_sensor(sd
, PO1030_WINDOWWIDTH_H
, &data
, 1);
225 data
= (width
+ 7) & 0xff;
226 err
= m5602_write_sensor(sd
, PO1030_WINDOWWIDTH_L
, &data
, 1);
230 data
= ((height
+ 3) >> 8) & 0xff;
231 err
= m5602_write_sensor(sd
, PO1030_WINDOWHEIGHT_H
, &data
, 1);
235 data
= (height
+ 3) & 0xff;
236 err
= m5602_write_sensor(sd
, PO1030_WINDOWHEIGHT_L
, &data
, 1);
242 err
= m5602_write_bridge(sd
, M5602_XB_SENSOR_TYPE
, 0x0c);
246 err
= m5602_write_bridge(sd
, M5602_XB_LINE_OF_FRAME_H
, 0x81);
250 err
= m5602_write_bridge(sd
, M5602_XB_PIX_OF_LINE_H
, 0x82);
254 err
= m5602_write_bridge(sd
, M5602_XB_SIG_INI
, 0x01);
258 err
= m5602_write_bridge(sd
, M5602_XB_VSYNC_PARA
,
259 ((ver_offs
>> 8) & 0xff));
263 err
= m5602_write_bridge(sd
, M5602_XB_VSYNC_PARA
, (ver_offs
& 0xff));
267 for (i
= 0; i
< 2 && !err
; i
++)
268 err
= m5602_write_bridge(sd
, M5602_XB_VSYNC_PARA
, 0);
272 err
= m5602_write_bridge(sd
, M5602_XB_VSYNC_PARA
, (height
>> 8) & 0xff);
276 err
= m5602_write_bridge(sd
, M5602_XB_VSYNC_PARA
, (height
& 0xff));
280 for (i
= 0; i
< 2 && !err
; i
++)
281 err
= m5602_write_bridge(sd
, M5602_XB_VSYNC_PARA
, 0);
283 for (i
= 0; i
< 2 && !err
; i
++)
284 err
= m5602_write_bridge(sd
, M5602_XB_SIG_INI
, 0);
286 for (i
= 0; i
< 2 && !err
; i
++)
287 err
= m5602_write_bridge(sd
, M5602_XB_HSYNC_PARA
, 0);
291 err
= m5602_write_bridge(sd
, M5602_XB_HSYNC_PARA
, (width
>> 8) & 0xff);
295 err
= m5602_write_bridge(sd
, M5602_XB_HSYNC_PARA
, (width
& 0xff));
299 err
= m5602_write_bridge(sd
, M5602_XB_SIG_INI
, 0);
303 static int po1030_set_exposure(struct gspca_dev
*gspca_dev
, __s32 val
)
305 struct sd
*sd
= (struct sd
*) gspca_dev
;
309 PDEBUG(D_CONF
, "Set exposure to %d", val
& 0xffff);
311 i2c_data
= ((val
& 0xff00) >> 8);
312 PDEBUG(D_CONF
, "Set exposure to high byte to 0x%x",
315 err
= m5602_write_sensor(sd
, PO1030_INTEGLINES_H
,
320 i2c_data
= (val
& 0xff);
321 PDEBUG(D_CONF
, "Set exposure to low byte to 0x%x",
323 err
= m5602_write_sensor(sd
, PO1030_INTEGLINES_M
,
329 static int po1030_set_gain(struct gspca_dev
*gspca_dev
, __s32 val
)
331 struct sd
*sd
= (struct sd
*) gspca_dev
;
335 i2c_data
= val
& 0xff;
336 PDEBUG(D_CONF
, "Set global gain to %d", i2c_data
);
337 err
= m5602_write_sensor(sd
, PO1030_GLOBALGAIN
,
342 static int po1030_set_hvflip(struct gspca_dev
*gspca_dev
)
344 struct sd
*sd
= (struct sd
*) gspca_dev
;
348 PDEBUG(D_CONF
, "Set hvflip %d %d", sd
->hflip
->val
, sd
->vflip
->val
);
349 err
= m5602_read_sensor(sd
, PO1030_CONTROL2
, &i2c_data
, 1);
353 i2c_data
= (0x3f & i2c_data
) | (sd
->hflip
->val
<< 7) |
354 (sd
->vflip
->val
<< 6);
356 err
= m5602_write_sensor(sd
, PO1030_CONTROL2
,
362 static int po1030_set_red_balance(struct gspca_dev
*gspca_dev
, __s32 val
)
364 struct sd
*sd
= (struct sd
*) gspca_dev
;
368 i2c_data
= val
& 0xff;
369 PDEBUG(D_CONF
, "Set red gain to %d", i2c_data
);
370 err
= m5602_write_sensor(sd
, PO1030_RED_GAIN
,
375 static int po1030_set_blue_balance(struct gspca_dev
*gspca_dev
, __s32 val
)
377 struct sd
*sd
= (struct sd
*) gspca_dev
;
381 i2c_data
= val
& 0xff;
382 PDEBUG(D_CONF
, "Set blue gain to %d", i2c_data
);
383 err
= m5602_write_sensor(sd
, PO1030_BLUE_GAIN
,
389 static int po1030_set_green_balance(struct gspca_dev
*gspca_dev
, __s32 val
)
391 struct sd
*sd
= (struct sd
*) gspca_dev
;
395 i2c_data
= val
& 0xff;
396 PDEBUG(D_CONF
, "Set green gain to %d", i2c_data
);
398 err
= m5602_write_sensor(sd
, PO1030_GREEN_1_GAIN
,
403 return m5602_write_sensor(sd
, PO1030_GREEN_2_GAIN
,
407 static int po1030_set_auto_white_balance(struct gspca_dev
*gspca_dev
,
410 struct sd
*sd
= (struct sd
*) gspca_dev
;
414 err
= m5602_read_sensor(sd
, PO1030_AUTOCTRL1
, &i2c_data
, 1);
418 PDEBUG(D_CONF
, "Set auto white balance to %d", val
);
419 i2c_data
= (i2c_data
& 0xfe) | (val
& 0x01);
420 err
= m5602_write_sensor(sd
, PO1030_AUTOCTRL1
, &i2c_data
, 1);
424 static int po1030_set_auto_exposure(struct gspca_dev
*gspca_dev
,
427 struct sd
*sd
= (struct sd
*) gspca_dev
;
431 err
= m5602_read_sensor(sd
, PO1030_AUTOCTRL1
, &i2c_data
, 1);
435 PDEBUG(D_CONF
, "Set auto exposure to %d", val
);
436 val
= (val
== V4L2_EXPOSURE_AUTO
);
437 i2c_data
= (i2c_data
& 0xfd) | ((val
& 0x01) << 1);
438 return m5602_write_sensor(sd
, PO1030_AUTOCTRL1
, &i2c_data
, 1);
441 void po1030_disconnect(struct sd
*sd
)
446 static int po1030_s_ctrl(struct v4l2_ctrl
*ctrl
)
448 struct gspca_dev
*gspca_dev
=
449 container_of(ctrl
->handler
, struct gspca_dev
, ctrl_handler
);
450 struct sd
*sd
= (struct sd
*) gspca_dev
;
453 if (!gspca_dev
->streaming
)
457 case V4L2_CID_AUTO_WHITE_BALANCE
:
458 err
= po1030_set_auto_white_balance(gspca_dev
, ctrl
->val
);
459 if (err
|| ctrl
->val
)
461 err
= po1030_set_green_balance(gspca_dev
, sd
->green_bal
->val
);
464 err
= po1030_set_red_balance(gspca_dev
, sd
->red_bal
->val
);
467 err
= po1030_set_blue_balance(gspca_dev
, sd
->blue_bal
->val
);
469 case V4L2_CID_EXPOSURE_AUTO
:
470 err
= po1030_set_auto_exposure(gspca_dev
, ctrl
->val
);
471 if (err
|| ctrl
->val
== V4L2_EXPOSURE_AUTO
)
473 err
= po1030_set_exposure(gspca_dev
, sd
->expo
->val
);
476 err
= po1030_set_gain(gspca_dev
, ctrl
->val
);
479 err
= po1030_set_hvflip(gspca_dev
);
488 static void po1030_dump_registers(struct sd
*sd
)
493 pr_info("Dumping the po1030 sensor core registers\n");
494 for (address
= 0; address
< 0x7f; address
++) {
495 m5602_read_sensor(sd
, address
, &value
, 1);
496 pr_info("register 0x%x contains 0x%x\n", address
, value
);
499 pr_info("po1030 register state dump complete\n");
501 pr_info("Probing for which registers that are read/write\n");
502 for (address
= 0; address
< 0xff; address
++) {
503 u8 old_value
, ctrl_value
;
504 u8 test_value
[2] = {0xff, 0xff};
506 m5602_read_sensor(sd
, address
, &old_value
, 1);
507 m5602_write_sensor(sd
, address
, test_value
, 1);
508 m5602_read_sensor(sd
, address
, &ctrl_value
, 1);
510 if (ctrl_value
== test_value
[0])
511 pr_info("register 0x%x is writeable\n", address
);
513 pr_info("register 0x%x is read only\n", address
);
515 /* Restore original value */
516 m5602_write_sensor(sd
, address
, &old_value
, 1);