mt9m111.c 25.6 KB
Newer Older
1
/*
2
 * Driver for MT9M111/MT9M112 CMOS Image Sensor from Micron
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
 *
 * Copyright (C) 2008, Robert Jarzmik <robert.jarzmik@free.fr>
 *
 * 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/log2.h>
#include <linux/gpio.h>
#include <linux/delay.h>

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

/*
22
 * mt9m111 and mt9m112 i2c address is 0x5d or 0x48 (depending on SAddr pin)
23 24 25 26 27 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 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
 * The platform has to define i2c_board_info and call i2c_register_board_info()
 */

/* mt9m111: Sensor register addresses */
#define MT9M111_CHIP_VERSION		0x000
#define MT9M111_ROW_START		0x001
#define MT9M111_COLUMN_START		0x002
#define MT9M111_WINDOW_HEIGHT		0x003
#define MT9M111_WINDOW_WIDTH		0x004
#define MT9M111_HORIZONTAL_BLANKING_B	0x005
#define MT9M111_VERTICAL_BLANKING_B	0x006
#define MT9M111_HORIZONTAL_BLANKING_A	0x007
#define MT9M111_VERTICAL_BLANKING_A	0x008
#define MT9M111_SHUTTER_WIDTH		0x009
#define MT9M111_ROW_SPEED		0x00a
#define MT9M111_EXTRA_DELAY		0x00b
#define MT9M111_SHUTTER_DELAY		0x00c
#define MT9M111_RESET			0x00d
#define MT9M111_READ_MODE_B		0x020
#define MT9M111_READ_MODE_A		0x021
#define MT9M111_FLASH_CONTROL		0x023
#define MT9M111_GREEN1_GAIN		0x02b
#define MT9M111_BLUE_GAIN		0x02c
#define MT9M111_RED_GAIN		0x02d
#define MT9M111_GREEN2_GAIN		0x02e
#define MT9M111_GLOBAL_GAIN		0x02f
#define MT9M111_CONTEXT_CONTROL		0x0c8
#define MT9M111_PAGE_MAP		0x0f0
#define MT9M111_BYTE_WISE_ADDR		0x0f1

#define MT9M111_RESET_SYNC_CHANGES	(1 << 15)
#define MT9M111_RESET_RESTART_BAD_FRAME	(1 << 9)
#define MT9M111_RESET_SHOW_BAD_FRAMES	(1 << 8)
#define MT9M111_RESET_RESET_SOC		(1 << 5)
#define MT9M111_RESET_OUTPUT_DISABLE	(1 << 4)
#define MT9M111_RESET_CHIP_ENABLE	(1 << 3)
#define MT9M111_RESET_ANALOG_STANDBY	(1 << 2)
#define MT9M111_RESET_RESTART_FRAME	(1 << 1)
#define MT9M111_RESET_RESET_MODE	(1 << 0)

#define MT9M111_RMB_MIRROR_COLS		(1 << 1)
#define MT9M111_RMB_MIRROR_ROWS		(1 << 0)
#define MT9M111_CTXT_CTRL_RESTART	(1 << 15)
#define MT9M111_CTXT_CTRL_DEFECTCOR_B	(1 << 12)
#define MT9M111_CTXT_CTRL_RESIZE_B	(1 << 10)
#define MT9M111_CTXT_CTRL_CTRL2_B	(1 << 9)
#define MT9M111_CTXT_CTRL_GAMMA_B	(1 << 8)
#define MT9M111_CTXT_CTRL_XENON_EN	(1 << 7)
#define MT9M111_CTXT_CTRL_READ_MODE_B	(1 << 3)
#define MT9M111_CTXT_CTRL_LED_FLASH_EN	(1 << 2)
#define MT9M111_CTXT_CTRL_VBLANK_SEL_B	(1 << 1)
#define MT9M111_CTXT_CTRL_HBLANK_SEL_B	(1 << 0)
/*
 * mt9m111: Colorpipe register addresses (0x100..0x1ff)
 */
#define MT9M111_OPER_MODE_CTRL		0x106
#define MT9M111_OUTPUT_FORMAT_CTRL	0x108
#define MT9M111_REDUCER_XZOOM_B		0x1a0
#define MT9M111_REDUCER_XSIZE_B		0x1a1
#define MT9M111_REDUCER_YZOOM_B		0x1a3
#define MT9M111_REDUCER_YSIZE_B		0x1a4
#define MT9M111_REDUCER_XZOOM_A		0x1a6
#define MT9M111_REDUCER_XSIZE_A		0x1a7
#define MT9M111_REDUCER_YZOOM_A		0x1a9
#define MT9M111_REDUCER_YSIZE_A		0x1aa

#define MT9M111_OUTPUT_FORMAT_CTRL2_A	0x13a
#define MT9M111_OUTPUT_FORMAT_CTRL2_B	0x19b

#define MT9M111_OPMODE_AUTOEXPO_EN	(1 << 14)
93
#define MT9M111_OPMODE_AUTOWHITEBAL_EN	(1 << 1)
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115

