• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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