mt9v022.c 21.4 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
/*
 * Driver for MT9V022 CMOS Image Sensor from Micron
 *
 * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include <linux/videodev2.h>
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/delay.h>
#include <linux/log2.h>

#include <media/v4l2-common.h>
#include <media/v4l2-chip-ident.h>
#include <media/soc_camera.h>

/* mt9v022 i2c address 0x48, 0x4c, 0x58, 0x5c
 * The platform has to define i2c_board_info
 * and call i2c_register_board_info() */

static char *sensor_type;
module_param(sensor_type, charp, S_IRUGO);
27
MODULE_PARM_DESC(sensor_type, "Sensor type: \"colour\" or \"monochrome\"");
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57

/* mt9v022 selected register addresses */
#define MT9V022_CHIP_VERSION		0x00
#define MT9V022_COLUMN_START		0x01
#define MT9V022_ROW_START		0x02
#define MT9V022_WINDOW_HEIGHT		0x03
#define MT9V022_WINDOW_WIDTH		0x04
#define MT9V022_HORIZONTAL_BLANKING	0x05
#define MT9V022_VERTICAL_BLANKING	0x06
#define MT9V022_CHIP_CONTROL		0x07
#define MT9V022_SHUTTER_WIDTH1		0x08
#define MT9V022_SHUTTER_WIDTH2		0x09
#define MT9V022_SHUTTER_WIDTH_CTRL	0x0a
#define MT9V022_TOTAL_SHUTTER_WIDTH	0x0b
#define MT9V022_RESET			0x0c
#define MT9V022_READ_MODE		0x0d
#define MT9V022_MONITOR_MODE		0x0e
#define MT9V022_PIXEL_OPERATION_MODE	0x0f
#define MT9V022_LED_OUT_CONTROL		0x1b
#define MT9V022_ADC_MODE_CONTROL	0x1c
#define MT9V022_ANALOG_GAIN		0x34
#define MT9V022_BLACK_LEVEL_CALIB_CTRL	0x47
#define MT9V022_PIXCLK_FV_LV		0x74
#define MT9V022_DIGITAL_TEST_PATTERN	0x7f
#define MT9V022_AEC_AGC_ENABLE		0xAF
#define MT9V022_MAX_TOTAL_SHUTTER_WIDTH	0xBD

/* Progressive scan, master, defaults */
#define MT9V022_CHIP_CONTROL_DEFAULT	0x188

58 59 60
static const struct soc_camera_data_format mt9v022_colour_formats[] = {
	/* Order important: first natively supported,
	 * second supported with a GPIO extender */
61
	{
62
		.name		= "Bayer (sRGB) 10 bit",
63 64 65 66
		.depth		= 10,
		.fourcc		= V4L2_PIX_FMT_SBGGR16,
		.colorspace	= V4L2_COLORSPACE_SRGB,
	}, {
67 68 69 70 71 72 73 74 75 76
		.name		= "Bayer (sRGB) 8 bit",
		.depth		= 8,
		.fourcc		= V4L2_PIX_FMT_SBGGR8,
		.colorspace	= V4L2_COLORSPACE_SRGB,
	}
};

static const struct soc_camera_data_format mt9v022_monochrome_formats[] = {
	/* Order important - see above */
	{
77 78 79 80 81 82 83 84 85 86 87
		.name		= "Monochrome 10 bit",
		.depth		= 10,
		.fourcc		= V4L2_PIX_FMT_Y16,
	}, {
		.name		= "Monochrome 8 bit",
		.depth		= 8,
		.fourcc		= V4L2_PIX_FMT_GREY,
	},
};

struct mt9v022 {
88
	int model;	/* V4L2_IDENT_MT9V022* codes from v4l2-chip-ident.h */
89 90 91
	u16 chip_control;
};

92
static int reg_read(struct i2c_client *client, const u8 reg)
93 94 95 96 97
{
	s32 data = i2c_smbus_read_word_data(client, reg);
	return data < 0 ? data : swab16(data);
}

98
static int reg_write(struct i2c_client *client, const u8 reg,
99 100
		     const u16 data)
{
101
	return i2c_smbus_write_word_data(client, reg, swab16(data));
102 103
}

104
static int reg_set(struct i2c_client *client, const u8 reg,
105 106 107 108
		   const u16 data)
{
	int ret;

109
	ret = reg_read(client, reg);
110 111
	if (ret < 0)
		return ret;
112
	return reg_write(client, reg, ret | data);
113 114
}

