summaryrefslogtreecommitdiffstats
path: root/extras/recipes-kernel/linux/linux-omap-psp-2.6.32/cam/5m03/0001-mt9p031-import-driver-from-https-github.com-Aptina-B.patch
diff options
context:
space:
mode:
Diffstat (limited to 'extras/recipes-kernel/linux/linux-omap-psp-2.6.32/cam/5m03/0001-mt9p031-import-driver-from-https-github.com-Aptina-B.patch')
-rw-r--r--extras/recipes-kernel/linux/linux-omap-psp-2.6.32/cam/5m03/0001-mt9p031-import-driver-from-https-github.com-Aptina-B.patch1547
1 files changed, 1547 insertions, 0 deletions
diff --git a/extras/recipes-kernel/linux/linux-omap-psp-2.6.32/cam/5m03/0001-mt9p031-import-driver-from-https-github.com-Aptina-B.patch b/extras/recipes-kernel/linux/linux-omap-psp-2.6.32/cam/5m03/0001-mt9p031-import-driver-from-https-github.com-Aptina-B.patch
new file mode 100644
index 00000000..ee728b9d
--- /dev/null
+++ b/extras/recipes-kernel/linux/linux-omap-psp-2.6.32/cam/5m03/0001-mt9p031-import-driver-from-https-github.com-Aptina-B.patch
@@ -0,0 +1,1547 @@
1From eefcf5de4689fbd00119d7a7df75244ca6ca1187 Mon Sep 17 00:00:00 2001
2From: Koen Kooi <koen@dominion.thruhere.net>
3Date: Sun, 1 May 2011 16:40:54 +0200
4Subject: [PATCH 1/2] mt9p031: import driver from https://github.com/Aptina/BeagleBoard-xM/tree/master/Angstrom/MT9P031
5
6Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
7---
8 drivers/media/video/Kconfig | 6 +
9 drivers/media/video/Makefile | 1 +
10 drivers/media/video/mt9p031.c | 1445 +++++++++++++++++++++++++++++++++++++++
11 include/media/mt9p031.h | 30 +
12 include/media/v4l2-chip-ident.h | 1 +
13 5 files changed, 1483 insertions(+), 0 deletions(-)
14 create mode 100644 drivers/media/video/mt9p031.c
15 create mode 100644 include/media/mt9p031.h
16
17diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
18index 4c1fb0f..59f1133 100644
19--- a/drivers/media/video/Kconfig
20+++ b/drivers/media/video/Kconfig
21@@ -832,6 +832,12 @@ config SOC_CAMERA_MT9M111
22 help
23 This driver supports MT9M111 and MT9M112 cameras from Micron
24
25+config SOC_CAMERA_MT9P031
26+ tristate "mt9p031 support"
27+ depends on SOC_CAMERA && I2C
28+ help
29+ This driver supports MT9P031 cameras from Micron.
30+
31 config SOC_CAMERA_MT9T031
32 tristate "mt9t031 support"
33 depends on SOC_CAMERA && I2C
34diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
35index fb7e46c..f3110e7 100644
36--- a/drivers/media/video/Makefile
37+++ b/drivers/media/video/Makefile
38@@ -79,6 +79,7 @@ obj-$(CONFIG_VIDEO_MT9V113) += mt9v113.o
39
40 obj-$(CONFIG_SOC_CAMERA_MT9M001) += mt9m001.o
41 obj-$(CONFIG_SOC_CAMERA_MT9M111) += mt9m111.o
42+obj-$(CONFIG_SOC_CAMERA_MT9P031) += mt9p031.o
43 obj-$(CONFIG_SOC_CAMERA_MT9T031) += mt9t031.o
44 obj-$(CONFIG_SOC_CAMERA_MT9V022) += mt9v022.o
45 obj-$(CONFIG_SOC_CAMERA_OV772X) += ov772x.o
46diff --git a/drivers/media/video/mt9p031.c b/drivers/media/video/mt9p031.c
47new file mode 100644
48index 0000000..3047e43
49--- /dev/null
50+++ b/drivers/media/video/mt9p031.c
51@@ -0,0 +1,1445 @@
52+/*
53+ * drivers/media/video/mt9p031.c
54+ *
55+ * Aptina mt9p031 sensor driver
56+ *
57+ *
58+ * Copyright (C) 2010 Aptina Imaging
59+ *
60+ *
61+ * Leverage mt9p012.c
62+ *
63+ * This program is free software; you can redistribute it and/or modify
64+ * it under the terms of the GNU General Public License version 2 as
65+ * published by the Free Software Foundation.
66+ *
67+ * This program is distributed in the hope that it will be useful,
68+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
69+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
70+ * GNU General Public License for more details.
71+ *
72+ * You should have received a copy of the GNU General Public License
73+ * along with this program; if not, write to the Free Software
74+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
75+ *
76+ */
77+
78+
79+#include <linux/delay.h>
80+#include <linux/i2c.h>
81+#include <linux/init.h>
82+#include <linux/module.h>
83+#include <linux/slab.h>
84+#include <linux/kernel.h>
85+#include <linux/videodev2.h>
86+#include <linux/sysfs.h>
87+
88+#include <media/mt9p031.h>
89+#include <media/v4l2-int-device.h>
90+#include <media/v4l2-chip-ident.h>
91+
92+#define MT9P031_DEBUG
93+
94+#ifdef MT9P031_DEBUG
95+#define DPRINTK_DRIVER(format, ...) \
96+ printk(KERN_INFO "_MT9P031_DRIVER: " format, ## __VA_ARGS__)
97+#else
98+#define DPRINTK_DRIVER(format, ...)
99+#endif
100+/************************************************************************
101+ macro
102+************************************************************************/
103+// Macro to configure I2c level shifter. Use only for MT9P031 Headboards from Aptina; not required for Leopard Imaging or elsewise.
104+#define MT9P031_HEADBOARD
105+
106+#define MT9P031_CHIP_ID 0x1801
107+#define MT9P031_MAX_HEIGHT 1944
108+#define MT9P031_MAX_WIDTH 2592
109+#define MT9P031_MIN_HEIGHT 2
110+#define MT9P031_MIN_WIDTH 2
111+
112+#define VGA_HEIGHT 480
113+#define VGA_WIDTH 640
114+
115+#define MT9P031_NORMAL_OPERATION_MODE (0x1F82) //write
116+#define MT9P031_OUTPUT_CTRL_CHIP_UNSELECT (0x1F80)
117+#define MT9P031_OUTPUT_CTRL_HALT (0x1F83)
118+
119+/* FPS Capabilities */
120+#define MT9P031_MIN_FPS 10
121+#define MT9P031_DEF_FPS 30
122+#define MT9P031_MAX_FPS 50
123+
124+#define MT9P031_XCLK_NOM_1 12000000
125+#define MT9P031_XCLK_NOM_2 24000000
126+
127+/* Analog gain values */
128+#define MT9P031_EV_MIN_GAIN 0
129+#define MT9P031_EV_MAX_GAIN 47
130+#define MT9P031_EV_DEF_GAIN 24
131+#define MT9P031_EV_GAIN_STEP 1
132+
133+/* Exposure time values */
134+#define MT9P031_MIN_EXPOSURE 15000
135+#define MT9P031_MAX_EXPOSURE 128000
136+#define MT9P031_DEF_EXPOSURE 33000
137+#define MT9P031_EXPOSURE_STEP 100
138+#define Q12 4096
139+/************************************************************************
140+ Register Address
141+************************************************************************/
142+
143+#define REG_MT9P031_CHIP_VERSION 0x00
144+#define REG_MT9P031_ROWSTART 0x01
145+#define REG_MT9P031_COLSTART 0x02
146+#define REG_MT9P031_HEIGHT 0x03
147+#define REG_MT9P031_WIDTH 0x04
148+#define REG_MT9P031_HBLANK 0x05
149+#define REG_MT9P031_VBLANK 0x06
150+#define REG_MT9P031_OUT_CTRL 0x07
151+#define REG_MT9P031_SHUTTER_WIDTH_U 0x08
152+#define REG_MT9P031_SHUTTER_WIDTH_L 0x09
153+#define REG_MT9P031_PCLK_CTRL 0x0a
154+#define REG_MT9P031_RESTART 0x0b
155+#define REG_MT9P031_SHUTTER_DELAY 0x0c
156+#define REG_MT9P031_RESET 0x0d
157+
158+#define REG_MT9P031_PLL_CTRL 0x10
159+#define REG_MT9P031_PLL_CONF1 0x11
160+#define REG_MT9P031_PLL_CONF2 0x12
161+
162+#define REG_MT9P031_READ_MODE1 0x1e
163+#define REG_MT9P031_READ_MODE2 0x20
164+#define REG_MT9P031_ROW_ADDR_MODE 0x22
165+#define REG_MT9P031_COL_ADDR_MODE 0x23
166+#define REG_MT9P031_GREEN_1_GAIN 0x2b
167+#define REG_MT9P031_BLUE_GAIN 0x2c
168+#define REG_MT9P031_RED_GAIN 0x2d
169+#define REG_MT9P031_GREEN_2_GAIN 0x2e
170+#define REG_MT9P031_GLOBAL_GAIN 0x35
171+#define REG_MT9P031_CHIP_VERSION_ALT 0x0FF
172+
173+/************************************************************************
174+ struct
175+************************************************************************/
176+struct mt9p031_frame_size {
177+ u16 width;
178+ u16 height;
179+};
180+
181+struct mt9p031_priv {
182+ struct mt9p031_platform_data *pdata;
183+ struct v4l2_int_device *v4l2_int_device;
184+ struct i2c_client *client;
185+ struct v4l2_pix_format pix;
186+ struct v4l2_fract timeperframe;
187+ unsigned long xclk_current;
188+ int fps;
189+ int scaler;
190+ int ver;
191+ int model;
192+ u32 flags;
193+/* for flags */
194+#define INIT_DONE (1<<0)
195+};
196+
197+struct mt9p031_priv sysPriv;
198+
199+static const struct v4l2_fmtdesc mt9p031_formats[] = {
200+ {
201+ .description = "Bayer (sRGB) 10 bit",
202+ .pixelformat = V4L2_PIX_FMT_SRGGB10,
203+ },
204+};
205+
206+static const unsigned int mt9p031_num_formats = ARRAY_SIZE(mt9p031_formats);
207+
208+/***********************Minimum Horizontal blanking*********************/
209+int hb_min[4][4] = {
210+ { 450, 430, 0, 420 },
211+ { 796, 776, 0, 766 },
212+ { 0, 0, 0, 0 },
213+ { 1488, 1468, 0, 1458 },
214+};
215+
216+/**************************supported sizes******************************/
217+const static struct mt9p031_frame_size mt9p031_sizes[] = {
218+ { 640, 480 },
219+ { 1280, 720 },
220+ { 1920, 1080 },
221+ { 2048, 1536 }, //3MP
222+ { 2592, 1944 }, //5MP
223+};
224+
225+
226+struct mt9p031_format_params {
227+ int width;
228+ int height;
229+ int row_start;
230+ int col_start;
231+ int row_size;
232+ int col_size;
233+ int hblank;
234+ int vblank;
235+ int integ_time;
236+ int row_addr_mode;
237+ int col_addr_mode;
238+ int read_mode_2_config;
239+ int shutter_width_hi;
240+ int shutter_delay;
241+ int row_bin;
242+ int col_bin;
243+};
244+
245+enum mt9p031_image_size {
246+ VGA_BIN_30FPS,
247+ HDV_720P_30FPS,
248+ //HDV_720P_60FPS,
249+ //HDV_720P_60FPS_LVB,
250+ HDV_1080P_30FPS,
251+ MT9P031_THREE_MP,
252+ MT9P031_FIVE_MP,
253+};
254+
255+enum mt9p031_image_size mt9p031_current_format;
256+
257+const struct mt9p031_format_params mt9p031_supported_formats[] = {
258+ { 640, 480, 64, 24, 1919, 2559, 0, 0, 0x0296, 0x0033, 0x0033, 0x0060, 0, 0, 3, 3 }, // VGA_BIN_30FPS
259+ { 1280, 720, 64, 24, 1439, 2559, 0, 0, 0x0296, 0x0011, 0x0011, 0x0060, 0, 0, 1, 1 }, // 720P_HD_30FPS
260+ //{ 1280, 720, 0x0040, 0x0018, 0x059F, 0x09FF, 0, 0, 0x0296, 0x0011, 0x0011, 0x0060, 0, 0, 1, 1 }, // 720P_HD_60FPS
261+ //{ 1280, 720, 0x0040, 0x0018, 0x059F, 0x09FF, 0, 0x02D0, 0x0296, 0x0011, 0x0011, 0x0060, 0, 0, 1, 1 }, // 720P_HD_60FPS_LVB
262+ { 1920, 1080, 431, 335, 1079, 1919, 0, 0x0037, 0x01AC, 0, 0, 0x0040, 0, 0, 0, 0 }, // 1080P_30FPS
263+ { 2048, 1536, 431, 335, 1535, 2047, 0, 0x0037, 0x01AC, 0, 0, 0x0040, 0, 0, 0, 0 }, // 3MP CAPTURE
264+ { 2592, 1944, 431, 335, 1943, 2591, 0, 0x0037, 0x01AC, 0, 0, 0x0040, 0, 0, 0, 0 }, // 5MP CAPTURE
265+};
266+
267+
268+const struct v4l2_fract mt9p031_frameintervals[] = {
269+ { .numerator = 1, .denominator = 10 },
270+ { .numerator = 1, .denominator = 20 },
271+ { .numerator = 1, .denominator = 30 },
272+ { .numerator = 1, .denominator = 40 },
273+ { .numerator = 1, .denominator = 50 },
274+};
275+
276+
277+const u16 MT9P031_EV_GAIN_TBL[48] = {
278+ /* Gain x1 */
279+ 8, 9, 10, 11, 12, 13, 14, 15,
280+ /* Gain x2 */
281+ 16, 17, 18, 19, 20, 21, 22, 23,
282+ /* Gain x3 */
283+ 24, 25, 26, 27, 28, 29, 30, 31,
284+ /* Gain x4 */
285+ 32, 33, 34, 35,
286+ /* Gain x5 */
287+ 81, 82, 83,
288+ /* Gain x6 */
289+ 84, 85, 86, 87, 88, 89, 90, 91,
290+ /* Gain x7 */
291+ 92, 93, 94, 95, 96, 97, 98, 99,
292+ /* Gain x8 */
293+ 100,
294+};
295+
296+#ifdef MT9P031_HEADBOARD
297+/**
298+ * mt9p031_config_PCA9543A - configure on-board I2c level-shifter PCA9543A of MT9P031 Headboards from Aptina
299+ * @client: pointer to i2c client
300+ * Configures the level shifter to enable channel 0
301+ */
302+static int mt9p031_config_PCA9543A(const struct i2c_client *client)
303+{
304+ struct i2c_msg msg;
305+ int ret;
306+ u8 buf;
307+ buf = 0x21;
308+
309+ msg.addr = (0xE6 >> 1); //slave address of PCA9543A
310+ msg.flags = 0;
311+ msg.len = 1;
312+ msg.buf = &buf;
313+
314+ ret = i2c_transfer(client->adapter, &msg, 1);
315+
316+ return 0;
317+
318+}
319+#endif //MT9P031_HEADBOARD
320+
321+/**
322+ * mt9p031_reg_read - read resgiter value
323+ * @client: pointer to i2c client
324+ * @command: register address
325+ */
326+static int mt9p031_reg_read(const struct i2c_client *client, u16 command, u16 *val)
327+{
328+ struct i2c_msg msg[2];
329+ u8 buf[2];
330+ int ret;
331+
332+ // 8-bit/ byte addressable register
333+ buf[0] = command & 0xff;
334+
335+ msg[0].addr = client->addr;
336+ msg[0].flags = 0;
337+ msg[0].len = 1;
338+ msg[0].buf = buf ;
339+ ret = i2c_transfer(client->adapter, &msg[0], 1);
340+
341+ if(ret >= 0) {
342+ msg[1].addr = client->addr;
343+ msg[1].flags = I2C_M_RD; //1
344+ msg[1].len = 2;
345+ msg[1].buf = buf;
346+ ret = i2c_transfer(client->adapter, &msg[1], 1);
347+ }
348+ /*
349+ * if return value of this function is < 0,
350+ * it mean error.
351+ * else, under 16bit is valid data.
352+ */
353+ if(ret >= 0) {
354+ *val = 0;
355+ *val = buf[1] + (buf[0] << 8);
356+ return 0;
357+ }
358+
359+ v4l_err(client, "read from offset 0x%x error %d", command, ret);
360+ return ret;
361+}
362+
363+/**
364+ * mt9p031_reg_write - read resgiter value
365+ * @client: pointer to i2c client
366+ * @command: register address
367+ * @data: value to be written
368+ */
369+static int mt9p031_reg_write(const struct i2c_client *client,
370+ u16 command, u16 data)
371+{
372+ struct i2c_msg msg;
373+ u8 buf[3];
374+ int ret;
375+
376+ // 8-bit/ byte addressable register
377+
378+ buf[0] = command & 0xff;
379+ data = swab16(data);
380+ memcpy(buf + 1, &data, 2);
381+
382+ msg.addr = client->addr;
383+ msg.flags = 0;
384+ msg.len = 3;
385+ msg.buf = buf;
386+
387+ /*
388+ * i2c_transfer return message length,
389+ * but this function should return 0 if correct case
390+ */
391+ ret = i2c_transfer(client->adapter, &msg, 1);
392+ if (ret >= 0)
393+ ret = 0;
394+
395+ return ret;
396+}
397+
398+/**
399+ * struct vcontrol - Video controls
400+ * @v4l2_queryctrl: V4L2 VIDIOC_QUERYCTRL ioctl structure
401+ * @current_value: current value of this control
402+ */
403+static struct vcontrol {
404+ struct v4l2_queryctrl qc;
405+ int current_value;
406+} mt9p031_video_control[] = {
407+ {
408+ {
409+ .id = V4L2_CID_EXPOSURE,
410+ .type = V4L2_CTRL_TYPE_INTEGER,
411+ .name = "Exposure",
412+ .minimum = MT9P031_MIN_EXPOSURE,
413+ .maximum = MT9P031_MAX_EXPOSURE,
414+ .step = MT9P031_EXPOSURE_STEP,
415+ .default_value = MT9P031_DEF_EXPOSURE,
416+ },
417+ .current_value = MT9P031_DEF_EXPOSURE,
418+ },
419+ {
420+ {
421+ .id = V4L2_CID_GAIN,
422+ .type = V4L2_CTRL_TYPE_INTEGER,
423+ .name = "Analog Gain",
424+ .minimum = MT9P031_EV_MIN_GAIN,
425+ .maximum = MT9P031_EV_MAX_GAIN,
426+ .step = MT9P031_EV_GAIN_STEP,
427+ .default_value = MT9P031_EV_DEF_GAIN,
428+ },
429+ .current_value = MT9P031_EV_DEF_GAIN,
430+ },
431+};
432+
433+/**
434+ * find_vctrl - Finds the requested ID in the video control structure array
435+ * @id: ID of control to search the video control array for
436+ *
437+ * Returns the index of the requested ID from the control structure array
438+ */
439+static int
440+find_vctrl(int id)
441+{
442+ int i;
443+
444+ if (id < V4L2_CID_BASE)
445+ return -EDOM;
446+
447+ for (i = (ARRAY_SIZE(mt9p031_video_control) - 1); i >= 0; i--)
448+ if (mt9p031_video_control[i].qc.id == id)
449+ break;
450+ if (i < 0)
451+ i = -EINVAL;
452+ return i;
453+}
454+
455+/**
456+ * mt9p031_calc_size - Find the best match for a requested image capture size
457+ * @width: requested image width in pixels
458+ * @height: requested image height in pixels
459+ *
460+ * Find the best match for a requested image capture size. The best match
461+ * is chosen as the nearest match that has the same number or fewer pixels
462+ * as the requested size, or the smallest image size if the requested size
463+ * has fewer pixels than the smallest image.
464+ */
465+static enum mt9p031_image_size mt9p031_calc_size(unsigned int width,
466+ unsigned int height)
467+{
468+ enum mt9p031_image_size isize;
469+ unsigned long pixels = width * height;
470+
471+ for (isize = VGA_BIN_30FPS; isize <= MT9P031_FIVE_MP; isize++) {
472+ if (mt9p031_sizes[isize].height *
473+ mt9p031_sizes[isize].width >= pixels) {
474+
475+ return isize;
476+ }
477+ }
478+
479+ return MT9P031_FIVE_MP;
480+}
481+
482+/**
483+ * mt9p031_find_isize - Find the best match for a requested image capture size
484+ * @width: requested image width in pixels
485+ * @height: requested image height in pixels
486+ *
487+ * Find the best match for a requested image capture size. The best match
488+ * is chosen as the nearest match that has the same number or fewer pixels
489+ * as the requested size, or the smallest image size if the requested size
490+ * has fewer pixels than the smallest image.
491+ */
492+static enum mt9p031_image_size mt9p031_find_isize(unsigned int width)
493+{
494+ enum mt9p031_image_size isize;
495+
496+ for (isize = VGA_BIN_30FPS; isize <= MT9P031_FIVE_MP; isize++) {
497+ if (mt9p031_sizes[isize].width >= width)
498+ break;
499+ }
500+
501+ return isize;
502+}
503+
504+/**
505+ * mt9p031_calc_xclk - Calculate the required xclk frequency
506+ * @c: i2c client driver structure
507+ *
508+ * Given the image capture format in pix, the nominal frame period in
509+ * timeperframe, calculate and return the required xclk frequency
510+ */
511+static unsigned long mt9p031_calc_xclk(struct i2c_client *c)
512+{
513+ struct mt9p031_priv *priv = i2c_get_clientdata(c);
514+ struct v4l2_fract *timeperframe = &priv->timeperframe;
515+
516+ if (timeperframe->numerator == 0 ||
517+ timeperframe->denominator == 0) {
518+ /* supply a default nominal_timeperframe */
519+ timeperframe->numerator = 1;
520+ timeperframe->denominator = MT9P031_DEF_FPS;
521+ }
522+
523+ priv->fps = timeperframe->denominator / timeperframe->numerator;
524+ if (priv->fps < MT9P031_MIN_FPS)
525+ priv->fps = MT9P031_MIN_FPS;
526+ else if (priv->fps > MT9P031_MAX_FPS)
527+ priv->fps = MT9P031_MAX_FPS;
528+
529+ timeperframe->numerator = 1;
530+ timeperframe->denominator = priv->fps;
531+
532+ return MT9P031_XCLK_NOM_1;
533+}
534+
535+/**
536+ * mt9p031_set_params - sets register settings according to resolution
537+ * @client: pointer to standard i2c client
538+ * @width: width as queried by ioctl
539+ * @height: height as queried by ioctl
540+ */
541+static int mt9p031_set_params(struct i2c_client *client, u32 width, u32 height)
542+{
543+ struct mt9p031_priv *priv = i2c_get_clientdata(client);
544+ struct v4l2_pix_format *pix = &priv->pix;
545+ int ret;
546+ enum mt9p031_image_size i;
547+
548+ i = mt9p031_find_isize(pix->width);
549+ priv->pix.width = mt9p031_supported_formats[i].width;
550+ priv->pix.height = mt9p031_supported_formats[i].height;
551+
552+ ret = mt9p031_reg_write(client, REG_MT9P031_ROWSTART, mt9p031_supported_formats[i].row_start); //ROW_WINDOW_START_REG
553+ ret |= mt9p031_reg_write(client, REG_MT9P031_COLSTART, mt9p031_supported_formats[i].col_start); //COL_WINDOW_START_REG
554+ ret |= mt9p031_reg_write(client, REG_MT9P031_HEIGHT, mt9p031_supported_formats[i].row_size); //ROW_WINDOW_SIZE_REG=1439
555+ ret |= mt9p031_reg_write(client, REG_MT9P031_WIDTH, mt9p031_supported_formats[i].col_size); //COL_WINDOW_SIZE_REG=2559
556+ ret |= mt9p031_reg_write(client, REG_MT9P031_HBLANK, mt9p031_supported_formats[i].hblank); //HORZ_BLANK=0
557+ ret |= mt9p031_reg_write(client, REG_MT9P031_VBLANK, mt9p031_supported_formats[i].vblank); //VERT_BLANK_REG=720
558+ ret |= mt9p031_reg_write(client, REG_MT9P031_SHUTTER_WIDTH_L, 0x0400); //SHUTTER_WIDTH_LOW (INTEG_TIME_REG = 1024)
559+ ret |= mt9p031_reg_write(client, REG_MT9P031_ROW_ADDR_MODE, mt9p031_supported_formats[i].row_addr_mode); //ROW_MODE, ROW_SKIP=1, ROW_BIN=1
560+ ret |= mt9p031_reg_write(client, REG_MT9P031_COL_ADDR_MODE, mt9p031_supported_formats[i].col_addr_mode); //COL_MODE, COL_SKIP=1, COL_BIN=1
561+ ret |= mt9p031_reg_write(client, REG_MT9P031_READ_MODE2, mt9p031_supported_formats[i].read_mode_2_config); //READ_MODE_2, COL_SUM
562+ ret |= mt9p031_reg_write(client, REG_MT9P031_SHUTTER_WIDTH_U, mt9p031_supported_formats[i].shutter_width_hi); //SHUTTER_WIDTH_HI
563+ ret |= mt9p031_reg_write(client, REG_MT9P031_SHUTTER_WIDTH_L, mt9p031_supported_formats[i].integ_time); //SHUTTER_WIDTH_LOW (INTEG_TIME_REG)
564+ ret |= mt9p031_reg_write(client, REG_MT9P031_SHUTTER_DELAY, mt9p031_supported_formats[i].shutter_delay); //SHUTTER_DELAY_REG
565+
566+ return ret;
567+}
568+
569+/**
570+ * mt9p031_init_camera - initialize camera settings
571+ * @client: pointer to i2c client
572+ * Initialize camera settings
573+ */
574+static int mt9p031_init_camera(const struct i2c_client *client)
575+{
576+ int ret;
577+ struct mt9p031_priv *priv = i2c_get_clientdata(client);
578+ struct v4l2_pix_format *pix = &priv->pix;
579+
580+ ret = mt9p031_reg_write(client, REG_MT9P031_PLL_CTRL, 0x0051); //PLL_CTRL; power up pll
581+ ret |= mt9p031_reg_write(client, REG_MT9P031_PLL_CONF1, 0x1801); //PLL_CONFIG_1: m=24, n=1
582+ ret |= mt9p031_reg_write(client, REG_MT9P031_PLL_CONF2, 0x0002); //PLL_CONFIG_2: p1=2, p2=0
583+ mdelay(10); //wait 10 ms for VCO to lock
584+ ret |= mt9p031_reg_write(client, REG_MT9P031_PLL_CTRL, 0x0053); //PLL_CONTROL; use PLL
585+ mdelay(200);
586+
587+ ret |= mt9p031_set_params(priv->client, pix->width, pix->height);
588+
589+ ret |= mt9p031_reg_write(client, REG_MT9P031_RESET, 0x0001); //High
590+ ret |= mt9p031_reg_write(client, REG_MT9P031_RESET, 0x0000); //Low
591+ mdelay(100);
592+
593+ ret |= mt9p031_reg_write(client, REG_MT9P031_GREEN_1_GAIN, 0x0051); //Green1_gain_reg
594+ ret |= mt9p031_reg_write(client, REG_MT9P031_BLUE_GAIN, 0x0051); //Blue_gain_reg
595+ ret |= mt9p031_reg_write(client, REG_MT9P031_RED_GAIN, 0x0051); //Red_gain_reg
596+ ret |= mt9p031_reg_write(client, REG_MT9P031_GREEN_2_GAIN, 0x0051); //Green2_gain_reg
597+ ret |= mt9p031_reg_write(client, REG_MT9P031_GLOBAL_GAIN, 0x0008); //Analog Gain
598+ ret |= mt9p031_reg_write(client, REG_MT9P031_READ_MODE1, 0x0006); //Read_mode_1 //disable AB
599+ ret |= mt9p031_reg_write(client, REG_MT9P031_OUT_CTRL, 0x1F8E); //Enable parll fifo data
600+
601+ return ret>= 0 ? 0 : -EIO;
602+}
603+
604+/************************************************************************
605+ i2c driver
606+************************************************************************/
607+/**
608+ * mt9p031_detect - Detect if an mt9p031 is present, and if so which revision
609+ * @client: pointer to the i2c client driver structure
610+ *
611+ * Returns a negative error number if no device is detected
612+ */
613+static int mt9p031_detect(struct i2c_client *client)
614+{
615+ struct mt9p031_priv *priv = i2c_get_clientdata(client);
616+ const char *devname;
617+ u16 chipid;
618+
619+ if (!client)
620+ return -ENODEV;
621+ /*
622+ * Set Normal Mode
623+ */
624+ if(mt9p031_reg_write(client, REG_MT9P031_OUT_CTRL, MT9P031_NORMAL_OPERATION_MODE))
625+ return -ENODEV;
626+ /*
627+ * check and show chip ID
628+ */
629+ if(mt9p031_reg_read(client, REG_MT9P031_CHIP_VERSION, &chipid))
630+ return -ENODEV;
631+
632+ if(chipid == MT9P031_CHIP_ID) {
633+ devname = "mt9p031";
634+ priv->model = V4L2_IDENT_MT9P031;
635+ dev_info(&client->dev, "%s chip ID %04x\n", devname, chipid);
636+ return 0;
637+ }
638+
639+ dev_err(&client->dev, "Product ID error %04x\n", chipid);
640+ return -ENODEV;
641+}
642+
643+/**
644+ * mt9p031_set_exposure_time - sets exposure time per input value
645+ * @exp_time: exposure time to be set on device
646+ * @client: pointer to standard i2c client
647+ * @lvc: pointer to V4L2 exposure entry in video_controls array
648+ *
649+ * If the requested exposure time is within the allowed limits, the HW
650+ * is configured to use the new exposure time, and the video_controls
651+ * array is updated with the new current value.
652+ * The function returns 0 upon success. Otherwise an error code is
653+ * returned.
654+ */
655+static int mt9p031_set_exposure_time(u32 exp_time, struct i2c_client *client,
656+ struct vcontrol *lvc)
657+{
658+ int ret = 0, i, shutter_width, so_p, t_pix_clk, sd_p, shutter_delay;
659+ int sw_l ,sw_u ,W ,h_blanking, t_row;
660+
661+ if(exp_time < MT9P031_MIN_EXPOSURE)
662+ exp_time = MT9P031_MIN_EXPOSURE;
663+ else if(exp_time > MT9P031_MAX_EXPOSURE)
664+ exp_time = MT9P031_MAX_EXPOSURE;
665+
666+ shutter_delay = mt9p031_supported_formats[mt9p031_current_format].shutter_delay;
667+ sd_p = min(shutter_delay + 1, 1504);
668+ so_p = 208 * (mt9p031_supported_formats[mt9p031_current_format].row_bin + 1) + 98 + sd_p - 94;
669+ t_pix_clk = (Q12/96 );
670+ h_blanking = mt9p031_supported_formats[mt9p031_current_format].hblank + 1;
671+ W = 2 * (int)((mt9p031_supported_formats[mt9p031_current_format].row_size + 1) / (2 * (mt9p031_supported_formats[mt9p031_current_format].row_bin + 1)) + 1);
672+ t_row = 2 * t_pix_clk * max(W/2 + max(h_blanking, hb_min[mt9p031_supported_formats[mt9p031_current_format].row_bin][mt9p031_supported_formats[mt9p031_current_format].col_bin]),
673+ (41 + 346 * (mt9p031_supported_formats[mt9p031_current_format].row_bin + 1) + 99))/Q12;
674+
675+ shutter_width = (exp_time + 2*so_p*t_pix_clk) / t_row;
676+
677+ if (shutter_width< 3) {
678+ sd_p = 1232 > shutter_delay ? 1232 : shutter_delay;
679+ so_p = 208 * (mt9p031_supported_formats[mt9p031_current_format].row_bin + 1) + 98 + sd_p - 94;
680+ shutter_width = ((exp_time*Q12 + 2*so_p*t_pix_clk) / (t_row * Q12));
681+ }
682+
683+ if (shutter_width < 1)
684+ shutter_width = 1;
685+ sw_l = shutter_width& 0xffff;
686+ sw_u = (shutter_width)>> 16;
687+ ret = mt9p031_reg_write(client, REG_MT9P031_SHUTTER_WIDTH_L,sw_l);
688+ mdelay(1);
689+ ret = mt9p031_reg_write(client, REG_MT9P031_SHUTTER_WIDTH_U,sw_u);
690+
691+ if (ret)
692+ dev_err(&client->dev, "Error setting exposure time %d\n",
693+ ret);
694+ else{
695+ i = find_vctrl(V4L2_CID_EXPOSURE);
696+ if (i >= 0) {
697+ lvc = &mt9p031_video_control[i];
698+ lvc->current_value = exp_time;
699+ }
700+ }
701+
702+ return ret;
703+}
704+
705+/**
706+ * mt9p031_set_gain - sets sensor analog gain per input value
707+ * @lineargain: analog gain value index to be set on device
708+ * @client: pointer to standard i2c client
709+ * @lvc: pointer to V4L2 analog gain entry in video_controls array
710+ *
711+ * If the requested analog gain is within the allowed limits, the HW
712+ * is configured to use the new gain value, and the video_controls
713+ * array is updated with the new current value.
714+ * The function returns 0 upon success. Otherwise an error code is
715+ * returned.
716+ */
717+int mt9p031_set_gain(u16 lineargain, struct i2c_client *client,
718+ struct vcontrol *lvc)
719+{
720+ int ret= 0, i;
721+ u16 reg_gain = 0;
722+
723+ if (lineargain < MT9P031_EV_MIN_GAIN) {
724+ lineargain = MT9P031_EV_MIN_GAIN;
725+ v4l_err(client, "Gain out of legal range.");
726+ }
727+ if (lineargain > MT9P031_EV_MAX_GAIN) {
728+ lineargain = MT9P031_EV_MAX_GAIN;
729+ v4l_err(client, "Gain out of legal range.");
730+ }
731+
732+ reg_gain = MT9P031_EV_GAIN_TBL[lineargain];
733+ ret = mt9p031_reg_write(client, REG_MT9P031_GLOBAL_GAIN,
734+ reg_gain);
735+
736+ if (ret) {
737+ dev_err(&client->dev, "Error setting gain.%d", ret);
738+ return ret;
739+ }
740+ else {
741+ i = find_vctrl(V4L2_CID_GAIN);
742+ if (i >= 0) {
743+ lvc = &mt9p031_video_control[i];
744+ lvc->current_value = lineargain;
745+ }
746+ }
747+
748+ return ret;
749+}
750+
751+/************************************************************************
752+ v4l2_ioctls
753+************************************************************************/
754+
755+/**
756+ * mt9p031_v4l2_int_s_power - V4L2 sensor interface handler for vidioc_int_s_power_num
757+ * @s: pointer to standard V4L2 device structure
758+ * @on: power state to which device is to be set
759+ *
760+ * Sets devices power state to requrested state, if possible.
761+ */
762+static int mt9p031_v4l2_int_s_power(struct v4l2_int_device *s,
763+ enum v4l2_power power)
764+{
765+ struct mt9p031_priv *priv = s->priv;
766+ struct i2c_client *client = priv->client;
767+
768+ int ret;
769+
770+ switch (power) {
771+ case V4L2_POWER_STANDBY:
772+ /* FALLTHROUGH */
773+ case V4L2_POWER_OFF:
774+ ret = priv->pdata->power_set(s, power);
775+ if (ret < 0) {
776+ dev_err(&client->dev, "Unable to set target board power "
777+ "state (OFF/STANDBY)\n");
778+ return ret;
779+ }
780+ break;
781+ case V4L2_POWER_ON:
782+ ret = priv->pdata->power_set(s, power);
783+
784+ if (ret < 0) {
785+ dev_err(&client->dev, "Unable to set target board power "
786+ "state (ON)\n");
787+ return ret;
788+ }
789+ if (!(priv->flags & INIT_DONE)) {
790+ ret = mt9p031_detect(client);
791+ if (ret < 0) {
792+ dev_err(&client->dev, "Unable to detect sensor\n");
793+ return ret;
794+ }
795+ priv->flags |= INIT_DONE;
796+ }
797+
798+ ret = mt9p031_init_camera(client);
799+ if (ret < 0) {
800+ dev_err(&client->dev, "Unable to initialize sensor\n");
801+ return ret;
802+ }
803+ }
804+
805+ return 0;
806+}
807+
808+/**
809+ * mt9p031_v4l2_s_ctrl - V4L2 sensor interface handler for VIDIOC_S_CTRL ioctl
810+ * @s: pointer to standard V4L2 device structure
811+ * @vc: standard V4L2 VIDIOC_S_CTRL ioctl structure
812+ *
813+ * If the requested control is supported, sets the control's current
814+ * value in HW (and updates the video_control[] array). Otherwise,
815+ * returns -EINVAL if the control is not supported.
816+ */
817+static int mt9p031_v4l2_s_ctrl(struct v4l2_int_device *s,
818+ struct v4l2_control *vc)
819+{
820+ int retval = -EINVAL;
821+ int i;
822+ struct vcontrol *lvc;
823+ struct mt9p031_priv *priv = s->priv;
824+ struct i2c_client *client = priv->client;
825+
826+ i = find_vctrl(vc->id);
827+ if (i < 0)
828+ return -EINVAL;
829+ lvc = &mt9p031_video_control[i];
830+
831+ switch (vc->id) {
832+ case V4L2_CID_EXPOSURE:
833+ retval = mt9p031_set_exposure_time(vc->value, client, lvc);
834+ break;
835+ case V4L2_CID_GAIN:
836+ retval = mt9p031_set_gain(vc->value, client, lvc);
837+ break;
838+ }
839+
840+ return retval;
841+}
842+
843+/**
844+ * mt9p031_v4l2_g_ctrl - V4L2 sensor interface handler for VIDIOC_G_CTRL ioctl
845+ * @s: pointer to standard V4L2 device structure
846+ * @vc: standard V4L2 VIDIOC_G_CTRL ioctl structure
847+ *
848+ * If the requested control is supported, returns the control's current
849+ * value from the video_control[] array. Otherwise, returns -EINVAL
850+ * if the control is not supported.
851+ */
852+static int mt9p031_v4l2_g_ctrl(struct v4l2_int_device *s,
853+ struct v4l2_control *vc)
854+{
855+ struct vcontrol *lvc;
856+ int i;
857+
858+ i = find_vctrl(vc->id);
859+ if (i < 0)
860+ return -EINVAL;
861+ lvc = &mt9p031_video_control[i];
862+
863+ switch (vc->id) {
864+ case V4L2_CID_EXPOSURE:
865+ vc->value = lvc->current_value;
866+ break;
867+ case V4L2_CID_GAIN:
868+ vc->value = lvc->current_value;
869+ break;
870+ }
871+
872+ return 0;
873+}
874+
875+/**
876+ * mt9p031_v4l2_queryctrl - V4L2 sensor interface handler for VIDIOC_QUERYCTRL ioctl
877+ * @s: pointer to standard V4L2 device structure
878+ * @qc: standard V4L2 VIDIOC_QUERYCTRL ioctl structure
879+ *
880+ * If the requested control is supported, returns the control information
881+ * from the video_control[] array. Otherwise, returns -EINVAL if the
882+ * control is not supported.
883+ */
884+static int mt9p031_v4l2_queryctrl(struct v4l2_int_device *s, struct v4l2_queryctrl *qc)
885+{
886+ int i;
887+
888+ i = find_vctrl(qc->id);
889+ if (i == -EINVAL)
890+ qc->flags = V4L2_CTRL_FLAG_DISABLED;
891+
892+ if (i < 0)
893+ return -EINVAL;
894+
895+ *qc = mt9p031_video_control[i].qc;
896+ return 0;
897+}
898+
899+
900+/**
901+ * mt9p031_v4l2_int_enum_fmt_cap - Implement the CAPTURE buffer VIDIOC_ENUM_FMT ioctl
902+ * @s: pointer to standard V4L2 device structure
903+ * @fmt: standard V4L2 VIDIOC_ENUM_FMT ioctl structure
904+ *
905+ * Implement the VIDIOC_ENUM_FMT ioctl for the CAPTURE buffer type.
906+ */
907+static int mt9p031_v4l2_int_enum_fmt_cap(struct v4l2_int_device *s,
908+ struct v4l2_fmtdesc *fmt)
909+{
910+ int index = fmt->index;
911+ enum v4l2_buf_type type = fmt->type;
912+
913+ memset(fmt, 0, sizeof(*fmt));
914+ fmt->index = index;
915+ fmt->type = type;
916+
917+ switch (fmt->type) {
918+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
919+ if (index >= ARRAY_SIZE(mt9p031_formats))
920+ return -EINVAL;
921+ break;
922+ default:
923+ return -EINVAL;
924+ }
925+
926+ strlcpy(fmt->description, mt9p031_formats[index].description,
927+ sizeof(fmt->description));
928+ fmt->pixelformat = mt9p031_formats[index].pixelformat;
929+
930+ return 0;
931+}
932+
933+/**
934+ * mt9p031_v4l2_int_try_fmt_cap - Implement the CAPTURE buffer VIDIOC_TRY_FMT ioctl
935+ * @s: pointer to standard V4L2 device structure
936+ * @f: pointer to standard V4L2 VIDIOC_TRY_FMT ioctl structure
937+ *
938+ * Implement the VIDIOC_TRY_FMT ioctl for the CAPTURE buffer type. This
939+ * ioctl is used to negotiate the image capture size and pixel format
940+ * without actually making it take effect.
941+ */
942+static int mt9p031_v4l2_int_try_fmt_cap(struct v4l2_int_device *s,
943+ struct v4l2_format *f)
944+{
945+ enum mt9p031_image_size isize;
946+ int ifmt;
947+ struct v4l2_pix_format *pix = &f->fmt.pix;
948+ struct mt9p031_priv *priv = s->priv;
949+ struct v4l2_pix_format *pix2 = &priv->pix;
950+
951+ isize = mt9p031_calc_size(pix->width, pix->height);
952+ mt9p031_current_format = isize;
953+
954+ pix->width = mt9p031_sizes[isize].width;
955+ pix->height = mt9p031_sizes[isize].height;
956+ for (ifmt = 0; ifmt < mt9p031_num_formats; ifmt++) {
957+ if (pix->pixelformat == mt9p031_formats[ifmt].pixelformat)
958+ break;
959+ }
960+ if (ifmt == mt9p031_num_formats)
961+ ifmt = 0;
962+ pix->pixelformat = mt9p031_formats[ifmt].pixelformat;
963+ pix->field = V4L2_FIELD_NONE;
964+ pix->bytesperline = pix->width * 2;
965+ pix->sizeimage = pix->bytesperline * pix->height;
966+ pix->priv = 0;
967+ pix->colorspace = V4L2_COLORSPACE_SRGB;
968+
969+ *pix2 = *pix;
970+
971+ return 0;
972+}
973+
974+/**
975+ * mt9p031_v4l2_int_s_fmt_cap - V4L2 sensor interface handler for VIDIOC_S_FMT ioctl
976+ * @s: pointer to standard V4L2 device structure
977+ * @f: pointer to standard V4L2 VIDIOC_S_FMT ioctl structure
978+ *
979+ * If the requested format is supported, configures the HW to use that
980+ * format, returns error code if format not supported or HW can't be
981+ * correctly configured.
982+ */
983+static int mt9p031_v4l2_int_s_fmt_cap(struct v4l2_int_device *s,
984+ struct v4l2_format *f)
985+{
986+ struct mt9p031_priv *priv = s->priv;
987+ struct v4l2_pix_format *pix = &f->fmt.pix;
988+ int rval;
989+
990+ rval = mt9p031_v4l2_int_try_fmt_cap(s, f);
991+ if (!rval)
992+ priv->pix = *pix;
993+
994+ return rval;
995+}
996+
997+/**
998+ * mt9p031_v4l2_int_g_fmt_cap - V4L2 sensor interface handler for ioctl_g_fmt_cap
999+ * @s: pointer to standard V4L2 device structure
1000+ * @f: pointer to standard V4L2 v4l2_format structure
1001+ *
1002+ * Returns the sensor's current pixel format in the v4l2_format
1003+ * parameter.
1004+ */
1005+static int mt9p031_v4l2_int_g_fmt_cap(struct v4l2_int_device *s,
1006+ struct v4l2_format *f)
1007+{
1008+ struct mt9p031_priv *priv = s->priv;
1009+
1010+ f->fmt.pix.width = priv->pix.width;
1011+ f->fmt.pix.height = priv->pix.height;
1012+ f->fmt.pix.pixelformat = V4L2_COLORSPACE_SRGB;
1013+ f->fmt.pix.pixelformat = priv->pix.pixelformat;
1014+ f->fmt.pix.field = V4L2_FIELD_NONE;
1015+
1016+ return 0;
1017+}
1018+
1019+/**
1020+ * mt9p031_v4l2_int_s_parm - V4L2 sensor interface handler for VIDIOC_S_PARM ioctl
1021+ * @s: pointer to standard V4L2 device structure
1022+ * @a: pointer to standard V4L2 VIDIOC_S_PARM ioctl structure
1023+ *
1024+ * Configures the sensor to use the input parameters, if possible. If
1025+ * not possible, reverts to the old parameters and returns the
1026+ * appropriate error code.
1027+ */
1028+
1029+
1030+static int mt9p031_v4l2_int_s_parm(struct v4l2_int_device *s,
1031+ struct v4l2_streamparm *a)
1032+{
1033+ struct mt9p031_priv *priv = s->priv;
1034+ struct i2c_client *client = priv->client;
1035+ struct v4l2_fract *timeperframe = &a->parm.capture.timeperframe;
1036+
1037+ priv->timeperframe = *timeperframe;
1038+ priv->xclk_current = mt9p031_calc_xclk(client);
1039+ *timeperframe = priv->timeperframe;
1040+
1041+ return 0;
1042+}
1043+
1044+/**
1045+ * mt9p031_v4l2_int_g_parm - V4L2 sensor interface handler for VIDIOC_G_PARM ioctl
1046+ * @s: pointer to standard V4L2 device structure
1047+ * @a: pointer to standard V4L2 VIDIOC_G_PARM ioctl structure
1048+ *
1049+ * Returns the sensor's video CAPTURE parameters.
1050+ */
1051+static int mt9p031_v4l2_int_g_parm(struct v4l2_int_device *s,
1052+ struct v4l2_streamparm *a)
1053+{
1054+ struct mt9p031_priv *priv = s->priv;
1055+ struct v4l2_captureparm *cparm = &a->parm.capture;
1056+
1057+ if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1058+ return -EINVAL;
1059+
1060+ memset(a, 0, sizeof(*a));
1061+ a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1062+
1063+ cparm->capability = V4L2_CAP_TIMEPERFRAME;
1064+ cparm->timeperframe.numerator = 1;
1065+ cparm->timeperframe = priv->timeperframe;
1066+
1067+ return 0;
1068+}
1069+
1070+/**
1071+ * mt9p031_v4l2_int_g_priv - V4L2 sensor interface handler for vidioc_int_g_priv_num
1072+ * @s: pointer to standard V4L2 device structure
1073+ * @p: void pointer to hold sensor's private data address
1074+ *
1075+ * Returns device's (sensor's) private data area address in p parameter
1076+ */
1077+static int mt9p031_v4l2_int_g_priv(struct v4l2_int_device *s, void *p)
1078+{
1079+ struct mt9p031_priv *priv = s->priv;
1080+
1081+ return priv->pdata->priv_data_set(p);
1082+}
1083+
1084+/**
1085+ * mt9p031_v4l2_int_g_ifparm - V4L2 sensor interface handler for vidioc_int_g_priv_num
1086+ * @s: pointer to standard V4L2 device structure
1087+ * @p: void pointer to hold sensor's ifparm
1088+ *
1089+ * Returns device's (sensor's) ifparm in p parameter
1090+ */
1091+static int mt9p031_v4l2_int_g_ifparm(struct v4l2_int_device *s,
1092+ struct v4l2_ifparm *p)
1093+{
1094+ struct mt9p031_priv *priv = s->priv;
1095+ int rval;
1096+
1097+ if (p == NULL)
1098+ return -EINVAL;
1099+
1100+ if (!priv->pdata->ifparm)
1101+ return -EINVAL;
1102+
1103+ rval = priv->pdata->ifparm(p);
1104+ if (rval) {
1105+ v4l_err(priv->client, "g_ifparm.Err[%d]\n", rval);
1106+ return rval;
1107+ }
1108+
1109+ return 0;
1110+}
1111+
1112+/**
1113+ * mt9p031_v4l2_int_enum_framesizes - V4L2 sensor if handler for vidioc_int_enum_framesizes
1114+ * @s: pointer to standard V4L2 device structure
1115+ * @frms: pointer to standard V4L2 framesizes enumeration structure
1116+ *
1117+ * Returns possible framesizes depending on choosen pixel format
1118+ */
1119+static int mt9p031_v4l2_int_enum_framesizes(struct v4l2_int_device *s,
1120+ struct v4l2_frmsizeenum *frms)
1121+{
1122+ int ifmt;
1123+
1124+ for (ifmt = 0; ifmt < ARRAY_SIZE(mt9p031_formats); ifmt++)
1125+ if (mt9p031_formats[ifmt].pixelformat == frms->pixel_format)
1126+ break;
1127+
1128+ if (ifmt == ARRAY_SIZE(mt9p031_formats))
1129+ return -EINVAL;
1130+
1131+ /* Do we already reached all discrete framesizes? */
1132+ if (frms->index >= ARRAY_SIZE(mt9p031_sizes))
1133+ return -EINVAL;
1134+
1135+ frms->type = V4L2_FRMSIZE_TYPE_DISCRETE;
1136+ frms->discrete.width = mt9p031_sizes[frms->index].width;
1137+ frms->discrete.height = mt9p031_sizes[frms->index].height;
1138+
1139+ return 0;
1140+}
1141+
1142+static int mt9p031_v4l2_int_enum_frameintervals(struct v4l2_int_device *s,
1143+ struct v4l2_frmivalenum *frmi)
1144+{
1145+ int ifmt;
1146+ int max_size;
1147+
1148+ for (ifmt = 0; ifmt < ARRAY_SIZE(mt9p031_formats); ifmt++)
1149+ if (mt9p031_formats[ifmt].pixelformat == frmi->pixel_format)
1150+ break;
1151+
1152+ if (ifmt == ARRAY_SIZE(mt9p031_formats))
1153+ return -EINVAL;
1154+
1155+ max_size = ARRAY_SIZE(mt9p031_sizes);
1156+
1157+ for(ifmt = 0; ifmt < max_size; ifmt++) {
1158+ if(frmi->width <= mt9p031_sizes[ifmt].width) {
1159+ frmi->type = V4L2_FRMSIZE_TYPE_DISCRETE;
1160+ frmi->discrete.numerator =
1161+ mt9p031_frameintervals[frmi->index].numerator;
1162+ frmi->discrete.denominator =
1163+ mt9p031_frameintervals[frmi->index].denominator;
1164+
1165+ if(frmi->discrete.denominator <= mt9p031_frameintervals[max_size - ifmt - 1].denominator)
1166+ return 0;
1167+ else
1168+ return -EINVAL;
1169+ }
1170+ }
1171+
1172+ return 0;
1173+}
1174+
1175+static struct v4l2_int_ioctl_desc mt9p031_ioctl_desc[] = {
1176+ { .num = vidioc_int_enum_framesizes_num,
1177+ .func = (v4l2_int_ioctl_func *)mt9p031_v4l2_int_enum_framesizes },
1178+ { .num = vidioc_int_enum_frameintervals_num,
1179+ .func = (v4l2_int_ioctl_func *)mt9p031_v4l2_int_enum_frameintervals },
1180+ { .num = vidioc_int_s_power_num,
1181+ .func = (v4l2_int_ioctl_func *)mt9p031_v4l2_int_s_power },
1182+ { .num = vidioc_int_g_priv_num,
1183+ .func = (v4l2_int_ioctl_func *)mt9p031_v4l2_int_g_priv },
1184+ { .num = vidioc_int_g_ifparm_num,
1185+ .func = (v4l2_int_ioctl_func *)mt9p031_v4l2_int_g_ifparm },
1186+ { .num = vidioc_int_enum_fmt_cap_num,
1187+ .func = (v4l2_int_ioctl_func *)mt9p031_v4l2_int_enum_fmt_cap },
1188+ { .num = vidioc_int_try_fmt_cap_num,
1189+ .func = (v4l2_int_ioctl_func *)mt9p031_v4l2_int_try_fmt_cap },
1190+ { .num = vidioc_int_g_fmt_cap_num,
1191+ .func = (v4l2_int_ioctl_func *)mt9p031_v4l2_int_g_fmt_cap },
1192+ { .num = vidioc_int_s_fmt_cap_num,
1193+ .func = (v4l2_int_ioctl_func *)mt9p031_v4l2_int_s_fmt_cap },
1194+ { .num = vidioc_int_g_parm_num,
1195+ .func = (v4l2_int_ioctl_func *)mt9p031_v4l2_int_g_parm },
1196+ { .num = vidioc_int_s_parm_num,
1197+ .func = (v4l2_int_ioctl_func *)mt9p031_v4l2_int_s_parm },
1198+ { .num = vidioc_int_g_ctrl_num,
1199+ .func = (v4l2_int_ioctl_func *)mt9p031_v4l2_g_ctrl },
1200+ { .num = vidioc_int_s_ctrl_num,
1201+ .func = (v4l2_int_ioctl_func *)mt9p031_v4l2_s_ctrl },
1202+ { .num = vidioc_int_queryctrl_num,
1203+ .func = (v4l2_int_ioctl_func *)mt9p031_v4l2_queryctrl },
1204+};
1205+
1206+#ifdef MT9P031_DEBUG
1207+/**
1208+ * ---------------------------------------------------------------------------------
1209+ * Sysfs
1210+ * ---------------------------------------------------------------------------------
1211+ */
1212+
1213+/* Basic register read write support */
1214+static u16 mt9p031_attr_basic_addr = 0x0000;
1215+
1216+static ssize_t
1217+mt9p031_basic_reg_addr_show( struct device *dev, struct device_attribute *attr, char *buf)
1218+{
1219+ return sprintf(buf, "0x%x\n", mt9p031_attr_basic_addr);
1220+}
1221+
1222+static ssize_t
1223+mt9p031_basic_reg_addr_store( struct device *dev, struct device_attribute *attr, const char *buf, size_t n)
1224+{
1225+ u16 val;
1226+ sscanf(buf, "%hx", &val);
1227+ mt9p031_attr_basic_addr = (u16) val;
1228+ return n;
1229+}
1230+
1231+static DEVICE_ATTR( basic_reg_addr, S_IRUGO|S_IWUSR, mt9p031_basic_reg_addr_show, mt9p031_basic_reg_addr_store);
1232+
1233+
1234+static ssize_t
1235+mt9p031_basic_reg_val_show( struct device *dev, struct device_attribute *attr, char *buf)
1236+{
1237+ u16 val;
1238+ int ret;
1239+ ret = mt9p031_reg_read(sysPriv.client, mt9p031_attr_basic_addr, &val);
1240+ if(ret < 0){
1241+ printk(KERN_INFO "mt9p031: Basic register read failed");
1242+ return 1; // nothing processed
1243+ } else {
1244+ return sprintf(buf, "0x%x\n", val);
1245+ }
1246+}
1247+
1248+static ssize_t
1249+mt9p031_basic_reg_val_store( struct device *dev, struct device_attribute *attr, const char *buf, size_t n)
1250+{
1251+ u32 val;
1252+ sscanf(buf, "%x", &val);
1253+
1254+ if (mt9p031_reg_write(sysPriv.client, mt9p031_attr_basic_addr, (u16)val)) {
1255+ printk(KERN_INFO "mt9p031: Basic regiser write failed");
1256+ return n; // nothing processed
1257+ } else {
1258+ return n;
1259+ }
1260+}
1261+static DEVICE_ATTR( basic_reg_val, S_IRUGO|S_IWUSR, mt9p031_basic_reg_val_show, mt9p031_basic_reg_val_store);
1262+
1263+
1264+/* Exposure time access support */
1265+static ssize_t
1266+mt9p031_exposure_val_show( struct device *dev, struct device_attribute *attr, char *buf)
1267+{
1268+ u32 val;
1269+ struct vcontrol *lvc;
1270+ int i = find_vctrl(V4L2_CID_EXPOSURE);
1271+ if (i < 0)
1272+ return -EINVAL;
1273+ lvc = &mt9p031_video_control[i];
1274+ val = lvc->current_value;
1275+
1276+ if(val < 0){
1277+ printk(KERN_INFO "mt9p031: Exposure value read failed");
1278+ return 1; // nothing processed
1279+ } else {
1280+ return sprintf(buf, "%d\n", val);
1281+ }
1282+}
1283+
1284+
1285+static ssize_t
1286+mt9p031_exposure_val_store( struct device *dev, struct device_attribute *attr, const char *buf, size_t n)
1287+{
1288+ u32 val;
1289+ struct i2c_client *client;
1290+ struct vcontrol *lvc;
1291+
1292+ sscanf(buf, "%d", &val);
1293+ client = sysPriv.client;
1294+
1295+ lvc = &mt9p031_video_control[V4L2_CID_EXPOSURE];
1296+
1297+ if (mt9p031_set_exposure_time((u32)val, client, lvc)) {
1298+ printk(KERN_INFO "mt9p031: Exposure write failed");
1299+ return n; // nothing processed
1300+ } else {
1301+ return n;
1302+ }
1303+}
1304+
1305+static DEVICE_ATTR( exposure_val, S_IRUGO|S_IWUSR, mt9p031_exposure_val_show, mt9p031_exposure_val_store);
1306+
1307+
1308+/* Global Gain access support */
1309+static ssize_t
1310+mt9p031_gain_val_show( struct device *dev, struct device_attribute *attr, char *buf)
1311+{
1312+ u16 val;
1313+ struct vcontrol *lvc;
1314+
1315+ int i = find_vctrl(V4L2_CID_GAIN);
1316+ if (i < 0)
1317+ return -EINVAL;
1318+ lvc = &mt9p031_video_control[i];
1319+ val = lvc->current_value;
1320+
1321+ if(val < 0){
1322+ printk(KERN_INFO "mt9p031: Global Gain value read failed");
1323+ return 1; // nothing processed
1324+ } else {
1325+ return sprintf(buf, "%d\n", val);
1326+ }
1327+}
1328+
1329+static ssize_t
1330+mt9p031_gain_val_store( struct device *dev, struct device_attribute *attr, const char *buf, size_t n)
1331+{
1332+ u16 val;
1333+ struct i2c_client *client;
1334+ struct vcontrol *lvc;
1335+
1336+ sscanf(buf, "%hd", &val);
1337+ client = sysPriv.client;
1338+
1339+ lvc = &mt9p031_video_control[V4L2_CID_GAIN];
1340+
1341+ if (mt9p031_set_gain(val, client, lvc)) {
1342+ printk(KERN_INFO "mt9p031: Global gain write failed");
1343+ return n; // nothing processed
1344+ } else {
1345+ return n;
1346+ }
1347+}
1348+
1349+static DEVICE_ATTR( gain_val, S_IRUGO|S_IWUSR, mt9p031_gain_val_show, mt9p031_gain_val_store);
1350+
1351+
1352+static struct attribute *mt9p031_sysfs_attr[] = {
1353+ &dev_attr_basic_reg_addr.attr,
1354+ &dev_attr_basic_reg_val.attr,
1355+ &dev_attr_exposure_val.attr,
1356+ &dev_attr_gain_val.attr,
1357+};
1358+
1359+static int mt9p031_sysfs_add(struct kobject *kobj)
1360+{
1361+ int i = ARRAY_SIZE(mt9p031_sysfs_attr);
1362+ int rval = 0;
1363+
1364+ do {
1365+ rval = sysfs_create_file(kobj, mt9p031_sysfs_attr[--i]);
1366+ } while((i > 0) && (rval == 0));
1367+ return rval;
1368+}
1369+
1370+static int mt9p031_sysfs_rm(struct kobject *kobj)
1371+{
1372+ int i = ARRAY_SIZE(mt9p031_sysfs_attr);
1373+ int rval = 0;
1374+
1375+ do {
1376+ sysfs_remove_file(kobj, mt9p031_sysfs_attr[--i]);
1377+ } while(i > 0);
1378+ return rval;
1379+}
1380+#endif //MT9P031_DEBUG
1381+
1382+static struct v4l2_int_slave mt9p031_slave = {
1383+ .ioctls = mt9p031_ioctl_desc,
1384+ .num_ioctls = ARRAY_SIZE(mt9p031_ioctl_desc),
1385+};
1386+
1387+static int mt9p031_probe(struct i2c_client *client,
1388+ const struct i2c_device_id *did)
1389+{
1390+ struct mt9p031_priv *priv;
1391+ struct v4l2_int_device *v4l2_int_device;
1392+ int ret;
1393+ if (!client->dev.platform_data) {
1394+ dev_err(&client->dev, "no platform data?\n");
1395+ return -ENODEV;
1396+ }
1397+
1398+ priv = kzalloc(sizeof(*priv), GFP_KERNEL);
1399+ if (!priv)
1400+ return -ENOMEM;
1401+
1402+ v4l2_int_device = kzalloc(sizeof(*v4l2_int_device), GFP_KERNEL);
1403+ if (!v4l2_int_device) {
1404+ kfree(priv);
1405+ return -ENOMEM;
1406+ }
1407+
1408+#ifdef MT9P031_HEADBOARD
1409+ mt9p031_config_PCA9543A(client); //configure i2c level shifter on mt9p031 head-board, no need for Leopard module
1410+ mdelay(10);
1411+#endif //MT9P031_HEADBOARD
1412+
1413+ v4l2_int_device->module = THIS_MODULE;
1414+ strncpy(v4l2_int_device->name, "mt9p031", sizeof(v4l2_int_device->name));
1415+
1416+ v4l2_int_device->type = v4l2_int_type_slave;
1417+ v4l2_int_device->u.slave = &mt9p031_slave;
1418+
1419+ v4l2_int_device->priv = priv;
1420+
1421+ priv->v4l2_int_device = v4l2_int_device;
1422+ priv->client = client;
1423+ priv->pdata = client->dev.platform_data;
1424+
1425+ priv->pdata->flags = MT9P031_FLAG_PCLK_RISING_EDGE;
1426+
1427+ /* Setting Pixel Values */
1428+ priv->pix.width = mt9p031_sizes[0].width;
1429+ priv->pix.height = mt9p031_sizes[0].height;
1430+ priv->pix.pixelformat = mt9p031_formats[0].pixelformat;
1431+
1432+ i2c_set_clientdata(client, priv);
1433+
1434+ sysPriv.client = priv->client;
1435+
1436+ ret = v4l2_int_device_register(priv->v4l2_int_device);
1437+ if (ret) {
1438+ i2c_set_clientdata(client, NULL);
1439+ kfree(v4l2_int_device);
1440+ kfree(priv);
1441+ }
1442+
1443+#ifdef MT9P031_DEBUG
1444+ mt9p031_sysfs_add(&client->dev.kobj);
1445+#endif //MT9P031_DEBUG
1446+ return ret;
1447+}
1448+
1449+static int mt9p031_remove(struct i2c_client *client)
1450+{
1451+ struct mt9p031_priv *priv = i2c_get_clientdata(client);
1452+
1453+ v4l2_int_device_unregister(priv->v4l2_int_device);
1454+ i2c_set_clientdata(client, NULL);
1455+ mt9p031_sysfs_rm(&client->dev.kobj);
1456+
1457+ kfree(priv->v4l2_int_device);
1458+ kfree(priv);
1459+ return 0;
1460+}
1461+
1462+static const struct i2c_device_id mt9p031_id[] = {
1463+ { "mt9p031", 0 },
1464+ { }
1465+};
1466+MODULE_DEVICE_TABLE(i2c, mt9p031_id);
1467+
1468+static struct i2c_driver mt9p031_i2c_driver = {
1469+ .driver = {
1470+ .name = "mt9p031",
1471+ },
1472+ .probe = mt9p031_probe,
1473+ .remove = mt9p031_remove,
1474+ .id_table = mt9p031_id,
1475+};
1476+
1477+/************************************************************************
1478+ module function
1479+************************************************************************/
1480+static int __init mt9p031_module_init(void)
1481+{
1482+ return i2c_add_driver(&mt9p031_i2c_driver);
1483+}
1484+
1485+static void __exit mt9p031_module_exit(void)
1486+{
1487+ i2c_del_driver(&mt9p031_i2c_driver);
1488+}
1489+
1490+module_init(mt9p031_module_init);
1491+module_exit(mt9p031_module_exit);
1492+
1493+MODULE_DESCRIPTION("mt9p031 sensor driver");
1494+MODULE_AUTHOR("Aptina");
1495+MODULE_LICENSE("GPL v2");
1496+
1497diff --git a/include/media/mt9p031.h b/include/media/mt9p031.h
1498new file mode 100644
1499index 0000000..d119589
1500--- /dev/null
1501+++ b/include/media/mt9p031.h
1502@@ -0,0 +1,30 @@
1503+/* mt9p031 Camera
1504+ *
1505+ * This program is free software; you can redistribute it and/or modify
1506+ * it under the terms of the GNU General Public License version 2 as
1507+ * published by the Free Software Foundation.
1508+ */
1509+
1510+#ifndef __MT9P031_H__
1511+#define __MT9P031_H__
1512+
1513+#include <media/v4l2-int-device.h>
1514+
1515+#define MT9P031_I2C_ADDR 0x48 //(0x90 >> 1)
1516+
1517+#define MT9P031_CLK_MAX (27000000) /* 27MHz */
1518+#define MT9P031_CLK_MIN (6000000) /* 6Mhz */
1519+
1520+#define MT9P031_FLAG_PCLK_RISING_EDGE (1 << 0)
1521+#define MT9P031_FLAG_DATAWIDTH_8 (1 << 1) /* default width is 10 */
1522+
1523+struct mt9p031_platform_data {
1524+ char *master;
1525+ int (*power_set) (struct v4l2_int_device *s, enum v4l2_power on);
1526+ int (*ifparm) (struct v4l2_ifparm *p);
1527+ int (*priv_data_set) (void *);
1528+ u32 (*set_xclk) (struct v4l2_int_device *s, u32 xclkfreq);
1529+ u32 flags;
1530+};
1531+
1532+#endif /* __MT9P031_H__ */
1533diff --git a/include/media/v4l2-chip-ident.h b/include/media/v4l2-chip-ident.h
1534index 6cc107d..7599bf1 100644
1535--- a/include/media/v4l2-chip-ident.h
1536+++ b/include/media/v4l2-chip-ident.h
1537@@ -271,6 +271,7 @@ enum {
1538 V4L2_IDENT_MT9T112 = 45022,
1539 V4L2_IDENT_MT9V111 = 45031,
1540 V4L2_IDENT_MT9V112 = 45032,
1541+ V4L2_IDENT_MT9P031 = 6145,
1542
1543 /* HV7131R CMOS sensor: just ident 46000 */
1544 V4L2_IDENT_HV7131R = 46000,
1545--
15461.6.6.1
1547