1 /*
2  * Driver for the po1030 sensor
3  *
4  * Copyright (c) 2008 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_po1030.h"
22 
23 static int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
24 static int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
25 static int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
26 static int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val);
27 static int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val);
28 static int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val);
29 static int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val);
30 static int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val);
31 static int po1030_get_green_balance(struct gspca_dev *gspca_dev, __s32 *val);
32 static int po1030_set_green_balance(struct gspca_dev *gspca_dev, __s32 val);
33 static int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
34 static int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
35 static int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
36 static int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
37 static int po1030_set_auto_white_balance(struct gspca_dev *gspca_dev,
38 					 __s32 val);
39 static int po1030_get_auto_white_balance(struct gspca_dev *gspca_dev,
40 					 __s32 *val);
41 static int po1030_set_auto_exposure(struct gspca_dev *gspca_dev,
42 					 __s32 val);
43 static int po1030_get_auto_exposure(struct gspca_dev *gspca_dev,
44 					 __s32 *val);
45 
46 static struct v4l2_pix_format po1030_modes[] = {
47 	{
48 		640,
49 		480,
50 		V4L2_PIX_FMT_SBGGR8,
51 		V4L2_FIELD_NONE,
52 		.sizeimage = 640 * 480,
53 		.bytesperline = 640,
54 		.colorspace = V4L2_COLORSPACE_SRGB,
55 		.priv = 2
56 	}
57 };
58 
59 static const struct ctrl po1030_ctrls[] = {
60 #define GAIN_IDX 0
61 	{
62 		{
63 			.id		= V4L2_CID_GAIN,
64 			.type		= V4L2_CTRL_TYPE_INTEGER,
65 			.name		= "gain",
66 			.minimum	= 0x00,
67 			.maximum	= 0x4f,
68 			.step		= 0x1,
69 			.default_value	= PO1030_GLOBAL_GAIN_DEFAULT,
70 			.flags		= V4L2_CTRL_FLAG_SLIDER
71 		},
72 		.set = po1030_set_gain,
73 		.get = po1030_get_gain
74 	},
75 #define EXPOSURE_IDX 1
76 	{
77 		{
78 			.id		= V4L2_CID_EXPOSURE,
79 			.type		= V4L2_CTRL_TYPE_INTEGER,
80 			.name		= "exposure",
81 			.minimum	= 0x00,
82 			.maximum	= 0x02ff,
83 			.step		= 0x1,
84 			.default_value	= PO1030_EXPOSURE_DEFAULT,
85 			.flags		= V4L2_CTRL_FLAG_SLIDER
86 		},
87 		.set = po1030_set_exposure,
88 		.get = po1030_get_exposure
89 	},
90 #define RED_BALANCE_IDX 2
91 	{
92 		{
93 			.id		= V4L2_CID_RED_BALANCE,
94 			.type		= V4L2_CTRL_TYPE_INTEGER,
95 			.name		= "red balance",
96 			.minimum	= 0x00,
97 			.maximum	= 0xff,
98 			.step		= 0x1,
99 			.default_value	= PO1030_RED_GAIN_DEFAULT,
100 			.flags		= V4L2_CTRL_FLAG_SLIDER
101 		},
102 		.set = po1030_set_red_balance,
103 		.get = po1030_get_red_balance
104 	},
105 #define BLUE_BALANCE_IDX 3
106 	{
107 		{
108 			.id		= V4L2_CID_BLUE_BALANCE,
109 			.type		= V4L2_CTRL_TYPE_INTEGER,
110 			.name		= "blue balance",
111 			.minimum	= 0x00,
112 			.maximum	= 0xff,
113 			.step		= 0x1,
114 			.default_value	= PO1030_BLUE_GAIN_DEFAULT,
115 			.flags		= V4L2_CTRL_FLAG_SLIDER
116 		},
117 		.set = po1030_set_blue_balance,
118 		.get = po1030_get_blue_balance
119 	},
120 #define HFLIP_IDX 4
121 	{
122 		{
123 			.id		= V4L2_CID_HFLIP,
124 			.type		= V4L2_CTRL_TYPE_BOOLEAN,
125 			.name		= "horizontal flip",
126 			.minimum	= 0,
127 			.maximum	= 1,
128 			.step		= 1,
129 			.default_value	= 0,
130 		},
131 		.set = po1030_set_hflip,
132 		.get = po1030_get_hflip
133 	},
134 #define VFLIP_IDX 5
135 	{
136 		{
137 			.id		= V4L2_CID_VFLIP,
138 			.type		= V4L2_CTRL_TYPE_BOOLEAN,
139 			.name		= "vertical flip",
140 			.minimum	= 0,
141 			.maximum	= 1,
142 			.step		= 1,
143 			.default_value	= 0,
144 		},
145 		.set = po1030_set_vflip,
146 		.get = po1030_get_vflip
147 	},
148 #define AUTO_WHITE_BALANCE_IDX 6
149 	{
150 		{
151 			.id		= V4L2_CID_AUTO_WHITE_BALANCE,
152 			.type		= V4L2_CTRL_TYPE_BOOLEAN,
153 			.name		= "auto white balance",
154 			.minimum	= 0,
155 			.maximum	= 1,
156 			.step		= 1,
157 			.default_value	= 0,
158 		},
159 		.set = po1030_set_auto_white_balance,
160 		.get = po1030_get_auto_white_balance
161 	},
162 #define AUTO_EXPOSURE_IDX 7
163 	{
164 		{
165 			.id		= V4L2_CID_EXPOSURE_AUTO,
166 			.type		= V4L2_CTRL_TYPE_BOOLEAN,
167 			.name		= "auto exposure",
168 			.minimum	= 0,
169 			.maximum	= 1,
170 			.step		= 1,
171 			.default_value	= 0,
172 		},
173 		.set = po1030_set_auto_exposure,
174 		.get = po1030_get_auto_exposure
175 	},
176 #define GREEN_BALANCE_IDX 8
177 	{
178 		{
179 			.id		= M5602_V4L2_CID_GREEN_BALANCE,
180 			.type		= V4L2_CTRL_TYPE_INTEGER,
181 			.name		= "green balance",
182 			.minimum	= 0x00,
183 			.maximum	= 0xff,
184 			.step		= 0x1,
185 			.default_value	= PO1030_GREEN_GAIN_DEFAULT,
186 			.flags		= V4L2_CTRL_FLAG_SLIDER
187 		},
188 		.set = po1030_set_green_balance,
189 		.get = po1030_get_green_balance
190 	},
191 };
192 
193 static void po1030_dump_registers(struct sd *sd);
194 
195 int po1030_probe(struct sd *sd)
196 {
197 	u8 dev_id_h = 0, i;
198 	s32 *sensor_settings;
199 
200 	if (force_sensor) {
201 		if (force_sensor == PO1030_SENSOR) {
202 			pr_info("Forcing a %s sensor\n", po1030.name);
203 			goto sensor_found;
204 		}
205 		/* If we want to force another sensor, don't try to probe this
206 		 * one */
207 		return -ENODEV;
208 	}
209 
210 	PDEBUG(D_PROBE, "Probing for a po1030 sensor");
211 
212 	/* Run the pre-init to actually probe the unit */
213 	for (i = 0; i < ARRAY_SIZE(preinit_po1030); i++) {
214 		u8 data = preinit_po1030[i][2];
215 		if (preinit_po1030[i][0] == SENSOR)
216 			m5602_write_sensor(sd,
217 				preinit_po1030[i][1], &data, 1);
218 		else
219 			m5602_write_bridge(sd, preinit_po1030[i][1], data);
220 	}
221 
222 	if (m5602_read_sensor(sd, PO1030_DEVID_H, &dev_id_h, 1))
223 		return -ENODEV;
224 
225 	if (dev_id_h == 0x30) {
226 		pr_info("Detected a po1030 sensor\n");
227 		goto sensor_found;
228 	}
229 	return -ENODEV;
230 
231 sensor_found:
232 	sensor_settings = kmalloc(
233 		ARRAY_SIZE(po1030_ctrls) * sizeof(s32), GFP_KERNEL);
234 	if (!sensor_settings)
235 		return -ENOMEM;
236 
237 	sd->gspca_dev.cam.cam_mode = po1030_modes;
238 	sd->gspca_dev.cam.nmodes = ARRAY_SIZE(po1030_modes);
239 	sd->desc->ctrls = po1030_ctrls;
240 	sd->desc->nctrls = ARRAY_SIZE(po1030_ctrls);
241 
242 	for (i = 0; i < ARRAY_SIZE(po1030_ctrls); i++)
243 		sensor_settings[i] = po1030_ctrls[i].qctrl.default_value;
244 	sd->sensor_priv = sensor_settings;
245 
246 	return 0;
247 }
248 
249 int po1030_init(struct sd *sd)
250 {
251 	s32 *sensor_settings = sd->sensor_priv;
252 	int i, err = 0;
253 
254 	/* Init the sensor */
255 	for (i = 0; i < ARRAY_SIZE(init_po1030) && !err; i++) {
256 		u8 data[2] = {0x00, 0x00};
257 
258 		switch (init_po1030[i][0]) {
259 		case BRIDGE:
260 			err = m5602_write_bridge(sd,
261 				init_po1030[i][1],
262 				init_po1030[i][2]);
263 			break;
264 
265 		case SENSOR:
266 			data[0] = init_po1030[i][2];
267 			err = m5602_write_sensor(sd,
268 				init_po1030[i][1], data, 1);
269 			break;
270 
271 		default:
272 			pr_info("Invalid stream command, exiting init\n");
273 			return -EINVAL;
274 		}
275 	}
276 	if (err < 0)
277 		return err;
278 
279 	if (dump_sensor)
280 		po1030_dump_registers(sd);
281 
282 	err = po1030_set_exposure(&sd->gspca_dev,
283 				   sensor_settings[EXPOSURE_IDX]);
284 	if (err < 0)
285 		return err;
286 
287 	err = po1030_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]);
288 	if (err < 0)
289 		return err;
290 
291 	err = po1030_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]);
292 	if (err < 0)
293 		return err;
294 
295 	err = po1030_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]);
296 	if (err < 0)
297 		return err;
298 
299 	err = po1030_set_red_balance(&sd->gspca_dev,
300 				      sensor_settings[RED_BALANCE_IDX]);
301 	if (err < 0)
302 		return err;
303 
304 	err = po1030_set_blue_balance(&sd->gspca_dev,
305 				      sensor_settings[BLUE_BALANCE_IDX]);
306 	if (err < 0)
307 		return err;
308 
309 	err = po1030_set_green_balance(&sd->gspca_dev,
310 				       sensor_settings[GREEN_BALANCE_IDX]);
311 	if (err < 0)
312 		return err;
313 
314 	err = po1030_set_auto_white_balance(&sd->gspca_dev,
315 				sensor_settings[AUTO_WHITE_BALANCE_IDX]);
316 	if (err < 0)
317 		return err;
318 
319 	err = po1030_set_auto_exposure(&sd->gspca_dev,
320 				sensor_settings[AUTO_EXPOSURE_IDX]);
321 	return err;
322 }
323 
324 int po1030_start(struct sd *sd)
325 {
326 	struct cam *cam = &sd->gspca_dev.cam;
327 	int i, err = 0;
328 	int width = cam->cam_mode[sd->gspca_dev.curr_mode].width;
329 	int height = cam->cam_mode[sd->gspca_dev.curr_mode].height;
330 	int ver_offs = cam->cam_mode[sd->gspca_dev.curr_mode].priv;
331 	u8 data;
332 
333 	switch (width) {
334 	case 320:
335 		data = PO1030_SUBSAMPLING;
336 		err = m5602_write_sensor(sd, PO1030_CONTROL3, &data, 1);
337 		if (err < 0)
338 			return err;
339 
340 		data = ((width + 3) >> 8) & 0xff;
341 		err = m5602_write_sensor(sd, PO1030_WINDOWWIDTH_H, &data, 1);
342 		if (err < 0)
343 			return err;
344 
345 		data = (width + 3) & 0xff;
346 		err = m5602_write_sensor(sd, PO1030_WINDOWWIDTH_L, &data, 1);
347 		if (err < 0)
348 			return err;
349 
350 		data = ((height + 1) >> 8) & 0xff;
351 		err = m5602_write_sensor(sd, PO1030_WINDOWHEIGHT_H, &data, 1);
352 		if (err < 0)
353 			return err;
354 
355 		data = (height + 1) & 0xff;
356 		err = m5602_write_sensor(sd, PO1030_WINDOWHEIGHT_L, &data, 1);
357 
358 		height += 6;
359 		width -= 1;
360 		break;
361 
362 	case 640:
363 		data = 0;
364 		err = m5602_write_sensor(sd, PO1030_CONTROL3, &data, 1);
365 		if (err < 0)
366 			return err;
367 
368 		data = ((width + 7) >> 8) & 0xff;
369 		err = m5602_write_sensor(sd, PO1030_WINDOWWIDTH_H, &data, 1);
370 		if (err < 0)
371 			return err;
372 
373 		data = (width + 7) & 0xff;
374 		err = m5602_write_sensor(sd, PO1030_WINDOWWIDTH_L, &data, 1);
375 		if (err < 0)
376 			return err;
377 
378 		data = ((height + 3) >> 8) & 0xff;
379 		err = m5602_write_sensor(sd, PO1030_WINDOWHEIGHT_H, &data, 1);
380 		if (err < 0)
381 			return err;
382 
383 		data = (height + 3) & 0xff;
384 		err = m5602_write_sensor(sd, PO1030_WINDOWHEIGHT_L, &data, 1);
385 
386 		height += 12;
387 		width -= 2;
388 		break;
389 	}
390 	err = m5602_write_bridge(sd, M5602_XB_SENSOR_TYPE, 0x0c);
391 	if (err < 0)
392 		return err;
393 
394 	err = m5602_write_bridge(sd, M5602_XB_LINE_OF_FRAME_H, 0x81);
395 	if (err < 0)
396 		return err;
397 
398 	err = m5602_write_bridge(sd, M5602_XB_PIX_OF_LINE_H, 0x82);
399 	if (err < 0)
400 		return err;
401 
402 	err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0x01);
403 	if (err < 0)
404 		return err;
405 
406 	err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA,
407 				 ((ver_offs >> 8) & 0xff));
408 	if (err < 0)
409 		return err;
410 
411 	err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (ver_offs & 0xff));
412 	if (err < 0)
413 		return err;
414 
415 	for (i = 0; i < 2 && !err; i++)
416 		err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0);
417 	if (err < 0)
418 		return err;
419 
420 	err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height >> 8) & 0xff);
421 	if (err < 0)
422 		return err;
423 
424 	err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height & 0xff));
425 	if (err < 0)
426 		return err;
427 
428 	for (i = 0; i < 2 && !err; i++)
429 		err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0);
430 
431 	for (i = 0; i < 2 && !err; i++)
432 		err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0);
433 
434 	for (i = 0; i < 2 && !err; i++)
435 		err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, 0);
436 	if (err < 0)
437 		return err;
438 
439 	err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, (width >> 8) & 0xff);
440 	if (err < 0)
441 		return err;
442 
443 	err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, (width & 0xff));
444 	if (err < 0)
445 		return err;
446 
447 	err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0);
448 	return err;
449 }
450 
451 static int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
452 {
453 	struct sd *sd = (struct sd *) gspca_dev;
454 	s32 *sensor_settings = sd->sensor_priv;
455 
456 	*val = sensor_settings[EXPOSURE_IDX];
457 	PDEBUG(D_V4L2, "Exposure read as %d", *val);
458 	return 0;
459 }
460 
461 static int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
462 {
463 	struct sd *sd = (struct sd *) gspca_dev;
464 	s32 *sensor_settings = sd->sensor_priv;
465 	u8 i2c_data;
466 	int err;
467 
468 	sensor_settings[EXPOSURE_IDX] = val;
469 	PDEBUG(D_V4L2, "Set exposure to %d", val & 0xffff);
470 
471 	i2c_data = ((val & 0xff00) >> 8);
472 	PDEBUG(D_V4L2, "Set exposure to high byte to 0x%x",
473 	       i2c_data);
474 
475 	err = m5602_write_sensor(sd, PO1030_INTEGLINES_H,
476 				  &i2c_data, 1);
477 	if (err < 0)
478 		return err;
479 
480 	i2c_data = (val & 0xff);
481 	PDEBUG(D_V4L2, "Set exposure to low byte to 0x%x",
482 	       i2c_data);
483 	err = m5602_write_sensor(sd, PO1030_INTEGLINES_M,
484 				  &i2c_data, 1);
485 
486 	return err;
487 }
488 
489 static int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
490 {
491 	struct sd *sd = (struct sd *) gspca_dev;
492 	s32 *sensor_settings = sd->sensor_priv;
493 
494 	*val = sensor_settings[GAIN_IDX];
495 	PDEBUG(D_V4L2, "Read global gain %d", *val);
496 	return 0;
497 }
498 
499 static int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val)
500 {
501 	struct sd *sd = (struct sd *) gspca_dev;
502 	s32 *sensor_settings = sd->sensor_priv;
503 	u8 i2c_data;
504 	int err;
505 
506 	sensor_settings[GAIN_IDX] = val;
507 
508 	i2c_data = val & 0xff;
509 	PDEBUG(D_V4L2, "Set global gain to %d", i2c_data);
510 	err = m5602_write_sensor(sd, PO1030_GLOBALGAIN,
511 				 &i2c_data, 1);
512 	return err;
513 }
514 
515 static int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
516 {
517 	struct sd *sd = (struct sd *) gspca_dev;
518 	s32 *sensor_settings = sd->sensor_priv;
519 
520 	*val = sensor_settings[HFLIP_IDX];
521 	PDEBUG(D_V4L2, "Read hflip %d", *val);
522 
523 	return 0;
524 }
525 
526 static int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
527 {
528 	struct sd *sd = (struct sd *) gspca_dev;
529 	s32 *sensor_settings = sd->sensor_priv;
530 	u8 i2c_data;
531 	int err;
532 
533 	sensor_settings[HFLIP_IDX] = val;
534 
535 	PDEBUG(D_V4L2, "Set hflip %d", val);
536 	err = m5602_read_sensor(sd, PO1030_CONTROL2, &i2c_data, 1);
537 	if (err < 0)
538 		return err;
539 
540 	i2c_data = (0x7f & i2c_data) | ((val & 0x01) << 7);
541 
542 	err = m5602_write_sensor(sd, PO1030_CONTROL2,
543 				 &i2c_data, 1);
544 
545 	return err;
546 }
547 
548 static int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
549 {
550 	struct sd *sd = (struct sd *) gspca_dev;
551 	s32 *sensor_settings = sd->sensor_priv;
552 
553 	*val = sensor_settings[VFLIP_IDX];
554 	PDEBUG(D_V4L2, "Read vflip %d", *val);
555 
556 	return 0;
557 }
558 
559 static int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
560 {
561 	struct sd *sd = (struct sd *) gspca_dev;
562 	s32 *sensor_settings = sd->sensor_priv;
563 	u8 i2c_data;
564 	int err;
565 
566 	sensor_settings[VFLIP_IDX] = val;
567 
568 	PDEBUG(D_V4L2, "Set vflip %d", val);
569 	err = m5602_read_sensor(sd, PO1030_CONTROL2, &i2c_data, 1);
570 	if (err < 0)
571 		return err;
572 
573 	i2c_data = (i2c_data & 0xbf) | ((val & 0x01) << 6);
574 
575 	err = m5602_write_sensor(sd, PO1030_CONTROL2,
576 				 &i2c_data, 1);
577 
578 	return err;
579 }
580 
581 static int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
582 {
583 	struct sd *sd = (struct sd *) gspca_dev;
584 	s32 *sensor_settings = sd->sensor_priv;
585 
586 	*val = sensor_settings[RED_BALANCE_IDX];
587 	PDEBUG(D_V4L2, "Read red gain %d", *val);
588 	return 0;
589 }
590 
591 static int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
592 {
593 	struct sd *sd = (struct sd *) gspca_dev;
594 	s32 *sensor_settings = sd->sensor_priv;
595 	u8 i2c_data;
596 	int err;
597 
598 	sensor_settings[RED_BALANCE_IDX] = val;
599 
600 	i2c_data = val & 0xff;
601 	PDEBUG(D_V4L2, "Set red gain to %d", i2c_data);
602 	err = m5602_write_sensor(sd, PO1030_RED_GAIN,
603 				  &i2c_data, 1);
604 	return err;
605 }
606 
607 static int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
608 {
609 	struct sd *sd = (struct sd *) gspca_dev;
610 	s32 *sensor_settings = sd->sensor_priv;
611 
612 	*val = sensor_settings[BLUE_BALANCE_IDX];
613 	PDEBUG(D_V4L2, "Read blue gain %d", *val);
614 
615 	return 0;
616 }
617 
618 static int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
619 {
620 	struct sd *sd = (struct sd *) gspca_dev;
621 	s32 *sensor_settings = sd->sensor_priv;
622 	u8 i2c_data;
623 	int err;
624 
625 	sensor_settings[BLUE_BALANCE_IDX] = val;
626 
627 	i2c_data = val & 0xff;
628 	PDEBUG(D_V4L2, "Set blue gain to %d", i2c_data);
629 	err = m5602_write_sensor(sd, PO1030_BLUE_GAIN,
630 				  &i2c_data, 1);
631 
632 	return err;
633 }
634 
635 static int po1030_get_green_balance(struct gspca_dev *gspca_dev, __s32 *val)
636 {
637 	struct sd *sd = (struct sd *) gspca_dev;
638 	s32 *sensor_settings = sd->sensor_priv;
639 
640 	*val = sensor_settings[GREEN_BALANCE_IDX];
641 	PDEBUG(D_V4L2, "Read green gain %d", *val);
642 
643 	return 0;
644 }
645 
646 static int po1030_set_green_balance(struct gspca_dev *gspca_dev, __s32 val)
647 {
648 	struct sd *sd = (struct sd *) gspca_dev;
649 	s32 *sensor_settings = sd->sensor_priv;
650 	u8 i2c_data;
651 	int err;
652 
653 	sensor_settings[GREEN_BALANCE_IDX] = val;
654 	i2c_data = val & 0xff;
655 	PDEBUG(D_V4L2, "Set green gain to %d", i2c_data);
656 
657 	err = m5602_write_sensor(sd, PO1030_GREEN_1_GAIN,
658 			   &i2c_data, 1);
659 	if (err < 0)
660 		return err;
661 
662 	return m5602_write_sensor(sd, PO1030_GREEN_2_GAIN,
663 				 &i2c_data, 1);
664 }
665 
666 static int po1030_get_auto_white_balance(struct gspca_dev *gspca_dev,
667 					 __s32 *val)
668 {
669 	struct sd *sd = (struct sd *) gspca_dev;
670 	s32 *sensor_settings = sd->sensor_priv;
671 
672 	*val = sensor_settings[AUTO_WHITE_BALANCE_IDX];
673 	PDEBUG(D_V4L2, "Auto white balancing is %d", *val);
674 
675 	return 0;
676 }
677 
678 static int po1030_set_auto_white_balance(struct gspca_dev *gspca_dev,
679 					 __s32 val)
680 {
681 	struct sd *sd = (struct sd *) gspca_dev;
682 	s32 *sensor_settings = sd->sensor_priv;
683 	u8 i2c_data;
684 	int err;
685 
686 	sensor_settings[AUTO_WHITE_BALANCE_IDX] = val;
687 
688 	err = m5602_read_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1);
689 	if (err < 0)
690 		return err;
691 
692 	PDEBUG(D_V4L2, "Set auto white balance to %d", val);
693 	i2c_data = (i2c_data & 0xfe) | (val & 0x01);
694 	err = m5602_write_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1);
695 	return err;
696 }
697 
698 static int po1030_get_auto_exposure(struct gspca_dev *gspca_dev,
699 				    __s32 *val)
700 {
701 	struct sd *sd = (struct sd *) gspca_dev;
702 	s32 *sensor_settings = sd->sensor_priv;
703 
704 	*val = sensor_settings[AUTO_EXPOSURE_IDX];
705 	PDEBUG(D_V4L2, "Auto exposure is %d", *val);
706 	return 0;
707 }
708 
709 static int po1030_set_auto_exposure(struct gspca_dev *gspca_dev,
710 				    __s32 val)
711 {
712 	struct sd *sd = (struct sd *) gspca_dev;
713 	s32 *sensor_settings = sd->sensor_priv;
714 	u8 i2c_data;
715 	int err;
716 
717 	sensor_settings[AUTO_EXPOSURE_IDX] = val;
718 	err = m5602_read_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1);
719 	if (err < 0)
720 		return err;
721 
722 	PDEBUG(D_V4L2, "Set auto exposure to %d", val);
723 	i2c_data = (i2c_data & 0xfd) | ((val & 0x01) << 1);
724 	return m5602_write_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1);
725 }
726 
727 void po1030_disconnect(struct sd *sd)
728 {
729 	sd->sensor = NULL;
730 	kfree(sd->sensor_priv);
731 }
732 
733 static void po1030_dump_registers(struct sd *sd)
734 {
735 	int address;
736 	u8 value = 0;
737 
738 	pr_info("Dumping the po1030 sensor core registers\n");
739 	for (address = 0; address < 0x7f; address++) {
740 		m5602_read_sensor(sd, address, &value, 1);
741 		pr_info("register 0x%x contains 0x%x\n", address, value);
742 	}
743 
744 	pr_info("po1030 register state dump complete\n");
745 
746 	pr_info("Probing for which registers that are read/write\n");
747 	for (address = 0; address < 0xff; address++) {
748 		u8 old_value, ctrl_value;
749 		u8 test_value[2] = {0xff, 0xff};
750 
751 		m5602_read_sensor(sd, address, &old_value, 1);
752 		m5602_write_sensor(sd, address, test_value, 1);
753 		m5602_read_sensor(sd, address, &ctrl_value, 1);
754 
755 		if (ctrl_value == test_value[0])
756 			pr_info("register 0x%x is writeable\n", address);
757 		else
758 			pr_info("register 0x%x is read only\n", address);
759 
760 		/* Restore original value */
761 		m5602_write_sensor(sd, address, &old_value, 1);
762 	}
763 }
764