1/*
2 * Driver for the mt9m111 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_mt9m111.h"
22
23static int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
24static int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
25static int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
26static int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
27static int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
28static int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val);
29static int mt9m111_set_auto_white_balance(struct gspca_dev *gspca_dev,
30					 __s32 val);
31static int mt9m111_get_auto_white_balance(struct gspca_dev *gspca_dev,
32					  __s32 *val);
33static int mt9m111_get_green_balance(struct gspca_dev *gspca_dev, __s32 *val);
34static int mt9m111_set_green_balance(struct gspca_dev *gspca_dev, __s32 val);
35static int mt9m111_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val);
36static int mt9m111_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val);
37static int mt9m111_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val);
38static int mt9m111_set_red_balance(struct gspca_dev *gspca_dev, __s32 val);
39
40static struct v4l2_pix_format mt9m111_modes[] = {
41	{
42		640,
43		480,
44		V4L2_PIX_FMT_SBGGR8,
45		V4L2_FIELD_NONE,
46		.sizeimage = 640 * 480,
47		.bytesperline = 640,
48		.colorspace = V4L2_COLORSPACE_SRGB,
49		.priv = 0
50	}
51};
52
53static const struct ctrl mt9m111_ctrls[] = {
54#define VFLIP_IDX 0
55	{
56		{
57			.id		= V4L2_CID_VFLIP,
58			.type           = V4L2_CTRL_TYPE_BOOLEAN,
59			.name           = "vertical flip",
60			.minimum        = 0,
61			.maximum        = 1,
62			.step           = 1,
63			.default_value  = 0
64		},
65		.set = mt9m111_set_vflip,
66		.get = mt9m111_get_vflip
67	},
68#define HFLIP_IDX 1
69	{
70		{
71			.id             = V4L2_CID_HFLIP,
72			.type           = V4L2_CTRL_TYPE_BOOLEAN,
73			.name           = "horizontal flip",
74			.minimum        = 0,
75			.maximum        = 1,
76			.step           = 1,
77			.default_value  = 0
78		},
79		.set = mt9m111_set_hflip,
80		.get = mt9m111_get_hflip
81	},
82#define GAIN_IDX 2
83	{
84		{
85			.id             = V4L2_CID_GAIN,
86			.type           = V4L2_CTRL_TYPE_INTEGER,
87			.name           = "gain",
88			.minimum        = 0,
89			.maximum        = (INITIAL_MAX_GAIN - 1) * 2 * 2 * 2,
90			.step           = 1,
91			.default_value  = MT9M111_DEFAULT_GAIN,
92			.flags          = V4L2_CTRL_FLAG_SLIDER
93		},
94		.set = mt9m111_set_gain,
95		.get = mt9m111_get_gain
96	},
97#define AUTO_WHITE_BALANCE_IDX 3
98	{
99		{
100			.id             = V4L2_CID_AUTO_WHITE_BALANCE,
101			.type           = V4L2_CTRL_TYPE_BOOLEAN,
102			.name           = "auto white balance",
103			.minimum        = 0,
104			.maximum        = 1,
105			.step           = 1,
106			.default_value  = 0,
107		},
108		.set = mt9m111_set_auto_white_balance,
109		.get = mt9m111_get_auto_white_balance
110	},
111#define GREEN_BALANCE_IDX 4
112	{
113		{
114			.id		= M5602_V4L2_CID_GREEN_BALANCE,
115			.type		= V4L2_CTRL_TYPE_INTEGER,
116			.name		= "green balance",
117			.minimum	= 0x00,
118			.maximum	= 0x7ff,
119			.step		= 0x1,
120			.default_value	= MT9M111_GREEN_GAIN_DEFAULT,
121			.flags		= V4L2_CTRL_FLAG_SLIDER
122		},
123		.set = mt9m111_set_green_balance,
124		.get = mt9m111_get_green_balance
125	},
126#define BLUE_BALANCE_IDX 5
127	{
128		{
129			.id		= V4L2_CID_BLUE_BALANCE,
130			.type		= V4L2_CTRL_TYPE_INTEGER,
131			.name		= "blue balance",
132			.minimum	= 0x00,
133			.maximum	= 0x7ff,
134			.step		= 0x1,
135			.default_value	= MT9M111_BLUE_GAIN_DEFAULT,
136			.flags		= V4L2_CTRL_FLAG_SLIDER
137		},
138		.set = mt9m111_set_blue_balance,
139		.get = mt9m111_get_blue_balance
140	},
141#define RED_BALANCE_IDX 5
142	{
143		{
144			.id		= V4L2_CID_RED_BALANCE,
145			.type		= V4L2_CTRL_TYPE_INTEGER,
146			.name		= "red balance",
147			.minimum	= 0x00,
148			.maximum	= 0x7ff,
149			.step		= 0x1,
150			.default_value	= MT9M111_RED_GAIN_DEFAULT,
151			.flags		= V4L2_CTRL_FLAG_SLIDER
152		},
153		.set = mt9m111_set_red_balance,
154		.get = mt9m111_get_red_balance
155	},
156};
157
158static void mt9m111_dump_registers(struct sd *sd);
159
160int mt9m111_probe(struct sd *sd)
161{
162	u8 data[2] = {0x00, 0x00};
163	int i;
164	s32 *sensor_settings;
165
166	if (force_sensor) {
167		if (force_sensor == MT9M111_SENSOR) {
168			pr_info("Forcing a %s sensor\n", mt9m111.name);
169			goto sensor_found;
170		}
171		/* If we want to force another sensor, don't try to probe this
172		 * one */
173		return -ENODEV;
174	}
175
176	PDEBUG(D_PROBE, "Probing for a mt9m111 sensor");
177
178	/* Do the preinit */
179	for (i = 0; i < ARRAY_SIZE(preinit_mt9m111); i++) {
180		if (preinit_mt9m111[i][0] == BRIDGE) {
181			m5602_write_bridge(sd,
182				preinit_mt9m111[i][1],
183				preinit_mt9m111[i][2]);
184		} else {
185			data[0] = preinit_mt9m111[i][2];
186			data[1] = preinit_mt9m111[i][3];
187			m5602_write_sensor(sd,
188				preinit_mt9m111[i][1], data, 2);
189		}
190	}
191
192	if (m5602_read_sensor(sd, MT9M111_SC_CHIPVER, data, 2))
193		return -ENODEV;
194
195	if ((data[0] == 0x14) && (data[1] == 0x3a)) {
196		pr_info("Detected a mt9m111 sensor\n");
197		goto sensor_found;
198	}
199
200	return -ENODEV;
201
202sensor_found:
203	sensor_settings = kmalloc(ARRAY_SIZE(mt9m111_ctrls) * sizeof(s32),
204				  GFP_KERNEL);
205	if (!sensor_settings)
206		return -ENOMEM;
207
208	sd->gspca_dev.cam.cam_mode = mt9m111_modes;
209	sd->gspca_dev.cam.nmodes = ARRAY_SIZE(mt9m111_modes);
210	sd->desc->ctrls = mt9m111_ctrls;
211	sd->desc->nctrls = ARRAY_SIZE(mt9m111_ctrls);
212
213	for (i = 0; i < ARRAY_SIZE(mt9m111_ctrls); i++)
214		sensor_settings[i] = mt9m111_ctrls[i].qctrl.default_value;
215	sd->sensor_priv = sensor_settings;
216
217	return 0;
218}
219
220int mt9m111_init(struct sd *sd)
221{
222	int i, err = 0;
223	s32 *sensor_settings = sd->sensor_priv;
224
225	/* Init the sensor */
226	for (i = 0; i < ARRAY_SIZE(init_mt9m111) && !err; i++) {
227		u8 data[2];
228
229		if (init_mt9m111[i][0] == BRIDGE) {
230			err = m5602_write_bridge(sd,
231				init_mt9m111[i][1],
232				init_mt9m111[i][2]);
233		} else {
234			data[0] = init_mt9m111[i][2];
235			data[1] = init_mt9m111[i][3];
236			err = m5602_write_sensor(sd,
237				init_mt9m111[i][1], data, 2);
238		}
239	}
240
241	if (dump_sensor)
242		mt9m111_dump_registers(sd);
243
244	err = mt9m111_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]);
245	if (err < 0)
246		return err;
247
248	err = mt9m111_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]);
249	if (err < 0)
250		return err;
251
252	err = mt9m111_set_green_balance(&sd->gspca_dev,
253					 sensor_settings[GREEN_BALANCE_IDX]);
254	if (err < 0)
255		return err;
256
257	err = mt9m111_set_blue_balance(&sd->gspca_dev,
258					 sensor_settings[BLUE_BALANCE_IDX]);
259	if (err < 0)
260		return err;
261
262	err = mt9m111_set_red_balance(&sd->gspca_dev,
263					sensor_settings[RED_BALANCE_IDX]);
264	if (err < 0)
265		return err;
266
267	return mt9m111_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]);
268}
269
270int mt9m111_start(struct sd *sd)
271{
272	int i, err = 0;
273	u8 data[2];
274	struct cam *cam = &sd->gspca_dev.cam;
275	s32 *sensor_settings = sd->sensor_priv;
276
277	int width = cam->cam_mode[sd->gspca_dev.curr_mode].width - 1;
278	int height = cam->cam_mode[sd->gspca_dev.curr_mode].height;
279
280	for (i = 0; i < ARRAY_SIZE(start_mt9m111) && !err; i++) {
281		if (start_mt9m111[i][0] == BRIDGE) {
282			err = m5602_write_bridge(sd,
283				start_mt9m111[i][1],
284				start_mt9m111[i][2]);
285		} else {
286			data[0] = start_mt9m111[i][2];
287			data[1] = start_mt9m111[i][3];
288			err = m5602_write_sensor(sd,
289				start_mt9m111[i][1], data, 2);
290		}
291	}
292	if (err < 0)
293		return err;
294
295	err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height >> 8) & 0xff);
296	if (err < 0)
297		return err;
298
299	err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height & 0xff));
300	if (err < 0)
301		return err;
302
303	for (i = 0; i < 2 && !err; i++)
304		err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0);
305	if (err < 0)
306		return err;
307
308	err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0);
309	if (err < 0)
310		return err;
311
312	err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 2);
313	if (err < 0)
314		return err;
315
316	for (i = 0; i < 2 && !err; i++)
317		err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, 0);
318	if (err < 0)
319		return err;
320
321	err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA,
322				 (width >> 8) & 0xff);
323	if (err < 0)
324		return err;
325
326	err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, width & 0xff);
327	if (err < 0)
328		return err;
329
330	err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0);
331	if (err < 0)
332		return err;
333
334	switch (width) {
335	case 640:
336		PDEBUG(D_V4L2, "Configuring camera for VGA mode");
337		data[0] = MT9M111_RMB_OVER_SIZED;
338		data[1] = MT9M111_RMB_ROW_SKIP_2X |
339			  MT9M111_RMB_COLUMN_SKIP_2X |
340			  (sensor_settings[VFLIP_IDX] << 0) |
341			  (sensor_settings[HFLIP_IDX] << 1);
342
343		err = m5602_write_sensor(sd,
344					 MT9M111_SC_R_MODE_CONTEXT_B, data, 2);
345		break;
346
347	case 320:
348		PDEBUG(D_V4L2, "Configuring camera for QVGA mode");
349		data[0] = MT9M111_RMB_OVER_SIZED;
350		data[1] = MT9M111_RMB_ROW_SKIP_4X |
351				MT9M111_RMB_COLUMN_SKIP_4X |
352				(sensor_settings[VFLIP_IDX] << 0) |
353				(sensor_settings[HFLIP_IDX] << 1);
354		err = m5602_write_sensor(sd,
355					 MT9M111_SC_R_MODE_CONTEXT_B, data, 2);
356		break;
357	}
358	return err;
359}
360
361void mt9m111_disconnect(struct sd *sd)
362{
363	sd->sensor = NULL;
364	kfree(sd->sensor_priv);
365}
366
367static int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
368{
369	struct sd *sd = (struct sd *) gspca_dev;
370	s32 *sensor_settings = sd->sensor_priv;
371
372	*val = sensor_settings[VFLIP_IDX];
373	PDEBUG(D_V4L2, "Read vertical flip %d", *val);
374
375	return 0;
376}
377
378static int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
379{
380	int err;
381	u8 data[2] = {0x00, 0x00};
382	struct sd *sd = (struct sd *) gspca_dev;
383	s32 *sensor_settings = sd->sensor_priv;
384
385	PDEBUG(D_V4L2, "Set vertical flip to %d", val);
386
387	sensor_settings[VFLIP_IDX] = val;
388
389	/* The mt9m111 is flipped by default */
390	val = !val;
391
392	/* Set the correct page map */
393	err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2);
394	if (err < 0)
395		return err;
396
397	err = m5602_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, data, 2);
398	if (err < 0)
399		return err;
400
401	data[1] = (data[1] & 0xfe) | val;
402	err = m5602_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B,
403				   data, 2);
404	return err;
405}
406
407static int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
408{
409	struct sd *sd = (struct sd *) gspca_dev;
410	s32 *sensor_settings = sd->sensor_priv;
411
412	*val = sensor_settings[HFLIP_IDX];
413	PDEBUG(D_V4L2, "Read horizontal flip %d", *val);
414
415	return 0;
416}
417
418static int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
419{
420	int err;
421	u8 data[2] = {0x00, 0x00};
422	struct sd *sd = (struct sd *) gspca_dev;
423	s32 *sensor_settings = sd->sensor_priv;
424
425	PDEBUG(D_V4L2, "Set horizontal flip to %d", val);
426
427	sensor_settings[HFLIP_IDX] = val;
428
429	/* The mt9m111 is flipped by default */
430	val = !val;
431
432	/* Set the correct page map */
433	err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2);
434	if (err < 0)
435		return err;
436
437	err = m5602_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, data, 2);
438	if (err < 0)
439		return err;
440
441	data[1] = (data[1] & 0xfd) | ((val << 1) & 0x02);
442	err = m5602_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B,
443					data, 2);
444	return err;
445}
446
447static int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
448{
449	struct sd *sd = (struct sd *) gspca_dev;
450	s32 *sensor_settings = sd->sensor_priv;
451
452	*val = sensor_settings[GAIN_IDX];
453	PDEBUG(D_V4L2, "Read gain %d", *val);
454
455	return 0;
456}
457
458static int mt9m111_set_auto_white_balance(struct gspca_dev *gspca_dev,
459					  __s32 val)
460{
461	struct sd *sd = (struct sd *) gspca_dev;
462	s32 *sensor_settings = sd->sensor_priv;
463	int err;
464	u8 data[2];
465
466	err = m5602_read_sensor(sd, MT9M111_CP_OPERATING_MODE_CTL, data, 2);
467	if (err < 0)
468		return err;
469
470	sensor_settings[AUTO_WHITE_BALANCE_IDX] = val & 0x01;
471	data[1] = ((data[1] & 0xfd) | ((val & 0x01) << 1));
472
473	err = m5602_write_sensor(sd, MT9M111_CP_OPERATING_MODE_CTL, data, 2);
474
475	PDEBUG(D_V4L2, "Set auto white balance %d", val);
476	return err;
477}
478
479static int mt9m111_get_auto_white_balance(struct gspca_dev *gspca_dev,
480					  __s32 *val) {
481	struct sd *sd = (struct sd *) gspca_dev;
482	s32 *sensor_settings = sd->sensor_priv;
483
484	*val = sensor_settings[AUTO_WHITE_BALANCE_IDX];
485	PDEBUG(D_V4L2, "Read auto white balance %d", *val);
486	return 0;
487}
488
489static int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val)
490{
491	int err, tmp;
492	u8 data[2] = {0x00, 0x00};
493	struct sd *sd = (struct sd *) gspca_dev;
494	s32 *sensor_settings = sd->sensor_priv;
495
496	sensor_settings[GAIN_IDX] = val;
497
498	/* Set the correct page map */
499	err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2);
500	if (err < 0)
501		return err;
502
503	if (val >= INITIAL_MAX_GAIN * 2 * 2 * 2)
504		return -EINVAL;
505
506	if ((val >= INITIAL_MAX_GAIN * 2 * 2) &&
507	    (val < (INITIAL_MAX_GAIN - 1) * 2 * 2 * 2))
508		tmp = (1 << 10) | (val << 9) |
509				(val << 8) | (val / 8);
510	else if ((val >= INITIAL_MAX_GAIN * 2) &&
511		 (val <  INITIAL_MAX_GAIN * 2 * 2))
512		tmp = (1 << 9) | (1 << 8) | (val / 4);
513	else if ((val >= INITIAL_MAX_GAIN) &&
514		 (val < INITIAL_MAX_GAIN * 2))
515		tmp = (1 << 8) | (val / 2);
516	else
517		tmp = val;
518
519	data[1] = (tmp & 0xff);
520	data[0] = (tmp & 0xff00) >> 8;
521	PDEBUG(D_V4L2, "tmp=%d, data[1]=%d, data[0]=%d", tmp,
522	       data[1], data[0]);
523
524	err = m5602_write_sensor(sd, MT9M111_SC_GLOBAL_GAIN,
525				   data, 2);
526
527	return err;
528}
529
530static int mt9m111_set_green_balance(struct gspca_dev *gspca_dev, __s32 val)
531{
532	int err;
533	u8 data[2];
534	struct sd *sd = (struct sd *) gspca_dev;
535	s32 *sensor_settings = sd->sensor_priv;
536
537	sensor_settings[GREEN_BALANCE_IDX] = val;
538	data[1] = (val & 0xff);
539	data[0] = (val & 0xff00) >> 8;
540
541	PDEBUG(D_V4L2, "Set green balance %d", val);
542	err = m5602_write_sensor(sd, MT9M111_SC_GREEN_1_GAIN,
543				 data, 2);
544	if (err < 0)
545		return err;
546
547	return m5602_write_sensor(sd, MT9M111_SC_GREEN_2_GAIN,
548				  data, 2);
549}
550
551static int mt9m111_get_green_balance(struct gspca_dev *gspca_dev, __s32 *val)
552{
553	struct sd *sd = (struct sd *) gspca_dev;
554	s32 *sensor_settings = sd->sensor_priv;
555
556	*val = sensor_settings[GREEN_BALANCE_IDX];
557	PDEBUG(D_V4L2, "Read green balance %d", *val);
558	return 0;
559}
560
561static int mt9m111_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
562{
563	u8 data[2];
564	struct sd *sd = (struct sd *) gspca_dev;
565	s32 *sensor_settings = sd->sensor_priv;
566
567	sensor_settings[BLUE_BALANCE_IDX] = val;
568	data[1] = (val & 0xff);
569	data[0] = (val & 0xff00) >> 8;
570
571	PDEBUG(D_V4L2, "Set blue balance %d", val);
572
573	return m5602_write_sensor(sd, MT9M111_SC_BLUE_GAIN,
574				  data, 2);
575}
576
577static int mt9m111_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
578{
579	struct sd *sd = (struct sd *) gspca_dev;
580	s32 *sensor_settings = sd->sensor_priv;
581
582	*val = sensor_settings[BLUE_BALANCE_IDX];
583	PDEBUG(D_V4L2, "Read blue balance %d", *val);
584	return 0;
585}
586
587static int mt9m111_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
588{
589	u8 data[2];
590	struct sd *sd = (struct sd *) gspca_dev;
591	s32 *sensor_settings = sd->sensor_priv;
592
593	sensor_settings[RED_BALANCE_IDX] = val;
594	data[1] = (val & 0xff);
595	data[0] = (val & 0xff00) >> 8;
596
597	PDEBUG(D_V4L2, "Set red balance %d", val);
598
599	return m5602_write_sensor(sd, MT9M111_SC_RED_GAIN,
600				  data, 2);
601}
602
603static int mt9m111_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
604{
605	struct sd *sd = (struct sd *) gspca_dev;
606	s32 *sensor_settings = sd->sensor_priv;
607
608	*val = sensor_settings[RED_BALANCE_IDX];
609	PDEBUG(D_V4L2, "Read red balance %d", *val);
610	return 0;
611}
612
613static void mt9m111_dump_registers(struct sd *sd)
614{
615	u8 address, value[2] = {0x00, 0x00};
616
617	pr_info("Dumping the mt9m111 register state\n");
618
619	pr_info("Dumping the mt9m111 sensor core registers\n");
620	value[1] = MT9M111_SENSOR_CORE;
621	m5602_write_sensor(sd, MT9M111_PAGE_MAP, value, 2);
622	for (address = 0; address < 0xff; address++) {
623		m5602_read_sensor(sd, address, value, 2);
624		pr_info("register 0x%x contains 0x%x%x\n",
625			address, value[0], value[1]);
626	}
627
628	pr_info("Dumping the mt9m111 color pipeline registers\n");
629	value[1] = MT9M111_COLORPIPE;
630	m5602_write_sensor(sd, MT9M111_PAGE_MAP, value, 2);
631	for (address = 0; address < 0xff; address++) {
632		m5602_read_sensor(sd, address, value, 2);
633		pr_info("register 0x%x contains 0x%x%x\n",
634			address, value[0], value[1]);
635	}
636
637	pr_info("Dumping the mt9m111 camera control registers\n");
638	value[1] = MT9M111_CAMERA_CONTROL;
639	m5602_write_sensor(sd, MT9M111_PAGE_MAP, value, 2);
640	for (address = 0; address < 0xff; address++) {
641		m5602_read_sensor(sd, address, value, 2);
642		pr_info("register 0x%x contains 0x%x%x\n",
643			address, value[0], value[1]);
644	}
645
646	pr_info("mt9m111 register state dump complete\n");
647}
648