115
static int reg_clear(struct i2c_client *client, const u8 reg,
116 117 118 119
		     const u16 data)
{
	int ret;

120
	ret = reg_read(client, reg);
121 122
	if (ret < 0)
		return ret;
123
	return reg_write(client, reg, ret & ~data);
124 125 126 127
}

static int mt9v022_init(struct soc_camera_device *icd)
{
128 129 130
	struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
	struct soc_camera_link *icl = to_soc_camera_link(icd);
	struct mt9v022 *mt9v022 = i2c_get_clientdata(client);
131 132
	int ret;

133
	if (icl->power) {
134
		ret = icl->power(&client->dev, 1);
135 136 137 138 139 140 141 142 143 144 145 146
		if (ret < 0) {
			dev_err(icd->vdev->parent,
				"Platform failed to power-on the camera.\n");
			return ret;
		}
	}

	/*
	 * The camera could have been already on, we hard-reset it additionally,
	 * if available. Soft reset is done in video_probe().
	 */
	if (icl->reset)
147
		icl->reset(&client->dev);
148

149 150 151 152
	/* Almost the default mode: master, parallel, simultaneous, and an
	 * undocumented bit 0x200, which is present in table 7, but not in 8,
	 * plus snapshot mode to disable scan for now */
	mt9v022->chip_control |= 0x10;
153
	ret = reg_write(client, MT9V022_CHIP_CONTROL, mt9v022->chip_control);
154
	if (!ret)
155
		ret = reg_write(client, MT9V022_READ_MODE, 0x300);
156 157

	/* All defaults */
158
	if (!ret)
159
		/* AEC, AGC on */
160
		ret = reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x3);
161
	if (!ret)
162
		ret = reg_write(client, MT9V022_MAX_TOTAL_SHUTTER_WIDTH, 480);
163
	if (!ret)
164
		/* default - auto */
165
		ret = reg_clear(client, MT9V022_BLACK_LEVEL_CALIB_CTRL, 1);
166
	if (!ret)
167
		ret = reg_write(client, MT9V022_DIGITAL_TEST_PATTERN, 0);
168

169
	return ret;
170 171 172 173
}

static int mt9v022_release(struct soc_camera_device *icd)
{
174 175
	struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
	struct soc_camera_link *icl = to_soc_camera_link(icd);
176 177

	if (icl->power)
178
		icl->power(&client->dev, 0);
179

180 181 182 183 184
	return 0;
}

static int mt9v022_start_capture(struct soc_camera_device *icd)
{
185 186
	struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
	struct mt9v022 *mt9v022 = i2c_get_clientdata(client);
187 188
	/* Switch to master "normal" mode */
	mt9v022->chip_control &= ~0x10;
189
	if (reg_write(client, MT9V022_CHIP_CONTROL,
190 191 192 193 194 195 196
		      mt9v022->chip_control) < 0)
		return -EIO;
	return 0;
}

static int mt9v022_stop_capture(struct soc_camera_device *icd)
{
197 198
	struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
	struct mt9v022 *mt9v022 = i2c_get_clientdata(client);
199 200
	/* Switch to snapshot mode */
	mt9v022->chip_control |= 0x10;
201
	if (reg_write(client, MT9V022_CHIP_CONTROL,
202 203 204 205 206
		      mt9v022->chip_control) < 0)
		return -EIO;
	return 0;
}

207 208
static int mt9v022_set_bus_param(struct soc_camera_device *icd,
				 unsigned long flags)