#define MT9M111_OUTFMT_PROCESSED_BAYER	(1 << 14)
#define MT9M111_OUTFMT_BYPASS_IFP	(1 << 10)
#define MT9M111_OUTFMT_INV_PIX_CLOCK	(1 << 9)
#define MT9M111_OUTFMT_RGB		(1 << 8)
#define MT9M111_OUTFMT_RGB565		(0x0 << 6)
#define MT9M111_OUTFMT_RGB555		(0x1 << 6)
#define MT9M111_OUTFMT_RGB444x		(0x2 << 6)
#define MT9M111_OUTFMT_RGBx444		(0x3 << 6)
#define MT9M111_OUTFMT_TST_RAMP_OFF	(0x0 << 4)
#define MT9M111_OUTFMT_TST_RAMP_COL	(0x1 << 4)
#define MT9M111_OUTFMT_TST_RAMP_ROW	(0x2 << 4)
#define MT9M111_OUTFMT_TST_RAMP_FRAME	(0x3 << 4)
#define MT9M111_OUTFMT_SHIFT_3_UP	(1 << 3)
#define MT9M111_OUTFMT_AVG_CHROMA	(1 << 2)
#define MT9M111_OUTFMT_SWAP_YCbCr_C_Y	(1 << 1)
#define MT9M111_OUTFMT_SWAP_RGB_EVEN	(1 << 1)
#define MT9M111_OUTFMT_SWAP_YCbCr_Cb_Cr	(1 << 0)
/*
 * mt9m111: Camera control register addresses (0x200..0x2ff not implemented)
 */

116 117 118 119
#define reg_read(reg) mt9m111_reg_read(client, MT9M111_##reg)
#define reg_write(reg, val) mt9m111_reg_write(client, MT9M111_##reg, (val))
#define reg_set(reg, val) mt9m111_reg_set(client, MT9M111_##reg, (val))
#define reg_clear(reg, val) mt9m111_reg_clear(client, MT9M111_##reg, (val))
120 121 122 123 124 125 126 127 128 129 130

#define MT9M111_MIN_DARK_ROWS	8
#define MT9M111_MIN_DARK_COLS	24
#define MT9M111_MAX_HEIGHT	1024
#define MT9M111_MAX_WIDTH	1280

#define COL_FMT(_name, _depth, _fourcc, _colorspace) \
	{ .name = _name, .depth = _depth, .fourcc = _fourcc, \
	.colorspace = _colorspace }
#define RGB_FMT(_name, _depth, _fourcc) \
	COL_FMT(_name, _depth, _fourcc, V4L2_COLORSPACE_SRGB)
131 132
#define JPG_FMT(_name, _depth, _fourcc) \
	COL_FMT(_name, _depth, _fourcc, V4L2_COLORSPACE_JPEG)
133 134

static const struct soc_camera_data_format mt9m111_colour_formats[] = {
135 136 137 138
	JPG_FMT("CbYCrY 16 bit", 16, V4L2_PIX_FMT_UYVY),
	JPG_FMT("CrYCbY 16 bit", 16, V4L2_PIX_FMT_VYUY),
	JPG_FMT("YCbYCr 16 bit", 16, V4L2_PIX_FMT_YUYV),
	JPG_FMT("YCrYCb 16 bit", 16, V4L2_PIX_FMT_YVYU),
139 140 141 142 143 144 145 146 147 148 149 150
	RGB_FMT("RGB 565", 16, V4L2_PIX_FMT_RGB565),
	RGB_FMT("RGB 555", 16, V4L2_PIX_FMT_RGB555),
	RGB_FMT("Bayer (sRGB) 10 bit", 10, V4L2_PIX_FMT_SBGGR16),
	RGB_FMT("Bayer (sRGB) 8 bit", 8, V4L2_PIX_FMT_SBGGR8),
};

enum mt9m111_context {
	HIGHPOWER = 0,
	LOWPOWER,
};

struct mt9m111 {
151
	struct v4l2_subdev subdev;
152
	int model;	/* V4L2_IDENT_MT9M11x* codes from v4l2-chip-ident.h */
153
	enum mt9m111_context context;
154
	struct v4l2_rect rect;
155 156 157 158 159 160 161 162 163 164
	u32 pixfmt;
	unsigned char autoexposure;
	unsigned char datawidth;
	unsigned int powered:1;
	unsigned int hflip:1;
	unsigned int vflip:1;
	unsigned int swap_rgb_even_odd:1;
	unsigned int swap_rgb_red_blue:1;
	unsigned int swap_yuv_y_chromas:1;
	unsigned int swap_yuv_cb_cr:1;
165
	unsigned int autowhitebalance:1;
166 167
};

168 169 170 171 172
static struct mt9m111 *to_mt9m111(const struct i2c_client *client)
{
	return container_of(i2c_get_clientdata(client), struct mt9m111, subdev);
}

173 174 175 176 177 178 179 180 181 182 183 184 185
static int reg_page_map_set(struct i2c_client *client, const u16 reg)
{
	int ret;
	u16 page;
	static int lastpage = -1;	/* PageMap cache value */

	page = (reg >> 8);
	if (page == lastpage)
		return 0;
	if (page > 2)
		return -EINVAL;

	ret = i2c_smbus_write_word_data(client, MT9M111_PAGE_MAP, swab16(page));
186
	if (!ret)
187 188 189 190
		lastpage = page;
	return ret;
}

