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