209
{
210 211 212
	struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
	struct mt9v022 *mt9v022 = i2c_get_clientdata(client);
	struct soc_camera_link *icl = to_soc_camera_link(icd);
213
	unsigned int width_flag = flags & SOCAM_DATAWIDTH_MASK;
214
	int ret;
215
	u16 pixclk = 0;
216 217 218 219 220

	/* Only one width bit may be set */
	if (!is_power_of_2(width_flag))
		return -EINVAL;

221 222 223
	if (icl->set_bus_param) {
		ret = icl->set_bus_param(icl, width_flag);
		if (ret)
224
			return ret;
225 226 227 228 229 230 231
	} else {
		/*
		 * Without board specific bus width settings we only support the
		 * sensors native bus width
		 */
		if (width_flag != SOCAM_DATAWIDTH_10)
			return -EINVAL;
232 233
	}

234 235
	flags = soc_camera_apply_sensor_flags(icl, flags);

236 237 238 239 240 241 242 243 244
	if (flags & SOCAM_PCLK_SAMPLE_RISING)
		pixclk |= 0x10;

	if (!(flags & SOCAM_HSYNC_ACTIVE_HIGH))
		pixclk |= 0x1;

	if (!(flags & SOCAM_VSYNC_ACTIVE_HIGH))
		pixclk |= 0x2;

245
	ret = reg_write(client, MT9V022_PIXCLK_FV_LV, pixclk);
246 247 248 249 250 251
	if (ret < 0)
		return ret;

	if (!(flags & SOCAM_MASTER))
		mt9v022->chip_control &= ~0x8;

252
	ret = reg_write(client, MT9V022_CHIP_CONTROL, mt9v022->chip_control);
253 254 255 256 257 258 259 260 261 262 263
	if (ret < 0)
		return ret;

	dev_dbg(&icd->dev, "Calculated pixclk 0x%x, chip control 0x%x\n",
		pixclk, mt9v022->chip_control);

	return 0;
}

static unsigned long mt9v022_query_bus_param(struct soc_camera_device *icd)
{
264
	struct soc_camera_link *icl = to_soc_camera_link(icd);
265
	unsigned int width_flag;
266

267 268 269 270 271
	if (icl->query_bus_param)
		width_flag = icl->query_bus_param(icl) &
			SOCAM_DATAWIDTH_MASK;
	else
		width_flag = SOCAM_DATAWIDTH_10;
272 273 274 275

	return SOCAM_PCLK_SAMPLE_RISING | SOCAM_PCLK_SAMPLE_FALLING |
		SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_LOW |
		SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |
276
		SOCAM_DATA_ACTIVE_HIGH | SOCAM_MASTER | SOCAM_SLAVE |
277 278 279
		width_flag;
}

280 281
static int mt9v022_set_crop(struct soc_camera_device *icd,
			    struct v4l2_rect *rect)
282
{
283
	struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
284 285
	int ret;

286
	/* Like in example app. Contradicts the datasheet though */
287
	ret = reg_read(client, MT9V022_AEC_AGC_ENABLE);
288 289
	if (ret >= 0) {
		if (ret & 1) /* Autoexposure */
290
			ret = reg_write(client, MT9V022_MAX_TOTAL_SHUTTER_WIDTH,
291 292
					rect->height + icd->y_skip_top + 43);
		else
293
			ret = reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH,
294 295 296
					rect->height + icd->y_skip_top + 43);
	}
	/* Setup frame format: defaults apart from width and height */
297
	if (!ret)
298
		ret = reg_write(client, MT9V022_COLUMN_START, rect->left);
299
	if (!ret)
300
		ret = reg_write(client, MT9V022_ROW_START, rect->top);
301
	if (!ret)
302 303
		/* Default 94, Phytec driver says:
		 * "width + horizontal blank >= 660" */
304
		ret = reg_write(client, MT9V022_HORIZONTAL_BLANKING,
305 306
				rect->width > 660 - 43 ? 43 :
				660 - rect->width);
307
	if (!ret)
308
		ret = reg_write(client, MT9V022_VERTICAL_BLANKING, 45);
309
	if (!ret)
310
		ret = reg_write(client, MT9V022_WINDOW_WIDTH, rect->width);
311
	if (!ret)
312
		ret = reg_write(client, MT9V022_WINDOW_HEIGHT,
313 314 315 316 317 318 319 320 321 322
				rect->height + icd->y_skip_top);

	if (ret < 0)
		return ret;

	dev_dbg(&icd->dev, "Frame %ux%u pixel\n", rect->width, rect->height);

	return 0;
}

323 324 325
static int mt9v022_set_fmt(struct soc_camera_device *icd,
			   struct v4l2_format *f)
{
326 327
	struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
	struct mt9v022 *mt9v022 = i2c_get_clientdata(client);
328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359
	struct v4l2_pix_format *pix = &f->fmt.pix;
	struct v4l2_rect rect = {
		.left	= icd->x_current,
		.top	= icd->y_current,
		.width	= pix->width,
		.height	= pix->height,
	};

