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