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 #include "m5602_ov9650.h"
21 static int ov9650_set_exposure(struct gspca_dev
*gspca_dev
, __s32 val
);
22 static int ov9650_get_exposure(struct gspca_dev
*gspca_dev
, __s32
*val
);
23 static int ov9650_get_gain(struct gspca_dev
*gspca_dev
, __s32
*val
);
24 static int ov9650_set_gain(struct gspca_dev
*gspca_dev
, __s32 val
);
25 static int ov9650_get_red_balance(struct gspca_dev
*gspca_dev
, __s32
*val
);
26 static int ov9650_set_red_balance(struct gspca_dev
*gspca_dev
, __s32 val
);
27 static int ov9650_get_blue_balance(struct gspca_dev
*gspca_dev
, __s32
*val
);
28 static int ov9650_set_blue_balance(struct gspca_dev
*gspca_dev
, __s32 val
);
29 static int ov9650_get_hflip(struct gspca_dev
*gspca_dev
, __s32
*val
);
30 static int ov9650_set_hflip(struct gspca_dev
*gspca_dev
, __s32 val
);
31 static int ov9650_get_vflip(struct gspca_dev
*gspca_dev
, __s32
*val
);
32 static int ov9650_set_vflip(struct gspca_dev
*gspca_dev
, __s32 val
);
33 static int ov9650_get_auto_white_balance(struct gspca_dev
*gspca_dev
,
35 static int ov9650_set_auto_white_balance(struct gspca_dev
*gspca_dev
,
37 static int ov9650_get_auto_gain(struct gspca_dev
*gspca_dev
, __s32
*val
);
38 static int ov9650_set_auto_gain(struct gspca_dev
*gspca_dev
, __s32 val
);
40 /* Vertically and horizontally flips the image if matched, needed for machines
41 where the sensor is mounted upside down */
44 struct dmi_system_id ov9650_flip_dmi_table
[] = {
48 DMI_MATCH(DMI_SYS_VENDOR
, "ASUSTeK Computer Inc."),
49 DMI_MATCH(DMI_PRODUCT_NAME
, "A6VC")
55 DMI_MATCH(DMI_SYS_VENDOR
, "ASUSTeK Computer Inc."),
56 DMI_MATCH(DMI_PRODUCT_NAME
, "A6VM")
62 DMI_MATCH(DMI_SYS_VENDOR
, "ASUSTeK Computer Inc."),
63 DMI_MATCH(DMI_PRODUCT_NAME
, "A6JC")
69 DMI_MATCH(DMI_SYS_VENDOR
, "ASUSTeK Computer Inc."),
70 DMI_MATCH(DMI_PRODUCT_NAME
, "A6J")
76 DMI_MATCH(DMI_SYS_VENDOR
, "ASUSTeK Computer Inc."),
77 DMI_MATCH(DMI_PRODUCT_NAME
, "A6Kt")
81 .ident
= "Alienware Aurora m9700",
83 DMI_MATCH(DMI_SYS_VENDOR
, "alienware"),
84 DMI_MATCH(DMI_PRODUCT_NAME
, "Aurora m9700")
90 const static struct ctrl ov9650_ctrls
[] = {
91 #define EXPOSURE_IDX 0
94 .id
= V4L2_CID_EXPOSURE
,
95 .type
= V4L2_CTRL_TYPE_INTEGER
,
100 .default_value
= EXPOSURE_DEFAULT
,
101 .flags
= V4L2_CTRL_FLAG_SLIDER
103 .set
= ov9650_set_exposure
,
104 .get
= ov9650_get_exposure
110 .type
= V4L2_CTRL_TYPE_INTEGER
,
115 .default_value
= GAIN_DEFAULT
,
116 .flags
= V4L2_CTRL_FLAG_SLIDER
118 .set
= ov9650_set_gain
,
119 .get
= ov9650_get_gain
121 #define RED_BALANCE_IDX 2
124 .type
= V4L2_CTRL_TYPE_INTEGER
,
125 .name
= "red balance",
129 .default_value
= RED_GAIN_DEFAULT
,
130 .flags
= V4L2_CTRL_FLAG_SLIDER
132 .set
= ov9650_set_red_balance
,
133 .get
= ov9650_get_red_balance
135 #define BLUE_BALANCE_IDX 3
138 .type
= V4L2_CTRL_TYPE_INTEGER
,
139 .name
= "blue balance",
143 .default_value
= BLUE_GAIN_DEFAULT
,
144 .flags
= V4L2_CTRL_FLAG_SLIDER
146 .set
= ov9650_set_blue_balance
,
147 .get
= ov9650_get_blue_balance
152 .id
= V4L2_CID_HFLIP
,
153 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
154 .name
= "horizontal flip",
160 .set
= ov9650_set_hflip
,
161 .get
= ov9650_get_hflip
166 .id
= V4L2_CID_VFLIP
,
167 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
168 .name
= "vertical flip",
174 .set
= ov9650_set_vflip
,
175 .get
= ov9650_get_vflip
177 #define AUTO_WHITE_BALANCE_IDX 6
180 .id
= V4L2_CID_AUTO_WHITE_BALANCE
,
181 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
182 .name
= "auto white balance",
188 .set
= ov9650_set_auto_white_balance
,
189 .get
= ov9650_get_auto_white_balance
191 #define AUTO_GAIN_CTRL_IDX 7
194 .id
= V4L2_CID_AUTOGAIN
,
195 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
196 .name
= "auto gain control",
202 .set
= ov9650_set_auto_gain
,
203 .get
= ov9650_get_auto_gain
207 static struct v4l2_pix_format ov9650_modes
[] = {
216 .colorspace
= V4L2_COLORSPACE_SRGB
,
226 .colorspace
= V4L2_COLORSPACE_SRGB
,
236 .colorspace
= V4L2_COLORSPACE_SRGB
,
246 .colorspace
= V4L2_COLORSPACE_SRGB
,
251 static void ov9650_dump_registers(struct sd
*sd
);
253 int ov9650_probe(struct sd
*sd
)
256 u8 prod_id
= 0, ver_id
= 0, i
;
257 s32
*sensor_settings
;
260 if (force_sensor
== OV9650_SENSOR
) {
261 info("Forcing an %s sensor", ov9650
.name
);
264 /* If we want to force another sensor,
265 don't try to probe this one */
269 info("Probing for an ov9650 sensor");
271 /* Run the pre-init before probing the sensor */
272 for (i
= 0; i
< ARRAY_SIZE(preinit_ov9650
) && !err
; i
++) {
273 u8 data
= preinit_ov9650
[i
][2];
274 if (preinit_ov9650
[i
][0] == SENSOR
)
275 err
= m5602_write_sensor(sd
,
276 preinit_ov9650
[i
][1], &data
, 1);
278 err
= m5602_write_bridge(sd
,
279 preinit_ov9650
[i
][1], data
);
285 if (m5602_read_sensor(sd
, OV9650_PID
, &prod_id
, 1))
288 if (m5602_read_sensor(sd
, OV9650_VER
, &ver_id
, 1))
291 if ((prod_id
== 0x96) && (ver_id
== 0x52)) {
292 info("Detected an ov9650 sensor");
298 sensor_settings
= kmalloc(
299 ARRAY_SIZE(ov9650_ctrls
) * sizeof(s32
), GFP_KERNEL
);
300 if (!sensor_settings
)
303 sd
->gspca_dev
.cam
.cam_mode
= ov9650_modes
;
304 sd
->gspca_dev
.cam
.nmodes
= ARRAY_SIZE(ov9650_modes
);
305 sd
->desc
->ctrls
= ov9650_ctrls
;
306 sd
->desc
->nctrls
= ARRAY_SIZE(ov9650_ctrls
);
308 for (i
= 0; i
< ARRAY_SIZE(ov9650_ctrls
); i
++)
309 sensor_settings
[i
] = ov9650_ctrls
[i
].qctrl
.default_value
;
310 sd
->sensor_priv
= sensor_settings
;
314 int ov9650_init(struct sd
*sd
)
318 s32
*sensor_settings
= sd
->sensor_priv
;
321 ov9650_dump_registers(sd
);
323 for (i
= 0; i
< ARRAY_SIZE(init_ov9650
) && !err
; i
++) {
324 data
= init_ov9650
[i
][2];
325 if (init_ov9650
[i
][0] == SENSOR
)
326 err
= m5602_write_sensor(sd
, init_ov9650
[i
][1],
329 err
= m5602_write_bridge(sd
, init_ov9650
[i
][1], data
);
332 err
= ov9650_set_exposure(&sd
->gspca_dev
,
333 sensor_settings
[EXPOSURE_IDX
]);
337 err
= ov9650_set_gain(&sd
->gspca_dev
, sensor_settings
[GAIN_IDX
]);
341 err
= ov9650_set_red_balance(&sd
->gspca_dev
,
342 sensor_settings
[RED_BALANCE_IDX
]);
346 err
= ov9650_set_blue_balance(&sd
->gspca_dev
,
347 sensor_settings
[BLUE_BALANCE_IDX
]);
351 err
= ov9650_set_hflip(&sd
->gspca_dev
, sensor_settings
[HFLIP_IDX
]);
355 err
= ov9650_set_vflip(&sd
->gspca_dev
, sensor_settings
[VFLIP_IDX
]);
359 err
= ov9650_set_auto_white_balance(&sd
->gspca_dev
,
360 sensor_settings
[AUTO_WHITE_BALANCE_IDX
]);
364 err
= ov9650_set_auto_gain(&sd
->gspca_dev
,
365 sensor_settings
[AUTO_GAIN_CTRL_IDX
]);
369 int ov9650_start(struct sd
*sd
)
373 struct cam
*cam
= &sd
->gspca_dev
.cam
;
374 s32
*sensor_settings
= sd
->sensor_priv
;
376 int width
= cam
->cam_mode
[sd
->gspca_dev
.curr_mode
].width
;
377 int height
= cam
->cam_mode
[sd
->gspca_dev
.curr_mode
].height
;
378 int ver_offs
= cam
->cam_mode
[sd
->gspca_dev
.curr_mode
].priv
;
379 int hor_offs
= OV9650_LEFT_OFFSET
;
381 if ((!dmi_check_system(ov9650_flip_dmi_table
) &&
382 sensor_settings
[VFLIP_IDX
]) ||
383 (dmi_check_system(ov9650_flip_dmi_table
) &&
384 !sensor_settings
[VFLIP_IDX
]))
390 /* Synthesize the vsync/hsync setup */
391 for (i
= 0; i
< ARRAY_SIZE(res_init_ov9650
) && !err
; i
++) {
392 if (res_init_ov9650
[i
][0] == BRIDGE
)
393 err
= m5602_write_bridge(sd
, res_init_ov9650
[i
][1],
394 res_init_ov9650
[i
][2]);
395 else if (res_init_ov9650
[i
][0] == SENSOR
) {
396 u8 data
= res_init_ov9650
[i
][2];
397 err
= m5602_write_sensor(sd
,
398 res_init_ov9650
[i
][1], &data
, 1);
404 err
= m5602_write_bridge(sd
, M5602_XB_VSYNC_PARA
,
405 ((ver_offs
>> 8) & 0xff));
409 err
= m5602_write_bridge(sd
, M5602_XB_VSYNC_PARA
, (ver_offs
& 0xff));
413 err
= m5602_write_bridge(sd
, M5602_XB_VSYNC_PARA
, 0);
417 err
= m5602_write_bridge(sd
, M5602_XB_VSYNC_PARA
, (height
>> 8) & 0xff);
421 err
= m5602_write_bridge(sd
, M5602_XB_VSYNC_PARA
, (height
& 0xff));
425 for (i
= 0; i
< 2 && !err
; i
++)
426 err
= m5602_write_bridge(sd
, M5602_XB_VSYNC_PARA
, 0);
430 err
= m5602_write_bridge(sd
, M5602_XB_HSYNC_PARA
,
431 (hor_offs
>> 8) & 0xff);
435 err
= m5602_write_bridge(sd
, M5602_XB_HSYNC_PARA
, hor_offs
& 0xff);
439 err
= m5602_write_bridge(sd
, M5602_XB_HSYNC_PARA
,
440 ((width
+ hor_offs
) >> 8) & 0xff);
444 err
= m5602_write_bridge(sd
, M5602_XB_HSYNC_PARA
,
445 ((width
+ hor_offs
) & 0xff));
451 PDEBUG(D_V4L2
, "Configuring camera for VGA mode");
453 data
= OV9650_VGA_SELECT
| OV9650_RGB_SELECT
|
454 OV9650_RAW_RGB_SELECT
;
455 err
= m5602_write_sensor(sd
, OV9650_COM7
, &data
, 1);
459 PDEBUG(D_V4L2
, "Configuring camera for CIF mode");
461 data
= OV9650_CIF_SELECT
| OV9650_RGB_SELECT
|
462 OV9650_RAW_RGB_SELECT
;
463 err
= m5602_write_sensor(sd
, OV9650_COM7
, &data
, 1);
467 PDEBUG(D_V4L2
, "Configuring camera for QVGA mode");
469 data
= OV9650_QVGA_SELECT
| OV9650_RGB_SELECT
|
470 OV9650_RAW_RGB_SELECT
;
471 err
= m5602_write_sensor(sd
, OV9650_COM7
, &data
, 1);
475 PDEBUG(D_V4L2
, "Configuring camera for QCIF mode");
477 data
= OV9650_QCIF_SELECT
| OV9650_RGB_SELECT
|
478 OV9650_RAW_RGB_SELECT
;
479 err
= m5602_write_sensor(sd
, OV9650_COM7
, &data
, 1);
485 int ov9650_stop(struct sd
*sd
)
487 u8 data
= OV9650_SOFT_SLEEP
| OV9650_OUTPUT_DRIVE_2X
;
488 return m5602_write_sensor(sd
, OV9650_COM2
, &data
, 1);
491 void ov9650_disconnect(struct sd
*sd
)
496 kfree(sd
->sensor_priv
);
499 static int ov9650_get_exposure(struct gspca_dev
*gspca_dev
, __s32
*val
)
501 struct sd
*sd
= (struct sd
*) gspca_dev
;
502 s32
*sensor_settings
= sd
->sensor_priv
;
504 *val
= sensor_settings
[EXPOSURE_IDX
];
505 PDEBUG(D_V4L2
, "Read exposure %d", *val
);
509 static int ov9650_set_exposure(struct gspca_dev
*gspca_dev
, __s32 val
)
511 struct sd
*sd
= (struct sd
*) gspca_dev
;
512 s32
*sensor_settings
= sd
->sensor_priv
;
516 PDEBUG(D_V4L2
, "Set exposure to %d", val
);
518 sensor_settings
[EXPOSURE_IDX
] = val
;
520 i2c_data
= (val
>> 10) & 0x3f;
521 err
= m5602_write_sensor(sd
, OV9650_AECHM
,
526 /* The 8 middle bits */
527 i2c_data
= (val
>> 2) & 0xff;
528 err
= m5602_write_sensor(sd
, OV9650_AECH
,
534 i2c_data
= val
& 0x03;
535 err
= m5602_write_sensor(sd
, OV9650_COM1
, &i2c_data
, 1);
539 static int ov9650_get_gain(struct gspca_dev
*gspca_dev
, __s32
*val
)
541 struct sd
*sd
= (struct sd
*) gspca_dev
;
542 s32
*sensor_settings
= sd
->sensor_priv
;
544 *val
= sensor_settings
[GAIN_IDX
];
545 PDEBUG(D_V4L2
, "Read gain %d", *val
);
549 static int ov9650_set_gain(struct gspca_dev
*gspca_dev
, __s32 val
)
553 struct sd
*sd
= (struct sd
*) gspca_dev
;
554 s32
*sensor_settings
= sd
->sensor_priv
;
556 PDEBUG(D_V4L2
, "Setting gain to %d", val
);
558 sensor_settings
[GAIN_IDX
] = val
;
561 /* Read the OV9650_VREF register first to avoid
562 corrupting the VREF high and low bits */
563 err
= m5602_read_sensor(sd
, OV9650_VREF
, &i2c_data
, 1);
567 /* Mask away all uninteresting bits */
568 i2c_data
= ((val
& 0x0300) >> 2) |
570 err
= m5602_write_sensor(sd
, OV9650_VREF
, &i2c_data
, 1);
575 i2c_data
= val
& 0xff;
576 err
= m5602_write_sensor(sd
, OV9650_GAIN
, &i2c_data
, 1);
580 static int ov9650_get_red_balance(struct gspca_dev
*gspca_dev
, __s32
*val
)
582 struct sd
*sd
= (struct sd
*) gspca_dev
;
583 s32
*sensor_settings
= sd
->sensor_priv
;
585 *val
= sensor_settings
[RED_BALANCE_IDX
];
586 PDEBUG(D_V4L2
, "Read red gain %d", *val
);
590 static int ov9650_set_red_balance(struct gspca_dev
*gspca_dev
, __s32 val
)
594 struct sd
*sd
= (struct sd
*) gspca_dev
;
595 s32
*sensor_settings
= sd
->sensor_priv
;
597 PDEBUG(D_V4L2
, "Set red gain to %d", val
);
599 sensor_settings
[RED_BALANCE_IDX
] = val
;
601 i2c_data
= val
& 0xff;
602 err
= m5602_write_sensor(sd
, OV9650_RED
, &i2c_data
, 1);
606 static int ov9650_get_blue_balance(struct gspca_dev
*gspca_dev
, __s32
*val
)
608 struct sd
*sd
= (struct sd
*) gspca_dev
;
609 s32
*sensor_settings
= sd
->sensor_priv
;
611 *val
= sensor_settings
[BLUE_BALANCE_IDX
];
612 PDEBUG(D_V4L2
, "Read blue gain %d", *val
);
617 static int ov9650_set_blue_balance(struct gspca_dev
*gspca_dev
, __s32 val
)
621 struct sd
*sd
= (struct sd
*) gspca_dev
;
622 s32
*sensor_settings
= sd
->sensor_priv
;
624 PDEBUG(D_V4L2
, "Set blue gain to %d", val
);
626 sensor_settings
[BLUE_BALANCE_IDX
] = val
;
628 i2c_data
= val
& 0xff;
629 err
= m5602_write_sensor(sd
, OV9650_BLUE
, &i2c_data
, 1);
633 static int ov9650_get_hflip(struct gspca_dev
*gspca_dev
, __s32
*val
)
635 struct sd
*sd
= (struct sd
*) gspca_dev
;
636 s32
*sensor_settings
= sd
->sensor_priv
;
638 *val
= sensor_settings
[HFLIP_IDX
];
639 PDEBUG(D_V4L2
, "Read horizontal flip %d", *val
);
643 static int ov9650_set_hflip(struct gspca_dev
*gspca_dev
, __s32 val
)
647 struct sd
*sd
= (struct sd
*) gspca_dev
;
648 s32
*sensor_settings
= sd
->sensor_priv
;
650 PDEBUG(D_V4L2
, "Set horizontal flip to %d", val
);
652 sensor_settings
[HFLIP_IDX
] = val
;
654 if (!dmi_check_system(ov9650_flip_dmi_table
))
655 i2c_data
= ((val
& 0x01) << 5) |
656 (sensor_settings
[VFLIP_IDX
] << 4);
658 i2c_data
= ((val
& 0x01) << 5) |
659 (!sensor_settings
[VFLIP_IDX
] << 4);
661 err
= m5602_write_sensor(sd
, OV9650_MVFP
, &i2c_data
, 1);
666 static int ov9650_get_vflip(struct gspca_dev
*gspca_dev
, __s32
*val
)
668 struct sd
*sd
= (struct sd
*) gspca_dev
;
669 s32
*sensor_settings
= sd
->sensor_priv
;
671 *val
= sensor_settings
[VFLIP_IDX
];
672 PDEBUG(D_V4L2
, "Read vertical flip %d", *val
);
677 static int ov9650_set_vflip(struct gspca_dev
*gspca_dev
, __s32 val
)
681 struct sd
*sd
= (struct sd
*) gspca_dev
;
682 s32
*sensor_settings
= sd
->sensor_priv
;
684 PDEBUG(D_V4L2
, "Set vertical flip to %d", val
);
685 sensor_settings
[VFLIP_IDX
] = val
;
687 if (dmi_check_system(ov9650_flip_dmi_table
))
690 i2c_data
= ((val
& 0x01) << 4) | (sensor_settings
[VFLIP_IDX
] << 5);
691 err
= m5602_write_sensor(sd
, OV9650_MVFP
, &i2c_data
, 1);
695 /* When vflip is toggled we need to readjust the bridge hsync/vsync */
696 if (gspca_dev
->streaming
)
697 err
= ov9650_start(sd
);
702 static int ov9650_get_auto_white_balance(struct gspca_dev
*gspca_dev
,
705 struct sd
*sd
= (struct sd
*) gspca_dev
;
706 s32
*sensor_settings
= sd
->sensor_priv
;
708 *val
= sensor_settings
[AUTO_WHITE_BALANCE_IDX
];
712 static int ov9650_set_auto_white_balance(struct gspca_dev
*gspca_dev
,
717 struct sd
*sd
= (struct sd
*) gspca_dev
;
718 s32
*sensor_settings
= sd
->sensor_priv
;
720 PDEBUG(D_V4L2
, "Set auto white balance to %d", val
);
722 sensor_settings
[AUTO_WHITE_BALANCE_IDX
] = val
;
723 err
= m5602_read_sensor(sd
, OV9650_COM8
, &i2c_data
, 1);
727 i2c_data
= ((i2c_data
& 0xfd) | ((val
& 0x01) << 1));
728 err
= m5602_write_sensor(sd
, OV9650_COM8
, &i2c_data
, 1);
733 static int ov9650_get_auto_gain(struct gspca_dev
*gspca_dev
, __s32
*val
)
735 struct sd
*sd
= (struct sd
*) gspca_dev
;
736 s32
*sensor_settings
= sd
->sensor_priv
;
738 *val
= sensor_settings
[AUTO_GAIN_CTRL_IDX
];
739 PDEBUG(D_V4L2
, "Read auto gain control %d", *val
);
743 static int ov9650_set_auto_gain(struct gspca_dev
*gspca_dev
, __s32 val
)
747 struct sd
*sd
= (struct sd
*) gspca_dev
;
748 s32
*sensor_settings
= sd
->sensor_priv
;
750 PDEBUG(D_V4L2
, "Set auto gain control to %d", val
);
752 sensor_settings
[AUTO_GAIN_CTRL_IDX
] = val
;
753 err
= m5602_read_sensor(sd
, OV9650_COM8
, &i2c_data
, 1);
757 i2c_data
= ((i2c_data
& 0xfb) | ((val
& 0x01) << 2));
758 err
= m5602_write_sensor(sd
, OV9650_COM8
, &i2c_data
, 1);
763 static void ov9650_dump_registers(struct sd
*sd
)
766 info("Dumping the ov9650 register state");
767 for (address
= 0; address
< 0xa9; address
++) {
769 m5602_read_sensor(sd
, address
, &value
, 1);
770 info("register 0x%x contains 0x%x",
774 info("ov9650 register state dump complete");
776 info("Probing for which registers that are read/write");
777 for (address
= 0; address
< 0xff; address
++) {
778 u8 old_value
, ctrl_value
;
779 u8 test_value
[2] = {0xff, 0xff};
781 m5602_read_sensor(sd
, address
, &old_value
, 1);
782 m5602_write_sensor(sd
, address
, test_value
, 1);
783 m5602_read_sensor(sd
, address
, &ctrl_value
, 1);
785 if (ctrl_value
== test_value
[0])
786 info("register 0x%x is writeable", address
);
788 info("register 0x%x is read only", address
);
790 /* Restore original value */
791 m5602_write_sensor(sd
, address
, &old_value
, 1);