191
static int mt9m111_reg_read(struct i2c_client *client, const u16 reg)
192 193 194 195 196 197 198
{
	int ret;

	ret = reg_page_map_set(client, reg);
	if (!ret)
		ret = swab16(i2c_smbus_read_word_data(client, (reg & 0xff)));

199
	dev_dbg(&client->dev, "read  reg.%03x -> %04x\n", reg, ret);
200 201 202
	return ret;
}

203
static int mt9m111_reg_write(struct i2c_client *client, const u16 reg,
204 205 206 207 208
			     const u16 data)
{
	int ret;

	ret = reg_page_map_set(client, reg);
209
	if (!ret)
210
		ret = i2c_smbus_write_word_data(client, reg & 0xff,
211
						swab16(data));
212
	dev_dbg(&client->dev, "write reg.%03x = %04x -> %d\n", reg, data, ret);
213 214 215
	return ret;
}

216
static int mt9m111_reg_set(struct i2c_client *client, const u16 reg,
217 218 219 220
			   const u16 data)
{
	int ret;

221
	ret = mt9m111_reg_read(client, reg);
222
	if (ret >= 0)
223
		ret = mt9m111_reg_write(client, reg, ret | data);
224 225 226
	return ret;
}

227
static int mt9m111_reg_clear(struct i2c_client *client, const u16 reg,
228 229 230 231
			     const u16 data)
{
	int ret;

232 233
	ret = mt9m111_reg_read(client, reg);
	return mt9m111_reg_write(client, reg, ret & ~data);
234 235
}

236
static int mt9m111_set_context(struct i2c_client *client,
237 238 239 240 241 242 243 244 245 246 247 248 249 250 251
			       enum mt9m111_context ctxt)
{
	int valB = MT9M111_CTXT_CTRL_RESTART | MT9M111_CTXT_CTRL_DEFECTCOR_B
		| MT9M111_CTXT_CTRL_RESIZE_B | MT9M111_CTXT_CTRL_CTRL2_B
		| MT9M111_CTXT_CTRL_GAMMA_B | MT9M111_CTXT_CTRL_READ_MODE_B
		| MT9M111_CTXT_CTRL_VBLANK_SEL_B
		| MT9M111_CTXT_CTRL_HBLANK_SEL_B;
	int valA = MT9M111_CTXT_CTRL_RESTART;

	if (ctxt == HIGHPOWER)
		return reg_write(CONTEXT_CONTROL, valB);
	else
		return reg_write(CONTEXT_CONTROL, valA);
}

252
static int mt9m111_setup_rect(struct i2c_client *client,
253
			      struct v4l2_rect *rect)
254
{
255
	struct mt9m111 *mt9m111 = to_mt9m111(client);
256
	int ret, is_raw_format;
257 258
	int width = rect->width;
	int height = rect->height;
259 260 261 262 263 264 265

	if ((mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR8)
	    || (mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR16))
		is_raw_format = 1;
	else
		is_raw_format = 0;

266
	ret = reg_write(COLUMN_START, rect->left);
267
	if (!ret)
268
		ret = reg_write(ROW_START, rect->top);
269 270

	if (is_raw_format) {
271
		if (!ret)
272
			ret = reg_write(WINDOW_WIDTH, width);
273
		if (!ret)
274 275
			ret = reg_write(WINDOW_HEIGHT, height);
	} else {
276
		if (!ret)
277
			ret = reg_write(REDUCER_XZOOM_B, MT9M111_MAX_WIDTH);
278
		if (!ret)
279
			ret = reg_write(REDUCER_YZOOM_B, MT9M111_MAX_HEIGHT);
280
		if (!ret)
281
			ret = reg_write(REDUCER_XSIZE_B, width);
282
		if (!ret)
283
			ret = reg_write(REDUCER_YSIZE_B, height);
284
		if (!ret)
285
			ret = reg_write(REDUCER_XZOOM_A, MT9M111_MAX_WIDTH);
286
		if (!ret)
287
			ret = reg_write(REDUCER_YZOOM_A, MT9M111_MAX_HEIGHT);
288
		if (!ret)
289
			ret = reg_write(REDUCER_XSIZE_A, width);
290
		if (!ret)
291 292 293 294 295 296
			ret = reg_write(REDUCER_YSIZE_A, height);
	}

	return ret;
}

297
static int mt9m111_setup_pixfmt(struct i2c_client *client, u16 outfmt)
298 299 300 301
{
	int ret;

	ret = reg_write(OUTPUT_FORMAT_CTRL2_A, outfmt);
302
	if (!ret)
303 304 305 306
		ret = reg_write(OUTPUT_FORMAT_CTRL2_B, outfmt);
	return ret;
}

307
static int mt9m111_setfmt_bayer8(struct i2c_client *client)
308
{
309
	return mt9m111_setup_pixfmt(client, MT9M111_OUTFMT_PROCESSED_BAYER);
310 311
}

