Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

V4L/DVB (13670): soc-camera: Add mt9t112 camera driver

create mode 100644 drivers/media/video/mt9t112.c
create mode 100644 include/media/mt9t112.h

Signed-off-by: Kuninori Morimoto <morimoto.kuninori@renesas.com>
Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

authored by

Kuninori Morimoto and committed by
Mauro Carvalho Chehab
858424b9 70da92e5

+1216
+6
drivers/media/video/Kconfig
··· 836 836 help 837 837 This driver supports MT9T031 cameras from Micron. 838 838 839 + config SOC_CAMERA_MT9T112 840 + tristate "mt9t112 support" 841 + depends on SOC_CAMERA && I2C 842 + help 843 + This driver supports MT9T112 cameras from Aptina. 844 + 839 845 config SOC_CAMERA_MT9V022 840 846 tristate "mt9v022 support" 841 847 depends on SOC_CAMERA && I2C
+1
drivers/media/video/Makefile
··· 75 75 obj-$(CONFIG_SOC_CAMERA_MT9M001) += mt9m001.o 76 76 obj-$(CONFIG_SOC_CAMERA_MT9M111) += mt9m111.o 77 77 obj-$(CONFIG_SOC_CAMERA_MT9T031) += mt9t031.o 78 + obj-$(CONFIG_SOC_CAMERA_MT9T112) += mt9t112.o 78 79 obj-$(CONFIG_SOC_CAMERA_MT9V022) += mt9v022.o 79 80 obj-$(CONFIG_SOC_CAMERA_OV772X) += ov772x.o 80 81 obj-$(CONFIG_SOC_CAMERA_OV9640) += ov9640.o
+1177
drivers/media/video/mt9t112.c
··· 1 + /* 2 + * mt9t112 Camera Driver 3 + * 4 + * Copyright (C) 2009 Renesas Solutions Corp. 5 + * Kuninori Morimoto <morimoto.kuninori@renesas.com> 6 + * 7 + * Based on ov772x driver, mt9m111 driver, 8 + * 9 + * Copyright (C) 2008 Kuninori Morimoto <morimoto.kuninori@renesas.com> 10 + * Copyright (C) 2008, Robert Jarzmik <robert.jarzmik@free.fr> 11 + * Copyright 2006-7 Jonathan Corbet <corbet@lwn.net> 12 + * Copyright (C) 2008 Magnus Damm 13 + * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de> 14 + * 15 + * This program is free software; you can redistribute it and/or modify 16 + * it under the terms of the GNU General Public License version 2 as 17 + * published by the Free Software Foundation. 18 + */ 19 + 20 + #include <linux/delay.h> 21 + #include <linux/i2c.h> 22 + #include <linux/init.h> 23 + #include <linux/module.h> 24 + #include <linux/slab.h> 25 + #include <linux/videodev2.h> 26 + 27 + #include <media/mt9t112.h> 28 + #include <media/soc_camera.h> 29 + #include <media/soc_mediabus.h> 30 + #include <media/v4l2-chip-ident.h> 31 + #include <media/v4l2-common.h> 32 + 33 + /* you can check PLL/clock info */ 34 + /* #define EXT_CLOCK 24000000 */ 35 + 36 + /************************************************************************ 37 + 38 + 39 + macro 40 + 41 + 42 + ************************************************************************/ 43 + /* 44 + * frame size 45 + */ 46 + #define MAX_WIDTH 2048 47 + #define MAX_HEIGHT 1536 48 + 49 + #define VGA_WIDTH 640 50 + #define VGA_HEIGHT 480 51 + 52 + /* 53 + * macro of read/write 54 + */ 55 + #define ECHECKER(ret, x) \ 56 + do { \ 57 + (ret) = (x); \ 58 + if ((ret) < 0) \ 59 + return (ret); \ 60 + } while (0) 61 + 62 + #define mt9t112_reg_write(ret, client, a, b) \ 63 + ECHECKER(ret, __mt9t112_reg_write(client, a, b)) 64 + #define mt9t112_mcu_write(ret, client, a, b) \ 65 + ECHECKER(ret, __mt9t112_mcu_write(client, a, b)) 66 + 67 + #define mt9t112_reg_mask_set(ret, client, a, b, c) \ 68 + ECHECKER(ret, __mt9t112_reg_mask_set(client, a, b, c)) 69 + #define mt9t112_mcu_mask_set(ret, client, a, b, c) \ 70 + ECHECKER(ret, __mt9t112_mcu_mask_set(client, a, b, c)) 71 + 72 + #define mt9t112_reg_read(ret, client, a) \ 73 + ECHECKER(ret, __mt9t112_reg_read(client, a)) 74 + 75 + /* 76 + * Logical address 77 + */ 78 + #define _VAR(id, offset, base) (base | (id & 0x1f) << 10 | (offset & 0x3ff)) 79 + #define VAR(id, offset) _VAR(id, offset, 0x0000) 80 + #define VAR8(id, offset) _VAR(id, offset, 0x8000) 81 + 82 + /************************************************************************ 83 + 84 + 85 + struct 86 + 87 + 88 + ************************************************************************/ 89 + struct mt9t112_frame_size { 90 + u16 width; 91 + u16 height; 92 + }; 93 + 94 + struct mt9t112_format { 95 + enum v4l2_mbus_pixelcode code; 96 + enum v4l2_colorspace colorspace; 97 + u16 fmt; 98 + u16 order; 99 + }; 100 + 101 + struct mt9t112_priv { 102 + struct v4l2_subdev subdev; 103 + struct mt9t112_camera_info *info; 104 + struct i2c_client *client; 105 + struct soc_camera_device icd; 106 + struct mt9t112_frame_size frame; 107 + const struct mt9t112_format *format; 108 + int model; 109 + u32 flags; 110 + /* for flags */ 111 + #define INIT_DONE (1<<0) 112 + }; 113 + 114 + /************************************************************************ 115 + 116 + 117 + supported format 118 + 119 + 120 + ************************************************************************/ 121 + 122 + static const struct mt9t112_format mt9t112_cfmts[] = { 123 + { 124 + .code = V4L2_MBUS_FMT_YUYV8_2X8_BE, 125 + .colorspace = V4L2_COLORSPACE_JPEG, 126 + .fmt = 1, 127 + .order = 0, 128 + }, { 129 + .code = V4L2_MBUS_FMT_YVYU8_2X8_BE, 130 + .colorspace = V4L2_COLORSPACE_JPEG, 131 + .fmt = 1, 132 + .order = 1, 133 + }, { 134 + .code = V4L2_MBUS_FMT_YUYV8_2X8_LE, 135 + .colorspace = V4L2_COLORSPACE_JPEG, 136 + .fmt = 1, 137 + .order = 2, 138 + }, { 139 + .code = V4L2_MBUS_FMT_YVYU8_2X8_LE, 140 + .colorspace = V4L2_COLORSPACE_JPEG, 141 + .fmt = 1, 142 + .order = 3, 143 + }, { 144 + .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE, 145 + .colorspace = V4L2_COLORSPACE_SRGB, 146 + .fmt = 8, 147 + .order = 2, 148 + }, { 149 + .code = V4L2_MBUS_FMT_RGB565_2X8_LE, 150 + .colorspace = V4L2_COLORSPACE_SRGB, 151 + .fmt = 4, 152 + .order = 2, 153 + }, 154 + }; 155 + 156 + /************************************************************************ 157 + 158 + 159 + general function 160 + 161 + 162 + ************************************************************************/ 163 + static struct mt9t112_priv *to_mt9t112(const struct i2c_client *client) 164 + { 165 + return container_of(i2c_get_clientdata(client), 166 + struct mt9t112_priv, 167 + subdev); 168 + } 169 + 170 + static int __mt9t112_reg_read(const struct i2c_client *client, u16 command) 171 + { 172 + struct i2c_msg msg[2]; 173 + u8 buf[2]; 174 + int ret; 175 + 176 + command = swab16(command); 177 + 178 + msg[0].addr = client->addr; 179 + msg[0].flags = 0; 180 + msg[0].len = 2; 181 + msg[0].buf = (u8 *)&command; 182 + 183 + msg[1].addr = client->addr; 184 + msg[1].flags = I2C_M_RD; 185 + msg[1].len = 2; 186 + msg[1].buf = buf; 187 + 188 + /* 189 + * if return value of this function is < 0, 190 + * it mean error. 191 + * else, under 16bit is valid data. 192 + */ 193 + ret = i2c_transfer(client->adapter, msg, 2); 194 + if (ret < 0) 195 + return ret; 196 + 197 + memcpy(&ret, buf, 2); 198 + return swab16(ret); 199 + } 200 + 201 + static int __mt9t112_reg_write(const struct i2c_client *client, 202 + u16 command, u16 data) 203 + { 204 + struct i2c_msg msg; 205 + u8 buf[4]; 206 + int ret; 207 + 208 + command = swab16(command); 209 + data = swab16(data); 210 + 211 + memcpy(buf + 0, &command, 2); 212 + memcpy(buf + 2, &data, 2); 213 + 214 + msg.addr = client->addr; 215 + msg.flags = 0; 216 + msg.len = 4; 217 + msg.buf = buf; 218 + 219 + /* 220 + * i2c_transfer return message length, 221 + * but this function should return 0 if correct case 222 + */ 223 + ret = i2c_transfer(client->adapter, &msg, 1); 224 + if (ret >= 0) 225 + ret = 0; 226 + 227 + return ret; 228 + } 229 + 230 + static int __mt9t112_reg_mask_set(const struct i2c_client *client, 231 + u16 command, 232 + u16 mask, 233 + u16 set) 234 + { 235 + int val = __mt9t112_reg_read(client, command); 236 + if (val < 0) 237 + return val; 238 + 239 + val &= ~mask; 240 + val |= set & mask; 241 + 242 + return __mt9t112_reg_write(client, command, val); 243 + } 244 + 245 + /* mcu access */ 246 + static int __mt9t112_mcu_read(const struct i2c_client *client, u16 command) 247 + { 248 + int ret; 249 + 250 + ret = __mt9t112_reg_write(client, 0x098E, command); 251 + if (ret < 0) 252 + return ret; 253 + 254 + return __mt9t112_reg_read(client, 0x0990); 255 + } 256 + 257 + static int __mt9t112_mcu_write(const struct i2c_client *client, 258 + u16 command, u16 data) 259 + { 260 + int ret; 261 + 262 + ret = __mt9t112_reg_write(client, 0x098E, command); 263 + if (ret < 0) 264 + return ret; 265 + 266 + return __mt9t112_reg_write(client, 0x0990, data); 267 + } 268 + 269 + static int __mt9t112_mcu_mask_set(const struct i2c_client *client, 270 + u16 command, 271 + u16 mask, 272 + u16 set) 273 + { 274 + int val = __mt9t112_mcu_read(client, command); 275 + if (val < 0) 276 + return val; 277 + 278 + val &= ~mask; 279 + val |= set & mask; 280 + 281 + return __mt9t112_mcu_write(client, command, val); 282 + } 283 + 284 + static int mt9t112_reset(const struct i2c_client *client) 285 + { 286 + int ret; 287 + 288 + mt9t112_reg_mask_set(ret, client, 0x001a, 0x0001, 0x0001); 289 + msleep(1); 290 + mt9t112_reg_mask_set(ret, client, 0x001a, 0x0001, 0x0000); 291 + 292 + return ret; 293 + } 294 + 295 + #ifndef EXT_CLOCK 296 + #define CLOCK_INFO(a, b) 297 + #else 298 + #define CLOCK_INFO(a, b) mt9t112_clock_info(a, b) 299 + static int mt9t112_clock_info(const struct i2c_client *client, u32 ext) 300 + { 301 + int m, n, p1, p2, p3, p4, p5, p6, p7; 302 + u32 vco, clk; 303 + char *enable; 304 + 305 + ext /= 1000; /* kbyte order */ 306 + 307 + mt9t112_reg_read(n, client, 0x0012); 308 + p1 = n & 0x000f; 309 + n = n >> 4; 310 + p2 = n & 0x000f; 311 + n = n >> 4; 312 + p3 = n & 0x000f; 313 + 314 + mt9t112_reg_read(n, client, 0x002a); 315 + p4 = n & 0x000f; 316 + n = n >> 4; 317 + p5 = n & 0x000f; 318 + n = n >> 4; 319 + p6 = n & 0x000f; 320 + 321 + mt9t112_reg_read(n, client, 0x002c); 322 + p7 = n & 0x000f; 323 + 324 + mt9t112_reg_read(n, client, 0x0010); 325 + m = n & 0x00ff; 326 + n = (n >> 8) & 0x003f; 327 + 328 + enable = ((6000 > ext) || (54000 < ext)) ? "X" : ""; 329 + dev_info(&client->dev, "EXTCLK : %10u K %s\n", ext, enable); 330 + 331 + vco = 2 * m * ext / (n+1); 332 + enable = ((384000 > vco) || (768000 < vco)) ? "X" : ""; 333 + dev_info(&client->dev, "VCO : %10u K %s\n", vco, enable); 334 + 335 + clk = vco / (p1+1) / (p2+1); 336 + enable = (96000 < clk) ? "X" : ""; 337 + dev_info(&client->dev, "PIXCLK : %10u K %s\n", clk, enable); 338 + 339 + clk = vco / (p3+1); 340 + enable = (768000 < clk) ? "X" : ""; 341 + dev_info(&client->dev, "MIPICLK : %10u K %s\n", clk, enable); 342 + 343 + clk = vco / (p6+1); 344 + enable = (96000 < clk) ? "X" : ""; 345 + dev_info(&client->dev, "MCU CLK : %10u K %s\n", clk, enable); 346 + 347 + clk = vco / (p5+1); 348 + enable = (54000 < clk) ? "X" : ""; 349 + dev_info(&client->dev, "SOC CLK : %10u K %s\n", clk, enable); 350 + 351 + clk = vco / (p4+1); 352 + enable = (70000 < clk) ? "X" : ""; 353 + dev_info(&client->dev, "Sensor CLK : %10u K %s\n", clk, enable); 354 + 355 + clk = vco / (p7+1); 356 + dev_info(&client->dev, "External sensor : %10u K\n", clk); 357 + 358 + clk = ext / (n+1); 359 + enable = ((2000 > clk) || (24000 < clk)) ? "X" : ""; 360 + dev_info(&client->dev, "PFD : %10u K %s\n", clk, enable); 361 + 362 + return 0; 363 + } 364 + #endif 365 + 366 + static void mt9t112_frame_check(u32 *width, u32 *height) 367 + { 368 + if (*width > MAX_WIDTH) 369 + *width = MAX_WIDTH; 370 + 371 + if (*height > MAX_HEIGHT) 372 + *height = MAX_HEIGHT; 373 + } 374 + 375 + static int mt9t112_set_a_frame_size(const struct i2c_client *client, 376 + u16 width, 377 + u16 height) 378 + { 379 + int ret; 380 + u16 wstart = (MAX_WIDTH - width) / 2; 381 + u16 hstart = (MAX_HEIGHT - height) / 2; 382 + 383 + /* (Context A) Image Width/Height */ 384 + mt9t112_mcu_write(ret, client, VAR(26, 0), width); 385 + mt9t112_mcu_write(ret, client, VAR(26, 2), height); 386 + 387 + /* (Context A) Output Width/Height */ 388 + mt9t112_mcu_write(ret, client, VAR(18, 43), 8 + width); 389 + mt9t112_mcu_write(ret, client, VAR(18, 45), 8 + height); 390 + 391 + /* (Context A) Start Row/Column */ 392 + mt9t112_mcu_write(ret, client, VAR(18, 2), 4 + hstart); 393 + mt9t112_mcu_write(ret, client, VAR(18, 4), 4 + wstart); 394 + 395 + /* (Context A) End Row/Column */ 396 + mt9t112_mcu_write(ret, client, VAR(18, 6), 11 + height + hstart); 397 + mt9t112_mcu_write(ret, client, VAR(18, 8), 11 + width + wstart); 398 + 399 + mt9t112_mcu_write(ret, client, VAR8(1, 0), 0x06); 400 + 401 + return ret; 402 + } 403 + 404 + static int mt9t112_set_pll_dividers(const struct i2c_client *client, 405 + u8 m, u8 n, 406 + u8 p1, u8 p2, u8 p3, 407 + u8 p4, u8 p5, u8 p6, 408 + u8 p7) 409 + { 410 + int ret; 411 + u16 val; 412 + 413 + /* N/M */ 414 + val = (n << 8) | 415 + (m << 0); 416 + mt9t112_reg_mask_set(ret, client, 0x0010, 0x3fff, val); 417 + 418 + /* P1/P2/P3 */ 419 + val = ((p3 & 0x0F) << 8) | 420 + ((p2 & 0x0F) << 4) | 421 + ((p1 & 0x0F) << 0); 422 + mt9t112_reg_mask_set(ret, client, 0x0012, 0x0fff, val); 423 + 424 + /* P4/P5/P6 */ 425 + val = (0x7 << 12) | 426 + ((p6 & 0x0F) << 8) | 427 + ((p5 & 0x0F) << 4) | 428 + ((p4 & 0x0F) << 0); 429 + mt9t112_reg_mask_set(ret, client, 0x002A, 0x7fff, val); 430 + 431 + /* P7 */ 432 + val = (0x1 << 12) | 433 + ((p7 & 0x0F) << 0); 434 + mt9t112_reg_mask_set(ret, client, 0x002C, 0x100f, val); 435 + 436 + return ret; 437 + } 438 + 439 + static int mt9t112_init_pll(const struct i2c_client *client) 440 + { 441 + struct mt9t112_priv *priv = to_mt9t112(client); 442 + int data, i, ret; 443 + 444 + mt9t112_reg_mask_set(ret, client, 0x0014, 0x003, 0x0001); 445 + 446 + /* PLL control: BYPASS PLL = 8517 */ 447 + mt9t112_reg_write(ret, client, 0x0014, 0x2145); 448 + 449 + /* Replace these registers when new timing parameters are generated */ 450 + mt9t112_set_pll_dividers(client, 451 + priv->info->divider.m, 452 + priv->info->divider.n, 453 + priv->info->divider.p1, 454 + priv->info->divider.p2, 455 + priv->info->divider.p3, 456 + priv->info->divider.p4, 457 + priv->info->divider.p5, 458 + priv->info->divider.p6, 459 + priv->info->divider.p7); 460 + 461 + /* 462 + * TEST_BYPASS on 463 + * PLL_ENABLE on 464 + * SEL_LOCK_DET on 465 + * TEST_BYPASS off 466 + */ 467 + mt9t112_reg_write(ret, client, 0x0014, 0x2525); 468 + mt9t112_reg_write(ret, client, 0x0014, 0x2527); 469 + mt9t112_reg_write(ret, client, 0x0014, 0x3427); 470 + mt9t112_reg_write(ret, client, 0x0014, 0x3027); 471 + 472 + mdelay(10); 473 + 474 + /* 475 + * PLL_BYPASS off 476 + * Reference clock count 477 + * I2C Master Clock Divider 478 + */ 479 + mt9t112_reg_write(ret, client, 0x0014, 0x3046); 480 + mt9t112_reg_write(ret, client, 0x0022, 0x0190); 481 + mt9t112_reg_write(ret, client, 0x3B84, 0x0212); 482 + 483 + /* External sensor clock is PLL bypass */ 484 + mt9t112_reg_write(ret, client, 0x002E, 0x0500); 485 + 486 + mt9t112_reg_mask_set(ret, client, 0x0018, 0x0002, 0x0002); 487 + mt9t112_reg_mask_set(ret, client, 0x3B82, 0x0004, 0x0004); 488 + 489 + /* MCU disabled */ 490 + mt9t112_reg_mask_set(ret, client, 0x0018, 0x0004, 0x0004); 491 + 492 + /* out of standby */ 493 + mt9t112_reg_mask_set(ret, client, 0x0018, 0x0001, 0); 494 + 495 + mdelay(50); 496 + 497 + /* 498 + * Standby Workaround 499 + * Disable Secondary I2C Pads 500 + */ 501 + mt9t112_reg_write(ret, client, 0x0614, 0x0001); 502 + mdelay(1); 503 + mt9t112_reg_write(ret, client, 0x0614, 0x0001); 504 + mdelay(1); 505 + mt9t112_reg_write(ret, client, 0x0614, 0x0001); 506 + mdelay(1); 507 + mt9t112_reg_write(ret, client, 0x0614, 0x0001); 508 + mdelay(1); 509 + mt9t112_reg_write(ret, client, 0x0614, 0x0001); 510 + mdelay(1); 511 + mt9t112_reg_write(ret, client, 0x0614, 0x0001); 512 + mdelay(1); 513 + 514 + /* poll to verify out of standby. Must Poll this bit */ 515 + for (i = 0; i < 100; i++) { 516 + mt9t112_reg_read(data, client, 0x0018); 517 + if (0x4000 & data) 518 + break; 519 + 520 + mdelay(10); 521 + } 522 + 523 + return ret; 524 + } 525 + 526 + static int mt9t112_init_setting(const struct i2c_client *client) 527 + { 528 + 529 + int ret; 530 + 531 + /* Adaptive Output Clock (A) */ 532 + mt9t112_mcu_mask_set(ret, client, VAR(26, 160), 0x0040, 0x0000); 533 + 534 + /* Read Mode (A) */ 535 + mt9t112_mcu_write(ret, client, VAR(18, 12), 0x0024); 536 + 537 + /* Fine Correction (A) */ 538 + mt9t112_mcu_write(ret, client, VAR(18, 15), 0x00CC); 539 + 540 + /* Fine IT Min (A) */ 541 + mt9t112_mcu_write(ret, client, VAR(18, 17), 0x01f1); 542 + 543 + /* Fine IT Max Margin (A) */ 544 + mt9t112_mcu_write(ret, client, VAR(18, 19), 0x00fF); 545 + 546 + /* Base Frame Lines (A) */ 547 + mt9t112_mcu_write(ret, client, VAR(18, 29), 0x032D); 548 + 549 + /* Min Line Length (A) */ 550 + mt9t112_mcu_write(ret, client, VAR(18, 31), 0x073a); 551 + 552 + /* Line Length (A) */ 553 + mt9t112_mcu_write(ret, client, VAR(18, 37), 0x07d0); 554 + 555 + /* Adaptive Output Clock (B) */ 556 + mt9t112_mcu_mask_set(ret, client, VAR(27, 160), 0x0040, 0x0000); 557 + 558 + /* Row Start (B) */ 559 + mt9t112_mcu_write(ret, client, VAR(18, 74), 0x004); 560 + 561 + /* Column Start (B) */ 562 + mt9t112_mcu_write(ret, client, VAR(18, 76), 0x004); 563 + 564 + /* Row End (B) */ 565 + mt9t112_mcu_write(ret, client, VAR(18, 78), 0x60B); 566 + 567 + /* Column End (B) */ 568 + mt9t112_mcu_write(ret, client, VAR(18, 80), 0x80B); 569 + 570 + /* Fine Correction (B) */ 571 + mt9t112_mcu_write(ret, client, VAR(18, 87), 0x008C); 572 + 573 + /* Fine IT Min (B) */ 574 + mt9t112_mcu_write(ret, client, VAR(18, 89), 0x01F1); 575 + 576 + /* Fine IT Max Margin (B) */ 577 + mt9t112_mcu_write(ret, client, VAR(18, 91), 0x00FF); 578 + 579 + /* Base Frame Lines (B) */ 580 + mt9t112_mcu_write(ret, client, VAR(18, 101), 0x0668); 581 + 582 + /* Min Line Length (B) */ 583 + mt9t112_mcu_write(ret, client, VAR(18, 103), 0x0AF0); 584 + 585 + /* Line Length (B) */ 586 + mt9t112_mcu_write(ret, client, VAR(18, 109), 0x0AF0); 587 + 588 + /* 589 + * Flicker Dectection registers 590 + * This section should be replaced whenever new Timing file is generated 591 + * All the following registers need to be replaced 592 + * Following registers are generated from Register Wizard but user can 593 + * modify them. For detail see auto flicker detection tuning 594 + */ 595 + 596 + /* FD_FDPERIOD_SELECT */ 597 + mt9t112_mcu_write(ret, client, VAR8(8, 5), 0x01); 598 + 599 + /* PRI_B_CONFIG_FD_ALGO_RUN */ 600 + mt9t112_mcu_write(ret, client, VAR(27, 17), 0x0003); 601 + 602 + /* PRI_A_CONFIG_FD_ALGO_RUN */ 603 + mt9t112_mcu_write(ret, client, VAR(26, 17), 0x0003); 604 + 605 + /* 606 + * AFD range detection tuning registers 607 + */ 608 + 609 + /* search_f1_50 */ 610 + mt9t112_mcu_write(ret, client, VAR8(18, 165), 0x25); 611 + 612 + /* search_f2_50 */ 613 + mt9t112_mcu_write(ret, client, VAR8(18, 166), 0x28); 614 + 615 + /* search_f1_60 */ 616 + mt9t112_mcu_write(ret, client, VAR8(18, 167), 0x2C); 617 + 618 + /* search_f2_60 */ 619 + mt9t112_mcu_write(ret, client, VAR8(18, 168), 0x2F); 620 + 621 + /* period_50Hz (A) */ 622 + mt9t112_mcu_write(ret, client, VAR8(18, 68), 0xBA); 623 + 624 + /* secret register by aptina */ 625 + /* period_50Hz (A MSB) */ 626 + mt9t112_mcu_write(ret, client, VAR8(18, 303), 0x00); 627 + 628 + /* period_60Hz (A) */ 629 + mt9t112_mcu_write(ret, client, VAR8(18, 69), 0x9B); 630 + 631 + /* secret register by aptina */ 632 + /* period_60Hz (A MSB) */ 633 + mt9t112_mcu_write(ret, client, VAR8(18, 301), 0x00); 634 + 635 + /* period_50Hz (B) */ 636 + mt9t112_mcu_write(ret, client, VAR8(18, 140), 0x82); 637 + 638 + /* secret register by aptina */ 639 + /* period_50Hz (B) MSB */ 640 + mt9t112_mcu_write(ret, client, VAR8(18, 304), 0x00); 641 + 642 + /* period_60Hz (B) */ 643 + mt9t112_mcu_write(ret, client, VAR8(18, 141), 0x6D); 644 + 645 + /* secret register by aptina */ 646 + /* period_60Hz (B) MSB */ 647 + mt9t112_mcu_write(ret, client, VAR8(18, 302), 0x00); 648 + 649 + /* FD Mode */ 650 + mt9t112_mcu_write(ret, client, VAR8(8, 2), 0x10); 651 + 652 + /* Stat_min */ 653 + mt9t112_mcu_write(ret, client, VAR8(8, 9), 0x02); 654 + 655 + /* Stat_max */ 656 + mt9t112_mcu_write(ret, client, VAR8(8, 10), 0x03); 657 + 658 + /* Min_amplitude */ 659 + mt9t112_mcu_write(ret, client, VAR8(8, 12), 0x0A); 660 + 661 + /* RX FIFO Watermark (A) */ 662 + mt9t112_mcu_write(ret, client, VAR(18, 70), 0x0014); 663 + 664 + /* RX FIFO Watermark (B) */ 665 + mt9t112_mcu_write(ret, client, VAR(18, 142), 0x0014); 666 + 667 + /* MCLK: 16MHz 668 + * PCLK: 73MHz 669 + * CorePixCLK: 36.5 MHz 670 + */ 671 + mt9t112_mcu_write(ret, client, VAR8(18, 0x0044), 133); 672 + mt9t112_mcu_write(ret, client, VAR8(18, 0x0045), 110); 673 + mt9t112_mcu_write(ret, client, VAR8(18, 0x008c), 130); 674 + mt9t112_mcu_write(ret, client, VAR8(18, 0x008d), 108); 675 + 676 + mt9t112_mcu_write(ret, client, VAR8(18, 0x00A5), 27); 677 + mt9t112_mcu_write(ret, client, VAR8(18, 0x00a6), 30); 678 + mt9t112_mcu_write(ret, client, VAR8(18, 0x00a7), 32); 679 + mt9t112_mcu_write(ret, client, VAR8(18, 0x00a8), 35); 680 + 681 + return ret; 682 + } 683 + 684 + static int mt9t112_auto_focus_setting(const struct i2c_client *client) 685 + { 686 + int ret; 687 + 688 + mt9t112_mcu_write(ret, client, VAR(12, 13), 0x000F); 689 + mt9t112_mcu_write(ret, client, VAR(12, 23), 0x0F0F); 690 + mt9t112_mcu_write(ret, client, VAR8(1, 0), 0x06); 691 + 692 + mt9t112_reg_write(ret, client, 0x0614, 0x0000); 693 + 694 + mt9t112_mcu_write(ret, client, VAR8(1, 0), 0x05); 695 + mt9t112_mcu_write(ret, client, VAR8(12, 2), 0x02); 696 + mt9t112_mcu_write(ret, client, VAR(12, 3), 0x0002); 697 + mt9t112_mcu_write(ret, client, VAR(17, 3), 0x8001); 698 + mt9t112_mcu_write(ret, client, VAR(17, 11), 0x0025); 699 + mt9t112_mcu_write(ret, client, VAR(17, 13), 0x0193); 700 + mt9t112_mcu_write(ret, client, VAR8(17, 33), 0x18); 701 + mt9t112_mcu_write(ret, client, VAR8(1, 0), 0x05); 702 + 703 + return ret; 704 + } 705 + 706 + static int mt9t112_auto_focus_trigger(const struct i2c_client *client) 707 + { 708 + int ret; 709 + 710 + mt9t112_mcu_write(ret, client, VAR8(12, 25), 0x01); 711 + 712 + return ret; 713 + } 714 + 715 + static int mt9t112_init_camera(const struct i2c_client *client) 716 + { 717 + int ret; 718 + 719 + ECHECKER(ret, mt9t112_reset(client)); 720 + 721 + ECHECKER(ret, mt9t112_init_pll(client)); 722 + 723 + ECHECKER(ret, mt9t112_init_setting(client)); 724 + 725 + ECHECKER(ret, mt9t112_auto_focus_setting(client)); 726 + 727 + mt9t112_reg_mask_set(ret, client, 0x0018, 0x0004, 0); 728 + 729 + /* Analog setting B */ 730 + mt9t112_reg_write(ret, client, 0x3084, 0x2409); 731 + mt9t112_reg_write(ret, client, 0x3092, 0x0A49); 732 + mt9t112_reg_write(ret, client, 0x3094, 0x4949); 733 + mt9t112_reg_write(ret, client, 0x3096, 0x4950); 734 + 735 + /* 736 + * Disable adaptive clock 737 + * PRI_A_CONFIG_JPEG_OB_TX_CONTROL_VAR 738 + * PRI_B_CONFIG_JPEG_OB_TX_CONTROL_VAR 739 + */ 740 + mt9t112_mcu_write(ret, client, VAR(26, 160), 0x0A2E); 741 + mt9t112_mcu_write(ret, client, VAR(27, 160), 0x0A2E); 742 + 743 + /* Configure STatus in Status_before_length Format and enable header */ 744 + /* PRI_B_CONFIG_JPEG_OB_TX_CONTROL_VAR */ 745 + mt9t112_mcu_write(ret, client, VAR(27, 144), 0x0CB4); 746 + 747 + /* Enable JPEG in context B */ 748 + /* PRI_B_CONFIG_JPEG_OB_TX_CONTROL_VAR */ 749 + mt9t112_mcu_write(ret, client, VAR8(27, 142), 0x01); 750 + 751 + /* Disable Dac_TXLO */ 752 + mt9t112_reg_write(ret, client, 0x316C, 0x350F); 753 + 754 + /* Set max slew rates */ 755 + mt9t112_reg_write(ret, client, 0x1E, 0x777); 756 + 757 + return ret; 758 + } 759 + 760 + /************************************************************************ 761 + 762 + 763 + soc_camera_ops 764 + 765 + 766 + ************************************************************************/ 767 + static int mt9t112_set_bus_param(struct soc_camera_device *icd, 768 + unsigned long flags) 769 + { 770 + return 0; 771 + } 772 + 773 + static unsigned long mt9t112_query_bus_param(struct soc_camera_device *icd) 774 + { 775 + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 776 + struct mt9t112_priv *priv = to_mt9t112(client); 777 + struct soc_camera_link *icl = to_soc_camera_link(icd); 778 + unsigned long flags = SOCAM_MASTER | SOCAM_VSYNC_ACTIVE_HIGH | 779 + SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_DATA_ACTIVE_HIGH; 780 + 781 + flags |= (priv->info->flags & MT9T112_FLAG_PCLK_RISING_EDGE) ? 782 + SOCAM_PCLK_SAMPLE_RISING : SOCAM_PCLK_SAMPLE_FALLING; 783 + 784 + if (priv->info->flags & MT9T112_FLAG_DATAWIDTH_8) 785 + flags |= SOCAM_DATAWIDTH_8; 786 + else 787 + flags |= SOCAM_DATAWIDTH_10; 788 + 789 + return soc_camera_apply_sensor_flags(icl, flags); 790 + } 791 + 792 + static struct soc_camera_ops mt9t112_ops = { 793 + .set_bus_param = mt9t112_set_bus_param, 794 + .query_bus_param = mt9t112_query_bus_param, 795 + }; 796 + 797 + /************************************************************************ 798 + 799 + 800 + v4l2_subdev_core_ops 801 + 802 + 803 + ************************************************************************/ 804 + static int mt9t112_g_chip_ident(struct v4l2_subdev *sd, 805 + struct v4l2_dbg_chip_ident *id) 806 + { 807 + struct i2c_client *client = sd->priv; 808 + struct mt9t112_priv *priv = to_mt9t112(client); 809 + 810 + id->ident = priv->model; 811 + id->revision = 0; 812 + 813 + return 0; 814 + } 815 + 816 + #ifdef CONFIG_VIDEO_ADV_DEBUG 817 + static int mt9t112_g_register(struct v4l2_subdev *sd, 818 + struct v4l2_dbg_register *reg) 819 + { 820 + struct i2c_client *client = sd->priv; 821 + int ret; 822 + 823 + reg->size = 2; 824 + mt9t112_reg_read(ret, client, reg->reg); 825 + 826 + reg->val = (__u64)ret; 827 + 828 + return 0; 829 + } 830 + 831 + static int mt9t112_s_register(struct v4l2_subdev *sd, 832 + struct v4l2_dbg_register *reg) 833 + { 834 + struct i2c_client *client = sd->priv; 835 + int ret; 836 + 837 + mt9t112_reg_write(ret, client, reg->reg, reg->val); 838 + 839 + return ret; 840 + } 841 + #endif 842 + 843 + static struct v4l2_subdev_core_ops mt9t112_subdev_core_ops = { 844 + .g_chip_ident = mt9t112_g_chip_ident, 845 + #ifdef CONFIG_VIDEO_ADV_DEBUG 846 + .g_register = mt9t112_g_register, 847 + .s_register = mt9t112_s_register, 848 + #endif 849 + }; 850 + 851 + 852 + /************************************************************************ 853 + 854 + 855 + v4l2_subdev_video_ops 856 + 857 + 858 + ************************************************************************/ 859 + static int mt9t112_s_stream(struct v4l2_subdev *sd, int enable) 860 + { 861 + struct i2c_client *client = sd->priv; 862 + struct mt9t112_priv *priv = to_mt9t112(client); 863 + int ret = 0; 864 + 865 + if (!enable) { 866 + /* FIXME 867 + * 868 + * If user selected large output size, 869 + * and used it long time, 870 + * mt9t112 camera will be very warm. 871 + * 872 + * But current driver can not stop mt9t112 camera. 873 + * So, set small size here to solve this problem. 874 + */ 875 + mt9t112_set_a_frame_size(client, VGA_WIDTH, VGA_HEIGHT); 876 + return ret; 877 + } 878 + 879 + if (!(priv->flags & INIT_DONE)) { 880 + u16 param = (MT9T112_FLAG_PCLK_RISING_EDGE & 881 + priv->info->flags) ? 0x0001 : 0x0000; 882 + 883 + ECHECKER(ret, mt9t112_init_camera(client)); 884 + 885 + /* Invert PCLK (Data sampled on falling edge of pixclk) */ 886 + mt9t112_reg_write(ret, client, 0x3C20, param); 887 + 888 + mdelay(5); 889 + 890 + priv->flags |= INIT_DONE; 891 + } 892 + 893 + mt9t112_mcu_write(ret, client, VAR(26, 7), priv->format->fmt); 894 + mt9t112_mcu_write(ret, client, VAR(26, 9), priv->format->order); 895 + mt9t112_mcu_write(ret, client, VAR8(1, 0), 0x06); 896 + 897 + mt9t112_set_a_frame_size(client, 898 + priv->frame.width, 899 + priv->frame.height); 900 + 901 + ECHECKER(ret, mt9t112_auto_focus_trigger(client)); 902 + 903 + dev_dbg(&client->dev, "format : %d\n", priv->format->code); 904 + dev_dbg(&client->dev, "size : %d x %d\n", 905 + priv->frame.width, 906 + priv->frame.height); 907 + 908 + CLOCK_INFO(client, EXT_CLOCK); 909 + 910 + return ret; 911 + } 912 + 913 + static int mt9t112_set_params(struct i2c_client *client, u32 width, u32 height, 914 + enum v4l2_mbus_pixelcode code) 915 + { 916 + struct mt9t112_priv *priv = to_mt9t112(client); 917 + int i; 918 + 919 + priv->format = NULL; 920 + 921 + /* 922 + * frame size check 923 + */ 924 + mt9t112_frame_check(&width, &height); 925 + 926 + /* 927 + * get color format 928 + */ 929 + for (i = 0; i < ARRAY_SIZE(mt9t112_cfmts); i++) 930 + if (mt9t112_cfmts[i].code == code) 931 + break; 932 + 933 + if (i == ARRAY_SIZE(mt9t112_cfmts)) 934 + return -EINVAL; 935 + 936 + priv->frame.width = (u16)width; 937 + priv->frame.height = (u16)height; 938 + 939 + priv->format = mt9t112_cfmts + i; 940 + 941 + return 0; 942 + } 943 + 944 + static int mt9t112_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) 945 + { 946 + a->bounds.left = 0; 947 + a->bounds.top = 0; 948 + a->bounds.width = VGA_WIDTH; 949 + a->bounds.height = VGA_HEIGHT; 950 + a->defrect = a->bounds; 951 + a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 952 + a->pixelaspect.numerator = 1; 953 + a->pixelaspect.denominator = 1; 954 + 955 + return 0; 956 + } 957 + 958 + static int mt9t112_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) 959 + { 960 + a->c.left = 0; 961 + a->c.top = 0; 962 + a->c.width = VGA_WIDTH; 963 + a->c.height = VGA_HEIGHT; 964 + a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 965 + 966 + return 0; 967 + } 968 + 969 + static int mt9t112_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) 970 + { 971 + struct i2c_client *client = sd->priv; 972 + struct v4l2_rect *rect = &a->c; 973 + 974 + return mt9t112_set_params(client, rect->width, rect->height, 975 + V4L2_MBUS_FMT_YUYV8_2X8_BE); 976 + } 977 + 978 + static int mt9t112_g_fmt(struct v4l2_subdev *sd, 979 + struct v4l2_mbus_framefmt *mf) 980 + { 981 + struct i2c_client *client = sd->priv; 982 + struct mt9t112_priv *priv = to_mt9t112(client); 983 + 984 + if (!priv->format) { 985 + int ret = mt9t112_set_params(client, VGA_WIDTH, VGA_HEIGHT, 986 + V4L2_MBUS_FMT_YUYV8_2X8_BE); 987 + if (ret < 0) 988 + return ret; 989 + } 990 + 991 + mf->width = priv->frame.width; 992 + mf->height = priv->frame.height; 993 + /* TODO: set colorspace */ 994 + mf->code = priv->format->code; 995 + mf->field = V4L2_FIELD_NONE; 996 + 997 + return 0; 998 + } 999 + 1000 + static int mt9t112_s_fmt(struct v4l2_subdev *sd, 1001 + struct v4l2_mbus_framefmt *mf) 1002 + { 1003 + struct i2c_client *client = sd->priv; 1004 + 1005 + /* TODO: set colorspace */ 1006 + return mt9t112_set_params(client, mf->width, mf->height, mf->code); 1007 + } 1008 + 1009 + static int mt9t112_try_fmt(struct v4l2_subdev *sd, 1010 + struct v4l2_mbus_framefmt *mf) 1011 + { 1012 + mt9t112_frame_check(&mf->width, &mf->height); 1013 + 1014 + /* TODO: set colorspace */ 1015 + mf->field = V4L2_FIELD_NONE; 1016 + 1017 + return 0; 1018 + } 1019 + 1020 + static int mt9t112_enum_fmt(struct v4l2_subdev *sd, int index, 1021 + enum v4l2_mbus_pixelcode *code) 1022 + { 1023 + if ((unsigned int)index >= ARRAY_SIZE(mt9t112_cfmts)) 1024 + return -EINVAL; 1025 + 1026 + *code = mt9t112_cfmts[index].code; 1027 + return 0; 1028 + } 1029 + 1030 + static struct v4l2_subdev_video_ops mt9t112_subdev_video_ops = { 1031 + .s_stream = mt9t112_s_stream, 1032 + .g_mbus_fmt = mt9t112_g_fmt, 1033 + .s_mbus_fmt = mt9t112_s_fmt, 1034 + .try_mbus_fmt = mt9t112_try_fmt, 1035 + .cropcap = mt9t112_cropcap, 1036 + .g_crop = mt9t112_g_crop, 1037 + .s_crop = mt9t112_s_crop, 1038 + .enum_mbus_fmt = mt9t112_enum_fmt, 1039 + }; 1040 + 1041 + /************************************************************************ 1042 + 1043 + 1044 + i2c driver 1045 + 1046 + 1047 + ************************************************************************/ 1048 + static struct v4l2_subdev_ops mt9t112_subdev_ops = { 1049 + .core = &mt9t112_subdev_core_ops, 1050 + .video = &mt9t112_subdev_video_ops, 1051 + }; 1052 + 1053 + static int mt9t112_camera_probe(struct soc_camera_device *icd, 1054 + struct i2c_client *client) 1055 + { 1056 + struct mt9t112_priv *priv = to_mt9t112(client); 1057 + const char *devname; 1058 + int chipid; 1059 + 1060 + /* 1061 + * We must have a parent by now. And it cannot be a wrong one. 1062 + * So this entire test is completely redundant. 1063 + */ 1064 + if (!icd->dev.parent || 1065 + to_soc_camera_host(icd->dev.parent)->nr != icd->iface) 1066 + return -ENODEV; 1067 + 1068 + /* 1069 + * check and show chip ID 1070 + */ 1071 + mt9t112_reg_read(chipid, client, 0x0000); 1072 + 1073 + switch (chipid) { 1074 + case 0x2680: 1075 + devname = "mt9t111"; 1076 + priv->model = V4L2_IDENT_MT9T111; 1077 + break; 1078 + case 0x2682: 1079 + devname = "mt9t112"; 1080 + priv->model = V4L2_IDENT_MT9T112; 1081 + break; 1082 + default: 1083 + dev_err(&client->dev, "Product ID error %04x\n", chipid); 1084 + return -ENODEV; 1085 + } 1086 + 1087 + dev_info(&client->dev, "%s chip ID %04x\n", devname, chipid); 1088 + 1089 + return 0; 1090 + } 1091 + 1092 + static int mt9t112_probe(struct i2c_client *client, 1093 + const struct i2c_device_id *did) 1094 + { 1095 + struct mt9t112_priv *priv; 1096 + struct soc_camera_device *icd = client->dev.platform_data; 1097 + struct soc_camera_link *icl; 1098 + int ret; 1099 + 1100 + if (!icd) { 1101 + dev_err(&client->dev, "mt9t112: missing soc-camera data!\n"); 1102 + return -EINVAL; 1103 + } 1104 + 1105 + icl = to_soc_camera_link(icd); 1106 + if (!icl || !icl->priv) 1107 + return -EINVAL; 1108 + 1109 + priv = kzalloc(sizeof(*priv), GFP_KERNEL); 1110 + if (!priv) 1111 + return -ENOMEM; 1112 + 1113 + priv->info = icl->priv; 1114 + 1115 + v4l2_i2c_subdev_init(&priv->subdev, client, &mt9t112_subdev_ops); 1116 + 1117 + icd->ops = &mt9t112_ops; 1118 + 1119 + ret = mt9t112_camera_probe(icd, client); 1120 + if (ret) { 1121 + icd->ops = NULL; 1122 + i2c_set_clientdata(client, NULL); 1123 + kfree(priv); 1124 + } 1125 + 1126 + return ret; 1127 + } 1128 + 1129 + static int mt9t112_remove(struct i2c_client *client) 1130 + { 1131 + struct mt9t112_priv *priv = to_mt9t112(client); 1132 + struct soc_camera_device *icd = client->dev.platform_data; 1133 + 1134 + icd->ops = NULL; 1135 + i2c_set_clientdata(client, NULL); 1136 + kfree(priv); 1137 + return 0; 1138 + } 1139 + 1140 + static const struct i2c_device_id mt9t112_id[] = { 1141 + { "mt9t112", 0 }, 1142 + { } 1143 + }; 1144 + MODULE_DEVICE_TABLE(i2c, mt9t112_id); 1145 + 1146 + static struct i2c_driver mt9t112_i2c_driver = { 1147 + .driver = { 1148 + .name = "mt9t112", 1149 + }, 1150 + .probe = mt9t112_probe, 1151 + .remove = mt9t112_remove, 1152 + .id_table = mt9t112_id, 1153 + }; 1154 + 1155 + /************************************************************************ 1156 + 1157 + 1158 + module function 1159 + 1160 + 1161 + ************************************************************************/ 1162 + static int __init mt9t112_module_init(void) 1163 + { 1164 + return i2c_add_driver(&mt9t112_i2c_driver); 1165 + } 1166 + 1167 + static void __exit mt9t112_module_exit(void) 1168 + { 1169 + i2c_del_driver(&mt9t112_i2c_driver); 1170 + } 1171 + 1172 + module_init(mt9t112_module_init); 1173 + module_exit(mt9t112_module_exit); 1174 + 1175 + MODULE_DESCRIPTION("SoC Camera driver for mt9t112"); 1176 + MODULE_AUTHOR("Kuninori Morimoto"); 1177 + MODULE_LICENSE("GPL v2");
+30
include/media/mt9t112.h
··· 1 + /* mt9t112 Camera 2 + * 3 + * Copyright (C) 2009 Renesas Solutions Corp. 4 + * Kuninori Morimoto <morimoto.kuninori@renesas.com> 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 + #ifndef __MT9T112_H__ 12 + #define __MT9T112_H__ 13 + 14 + #define MT9T112_FLAG_PCLK_RISING_EDGE (1 << 0) 15 + #define MT9T112_FLAG_DATAWIDTH_8 (1 << 1) /* default width is 10 */ 16 + 17 + struct mt9t112_pll_divider { 18 + u8 m, n; 19 + u8 p1, p2, p3, p4, p5, p6, p7; 20 + }; 21 + 22 + /* 23 + * mt9t112 camera info 24 + */ 25 + struct mt9t112_camera_info { 26 + u32 flags; 27 + struct mt9t112_pll_divider divider; 28 + }; 29 + 30 + #endif /* __MT9T112_H__ */
+2
include/media/v4l2-chip-ident.h
··· 267 267 V4L2_IDENT_MT9V022IX7ATC = 45010, /* No way to detect "normal" I77ATx */ 268 268 V4L2_IDENT_MT9V022IX7ATM = 45015, /* and "lead free" IA7ATx chips */ 269 269 V4L2_IDENT_MT9T031 = 45020, 270 + V4L2_IDENT_MT9T111 = 45021, 271 + V4L2_IDENT_MT9T112 = 45022, 270 272 V4L2_IDENT_MT9V111 = 45031, 271 273 V4L2_IDENT_MT9V112 = 45032, 272 274