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 #include "m5602_ov7660.h"
20 
21 static int ov7660_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
22 static int ov7660_set_gain(struct gspca_dev *gspca_dev, __s32 val);
23 static int ov7660_get_auto_white_balance(struct gspca_dev *gspca_dev,
24 					 __s32 *val);
25 static int ov7660_set_auto_white_balance(struct gspca_dev *gspca_dev,
26 					 __s32 val);
27 static int ov7660_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val);
28 static int ov7660_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val);
29 static int ov7660_get_auto_exposure(struct gspca_dev *gspca_dev, __s32 *val);
30 static int ov7660_set_auto_exposure(struct gspca_dev *gspca_dev, __s32 val);
31 static int ov7660_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
32 static int ov7660_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
33 static int ov7660_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
34 static int ov7660_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
35 
36 static const struct ctrl ov7660_ctrls[] = {
37 #define GAIN_IDX 1
38 	{
39 		{
40 			.id		= V4L2_CID_GAIN,
41 			.type		= V4L2_CTRL_TYPE_INTEGER,
42 			.name		= "gain",
43 			.minimum	= 0x00,
44 			.maximum	= 0xff,
45 			.step		= 0x1,
46 			.default_value	= OV7660_DEFAULT_GAIN,
47 			.flags		= V4L2_CTRL_FLAG_SLIDER
48 		},
49 		.set = ov7660_set_gain,
50 		.get = ov7660_get_gain
51 	},
52 #define BLUE_BALANCE_IDX 2
53 #define RED_BALANCE_IDX 3
54 #define AUTO_WHITE_BALANCE_IDX 4
55 	{
56 		{
57 			.id		= V4L2_CID_AUTO_WHITE_BALANCE,
58 			.type		= V4L2_CTRL_TYPE_BOOLEAN,
59 			.name		= "auto white balance",
60 			.minimum	= 0,
61 			.maximum	= 1,
62 			.step		= 1,
63 			.default_value	= 1
64 		},
65 		.set = ov7660_set_auto_white_balance,
66 		.get = ov7660_get_auto_white_balance
67 	},
68 #define AUTO_GAIN_CTRL_IDX 5
69 	{
70 		{
71 			.id		= V4L2_CID_AUTOGAIN,
72 			.type		= V4L2_CTRL_TYPE_BOOLEAN,
73 			.name		= "auto gain control",
74 			.minimum	= 0,
75 			.maximum	= 1,
76 			.step		= 1,
77 			.default_value	= 1
78 		},
79 		.set = ov7660_set_auto_gain,
80 		.get = ov7660_get_auto_gain
81 	},
82 #define AUTO_EXPOSURE_IDX 6
83 	{
84 		{
85 			.id		= V4L2_CID_EXPOSURE_AUTO,
86 			.type		= V4L2_CTRL_TYPE_BOOLEAN,
87 			.name		= "auto exposure",
88 			.minimum	= 0,
89 			.maximum	= 1,
90 			.step		= 1,
91 			.default_value	= 1
92 		},
93 		.set = ov7660_set_auto_exposure,
94 		.get = ov7660_get_auto_exposure
95 	},
96 #define HFLIP_IDX 7
97 	{
98 		{
99 			.id		= V4L2_CID_HFLIP,
100 			.type		= V4L2_CTRL_TYPE_BOOLEAN,
101 			.name		= "horizontal flip",
102 			.minimum	= 0,
103 			.maximum	= 1,
104 			.step		= 1,
105 			.default_value	= 0
106 		},
107 		.set = ov7660_set_hflip,
108 		.get = ov7660_get_hflip
109 	},
110 #define VFLIP_IDX 8
111 	{
112 		{
113 			.id		= V4L2_CID_VFLIP,
114 			.type		= V4L2_CTRL_TYPE_BOOLEAN,
115 			.name		= "vertical flip",
116 			.minimum	= 0,
117 			.maximum	= 1,
118 			.step		= 1,
119 			.default_value	= 0
120 		},
121 		.set = ov7660_set_vflip,
122 		.get = ov7660_get_vflip
123 	},
124 
125 };
126 
127 static struct v4l2_pix_format ov7660_modes[] = {
128 	{
129 		640,
130 		480,
131 		V4L2_PIX_FMT_SBGGR8,
132 		V4L2_FIELD_NONE,
133 		.sizeimage =
134 			640 * 480,
135 		.bytesperline = 640,
136 		.colorspace = V4L2_COLORSPACE_SRGB,
137 		.priv = 0
138 	}
139 };
140 
141 static void ov7660_dump_registers(struct sd *sd);
142 
ov7660_probe(struct sd * sd)143 int ov7660_probe(struct sd *sd)
144 {
145 	int err = 0, i;
146 	u8 prod_id = 0, ver_id = 0;
147 
148 	s32 *sensor_settings;
149 
150 	if (force_sensor) {
151 		if (force_sensor == OV7660_SENSOR) {
152 			info("Forcing an %s sensor", ov7660.name);
153 			goto sensor_found;
154 		}
155 		/* If we want to force another sensor,
156 		don't try to probe this one */
157 		return -ENODEV;
158 	}
159 
160 	/* Do the preinit */
161 	for (i = 0; i < ARRAY_SIZE(preinit_ov7660) && !err; i++) {
162 		u8 data[2];
163 
164 		if (preinit_ov7660[i][0] == BRIDGE) {
165 			err = m5602_write_bridge(sd,
166 				preinit_ov7660[i][1],
167 				preinit_ov7660[i][2]);
168 		} else {
169 			data[0] = preinit_ov7660[i][2];
170 			err = m5602_write_sensor(sd,
171 				preinit_ov7660[i][1], data, 1);
172 		}
173 	}
174 	if (err < 0)
175 		return err;
176 
177 	if (m5602_read_sensor(sd, OV7660_PID, &prod_id, 1))
178 		return -ENODEV;
179 
180 	if (m5602_read_sensor(sd, OV7660_VER, &ver_id, 1))
181 		return -ENODEV;
182 
183 	info("Sensor reported 0x%x%x", prod_id, ver_id);
184 
185 	if ((prod_id == 0x76) && (ver_id == 0x60)) {
186 		info("Detected a ov7660 sensor");
187 		goto sensor_found;
188 	}
189 	return -ENODEV;
190 
191 sensor_found:
192 	sensor_settings = kmalloc(
193 		ARRAY_SIZE(ov7660_ctrls) * sizeof(s32), GFP_KERNEL);
194 	if (!sensor_settings)
195 		return -ENOMEM;
196 
197 	sd->gspca_dev.cam.cam_mode = ov7660_modes;
198 	sd->gspca_dev.cam.nmodes = ARRAY_SIZE(ov7660_modes);
199 	sd->desc->ctrls = ov7660_ctrls;
200 	sd->desc->nctrls = ARRAY_SIZE(ov7660_ctrls);
201 
202 	for (i = 0; i < ARRAY_SIZE(ov7660_ctrls); i++)
203 		sensor_settings[i] = ov7660_ctrls[i].qctrl.default_value;
204 	sd->sensor_priv = sensor_settings;
205 
206 	return 0;
207 }
208 
ov7660_init(struct sd * sd)209 int ov7660_init(struct sd *sd)
210 {
211 	int i, err = 0;
212 	s32 *sensor_settings = sd->sensor_priv;
213 
214 	/* Init the sensor */
215 	for (i = 0; i < ARRAY_SIZE(init_ov7660); i++) {
216 		u8 data[2];
217 
218 		if (init_ov7660[i][0] == BRIDGE) {
219 			err = m5602_write_bridge(sd,
220 				init_ov7660[i][1],
221 				init_ov7660[i][2]);
222 		} else {
223 			data[0] = init_ov7660[i][2];
224 			err = m5602_write_sensor(sd,
225 				init_ov7660[i][1], data, 1);
226 		}
227 	}
228 
229 	if (dump_sensor)
230 		ov7660_dump_registers(sd);
231 
232 	err = ov7660_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]);
233 	if (err < 0)
234 		return err;
235 
236 	err = ov7660_set_auto_white_balance(&sd->gspca_dev,
237 		sensor_settings[AUTO_WHITE_BALANCE_IDX]);
238 	if (err < 0)
239 		return err;
240 
241 	err = ov7660_set_auto_gain(&sd->gspca_dev,
242 		sensor_settings[AUTO_GAIN_CTRL_IDX]);
243 	if (err < 0)
244 		return err;
245 
246 	err = ov7660_set_auto_exposure(&sd->gspca_dev,
247 		sensor_settings[AUTO_EXPOSURE_IDX]);
248 	if (err < 0)
249 		return err;
250 	err = ov7660_set_hflip(&sd->gspca_dev,
251 		sensor_settings[HFLIP_IDX]);
252 	if (err < 0)
253 		return err;
254 
255 	err = ov7660_set_vflip(&sd->gspca_dev,
256 		sensor_settings[VFLIP_IDX]);
257 
258 	return err;
259 }
260 
ov7660_start(struct sd * sd)261 int ov7660_start(struct sd *sd)
262 {
263 	return 0;
264 }
265 
ov7660_stop(struct sd * sd)266 int ov7660_stop(struct sd *sd)
267 {
268 	return 0;
269 }
270 
ov7660_disconnect(struct sd * sd)271 void ov7660_disconnect(struct sd *sd)
272 {
273 	ov7660_stop(sd);
274 
275 	sd->sensor = NULL;
276 	kfree(sd->sensor_priv);
277 }
278 
ov7660_get_gain(struct gspca_dev * gspca_dev,__s32 * val)279 static int ov7660_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
280 {
281 	struct sd *sd = (struct sd *) gspca_dev;
282 	s32 *sensor_settings = sd->sensor_priv;
283 
284 	*val = sensor_settings[GAIN_IDX];
285 	PDEBUG(D_V4L2, "Read gain %d", *val);
286 	return 0;
287 }
288 
ov7660_set_gain(struct gspca_dev * gspca_dev,__s32 val)289 static int ov7660_set_gain(struct gspca_dev *gspca_dev, __s32 val)
290 {
291 	int err;
292 	u8 i2c_data;
293 	struct sd *sd = (struct sd *) gspca_dev;
294 	s32 *sensor_settings = sd->sensor_priv;
295 
296 	PDEBUG(D_V4L2, "Setting gain to %d", val);
297 
298 	sensor_settings[GAIN_IDX] = val;
299 
300 	err = m5602_write_sensor(sd, OV7660_GAIN, &i2c_data, 1);
301 	return err;
302 }
303 
304 
ov7660_get_auto_white_balance(struct gspca_dev * gspca_dev,__s32 * val)305 static int ov7660_get_auto_white_balance(struct gspca_dev *gspca_dev,
306 					 __s32 *val)
307 {
308 	struct sd *sd = (struct sd *) gspca_dev;
309 	s32 *sensor_settings = sd->sensor_priv;
310 
311 	*val = sensor_settings[AUTO_WHITE_BALANCE_IDX];
312 	return 0;
313 }
314 
ov7660_set_auto_white_balance(struct gspca_dev * gspca_dev,__s32 val)315 static int ov7660_set_auto_white_balance(struct gspca_dev *gspca_dev,
316 					 __s32 val)
317 {
318 	int err;
319 	u8 i2c_data;
320 	struct sd *sd = (struct sd *) gspca_dev;
321 	s32 *sensor_settings = sd->sensor_priv;
322 
323 	PDEBUG(D_V4L2, "Set auto white balance to %d", val);
324 
325 	sensor_settings[AUTO_WHITE_BALANCE_IDX] = val;
326 	err = m5602_read_sensor(sd, OV7660_COM8, &i2c_data, 1);
327 	if (err < 0)
328 		return err;
329 
330 	i2c_data = ((i2c_data & 0xfd) | ((val & 0x01) << 1));
331 	err = m5602_write_sensor(sd, OV7660_COM8, &i2c_data, 1);
332 
333 	return err;
334 }
335 
ov7660_get_auto_gain(struct gspca_dev * gspca_dev,__s32 * val)336 static int ov7660_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val)
337 {
338 	struct sd *sd = (struct sd *) gspca_dev;
339 	s32 *sensor_settings = sd->sensor_priv;
340 
341 	*val = sensor_settings[AUTO_GAIN_CTRL_IDX];
342 	PDEBUG(D_V4L2, "Read auto gain control %d", *val);
343 	return 0;
344 }
345 
ov7660_set_auto_gain(struct gspca_dev * gspca_dev,__s32 val)346 static int ov7660_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val)
347 {
348 	int err;
349 	u8 i2c_data;
350 	struct sd *sd = (struct sd *) gspca_dev;
351 	s32 *sensor_settings = sd->sensor_priv;
352 
353 	PDEBUG(D_V4L2, "Set auto gain control to %d", val);
354 
355 	sensor_settings[AUTO_GAIN_CTRL_IDX] = val;
356 	err = m5602_read_sensor(sd, OV7660_COM8, &i2c_data, 1);
357 	if (err < 0)
358 		return err;
359 
360 	i2c_data = ((i2c_data & 0xfb) | ((val & 0x01) << 2));
361 
362 	return m5602_write_sensor(sd, OV7660_COM8, &i2c_data, 1);
363 }
364 
ov7660_get_auto_exposure(struct gspca_dev * gspca_dev,__s32 * val)365 static int ov7660_get_auto_exposure(struct gspca_dev *gspca_dev, __s32 *val)
366 {
367 	struct sd *sd = (struct sd *) gspca_dev;
368 	s32 *sensor_settings = sd->sensor_priv;
369 
370 	*val = sensor_settings[AUTO_EXPOSURE_IDX];
371 	PDEBUG(D_V4L2, "Read auto exposure control %d", *val);
372 	return 0;
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 	s32 *sensor_settings = sd->sensor_priv;
382 
383 	PDEBUG(D_V4L2, "Set auto exposure control to %d", val);
384 
385 	sensor_settings[AUTO_EXPOSURE_IDX] = val;
386 	err = m5602_read_sensor(sd, OV7660_COM8, &i2c_data, 1);
387 	if (err < 0)
388 		return err;
389 
390 	i2c_data = ((i2c_data & 0xfe) | ((val & 0x01) << 0));
391 
392 	return m5602_write_sensor(sd, OV7660_COM8, &i2c_data, 1);
393 }
394 
ov7660_get_hflip(struct gspca_dev * gspca_dev,__s32 * val)395 static int ov7660_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
396 {
397 	struct sd *sd = (struct sd *) gspca_dev;
398 	s32 *sensor_settings = sd->sensor_priv;
399 
400 	*val = sensor_settings[HFLIP_IDX];
401 	PDEBUG(D_V4L2, "Read horizontal flip %d", *val);
402 	return 0;
403 }
404 
ov7660_set_hflip(struct gspca_dev * gspca_dev,__s32 val)405 static int ov7660_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
406 {
407 	int err;
408 	u8 i2c_data;
409 	struct sd *sd = (struct sd *) gspca_dev;
410 	s32 *sensor_settings = sd->sensor_priv;
411 
412 	PDEBUG(D_V4L2, "Set horizontal flip to %d", val);
413 
414 	sensor_settings[HFLIP_IDX] = val;
415 
416 	i2c_data = ((val & 0x01) << 5) |
417 		(sensor_settings[VFLIP_IDX] << 4);
418 
419 	err = m5602_write_sensor(sd, OV7660_MVFP, &i2c_data, 1);
420 
421 	return err;
422 }
423 
ov7660_get_vflip(struct gspca_dev * gspca_dev,__s32 * val)424 static int ov7660_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
425 {
426 	struct sd *sd = (struct sd *) gspca_dev;
427 	s32 *sensor_settings = sd->sensor_priv;
428 
429 	*val = sensor_settings[VFLIP_IDX];
430 	PDEBUG(D_V4L2, "Read vertical flip %d", *val);
431 
432 	return 0;
433 }
434 
ov7660_set_vflip(struct gspca_dev * gspca_dev,__s32 val)435 static int ov7660_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
436 {
437 	int err;
438 	u8 i2c_data;
439 	struct sd *sd = (struct sd *) gspca_dev;
440 	s32 *sensor_settings = sd->sensor_priv;
441 
442 	PDEBUG(D_V4L2, "Set vertical flip to %d", val);
443 	sensor_settings[VFLIP_IDX] = val;
444 
445 	i2c_data = ((val & 0x01) << 4) | (sensor_settings[VFLIP_IDX] << 5);
446 	err = m5602_write_sensor(sd, OV7660_MVFP, &i2c_data, 1);
447 	if (err < 0)
448 		return err;
449 
450 	/* When vflip is toggled we need to readjust the bridge hsync/vsync */
451 	if (gspca_dev->streaming)
452 		err = ov7660_start(sd);
453 
454 	return err;
455 }
456 
ov7660_dump_registers(struct sd * sd)457 static void ov7660_dump_registers(struct sd *sd)
458 {
459 	int address;
460 	info("Dumping the ov7660 register state");
461 	for (address = 0; address < 0xa9; address++) {
462 		u8 value;
463 		m5602_read_sensor(sd, address, &value, 1);
464 		info("register 0x%x contains 0x%x",
465 		     address, value);
466 	}
467 
468 	info("ov7660 register state dump complete");
469 
470 	info("Probing for which registers that are read/write");
471 	for (address = 0; address < 0xff; address++) {
472 		u8 old_value, ctrl_value;
473 		u8 test_value[2] = {0xff, 0xff};
474 
475 		m5602_read_sensor(sd, address, &old_value, 1);
476 		m5602_write_sensor(sd, address, test_value, 1);
477 		m5602_read_sensor(sd, address, &ctrl_value, 1);
478 
479 		if (ctrl_value == test_value[0])
480 			info("register 0x%x is writeable", address);
481 		else
482 			info("register 0x%x is read only", address);
483 
484 		/* Restore original value */
485 		m5602_write_sensor(sd, address, &old_value, 1);
486 	}
487 }
488