	/* The caller provides a supported format, as verified per call to
	 * icd->try_fmt(), datawidth is from our supported format list */
	switch (pix->pixelformat) {
	case V4L2_PIX_FMT_GREY:
	case V4L2_PIX_FMT_Y16:
		if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATM)
			return -EINVAL;
		break;
	case V4L2_PIX_FMT_SBGGR8:
	case V4L2_PIX_FMT_SBGGR16:
		if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATC)
			return -EINVAL;
		break;
	case 0:
		/* No format change, only geometry */
		break;
	default:
		return -EINVAL;
	}

	/* No support for scaling on this camera, just crop. */
	return mt9v022_set_crop(icd, &rect);
}

360 361
static int mt9v022_try_fmt(struct soc_camera_device *icd,
			   struct v4l2_format *f)
362
{
363 364
	struct v4l2_pix_format *pix = &f->fmt.pix;

365 366 367
	v4l_bound_align_image(&pix->width, 48, 752, 2 /* ? */,
			      &pix->height, 32 + icd->y_skip_top,
			      480 + icd->y_skip_top, 0, 0);
368 369 370 371 372

	return 0;
}

static int mt9v022_get_chip_id(struct soc_camera_device *icd,
373
			       struct v4l2_dbg_chip_ident *id)
374
{
375 376
	struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
	struct mt9v022 *mt9v022 = i2c_get_clientdata(client);
377

378
	if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
379 380
		return -EINVAL;

381
	if (id->match.addr != client->addr)
382 383 384 385 386 387 388 389 390 391
		return -ENODEV;

	id->ident	= mt9v022->model;
	id->revision	= 0;

	return 0;
}

#ifdef CONFIG_VIDEO_ADV_DEBUG
static int mt9v022_get_register(struct soc_camera_device *icd,
392
				struct v4l2_dbg_register *reg)
393
{
394
	struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
395

396
	if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
397 398
		return -EINVAL;

399
	if (reg->match.addr != client->addr)
400 401
		return -ENODEV;

402
	reg->size = 2;
403
	reg->val = reg_read(client, reg->reg);
404 405 406 407 408 409 410 411

	if (reg->val > 0xffff)
		return -EIO;

	return 0;
}

static int mt9v022_set_register(struct soc_camera_device *icd,
412
				struct v4l2_dbg_register *reg)
413
{
414
	struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
415

416
	if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
417 418
		return -EINVAL;

419
	if (reg->match.addr != client->addr)
420 421
		return -ENODEV;

422
	if (reg_write(client, reg->reg, reg->val) < 0)
423 424 425 426 427 428
		return -EIO;

	return 0;
}
#endif

429
static const struct v4l2_queryctrl mt9v022_controls[] = {
430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482
	{
		.id		= V4L2_CID_VFLIP,
		.type		= V4L2_CTRL_TYPE_BOOLEAN,
		.name		= "Flip Vertically",
		.minimum	= 0,
		.maximum	= 1,
		.step		= 1,
		.default_value	= 0,
	}, {
		.id		= V4L2_CID_HFLIP,
		.type		= V4L2_CTRL_TYPE_BOOLEAN,
		.name		= "Flip Horizontally",
		.minimum	= 0,
		.maximum	= 1,
		.step		= 1,
		.default_value	= 0,
	}, {
		.id		= V4L2_CID_GAIN,
		.type		= V4L2_CTRL_TYPE_INTEGER,
		.name		= "Analog Gain",
		.minimum	= 64,
		.maximum	= 127,
		.step		= 1,
		.default_value	= 64,
		.flags		= V4L2_CTRL_FLAG_SLIDER,
	}, {
		.id		= V4L2_CID_EXPOSURE,
		.type		= V4L2_CTRL_TYPE_INTEGER,
		.name		= "Exposure",
		.minimum	= 1,
		.maximum	= 255,
		.step		= 1,
		.default_value	= 255,
		.flags		= V4L2_CTRL_FLAG_SLIDER,
	}, {
		.id		= V4L2_CID_AUTOGAIN,
		.type		= V4L2_CTRL_TYPE_BOOLEAN,
		.name		= "Automatic Gain",
		.minimum	= 0,
		.maximum	= 1,
		.step		= 1,
		.default_value	= 1,
	}, {
		.id		= V4L2_CID_EXPOSURE_AUTO,
		.type		= V4L2_CTRL_TYPE_BOOLEAN,
		.name		= "Automatic Exposure",
		.minimum	= 0,
		.maximum	= 1,
		.step		= 1,
		.default_value	= 1,
	}
};

