Linux-libre 5.3.12-gnu
[librecmc/linux-libre.git] / drivers / media / usb / gspca / m5602 / m5602_ov7660.c
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
19 static int ov7660_s_ctrl(struct v4l2_ctrl *ctrl);
20 static void ov7660_dump_registers(struct sd *sd);
21
22 static 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
56 static 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
175 static 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
189 static const struct v4l2_ctrl_ops ov7660_ctrl_ops = {
190         .s_ctrl = ov7660_s_ctrl,
191 };
192
193 int 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
239 sensor_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
246 int 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
273 int 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
306 int ov7660_start(struct sd *sd)
307 {
308         return 0;
309 }
310
311 int ov7660_stop(struct sd *sd)
312 {
313         return 0;
314 }
315
316 void ov7660_disconnect(struct sd *sd)
317 {
318         ov7660_stop(sd);
319
320         sd->sensor = NULL;
321 }
322
323 static 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
335 static 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
354 static 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
371 static 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
390 static 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
406 static 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
439 static 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 }