312
static int mt9m111_setfmt_bayer10(struct i2c_client *client)
313
{
314
	return mt9m111_setup_pixfmt(client, MT9M111_OUTFMT_BYPASS_IFP);
315 316
}

317
static int mt9m111_setfmt_rgb565(struct i2c_client *client)
318
{
319
	struct mt9m111 *mt9m111 = to_mt9m111(client);
320 321 322 323 324 325 326 327
	int val = 0;

	if (mt9m111->swap_rgb_red_blue)
		val |= MT9M111_OUTFMT_SWAP_YCbCr_Cb_Cr;
	if (mt9m111->swap_rgb_even_odd)
		val |= MT9M111_OUTFMT_SWAP_RGB_EVEN;
	val |= MT9M111_OUTFMT_RGB | MT9M111_OUTFMT_RGB565;

328
	return mt9m111_setup_pixfmt(client, val);
329 330
}

331
static int mt9m111_setfmt_rgb555(struct i2c_client *client)
332
{
333
	struct mt9m111 *mt9m111 = to_mt9m111(client);
334 335 336 337 338 339 340 341
	int val = 0;

	if (mt9m111->swap_rgb_red_blue)
		val |= MT9M111_OUTFMT_SWAP_YCbCr_Cb_Cr;
	if (mt9m111->swap_rgb_even_odd)
		val |= MT9M111_OUTFMT_SWAP_RGB_EVEN;
	val |= MT9M111_OUTFMT_RGB | MT9M111_OUTFMT_RGB555;

342
	return mt9m111_setup_pixfmt(client, val);
343 344
}

345
static int mt9m111_setfmt_yuv(struct i2c_client *client)
346
{
347
	struct mt9m111 *mt9m111 = to_mt9m111(client);
348 349 350 351 352 353 354
	int val = 0;

	if (mt9m111->swap_yuv_cb_cr)
		val |= MT9M111_OUTFMT_SWAP_YCbCr_Cb_Cr;
	if (mt9m111->swap_yuv_y_chromas)
		val |= MT9M111_OUTFMT_SWAP_YCbCr_C_Y;

355
	return mt9m111_setup_pixfmt(client, val);
356 357
}

358
static int mt9m111_enable(struct i2c_client *client)
359
{
360
	struct mt9m111 *mt9m111 = to_mt9m111(client);
361 362 363
	int ret;

	ret = reg_set(RESET, MT9M111_RESET_CHIP_ENABLE);
364
	if (!ret)
365 366 367 368
		mt9m111->powered = 1;
	return ret;
}

369
static int mt9m111_reset(struct i2c_client *client)
370 371 372 373
{
	int ret;

	ret = reg_set(RESET, MT9M111_RESET_RESET_MODE);
374
	if (!ret)
375
		ret = reg_set(RESET, MT9M111_RESET_RESET_SOC);
376
	if (!ret)
377 378
		ret = reg_clear(RESET, MT9M111_RESET_RESET_MODE
				| MT9M111_RESET_RESET_SOC);
379

380 381 382 383 384
	return ret;
}

static unsigned long mt9m111_query_bus_param(struct soc_camera_device *icd)
{
385
	struct soc_camera_link *icl = to_soc_camera_link(icd);
386
	unsigned long flags = SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |
387
		SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH |
388
		SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8;
389 390

	return soc_camera_apply_sensor_flags(icl, flags);
391 392 393 394 395 396 397
}

static int mt9m111_set_bus_param(struct soc_camera_device *icd, unsigned long f)
{
	return 0;
}

398
static int mt9m111_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
399
{
400 401
	struct v4l2_rect *rect = &a->c;
	struct i2c_client *client = sd->priv;
402
	struct mt9m111 *mt9m111 = to_mt9m111(client);
403 404
	int ret;

405
	dev_dbg(&client->dev, "%s left=%d, top=%d, width=%d, height=%d\n",
406 407 408
		__func__, rect->left, rect->top, rect->width,
		rect->height);

409
	ret = mt9m111_setup_rect(client, rect);
410 411 412 413 414
	if (!ret)
		mt9m111->rect = *rect;
	return ret;
}

