• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/drivers/media/video/
1/*
2 * Driver for MT9V022 CMOS Image Sensor from Micron
3 *
4 * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/videodev2.h>
12#include <linux/slab.h>
13#include <linux/i2c.h>
14#include <linux/delay.h>
15#include <linux/log2.h>
16
17#include <media/v4l2-subdev.h>
18#include <media/v4l2-chip-ident.h>
19#include <media/soc_camera.h>
20
21/*
22 * mt9v022 i2c address 0x48, 0x4c, 0x58, 0x5c
23 * The platform has to define ctruct i2c_board_info objects and link to them
24 * from struct soc_camera_link
25 */
26
27static char *sensor_type;
28module_param(sensor_type, charp, S_IRUGO);
29MODULE_PARM_DESC(sensor_type, "Sensor type: \"colour\" or \"monochrome\"");
30
31/* mt9v022 selected register addresses */
32#define MT9V022_CHIP_VERSION		0x00
33#define MT9V022_COLUMN_START		0x01
34#define MT9V022_ROW_START		0x02
35#define MT9V022_WINDOW_HEIGHT		0x03
36#define MT9V022_WINDOW_WIDTH		0x04
37#define MT9V022_HORIZONTAL_BLANKING	0x05
38#define MT9V022_VERTICAL_BLANKING	0x06
39#define MT9V022_CHIP_CONTROL		0x07
40#define MT9V022_SHUTTER_WIDTH1		0x08
41#define MT9V022_SHUTTER_WIDTH2		0x09
42#define MT9V022_SHUTTER_WIDTH_CTRL	0x0a
43#define MT9V022_TOTAL_SHUTTER_WIDTH	0x0b
44#define MT9V022_RESET			0x0c
45#define MT9V022_READ_MODE		0x0d
46#define MT9V022_MONITOR_MODE		0x0e
47#define MT9V022_PIXEL_OPERATION_MODE	0x0f
48#define MT9V022_LED_OUT_CONTROL		0x1b
49#define MT9V022_ADC_MODE_CONTROL	0x1c
50#define MT9V022_ANALOG_GAIN		0x35
51#define MT9V022_BLACK_LEVEL_CALIB_CTRL	0x47
52#define MT9V022_PIXCLK_FV_LV		0x74
53#define MT9V022_DIGITAL_TEST_PATTERN	0x7f
54#define MT9V022_AEC_AGC_ENABLE		0xAF
55#define MT9V022_MAX_TOTAL_SHUTTER_WIDTH	0xBD
56
57/* Progressive scan, master, defaults */
58#define MT9V022_CHIP_CONTROL_DEFAULT	0x188
59
60#define MT9V022_MAX_WIDTH		752
61#define MT9V022_MAX_HEIGHT		480
62#define MT9V022_MIN_WIDTH		48
63#define MT9V022_MIN_HEIGHT		32
64#define MT9V022_COLUMN_SKIP		1
65#define MT9V022_ROW_SKIP		4
66
67/* MT9V022 has only one fixed colorspace per pixelcode */
68struct mt9v022_datafmt {
69	enum v4l2_mbus_pixelcode	code;
70	enum v4l2_colorspace		colorspace;
71};
72
73/* Find a data format by a pixel code in an array */
74static const struct mt9v022_datafmt *mt9v022_find_datafmt(
75	enum v4l2_mbus_pixelcode code, const struct mt9v022_datafmt *fmt,
76	int n)
77{
78	int i;
79	for (i = 0; i < n; i++)
80		if (fmt[i].code == code)
81			return fmt + i;
82
83	return NULL;
84}
85
86static const struct mt9v022_datafmt mt9v022_colour_fmts[] = {
87	/*
88	 * Order important: first natively supported,
89	 * second supported with a GPIO extender
90	 */
91	{V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_COLORSPACE_SRGB},
92	{V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_COLORSPACE_SRGB},
93};
94
95static const struct mt9v022_datafmt mt9v022_monochrome_fmts[] = {
96	/* Order important - see above */
97	{V4L2_MBUS_FMT_Y10_1X10, V4L2_COLORSPACE_JPEG},
98	{V4L2_MBUS_FMT_GREY8_1X8, V4L2_COLORSPACE_JPEG},
99};
100
101struct mt9v022 {
102	struct v4l2_subdev subdev;
103	struct v4l2_rect rect;	/* Sensor window */
104	const struct mt9v022_datafmt *fmt;
105	const struct mt9v022_datafmt *fmts;
106	int num_fmts;
107	int model;	/* V4L2_IDENT_MT9V022* codes from v4l2-chip-ident.h */
108	u16 chip_control;
109	unsigned short y_skip_top;	/* Lines to skip at the top */
110};
111
112static struct mt9v022 *to_mt9v022(const struct i2c_client *client)
113{
114	return container_of(i2c_get_clientdata(client), struct mt9v022, subdev);
115}
116
117static int reg_read(struct i2c_client *client, const u8 reg)
118{
119	s32 data = i2c_smbus_read_word_data(client, reg);
120	return data < 0 ? data : swab16(data);
121}
122
123static int reg_write(struct i2c_client *client, const u8 reg,
124		     const u16 data)
125{
126	return i2c_smbus_write_word_data(client, reg, swab16(data));
127}
128
129static int reg_set(struct i2c_client *client, const u8 reg,
130		   const u16 data)
131{
132	int ret;
133
134	ret = reg_read(client, reg);
135	if (ret < 0)
136		return ret;
137	return reg_write(client, reg, ret | data);
138}
139
140static int reg_clear(struct i2c_client *client, const u8 reg,
141		     const u16 data)
142{
143	int ret;
144
145	ret = reg_read(client, reg);
146	if (ret < 0)
147		return ret;
148	return reg_write(client, reg, ret & ~data);
149}
150
151static int mt9v022_init(struct i2c_client *client)
152{
153	struct mt9v022 *mt9v022 = to_mt9v022(client);
154	int ret;
155
156	/*
157	 * Almost the default mode: master, parallel, simultaneous, and an
158	 * undocumented bit 0x200, which is present in table 7, but not in 8,
159	 * plus snapshot mode to disable scan for now
160	 */
161	mt9v022->chip_control |= 0x10;
162	ret = reg_write(client, MT9V022_CHIP_CONTROL, mt9v022->chip_control);
163	if (!ret)
164		ret = reg_write(client, MT9V022_READ_MODE, 0x300);
165
166	/* All defaults */
167	if (!ret)
168		/* AEC, AGC on */
169		ret = reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x3);
170	if (!ret)
171		ret = reg_write(client, MT9V022_ANALOG_GAIN, 16);
172	if (!ret)
173		ret = reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH, 480);
174	if (!ret)
175		ret = reg_write(client, MT9V022_MAX_TOTAL_SHUTTER_WIDTH, 480);
176	if (!ret)
177		/* default - auto */
178		ret = reg_clear(client, MT9V022_BLACK_LEVEL_CALIB_CTRL, 1);
179	if (!ret)
180		ret = reg_write(client, MT9V022_DIGITAL_TEST_PATTERN, 0);
181
182	return ret;
183}
184
185static int mt9v022_s_stream(struct v4l2_subdev *sd, int enable)
186{
187	struct i2c_client *client = sd->priv;
188	struct mt9v022 *mt9v022 = to_mt9v022(client);
189
190	if (enable)
191		/* Switch to master "normal" mode */
192		mt9v022->chip_control &= ~0x10;
193	else
194		/* Switch to snapshot mode */
195		mt9v022->chip_control |= 0x10;
196
197	if (reg_write(client, MT9V022_CHIP_CONTROL, mt9v022->chip_control) < 0)
198		return -EIO;
199	return 0;
200}
201
202static int mt9v022_set_bus_param(struct soc_camera_device *icd,
203				 unsigned long flags)
204{
205	struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
206	struct mt9v022 *mt9v022 = to_mt9v022(client);
207	struct soc_camera_link *icl = to_soc_camera_link(icd);
208	unsigned int width_flag = flags & SOCAM_DATAWIDTH_MASK;
209	int ret;
210	u16 pixclk = 0;
211
212	/* Only one width bit may be set */
213	if (!is_power_of_2(width_flag))
214		return -EINVAL;
215
216	if (icl->set_bus_param) {
217		ret = icl->set_bus_param(icl, width_flag);
218		if (ret)
219			return ret;
220	} else {
221		/*
222		 * Without board specific bus width settings we only support the
223		 * sensors native bus width
224		 */
225		if (width_flag != SOCAM_DATAWIDTH_10)
226			return -EINVAL;
227	}
228
229	flags = soc_camera_apply_sensor_flags(icl, flags);
230
231	if (flags & SOCAM_PCLK_SAMPLE_RISING)
232		pixclk |= 0x10;
233
234	if (!(flags & SOCAM_HSYNC_ACTIVE_HIGH))
235		pixclk |= 0x1;
236
237	if (!(flags & SOCAM_VSYNC_ACTIVE_HIGH))
238		pixclk |= 0x2;
239
240	ret = reg_write(client, MT9V022_PIXCLK_FV_LV, pixclk);
241	if (ret < 0)
242		return ret;
243
244	if (!(flags & SOCAM_MASTER))
245		mt9v022->chip_control &= ~0x8;
246
247	ret = reg_write(client, MT9V022_CHIP_CONTROL, mt9v022->chip_control);
248	if (ret < 0)
249		return ret;
250
251	dev_dbg(&client->dev, "Calculated pixclk 0x%x, chip control 0x%x\n",
252		pixclk, mt9v022->chip_control);
253
254	return 0;
255}
256
257static unsigned long mt9v022_query_bus_param(struct soc_camera_device *icd)
258{
259	struct soc_camera_link *icl = to_soc_camera_link(icd);
260	unsigned int flags = SOCAM_MASTER | SOCAM_SLAVE |
261		SOCAM_PCLK_SAMPLE_RISING | SOCAM_PCLK_SAMPLE_FALLING |
262		SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_LOW |
263		SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |
264		SOCAM_DATA_ACTIVE_HIGH;
265
266	if (icl->query_bus_param)
267		flags |= icl->query_bus_param(icl) & SOCAM_DATAWIDTH_MASK;
268	else
269		flags |= SOCAM_DATAWIDTH_10;
270
271	return soc_camera_apply_sensor_flags(icl, flags);
272}
273
274static int mt9v022_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
275{
276	struct i2c_client *client = sd->priv;
277	struct mt9v022 *mt9v022 = to_mt9v022(client);
278	struct v4l2_rect rect = a->c;
279	int ret;
280
281	/* Bayer format - even size lengths */
282	if (mt9v022->fmts == mt9v022_colour_fmts) {
283		rect.width	= ALIGN(rect.width, 2);
284		rect.height	= ALIGN(rect.height, 2);
285		/* Let the user play with the starting pixel */
286	}
287
288	soc_camera_limit_side(&rect.left, &rect.width,
289		     MT9V022_COLUMN_SKIP, MT9V022_MIN_WIDTH, MT9V022_MAX_WIDTH);
290
291	soc_camera_limit_side(&rect.top, &rect.height,
292		     MT9V022_ROW_SKIP, MT9V022_MIN_HEIGHT, MT9V022_MAX_HEIGHT);
293
294	/* Like in example app. Contradicts the datasheet though */
295	ret = reg_read(client, MT9V022_AEC_AGC_ENABLE);
296	if (ret >= 0) {
297		if (ret & 1) /* Autoexposure */
298			ret = reg_write(client, MT9V022_MAX_TOTAL_SHUTTER_WIDTH,
299					rect.height + mt9v022->y_skip_top + 43);
300		else
301			ret = reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH,
302					rect.height + mt9v022->y_skip_top + 43);
303	}
304	/* Setup frame format: defaults apart from width and height */
305	if (!ret)
306		ret = reg_write(client, MT9V022_COLUMN_START, rect.left);
307	if (!ret)
308		ret = reg_write(client, MT9V022_ROW_START, rect.top);
309	if (!ret)
310		/*
311		 * Default 94, Phytec driver says:
312		 * "width + horizontal blank >= 660"
313		 */
314		ret = reg_write(client, MT9V022_HORIZONTAL_BLANKING,
315				rect.width > 660 - 43 ? 43 :
316				660 - rect.width);
317	if (!ret)
318		ret = reg_write(client, MT9V022_VERTICAL_BLANKING, 45);
319	if (!ret)
320		ret = reg_write(client, MT9V022_WINDOW_WIDTH, rect.width);
321	if (!ret)
322		ret = reg_write(client, MT9V022_WINDOW_HEIGHT,
323				rect.height + mt9v022->y_skip_top);
324
325	if (ret < 0)
326		return ret;
327
328	dev_dbg(&client->dev, "Frame %dx%d pixel\n", rect.width, rect.height);
329
330	mt9v022->rect = rect;
331
332	return 0;
333}
334
335static int mt9v022_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
336{
337	struct i2c_client *client = sd->priv;
338	struct mt9v022 *mt9v022 = to_mt9v022(client);
339
340	a->c	= mt9v022->rect;
341	a->type	= V4L2_BUF_TYPE_VIDEO_CAPTURE;
342
343	return 0;
344}
345
346static int mt9v022_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
347{
348	a->bounds.left			= MT9V022_COLUMN_SKIP;
349	a->bounds.top			= MT9V022_ROW_SKIP;
350	a->bounds.width			= MT9V022_MAX_WIDTH;
351	a->bounds.height		= MT9V022_MAX_HEIGHT;
352	a->defrect			= a->bounds;
353	a->type				= V4L2_BUF_TYPE_VIDEO_CAPTURE;
354	a->pixelaspect.numerator	= 1;
355	a->pixelaspect.denominator	= 1;
356
357	return 0;
358}
359
360static int mt9v022_g_fmt(struct v4l2_subdev *sd,
361			 struct v4l2_mbus_framefmt *mf)
362{
363	struct i2c_client *client = sd->priv;
364	struct mt9v022 *mt9v022 = to_mt9v022(client);
365
366	mf->width	= mt9v022->rect.width;
367	mf->height	= mt9v022->rect.height;
368	mf->code	= mt9v022->fmt->code;
369	mf->colorspace	= mt9v022->fmt->colorspace;
370	mf->field	= V4L2_FIELD_NONE;
371
372	return 0;
373}
374
375static int mt9v022_s_fmt(struct v4l2_subdev *sd,
376			 struct v4l2_mbus_framefmt *mf)
377{
378	struct i2c_client *client = sd->priv;
379	struct mt9v022 *mt9v022 = to_mt9v022(client);
380	struct v4l2_crop a = {
381		.c = {
382			.left	= mt9v022->rect.left,
383			.top	= mt9v022->rect.top,
384			.width	= mf->width,
385			.height	= mf->height,
386		},
387	};
388	int ret;
389
390	/*
391	 * The caller provides a supported format, as verified per call to
392	 * icd->try_fmt(), datawidth is from our supported format list
393	 */
394	switch (mf->code) {
395	case V4L2_MBUS_FMT_GREY8_1X8:
396	case V4L2_MBUS_FMT_Y10_1X10:
397		if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATM)
398			return -EINVAL;
399		break;
400	case V4L2_MBUS_FMT_SBGGR8_1X8:
401	case V4L2_MBUS_FMT_SBGGR10_1X10:
402		if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATC)
403			return -EINVAL;
404		break;
405	default:
406		return -EINVAL;
407	}
408
409	/* No support for scaling on this camera, just crop. */
410	ret = mt9v022_s_crop(sd, &a);
411	if (!ret) {
412		mf->width	= mt9v022->rect.width;
413		mf->height	= mt9v022->rect.height;
414		mt9v022->fmt	= mt9v022_find_datafmt(mf->code,
415					mt9v022->fmts, mt9v022->num_fmts);
416		mf->colorspace	= mt9v022->fmt->colorspace;
417	}
418
419	return ret;
420}
421
422static int mt9v022_try_fmt(struct v4l2_subdev *sd,
423			   struct v4l2_mbus_framefmt *mf)
424{
425	struct i2c_client *client = sd->priv;
426	struct mt9v022 *mt9v022 = to_mt9v022(client);
427	const struct mt9v022_datafmt *fmt;
428	int align = mf->code == V4L2_MBUS_FMT_SBGGR8_1X8 ||
429		mf->code == V4L2_MBUS_FMT_SBGGR10_1X10;
430
431	v4l_bound_align_image(&mf->width, MT9V022_MIN_WIDTH,
432		MT9V022_MAX_WIDTH, align,
433		&mf->height, MT9V022_MIN_HEIGHT + mt9v022->y_skip_top,
434		MT9V022_MAX_HEIGHT + mt9v022->y_skip_top, align, 0);
435
436	fmt = mt9v022_find_datafmt(mf->code, mt9v022->fmts,
437				   mt9v022->num_fmts);
438	if (!fmt) {
439		fmt = mt9v022->fmt;
440		mf->code = fmt->code;
441	}
442
443	mf->colorspace	= fmt->colorspace;
444
445	return 0;
446}
447
448static int mt9v022_g_chip_ident(struct v4l2_subdev *sd,
449				struct v4l2_dbg_chip_ident *id)
450{
451	struct i2c_client *client = sd->priv;
452	struct mt9v022 *mt9v022 = to_mt9v022(client);
453
454	if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
455		return -EINVAL;
456
457	if (id->match.addr != client->addr)
458		return -ENODEV;
459
460	id->ident	= mt9v022->model;
461	id->revision	= 0;
462
463	return 0;
464}
465
466#ifdef CONFIG_VIDEO_ADV_DEBUG
467static int mt9v022_g_register(struct v4l2_subdev *sd,
468			      struct v4l2_dbg_register *reg)
469{
470	struct i2c_client *client = sd->priv;
471
472	if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
473		return -EINVAL;
474
475	if (reg->match.addr != client->addr)
476		return -ENODEV;
477
478	reg->size = 2;
479	reg->val = reg_read(client, reg->reg);
480
481	if (reg->val > 0xffff)
482		return -EIO;
483
484	return 0;
485}
486
487static int mt9v022_s_register(struct v4l2_subdev *sd,
488			      struct v4l2_dbg_register *reg)
489{
490	struct i2c_client *client = sd->priv;
491
492	if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
493		return -EINVAL;
494
495	if (reg->match.addr != client->addr)
496		return -ENODEV;
497
498	if (reg_write(client, reg->reg, reg->val) < 0)
499		return -EIO;
500
501	return 0;
502}
503#endif
504
505static const struct v4l2_queryctrl mt9v022_controls[] = {
506	{
507		.id		= V4L2_CID_VFLIP,
508		.type		= V4L2_CTRL_TYPE_BOOLEAN,
509		.name		= "Flip Vertically",
510		.minimum	= 0,
511		.maximum	= 1,
512		.step		= 1,
513		.default_value	= 0,
514	}, {
515		.id		= V4L2_CID_HFLIP,
516		.type		= V4L2_CTRL_TYPE_BOOLEAN,
517		.name		= "Flip Horizontally",
518		.minimum	= 0,
519		.maximum	= 1,
520		.step		= 1,
521		.default_value	= 0,
522	}, {
523		.id		= V4L2_CID_GAIN,
524		.type		= V4L2_CTRL_TYPE_INTEGER,
525		.name		= "Analog Gain",
526		.minimum	= 64,
527		.maximum	= 127,
528		.step		= 1,
529		.default_value	= 64,
530		.flags		= V4L2_CTRL_FLAG_SLIDER,
531	}, {
532		.id		= V4L2_CID_EXPOSURE,
533		.type		= V4L2_CTRL_TYPE_INTEGER,
534		.name		= "Exposure",
535		.minimum	= 1,
536		.maximum	= 255,
537		.step		= 1,
538		.default_value	= 255,
539		.flags		= V4L2_CTRL_FLAG_SLIDER,
540	}, {
541		.id		= V4L2_CID_AUTOGAIN,
542		.type		= V4L2_CTRL_TYPE_BOOLEAN,
543		.name		= "Automatic Gain",
544		.minimum	= 0,
545		.maximum	= 1,
546		.step		= 1,
547		.default_value	= 1,
548	}, {
549		.id		= V4L2_CID_EXPOSURE_AUTO,
550		.type		= V4L2_CTRL_TYPE_BOOLEAN,
551		.name		= "Automatic Exposure",
552		.minimum	= 0,
553		.maximum	= 1,
554		.step		= 1,
555		.default_value	= 1,
556	}
557};
558
559static struct soc_camera_ops mt9v022_ops = {
560	.set_bus_param		= mt9v022_set_bus_param,
561	.query_bus_param	= mt9v022_query_bus_param,
562	.controls		= mt9v022_controls,
563	.num_controls		= ARRAY_SIZE(mt9v022_controls),
564};
565
566static int mt9v022_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
567{
568	struct i2c_client *client = sd->priv;
569	const struct v4l2_queryctrl *qctrl;
570	unsigned long range;
571	int data;
572
573	qctrl = soc_camera_find_qctrl(&mt9v022_ops, ctrl->id);
574
575	switch (ctrl->id) {
576	case V4L2_CID_VFLIP:
577		data = reg_read(client, MT9V022_READ_MODE);
578		if (data < 0)
579			return -EIO;
580		ctrl->value = !!(data & 0x10);
581		break;
582	case V4L2_CID_HFLIP:
583		data = reg_read(client, MT9V022_READ_MODE);
584		if (data < 0)
585			return -EIO;
586		ctrl->value = !!(data & 0x20);
587		break;
588	case V4L2_CID_EXPOSURE_AUTO:
589		data = reg_read(client, MT9V022_AEC_AGC_ENABLE);
590		if (data < 0)
591			return -EIO;
592		ctrl->value = !!(data & 0x1);
593		break;
594	case V4L2_CID_AUTOGAIN:
595		data = reg_read(client, MT9V022_AEC_AGC_ENABLE);
596		if (data < 0)
597			return -EIO;
598		ctrl->value = !!(data & 0x2);
599		break;
600	case V4L2_CID_GAIN:
601		data = reg_read(client, MT9V022_ANALOG_GAIN);
602		if (data < 0)
603			return -EIO;
604
605		range = qctrl->maximum - qctrl->minimum;
606		ctrl->value = ((data - 16) * range + 24) / 48 + qctrl->minimum;
607
608		break;
609	case V4L2_CID_EXPOSURE:
610		data = reg_read(client, MT9V022_TOTAL_SHUTTER_WIDTH);
611		if (data < 0)
612			return -EIO;
613
614		range = qctrl->maximum - qctrl->minimum;
615		ctrl->value = ((data - 1) * range + 239) / 479 + qctrl->minimum;
616
617		break;
618	}
619	return 0;
620}
621
622static int mt9v022_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
623{
624	int data;
625	struct i2c_client *client = sd->priv;
626	const struct v4l2_queryctrl *qctrl;
627
628	qctrl = soc_camera_find_qctrl(&mt9v022_ops, ctrl->id);
629	if (!qctrl)
630		return -EINVAL;
631
632	switch (ctrl->id) {
633	case V4L2_CID_VFLIP:
634		if (ctrl->value)
635			data = reg_set(client, MT9V022_READ_MODE, 0x10);
636		else
637			data = reg_clear(client, MT9V022_READ_MODE, 0x10);
638		if (data < 0)
639			return -EIO;
640		break;
641	case V4L2_CID_HFLIP:
642		if (ctrl->value)
643			data = reg_set(client, MT9V022_READ_MODE, 0x20);
644		else
645			data = reg_clear(client, MT9V022_READ_MODE, 0x20);
646		if (data < 0)
647			return -EIO;
648		break;
649	case V4L2_CID_GAIN:
650		/* mt9v022 has minimum == default */
651		if (ctrl->value > qctrl->maximum || ctrl->value < qctrl->minimum)
652			return -EINVAL;
653		else {
654			unsigned long range = qctrl->maximum - qctrl->minimum;
655			/* Valid values 16 to 64, 32 to 64 must be even. */
656			unsigned long gain = ((ctrl->value - qctrl->minimum) *
657					      48 + range / 2) / range + 16;
658			if (gain >= 32)
659				gain &= ~1;
660			/*
661			 * The user wants to set gain manually, hope, she
662			 * knows, what she's doing... Switch AGC off.
663			 */
664
665			if (reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x2) < 0)
666				return -EIO;
667
668			dev_dbg(&client->dev, "Setting gain from %d to %lu\n",
669				reg_read(client, MT9V022_ANALOG_GAIN), gain);
670			if (reg_write(client, MT9V022_ANALOG_GAIN, gain) < 0)
671				return -EIO;
672		}
673		break;
674	case V4L2_CID_EXPOSURE:
675		/* mt9v022 has maximum == default */
676		if (ctrl->value > qctrl->maximum || ctrl->value < qctrl->minimum)
677			return -EINVAL;
678		else {
679			unsigned long range = qctrl->maximum - qctrl->minimum;
680			unsigned long shutter = ((ctrl->value - qctrl->minimum) *
681						 479 + range / 2) / range + 1;
682			/*
683			 * The user wants to set shutter width manually, hope,
684			 * she knows, what she's doing... Switch AEC off.
685			 */
686
687			if (reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x1) < 0)
688				return -EIO;
689
690			dev_dbg(&client->dev, "Shutter width from %d to %lu\n",
691				reg_read(client, MT9V022_TOTAL_SHUTTER_WIDTH),
692				shutter);
693			if (reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH,
694				      shutter) < 0)
695				return -EIO;
696		}
697		break;
698	case V4L2_CID_AUTOGAIN:
699		if (ctrl->value)
700			data = reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x2);
701		else
702			data = reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x2);
703		if (data < 0)
704			return -EIO;
705		break;
706	case V4L2_CID_EXPOSURE_AUTO:
707		if (ctrl->value)
708			data = reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x1);
709		else
710			data = reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x1);
711		if (data < 0)
712			return -EIO;
713		break;
714	}
715	return 0;
716}
717
718/*
719 * Interface active, can use i2c. If it fails, it can indeed mean, that
720 * this wasn't our capture interface, so, we wait for the right one
721 */
722static int mt9v022_video_probe(struct soc_camera_device *icd,
723			       struct i2c_client *client)
724{
725	struct mt9v022 *mt9v022 = to_mt9v022(client);
726	struct soc_camera_link *icl = to_soc_camera_link(icd);
727	s32 data;
728	int ret;
729	unsigned long flags;
730
731	if (!icd->dev.parent ||
732	    to_soc_camera_host(icd->dev.parent)->nr != icd->iface)
733		return -ENODEV;
734
735	/* Read out the chip version register */
736	data = reg_read(client, MT9V022_CHIP_VERSION);
737
738	/* must be 0x1311 or 0x1313 */
739	if (data != 0x1311 && data != 0x1313) {
740		ret = -ENODEV;
741		dev_info(&client->dev, "No MT9V022 found, ID register 0x%x\n",
742			 data);
743		goto ei2c;
744	}
745
746	/* Soft reset */
747	ret = reg_write(client, MT9V022_RESET, 1);
748	if (ret < 0)
749		goto ei2c;
750	/* 15 clock cycles */
751	udelay(200);
752	if (reg_read(client, MT9V022_RESET)) {
753		dev_err(&client->dev, "Resetting MT9V022 failed!\n");
754		if (ret > 0)
755			ret = -EIO;
756		goto ei2c;
757	}
758
759	/* Set monochrome or colour sensor type */
760	if (sensor_type && (!strcmp("colour", sensor_type) ||
761			    !strcmp("color", sensor_type))) {
762		ret = reg_write(client, MT9V022_PIXEL_OPERATION_MODE, 4 | 0x11);
763		mt9v022->model = V4L2_IDENT_MT9V022IX7ATC;
764		mt9v022->fmts = mt9v022_colour_fmts;
765	} else {
766		ret = reg_write(client, MT9V022_PIXEL_OPERATION_MODE, 0x11);
767		mt9v022->model = V4L2_IDENT_MT9V022IX7ATM;
768		mt9v022->fmts = mt9v022_monochrome_fmts;
769	}
770
771	if (ret < 0)
772		goto ei2c;
773
774	mt9v022->num_fmts = 0;
775
776	/*
777	 * This is a 10bit sensor, so by default we only allow 10bit.
778	 * The platform may support different bus widths due to
779	 * different routing of the data lines.
780	 */
781	if (icl->query_bus_param)
782		flags = icl->query_bus_param(icl);
783	else
784		flags = SOCAM_DATAWIDTH_10;
785
786	if (flags & SOCAM_DATAWIDTH_10)
787		mt9v022->num_fmts++;
788	else
789		mt9v022->fmts++;
790
791	if (flags & SOCAM_DATAWIDTH_8)
792		mt9v022->num_fmts++;
793
794	mt9v022->fmt = &mt9v022->fmts[0];
795
796	dev_info(&client->dev, "Detected a MT9V022 chip ID %x, %s sensor\n",
797		 data, mt9v022->model == V4L2_IDENT_MT9V022IX7ATM ?
798		 "monochrome" : "colour");
799
800	ret = mt9v022_init(client);
801	if (ret < 0)
802		dev_err(&client->dev, "Failed to initialise the camera\n");
803
804ei2c:
805	return ret;
806}
807
808static void mt9v022_video_remove(struct soc_camera_device *icd)
809{
810	struct soc_camera_link *icl = to_soc_camera_link(icd);
811
812	dev_dbg(&icd->dev, "Video removed: %p, %p\n",
813		icd->dev.parent, icd->vdev);
814	if (icl->free_bus)
815		icl->free_bus(icl);
816}
817
818static int mt9v022_g_skip_top_lines(struct v4l2_subdev *sd, u32 *lines)
819{
820	struct i2c_client *client = sd->priv;
821	struct mt9v022 *mt9v022 = to_mt9v022(client);
822
823	*lines = mt9v022->y_skip_top;
824
825	return 0;
826}
827
828static struct v4l2_subdev_core_ops mt9v022_subdev_core_ops = {
829	.g_ctrl		= mt9v022_g_ctrl,
830	.s_ctrl		= mt9v022_s_ctrl,
831	.g_chip_ident	= mt9v022_g_chip_ident,
832#ifdef CONFIG_VIDEO_ADV_DEBUG
833	.g_register	= mt9v022_g_register,
834	.s_register	= mt9v022_s_register,
835#endif
836};
837
838static int mt9v022_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
839			    enum v4l2_mbus_pixelcode *code)
840{
841	struct i2c_client *client = sd->priv;
842	struct mt9v022 *mt9v022 = to_mt9v022(client);
843
844	if (index >= mt9v022->num_fmts)
845		return -EINVAL;
846
847	*code = mt9v022->fmts[index].code;
848	return 0;
849}
850
851static struct v4l2_subdev_video_ops mt9v022_subdev_video_ops = {
852	.s_stream	= mt9v022_s_stream,
853	.s_mbus_fmt	= mt9v022_s_fmt,
854	.g_mbus_fmt	= mt9v022_g_fmt,
855	.try_mbus_fmt	= mt9v022_try_fmt,
856	.s_crop		= mt9v022_s_crop,
857	.g_crop		= mt9v022_g_crop,
858	.cropcap	= mt9v022_cropcap,
859	.enum_mbus_fmt	= mt9v022_enum_fmt,
860};
861
862static struct v4l2_subdev_sensor_ops mt9v022_subdev_sensor_ops = {
863	.g_skip_top_lines	= mt9v022_g_skip_top_lines,
864};
865
866static struct v4l2_subdev_ops mt9v022_subdev_ops = {
867	.core	= &mt9v022_subdev_core_ops,
868	.video	= &mt9v022_subdev_video_ops,
869	.sensor	= &mt9v022_subdev_sensor_ops,
870};
871
872static int mt9v022_probe(struct i2c_client *client,
873			 const struct i2c_device_id *did)
874{
875	struct mt9v022 *mt9v022;
876	struct soc_camera_device *icd = client->dev.platform_data;
877	struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
878	struct soc_camera_link *icl;
879	int ret;
880
881	if (!icd) {
882		dev_err(&client->dev, "MT9V022: missing soc-camera data!\n");
883		return -EINVAL;
884	}
885
886	icl = to_soc_camera_link(icd);
887	if (!icl) {
888		dev_err(&client->dev, "MT9V022 driver needs platform data\n");
889		return -EINVAL;
890	}
891
892	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) {
893		dev_warn(&adapter->dev,
894			 "I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n");
895		return -EIO;
896	}
897
898	mt9v022 = kzalloc(sizeof(struct mt9v022), GFP_KERNEL);
899	if (!mt9v022)
900		return -ENOMEM;
901
902	v4l2_i2c_subdev_init(&mt9v022->subdev, client, &mt9v022_subdev_ops);
903
904	mt9v022->chip_control = MT9V022_CHIP_CONTROL_DEFAULT;
905
906	icd->ops		= &mt9v022_ops;
907	/*
908	 * MT9V022 _really_ corrupts the first read out line.
909	 * TODO: verify on i.MX31
910	 */
911	mt9v022->y_skip_top	= 1;
912	mt9v022->rect.left	= MT9V022_COLUMN_SKIP;
913	mt9v022->rect.top	= MT9V022_ROW_SKIP;
914	mt9v022->rect.width	= MT9V022_MAX_WIDTH;
915	mt9v022->rect.height	= MT9V022_MAX_HEIGHT;
916
917	ret = mt9v022_video_probe(icd, client);
918	if (ret) {
919		icd->ops = NULL;
920		kfree(mt9v022);
921	}
922
923	return ret;
924}
925
926static int mt9v022_remove(struct i2c_client *client)
927{
928	struct mt9v022 *mt9v022 = to_mt9v022(client);
929	struct soc_camera_device *icd = client->dev.platform_data;
930
931	icd->ops = NULL;
932	mt9v022_video_remove(icd);
933	client->driver = NULL;
934	kfree(mt9v022);
935
936	return 0;
937}
938static const struct i2c_device_id mt9v022_id[] = {
939	{ "mt9v022", 0 },
940	{ }
941};
942MODULE_DEVICE_TABLE(i2c, mt9v022_id);
943
944static struct i2c_driver mt9v022_i2c_driver = {
945	.driver = {
946		.name = "mt9v022",
947	},
948	.probe		= mt9v022_probe,
949	.remove		= mt9v022_remove,
950	.id_table	= mt9v022_id,
951};
952
953static int __init mt9v022_mod_init(void)
954{
955	return i2c_add_driver(&mt9v022_i2c_driver);
956}
957
958static void __exit mt9v022_mod_exit(void)
959{
960	i2c_del_driver(&mt9v022_i2c_driver);
961}
962
963module_init(mt9v022_mod_init);
964module_exit(mt9v022_mod_exit);
965
966MODULE_DESCRIPTION("Micron MT9V022 Camera driver");
967MODULE_AUTHOR("Guennadi Liakhovetski <kernel@pengutronix.de>");
968MODULE_LICENSE("GPL");
969