483 484
static int mt9v022_get_control(struct soc_camera_device *, struct v4l2_control *);
static int mt9v022_set_control(struct soc_camera_device *, struct v4l2_control *);
485 486 487 488 489 490 491

static struct soc_camera_ops mt9v022_ops = {
	.owner			= THIS_MODULE,
	.init			= mt9v022_init,
	.release		= mt9v022_release,
	.start_capture		= mt9v022_start_capture,
	.stop_capture		= mt9v022_stop_capture,
492
	.set_crop		= mt9v022_set_crop,
493 494
	.set_fmt		= mt9v022_set_fmt,
	.try_fmt		= mt9v022_try_fmt,
495 496
	.set_bus_param		= mt9v022_set_bus_param,
	.query_bus_param	= mt9v022_query_bus_param,
497 498 499 500 501 502 503 504 505 506 507 508 509 510
	.controls		= mt9v022_controls,
	.num_controls		= ARRAY_SIZE(mt9v022_controls),
	.get_control		= mt9v022_get_control,
	.set_control		= mt9v022_set_control,
	.get_chip_id		= mt9v022_get_chip_id,
#ifdef CONFIG_VIDEO_ADV_DEBUG
	.get_register		= mt9v022_get_register,
	.set_register		= mt9v022_set_register,
#endif
};

static int mt9v022_get_control(struct soc_camera_device *icd,
			       struct v4l2_control *ctrl)
{
511
	struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
512 513 514 515
	int data;

	switch (ctrl->id) {
	case V4L2_CID_VFLIP:
516
		data = reg_read(client, MT9V022_READ_MODE);
517 518 519 520 521
		if (data < 0)
			return -EIO;
		ctrl->value = !!(data & 0x10);
		break;
	case V4L2_CID_HFLIP:
522
		data = reg_read(client, MT9V022_READ_MODE);
523 524 525 526 527
		if (data < 0)
			return -EIO;
		ctrl->value = !!(data & 0x20);
		break;
	case V4L2_CID_EXPOSURE_AUTO:
528
		data = reg_read(client, MT9V022_AEC_AGC_ENABLE);
529 530 531 532 533
		if (data < 0)
			return -EIO;
		ctrl->value = !!(data & 0x1);
		break;
	case V4L2_CID_AUTOGAIN:
534
		data = reg_read(client, MT9V022_AEC_AGC_ENABLE);
535 536 537 538 539 540 541 542 543 544 545 546
		if (data < 0)
			return -EIO;
		ctrl->value = !!(data & 0x2);
		break;
	}
	return 0;
}

static int mt9v022_set_control(struct soc_camera_device *icd,
			       struct v4l2_control *ctrl)
{
	int data;
547
	struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
548 549 550 551 552 553 554 555 556 557
	const struct v4l2_queryctrl *qctrl;

	qctrl = soc_camera_find_qctrl(&mt9v022_ops, ctrl->id);

	if (!qctrl)
		return -EINVAL;

	switch (ctrl->id) {
	case V4L2_CID_VFLIP:
		if (ctrl->value)
558
			data = reg_set(client, MT9V022_READ_MODE, 0x10);
559
		else
560
			data = reg_clear(client, MT9V022_READ_MODE, 0x10);
561 562 563 564 565
		if (data < 0)
			return -EIO;
		break;
	case V4L2_CID_HFLIP:
		if (ctrl->value)
566
			data = reg_set(client, MT9V022_READ_MODE, 0x20);
567
		else
568
			data = reg_clear(client, MT9V022_READ_MODE, 0x20);
569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588
		if (data < 0)
			return -EIO;
		break;
	case V4L2_CID_GAIN:
		/* mt9v022 has minimum == default */
		if (ctrl->value > qctrl->maximum || ctrl->value < qctrl->minimum)
			return -EINVAL;
		else {
			unsigned long range = qctrl->maximum - qctrl->minimum;
			/* Datasheet says 16 to 64. autogain only works properly
			 * after setting gain to maximum 14. Larger values
			 * produce "white fly" noise effect. On the whole,
			 * manually setting analog gain does no good. */
			unsigned long gain = ((ctrl->value - qctrl->minimum) *
					      10 + range / 2) / range + 4;
			if (gain >= 32)
				gain &= ~1;
			/* The user wants to set gain manually, hope, she
			 * knows, what she's doing... Switch AGC off. */

589
			if (reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x2) < 0)
590 591 592
				return -EIO;

			dev_info(&icd->dev, "Setting gain from %d to %lu\n",
593 594
				 reg_read(client, MT9V022_ANALOG_GAIN), gain);
			if (reg_write(client, MT9V022_ANALOG_GAIN, gain) < 0)
595 596 597 598 599 600 601 602 603 604 605 606 607 608 609
				return -EIO;
			icd->gain = ctrl->value;
		}
		break;
	case V4L2_CID_EXPOSURE:
		/* mt9v022 has maximum == default */
		if (ctrl->value > qctrl->maximum || ctrl->value < qctrl->minimum)
			return -EINVAL;
		else {
			unsigned long range = qctrl->maximum - qctrl->minimum;
			unsigned long shutter = ((ctrl->value - qctrl->minimum) *
						 479 + range / 2) / range + 1;
			/* The user wants to set shutter width manually, hope,
			 * she knows, what she's doing... Switch AEC off. */

610
			if (reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x1) < 0)
611 612 613
				return -EIO;

