aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/platform/mxc/capture/Kconfig6
-rw-r--r--drivers/media/platform/mxc/capture/Makefile3
-rw-r--r--drivers/media/platform/mxc/capture/ov5640_mipi.c2104
3 files changed, 2113 insertions, 0 deletions
diff --git a/drivers/media/platform/mxc/capture/Kconfig b/drivers/media/platform/mxc/capture/Kconfig
index 3f7274cb4f8b..6f253c1e45f5 100644
--- a/drivers/media/platform/mxc/capture/Kconfig
+++ b/drivers/media/platform/mxc/capture/Kconfig
@@ -24,6 +24,12 @@ config MXC_CAMERA_OV5642
24 ---help--- 24 ---help---
25 If you plan to use the ov5642 Camera with your MXC system, say Y here. 25 If you plan to use the ov5642 Camera with your MXC system, say Y here.
26 26
27config MXC_CAMERA_OV5640_MIPI
28 tristate "OmniVision ov5640 camera support using mipi"
29 depends on !VIDEO_MXC_EMMA_CAMERA && I2C
30 ---help---
31 If you plan to use the ov5640 Camera with mipi interface in your MXC system, say Y here.
32
27choice 33choice
28 prompt "Select Overlay Rounting" 34 prompt "Select Overlay Rounting"
29 default MXC_IPU_DEVICE_QUEUE_SDC 35 default MXC_IPU_DEVICE_QUEUE_SDC
diff --git a/drivers/media/platform/mxc/capture/Makefile b/drivers/media/platform/mxc/capture/Makefile
index cd225040e547..0f5eb3d10192 100644
--- a/drivers/media/platform/mxc/capture/Makefile
+++ b/drivers/media/platform/mxc/capture/Makefile
@@ -13,3 +13,6 @@ obj-$(CONFIG_MXC_CAMERA_OV5640) += ov5640_camera.o
13 13
14ov5642_camera-objs := ov5642.o 14ov5642_camera-objs := ov5642.o
15obj-$(CONFIG_MXC_CAMERA_OV5642) += ov5642_camera.o 15obj-$(CONFIG_MXC_CAMERA_OV5642) += ov5642_camera.o
16
17ov5640_camera_mipi-objs := ov5640_mipi.o
18obj-$(CONFIG_MXC_CAMERA_OV5640_MIPI) += ov5640_camera_mipi.o
diff --git a/drivers/media/platform/mxc/capture/ov5640_mipi.c b/drivers/media/platform/mxc/capture/ov5640_mipi.c
new file mode 100644
index 000000000000..79264bc63796
--- /dev/null
+++ b/drivers/media/platform/mxc/capture/ov5640_mipi.c
@@ -0,0 +1,2104 @@
1/*
2 * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
3 */
4
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 as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21#include <linux/module.h>
22#include <linux/init.h>
23#include <linux/slab.h>
24#include <linux/ctype.h>
25#include <linux/types.h>
26#include <linux/delay.h>
27#include <linux/clk.h>
28#include <linux/of_device.h>
29#include <linux/i2c.h>
30#include <linux/of_gpio.h>
31#include <linux/pinctrl/consumer.h>
32#include <linux/regulator/consumer.h>
33#include <linux/fsl_devices.h>
34#include <linux/mipi_csi2.h>
35#include <media/v4l2-chip-ident.h>
36#include <media/v4l2-int-device.h>
37#include "mxc_v4l2_capture.h"
38
39#define OV5640_VOLTAGE_ANALOG 2800000
40#define OV5640_VOLTAGE_DIGITAL_CORE 1500000
41#define OV5640_VOLTAGE_DIGITAL_IO 1800000
42
43#define MIN_FPS 15
44#define MAX_FPS 30
45#define DEFAULT_FPS 30
46
47#define OV5640_XCLK_MIN 6000000
48#define OV5640_XCLK_MAX 24000000
49
50#define OV5640_CHIP_ID_HIGH_BYTE 0x300A
51#define OV5640_CHIP_ID_LOW_BYTE 0x300B
52
53enum ov5640_mode {
54 ov5640_mode_MIN = 0,
55 ov5640_mode_VGA_640_480 = 0,
56 ov5640_mode_QVGA_320_240 = 1,
57 ov5640_mode_NTSC_720_480 = 2,
58 ov5640_mode_PAL_720_576 = 3,
59 ov5640_mode_720P_1280_720 = 4,
60 ov5640_mode_1080P_1920_1080 = 5,
61 ov5640_mode_QSXGA_2592_1944 = 6,
62 ov5640_mode_QCIF_176_144 = 7,
63 ov5640_mode_XGA_1024_768 = 8,
64 ov5640_mode_MAX = 8,
65 ov5640_mode_INIT = 0xff, /*only for sensor init*/
66};
67
68enum ov5640_frame_rate {
69 ov5640_15_fps,
70 ov5640_30_fps
71};
72
73/* image size under 1280 * 960 are SUBSAMPLING
74 * image size upper 1280 * 960 are SCALING
75 */
76enum ov5640_downsize_mode {
77 SUBSAMPLING,
78 SCALING,
79};
80
81struct reg_value {
82 u16 u16RegAddr;
83 u8 u8Val;
84 u8 u8Mask;
85 u32 u32Delay_ms;
86};
87
88struct ov5640_mode_info {
89 enum ov5640_mode mode;
90 enum ov5640_downsize_mode dn_mode;
91 u32 width;
92 u32 height;
93 struct reg_value *init_data_ptr;
94 u32 init_data_size;
95};
96
97/*!
98 * Maintains the information on the current state of the sesor.
99 */
100static struct sensor_data ov5640_data;
101static int pwn_gpio, rst_gpio;
102
103static struct reg_value ov5640_init_setting_30fps_VGA[] = {
104
105 {0x3103, 0x11, 0, 0}, {0x3008, 0x82, 0, 5}, {0x3008, 0x42, 0, 0},
106 {0x3103, 0x03, 0, 0}, {0x3017, 0x00, 0, 0}, {0x3018, 0x00, 0, 0},
107 {0x3034, 0x18, 0, 0}, {0x3035, 0x14, 0, 0}, {0x3036, 0x38, 0, 0},
108 {0x3037, 0x13, 0, 0}, {0x3108, 0x01, 0, 0}, {0x3630, 0x36, 0, 0},
109 {0x3631, 0x0e, 0, 0}, {0x3632, 0xe2, 0, 0}, {0x3633, 0x12, 0, 0},
110 {0x3621, 0xe0, 0, 0}, {0x3704, 0xa0, 0, 0}, {0x3703, 0x5a, 0, 0},
111 {0x3715, 0x78, 0, 0}, {0x3717, 0x01, 0, 0}, {0x370b, 0x60, 0, 0},
112 {0x3705, 0x1a, 0, 0}, {0x3905, 0x02, 0, 0}, {0x3906, 0x10, 0, 0},
113 {0x3901, 0x0a, 0, 0}, {0x3731, 0x12, 0, 0}, {0x3600, 0x08, 0, 0},
114 {0x3601, 0x33, 0, 0}, {0x302d, 0x60, 0, 0}, {0x3620, 0x52, 0, 0},
115 {0x371b, 0x20, 0, 0}, {0x471c, 0x50, 0, 0}, {0x3a13, 0x43, 0, 0},
116 {0x3a18, 0x00, 0, 0}, {0x3a19, 0xf8, 0, 0}, {0x3635, 0x13, 0, 0},
117 {0x3636, 0x03, 0, 0}, {0x3634, 0x40, 0, 0}, {0x3622, 0x01, 0, 0},
118 {0x3c01, 0xa4, 0, 0}, {0x3c04, 0x28, 0, 0}, {0x3c05, 0x98, 0, 0},
119 {0x3c06, 0x00, 0, 0}, {0x3c07, 0x08, 0, 0}, {0x3c08, 0x00, 0, 0},
120 {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
121 {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
122 {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
123 {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
124 {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
125 {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0},
126 {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
127 {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
128 {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
129 {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
130 {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
131 {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
132 {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
133 {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
134 {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x3000, 0x00, 0, 0},
135 {0x3002, 0x1c, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3006, 0xc3, 0, 0},
136 {0x300e, 0x45, 0, 0}, {0x302e, 0x08, 0, 0}, {0x4300, 0x3f, 0, 0},
137 {0x501f, 0x00, 0, 0}, {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0},
138 {0x440e, 0x00, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
139 {0x4837, 0x0a, 0, 0}, {0x4800, 0x04, 0, 0}, {0x3824, 0x02, 0, 0},
140 {0x5000, 0xa7, 0, 0}, {0x5001, 0xa3, 0, 0}, {0x5180, 0xff, 0, 0},
141 {0x5181, 0xf2, 0, 0}, {0x5182, 0x00, 0, 0}, {0x5183, 0x14, 0, 0},
142 {0x5184, 0x25, 0, 0}, {0x5185, 0x24, 0, 0}, {0x5186, 0x09, 0, 0},
143 {0x5187, 0x09, 0, 0}, {0x5188, 0x09, 0, 0}, {0x5189, 0x88, 0, 0},
144 {0x518a, 0x54, 0, 0}, {0x518b, 0xee, 0, 0}, {0x518c, 0xb2, 0, 0},
145 {0x518d, 0x50, 0, 0}, {0x518e, 0x34, 0, 0}, {0x518f, 0x6b, 0, 0},
146 {0x5190, 0x46, 0, 0}, {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0},
147 {0x5193, 0x70, 0, 0}, {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0},
148 {0x5196, 0x03, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0},
149 {0x5199, 0x6c, 0, 0}, {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0},
150 {0x519c, 0x09, 0, 0}, {0x519d, 0x2b, 0, 0}, {0x519e, 0x38, 0, 0},
151 {0x5381, 0x1e, 0, 0}, {0x5382, 0x5b, 0, 0}, {0x5383, 0x08, 0, 0},
152 {0x5384, 0x0a, 0, 0}, {0x5385, 0x7e, 0, 0}, {0x5386, 0x88, 0, 0},
153 {0x5387, 0x7c, 0, 0}, {0x5388, 0x6c, 0, 0}, {0x5389, 0x10, 0, 0},
154 {0x538a, 0x01, 0, 0}, {0x538b, 0x98, 0, 0}, {0x5300, 0x08, 0, 0},
155 {0x5301, 0x30, 0, 0}, {0x5302, 0x10, 0, 0}, {0x5303, 0x00, 0, 0},
156 {0x5304, 0x08, 0, 0}, {0x5305, 0x30, 0, 0}, {0x5306, 0x08, 0, 0},
157 {0x5307, 0x16, 0, 0}, {0x5309, 0x08, 0, 0}, {0x530a, 0x30, 0, 0},
158 {0x530b, 0x04, 0, 0}, {0x530c, 0x06, 0, 0}, {0x5480, 0x01, 0, 0},
159 {0x5481, 0x08, 0, 0}, {0x5482, 0x14, 0, 0}, {0x5483, 0x28, 0, 0},
160 {0x5484, 0x51, 0, 0}, {0x5485, 0x65, 0, 0}, {0x5486, 0x71, 0, 0},
161 {0x5487, 0x7d, 0, 0}, {0x5488, 0x87, 0, 0}, {0x5489, 0x91, 0, 0},
162 {0x548a, 0x9a, 0, 0}, {0x548b, 0xaa, 0, 0}, {0x548c, 0xb8, 0, 0},
163 {0x548d, 0xcd, 0, 0}, {0x548e, 0xdd, 0, 0}, {0x548f, 0xea, 0, 0},
164 {0x5490, 0x1d, 0, 0}, {0x5580, 0x02, 0, 0}, {0x5583, 0x40, 0, 0},
165 {0x5584, 0x10, 0, 0}, {0x5589, 0x10, 0, 0}, {0x558a, 0x00, 0, 0},
166 {0x558b, 0xf8, 0, 0}, {0x5800, 0x23, 0, 0}, {0x5801, 0x14, 0, 0},
167 {0x5802, 0x0f, 0, 0}, {0x5803, 0x0f, 0, 0}, {0x5804, 0x12, 0, 0},
168 {0x5805, 0x26, 0, 0}, {0x5806, 0x0c, 0, 0}, {0x5807, 0x08, 0, 0},
169 {0x5808, 0x05, 0, 0}, {0x5809, 0x05, 0, 0}, {0x580a, 0x08, 0, 0},
170 {0x580b, 0x0d, 0, 0}, {0x580c, 0x08, 0, 0}, {0x580d, 0x03, 0, 0},
171 {0x580e, 0x00, 0, 0}, {0x580f, 0x00, 0, 0}, {0x5810, 0x03, 0, 0},
172 {0x5811, 0x09, 0, 0}, {0x5812, 0x07, 0, 0}, {0x5813, 0x03, 0, 0},
173 {0x5814, 0x00, 0, 0}, {0x5815, 0x01, 0, 0}, {0x5816, 0x03, 0, 0},
174 {0x5817, 0x08, 0, 0}, {0x5818, 0x0d, 0, 0}, {0x5819, 0x08, 0, 0},
175 {0x581a, 0x05, 0, 0}, {0x581b, 0x06, 0, 0}, {0x581c, 0x08, 0, 0},
176 {0x581d, 0x0e, 0, 0}, {0x581e, 0x29, 0, 0}, {0x581f, 0x17, 0, 0},
177 {0x5820, 0x11, 0, 0}, {0x5821, 0x11, 0, 0}, {0x5822, 0x15, 0, 0},
178 {0x5823, 0x28, 0, 0}, {0x5824, 0x46, 0, 0}, {0x5825, 0x26, 0, 0},
179 {0x5826, 0x08, 0, 0}, {0x5827, 0x26, 0, 0}, {0x5828, 0x64, 0, 0},
180 {0x5829, 0x26, 0, 0}, {0x582a, 0x24, 0, 0}, {0x582b, 0x22, 0, 0},
181 {0x582c, 0x24, 0, 0}, {0x582d, 0x24, 0, 0}, {0x582e, 0x06, 0, 0},
182 {0x582f, 0x22, 0, 0}, {0x5830, 0x40, 0, 0}, {0x5831, 0x42, 0, 0},
183 {0x5832, 0x24, 0, 0}, {0x5833, 0x26, 0, 0}, {0x5834, 0x24, 0, 0},
184 {0x5835, 0x22, 0, 0}, {0x5836, 0x22, 0, 0}, {0x5837, 0x26, 0, 0},
185 {0x5838, 0x44, 0, 0}, {0x5839, 0x24, 0, 0}, {0x583a, 0x26, 0, 0},
186 {0x583b, 0x28, 0, 0}, {0x583c, 0x42, 0, 0}, {0x583d, 0xce, 0, 0},
187 {0x5025, 0x00, 0, 0}, {0x3a0f, 0x30, 0, 0}, {0x3a10, 0x28, 0, 0},
188 {0x3a1b, 0x30, 0, 0}, {0x3a1e, 0x26, 0, 0}, {0x3a11, 0x60, 0, 0},
189 {0x3a1f, 0x14, 0, 0}, {0x3008, 0x02, 0, 0}, {0x3c00, 0x04, 0, 300},
190};
191
192static struct reg_value ov5640_setting_30fps_VGA_640_480[] = {
193
194 {0x3035, 0x14, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
195 {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
196 {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
197 {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
198 {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
199 {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
200 {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0},
201 {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
202 {0x380e, 0x04, 0, 0}, {0x380f, 0x38, 0, 0}, {0x3810, 0x00, 0, 0},
203 {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
204 {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
205 {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
206 {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x0e, 0, 0},
207 {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
208 {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
209 {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
210 {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
211 {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0}, {0x3503, 0x00, 0, 0},
212};
213
214static struct reg_value ov5640_setting_15fps_VGA_640_480[] = {
215 {0x3035, 0x22, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
216 {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
217 {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
218 {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
219 {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
220 {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
221 {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0},
222 {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
223 {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
224 {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
225 {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
226 {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
227 {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
228 {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
229 {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
230 {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
231 {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
232 {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
233};
234
235static struct reg_value ov5640_setting_30fps_XGA_1024_768[] = {
236
237 {0x3035, 0x14, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
238 {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
239 {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
240 {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
241 {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
242 {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
243 {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0},
244 {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
245 {0x380e, 0x04, 0, 0}, {0x380f, 0x38, 0, 0}, {0x3810, 0x00, 0, 0},
246 {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
247 {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
248 {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
249 {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x0e, 0, 0},
250 {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
251 {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
252 {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
253 {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
254 {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0}, {0x3503, 0x00, 0, 0},
255 {0x3808, 0x04, 0, 0}, {0x3809, 0x00, 0, 0}, {0x380a, 0x03, 0, 0},
256 {0x380b, 0x00, 0, 0}, {0x3035, 0x12, 0, 0},
257};
258
259static struct reg_value ov5640_setting_15fps_XGA_1024_768[] = {
260 {0x3035, 0x22, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
261 {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
262 {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
263 {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
264 {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
265 {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
266 {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0},
267 {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
268 {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
269 {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
270 {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
271 {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
272 {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
273 {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
274 {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
275 {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
276 {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
277 {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0}, {0x3808, 0x04, 0, 0},
278 {0x3809, 0x00, 0, 0}, {0x380a, 0x03, 0, 0}, {0x380b, 0x00, 0, 0},
279};
280
281static struct reg_value ov5640_setting_30fps_QVGA_320_240[] = {
282 {0x3035, 0x14, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
283 {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
284 {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
285 {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
286 {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
287 {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
288 {0x3808, 0x01, 0, 0}, {0x3809, 0x40, 0, 0}, {0x380a, 0x00, 0, 0},
289 {0x380b, 0xf0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
290 {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
291 {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
292 {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
293 {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
294 {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
295 {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
296 {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
297 {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
298 {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
299 {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
300};
301
302static struct reg_value ov5640_setting_15fps_QVGA_320_240[] = {
303 {0x3035, 0x22, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
304 {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
305 {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
306 {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
307 {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
308 {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
309 {0x3808, 0x01, 0, 0}, {0x3809, 0x40, 0, 0}, {0x380a, 0x00, 0, 0},
310 {0x380b, 0xf0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
311 {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
312 {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
313 {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
314 {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
315 {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
316 {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
317 {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
318 {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
319 {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
320 {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
321};
322
323static struct reg_value ov5640_setting_30fps_QCIF_176_144[] = {
324 {0x3035, 0x14, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
325 {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
326 {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
327 {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
328 {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
329 {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
330 {0x3808, 0x00, 0, 0}, {0x3809, 0xb0, 0, 0}, {0x380a, 0x00, 0, 0},
331 {0x380b, 0x90, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
332 {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
333 {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
334 {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
335 {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
336 {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
337 {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
338 {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
339 {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
340 {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
341 {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
342};
343static struct reg_value ov5640_setting_15fps_QCIF_176_144[] = {
344 {0x3035, 0x22, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
345 {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
346 {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
347 {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
348 {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
349 {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
350 {0x3808, 0x00, 0, 0}, {0x3809, 0xb0, 0, 0}, {0x380a, 0x00, 0, 0},
351 {0x380b, 0x90, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
352 {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
353 {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
354 {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
355 {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
356 {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
357 {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
358 {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
359 {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
360 {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
361 {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
362};
363
364static struct reg_value ov5640_setting_30fps_NTSC_720_480[] = {
365 {0x3035, 0x12, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
366 {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
367 {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
368 {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
369 {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
370 {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
371 {0x3808, 0x02, 0, 0}, {0x3809, 0xd0, 0, 0}, {0x380a, 0x01, 0, 0},
372 {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
373 {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
374 {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x3c, 0, 0},
375 {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
376 {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
377 {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
378 {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
379 {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
380 {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
381 {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
382 {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
383};
384
385static struct reg_value ov5640_setting_15fps_NTSC_720_480[] = {
386 {0x3035, 0x22, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
387 {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
388 {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
389 {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
390 {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
391 {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
392 {0x3808, 0x02, 0, 0}, {0x3809, 0xd0, 0, 0}, {0x380a, 0x01, 0, 0},
393 {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
394 {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
395 {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x3c, 0, 0},
396 {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
397 {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
398 {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
399 {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
400 {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
401 {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
402 {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
403 {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
404};
405
406static struct reg_value ov5640_setting_30fps_PAL_720_576[] = {
407 {0x3035, 0x12, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
408 {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
409 {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
410 {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
411 {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
412 {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
413 {0x3808, 0x02, 0, 0}, {0x3809, 0xd0, 0, 0}, {0x380a, 0x02, 0, 0},
414 {0x380b, 0x40, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
415 {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
416 {0x3811, 0x38, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
417 {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
418 {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
419 {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
420 {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
421 {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
422 {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
423 {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
424 {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
425};
426
427static struct reg_value ov5640_setting_15fps_PAL_720_576[] = {
428 {0x3035, 0x22, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
429 {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
430 {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
431 {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
432 {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
433 {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
434 {0x3808, 0x02, 0, 0}, {0x3809, 0xd0, 0, 0}, {0x380a, 0x02, 0, 0},
435 {0x380b, 0x40, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
436 {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
437 {0x3811, 0x38, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
438 {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
439 {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
440 {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
441 {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
442 {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
443 {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
444 {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
445 {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
446};
447
448static struct reg_value ov5640_setting_30fps_720P_1280_720[] = {
449 {0x3008, 0x42, 0, 0},
450 {0x3035, 0x21, 0, 0}, {0x3036, 0x54, 0, 0}, {0x3c07, 0x07, 0, 0},
451 {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
452 {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
453 {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
454 {0x3802, 0x00, 0, 0}, {0x3803, 0xfa, 0, 0}, {0x3804, 0x0a, 0, 0},
455 {0x3805, 0x3f, 0, 0}, {0x3806, 0x06, 0, 0}, {0x3807, 0xa9, 0, 0},
456 {0x3808, 0x05, 0, 0}, {0x3809, 0x00, 0, 0}, {0x380a, 0x02, 0, 0},
457 {0x380b, 0xd0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x64, 0, 0},
458 {0x380e, 0x02, 0, 0}, {0x380f, 0xe4, 0, 0}, {0x3810, 0x00, 0, 0},
459 {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x04, 0, 0},
460 {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
461 {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x02, 0, 0},
462 {0x3a03, 0xe4, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0xbc, 0, 0},
463 {0x3a0a, 0x01, 0, 0}, {0x3a0b, 0x72, 0, 0}, {0x3a0e, 0x01, 0, 0},
464 {0x3a0d, 0x02, 0, 0}, {0x3a14, 0x02, 0, 0}, {0x3a15, 0xe4, 0, 0},
465 {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x02, 0, 0},
466 {0x4407, 0x04, 0, 0}, {0x460b, 0x37, 0, 0}, {0x460c, 0x20, 0, 0},
467 {0x3824, 0x04, 0, 0}, {0x5001, 0x83, 0, 0}, {0x4005, 0x1a, 0, 0},
468 {0x3008, 0x02, 0, 0}, {0x3503, 0, 0, 0},
469};
470
471static struct reg_value ov5640_setting_15fps_720P_1280_720[] = {
472 {0x3035, 0x41, 0, 0}, {0x3036, 0x54, 0, 0}, {0x3c07, 0x07, 0, 0},
473 {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
474 {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
475 {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
476 {0x3802, 0x00, 0, 0}, {0x3803, 0xfa, 0, 0}, {0x3804, 0x0a, 0, 0},
477 {0x3805, 0x3f, 0, 0}, {0x3806, 0x06, 0, 0}, {0x3807, 0xa9, 0, 0},
478 {0x3808, 0x05, 0, 0}, {0x3809, 0x00, 0, 0}, {0x380a, 0x02, 0, 0},
479 {0x380b, 0xd0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x64, 0, 0},
480 {0x380e, 0x02, 0, 0}, {0x380f, 0xe4, 0, 0}, {0x3810, 0x00, 0, 0},
481 {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x04, 0, 0},
482 {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
483 {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x02, 0, 0},
484 {0x3a03, 0xe4, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0xbc, 0, 0},
485 {0x3a0a, 0x01, 0, 0}, {0x3a0b, 0x72, 0, 0}, {0x3a0e, 0x01, 0, 0},
486 {0x3a0d, 0x02, 0, 0}, {0x3a14, 0x02, 0, 0}, {0x3a15, 0xe4, 0, 0},
487 {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x02, 0, 0},
488 {0x4407, 0x04, 0, 0}, {0x460b, 0x37, 0, 0}, {0x460c, 0x20, 0, 0},
489 {0x3824, 0x04, 0, 0}, {0x5001, 0x83, 0, 0},
490};
491
492static struct reg_value ov5640_setting_30fps_1080P_1920_1080[] = {
493 {0x3008, 0x42, 0, 0},
494 {0x3035, 0x21, 0, 0}, {0x3036, 0x54, 0, 0}, {0x3c07, 0x08, 0, 0},
495 {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
496 {0x3820, 0x40, 0, 0}, {0x3821, 0x06, 0, 0}, {0x3814, 0x11, 0, 0},
497 {0x3815, 0x11, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
498 {0x3802, 0x00, 0, 0}, {0x3803, 0x00, 0, 0}, {0x3804, 0x0a, 0, 0},
499 {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9f, 0, 0},
500 {0x3808, 0x0a, 0, 0}, {0x3809, 0x20, 0, 0}, {0x380a, 0x07, 0, 0},
501 {0x380b, 0x98, 0, 0}, {0x380c, 0x0b, 0, 0}, {0x380d, 0x1c, 0, 0},
502 {0x380e, 0x07, 0, 0}, {0x380f, 0xb0, 0, 0}, {0x3810, 0x00, 0, 0},
503 {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x04, 0, 0},
504 {0x3618, 0x04, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x21, 0, 0},
505 {0x3709, 0x12, 0, 0}, {0x370c, 0x00, 0, 0}, {0x3a02, 0x03, 0, 0},
506 {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
507 {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
508 {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
509 {0x4001, 0x02, 0, 0}, {0x4004, 0x06, 0, 0}, {0x4713, 0x03, 0, 0},
510 {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
511 {0x3824, 0x02, 0, 0}, {0x5001, 0x83, 0, 0}, {0x3035, 0x11, 0, 0},
512 {0x3036, 0x54, 0, 0}, {0x3c07, 0x07, 0, 0}, {0x3c08, 0x00, 0, 0},
513 {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
514 {0x3800, 0x01, 0, 0}, {0x3801, 0x50, 0, 0}, {0x3802, 0x01, 0, 0},
515 {0x3803, 0xb2, 0, 0}, {0x3804, 0x08, 0, 0}, {0x3805, 0xef, 0, 0},
516 {0x3806, 0x05, 0, 0}, {0x3807, 0xf1, 0, 0}, {0x3808, 0x07, 0, 0},
517 {0x3809, 0x80, 0, 0}, {0x380a, 0x04, 0, 0}, {0x380b, 0x38, 0, 0},
518 {0x380c, 0x09, 0, 0}, {0x380d, 0xc4, 0, 0}, {0x380e, 0x04, 0, 0},
519 {0x380f, 0x60, 0, 0}, {0x3612, 0x2b, 0, 0}, {0x3708, 0x64, 0, 0},
520 {0x3a02, 0x04, 0, 0}, {0x3a03, 0x60, 0, 0}, {0x3a08, 0x01, 0, 0},
521 {0x3a09, 0x50, 0, 0}, {0x3a0a, 0x01, 0, 0}, {0x3a0b, 0x18, 0, 0},
522 {0x3a0e, 0x03, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x04, 0, 0},
523 {0x3a15, 0x60, 0, 0}, {0x4713, 0x02, 0, 0}, {0x4407, 0x04, 0, 0},
524 {0x460b, 0x37, 0, 0}, {0x460c, 0x20, 0, 0}, {0x3824, 0x04, 0, 0},
525 {0x4005, 0x1a, 0, 0}, {0x3008, 0x02, 0, 0},
526 {0x3503, 0, 0, 0},
527};
528
529static struct reg_value ov5640_setting_15fps_1080P_1920_1080[] = {
530 {0x3008, 0x42, 0, 0},
531 {0x3035, 0x21, 0, 0}, {0x3036, 0x54, 0, 0}, {0x3c07, 0x08, 0, 0},
532 {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
533 {0x3820, 0x40, 0, 0}, {0x3821, 0x06, 0, 0}, {0x3814, 0x11, 0, 0},
534 {0x3815, 0x11, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
535 {0x3802, 0x00, 0, 0}, {0x3803, 0x00, 0, 0}, {0x3804, 0x0a, 0, 0},
536 {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9f, 0, 0},
537 {0x3808, 0x0a, 0, 0}, {0x3809, 0x20, 0, 0}, {0x380a, 0x07, 0, 0},
538 {0x380b, 0x98, 0, 0}, {0x380c, 0x0b, 0, 0}, {0x380d, 0x1c, 0, 0},
539 {0x380e, 0x07, 0, 0}, {0x380f, 0xb0, 0, 0}, {0x3810, 0x00, 0, 0},
540 {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x04, 0, 0},
541 {0x3618, 0x04, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x21, 0, 0},
542 {0x3709, 0x12, 0, 0}, {0x370c, 0x00, 0, 0}, {0x3a02, 0x03, 0, 0},
543 {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
544 {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
545 {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
546 {0x4001, 0x02, 0, 0}, {0x4004, 0x06, 0, 0}, {0x4713, 0x03, 0, 0},
547 {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
548 {0x3824, 0x02, 0, 0}, {0x5001, 0x83, 0, 0}, {0x3035, 0x21, 0, 0},
549 {0x3036, 0x54, 0, 1}, {0x3c07, 0x07, 0, 0}, {0x3c08, 0x00, 0, 0},
550 {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
551 {0x3800, 0x01, 0, 0}, {0x3801, 0x50, 0, 0}, {0x3802, 0x01, 0, 0},
552 {0x3803, 0xb2, 0, 0}, {0x3804, 0x08, 0, 0}, {0x3805, 0xef, 0, 0},
553 {0x3806, 0x05, 0, 0}, {0x3807, 0xf1, 0, 0}, {0x3808, 0x07, 0, 0},
554 {0x3809, 0x80, 0, 0}, {0x380a, 0x04, 0, 0}, {0x380b, 0x38, 0, 0},
555 {0x380c, 0x09, 0, 0}, {0x380d, 0xc4, 0, 0}, {0x380e, 0x04, 0, 0},
556 {0x380f, 0x60, 0, 0}, {0x3612, 0x2b, 0, 0}, {0x3708, 0x64, 0, 0},
557 {0x3a02, 0x04, 0, 0}, {0x3a03, 0x60, 0, 0}, {0x3a08, 0x01, 0, 0},
558 {0x3a09, 0x50, 0, 0}, {0x3a0a, 0x01, 0, 0}, {0x3a0b, 0x18, 0, 0},
559 {0x3a0e, 0x03, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x04, 0, 0},
560 {0x3a15, 0x60, 0, 0}, {0x4713, 0x02, 0, 0}, {0x4407, 0x04, 0, 0},
561 {0x460b, 0x37, 0, 0}, {0x460c, 0x20, 0, 0}, {0x3824, 0x04, 0, 0},
562 {0x4005, 0x1a, 0, 0}, {0x3008, 0x02, 0, 0}, {0x3503, 0, 0, 0},
563};
564
565static struct reg_value ov5640_setting_15fps_QSXGA_2592_1944[] = {
566 {0x4202, 0x0f, 0, 0}, /* stream off the sensor */
567 {0x3820, 0x40, 0, 0}, {0x3821, 0x06, 0, 0}, /*disable flip*/
568 {0x3035, 0x21, 0, 0}, {0x3036, 0x54, 0, 0}, {0x3c07, 0x08, 0, 0},
569 {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
570 {0x3820, 0x40, 0, 0}, {0x3821, 0x06, 0, 0}, {0x3814, 0x11, 0, 0},
571 {0x3815, 0x11, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
572 {0x3802, 0x00, 0, 0}, {0x3803, 0x00, 0, 0}, {0x3804, 0x0a, 0, 0},
573 {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9f, 0, 0},
574 {0x3808, 0x0a, 0, 0}, {0x3809, 0x20, 0, 0}, {0x380a, 0x07, 0, 0},
575 {0x380b, 0x98, 0, 0}, {0x380c, 0x0b, 0, 0}, {0x380d, 0x1c, 0, 0},
576 {0x380e, 0x07, 0, 0}, {0x380f, 0xb0, 0, 0}, {0x3810, 0x00, 0, 0},
577 {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x04, 0, 0},
578 {0x3618, 0x04, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x21, 0, 0},
579 {0x3709, 0x12, 0, 0}, {0x370c, 0x00, 0, 0}, {0x3a02, 0x03, 0, 0},
580 {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
581 {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
582 {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
583 {0x4001, 0x02, 0, 0}, {0x4004, 0x06, 0, 0}, {0x4713, 0x03, 0, 0},
584 {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
585 {0x3824, 0x02, 0, 0}, {0x5001, 0x83, 0, 70},
586 {0x4202, 0x00, 0, 0}, /* stream on the sensor */
587};
588
589static struct ov5640_mode_info ov5640_mode_info_data[2][ov5640_mode_MAX + 1] = {
590 {
591 {ov5640_mode_VGA_640_480, SUBSAMPLING, 640, 480,
592 ov5640_setting_15fps_VGA_640_480,
593 ARRAY_SIZE(ov5640_setting_15fps_VGA_640_480)},
594 {ov5640_mode_QVGA_320_240, SUBSAMPLING, 320, 240,
595 ov5640_setting_15fps_QVGA_320_240,
596 ARRAY_SIZE(ov5640_setting_15fps_QVGA_320_240)},
597 {ov5640_mode_NTSC_720_480, SUBSAMPLING, 720, 480,
598 ov5640_setting_15fps_NTSC_720_480,
599 ARRAY_SIZE(ov5640_setting_15fps_NTSC_720_480)},
600 {ov5640_mode_PAL_720_576, SUBSAMPLING, 720, 576,
601 ov5640_setting_15fps_PAL_720_576,
602 ARRAY_SIZE(ov5640_setting_15fps_PAL_720_576)},
603 {ov5640_mode_720P_1280_720, SUBSAMPLING, 1280, 720,
604 ov5640_setting_15fps_720P_1280_720,
605 ARRAY_SIZE(ov5640_setting_15fps_720P_1280_720)},
606 {ov5640_mode_1080P_1920_1080, SCALING, 1920, 1080,
607 ov5640_setting_15fps_1080P_1920_1080,
608 ARRAY_SIZE(ov5640_setting_15fps_1080P_1920_1080)},
609 {ov5640_mode_QSXGA_2592_1944, SCALING, 2592, 1944,
610 ov5640_setting_15fps_QSXGA_2592_1944,
611 ARRAY_SIZE(ov5640_setting_15fps_QSXGA_2592_1944)},
612 {ov5640_mode_QCIF_176_144, SUBSAMPLING, 176, 144,
613 ov5640_setting_15fps_QCIF_176_144,
614 ARRAY_SIZE(ov5640_setting_15fps_QCIF_176_144)},
615 {ov5640_mode_XGA_1024_768, SUBSAMPLING, 1024, 768,
616 ov5640_setting_15fps_XGA_1024_768,
617 ARRAY_SIZE(ov5640_setting_15fps_XGA_1024_768)},
618 },
619 {
620 {ov5640_mode_VGA_640_480, SUBSAMPLING, 640, 480,
621 ov5640_setting_30fps_VGA_640_480,
622 ARRAY_SIZE(ov5640_setting_30fps_VGA_640_480)},
623 {ov5640_mode_QVGA_320_240, SUBSAMPLING, 320, 240,
624 ov5640_setting_30fps_QVGA_320_240,
625 ARRAY_SIZE(ov5640_setting_30fps_QVGA_320_240)},
626 {ov5640_mode_NTSC_720_480, SUBSAMPLING, 720, 480,
627 ov5640_setting_30fps_NTSC_720_480,
628 ARRAY_SIZE(ov5640_setting_30fps_NTSC_720_480)},
629 {ov5640_mode_PAL_720_576, SUBSAMPLING, 720, 576,
630 ov5640_setting_30fps_PAL_720_576,
631 ARRAY_SIZE(ov5640_setting_30fps_PAL_720_576)},
632 {ov5640_mode_720P_1280_720, SUBSAMPLING, 1280, 720,
633 ov5640_setting_30fps_720P_1280_720,
634 ARRAY_SIZE(ov5640_setting_30fps_720P_1280_720)},
635 {ov5640_mode_1080P_1920_1080, SCALING, 1920, 1080,
636 ov5640_setting_30fps_1080P_1920_1080,
637 ARRAY_SIZE(ov5640_setting_30fps_1080P_1920_1080)},
638 {ov5640_mode_QSXGA_2592_1944, -1, 0, 0, NULL, 0},
639 {ov5640_mode_QCIF_176_144, SUBSAMPLING, 176, 144,
640 ov5640_setting_30fps_QCIF_176_144,
641 ARRAY_SIZE(ov5640_setting_30fps_QCIF_176_144)},
642 {ov5640_mode_XGA_1024_768, SUBSAMPLING, 1024, 768,
643 ov5640_setting_30fps_XGA_1024_768,
644 ARRAY_SIZE(ov5640_setting_30fps_XGA_1024_768)},
645 },
646};
647
648static struct regulator *io_regulator;
649static struct regulator *core_regulator;
650static struct regulator *analog_regulator;
651static struct regulator *gpo_regulator;
652
653static int ov5640_probe(struct i2c_client *adapter,
654 const struct i2c_device_id *device_id);
655static int ov5640_remove(struct i2c_client *client);
656
657static s32 ov5640_read_reg(u16 reg, u8 *val);
658static s32 ov5640_write_reg(u16 reg, u8 val);
659
660static const struct i2c_device_id ov5640_id[] = {
661 {"ov5640_mipi", 0},
662 {},
663};
664
665MODULE_DEVICE_TABLE(i2c, ov5640_id);
666
667static struct i2c_driver ov5640_i2c_driver = {
668 .driver = {
669 .owner = THIS_MODULE,
670 .name = "ov5640_mipi",
671 },
672 .probe = ov5640_probe,
673 .remove = ov5640_remove,
674 .id_table = ov5640_id,
675};
676
677static void ov5640_standby(s32 enable)
678{
679 if (enable)
680 gpio_set_value(pwn_gpio, 1);
681 else
682 gpio_set_value(pwn_gpio, 0);
683
684 msleep(2);
685}
686
687static void ov5640_reset(void)
688{
689 /* camera reset */
690 gpio_set_value(rst_gpio, 1);
691
692 /* camera power dowmn */
693 gpio_set_value(pwn_gpio, 1);
694 msleep(5);
695
696 gpio_set_value(pwn_gpio, 0);
697 msleep(5);
698
699 gpio_set_value(rst_gpio, 0);
700 msleep(1);
701
702 gpio_set_value(rst_gpio, 1);
703 msleep(5);
704
705 gpio_set_value(pwn_gpio, 1);
706}
707
708static int ov5640_power_on(struct device *dev)
709{
710 int ret = 0;
711
712 io_regulator = devm_regulator_get(dev, "DOVDD");
713 if (!IS_ERR(io_regulator)) {
714 regulator_set_voltage(io_regulator,
715 OV5640_VOLTAGE_DIGITAL_IO,
716 OV5640_VOLTAGE_DIGITAL_IO);
717 ret = regulator_enable(io_regulator);
718 if (ret) {
719 pr_err("%s:io set voltage error\n", __func__);
720 return ret;
721 } else {
722 dev_dbg(dev,
723 "%s:io set voltage ok\n", __func__);
724 }
725 } else {
726 pr_err("%s: cannot get io voltage error\n", __func__);
727 io_regulator = NULL;
728 }
729
730 core_regulator = devm_regulator_get(dev, "DVDD");
731 if (!IS_ERR(core_regulator)) {
732 regulator_set_voltage(core_regulator,
733 OV5640_VOLTAGE_DIGITAL_CORE,
734 OV5640_VOLTAGE_DIGITAL_CORE);
735 ret = regulator_enable(core_regulator);
736 if (ret) {
737 pr_err("%s:core set voltage error\n", __func__);
738 return ret;
739 } else {
740 dev_dbg(dev,
741 "%s:core set voltage ok\n", __func__);
742 }
743 } else {
744 core_regulator = NULL;
745 pr_err("%s: cannot get core voltage error\n", __func__);
746 }
747
748 analog_regulator = devm_regulator_get(dev, "AVDD");
749 if (!IS_ERR(analog_regulator)) {
750 regulator_set_voltage(analog_regulator,
751 OV5640_VOLTAGE_ANALOG,
752 OV5640_VOLTAGE_ANALOG);
753 ret = regulator_enable(analog_regulator);
754 if (ret) {
755 pr_err("%s:analog set voltage error\n",
756 __func__);
757 return ret;
758 } else {
759 dev_dbg(dev,
760 "%s:analog set voltage ok\n", __func__);
761 }
762 } else {
763 analog_regulator = NULL;
764 pr_err("%s: cannot get analog voltage error\n", __func__);
765 }
766
767 return ret;
768}
769
770static s32 ov5640_write_reg(u16 reg, u8 val)
771{
772 u8 au8Buf[3] = {0};
773
774 au8Buf[0] = reg >> 8;
775 au8Buf[1] = reg & 0xff;
776 au8Buf[2] = val;
777
778 if (i2c_master_send(ov5640_data.i2c_client, au8Buf, 3) < 0) {
779 pr_err("%s:write reg error:reg=%x,val=%x\n",
780 __func__, reg, val);
781 return -1;
782 }
783
784 return 0;
785}
786
787static s32 ov5640_read_reg(u16 reg, u8 *val)
788{
789 u8 au8RegBuf[2] = {0};
790 u8 u8RdVal = 0;
791
792 au8RegBuf[0] = reg >> 8;
793 au8RegBuf[1] = reg & 0xff;
794
795 if (2 != i2c_master_send(ov5640_data.i2c_client, au8RegBuf, 2)) {
796 pr_err("%s:write reg error:reg=%x\n",
797 __func__, reg);
798 return -1;
799 }
800
801 if (1 != i2c_master_recv(ov5640_data.i2c_client, &u8RdVal, 1)) {
802 pr_err("%s:read reg error:reg=%x,val=%x\n",
803 __func__, reg, u8RdVal);
804 return -1;
805 }
806
807 *val = u8RdVal;
808
809 return u8RdVal;
810}
811
812static int prev_sysclk, prev_HTS;
813static int AE_low, AE_high, AE_Target = 52;
814
815void OV5640_stream_on(void)
816{
817 ov5640_write_reg(0x4202, 0x00);
818}
819
820void OV5640_stream_off(void)
821{
822 ov5640_write_reg(0x4202, 0x0f);
823}
824
825
826int OV5640_get_sysclk(void)
827{
828 /* calculate sysclk */
829 int xvclk = ov5640_data.mclk / 10000;
830 int temp1, temp2;
831 int Multiplier, PreDiv, VCO, SysDiv, Pll_rdiv;
832 int Bit_div2x = 1, sclk_rdiv, sysclk;
833 u8 temp;
834
835 int sclk_rdiv_map[] = {1, 2, 4, 8};
836
837 temp1 = ov5640_read_reg(0x3034, &temp);
838 temp2 = temp1 & 0x0f;
839 if (temp2 == 8 || temp2 == 10)
840 Bit_div2x = temp2 / 2;
841
842 temp1 = ov5640_read_reg(0x3035, &temp);
843 SysDiv = temp1>>4;
844 if (SysDiv == 0)
845 SysDiv = 16;
846
847 temp1 = ov5640_read_reg(0x3036, &temp);
848 Multiplier = temp1;
849
850 temp1 = ov5640_read_reg(0x3037, &temp);
851 PreDiv = temp1 & 0x0f;
852 Pll_rdiv = ((temp1 >> 4) & 0x01) + 1;
853
854 temp1 = ov5640_read_reg(0x3108, &temp);
855 temp2 = temp1 & 0x03;
856 sclk_rdiv = sclk_rdiv_map[temp2];
857
858 VCO = xvclk * Multiplier / PreDiv;
859
860 sysclk = VCO / SysDiv / Pll_rdiv * 2 / Bit_div2x / sclk_rdiv;
861
862 return sysclk;
863}
864
865void OV5640_set_night_mode(void)
866{
867 /* read HTS from register settings */
868 u8 mode;
869
870 ov5640_read_reg(0x3a00, &mode);
871 mode &= 0xfb;
872 ov5640_write_reg(0x3a00, mode);
873}
874
875int OV5640_get_HTS(void)
876{
877 /* read HTS from register settings */
878 int HTS;
879 u8 temp;
880
881 HTS = ov5640_read_reg(0x380c, &temp);
882 HTS = (HTS<<8) + ov5640_read_reg(0x380d, &temp);
883
884 return HTS;
885}
886
887int OV5640_get_VTS(void)
888{
889 /* read VTS from register settings */
890 int VTS;
891 u8 temp;
892
893 /* total vertical size[15:8] high byte */
894 VTS = ov5640_read_reg(0x380e, &temp);
895
896 VTS = (VTS<<8) + ov5640_read_reg(0x380f, &temp);
897
898 return VTS;
899}
900
901int OV5640_set_VTS(int VTS)
902{
903 /* write VTS to registers */
904 int temp;
905
906 temp = VTS & 0xff;
907 ov5640_write_reg(0x380f, temp);
908
909 temp = VTS>>8;
910 ov5640_write_reg(0x380e, temp);
911
912 return 0;
913}
914
915int OV5640_get_shutter(void)
916{
917 /* read shutter, in number of line period */
918 int shutter;
919 u8 temp;
920
921 shutter = (ov5640_read_reg(0x03500, &temp) & 0x0f);
922 shutter = (shutter<<8) + ov5640_read_reg(0x3501, &temp);
923 shutter = (shutter<<4) + (ov5640_read_reg(0x3502, &temp)>>4);
924
925 return shutter;
926}
927
928int OV5640_set_shutter(int shutter)
929{
930 /* write shutter, in number of line period */
931 int temp;
932
933 shutter = shutter & 0xffff;
934
935 temp = shutter & 0x0f;
936 temp = temp<<4;
937 ov5640_write_reg(0x3502, temp);
938
939 temp = shutter & 0xfff;
940 temp = temp>>4;
941 ov5640_write_reg(0x3501, temp);
942
943 temp = shutter>>12;
944 ov5640_write_reg(0x3500, temp);
945
946 return 0;
947}
948
949int OV5640_get_gain16(void)
950{
951 /* read gain, 16 = 1x */
952 int gain16;
953 u8 temp;
954
955 gain16 = ov5640_read_reg(0x350a, &temp) & 0x03;
956 gain16 = (gain16<<8) + ov5640_read_reg(0x350b, &temp);
957
958 return gain16;
959}
960
961int OV5640_set_gain16(int gain16)
962{
963 /* write gain, 16 = 1x */
964 u8 temp;
965 gain16 = gain16 & 0x3ff;
966
967 temp = gain16 & 0xff;
968 ov5640_write_reg(0x350b, temp);
969
970 temp = gain16>>8;
971 ov5640_write_reg(0x350a, temp);
972
973 return 0;
974}
975
976int OV5640_get_light_freq(void)
977{
978 /* get banding filter value */
979 int temp, temp1, light_freq = 0;
980 u8 tmp;
981
982 temp = ov5640_read_reg(0x3c01, &tmp);
983
984 if (temp & 0x80) {
985 /* manual */
986 temp1 = ov5640_read_reg(0x3c00, &tmp);
987 if (temp1 & 0x04) {
988 /* 50Hz */
989 light_freq = 50;
990 } else {
991 /* 60Hz */
992 light_freq = 60;
993 }
994 } else {
995 /* auto */
996 temp1 = ov5640_read_reg(0x3c0c, &tmp);
997 if (temp1 & 0x01) {
998 /* 50Hz */
999 light_freq = 50;
1000 } else {
1001 /* 60Hz */
1002 }
1003 }
1004 return light_freq;
1005}
1006
1007void OV5640_set_bandingfilter(void)
1008{
1009 int prev_VTS;
1010 int band_step60, max_band60, band_step50, max_band50;
1011
1012 /* read preview PCLK */
1013 prev_sysclk = OV5640_get_sysclk();
1014 /* read preview HTS */
1015 prev_HTS = OV5640_get_HTS();
1016
1017 /* read preview VTS */
1018 prev_VTS = OV5640_get_VTS();
1019
1020 /* calculate banding filter */
1021 /* 60Hz */
1022 band_step60 = prev_sysclk * 100/prev_HTS * 100/120;
1023 ov5640_write_reg(0x3a0a, (band_step60 >> 8));
1024 ov5640_write_reg(0x3a0b, (band_step60 & 0xff));
1025
1026 max_band60 = (int)((prev_VTS-4)/band_step60);
1027 ov5640_write_reg(0x3a0d, max_band60);
1028
1029 /* 50Hz */
1030 band_step50 = prev_sysclk * 100/prev_HTS;
1031 ov5640_write_reg(0x3a08, (band_step50 >> 8));
1032 ov5640_write_reg(0x3a09, (band_step50 & 0xff));
1033
1034 max_band50 = (int)((prev_VTS-4)/band_step50);
1035 ov5640_write_reg(0x3a0e, max_band50);
1036}
1037
1038int OV5640_set_AE_target(int target)
1039{
1040 /* stable in high */
1041 int fast_high, fast_low;
1042 AE_low = target * 23 / 25; /* 0.92 */
1043 AE_high = target * 27 / 25; /* 1.08 */
1044
1045 fast_high = AE_high<<1;
1046 if (fast_high > 255)
1047 fast_high = 255;
1048
1049 fast_low = AE_low >> 1;
1050
1051 ov5640_write_reg(0x3a0f, AE_high);
1052 ov5640_write_reg(0x3a10, AE_low);
1053 ov5640_write_reg(0x3a1b, AE_high);
1054 ov5640_write_reg(0x3a1e, AE_low);
1055 ov5640_write_reg(0x3a11, fast_high);
1056 ov5640_write_reg(0x3a1f, fast_low);
1057
1058 return 0;
1059}
1060
1061void OV5640_turn_on_AE_AG(int enable)
1062{
1063 u8 ae_ag_ctrl;
1064
1065 ov5640_read_reg(0x3503, &ae_ag_ctrl);
1066 if (enable) {
1067 /* turn on auto AE/AG */
1068 ae_ag_ctrl = ae_ag_ctrl & ~(0x03);
1069 } else {
1070 /* turn off AE/AG */
1071 ae_ag_ctrl = ae_ag_ctrl | 0x03;
1072 }
1073 ov5640_write_reg(0x3503, ae_ag_ctrl);
1074}
1075
1076bool binning_on(void)
1077{
1078 u8 temp;
1079 ov5640_read_reg(0x3821, &temp);
1080 temp &= 0xfe;
1081 if (temp)
1082 return true;
1083 else
1084 return false;
1085}
1086
1087static void ov5640_set_virtual_channel(int channel)
1088{
1089 u8 channel_id;
1090
1091 ov5640_read_reg(0x4814, &channel_id);
1092 channel_id &= ~(3 << 6);
1093 ov5640_write_reg(0x4814, channel_id | (channel << 6));
1094}
1095
1096/* download ov5640 settings to sensor through i2c */
1097static int ov5640_download_firmware(struct reg_value *pModeSetting, s32 ArySize)
1098{
1099 register u32 Delay_ms = 0;
1100 register u16 RegAddr = 0;
1101 register u8 Mask = 0;
1102 register u8 Val = 0;
1103 u8 RegVal = 0;
1104 int i, retval = 0;
1105
1106 for (i = 0; i < ArySize; ++i, ++pModeSetting) {
1107 Delay_ms = pModeSetting->u32Delay_ms;
1108 RegAddr = pModeSetting->u16RegAddr;
1109 Val = pModeSetting->u8Val;
1110 Mask = pModeSetting->u8Mask;
1111
1112 if (Mask) {
1113 retval = ov5640_read_reg(RegAddr, &RegVal);
1114 if (retval < 0)
1115 goto err;
1116
1117 RegVal &= ~(u8)Mask;
1118 Val &= Mask;
1119 Val |= RegVal;
1120 }
1121
1122 retval = ov5640_write_reg(RegAddr, Val);
1123 if (retval < 0)
1124 goto err;
1125
1126 if (Delay_ms)
1127 msleep(Delay_ms);
1128 }
1129err:
1130 return retval;
1131}
1132
1133/* sensor changes between scaling and subsampling
1134 * go through exposure calcualtion
1135 */
1136static int ov5640_change_mode_exposure_calc(enum ov5640_frame_rate frame_rate,
1137 enum ov5640_mode mode)
1138{
1139 struct reg_value *pModeSetting = NULL;
1140 s32 ArySize = 0;
1141 u8 average;
1142 int prev_shutter, prev_gain16;
1143 int cap_shutter, cap_gain16;
1144 int cap_sysclk, cap_HTS, cap_VTS;
1145 int light_freq, cap_bandfilt, cap_maxband;
1146 long cap_gain16_shutter;
1147 int retval = 0;
1148
1149 /* check if the input mode and frame rate is valid */
1150 pModeSetting =
1151 ov5640_mode_info_data[frame_rate][mode].init_data_ptr;
1152 ArySize =
1153 ov5640_mode_info_data[frame_rate][mode].init_data_size;
1154
1155 ov5640_data.pix.width =
1156 ov5640_mode_info_data[frame_rate][mode].width;
1157 ov5640_data.pix.height =
1158 ov5640_mode_info_data[frame_rate][mode].height;
1159
1160 if (ov5640_data.pix.width == 0 || ov5640_data.pix.height == 0 ||
1161 pModeSetting == NULL || ArySize == 0)
1162 return -EINVAL;
1163
1164 /* auto focus */
1165 /* OV5640_auto_focus();//if no af function, just skip it */
1166
1167 /* turn off AE/AG */
1168 OV5640_turn_on_AE_AG(0);
1169
1170 /* read preview shutter */
1171 prev_shutter = OV5640_get_shutter();
1172 if ((binning_on()) && (mode != ov5640_mode_720P_1280_720)
1173 && (mode != ov5640_mode_1080P_1920_1080))
1174 prev_shutter *= 2;
1175
1176 /* read preview gain */
1177 prev_gain16 = OV5640_get_gain16();
1178
1179 /* get average */
1180 ov5640_read_reg(0x56a1, &average);
1181
1182 /* turn off night mode for capture */
1183 OV5640_set_night_mode();
1184
1185 /* turn off overlay */
1186 /* ov5640_write_reg(0x3022, 0x06);//if no af function, just skip it */
1187
1188 OV5640_stream_off();
1189
1190 /* Write capture setting */
1191 retval = ov5640_download_firmware(pModeSetting, ArySize);
1192 if (retval < 0)
1193 goto err;
1194
1195 /* read capture VTS */
1196 cap_VTS = OV5640_get_VTS();
1197 cap_HTS = OV5640_get_HTS();
1198 cap_sysclk = OV5640_get_sysclk();
1199
1200 /* calculate capture banding filter */
1201 light_freq = OV5640_get_light_freq();
1202 if (light_freq == 60) {
1203 /* 60Hz */
1204 cap_bandfilt = cap_sysclk * 100 / cap_HTS * 100 / 120;
1205 } else {
1206 /* 50Hz */
1207 cap_bandfilt = cap_sysclk * 100 / cap_HTS;
1208 }
1209 cap_maxband = (int)((cap_VTS - 4)/cap_bandfilt);
1210
1211 /* calculate capture shutter/gain16 */
1212 if (average > AE_low && average < AE_high) {
1213 /* in stable range */
1214 cap_gain16_shutter =
1215 prev_gain16 * prev_shutter * cap_sysclk/prev_sysclk
1216 * prev_HTS/cap_HTS * AE_Target / average;
1217 } else {
1218 cap_gain16_shutter =
1219 prev_gain16 * prev_shutter * cap_sysclk/prev_sysclk
1220 * prev_HTS/cap_HTS;
1221 }
1222
1223 /* gain to shutter */
1224 if (cap_gain16_shutter < (cap_bandfilt * 16)) {
1225 /* shutter < 1/100 */
1226 cap_shutter = cap_gain16_shutter/16;
1227 if (cap_shutter < 1)
1228 cap_shutter = 1;
1229
1230 cap_gain16 = cap_gain16_shutter/cap_shutter;
1231 if (cap_gain16 < 16)
1232 cap_gain16 = 16;
1233 } else {
1234 if (cap_gain16_shutter >
1235 (cap_bandfilt * cap_maxband * 16)) {
1236 /* exposure reach max */
1237 cap_shutter = cap_bandfilt * cap_maxband;
1238 cap_gain16 = cap_gain16_shutter / cap_shutter;
1239 } else {
1240 /* 1/100 < (cap_shutter = n/100) =< max */
1241 cap_shutter =
1242 ((int) (cap_gain16_shutter/16 / cap_bandfilt))
1243 *cap_bandfilt;
1244 cap_gain16 = cap_gain16_shutter / cap_shutter;
1245 }
1246 }
1247
1248 /* write capture gain */
1249 OV5640_set_gain16(cap_gain16);
1250
1251 /* write capture shutter */
1252 if (cap_shutter > (cap_VTS - 4)) {
1253 cap_VTS = cap_shutter + 4;
1254 OV5640_set_VTS(cap_VTS);
1255 }
1256 OV5640_set_shutter(cap_shutter);
1257
1258 OV5640_stream_on();
1259
1260err:
1261 return retval;
1262}
1263
1264/* if sensor changes inside scaling or subsampling
1265 * change mode directly
1266 * */
1267static int ov5640_change_mode_direct(enum ov5640_frame_rate frame_rate,
1268 enum ov5640_mode mode)
1269{
1270 struct reg_value *pModeSetting = NULL;
1271 s32 ArySize = 0;
1272 int retval = 0;
1273
1274 /* check if the input mode and frame rate is valid */
1275 pModeSetting =
1276 ov5640_mode_info_data[frame_rate][mode].init_data_ptr;
1277 ArySize =
1278 ov5640_mode_info_data[frame_rate][mode].init_data_size;
1279
1280 ov5640_data.pix.width =
1281 ov5640_mode_info_data[frame_rate][mode].width;
1282 ov5640_data.pix.height =
1283 ov5640_mode_info_data[frame_rate][mode].height;
1284
1285 if (ov5640_data.pix.width == 0 || ov5640_data.pix.height == 0 ||
1286 pModeSetting == NULL || ArySize == 0)
1287 return -EINVAL;
1288
1289 /* turn off AE/AG */
1290 OV5640_turn_on_AE_AG(0);
1291
1292 OV5640_stream_off();
1293
1294 /* Write capture setting */
1295 retval = ov5640_download_firmware(pModeSetting, ArySize);
1296 if (retval < 0)
1297 goto err;
1298
1299 OV5640_stream_on();
1300
1301 OV5640_turn_on_AE_AG(1);
1302
1303err:
1304 return retval;
1305}
1306
1307static int ov5640_init_mode(enum ov5640_frame_rate frame_rate,
1308 enum ov5640_mode mode, enum ov5640_mode orig_mode)
1309{
1310 struct reg_value *pModeSetting = NULL;
1311 s32 ArySize = 0;
1312 int retval = 0;
1313 void *mipi_csi2_info;
1314 u32 mipi_reg, msec_wait4stable = 0;
1315 enum ov5640_downsize_mode dn_mode, orig_dn_mode;
1316
1317 if ((mode > ov5640_mode_MAX || mode < ov5640_mode_MIN)
1318 && (mode != ov5640_mode_INIT)) {
1319 pr_err("Wrong ov5640 mode detected!\n");
1320 return -1;
1321 }
1322
1323 mipi_csi2_info = mipi_csi2_get_info();
1324
1325 /* initial mipi dphy */
1326 if (!mipi_csi2_info) {
1327 printk(KERN_ERR "%s() in %s: Fail to get mipi_csi2_info!\n",
1328 __func__, __FILE__);
1329 return -1;
1330 }
1331
1332 if (!mipi_csi2_get_status(mipi_csi2_info))
1333 mipi_csi2_enable(mipi_csi2_info);
1334
1335 if (!mipi_csi2_get_status(mipi_csi2_info)) {
1336 pr_err("Can not enable mipi csi2 driver!\n");
1337 return -1;
1338 }
1339
1340 mipi_csi2_set_lanes(mipi_csi2_info);
1341
1342 /*Only reset MIPI CSI2 HW at sensor initialize*/
1343 if (mode == ov5640_mode_INIT)
1344 mipi_csi2_reset(mipi_csi2_info);
1345
1346 if (ov5640_data.pix.pixelformat == V4L2_PIX_FMT_UYVY)
1347 mipi_csi2_set_datatype(mipi_csi2_info, MIPI_DT_YUV422);
1348 else if (ov5640_data.pix.pixelformat == V4L2_PIX_FMT_RGB565)
1349 mipi_csi2_set_datatype(mipi_csi2_info, MIPI_DT_RGB565);
1350 else
1351 pr_err("currently this sensor format can not be supported!\n");
1352
1353 dn_mode = ov5640_mode_info_data[frame_rate][mode].dn_mode;
1354 orig_dn_mode = ov5640_mode_info_data[frame_rate][orig_mode].dn_mode;
1355 if (mode == ov5640_mode_INIT) {
1356 pModeSetting = ov5640_init_setting_30fps_VGA;
1357 ArySize = ARRAY_SIZE(ov5640_init_setting_30fps_VGA);
1358
1359 ov5640_data.pix.width = 640;
1360 ov5640_data.pix.height = 480;
1361 retval = ov5640_download_firmware(pModeSetting, ArySize);
1362 if (retval < 0)
1363 goto err;
1364
1365 pModeSetting = ov5640_setting_30fps_VGA_640_480;
1366 ArySize = ARRAY_SIZE(ov5640_setting_30fps_VGA_640_480);
1367 retval = ov5640_download_firmware(pModeSetting, ArySize);
1368 } else if ((dn_mode == SUBSAMPLING && orig_dn_mode == SCALING) ||
1369 (dn_mode == SCALING && orig_dn_mode == SUBSAMPLING)) {
1370 /* change between subsampling and scaling
1371 * go through exposure calucation */
1372 retval = ov5640_change_mode_exposure_calc(frame_rate, mode);
1373 } else {
1374 /* change inside subsampling or scaling
1375 * download firmware directly */
1376 retval = ov5640_change_mode_direct(frame_rate, mode);
1377 }
1378
1379 if (retval < 0)
1380 goto err;
1381
1382 OV5640_set_AE_target(AE_Target);
1383 OV5640_get_light_freq();
1384 OV5640_set_bandingfilter();
1385 ov5640_set_virtual_channel(ov5640_data.csi);
1386
1387 /* add delay to wait for sensor stable */
1388 if (mode == ov5640_mode_QSXGA_2592_1944) {
1389 /* dump the first two frames: 1/7.5*2
1390 * the frame rate of QSXGA is 7.5fps */
1391 msec_wait4stable = 267;
1392 } else if (frame_rate == ov5640_15_fps) {
1393 /* dump the first nine frames: 1/15*9 */
1394 msec_wait4stable = 600;
1395 } else if (frame_rate == ov5640_30_fps) {
1396 /* dump the first nine frames: 1/30*9 */
1397 msec_wait4stable = 300;
1398 }
1399 msleep(msec_wait4stable);
1400
1401 if (mipi_csi2_info) {
1402 unsigned int i;
1403
1404 i = 0;
1405
1406 /* wait for mipi sensor ready */
1407 mipi_reg = mipi_csi2_dphy_status(mipi_csi2_info);
1408 while ((mipi_reg == 0x200) && (i < 10)) {
1409 mipi_reg = mipi_csi2_dphy_status(mipi_csi2_info);
1410 i++;
1411 msleep(10);
1412 }
1413
1414 if (i >= 10) {
1415 pr_err("mipi csi2 can not receive sensor clk!\n");
1416 return -1;
1417 }
1418
1419 i = 0;
1420
1421 /* wait for mipi stable */
1422 mipi_reg = mipi_csi2_get_error1(mipi_csi2_info);
1423 while ((mipi_reg != 0x0) && (i < 10)) {
1424 mipi_reg = mipi_csi2_get_error1(mipi_csi2_info);
1425 i++;
1426 msleep(10);
1427 }
1428
1429 if (i >= 10) {
1430 pr_err("mipi csi2 can not reveive data correctly!\n");
1431 return -1;
1432 }
1433 }
1434err:
1435 return retval;
1436}
1437
1438/* --------------- IOCTL functions from v4l2_int_ioctl_desc --------------- */
1439
1440static int ioctl_g_ifparm(struct v4l2_int_device *s, struct v4l2_ifparm *p)
1441{
1442 if (s == NULL) {
1443 pr_err(" ERROR!! no slave device set!\n");
1444 return -1;
1445 }
1446
1447 memset(p, 0, sizeof(*p));
1448 p->u.bt656.clock_curr = ov5640_data.mclk;
1449 pr_debug(" clock_curr=mclk=%d\n", ov5640_data.mclk);
1450 p->if_type = V4L2_IF_TYPE_BT656;
1451 p->u.bt656.mode = V4L2_IF_TYPE_BT656_MODE_NOBT_8BIT;
1452 p->u.bt656.clock_min = OV5640_XCLK_MIN;
1453 p->u.bt656.clock_max = OV5640_XCLK_MAX;
1454 p->u.bt656.bt_sync_correct = 1; /* Indicate external vsync */
1455
1456 return 0;
1457}
1458
1459/*!
1460 * ioctl_s_power - V4L2 sensor interface handler for VIDIOC_S_POWER ioctl
1461 * @s: pointer to standard V4L2 device structure
1462 * @on: indicates power mode (on or off)
1463 *
1464 * Turns the power on or off, depending on the value of on and returns the
1465 * appropriate error code.
1466 */
1467static int ioctl_s_power(struct v4l2_int_device *s, int on)
1468{
1469 struct sensor_data *sensor = s->priv;
1470
1471 if (on && !sensor->on) {
1472 if (io_regulator)
1473 if (regulator_enable(io_regulator) != 0)
1474 return -EIO;
1475 if (core_regulator)
1476 if (regulator_enable(core_regulator) != 0)
1477 return -EIO;
1478 if (gpo_regulator)
1479 if (regulator_enable(gpo_regulator) != 0)
1480 return -EIO;
1481 if (analog_regulator)
1482 if (regulator_enable(analog_regulator) != 0)
1483 return -EIO;
1484 /* Make sure power on */
1485 ov5640_standby(0);
1486 } else if (!on && sensor->on) {
1487 if (analog_regulator)
1488 regulator_disable(analog_regulator);
1489 if (core_regulator)
1490 regulator_disable(core_regulator);
1491 if (io_regulator)
1492 regulator_disable(io_regulator);
1493 if (gpo_regulator)
1494 regulator_disable(gpo_regulator);
1495
1496 ov5640_standby(1);
1497 }
1498
1499 sensor->on = on;
1500
1501 return 0;
1502}
1503
1504/*!
1505 * ioctl_g_parm - V4L2 sensor interface handler for VIDIOC_G_PARM ioctl
1506 * @s: pointer to standard V4L2 device structure
1507 * @a: pointer to standard V4L2 VIDIOC_G_PARM ioctl structure
1508 *
1509 * Returns the sensor's video CAPTURE parameters.
1510 */
1511static int ioctl_g_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
1512{
1513 struct sensor_data *sensor = s->priv;
1514 struct v4l2_captureparm *cparm = &a->parm.capture;
1515 int ret = 0;
1516
1517 switch (a->type) {
1518 /* This is the only case currently handled. */
1519 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1520 memset(a, 0, sizeof(*a));
1521 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1522 cparm->capability = sensor->streamcap.capability;
1523 cparm->timeperframe = sensor->streamcap.timeperframe;
1524 cparm->capturemode = sensor->streamcap.capturemode;
1525 ret = 0;
1526 break;
1527
1528 /* These are all the possible cases. */
1529 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
1530 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1531 case V4L2_BUF_TYPE_VBI_CAPTURE:
1532 case V4L2_BUF_TYPE_VBI_OUTPUT:
1533 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
1534 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
1535 ret = -EINVAL;
1536 break;
1537
1538 default:
1539 pr_debug(" type is unknown - %d\n", a->type);
1540 ret = -EINVAL;
1541 break;
1542 }
1543
1544 return ret;
1545}
1546
1547/*!
1548 * ioctl_s_parm - V4L2 sensor interface handler for VIDIOC_S_PARM ioctl
1549 * @s: pointer to standard V4L2 device structure
1550 * @a: pointer to standard V4L2 VIDIOC_S_PARM ioctl structure
1551 *
1552 * Configures the sensor to use the input parameters, if possible. If
1553 * not possible, reverts to the old parameters and returns the
1554 * appropriate error code.
1555 */
1556static int ioctl_s_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
1557{
1558 struct sensor_data *sensor = s->priv;
1559 struct v4l2_fract *timeperframe = &a->parm.capture.timeperframe;
1560 u32 tgt_fps; /* target frames per secound */
1561 enum ov5640_frame_rate frame_rate;
1562 enum ov5640_mode orig_mode;
1563 int ret = 0;
1564
1565 /* Make sure power on */
1566 ov5640_standby(0);
1567
1568 switch (a->type) {
1569 /* This is the only case currently handled. */
1570 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1571 /* Check that the new frame rate is allowed. */
1572 if ((timeperframe->numerator == 0) ||
1573 (timeperframe->denominator == 0)) {
1574 timeperframe->denominator = DEFAULT_FPS;
1575 timeperframe->numerator = 1;
1576 }
1577
1578 tgt_fps = timeperframe->denominator /
1579 timeperframe->numerator;
1580
1581 if (tgt_fps > MAX_FPS) {
1582 timeperframe->denominator = MAX_FPS;
1583 timeperframe->numerator = 1;
1584 } else if (tgt_fps < MIN_FPS) {
1585 timeperframe->denominator = MIN_FPS;
1586 timeperframe->numerator = 1;
1587 }
1588
1589 /* Actual frame rate we use */
1590 tgt_fps = timeperframe->denominator /
1591 timeperframe->numerator;
1592
1593 if (tgt_fps == 15)
1594 frame_rate = ov5640_15_fps;
1595 else if (tgt_fps == 30)
1596 frame_rate = ov5640_30_fps;
1597 else {
1598 pr_err(" The camera frame rate is not supported!\n");
1599 return -EINVAL;
1600 }
1601
1602 orig_mode = sensor->streamcap.capturemode;
1603 ret = ov5640_init_mode(frame_rate,
1604 (u32)a->parm.capture.capturemode, orig_mode);
1605 if (ret < 0)
1606 return ret;
1607
1608 sensor->streamcap.timeperframe = *timeperframe;
1609 sensor->streamcap.capturemode =
1610 (u32)a->parm.capture.capturemode;
1611
1612 break;
1613
1614 /* These are all the possible cases. */
1615 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
1616 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1617 case V4L2_BUF_TYPE_VBI_CAPTURE:
1618 case V4L2_BUF_TYPE_VBI_OUTPUT:
1619 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
1620 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
1621 pr_debug(" type is not " \
1622 "V4L2_BUF_TYPE_VIDEO_CAPTURE but %d\n",
1623 a->type);
1624 ret = -EINVAL;
1625 break;
1626
1627 default:
1628 pr_debug(" type is unknown - %d\n", a->type);
1629 ret = -EINVAL;
1630 break;
1631 }
1632
1633 return ret;
1634}
1635
1636/*!
1637 * ioctl_g_fmt_cap - V4L2 sensor interface handler for ioctl_g_fmt_cap
1638 * @s: pointer to standard V4L2 device structure
1639 * @f: pointer to standard V4L2 v4l2_format structure
1640 *
1641 * Returns the sensor's current pixel format in the v4l2_format
1642 * parameter.
1643 */
1644static int ioctl_g_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f)
1645{
1646 struct sensor_data *sensor = s->priv;
1647
1648 f->fmt.pix = sensor->pix;
1649
1650 return 0;
1651}
1652
1653/*!
1654 * ioctl_g_ctrl - V4L2 sensor interface handler for VIDIOC_G_CTRL ioctl
1655 * @s: pointer to standard V4L2 device structure
1656 * @vc: standard V4L2 VIDIOC_G_CTRL ioctl structure
1657 *
1658 * If the requested control is supported, returns the control's current
1659 * value from the video_control[] array. Otherwise, returns -EINVAL
1660 * if the control is not supported.
1661 */
1662static int ioctl_g_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc)
1663{
1664 int ret = 0;
1665
1666 switch (vc->id) {
1667 case V4L2_CID_BRIGHTNESS:
1668 vc->value = ov5640_data.brightness;
1669 break;
1670 case V4L2_CID_HUE:
1671 vc->value = ov5640_data.hue;
1672 break;
1673 case V4L2_CID_CONTRAST:
1674 vc->value = ov5640_data.contrast;
1675 break;
1676 case V4L2_CID_SATURATION:
1677 vc->value = ov5640_data.saturation;
1678 break;
1679 case V4L2_CID_RED_BALANCE:
1680 vc->value = ov5640_data.red;
1681 break;
1682 case V4L2_CID_BLUE_BALANCE:
1683 vc->value = ov5640_data.blue;
1684 break;
1685 case V4L2_CID_EXPOSURE:
1686 vc->value = ov5640_data.ae_mode;
1687 break;
1688 default:
1689 ret = -EINVAL;
1690 }
1691
1692 return ret;
1693}
1694
1695/*!
1696 * ioctl_s_ctrl - V4L2 sensor interface handler for VIDIOC_S_CTRL ioctl
1697 * @s: pointer to standard V4L2 device structure
1698 * @vc: standard V4L2 VIDIOC_S_CTRL ioctl structure
1699 *
1700 * If the requested control is supported, sets the control's current
1701 * value in HW (and updates the video_control[] array). Otherwise,
1702 * returns -EINVAL if the control is not supported.
1703 */
1704static int ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc)
1705{
1706 int retval = 0;
1707
1708 pr_debug("In ov5640:ioctl_s_ctrl %d\n",
1709 vc->id);
1710
1711 switch (vc->id) {
1712 case V4L2_CID_BRIGHTNESS:
1713 break;
1714 case V4L2_CID_CONTRAST:
1715 break;
1716 case V4L2_CID_SATURATION:
1717 break;
1718 case V4L2_CID_HUE:
1719 break;
1720 case V4L2_CID_AUTO_WHITE_BALANCE:
1721 break;
1722 case V4L2_CID_DO_WHITE_BALANCE:
1723 break;
1724 case V4L2_CID_RED_BALANCE:
1725 break;
1726 case V4L2_CID_BLUE_BALANCE:
1727 break;
1728 case V4L2_CID_GAMMA:
1729 break;
1730 case V4L2_CID_EXPOSURE:
1731 break;
1732 case V4L2_CID_AUTOGAIN:
1733 break;
1734 case V4L2_CID_GAIN:
1735 break;
1736 case V4L2_CID_HFLIP:
1737 break;
1738 case V4L2_CID_VFLIP:
1739 break;
1740 default:
1741 retval = -EPERM;
1742 break;
1743 }
1744
1745 return retval;
1746}
1747
1748/*!
1749 * ioctl_enum_framesizes - V4L2 sensor interface handler for
1750 * VIDIOC_ENUM_FRAMESIZES ioctl
1751 * @s: pointer to standard V4L2 device structure
1752 * @fsize: standard V4L2 VIDIOC_ENUM_FRAMESIZES ioctl structure
1753 *
1754 * Return 0 if successful, otherwise -EINVAL.
1755 */
1756static int ioctl_enum_framesizes(struct v4l2_int_device *s,
1757 struct v4l2_frmsizeenum *fsize)
1758{
1759 if (fsize->index > ov5640_mode_MAX)
1760 return -EINVAL;
1761
1762 fsize->pixel_format = ov5640_data.pix.pixelformat;
1763 fsize->discrete.width =
1764 max(ov5640_mode_info_data[0][fsize->index].width,
1765 ov5640_mode_info_data[1][fsize->index].width);
1766 fsize->discrete.height =
1767 max(ov5640_mode_info_data[0][fsize->index].height,
1768 ov5640_mode_info_data[1][fsize->index].height);
1769 return 0;
1770}
1771
1772/*!
1773 * ioctl_g_chip_ident - V4L2 sensor interface handler for
1774 * VIDIOC_DBG_G_CHIP_IDENT ioctl
1775 * @s: pointer to standard V4L2 device structure
1776 * @id: pointer to int
1777 *
1778 * Return 0.
1779 */
1780static int ioctl_g_chip_ident(struct v4l2_int_device *s, int *id)
1781{
1782 ((struct v4l2_dbg_chip_ident *)id)->match.type =
1783 V4L2_CHIP_MATCH_I2C_DRIVER;
1784 strcpy(((struct v4l2_dbg_chip_ident *)id)->match.name,
1785 "ov5640_mipi_camera");
1786
1787 return 0;
1788}
1789
1790/*!
1791 * ioctl_init - V4L2 sensor interface handler for VIDIOC_INT_INIT
1792 * @s: pointer to standard V4L2 device structure
1793 */
1794static int ioctl_init(struct v4l2_int_device *s)
1795{
1796
1797 return 0;
1798}
1799
1800/*!
1801 * ioctl_enum_fmt_cap - V4L2 sensor interface handler for VIDIOC_ENUM_FMT
1802 * @s: pointer to standard V4L2 device structure
1803 * @fmt: pointer to standard V4L2 fmt description structure
1804 *
1805 * Return 0.
1806 */
1807static int ioctl_enum_fmt_cap(struct v4l2_int_device *s,
1808 struct v4l2_fmtdesc *fmt)
1809{
1810 if (fmt->index > ov5640_mode_MAX)
1811 return -EINVAL;
1812
1813 fmt->pixelformat = ov5640_data.pix.pixelformat;
1814
1815 return 0;
1816}
1817
1818/*!
1819 * ioctl_dev_init - V4L2 sensor interface handler for vidioc_int_dev_init_num
1820 * @s: pointer to standard V4L2 device structure
1821 *
1822 * Initialise the device when slave attaches to the master.
1823 */
1824static int ioctl_dev_init(struct v4l2_int_device *s)
1825{
1826 struct sensor_data *sensor = s->priv;
1827 u32 tgt_xclk; /* target xclk */
1828 u32 tgt_fps; /* target frames per secound */
1829 int ret;
1830 enum ov5640_frame_rate frame_rate;
1831 void *mipi_csi2_info;
1832
1833 ov5640_data.on = true;
1834
1835 /* mclk */
1836 tgt_xclk = ov5640_data.mclk;
1837 tgt_xclk = min(tgt_xclk, (u32)OV5640_XCLK_MAX);
1838 tgt_xclk = max(tgt_xclk, (u32)OV5640_XCLK_MIN);
1839 ov5640_data.mclk = tgt_xclk;
1840
1841 pr_debug(" Setting mclk to %d MHz\n", tgt_xclk / 1000000);
1842
1843 /* Default camera frame rate is set in probe */
1844 tgt_fps = sensor->streamcap.timeperframe.denominator /
1845 sensor->streamcap.timeperframe.numerator;
1846
1847 if (tgt_fps == 15)
1848 frame_rate = ov5640_15_fps;
1849 else if (tgt_fps == 30)
1850 frame_rate = ov5640_30_fps;
1851 else
1852 return -EINVAL; /* Only support 15fps or 30fps now. */
1853
1854 mipi_csi2_info = mipi_csi2_get_info();
1855
1856 /* enable mipi csi2 */
1857 if (mipi_csi2_info)
1858 mipi_csi2_enable(mipi_csi2_info);
1859 else {
1860 printk(KERN_ERR "%s() in %s: Fail to get mipi_csi2_info!\n",
1861 __func__, __FILE__);
1862 return -EPERM;
1863 }
1864
1865 ret = ov5640_init_mode(frame_rate, ov5640_mode_INIT, ov5640_mode_INIT);
1866
1867 return ret;
1868}
1869
1870/*!
1871 * ioctl_dev_exit - V4L2 sensor interface handler for vidioc_int_dev_exit_num
1872 * @s: pointer to standard V4L2 device structure
1873 *
1874 * Delinitialise the device when slave detaches to the master.
1875 */
1876static int ioctl_dev_exit(struct v4l2_int_device *s)
1877{
1878 void *mipi_csi2_info;
1879
1880 mipi_csi2_info = mipi_csi2_get_info();
1881
1882 /* disable mipi csi2 */
1883 if (mipi_csi2_info)
1884 if (mipi_csi2_get_status(mipi_csi2_info))
1885 mipi_csi2_disable(mipi_csi2_info);
1886
1887 return 0;
1888}
1889
1890/*!
1891 * This structure defines all the ioctls for this module and links them to the
1892 * enumeration.
1893 */
1894static struct v4l2_int_ioctl_desc ov5640_ioctl_desc[] = {
1895 {vidioc_int_dev_init_num, (v4l2_int_ioctl_func *) ioctl_dev_init},
1896 {vidioc_int_dev_exit_num, ioctl_dev_exit},
1897 {vidioc_int_s_power_num, (v4l2_int_ioctl_func *) ioctl_s_power},
1898 {vidioc_int_g_ifparm_num, (v4l2_int_ioctl_func *) ioctl_g_ifparm},
1899/* {vidioc_int_g_needs_reset_num,
1900 (v4l2_int_ioctl_func *)ioctl_g_needs_reset}, */
1901/* {vidioc_int_reset_num, (v4l2_int_ioctl_func *)ioctl_reset}, */
1902 {vidioc_int_init_num, (v4l2_int_ioctl_func *) ioctl_init},
1903 {vidioc_int_enum_fmt_cap_num,
1904 (v4l2_int_ioctl_func *) ioctl_enum_fmt_cap},
1905/* {vidioc_int_try_fmt_cap_num,
1906 (v4l2_int_ioctl_func *)ioctl_try_fmt_cap}, */
1907 {vidioc_int_g_fmt_cap_num, (v4l2_int_ioctl_func *) ioctl_g_fmt_cap},
1908/* {vidioc_int_s_fmt_cap_num, (v4l2_int_ioctl_func *) ioctl_s_fmt_cap}, */
1909 {vidioc_int_g_parm_num, (v4l2_int_ioctl_func *) ioctl_g_parm},
1910 {vidioc_int_s_parm_num, (v4l2_int_ioctl_func *) ioctl_s_parm},
1911/* {vidioc_int_queryctrl_num, (v4l2_int_ioctl_func *)ioctl_queryctrl}, */
1912 {vidioc_int_g_ctrl_num, (v4l2_int_ioctl_func *) ioctl_g_ctrl},
1913 {vidioc_int_s_ctrl_num, (v4l2_int_ioctl_func *) ioctl_s_ctrl},
1914 {vidioc_int_enum_framesizes_num,
1915 (v4l2_int_ioctl_func *) ioctl_enum_framesizes},
1916 {vidioc_int_g_chip_ident_num,
1917 (v4l2_int_ioctl_func *) ioctl_g_chip_ident},
1918};
1919
1920static struct v4l2_int_slave ov5640_slave = {
1921 .ioctls = ov5640_ioctl_desc,
1922 .num_ioctls = ARRAY_SIZE(ov5640_ioctl_desc),
1923};
1924
1925static struct v4l2_int_device ov5640_int_device = {
1926 .module = THIS_MODULE,
1927 .name = "ov5640",
1928 .type = v4l2_int_type_slave,
1929 .u = {
1930 .slave = &ov5640_slave,
1931 },
1932};
1933
1934/*!
1935 * ov5640 I2C probe function
1936 *
1937 * @param adapter struct i2c_adapter *
1938 * @return Error code indicating success or failure
1939 */
1940static int ov5640_probe(struct i2c_client *client,
1941 const struct i2c_device_id *id)
1942{
1943 struct device *dev = &client->dev;
1944 int retval;
1945 u8 chip_id_high, chip_id_low;
1946
1947 /* request power down pin */
1948 pwn_gpio = of_get_named_gpio(dev->of_node, "pwn-gpios", 0);
1949 if (!gpio_is_valid(pwn_gpio)) {
1950 dev_warn(dev, "no sensor pwdn pin available");
1951 return -EINVAL;
1952 }
1953 retval = devm_gpio_request_one(dev, pwn_gpio, GPIOF_OUT_INIT_HIGH,
1954 "ov5640_mipi_pwdn");
1955 if (retval < 0)
1956 return retval;
1957
1958 /* request reset pin */
1959 rst_gpio = of_get_named_gpio(dev->of_node, "rst-gpios", 0);
1960 if (!gpio_is_valid(rst_gpio)) {
1961 dev_warn(dev, "no sensor reset pin available");
1962 return -EINVAL;
1963 }
1964 retval = devm_gpio_request_one(dev, rst_gpio, GPIOF_OUT_INIT_HIGH,
1965 "ov5640_mipi_reset");
1966 if (retval < 0)
1967 return retval;
1968
1969 /* Set initial values for the sensor struct. */
1970 memset(&ov5640_data, 0, sizeof(ov5640_data));
1971 ov5640_data.sensor_clk = devm_clk_get(dev, "csi_mclk");
1972 if (IS_ERR(ov5640_data.sensor_clk)) {
1973 /* assuming clock enabled by default */
1974 ov5640_data.sensor_clk = NULL;
1975 dev_err(dev, "clock-frequency missing or invalid\n");
1976 return PTR_ERR(ov5640_data.sensor_clk);
1977 }
1978
1979 retval = of_property_read_u32(dev->of_node, "mclk",
1980 &(ov5640_data.mclk));
1981 if (retval) {
1982 dev_err(dev, "mclk missing or invalid\n");
1983 return retval;
1984 }
1985
1986 retval = of_property_read_u32(dev->of_node, "mclk_source",
1987 (u32 *) &(ov5640_data.mclk_source));
1988 if (retval) {
1989 dev_err(dev, "mclk_source missing or invalid\n");
1990 return retval;
1991 }
1992
1993 retval = of_property_read_u32(dev->of_node, "csi_id",
1994 &(ov5640_data.csi));
1995 if (retval) {
1996 dev_err(dev, "csi id missing or invalid\n");
1997 return retval;
1998 }
1999
2000 clk_prepare_enable(ov5640_data.sensor_clk);
2001
2002 ov5640_data.io_init = ov5640_reset;
2003 ov5640_data.i2c_client = client;
2004 ov5640_data.pix.pixelformat = V4L2_PIX_FMT_UYVY;
2005 ov5640_data.pix.width = 640;
2006 ov5640_data.pix.height = 480;
2007 ov5640_data.streamcap.capability = V4L2_MODE_HIGHQUALITY |
2008 V4L2_CAP_TIMEPERFRAME;
2009 ov5640_data.streamcap.capturemode = 0;
2010 ov5640_data.streamcap.timeperframe.denominator = DEFAULT_FPS;
2011 ov5640_data.streamcap.timeperframe.numerator = 1;
2012
2013 ov5640_power_on(dev);
2014
2015 ov5640_reset();
2016
2017 ov5640_standby(0);
2018
2019 retval = ov5640_read_reg(OV5640_CHIP_ID_HIGH_BYTE, &chip_id_high);
2020 if (retval < 0 || chip_id_high != 0x56) {
2021 pr_warning("camera ov5640_mipi is not found\n");
2022 clk_disable_unprepare(ov5640_data.sensor_clk);
2023 return -ENODEV;
2024 }
2025 retval = ov5640_read_reg(OV5640_CHIP_ID_LOW_BYTE, &chip_id_low);
2026 if (retval < 0 || chip_id_low != 0x40) {
2027 pr_warning("camera ov5640_mipi is not found\n");
2028 clk_disable_unprepare(ov5640_data.sensor_clk);
2029 return -ENODEV;
2030 }
2031
2032 ov5640_standby(1);
2033
2034 ov5640_int_device.priv = &ov5640_data;
2035 retval = v4l2_int_device_register(&ov5640_int_device);
2036
2037 clk_disable_unprepare(ov5640_data.sensor_clk);
2038
2039 pr_info("camera ov5640_mipi is found\n");
2040 return retval;
2041}
2042
2043/*!
2044 * ov5640 I2C detach function
2045 *
2046 * @param client struct i2c_client *
2047 * @return Error code indicating success or failure
2048 */
2049static int ov5640_remove(struct i2c_client *client)
2050{
2051 v4l2_int_device_unregister(&ov5640_int_device);
2052
2053 if (gpo_regulator)
2054 regulator_disable(gpo_regulator);
2055
2056 if (analog_regulator)
2057 regulator_disable(analog_regulator);
2058
2059 if (core_regulator)
2060 regulator_disable(core_regulator);
2061
2062 if (io_regulator)
2063 regulator_disable(io_regulator);
2064
2065 return 0;
2066}
2067
2068/*!
2069 * ov5640 init function
2070 * Called by insmod ov5640_camera.ko.
2071 *
2072 * @return Error code indicating success or failure
2073 */
2074static __init int ov5640_init(void)
2075{
2076 u8 err;
2077
2078 err = i2c_add_driver(&ov5640_i2c_driver);
2079 if (err != 0)
2080 pr_err("%s:driver registration failed, error=%d\n",
2081 __func__, err);
2082
2083 return err;
2084}
2085
2086/*!
2087 * OV5640 cleanup function
2088 * Called on rmmod ov5640_camera.ko
2089 *
2090 * @return Error code indicating success or failure
2091 */
2092static void __exit ov5640_clean(void)
2093{
2094 i2c_del_driver(&ov5640_i2c_driver);
2095}
2096
2097module_init(ov5640_init);
2098module_exit(ov5640_clean);
2099
2100MODULE_AUTHOR("Freescale Semiconductor, Inc.");
2101MODULE_DESCRIPTION("OV5640 MIPI Camera Driver");
2102MODULE_LICENSE("GPL");
2103MODULE_VERSION("1.0");
2104MODULE_ALIAS("CSI");