1 /*
2 * Driver for the ov7660 sensor
3 *
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>
7 *
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
12 *
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.
16 *
17 */
18
19 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
20
21 #include "m5602_ov7660.h"
22
23 static int ov7660_s_ctrl(struct v4l2_ctrl *ctrl);
24 static void ov7660_dump_registers(struct sd *sd);
25
26 static const unsigned char preinit_ov7660[][4] = {
27 {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02},
28 {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0},
29 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
30 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
31 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
32 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d},
33 {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00},
34 {BRIDGE, M5602_XB_GPIO_DIR, 0x03},
35 {BRIDGE, M5602_XB_GPIO_DIR, 0x03},
36 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
37 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
38
39 {SENSOR, OV7660_OFON, 0x0c},
40 {SENSOR, OV7660_COM2, 0x11},
41 {SENSOR, OV7660_COM7, 0x05},
42
43 {BRIDGE, M5602_XB_GPIO_DIR, 0x01},
44 {BRIDGE, M5602_XB_GPIO_DAT, 0x04},
45 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
46 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
47 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
48 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08},
49 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
50 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
51 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
52 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
53 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
54 {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
55 {BRIDGE, M5602_XB_GPIO_DAT, 0x00},
56 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
57 {BRIDGE, M5602_XB_GPIO_EN_L, 0x00}
58 };
59
60 static const unsigned char init_ov7660[][4] = {
61 {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02},
62 {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0},
63 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
64 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
65 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
66 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d},
67 {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00},
68 {BRIDGE, M5602_XB_GPIO_DIR, 0x01},
69 {BRIDGE, M5602_XB_GPIO_DIR, 0x01},
70 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
71 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
72 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
73 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
74 {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
75 {BRIDGE, M5602_XB_GPIO_DAT, 0x00},
76 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
77 {BRIDGE, M5602_XB_GPIO_EN_L, 0x00},
78 {SENSOR, OV7660_COM7, 0x80},
79 {SENSOR, OV7660_CLKRC, 0x80},
80 {SENSOR, OV7660_COM9, 0x4c},
81 {SENSOR, OV7660_OFON, 0x43},
82 {SENSOR, OV7660_COM12, 0x28},
83 {SENSOR, OV7660_COM8, 0x00},
84 {SENSOR, OV7660_COM10, 0x40},
85 {SENSOR, OV7660_HSTART, 0x0c},
86 {SENSOR, OV7660_HSTOP, 0x61},
87 {SENSOR, OV7660_HREF, 0xa4},
88 {SENSOR, OV7660_PSHFT, 0x0b},
89 {SENSOR, OV7660_VSTART, 0x01},
90 {SENSOR, OV7660_VSTOP, 0x7a},
91 {SENSOR, OV7660_VSTOP, 0x00},
92 {SENSOR, OV7660_COM7, 0x05},
93 {SENSOR, OV7660_COM6, 0x42},
94 {SENSOR, OV7660_BBIAS, 0x94},
95 {SENSOR, OV7660_GbBIAS, 0x94},
96 {SENSOR, OV7660_RSVD29, 0x94},
97 {SENSOR, OV7660_RBIAS, 0x94},
98 {SENSOR, OV7660_COM1, 0x00},
99 {SENSOR, OV7660_AECH, 0x00},
100 {SENSOR, OV7660_AECHH, 0x00},
101 {SENSOR, OV7660_ADC, 0x05},
102 {SENSOR, OV7660_COM13, 0x00},
103 {SENSOR, OV7660_RSVDA1, 0x23},
104 {SENSOR, OV7660_TSLB, 0x0d},
105 {SENSOR, OV7660_HV, 0x80},
106 {SENSOR, OV7660_LCC1, 0x00},
107 {SENSOR, OV7660_LCC2, 0x00},
108 {SENSOR, OV7660_LCC3, 0x10},
109 {SENSOR, OV7660_LCC4, 0x40},
110 {SENSOR, OV7660_LCC5, 0x01},
111
112 {SENSOR, OV7660_AECH, 0x20},
113 {SENSOR, OV7660_COM1, 0x00},
114 {SENSOR, OV7660_OFON, 0x0c},
115 {SENSOR, OV7660_COM2, 0x11},
116 {SENSOR, OV7660_COM7, 0x05},
117 {BRIDGE, M5602_XB_GPIO_DIR, 0x01},
118 {BRIDGE, M5602_XB_GPIO_DAT, 0x04},
119 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
120 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
121 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
122 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08},
123 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
124 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
125 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
126 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
127 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
128 {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
129 {BRIDGE, M5602_XB_GPIO_DAT, 0x00},
130 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
131 {BRIDGE, M5602_XB_GPIO_EN_L, 0x00},
132 {SENSOR, OV7660_AECH, 0x5f},
133 {SENSOR, OV7660_COM1, 0x03},
134 {SENSOR, OV7660_OFON, 0x0c},
135 {SENSOR, OV7660_COM2, 0x11},
136 {SENSOR, OV7660_COM7, 0x05},
137 {BRIDGE, M5602_XB_GPIO_DIR, 0x01},
138 {BRIDGE, M5602_XB_GPIO_DAT, 0x04},
139 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
140 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
141 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
142 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08},
143 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
144 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
145 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
146 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
147 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
148 {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
149 {BRIDGE, M5602_XB_GPIO_DAT, 0x00},
150 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
151 {BRIDGE, M5602_XB_GPIO_EN_L, 0x00},
152
153 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06},
154 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
155 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
156 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
157 {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81},
158 {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82},
159 {BRIDGE, M5602_XB_SIG_INI, 0x01},
160 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
161 {BRIDGE, M5602_XB_VSYNC_PARA, 0x08},
162 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
163 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
164 {BRIDGE, M5602_XB_VSYNC_PARA, 0x01},
165 {BRIDGE, M5602_XB_VSYNC_PARA, 0xec},
166 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
167 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
168 {BRIDGE, M5602_XB_SIG_INI, 0x00},
169 {BRIDGE, M5602_XB_SIG_INI, 0x02},
170 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
171 {BRIDGE, M5602_XB_HSYNC_PARA, 0x27},
172 {BRIDGE, M5602_XB_HSYNC_PARA, 0x02},
173 {BRIDGE, M5602_XB_HSYNC_PARA, 0xa7},
174 {BRIDGE, M5602_XB_SIG_INI, 0x00},
175 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
176 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
177 };
178
179 static struct v4l2_pix_format ov7660_modes[] = {
180 {
181 640,
182 480,
183 V4L2_PIX_FMT_SBGGR8,
184 V4L2_FIELD_NONE,
185 .sizeimage =
186 640 * 480,
187 .bytesperline = 640,
188 .colorspace = V4L2_COLORSPACE_SRGB,
189 .priv = 0
190 }
191 };
192
193 static const struct v4l2_ctrl_ops ov7660_ctrl_ops = {
194 .s_ctrl = ov7660_s_ctrl,
195 };
196
ov7660_probe(struct sd * sd)197 int ov7660_probe(struct sd *sd)
198 {
199 int err = 0, i;
200 u8 prod_id = 0, ver_id = 0;
201
202 if (force_sensor) {
203 if (force_sensor == OV7660_SENSOR) {
204 pr_info("Forcing an %s sensor\n", ov7660.name);
205 goto sensor_found;
206 }
207 /* If we want to force another sensor,
208 don't try to probe this one */
209 return -ENODEV;
210 }
211
212 /* Do the preinit */
213 for (i = 0; i < ARRAY_SIZE(preinit_ov7660) && !err; i++) {
214 u8 data[2];
215
216 if (preinit_ov7660[i][0] == BRIDGE) {
217 err = m5602_write_bridge(sd,
218 preinit_ov7660[i][1],
219 preinit_ov7660[i][2]);
220 } else {
221 data[0] = preinit_ov7660[i][2];
222 err = m5602_write_sensor(sd,
223 preinit_ov7660[i][1], data, 1);
224 }
225 }
226 if (err < 0)
227 return err;
228
229 if (m5602_read_sensor(sd, OV7660_PID, &prod_id, 1))
230 return -ENODEV;
231
232 if (m5602_read_sensor(sd, OV7660_VER, &ver_id, 1))
233 return -ENODEV;
234
235 pr_info("Sensor reported 0x%x%x\n", prod_id, ver_id);
236
237 if ((prod_id == 0x76) && (ver_id == 0x60)) {
238 pr_info("Detected a ov7660 sensor\n");
239 goto sensor_found;
240 }
241 return -ENODEV;
242
243 sensor_found:
244 sd->gspca_dev.cam.cam_mode = ov7660_modes;
245 sd->gspca_dev.cam.nmodes = ARRAY_SIZE(ov7660_modes);
246
247 return 0;
248 }
249
ov7660_init(struct sd * sd)250 int ov7660_init(struct sd *sd)
251 {
252 int i, err;
253
254 /* Init the sensor */
255 for (i = 0; i < ARRAY_SIZE(init_ov7660); i++) {
256 u8 data[2];
257
258 if (init_ov7660[i][0] == BRIDGE) {
259 err = m5602_write_bridge(sd,
260 init_ov7660[i][1],
261 init_ov7660[i][2]);
262 } else {
263 data[0] = init_ov7660[i][2];
264 err = m5602_write_sensor(sd,
265 init_ov7660[i][1], data, 1);
266 }
267 if (err < 0)
268 return err;
269 }
270
271 if (dump_sensor)
272 ov7660_dump_registers(sd);
273
274 return 0;
275 }
276
ov7660_init_controls(struct sd * sd)277 int ov7660_init_controls(struct sd *sd)
278 {
279 struct v4l2_ctrl_handler *hdl = &sd->gspca_dev.ctrl_handler;
280
281 sd->gspca_dev.vdev.ctrl_handler = hdl;
282 v4l2_ctrl_handler_init(hdl, 6);
283
284 v4l2_ctrl_new_std(hdl, &ov7660_ctrl_ops, V4L2_CID_AUTO_WHITE_BALANCE,
285 0, 1, 1, 1);
286 v4l2_ctrl_new_std_menu(hdl, &ov7660_ctrl_ops,
287 V4L2_CID_EXPOSURE_AUTO, 1, 0, V4L2_EXPOSURE_AUTO);
288
289 sd->autogain = v4l2_ctrl_new_std(hdl, &ov7660_ctrl_ops,
290 V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
291 sd->gain = v4l2_ctrl_new_std(hdl, &ov7660_ctrl_ops, V4L2_CID_GAIN, 0,
292 255, 1, OV7660_DEFAULT_GAIN);
293
294 sd->hflip = v4l2_ctrl_new_std(hdl, &ov7660_ctrl_ops, V4L2_CID_HFLIP,
295 0, 1, 1, 0);
296 sd->vflip = v4l2_ctrl_new_std(hdl, &ov7660_ctrl_ops, V4L2_CID_VFLIP,
297 0, 1, 1, 0);
298
299 if (hdl->error) {
300 pr_err("Could not initialize controls\n");
301 return hdl->error;
302 }
303
304 v4l2_ctrl_auto_cluster(2, &sd->autogain, 0, false);
305 v4l2_ctrl_cluster(2, &sd->hflip);
306
307 return 0;
308 }
309
ov7660_start(struct sd * sd)310 int ov7660_start(struct sd *sd)
311 {
312 return 0;
313 }
314
ov7660_stop(struct sd * sd)315 int ov7660_stop(struct sd *sd)
316 {
317 return 0;
318 }
319
ov7660_disconnect(struct sd * sd)320 void ov7660_disconnect(struct sd *sd)
321 {
322 ov7660_stop(sd);
323
324 sd->sensor = NULL;
325 }
326
ov7660_set_gain(struct gspca_dev * gspca_dev,__s32 val)327 static int ov7660_set_gain(struct gspca_dev *gspca_dev, __s32 val)
328 {
329 int err;
330 u8 i2c_data = val;
331 struct sd *sd = (struct sd *) gspca_dev;
332
333 gspca_dbg(gspca_dev, D_CONF, "Setting gain to %d\n", val);
334
335 err = m5602_write_sensor(sd, OV7660_GAIN, &i2c_data, 1);
336 return err;
337 }
338
ov7660_set_auto_white_balance(struct gspca_dev * gspca_dev,__s32 val)339 static int ov7660_set_auto_white_balance(struct gspca_dev *gspca_dev,
340 __s32 val)
341 {
342 int err;
343 u8 i2c_data;
344 struct sd *sd = (struct sd *) gspca_dev;
345
346 gspca_dbg(gspca_dev, D_CONF, "Set auto white balance to %d\n", val);
347
348 err = m5602_read_sensor(sd, OV7660_COM8, &i2c_data, 1);
349 if (err < 0)
350 return err;
351
352 i2c_data = ((i2c_data & 0xfd) | ((val & 0x01) << 1));
353 err = m5602_write_sensor(sd, OV7660_COM8, &i2c_data, 1);
354
355 return err;
356 }
357
ov7660_set_auto_gain(struct gspca_dev * gspca_dev,__s32 val)358 static int ov7660_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val)
359 {
360 int err;
361 u8 i2c_data;
362 struct sd *sd = (struct sd *) gspca_dev;
363
364 gspca_dbg(gspca_dev, D_CONF, "Set auto gain control to %d\n", val);
365
366 err = m5602_read_sensor(sd, OV7660_COM8, &i2c_data, 1);
367 if (err < 0)
368 return err;
369
370 i2c_data = ((i2c_data & 0xfb) | ((val & 0x01) << 2));
371
372 return m5602_write_sensor(sd, OV7660_COM8, &i2c_data, 1);
373 }
374
ov7660_set_auto_exposure(struct gspca_dev * gspca_dev,__s32 val)375 static int ov7660_set_auto_exposure(struct gspca_dev *gspca_dev,
376 __s32 val)
377 {
378 int err;
379 u8 i2c_data;
380 struct sd *sd = (struct sd *) gspca_dev;
381
382 gspca_dbg(gspca_dev, D_CONF, "Set auto exposure control to %d\n", val);
383
384 err = m5602_read_sensor(sd, OV7660_COM8, &i2c_data, 1);
385 if (err < 0)
386 return err;
387
388 val = (val == V4L2_EXPOSURE_AUTO);
389 i2c_data = ((i2c_data & 0xfe) | ((val & 0x01) << 0));
390
391 return m5602_write_sensor(sd, OV7660_COM8, &i2c_data, 1);
392 }
393
ov7660_set_hvflip(struct gspca_dev * gspca_dev)394 static int ov7660_set_hvflip(struct gspca_dev *gspca_dev)
395 {
396 int err;
397 u8 i2c_data;
398 struct sd *sd = (struct sd *) gspca_dev;
399
400 gspca_dbg(gspca_dev, D_CONF, "Set hvflip to %d, %d\n",
401 sd->hflip->val, sd->vflip->val);
402
403 i2c_data = (sd->hflip->val << 5) | (sd->vflip->val << 4);
404
405 err = m5602_write_sensor(sd, OV7660_MVFP, &i2c_data, 1);
406
407 return err;
408 }
409
ov7660_s_ctrl(struct v4l2_ctrl * ctrl)410 static int ov7660_s_ctrl(struct v4l2_ctrl *ctrl)
411 {
412 struct gspca_dev *gspca_dev =
413 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
414 struct sd *sd = (struct sd *) gspca_dev;
415 int err;
416
417 if (!gspca_dev->streaming)
418 return 0;
419
420 switch (ctrl->id) {
421 case V4L2_CID_AUTO_WHITE_BALANCE:
422 err = ov7660_set_auto_white_balance(gspca_dev, ctrl->val);
423 break;
424 case V4L2_CID_EXPOSURE_AUTO:
425 err = ov7660_set_auto_exposure(gspca_dev, ctrl->val);
426 break;
427 case V4L2_CID_AUTOGAIN:
428 err = ov7660_set_auto_gain(gspca_dev, ctrl->val);
429 if (err || ctrl->val)
430 return err;
431 err = ov7660_set_gain(gspca_dev, sd->gain->val);
432 break;
433 case V4L2_CID_HFLIP:
434 err = ov7660_set_hvflip(gspca_dev);
435 break;
436 default:
437 return -EINVAL;
438 }
439
440 return err;
441 }
442
ov7660_dump_registers(struct sd * sd)443 static void ov7660_dump_registers(struct sd *sd)
444 {
445 int address;
446 pr_info("Dumping the ov7660 register state\n");
447 for (address = 0; address < 0xa9; address++) {
448 u8 value;
449 m5602_read_sensor(sd, address, &value, 1);
450 pr_info("register 0x%x contains 0x%x\n", address, value);
451 }
452
453 pr_info("ov7660 register state dump complete\n");
454
455 pr_info("Probing for which registers that are read/write\n");
456 for (address = 0; address < 0xff; address++) {
457 u8 old_value, ctrl_value;
458 u8 test_value[2] = {0xff, 0xff};
459
460 m5602_read_sensor(sd, address, &old_value, 1);
461 m5602_write_sensor(sd, address, test_value, 1);
462 m5602_read_sensor(sd, address, &ctrl_value, 1);
463
464 if (ctrl_value == test_value[0])
465 pr_info("register 0x%x is writeable\n", address);
466 else
467 pr_info("register 0x%x is read only\n", address);
468
469 /* Restore original value */
470 m5602_write_sensor(sd, address, &old_value, 1);
471 }
472 }
473