			dev_dbg(&icd->dev, "Shutter width from %d to %lu\n",
614
				reg_read(client, MT9V022_TOTAL_SHUTTER_WIDTH),
615
				shutter);
616
			if (reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH,
617 618 619 620 621 622 623
				      shutter) < 0)
				return -EIO;
			icd->exposure = ctrl->value;
		}
		break;
	case V4L2_CID_AUTOGAIN:
		if (ctrl->value)
624
			data = reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x2);
625
		else
626
			data = reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x2);
627 628 629 630 631
		if (data < 0)
			return -EIO;
		break;
	case V4L2_CID_EXPOSURE_AUTO:
		if (ctrl->value)
632
			data = reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x1);
633
		else
634
			data = reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x1);
635 636 637 638 639 640 641 642 643
		if (data < 0)
			return -EIO;
		break;
	}
	return 0;
}

/* Interface active, can use i2c. If it fails, it can indeed mean, that
 * this wasn't our capture interface, so, we wait for the right one */
644 645
static int mt9v022_video_probe(struct soc_camera_device *icd,
			       struct i2c_client *client)
646
{
647 648
	struct mt9v022 *mt9v022 = i2c_get_clientdata(client);
	struct soc_camera_link *icl = to_soc_camera_link(icd);
649 650
	s32 data;
	int ret;
651
	unsigned long flags;
652 653 654 655 656

	if (!icd->dev.parent ||
	    to_soc_camera_host(icd->dev.parent)->nr != icd->iface)
		return -ENODEV;

657 658 659 660 661
	/* Switch master clock on */
	ret = soc_camera_video_start(icd, &client->dev);
	if (ret)
		return ret;

662
	/* Read out the chip version register */
663
	data = reg_read(client, MT9V022_CHIP_VERSION);
664 665 666 667 668 669 670 671 672 673

	/* must be 0x1311 or 0x1313 */
	if (data != 0x1311 && data != 0x1313) {
		ret = -ENODEV;
		dev_info(&icd->dev, "No MT9V022 detected, ID register 0x%x\n",
			 data);
		goto ei2c;
	}

	/* Soft reset */
674
	ret = reg_write(client, MT9V022_RESET, 1);
675 676 677 678
	if (ret < 0)
		goto ei2c;
	/* 15 clock cycles */
	udelay(200);
679
	if (reg_read(client, MT9V022_RESET)) {
680
		dev_err(&icd->dev, "Resetting MT9V022 failed!\n");
681 682
		if (ret > 0)
			ret = -EIO;
683 684 685 686 687 688
		goto ei2c;
	}

	/* Set monochrome or colour sensor type */
	if (sensor_type && (!strcmp("colour", sensor_type) ||
			    !strcmp("color", sensor_type))) {
689
		ret = reg_write(client, MT9V022_PIXEL_OPERATION_MODE, 4 | 0x11);
690
		mt9v022->model = V4L2_IDENT_MT9V022IX7ATC;
691
		icd->formats = mt9v022_colour_formats;
692
	} else {
693
		ret = reg_write(client, MT9V022_PIXEL_OPERATION_MODE, 0x11);
694
		mt9v022->model = V4L2_IDENT_MT9V022IX7ATM;
695
		icd->formats = mt9v022_monochrome_formats;
696 697
	}

698
	if (ret < 0)
699
		goto ei2c;
700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720

	icd->num_formats = 0;

	/*
	 * This is a 10bit sensor, so by default we only allow 10bit.
	 * The platform may support different bus widths due to
	 * different routing of the data lines.
	 */
	if (icl->query_bus_param)
		flags = icl->query_bus_param(icl);
	else
		flags = SOCAM_DATAWIDTH_10;

	if (flags & SOCAM_DATAWIDTH_10)
		icd->num_formats++;
	else
		icd->formats++;

	if (flags & SOCAM_DATAWIDTH_8)
		icd->num_formats++;

721 722 723 724 725
	dev_info(&icd->dev, "Detected a MT9V022 chip ID %x, %s sensor\n",
		 data, mt9v022->model == V4L2_IDENT_MT9V022IX7ATM ?
		 "monochrome" : "colour");

ei2c:
726 727
	soc_camera_video_stop(icd);

728 729 730 731 732
	return ret;
}

