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