415
static int mt9m111_set_pixfmt(struct i2c_client *client, u32 pixfmt)
416
{
417
	struct mt9m111 *mt9m111 = to_mt9m111(client);
418
	int ret;
419 420 421

	switch (pixfmt) {
	case V4L2_PIX_FMT_SBGGR8:
422
		ret = mt9m111_setfmt_bayer8(client);
423 424
		break;
	case V4L2_PIX_FMT_SBGGR16:
425
		ret = mt9m111_setfmt_bayer10(client);
426 427
		break;
	case V4L2_PIX_FMT_RGB555:
428
		ret = mt9m111_setfmt_rgb555(client);
429 430
		break;
	case V4L2_PIX_FMT_RGB565:
431
		ret = mt9m111_setfmt_rgb565(client);
432
		break;
433 434 435
	case V4L2_PIX_FMT_UYVY:
		mt9m111->swap_yuv_y_chromas = 0;
		mt9m111->swap_yuv_cb_cr = 0;
436
		ret = mt9m111_setfmt_yuv(client);
437 438 439 440
		break;
	case V4L2_PIX_FMT_VYUY:
		mt9m111->swap_yuv_y_chromas = 0;
		mt9m111->swap_yuv_cb_cr = 1;
441
		ret = mt9m111_setfmt_yuv(client);
442
		break;
443
	case V4L2_PIX_FMT_YUYV:
444 445
		mt9m111->swap_yuv_y_chromas = 1;
		mt9m111->swap_yuv_cb_cr = 0;
446
		ret = mt9m111_setfmt_yuv(client);
447 448 449 450
		break;
	case V4L2_PIX_FMT_YVYU:
		mt9m111->swap_yuv_y_chromas = 1;
		mt9m111->swap_yuv_cb_cr = 1;
451
		ret = mt9m111_setfmt_yuv(client);
452 453
		break;
	default:
454
		dev_err(&client->dev, "Pixel format not handled : %x\n", pixfmt);
455 456 457
		ret = -EINVAL;
	}

458
	if (!ret)
459 460 461 462 463
		mt9m111->pixfmt = pixfmt;

	return ret;
}

464
static int mt9m111_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
465
{
466 467
	struct i2c_client *client = sd->priv;
	struct mt9m111 *mt9m111 = to_mt9m111(client);
468 469 470 471 472 473 474
	struct v4l2_pix_format *pix = &f->fmt.pix;
	struct v4l2_rect rect = {
		.left	= mt9m111->rect.left,
		.top	= mt9m111->rect.top,
		.width	= pix->width,
		.height	= pix->height,
	};
475
	int ret;
476

477
	dev_dbg(&client->dev, "%s fmt=%x left=%d, top=%d, width=%d, height=%d\n",
478 479
		__func__, pix->pixelformat, rect.left, rect.top, rect.width,
		rect.height);
480

481
	ret = mt9m111_setup_rect(client, &rect);
482
	if (!ret)
483
		ret = mt9m111_set_pixfmt(client, pix->pixelformat);
484
	if (!ret)
485
		mt9m111->rect = rect;
486
	return ret;
487 488
}

489
static int mt9m111_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
490
{
491 492 493 494 495 496
	struct v4l2_pix_format *pix = &f->fmt.pix;

	if (pix->height > MT9M111_MAX_HEIGHT)
		pix->height = MT9M111_MAX_HEIGHT;
	if (pix->width > MT9M111_MAX_WIDTH)
		pix->width = MT9M111_MAX_WIDTH;
497 498 499 500

	return 0;
}

501 502
static int mt9m111_g_chip_ident(struct v4l2_subdev *sd,
				struct v4l2_dbg_chip_ident *id)
503
{
504 505
	struct i2c_client *client = sd->priv;
	struct mt9m111 *mt9m111 = to_mt9m111(client);
506

507
	if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
508 509
		return -EINVAL;

510
	if (id->match.addr != client->addr)
511 512 513 514 515 516 517 518 519
		return -ENODEV;

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

	return 0;
}

#ifdef CONFIG_VIDEO_ADV_DEBUG
520 521
static int mt9m111_g_register(struct v4l2_subdev *sd,
			      struct v4l2_dbg_register *reg)
522
{
523
	struct i2c_client *client = sd->priv;
524 525
	int val;

526
	if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff)
527
		return -EINVAL;
528
	if (reg->match.addr != client->addr)
529 530
		return -ENODEV;

531
	val = mt9m111_reg_read(client, reg->reg);
532
	reg->size = 2;
533 534 535 536 537 538 539 540
	reg->val = (u64)val;

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

	return 0;
}

541 542
static int mt9m111_s_register(struct v4l2_subdev *sd,
			      struct v4l2_dbg_register *reg)
543
{
544
	struct i2c_client *client = sd->priv;
545

546
	if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff)
547 548
		return -EINVAL;

549
	if (reg->match.addr != client->addr)
550 551
		return -ENODEV;

552
	if (mt9m111_reg_write(client, reg->reg, reg->val) < 0)
553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609
		return -EIO;

	return 0;
}
#endif

static const struct v4l2_queryctrl mt9m111_controls[] = {
	{
		.id		= V4L2_CID_VFLIP,
		.type		= V4L2_CTRL_TYPE_BOOLEAN,
		.name		= "Flip Verticaly",
		.minimum	= 0,
		.maximum	= 1,
		.step		= 1,
		.default_value	= 0,
	}, {
		.id		= V4L2_CID_HFLIP,
		.type		= V4L2_CTRL_TYPE_BOOLEAN,
		.name		= "Flip Horizontaly",
		.minimum	= 0,
		.maximum	= 1,
		.step		= 1,
		.default_value	= 0,
	}, {	/* gain = 1/32*val (=>gain=1 if val==32) */
		.id		= V4L2_CID_GAIN,
		.type		= V4L2_CTRL_TYPE_INTEGER,
		.name		= "Gain",
		.minimum	= 0,
		.maximum	= 63 * 2 * 2,
		.step		= 1,
		.default_value	= 32,
		.flags		= V4L2_CTRL_FLAG_SLIDER,
	}, {
		.id		= V4L2_CID_EXPOSURE_AUTO,
		.type		= V4L2_CTRL_TYPE_BOOLEAN,
		.name		= "Auto Exposure",
		.minimum	= 0,
		.maximum	= 1,
		.step		= 1,
		.default_value	= 1,
	}
};

