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 
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 
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 
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 
310 int ov7660_start(struct sd *sd)
311 {
312 	return 0;
313 }
314 
315 int ov7660_stop(struct sd *sd)
316 {
317 	return 0;
318 }
319 
320 void ov7660_disconnect(struct sd *sd)
321 {
322 	ov7660_stop(sd);
323 
324 	sd->sensor = NULL;
325 }
326 
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 
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 
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 
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 
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 
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 
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