static void mt9v022_video_remove(struct soc_camera_device *icd)
{
733 734
	struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
	struct soc_camera_link *icl = to_soc_camera_link(icd);
735

736
	dev_dbg(&icd->dev, "Video %x removed: %p, %p\n", client->addr,
737
		icd->dev.parent, icd->vdev);
738 739
	if (icl->free_bus)
		icl->free_bus(icl);
740 741
}

742 743
static int mt9v022_probe(struct i2c_client *client,
			 const struct i2c_device_id *did)
744 745
{
	struct mt9v022 *mt9v022;
746
	struct soc_camera_device *icd = client->dev.platform_data;
747
	struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
748
	struct soc_camera_link *icl;
749 750
	int ret;

751 752 753 754 755 756
	if (!icd) {
		dev_err(&client->dev, "MT9V022: missing soc-camera data!\n");
		return -EINVAL;
	}

	icl = to_soc_camera_link(icd);
757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785
	if (!icl) {
		dev_err(&client->dev, "MT9V022 driver needs platform data\n");
		return -EINVAL;
	}

	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) {
		dev_warn(&adapter->dev,
			 "I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n");
		return -EIO;
	}

	mt9v022 = kzalloc(sizeof(struct mt9v022), GFP_KERNEL);
	if (!mt9v022)
		return -ENOMEM;

	mt9v022->chip_control = MT9V022_CHIP_CONTROL_DEFAULT;
	i2c_set_clientdata(client, mt9v022);

	icd->ops	= &mt9v022_ops;
	icd->x_min	= 1;
	icd->y_min	= 4;
	icd->x_current	= 1;
	icd->y_current	= 4;
	icd->width_min	= 48;
	icd->width_max	= 752;
	icd->height_min	= 32;
	icd->height_max	= 480;
	icd->y_skip_top	= 1;

786 787 788 789 790 791
	ret = mt9v022_video_probe(icd, client);
	if (ret) {
		icd->ops = NULL;
		i2c_set_clientdata(client, NULL);
		kfree(mt9v022);
	}
792 793 794 795 796 797 798

	return ret;
}

static int mt9v022_remove(struct i2c_client *client)
{
	struct mt9v022 *mt9v022 = i2c_get_clientdata(client);
799
	struct soc_camera_device *icd = client->dev.platform_data;
800

801 802 803 804
	icd->ops = NULL;
	mt9v022_video_remove(icd);
	i2c_set_clientdata(client, NULL);
	client->driver = NULL;
805 806 807 808
	kfree(mt9v022);

	return 0;
}
809 810 811 812 813 814
static const struct i2c_device_id mt9v022_id[] = {
	{ "mt9v022", 0 },
	{ }
};
MODULE_DEVICE_TABLE(i2c, mt9v022_id);

815 816 817 818 819 820
static struct i2c_driver mt9v022_i2c_driver = {
	.driver = {
		.name = "mt9v022",
	},
	.probe		= mt9v022_probe,
	.remove		= mt9v022_remove,
821
	.id_table	= mt9v022_id,
822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839
};

static int __init mt9v022_mod_init(void)
{
	return i2c_add_driver(&mt9v022_i2c_driver);
}

static void __exit mt9v022_mod_exit(void)
{
	i2c_del_driver(&mt9v022_i2c_driver);
}

module_init(mt9v022_mod_init);
module_exit(mt9v022_mod_exit);

MODULE_DESCRIPTION("Micron MT9V022 Camera driver");
MODULE_AUTHOR("Guennadi Liakhovetski <kernel@pengutronix.de>");
MODULE_LICENSE("GPL");