static int mt9m111_resume(struct soc_camera_device *icd);
static int mt9m111_init(struct soc_camera_device *icd);
static int mt9m111_release(struct soc_camera_device *icd);

static struct soc_camera_ops mt9m111_ops = {
	.init			= mt9m111_init,
	.resume			= mt9m111_resume,
	.release		= mt9m111_release,
	.query_bus_param	= mt9m111_query_bus_param,
	.set_bus_param		= mt9m111_set_bus_param,
	.controls		= mt9m111_controls,
	.num_controls		= ARRAY_SIZE(mt9m111_controls),
};

610
static int mt9m111_set_flip(struct i2c_client *client, int flip, int mask)
611
{
612
	struct mt9m111 *mt9m111 = to_mt9m111(client);
613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629
	int ret;

	if (mt9m111->context == HIGHPOWER) {
		if (flip)
			ret = reg_set(READ_MODE_B, mask);
		else
			ret = reg_clear(READ_MODE_B, mask);
	} else {
		if (flip)
			ret = reg_set(READ_MODE_A, mask);
		else
			ret = reg_clear(READ_MODE_A, mask);
	}

	return ret;
}

630
static int mt9m111_get_global_gain(struct i2c_client *client)
631
{
632
	int data;
633 634 635

	data = reg_read(GLOBAL_GAIN);
	if (data >= 0)
636 637 638
		return (data & 0x2f) * (1 << ((data >> 10) & 1)) *
			(1 << ((data >> 9) & 1));
	return data;
639
}
640

641
static int mt9m111_set_global_gain(struct i2c_client *client, int gain)
642
{
643
	struct soc_camera_device *icd = client->dev.platform_data;
644 645 646 647 648 649 650 651 652
	u16 val;

	if (gain > 63 * 2 * 2)
		return -EINVAL;

	icd->gain = gain;
	if ((gain >= 64 * 2) && (gain < 63 * 2 * 2))
		val = (1 << 10) | (1 << 9) | (gain / 4);
	else if ((gain >= 64) && (gain < 64 * 2))
653
		val = (1 << 9) | (gain / 2);
654 655 656 657 658 659
	else
		val = gain;

	return reg_write(GLOBAL_GAIN, val);
}

660
static int mt9m111_set_autoexposure(struct i2c_client *client, int on)
661
{
662
	struct mt9m111 *mt9m111 = to_mt9m111(client);
663 664 665 666 667 668 669
	int ret;

	if (on)
		ret = reg_set(OPER_MODE_CTRL, MT9M111_OPMODE_AUTOEXPO_EN);
	else
		ret = reg_clear(OPER_MODE_CTRL, MT9M111_OPMODE_AUTOEXPO_EN);

670
	if (!ret)
671 672 673 674
		mt9m111->autoexposure = on;

	return ret;
}
675

676
static int mt9m111_set_autowhitebalance(struct i2c_client *client, int on)
677
{
678
	struct mt9m111 *mt9m111 = to_mt9m111(client);
679 680 681 682 683 684 685 686 687 688 689 690 691
	int ret;

	if (on)
		ret = reg_set(OPER_MODE_CTRL, MT9M111_OPMODE_AUTOWHITEBAL_EN);
	else
		ret = reg_clear(OPER_MODE_CTRL, MT9M111_OPMODE_AUTOWHITEBAL_EN);

	if (!ret)
		mt9m111->autowhitebalance = on;

	return ret;
}

692
static int mt9m111_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
693
{
694 695
	struct i2c_client *client = sd->priv;
	struct mt9m111 *mt9m111 = to_mt9m111(client);
696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719
	int data;

	switch (ctrl->id) {
	case V4L2_CID_VFLIP:
		if (mt9m111->context == HIGHPOWER)
			data = reg_read(READ_MODE_B);
		else
			data = reg_read(READ_MODE_A);

		if (data < 0)
			return -EIO;
		ctrl->value = !!(data & MT9M111_RMB_MIRROR_ROWS);
		break;
	case V4L2_CID_HFLIP:
		if (mt9m111->context == HIGHPOWER)
			data = reg_read(READ_MODE_B);
		else
			data = reg_read(READ_MODE_A);

		if (data < 0)
			return -EIO;
		ctrl->value = !!(data & MT9M111_RMB_MIRROR_COLS);
		break;
	case V4L2_CID_GAIN:
720
		data = mt9m111_get_global_gain(client);
721 722 723 724 725 726 727
		if (data < 0)
			return data;
		ctrl->value = data;
		break;
	case V4L2_CID_EXPOSURE_AUTO:
		ctrl->value = mt9m111->autoexposure;
		break;
728 729 730
	case V4L2_CID_AUTO_WHITE_BALANCE:
		ctrl->value = mt9m111->autowhitebalance;
		break;
731 732 733 734
	}
	return 0;
}

