2 * Driver for the ov7660 sensor
4 * Copyright (C) 2009 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_ov7660.h"
23 static int ov7660_s_ctrl(struct v4l2_ctrl
*ctrl
);
24 static void ov7660_dump_registers(struct sd
*sd
);
26 static struct v4l2_pix_format ov7660_modes
[] = {
35 .colorspace
= V4L2_COLORSPACE_SRGB
,
40 static const struct v4l2_ctrl_ops ov7660_ctrl_ops
= {
41 .s_ctrl
= ov7660_s_ctrl
,
44 int ov7660_probe(struct sd
*sd
)
47 u8 prod_id
= 0, ver_id
= 0;
50 if (force_sensor
== OV7660_SENSOR
) {
51 pr_info("Forcing an %s sensor\n", ov7660
.name
);
54 /* If we want to force another sensor,
55 don't try to probe this one */
60 for (i
= 0; i
< ARRAY_SIZE(preinit_ov7660
) && !err
; i
++) {
63 if (preinit_ov7660
[i
][0] == BRIDGE
) {
64 err
= m5602_write_bridge(sd
,
66 preinit_ov7660
[i
][2]);
68 data
[0] = preinit_ov7660
[i
][2];
69 err
= m5602_write_sensor(sd
,
70 preinit_ov7660
[i
][1], data
, 1);
76 if (m5602_read_sensor(sd
, OV7660_PID
, &prod_id
, 1))
79 if (m5602_read_sensor(sd
, OV7660_VER
, &ver_id
, 1))
82 pr_info("Sensor reported 0x%x%x\n", prod_id
, ver_id
);
84 if ((prod_id
== 0x76) && (ver_id
== 0x60)) {
85 pr_info("Detected a ov7660 sensor\n");
91 sd
->gspca_dev
.cam
.cam_mode
= ov7660_modes
;
92 sd
->gspca_dev
.cam
.nmodes
= ARRAY_SIZE(ov7660_modes
);
97 int ov7660_init(struct sd
*sd
)
101 /* Init the sensor */
102 for (i
= 0; i
< ARRAY_SIZE(init_ov7660
); i
++) {
105 if (init_ov7660
[i
][0] == BRIDGE
) {
106 err
= m5602_write_bridge(sd
,
110 data
[0] = init_ov7660
[i
][2];
111 err
= m5602_write_sensor(sd
,
112 init_ov7660
[i
][1], data
, 1);
119 ov7660_dump_registers(sd
);
124 int ov7660_init_controls(struct sd
*sd
)
126 struct v4l2_ctrl_handler
*hdl
= &sd
->gspca_dev
.ctrl_handler
;
128 sd
->gspca_dev
.vdev
.ctrl_handler
= hdl
;
129 v4l2_ctrl_handler_init(hdl
, 6);
131 v4l2_ctrl_new_std(hdl
, &ov7660_ctrl_ops
, V4L2_CID_AUTO_WHITE_BALANCE
,
133 v4l2_ctrl_new_std_menu(hdl
, &ov7660_ctrl_ops
,
134 V4L2_CID_EXPOSURE_AUTO
, 1, 0, V4L2_EXPOSURE_AUTO
);
136 sd
->autogain
= v4l2_ctrl_new_std(hdl
, &ov7660_ctrl_ops
,
137 V4L2_CID_AUTOGAIN
, 0, 1, 1, 1);
138 sd
->gain
= v4l2_ctrl_new_std(hdl
, &ov7660_ctrl_ops
, V4L2_CID_GAIN
, 0,
139 255, 1, OV7660_DEFAULT_GAIN
);
141 sd
->hflip
= v4l2_ctrl_new_std(hdl
, &ov7660_ctrl_ops
, V4L2_CID_HFLIP
,
143 sd
->vflip
= v4l2_ctrl_new_std(hdl
, &ov7660_ctrl_ops
, V4L2_CID_VFLIP
,
147 pr_err("Could not initialize controls\n");
151 v4l2_ctrl_auto_cluster(2, &sd
->autogain
, 0, false);
152 v4l2_ctrl_cluster(2, &sd
->hflip
);
157 int ov7660_start(struct sd
*sd
)
162 int ov7660_stop(struct sd
*sd
)
167 void ov7660_disconnect(struct sd
*sd
)
174 static int ov7660_set_gain(struct gspca_dev
*gspca_dev
, __s32 val
)
178 struct sd
*sd
= (struct sd
*) gspca_dev
;
180 PDEBUG(D_CONF
, "Setting gain to %d", val
);
182 err
= m5602_write_sensor(sd
, OV7660_GAIN
, &i2c_data
, 1);
186 static int ov7660_set_auto_white_balance(struct gspca_dev
*gspca_dev
,
191 struct sd
*sd
= (struct sd
*) gspca_dev
;
193 PDEBUG(D_CONF
, "Set auto white balance to %d", val
);
195 err
= m5602_read_sensor(sd
, OV7660_COM8
, &i2c_data
, 1);
199 i2c_data
= ((i2c_data
& 0xfd) | ((val
& 0x01) << 1));
200 err
= m5602_write_sensor(sd
, OV7660_COM8
, &i2c_data
, 1);
205 static int ov7660_set_auto_gain(struct gspca_dev
*gspca_dev
, __s32 val
)
209 struct sd
*sd
= (struct sd
*) gspca_dev
;
211 PDEBUG(D_CONF
, "Set auto gain control to %d", val
);
213 err
= m5602_read_sensor(sd
, OV7660_COM8
, &i2c_data
, 1);
217 i2c_data
= ((i2c_data
& 0xfb) | ((val
& 0x01) << 2));
219 return m5602_write_sensor(sd
, OV7660_COM8
, &i2c_data
, 1);
222 static int ov7660_set_auto_exposure(struct gspca_dev
*gspca_dev
,
227 struct sd
*sd
= (struct sd
*) gspca_dev
;
229 PDEBUG(D_CONF
, "Set auto exposure control to %d", val
);
231 err
= m5602_read_sensor(sd
, OV7660_COM8
, &i2c_data
, 1);
235 val
= (val
== V4L2_EXPOSURE_AUTO
);
236 i2c_data
= ((i2c_data
& 0xfe) | ((val
& 0x01) << 0));
238 return m5602_write_sensor(sd
, OV7660_COM8
, &i2c_data
, 1);
241 static int ov7660_set_hvflip(struct gspca_dev
*gspca_dev
)
245 struct sd
*sd
= (struct sd
*) gspca_dev
;
247 PDEBUG(D_CONF
, "Set hvflip to %d, %d", sd
->hflip
->val
, sd
->vflip
->val
);
249 i2c_data
= (sd
->hflip
->val
<< 5) | (sd
->vflip
->val
<< 4);
251 err
= m5602_write_sensor(sd
, OV7660_MVFP
, &i2c_data
, 1);
256 static int ov7660_s_ctrl(struct v4l2_ctrl
*ctrl
)
258 struct gspca_dev
*gspca_dev
=
259 container_of(ctrl
->handler
, struct gspca_dev
, ctrl_handler
);
260 struct sd
*sd
= (struct sd
*) gspca_dev
;
263 if (!gspca_dev
->streaming
)
267 case V4L2_CID_AUTO_WHITE_BALANCE
:
268 err
= ov7660_set_auto_white_balance(gspca_dev
, ctrl
->val
);
270 case V4L2_CID_EXPOSURE_AUTO
:
271 err
= ov7660_set_auto_exposure(gspca_dev
, ctrl
->val
);
273 case V4L2_CID_AUTOGAIN
:
274 err
= ov7660_set_auto_gain(gspca_dev
, ctrl
->val
);
275 if (err
|| ctrl
->val
)
277 err
= ov7660_set_gain(gspca_dev
, sd
->gain
->val
);
280 err
= ov7660_set_hvflip(gspca_dev
);
289 static void ov7660_dump_registers(struct sd
*sd
)
292 pr_info("Dumping the ov7660 register state\n");
293 for (address
= 0; address
< 0xa9; address
++) {
295 m5602_read_sensor(sd
, address
, &value
, 1);
296 pr_info("register 0x%x contains 0x%x\n", address
, value
);
299 pr_info("ov7660 register state dump complete\n");
301 pr_info("Probing for which registers that are read/write\n");
302 for (address
= 0; address
< 0xff; address
++) {
303 u8 old_value
, ctrl_value
;
304 u8 test_value
[2] = {0xff, 0xff};
306 m5602_read_sensor(sd
, address
, &old_value
, 1);
307 m5602_write_sensor(sd
, address
, test_value
, 1);
308 m5602_read_sensor(sd
, address
, &ctrl_value
, 1);
310 if (ctrl_value
== test_value
[0])
311 pr_info("register 0x%x is writeable\n", address
);
313 pr_info("register 0x%x is read only\n", address
);
315 /* Restore original value */
316 m5602_write_sensor(sd
, address
, &old_value
, 1);