1 // SPDX-License-Identifier: GPL-2.0-only
2
3 /*
4 * Driver for the ov9650 sensor
5 *
6 * Copyright (C) 2008 Erik Andrén
7 * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
8 * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
9 *
10 * Portions of code to USB interface and ALi driver software,
11 * Copyright (c) 2006 Willem Duinker
12 * v4l2 interface modeled after the V4L2 driver
13 * for SN9C10x PC Camera Controllers
14 */
15
16 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
17
18 #include "m5602_ov9650.h"
19
20 static int ov9650_s_ctrl(struct v4l2_ctrl *ctrl);
21 static void ov9650_dump_registers(struct sd *sd);
22
23 static const unsigned char preinit_ov9650[][3] = {
24 /* [INITCAM] */
25 {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02},
26 {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0},
27 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
28 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
29 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
30 {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00},
31
32 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x08},
33 {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
34 {BRIDGE, M5602_XB_GPIO_DAT, 0x04},
35 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
36 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
37 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
38 {BRIDGE, M5602_XB_GPIO_DAT, 0x00},
39 {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a},
40 /* Reset chip */
41 {SENSOR, OV9650_COM7, OV9650_REGISTER_RESET},
42 /* Enable double clock */
43 {SENSOR, OV9650_CLKRC, 0x80},
44 /* Do something out of spec with the power */
45 {SENSOR, OV9650_OFON, 0x40}
46 };
47
48 static const unsigned char init_ov9650[][3] = {
49 /* [INITCAM] */
50 {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02},
51 {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0},
52 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
53 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
54 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
55 {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00},
56
57 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x08},
58 {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
59 {BRIDGE, M5602_XB_GPIO_DAT, 0x04},
60 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
61 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
62 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
63 {BRIDGE, M5602_XB_GPIO_DAT, 0x00},
64 {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a},
65
66 /* Reset chip */
67 {SENSOR, OV9650_COM7, OV9650_REGISTER_RESET},
68 /* One extra reset is needed in order to make the sensor behave
69 properly when resuming from ram, could be a timing issue */
70 {SENSOR, OV9650_COM7, OV9650_REGISTER_RESET},
71
72 /* Enable double clock */
73 {SENSOR, OV9650_CLKRC, 0x80},
74 /* Do something out of spec with the power */
75 {SENSOR, OV9650_OFON, 0x40},
76
77 /* Set fast AGC/AEC algorithm with unlimited step size */
78 {SENSOR, OV9650_COM8, OV9650_FAST_AGC_AEC |
79 OV9650_AEC_UNLIM_STEP_SIZE},
80
81 {SENSOR, OV9650_CHLF, 0x10},
82 {SENSOR, OV9650_ARBLM, 0xbf},
83 {SENSOR, OV9650_ACOM38, 0x81},
84 /* Turn off color matrix coefficient double option */
85 {SENSOR, OV9650_COM16, 0x00},
86 /* Enable color matrix for RGB/YUV, Delay Y channel,
87 set output Y/UV delay to 1 */
88 {SENSOR, OV9650_COM13, 0x19},
89 /* Enable digital BLC, Set output mode to U Y V Y */
90 {SENSOR, OV9650_TSLB, 0x0c},
91 /* Limit the AGC/AEC stable upper region */
92 {SENSOR, OV9650_COM24, 0x00},
93 /* Enable HREF and some out of spec things */
94 {SENSOR, OV9650_COM12, 0x73},
95 /* Set all DBLC offset signs to positive and
96 do some out of spec stuff */
97 {SENSOR, OV9650_DBLC1, 0xdf},
98 {SENSOR, OV9650_COM21, 0x06},
99 {SENSOR, OV9650_RSVD35, 0x91},
100 /* Necessary, no camera stream without it */
101 {SENSOR, OV9650_RSVD16, 0x06},
102 {SENSOR, OV9650_RSVD94, 0x99},
103 {SENSOR, OV9650_RSVD95, 0x99},
104 {SENSOR, OV9650_RSVD96, 0x04},
105 /* Enable full range output */
106 {SENSOR, OV9650_COM15, 0x0},
107 /* Enable HREF at optical black, enable ADBLC bias,
108 enable ADBLC, reset timings at format change */
109 {SENSOR, OV9650_COM6, 0x4b},
110 /* Subtract 32 from the B channel bias */
111 {SENSOR, OV9650_BBIAS, 0xa0},
112 /* Subtract 32 from the Gb channel bias */
113 {SENSOR, OV9650_GbBIAS, 0xa0},
114 /* Do not bypass the analog BLC and to some out of spec stuff */
115 {SENSOR, OV9650_Gr_COM, 0x00},
116 /* Subtract 32 from the R channel bias */
117 {SENSOR, OV9650_RBIAS, 0xa0},
118 /* Subtract 32 from the R channel bias */
119 {SENSOR, OV9650_RBIAS, 0x0},
120 {SENSOR, OV9650_COM26, 0x80},
121 {SENSOR, OV9650_ACOMA9, 0x98},
122 /* Set the AGC/AEC stable region upper limit */
123 {SENSOR, OV9650_AEW, 0x68},
124 /* Set the AGC/AEC stable region lower limit */
125 {SENSOR, OV9650_AEB, 0x5c},
126 /* Set the high and low limit nibbles to 3 */
127 {SENSOR, OV9650_VPT, 0xc3},
128 /* Set the Automatic Gain Ceiling (AGC) to 128x,
129 drop VSYNC at frame drop,
130 limit exposure timing,
131 drop frame when the AEC step is larger than the exposure gap */
132 {SENSOR, OV9650_COM9, 0x6e},
133 /* Set VSYNC negative, Set RESET to SLHS (slave mode horizontal sync)
134 and set PWDN to SLVS (slave mode vertical sync) */
135 {SENSOR, OV9650_COM10, 0x42},
136 /* Set horizontal column start high to default value */
137 {SENSOR, OV9650_HSTART, 0x1a}, /* 210 */
138 /* Set horizontal column end */
139 {SENSOR, OV9650_HSTOP, 0xbf}, /* 1534 */
140 /* Complementing register to the two writes above */
141 {SENSOR, OV9650_HREF, 0xb2},
142 /* Set vertical row start high bits */
143 {SENSOR, OV9650_VSTRT, 0x02},
144 /* Set vertical row end low bits */
145 {SENSOR, OV9650_VSTOP, 0x7e},
146 /* Set complementing vertical frame control */
147 {SENSOR, OV9650_VREF, 0x10},
148 {SENSOR, OV9650_ADC, 0x04},
149 {SENSOR, OV9650_HV, 0x40},
150
151 /* Enable denoise, and white-pixel erase */
152 {SENSOR, OV9650_COM22, OV9650_DENOISE_ENABLE |
153 OV9650_WHITE_PIXEL_ENABLE |
154 OV9650_WHITE_PIXEL_OPTION},
155
156 /* Enable VARIOPIXEL */
157 {SENSOR, OV9650_COM3, OV9650_VARIOPIXEL},
158 {SENSOR, OV9650_COM4, OV9650_QVGA_VARIOPIXEL},
159
160 /* Put the sensor in soft sleep mode */
161 {SENSOR, OV9650_COM2, OV9650_SOFT_SLEEP | OV9650_OUTPUT_DRIVE_2X},
162 };
163
164 static const unsigned char res_init_ov9650[][3] = {
165 {SENSOR, OV9650_COM2, OV9650_OUTPUT_DRIVE_2X},
166
167 {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x82},
168 {BRIDGE, M5602_XB_LINE_OF_FRAME_L, 0x00},
169 {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82},
170 {BRIDGE, M5602_XB_PIX_OF_LINE_L, 0x00},
171 {BRIDGE, M5602_XB_SIG_INI, 0x01}
172 };
173
174 /* Vertically and horizontally flips the image if matched, needed for machines
175 where the sensor is mounted upside down */
176 static
177 const
178 struct dmi_system_id ov9650_flip_dmi_table[] = {
179 {
180 .ident = "ASUS A6Ja",
181 .matches = {
182 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
183 DMI_MATCH(DMI_PRODUCT_NAME, "A6J")
184 }
185 },
186 {
187 .ident = "ASUS A6JC",
188 .matches = {
189 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
190 DMI_MATCH(DMI_PRODUCT_NAME, "A6JC")
191 }
192 },
193 {
194 .ident = "ASUS A6K",
195 .matches = {
196 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
197 DMI_MATCH(DMI_PRODUCT_NAME, "A6K")
198 }
199 },
200 {
201 .ident = "ASUS A6Kt",
202 .matches = {
203 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
204 DMI_MATCH(DMI_PRODUCT_NAME, "A6Kt")
205 }
206 },
207 {
208 .ident = "ASUS A6VA",
209 .matches = {
210 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
211 DMI_MATCH(DMI_PRODUCT_NAME, "A6VA")
212 }
213 },
214 {
215
216 .ident = "ASUS A6VC",
217 .matches = {
218 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
219 DMI_MATCH(DMI_PRODUCT_NAME, "A6VC")
220 }
221 },
222 {
223 .ident = "ASUS A6VM",
224 .matches = {
225 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
226 DMI_MATCH(DMI_PRODUCT_NAME, "A6VM")
227 }
228 },
229 {
230 .ident = "ASUS A7V",
231 .matches = {
232 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
233 DMI_MATCH(DMI_PRODUCT_NAME, "A7V")
234 }
235 },
236 {
237 .ident = "Alienware Aurora m9700",
238 .matches = {
239 DMI_MATCH(DMI_SYS_VENDOR, "alienware"),
240 DMI_MATCH(DMI_PRODUCT_NAME, "Aurora m9700")
241 }
242 },
243 {}
244 };
245
246 static struct v4l2_pix_format ov9650_modes[] = {
247 {
248 176,
249 144,
250 V4L2_PIX_FMT_SBGGR8,
251 V4L2_FIELD_NONE,
252 .sizeimage =
253 176 * 144,
254 .bytesperline = 176,
255 .colorspace = V4L2_COLORSPACE_SRGB,
256 .priv = 9
257 }, {
258 320,
259 240,
260 V4L2_PIX_FMT_SBGGR8,
261 V4L2_FIELD_NONE,
262 .sizeimage =
263 320 * 240,
264 .bytesperline = 320,
265 .colorspace = V4L2_COLORSPACE_SRGB,
266 .priv = 8
267 }, {
268 352,
269 288,
270 V4L2_PIX_FMT_SBGGR8,
271 V4L2_FIELD_NONE,
272 .sizeimage =
273 352 * 288,
274 .bytesperline = 352,
275 .colorspace = V4L2_COLORSPACE_SRGB,
276 .priv = 9
277 }, {
278 640,
279 480,
280 V4L2_PIX_FMT_SBGGR8,
281 V4L2_FIELD_NONE,
282 .sizeimage =
283 640 * 480,
284 .bytesperline = 640,
285 .colorspace = V4L2_COLORSPACE_SRGB,
286 .priv = 9
287 }
288 };
289
290 static const struct v4l2_ctrl_ops ov9650_ctrl_ops = {
291 .s_ctrl = ov9650_s_ctrl,
292 };
293
ov9650_probe(struct sd * sd)294 int ov9650_probe(struct sd *sd)
295 {
296 int err = 0;
297 u8 prod_id = 0, ver_id = 0, i;
298 struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
299
300 if (force_sensor) {
301 if (force_sensor == OV9650_SENSOR) {
302 pr_info("Forcing an %s sensor\n", ov9650.name);
303 goto sensor_found;
304 }
305 /* If we want to force another sensor,
306 don't try to probe this one */
307 return -ENODEV;
308 }
309
310 gspca_dbg(gspca_dev, D_PROBE, "Probing for an ov9650 sensor\n");
311
312 /* Run the pre-init before probing the sensor */
313 for (i = 0; i < ARRAY_SIZE(preinit_ov9650) && !err; i++) {
314 u8 data = preinit_ov9650[i][2];
315 if (preinit_ov9650[i][0] == SENSOR)
316 err = m5602_write_sensor(sd,
317 preinit_ov9650[i][1], &data, 1);
318 else
319 err = m5602_write_bridge(sd,
320 preinit_ov9650[i][1], data);
321 }
322
323 if (err < 0)
324 return err;
325
326 if (m5602_read_sensor(sd, OV9650_PID, &prod_id, 1))
327 return -ENODEV;
328
329 if (m5602_read_sensor(sd, OV9650_VER, &ver_id, 1))
330 return -ENODEV;
331
332 if ((prod_id == 0x96) && (ver_id == 0x52)) {
333 pr_info("Detected an ov9650 sensor\n");
334 goto sensor_found;
335 }
336 return -ENODEV;
337
338 sensor_found:
339 sd->gspca_dev.cam.cam_mode = ov9650_modes;
340 sd->gspca_dev.cam.nmodes = ARRAY_SIZE(ov9650_modes);
341
342 return 0;
343 }
344
ov9650_init(struct sd * sd)345 int ov9650_init(struct sd *sd)
346 {
347 int i, err = 0;
348 u8 data;
349
350 if (dump_sensor)
351 ov9650_dump_registers(sd);
352
353 for (i = 0; i < ARRAY_SIZE(init_ov9650) && !err; i++) {
354 data = init_ov9650[i][2];
355 if (init_ov9650[i][0] == SENSOR)
356 err = m5602_write_sensor(sd, init_ov9650[i][1],
357 &data, 1);
358 else
359 err = m5602_write_bridge(sd, init_ov9650[i][1], data);
360 }
361
362 return 0;
363 }
364
ov9650_init_controls(struct sd * sd)365 int ov9650_init_controls(struct sd *sd)
366 {
367 struct v4l2_ctrl_handler *hdl = &sd->gspca_dev.ctrl_handler;
368
369 sd->gspca_dev.vdev.ctrl_handler = hdl;
370 v4l2_ctrl_handler_init(hdl, 9);
371
372 sd->auto_white_bal = v4l2_ctrl_new_std(hdl, &ov9650_ctrl_ops,
373 V4L2_CID_AUTO_WHITE_BALANCE,
374 0, 1, 1, 1);
375 sd->red_bal = v4l2_ctrl_new_std(hdl, &ov9650_ctrl_ops,
376 V4L2_CID_RED_BALANCE, 0, 255, 1,
377 RED_GAIN_DEFAULT);
378 sd->blue_bal = v4l2_ctrl_new_std(hdl, &ov9650_ctrl_ops,
379 V4L2_CID_BLUE_BALANCE, 0, 255, 1,
380 BLUE_GAIN_DEFAULT);
381
382 sd->autoexpo = v4l2_ctrl_new_std_menu(hdl, &ov9650_ctrl_ops,
383 V4L2_CID_EXPOSURE_AUTO, 1, 0, V4L2_EXPOSURE_AUTO);
384 sd->expo = v4l2_ctrl_new_std(hdl, &ov9650_ctrl_ops, V4L2_CID_EXPOSURE,
385 0, 0x1ff, 4, EXPOSURE_DEFAULT);
386
387 sd->autogain = v4l2_ctrl_new_std(hdl, &ov9650_ctrl_ops,
388 V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
389 sd->gain = v4l2_ctrl_new_std(hdl, &ov9650_ctrl_ops, V4L2_CID_GAIN, 0,
390 0x3ff, 1, GAIN_DEFAULT);
391
392 sd->hflip = v4l2_ctrl_new_std(hdl, &ov9650_ctrl_ops, V4L2_CID_HFLIP,
393 0, 1, 1, 0);
394 sd->vflip = v4l2_ctrl_new_std(hdl, &ov9650_ctrl_ops, V4L2_CID_VFLIP,
395 0, 1, 1, 0);
396
397 if (hdl->error) {
398 pr_err("Could not initialize controls\n");
399 return hdl->error;
400 }
401
402 v4l2_ctrl_auto_cluster(3, &sd->auto_white_bal, 0, false);
403 v4l2_ctrl_auto_cluster(2, &sd->autoexpo, 0, false);
404 v4l2_ctrl_auto_cluster(2, &sd->autogain, 0, false);
405 v4l2_ctrl_cluster(2, &sd->hflip);
406
407 return 0;
408 }
409
ov9650_start(struct sd * sd)410 int ov9650_start(struct sd *sd)
411 {
412 u8 data;
413 int i, err = 0;
414 struct cam *cam = &sd->gspca_dev.cam;
415
416 int width = cam->cam_mode[sd->gspca_dev.curr_mode].width;
417 int height = cam->cam_mode[sd->gspca_dev.curr_mode].height;
418 int ver_offs = cam->cam_mode[sd->gspca_dev.curr_mode].priv;
419 int hor_offs = OV9650_LEFT_OFFSET;
420 struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
421
422 if ((!dmi_check_system(ov9650_flip_dmi_table) &&
423 sd->vflip->val) ||
424 (dmi_check_system(ov9650_flip_dmi_table) &&
425 !sd->vflip->val))
426 ver_offs--;
427
428 if (width <= 320)
429 hor_offs /= 2;
430
431 /* Synthesize the vsync/hsync setup */
432 for (i = 0; i < ARRAY_SIZE(res_init_ov9650) && !err; i++) {
433 if (res_init_ov9650[i][0] == BRIDGE)
434 err = m5602_write_bridge(sd, res_init_ov9650[i][1],
435 res_init_ov9650[i][2]);
436 else if (res_init_ov9650[i][0] == SENSOR) {
437 data = res_init_ov9650[i][2];
438 err = m5602_write_sensor(sd,
439 res_init_ov9650[i][1], &data, 1);
440 }
441 }
442 if (err < 0)
443 return err;
444
445 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA,
446 ((ver_offs >> 8) & 0xff));
447 if (err < 0)
448 return err;
449
450 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (ver_offs & 0xff));
451 if (err < 0)
452 return err;
453
454 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0);
455 if (err < 0)
456 return err;
457
458 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height >> 8) & 0xff);
459 if (err < 0)
460 return err;
461
462 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height & 0xff));
463 if (err < 0)
464 return err;
465
466 for (i = 0; i < 2 && !err; i++)
467 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0);
468 if (err < 0)
469 return err;
470
471 err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0);
472 if (err < 0)
473 return err;
474
475 err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 2);
476 if (err < 0)
477 return err;
478
479 err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA,
480 (hor_offs >> 8) & 0xff);
481 if (err < 0)
482 return err;
483
484 err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, hor_offs & 0xff);
485 if (err < 0)
486 return err;
487
488 err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA,
489 ((width + hor_offs) >> 8) & 0xff);
490 if (err < 0)
491 return err;
492
493 err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA,
494 ((width + hor_offs) & 0xff));
495 if (err < 0)
496 return err;
497
498 err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0);
499 if (err < 0)
500 return err;
501
502 switch (width) {
503 case 640:
504 gspca_dbg(gspca_dev, D_CONF, "Configuring camera for VGA mode\n");
505
506 data = OV9650_VGA_SELECT | OV9650_RGB_SELECT |
507 OV9650_RAW_RGB_SELECT;
508 err = m5602_write_sensor(sd, OV9650_COM7, &data, 1);
509 break;
510
511 case 352:
512 gspca_dbg(gspca_dev, D_CONF, "Configuring camera for CIF mode\n");
513
514 data = OV9650_CIF_SELECT | OV9650_RGB_SELECT |
515 OV9650_RAW_RGB_SELECT;
516 err = m5602_write_sensor(sd, OV9650_COM7, &data, 1);
517 break;
518
519 case 320:
520 gspca_dbg(gspca_dev, D_CONF, "Configuring camera for QVGA mode\n");
521
522 data = OV9650_QVGA_SELECT | OV9650_RGB_SELECT |
523 OV9650_RAW_RGB_SELECT;
524 err = m5602_write_sensor(sd, OV9650_COM7, &data, 1);
525 break;
526
527 case 176:
528 gspca_dbg(gspca_dev, D_CONF, "Configuring camera for QCIF mode\n");
529
530 data = OV9650_QCIF_SELECT | OV9650_RGB_SELECT |
531 OV9650_RAW_RGB_SELECT;
532 err = m5602_write_sensor(sd, OV9650_COM7, &data, 1);
533 break;
534 }
535 return err;
536 }
537
ov9650_stop(struct sd * sd)538 int ov9650_stop(struct sd *sd)
539 {
540 u8 data = OV9650_SOFT_SLEEP | OV9650_OUTPUT_DRIVE_2X;
541 return m5602_write_sensor(sd, OV9650_COM2, &data, 1);
542 }
543
ov9650_disconnect(struct sd * sd)544 void ov9650_disconnect(struct sd *sd)
545 {
546 ov9650_stop(sd);
547
548 sd->sensor = NULL;
549 }
550
ov9650_set_exposure(struct gspca_dev * gspca_dev,__s32 val)551 static int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
552 {
553 struct sd *sd = (struct sd *) gspca_dev;
554 u8 i2c_data;
555 int err;
556
557 gspca_dbg(gspca_dev, D_CONF, "Set exposure to %d\n", val);
558
559 /* The 6 MSBs */
560 i2c_data = (val >> 10) & 0x3f;
561 err = m5602_write_sensor(sd, OV9650_AECHM,
562 &i2c_data, 1);
563 if (err < 0)
564 return err;
565
566 /* The 8 middle bits */
567 i2c_data = (val >> 2) & 0xff;
568 err = m5602_write_sensor(sd, OV9650_AECH,
569 &i2c_data, 1);
570 if (err < 0)
571 return err;
572
573 /* The 2 LSBs */
574 i2c_data = val & 0x03;
575 err = m5602_write_sensor(sd, OV9650_COM1, &i2c_data, 1);
576 return err;
577 }
578
ov9650_set_gain(struct gspca_dev * gspca_dev,__s32 val)579 static int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val)
580 {
581 int err;
582 u8 i2c_data;
583 struct sd *sd = (struct sd *) gspca_dev;
584
585 gspca_dbg(gspca_dev, D_CONF, "Setting gain to %d\n", val);
586
587 /* The 2 MSB */
588 /* Read the OV9650_VREF register first to avoid
589 corrupting the VREF high and low bits */
590 err = m5602_read_sensor(sd, OV9650_VREF, &i2c_data, 1);
591 if (err < 0)
592 return err;
593
594 /* Mask away all uninteresting bits */
595 i2c_data = ((val & 0x0300) >> 2) |
596 (i2c_data & 0x3f);
597 err = m5602_write_sensor(sd, OV9650_VREF, &i2c_data, 1);
598 if (err < 0)
599 return err;
600
601 /* The 8 LSBs */
602 i2c_data = val & 0xff;
603 err = m5602_write_sensor(sd, OV9650_GAIN, &i2c_data, 1);
604 return err;
605 }
606
ov9650_set_red_balance(struct gspca_dev * gspca_dev,__s32 val)607 static int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
608 {
609 int err;
610 u8 i2c_data;
611 struct sd *sd = (struct sd *) gspca_dev;
612
613 gspca_dbg(gspca_dev, D_CONF, "Set red gain to %d\n", val);
614
615 i2c_data = val & 0xff;
616 err = m5602_write_sensor(sd, OV9650_RED, &i2c_data, 1);
617 return err;
618 }
619
ov9650_set_blue_balance(struct gspca_dev * gspca_dev,__s32 val)620 static int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
621 {
622 int err;
623 u8 i2c_data;
624 struct sd *sd = (struct sd *) gspca_dev;
625
626 gspca_dbg(gspca_dev, D_CONF, "Set blue gain to %d\n", val);
627
628 i2c_data = val & 0xff;
629 err = m5602_write_sensor(sd, OV9650_BLUE, &i2c_data, 1);
630 return err;
631 }
632
ov9650_set_hvflip(struct gspca_dev * gspca_dev)633 static int ov9650_set_hvflip(struct gspca_dev *gspca_dev)
634 {
635 int err;
636 u8 i2c_data;
637 struct sd *sd = (struct sd *) gspca_dev;
638 int hflip = sd->hflip->val;
639 int vflip = sd->vflip->val;
640
641 gspca_dbg(gspca_dev, D_CONF, "Set hvflip to %d %d\n", hflip, vflip);
642
643 if (dmi_check_system(ov9650_flip_dmi_table))
644 vflip = !vflip;
645
646 i2c_data = (hflip << 5) | (vflip << 4);
647 err = m5602_write_sensor(sd, OV9650_MVFP, &i2c_data, 1);
648 if (err < 0)
649 return err;
650
651 /* When vflip is toggled we need to readjust the bridge hsync/vsync */
652 if (gspca_dev->streaming)
653 err = ov9650_start(sd);
654
655 return err;
656 }
657
ov9650_set_auto_exposure(struct gspca_dev * gspca_dev,__s32 val)658 static int ov9650_set_auto_exposure(struct gspca_dev *gspca_dev,
659 __s32 val)
660 {
661 int err;
662 u8 i2c_data;
663 struct sd *sd = (struct sd *) gspca_dev;
664
665 gspca_dbg(gspca_dev, D_CONF, "Set auto exposure control to %d\n", val);
666
667 err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1);
668 if (err < 0)
669 return err;
670
671 val = (val == V4L2_EXPOSURE_AUTO);
672 i2c_data = ((i2c_data & 0xfe) | ((val & 0x01) << 0));
673
674 return m5602_write_sensor(sd, OV9650_COM8, &i2c_data, 1);
675 }
676
ov9650_set_auto_white_balance(struct gspca_dev * gspca_dev,__s32 val)677 static int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev,
678 __s32 val)
679 {
680 int err;
681 u8 i2c_data;
682 struct sd *sd = (struct sd *) gspca_dev;
683
684 gspca_dbg(gspca_dev, D_CONF, "Set auto white balance to %d\n", val);
685
686 err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1);
687 if (err < 0)
688 return err;
689
690 i2c_data = ((i2c_data & 0xfd) | ((val & 0x01) << 1));
691 err = m5602_write_sensor(sd, OV9650_COM8, &i2c_data, 1);
692
693 return err;
694 }
695
ov9650_set_auto_gain(struct gspca_dev * gspca_dev,__s32 val)696 static int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val)
697 {
698 int err;
699 u8 i2c_data;
700 struct sd *sd = (struct sd *) gspca_dev;
701
702 gspca_dbg(gspca_dev, D_CONF, "Set auto gain control to %d\n", val);
703
704 err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1);
705 if (err < 0)
706 return err;
707
708 i2c_data = ((i2c_data & 0xfb) | ((val & 0x01) << 2));
709
710 return m5602_write_sensor(sd, OV9650_COM8, &i2c_data, 1);
711 }
712
ov9650_s_ctrl(struct v4l2_ctrl * ctrl)713 static int ov9650_s_ctrl(struct v4l2_ctrl *ctrl)
714 {
715 struct gspca_dev *gspca_dev =
716 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
717 struct sd *sd = (struct sd *) gspca_dev;
718 int err;
719
720 if (!gspca_dev->streaming)
721 return 0;
722
723 switch (ctrl->id) {
724 case V4L2_CID_AUTO_WHITE_BALANCE:
725 err = ov9650_set_auto_white_balance(gspca_dev, ctrl->val);
726 if (err || ctrl->val)
727 return err;
728 err = ov9650_set_red_balance(gspca_dev, sd->red_bal->val);
729 if (err)
730 return err;
731 err = ov9650_set_blue_balance(gspca_dev, sd->blue_bal->val);
732 break;
733 case V4L2_CID_EXPOSURE_AUTO:
734 err = ov9650_set_auto_exposure(gspca_dev, ctrl->val);
735 if (err || ctrl->val == V4L2_EXPOSURE_AUTO)
736 return err;
737 err = ov9650_set_exposure(gspca_dev, sd->expo->val);
738 break;
739 case V4L2_CID_AUTOGAIN:
740 err = ov9650_set_auto_gain(gspca_dev, ctrl->val);
741 if (err || ctrl->val)
742 return err;
743 err = ov9650_set_gain(gspca_dev, sd->gain->val);
744 break;
745 case V4L2_CID_HFLIP:
746 err = ov9650_set_hvflip(gspca_dev);
747 break;
748 default:
749 return -EINVAL;
750 }
751
752 return err;
753 }
754
ov9650_dump_registers(struct sd * sd)755 static void ov9650_dump_registers(struct sd *sd)
756 {
757 int address;
758 pr_info("Dumping the ov9650 register state\n");
759 for (address = 0; address < 0xa9; address++) {
760 u8 value;
761 m5602_read_sensor(sd, address, &value, 1);
762 pr_info("register 0x%x contains 0x%x\n", address, value);
763 }
764
765 pr_info("ov9650 register state dump complete\n");
766
767 pr_info("Probing for which registers that are read/write\n");
768 for (address = 0; address < 0xff; address++) {
769 u8 old_value, ctrl_value;
770 u8 test_value[2] = {0xff, 0xff};
771
772 m5602_read_sensor(sd, address, &old_value, 1);
773 m5602_write_sensor(sd, address, test_value, 1);
774 m5602_read_sensor(sd, address, &ctrl_value, 1);
775
776 if (ctrl_value == test_value[0])
777 pr_info("register 0x%x is writeable\n", address);
778 else
779 pr_info("register 0x%x is read only\n", address);
780
781 /* Restore original value */
782 m5602_write_sensor(sd, address, &old_value, 1);
783 }
784 }
785