735
static int mt9m111_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
736
{
737 738
	struct i2c_client *client = sd->priv;
	struct mt9m111 *mt9m111 = to_mt9m111(client);
739
	const struct v4l2_queryctrl *qctrl;
740
	int ret;
741 742 743 744 745 746 747 748

	qctrl = soc_camera_find_qctrl(&mt9m111_ops, ctrl->id);
	if (!qctrl)
		return -EINVAL;

	switch (ctrl->id) {
	case V4L2_CID_VFLIP:
		mt9m111->vflip = ctrl->value;
749
		ret = mt9m111_set_flip(client, ctrl->value,
750 751 752 753
					MT9M111_RMB_MIRROR_ROWS);
		break;
	case V4L2_CID_HFLIP:
		mt9m111->hflip = ctrl->value;
754
		ret = mt9m111_set_flip(client, ctrl->value,
755 756 757
					MT9M111_RMB_MIRROR_COLS);
		break;
	case V4L2_CID_GAIN:
758
		ret = mt9m111_set_global_gain(client, ctrl->value);
759 760
		break;
	case V4L2_CID_EXPOSURE_AUTO:
761
		ret =  mt9m111_set_autoexposure(client, ctrl->value);
762
		break;
763
	case V4L2_CID_AUTO_WHITE_BALANCE:
764
		ret =  mt9m111_set_autowhitebalance(client, ctrl->value);
765
		break;
766 767 768 769
	default:
		ret = -EINVAL;
	}

770
	return ret;
771 772
}

773
static int mt9m111_restore_state(struct i2c_client *client)
774
{
775 776 777 778 779 780 781 782 783 784 785
	struct mt9m111 *mt9m111 = to_mt9m111(client);
	struct soc_camera_device *icd = client->dev.platform_data;

	mt9m111_set_context(client, mt9m111->context);
	mt9m111_set_pixfmt(client, mt9m111->pixfmt);
	mt9m111_setup_rect(client, &mt9m111->rect);
	mt9m111_set_flip(client, mt9m111->hflip, MT9M111_RMB_MIRROR_COLS);
	mt9m111_set_flip(client, mt9m111->vflip, MT9M111_RMB_MIRROR_ROWS);
	mt9m111_set_global_gain(client, icd->gain);
	mt9m111_set_autoexposure(client, mt9m111->autoexposure);
	mt9m111_set_autowhitebalance(client, mt9m111->autowhitebalance);
786 787 788 789 790
	return 0;
}

static int mt9m111_resume(struct soc_camera_device *icd)
{
791
	struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
792
	struct mt9m111 *mt9m111 = to_mt9m111(client);
793 794 795
	int ret = 0;

	if (mt9m111->powered) {
796
		ret = mt9m111_enable(client);
797
		if (!ret)
798
			ret = mt9m111_reset(client);
799
		if (!ret)
800
			ret = mt9m111_restore_state(client);
801 802 803 804 805 806
	}
	return ret;
}

static int mt9m111_init(struct soc_camera_device *icd)
{
807
	struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
808
	struct mt9m111 *mt9m111 = to_mt9m111(client);
809 810 811
	int ret;

	mt9m111->context = HIGHPOWER;
812
	ret = mt9m111_enable(client);
813
	if (!ret)
814
		ret = mt9m111_reset(client);
815
	if (!ret)
816
		ret = mt9m111_set_context(client, mt9m111->context);
817
	if (!ret)
818
		ret = mt9m111_set_autoexposure(client, mt9m111->autoexposure);
819
	if (ret)
820
		dev_err(&client->dev, "mt9m11x init failed: %d\n", ret);
821
	return ret;
822 823 824 825
}

static int mt9m111_release(struct soc_camera_device *icd)
{
826 827
	struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
	struct mt9m111 *mt9m111 = to_mt9m111(client);
828 829
	int ret;

830 831 832 833
	ret = reg_clear(RESET, MT9M111_RESET_CHIP_ENABLE);
	if (!ret)
		mt9m111->powered = 0;

834
	if (ret < 0)
835
		dev_err(&client->dev, "mt9m11x release failed: %d\n", ret);
836

837
	return ret;
838 839 840 841 842 843
}

/*
 * 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
 */
844 845
static int mt9m111_video_probe(struct soc_camera_device *icd,
			       struct i2c_client *client)
