2 * Driver for the ov9650 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_ov9650.h"
23 static int ov9650_s_ctrl(struct v4l2_ctrl
*ctrl
);
24 static void ov9650_dump_registers(struct sd
*sd
);
26 /* Vertically and horizontally flips the image if matched, needed for machines
27 where the sensor is mounted upside down */
30 struct dmi_system_id ov9650_flip_dmi_table
[] = {
34 DMI_MATCH(DMI_SYS_VENDOR
, "ASUSTeK Computer Inc."),
35 DMI_MATCH(DMI_PRODUCT_NAME
, "A6J")
41 DMI_MATCH(DMI_SYS_VENDOR
, "ASUSTeK Computer Inc."),
42 DMI_MATCH(DMI_PRODUCT_NAME
, "A6JC")
48 DMI_MATCH(DMI_SYS_VENDOR
, "ASUSTeK Computer Inc."),
49 DMI_MATCH(DMI_PRODUCT_NAME
, "A6K")
55 DMI_MATCH(DMI_SYS_VENDOR
, "ASUSTeK Computer Inc."),
56 DMI_MATCH(DMI_PRODUCT_NAME
, "A6Kt")
62 DMI_MATCH(DMI_SYS_VENDOR
, "ASUSTeK Computer Inc."),
63 DMI_MATCH(DMI_PRODUCT_NAME
, "A6VA")
70 DMI_MATCH(DMI_SYS_VENDOR
, "ASUSTeK Computer Inc."),
71 DMI_MATCH(DMI_PRODUCT_NAME
, "A6VC")
77 DMI_MATCH(DMI_SYS_VENDOR
, "ASUSTeK Computer Inc."),
78 DMI_MATCH(DMI_PRODUCT_NAME
, "A6VM")
84 DMI_MATCH(DMI_SYS_VENDOR
, "ASUSTeK Computer Inc."),
85 DMI_MATCH(DMI_PRODUCT_NAME
, "A7V")
89 .ident
= "Alienware Aurora m9700",
91 DMI_MATCH(DMI_SYS_VENDOR
, "alienware"),
92 DMI_MATCH(DMI_PRODUCT_NAME
, "Aurora m9700")
98 static struct v4l2_pix_format ov9650_modes
[] = {
107 .colorspace
= V4L2_COLORSPACE_SRGB
,
117 .colorspace
= V4L2_COLORSPACE_SRGB
,
127 .colorspace
= V4L2_COLORSPACE_SRGB
,
137 .colorspace
= V4L2_COLORSPACE_SRGB
,
142 static const struct v4l2_ctrl_ops ov9650_ctrl_ops
= {
143 .s_ctrl
= ov9650_s_ctrl
,
146 int ov9650_probe(struct sd
*sd
)
149 u8 prod_id
= 0, ver_id
= 0, i
;
150 struct gspca_dev
*gspca_dev
= (struct gspca_dev
*)sd
;
153 if (force_sensor
== OV9650_SENSOR
) {
154 pr_info("Forcing an %s sensor\n", ov9650
.name
);
157 /* If we want to force another sensor,
158 don't try to probe this one */
162 PDEBUG(D_PROBE
, "Probing for an ov9650 sensor");
164 /* Run the pre-init before probing the sensor */
165 for (i
= 0; i
< ARRAY_SIZE(preinit_ov9650
) && !err
; i
++) {
166 u8 data
= preinit_ov9650
[i
][2];
167 if (preinit_ov9650
[i
][0] == SENSOR
)
168 err
= m5602_write_sensor(sd
,
169 preinit_ov9650
[i
][1], &data
, 1);
171 err
= m5602_write_bridge(sd
,
172 preinit_ov9650
[i
][1], data
);
178 if (m5602_read_sensor(sd
, OV9650_PID
, &prod_id
, 1))
181 if (m5602_read_sensor(sd
, OV9650_VER
, &ver_id
, 1))
184 if ((prod_id
== 0x96) && (ver_id
== 0x52)) {
185 pr_info("Detected an ov9650 sensor\n");
191 sd
->gspca_dev
.cam
.cam_mode
= ov9650_modes
;
192 sd
->gspca_dev
.cam
.nmodes
= ARRAY_SIZE(ov9650_modes
);
197 int ov9650_init(struct sd
*sd
)
203 ov9650_dump_registers(sd
);
205 for (i
= 0; i
< ARRAY_SIZE(init_ov9650
) && !err
; i
++) {
206 data
= init_ov9650
[i
][2];
207 if (init_ov9650
[i
][0] == SENSOR
)
208 err
= m5602_write_sensor(sd
, init_ov9650
[i
][1],
211 err
= m5602_write_bridge(sd
, init_ov9650
[i
][1], data
);
217 int ov9650_init_controls(struct sd
*sd
)
219 struct v4l2_ctrl_handler
*hdl
= &sd
->gspca_dev
.ctrl_handler
;
221 sd
->gspca_dev
.vdev
.ctrl_handler
= hdl
;
222 v4l2_ctrl_handler_init(hdl
, 9);
224 sd
->auto_white_bal
= v4l2_ctrl_new_std(hdl
, &ov9650_ctrl_ops
,
225 V4L2_CID_AUTO_WHITE_BALANCE
,
227 sd
->red_bal
= v4l2_ctrl_new_std(hdl
, &ov9650_ctrl_ops
,
228 V4L2_CID_RED_BALANCE
, 0, 255, 1,
230 sd
->blue_bal
= v4l2_ctrl_new_std(hdl
, &ov9650_ctrl_ops
,
231 V4L2_CID_BLUE_BALANCE
, 0, 255, 1,
234 sd
->autoexpo
= v4l2_ctrl_new_std_menu(hdl
, &ov9650_ctrl_ops
,
235 V4L2_CID_EXPOSURE_AUTO
, 1, 0, V4L2_EXPOSURE_AUTO
);
236 sd
->expo
= v4l2_ctrl_new_std(hdl
, &ov9650_ctrl_ops
, V4L2_CID_EXPOSURE
,
237 0, 0x1ff, 4, EXPOSURE_DEFAULT
);
239 sd
->autogain
= v4l2_ctrl_new_std(hdl
, &ov9650_ctrl_ops
,
240 V4L2_CID_AUTOGAIN
, 0, 1, 1, 1);
241 sd
->gain
= v4l2_ctrl_new_std(hdl
, &ov9650_ctrl_ops
, V4L2_CID_GAIN
, 0,
242 0x3ff, 1, GAIN_DEFAULT
);
244 sd
->hflip
= v4l2_ctrl_new_std(hdl
, &ov9650_ctrl_ops
, V4L2_CID_HFLIP
,
246 sd
->vflip
= v4l2_ctrl_new_std(hdl
, &ov9650_ctrl_ops
, V4L2_CID_VFLIP
,
250 pr_err("Could not initialize controls\n");
254 v4l2_ctrl_auto_cluster(3, &sd
->auto_white_bal
, 0, false);
255 v4l2_ctrl_auto_cluster(2, &sd
->autoexpo
, 0, false);
256 v4l2_ctrl_auto_cluster(2, &sd
->autogain
, 0, false);
257 v4l2_ctrl_cluster(2, &sd
->hflip
);
262 int ov9650_start(struct sd
*sd
)
266 struct cam
*cam
= &sd
->gspca_dev
.cam
;
268 int width
= cam
->cam_mode
[sd
->gspca_dev
.curr_mode
].width
;
269 int height
= cam
->cam_mode
[sd
->gspca_dev
.curr_mode
].height
;
270 int ver_offs
= cam
->cam_mode
[sd
->gspca_dev
.curr_mode
].priv
;
271 int hor_offs
= OV9650_LEFT_OFFSET
;
272 struct gspca_dev
*gspca_dev
= (struct gspca_dev
*)sd
;
274 if ((!dmi_check_system(ov9650_flip_dmi_table
) &&
276 (dmi_check_system(ov9650_flip_dmi_table
) &&
283 /* Synthesize the vsync/hsync setup */
284 for (i
= 0; i
< ARRAY_SIZE(res_init_ov9650
) && !err
; i
++) {
285 if (res_init_ov9650
[i
][0] == BRIDGE
)
286 err
= m5602_write_bridge(sd
, res_init_ov9650
[i
][1],
287 res_init_ov9650
[i
][2]);
288 else if (res_init_ov9650
[i
][0] == SENSOR
) {
289 data
= res_init_ov9650
[i
][2];
290 err
= m5602_write_sensor(sd
,
291 res_init_ov9650
[i
][1], &data
, 1);
297 err
= m5602_write_bridge(sd
, M5602_XB_VSYNC_PARA
,
298 ((ver_offs
>> 8) & 0xff));
302 err
= m5602_write_bridge(sd
, M5602_XB_VSYNC_PARA
, (ver_offs
& 0xff));
306 err
= m5602_write_bridge(sd
, M5602_XB_VSYNC_PARA
, 0);
310 err
= m5602_write_bridge(sd
, M5602_XB_VSYNC_PARA
, (height
>> 8) & 0xff);
314 err
= m5602_write_bridge(sd
, M5602_XB_VSYNC_PARA
, (height
& 0xff));
318 for (i
= 0; i
< 2 && !err
; i
++)
319 err
= m5602_write_bridge(sd
, M5602_XB_VSYNC_PARA
, 0);
323 err
= m5602_write_bridge(sd
, M5602_XB_SIG_INI
, 0);
327 err
= m5602_write_bridge(sd
, M5602_XB_SIG_INI
, 2);
331 err
= m5602_write_bridge(sd
, M5602_XB_HSYNC_PARA
,
332 (hor_offs
>> 8) & 0xff);
336 err
= m5602_write_bridge(sd
, M5602_XB_HSYNC_PARA
, hor_offs
& 0xff);
340 err
= m5602_write_bridge(sd
, M5602_XB_HSYNC_PARA
,
341 ((width
+ hor_offs
) >> 8) & 0xff);
345 err
= m5602_write_bridge(sd
, M5602_XB_HSYNC_PARA
,
346 ((width
+ hor_offs
) & 0xff));
350 err
= m5602_write_bridge(sd
, M5602_XB_SIG_INI
, 0);
356 PDEBUG(D_CONF
, "Configuring camera for VGA mode");
358 data
= OV9650_VGA_SELECT
| OV9650_RGB_SELECT
|
359 OV9650_RAW_RGB_SELECT
;
360 err
= m5602_write_sensor(sd
, OV9650_COM7
, &data
, 1);
364 PDEBUG(D_CONF
, "Configuring camera for CIF mode");
366 data
= OV9650_CIF_SELECT
| OV9650_RGB_SELECT
|
367 OV9650_RAW_RGB_SELECT
;
368 err
= m5602_write_sensor(sd
, OV9650_COM7
, &data
, 1);
372 PDEBUG(D_CONF
, "Configuring camera for QVGA mode");
374 data
= OV9650_QVGA_SELECT
| OV9650_RGB_SELECT
|
375 OV9650_RAW_RGB_SELECT
;
376 err
= m5602_write_sensor(sd
, OV9650_COM7
, &data
, 1);
380 PDEBUG(D_CONF
, "Configuring camera for QCIF mode");
382 data
= OV9650_QCIF_SELECT
| OV9650_RGB_SELECT
|
383 OV9650_RAW_RGB_SELECT
;
384 err
= m5602_write_sensor(sd
, OV9650_COM7
, &data
, 1);
390 int ov9650_stop(struct sd
*sd
)
392 u8 data
= OV9650_SOFT_SLEEP
| OV9650_OUTPUT_DRIVE_2X
;
393 return m5602_write_sensor(sd
, OV9650_COM2
, &data
, 1);
396 void ov9650_disconnect(struct sd
*sd
)
403 static int ov9650_set_exposure(struct gspca_dev
*gspca_dev
, __s32 val
)
405 struct sd
*sd
= (struct sd
*) gspca_dev
;
409 PDEBUG(D_CONF
, "Set exposure to %d", val
);
412 i2c_data
= (val
>> 10) & 0x3f;
413 err
= m5602_write_sensor(sd
, OV9650_AECHM
,
418 /* The 8 middle bits */
419 i2c_data
= (val
>> 2) & 0xff;
420 err
= m5602_write_sensor(sd
, OV9650_AECH
,
426 i2c_data
= val
& 0x03;
427 err
= m5602_write_sensor(sd
, OV9650_COM1
, &i2c_data
, 1);
431 static int ov9650_set_gain(struct gspca_dev
*gspca_dev
, __s32 val
)
435 struct sd
*sd
= (struct sd
*) gspca_dev
;
437 PDEBUG(D_CONF
, "Setting gain to %d", val
);
440 /* Read the OV9650_VREF register first to avoid
441 corrupting the VREF high and low bits */
442 err
= m5602_read_sensor(sd
, OV9650_VREF
, &i2c_data
, 1);
446 /* Mask away all uninteresting bits */
447 i2c_data
= ((val
& 0x0300) >> 2) |
449 err
= m5602_write_sensor(sd
, OV9650_VREF
, &i2c_data
, 1);
454 i2c_data
= val
& 0xff;
455 err
= m5602_write_sensor(sd
, OV9650_GAIN
, &i2c_data
, 1);
459 static int ov9650_set_red_balance(struct gspca_dev
*gspca_dev
, __s32 val
)
463 struct sd
*sd
= (struct sd
*) gspca_dev
;
465 PDEBUG(D_CONF
, "Set red gain to %d", val
);
467 i2c_data
= val
& 0xff;
468 err
= m5602_write_sensor(sd
, OV9650_RED
, &i2c_data
, 1);
472 static int ov9650_set_blue_balance(struct gspca_dev
*gspca_dev
, __s32 val
)
476 struct sd
*sd
= (struct sd
*) gspca_dev
;
478 PDEBUG(D_CONF
, "Set blue gain to %d", val
);
480 i2c_data
= val
& 0xff;
481 err
= m5602_write_sensor(sd
, OV9650_BLUE
, &i2c_data
, 1);
485 static int ov9650_set_hvflip(struct gspca_dev
*gspca_dev
)
489 struct sd
*sd
= (struct sd
*) gspca_dev
;
490 int hflip
= sd
->hflip
->val
;
491 int vflip
= sd
->vflip
->val
;
493 PDEBUG(D_CONF
, "Set hvflip to %d %d", hflip
, vflip
);
495 if (dmi_check_system(ov9650_flip_dmi_table
))
498 i2c_data
= (hflip
<< 5) | (vflip
<< 4);
499 err
= m5602_write_sensor(sd
, OV9650_MVFP
, &i2c_data
, 1);
503 /* When vflip is toggled we need to readjust the bridge hsync/vsync */
504 if (gspca_dev
->streaming
)
505 err
= ov9650_start(sd
);
510 static int ov9650_set_auto_exposure(struct gspca_dev
*gspca_dev
,
515 struct sd
*sd
= (struct sd
*) gspca_dev
;
517 PDEBUG(D_CONF
, "Set auto exposure control to %d", val
);
519 err
= m5602_read_sensor(sd
, OV9650_COM8
, &i2c_data
, 1);
523 val
= (val
== V4L2_EXPOSURE_AUTO
);
524 i2c_data
= ((i2c_data
& 0xfe) | ((val
& 0x01) << 0));
526 return m5602_write_sensor(sd
, OV9650_COM8
, &i2c_data
, 1);
529 static int ov9650_set_auto_white_balance(struct gspca_dev
*gspca_dev
,
534 struct sd
*sd
= (struct sd
*) gspca_dev
;
536 PDEBUG(D_CONF
, "Set auto white balance to %d", val
);
538 err
= m5602_read_sensor(sd
, OV9650_COM8
, &i2c_data
, 1);
542 i2c_data
= ((i2c_data
& 0xfd) | ((val
& 0x01) << 1));
543 err
= m5602_write_sensor(sd
, OV9650_COM8
, &i2c_data
, 1);
548 static int ov9650_set_auto_gain(struct gspca_dev
*gspca_dev
, __s32 val
)
552 struct sd
*sd
= (struct sd
*) gspca_dev
;
554 PDEBUG(D_CONF
, "Set auto gain control to %d", val
);
556 err
= m5602_read_sensor(sd
, OV9650_COM8
, &i2c_data
, 1);
560 i2c_data
= ((i2c_data
& 0xfb) | ((val
& 0x01) << 2));
562 return m5602_write_sensor(sd
, OV9650_COM8
, &i2c_data
, 1);
565 static int ov9650_s_ctrl(struct v4l2_ctrl
*ctrl
)
567 struct gspca_dev
*gspca_dev
=
568 container_of(ctrl
->handler
, struct gspca_dev
, ctrl_handler
);
569 struct sd
*sd
= (struct sd
*) gspca_dev
;
572 if (!gspca_dev
->streaming
)
576 case V4L2_CID_AUTO_WHITE_BALANCE
:
577 err
= ov9650_set_auto_white_balance(gspca_dev
, ctrl
->val
);
578 if (err
|| ctrl
->val
)
580 err
= ov9650_set_red_balance(gspca_dev
, sd
->red_bal
->val
);
583 err
= ov9650_set_blue_balance(gspca_dev
, sd
->blue_bal
->val
);
585 case V4L2_CID_EXPOSURE_AUTO
:
586 err
= ov9650_set_auto_exposure(gspca_dev
, ctrl
->val
);
587 if (err
|| ctrl
->val
== V4L2_EXPOSURE_AUTO
)
589 err
= ov9650_set_exposure(gspca_dev
, sd
->expo
->val
);
591 case V4L2_CID_AUTOGAIN
:
592 err
= ov9650_set_auto_gain(gspca_dev
, ctrl
->val
);
593 if (err
|| ctrl
->val
)
595 err
= ov9650_set_gain(gspca_dev
, sd
->gain
->val
);
598 err
= ov9650_set_hvflip(gspca_dev
);
607 static void ov9650_dump_registers(struct sd
*sd
)
610 pr_info("Dumping the ov9650 register state\n");
611 for (address
= 0; address
< 0xa9; address
++) {
613 m5602_read_sensor(sd
, address
, &value
, 1);
614 pr_info("register 0x%x contains 0x%x\n", address
, value
);
617 pr_info("ov9650 register state dump complete\n");
619 pr_info("Probing for which registers that are read/write\n");
620 for (address
= 0; address
< 0xff; address
++) {
621 u8 old_value
, ctrl_value
;
622 u8 test_value
[2] = {0xff, 0xff};
624 m5602_read_sensor(sd
, address
, &old_value
, 1);
625 m5602_write_sensor(sd
, address
, test_value
, 1);
626 m5602_read_sensor(sd
, address
, &ctrl_value
, 1);
628 if (ctrl_value
== test_value
[0])
629 pr_info("register 0x%x is writeable\n", address
);
631 pr_info("register 0x%x is read only\n", address
);
633 /* Restore original value */
634 m5602_write_sensor(sd
, address
, &old_value
, 1);