846
{
847
	struct mt9m111 *mt9m111 = to_mt9m111(client);
848 849 850 851 852 853 854 855 856 857 858
	s32 data;
	int ret;

	/*
	 * We must have a parent by now. And it cannot be a wrong one.
	 * So this entire test is completely redundant.
	 */
	if (!icd->dev.parent ||
	    to_soc_camera_host(icd->dev.parent)->nr != icd->iface)
		return -ENODEV;

859
	ret = mt9m111_enable(client);
860 861
	if (ret)
		goto ei2c;
862
	ret = mt9m111_reset(client);
863 864 865 866 867 868
	if (ret)
		goto ei2c;

	data = reg_read(CHIP_VERSION);

	switch (data) {
869
	case 0x143a: /* MT9M111 */
870
		mt9m111->model = V4L2_IDENT_MT9M111;
871 872 873
		break;
	case 0x148c: /* MT9M112 */
		mt9m111->model = V4L2_IDENT_MT9M112;
874 875 876
		break;
	default:
		ret = -ENODEV;
877
		dev_err(&client->dev,
878
			"No MT9M11x chip detected, register read %x\n", data);
879 880 881
		goto ei2c;
	}

882 883 884
	icd->formats = mt9m111_colour_formats;
	icd->num_formats = ARRAY_SIZE(mt9m111_colour_formats);

885
	dev_info(&client->dev, "Detected a MT9M11x chip ID %x\n", data);
886 887

	mt9m111->autoexposure = 1;
888
	mt9m111->autowhitebalance = 1;
889 890 891 892 893 894 895 896

	mt9m111->swap_rgb_even_odd = 1;
	mt9m111->swap_rgb_red_blue = 1;

ei2c:
	return ret;
}

897 898 899 900 901 902 903 904 905 906 907 908 909
static struct v4l2_subdev_core_ops mt9m111_subdev_core_ops = {
	.g_ctrl		= mt9m111_g_ctrl,
	.s_ctrl		= mt9m111_s_ctrl,
	.g_chip_ident	= mt9m111_g_chip_ident,
#ifdef CONFIG_VIDEO_ADV_DEBUG
	.g_register	= mt9m111_g_register,
	.s_register	= mt9m111_s_register,
#endif
};

static struct v4l2_subdev_video_ops mt9m111_subdev_video_ops = {
	.s_fmt		= mt9m111_s_fmt,
	.try_fmt	= mt9m111_try_fmt,
910
	.s_crop		= mt9m111_s_crop,
911 912 913 914 915 916 917
};

static struct v4l2_subdev_ops mt9m111_subdev_ops = {
	.core	= &mt9m111_subdev_core_ops,
	.video	= &mt9m111_subdev_video_ops,
};

918 919 920 921
static int mt9m111_probe(struct i2c_client *client,
			 const struct i2c_device_id *did)
{
	struct mt9m111 *mt9m111;
922
	struct soc_camera_device *icd = client->dev.platform_data;
923
	struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
924
	struct soc_camera_link *icl;
925 926
	int ret;

927 928 929 930 931 932
	if (!icd) {
		dev_err(&client->dev, "MT9M11x: missing soc-camera data!\n");
		return -EINVAL;
	}

	icl = to_soc_camera_link(icd);
933
	if (!icl) {
934
		dev_err(&client->dev, "MT9M11x driver needs platform data\n");
935 936 937 938 939 940 941 942 943 944 945 946 947
		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;
	}

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

948
	v4l2_i2c_subdev_init(&mt9m111->subdev, client, &mt9m111_subdev_ops);
949 950

	/* Second stage probe - when a capture adapter is there */
951 952 953 954 955 956 957 958 959 960
	icd->ops		= &mt9m111_ops;
	icd->rect_max.left	= MT9M111_MIN_DARK_COLS;
	icd->rect_max.top	= MT9M111_MIN_DARK_ROWS;
	icd->rect_max.width	= MT9M111_MAX_WIDTH;
	icd->rect_max.height	= MT9M111_MAX_HEIGHT;
	icd->rect_current.left	= icd->rect_max.left;
	icd->rect_current.top	= icd->rect_max.top;
	icd->width_min		= MT9M111_MIN_DARK_ROWS;
	icd->height_min		= MT9M111_MIN_DARK_COLS;
	icd->y_skip_top		= 0;
961

962 963 964 965 966 967
	ret = mt9m111_video_probe(icd, client);
	if (ret) {
		icd->ops = NULL;
		i2c_set_clientdata(client, NULL);
		kfree(mt9m111);
	}
968 969 970 971 972 973

	return ret;
}

static int mt9m111_remove(struct i2c_client *client)
{
974
	struct mt9m111 *mt9m111 = to_mt9m111(client);
975 976 977 978 979
	struct soc_camera_device *icd = client->dev.platform_data;

	icd->ops = NULL;
	i2c_set_clientdata(client, NULL);
	client->driver = NULL;
980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012
	kfree(mt9m111);

	return 0;
}

static const struct i2c_device_id mt9m111_id[] = {
	{ "mt9m111", 0 },
	{ }
};
MODULE_DEVICE_TABLE(i2c, mt9m111_id);

static struct i2c_driver mt9m111_i2c_driver = {
	.driver = {
		.name = "mt9m111",
	},
	.probe		= mt9m111_probe,
	.remove		= mt9m111_remove,
	.id_table	= mt9m111_id,
};

static int __init mt9m111_mod_init(void)
{
	return i2c_add_driver(&mt9m111_i2c_driver);
}

static void __exit mt9m111_mod_exit(void)
{
	i2c_del_driver(&mt9m111_i2c_driver);
}

module_init(mt9m111_mod_init);
module_exit(mt9m111_mod_exit);

1013
MODULE_DESCRIPTION("Micron MT9M111/MT9M112 Camera driver");
1014 1015
MODULE_AUTHOR("Robert Jarzmik");
MODULE_LICENSE("GPL");