2 * Copyright (C) 2012-2014 Freescale Semiconductor, Inc. All Rights Reserved.
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.
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.
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.
21 #include <linux/clk.h>
22 #include <linux/delay.h>
23 #include <linux/device.h>
24 #include <linux/i2c.h>
25 #include <linux/init.h>
26 #include <linux/module.h>
27 #include <linux/of_device.h>
28 #include <linux/of_gpio.h>
29 #include <linux/pinctrl/consumer.h>
30 #include <linux/regulator/consumer.h>
31 #include <linux/v4l2-mediabus.h>
32 #include <media/v4l2-device.h>
33 #include <media/v4l2-ctrls.h>
35 #define OV5640_VOLTAGE_ANALOG 2800000
36 #define OV5640_VOLTAGE_DIGITAL_CORE 1500000
37 #define OV5640_VOLTAGE_DIGITAL_IO 1800000
41 #define DEFAULT_FPS 30
43 #define OV5640_XCLK_MIN 6000000
44 #define OV5640_XCLK_MAX 24000000
46 #define OV5640_CHIP_ID_HIGH_BYTE 0x300A
47 #define OV5640_CHIP_ID_LOW_BYTE 0x300B
51 ov5640_mode_VGA_640_480 = 0,
52 ov5640_mode_QVGA_320_240 = 1,
53 ov5640_mode_NTSC_720_480 = 2,
54 ov5640_mode_PAL_720_576 = 3,
55 ov5640_mode_720P_1280_720 = 4,
56 ov5640_mode_1080P_1920_1080 = 5,
57 ov5640_mode_QSXGA_2592_1944 = 6,
58 ov5640_mode_QCIF_176_144 = 7,
59 ov5640_mode_XGA_1024_768 = 8,
63 enum ov5640_frame_rate {
68 static int ov5640_framerates[] = {
73 struct ov5640_datafmt {
74 enum v4l2_mbus_pixelcode code;
75 enum v4l2_colorspace colorspace;
85 struct ov5640_mode_info {
86 enum ov5640_mode mode;
89 struct reg_value *init_data_ptr;
94 struct v4l2_subdev subdev;
95 struct i2c_client *i2c_client;
96 struct v4l2_pix_format pix;
97 const struct ov5640_datafmt *fmt;
98 struct v4l2_captureparm streamcap;
101 /* control settings */
113 struct clk *sensor_clk;
116 void (*io_init)(void);
120 * Maintains the information on the current state of the sesor.
122 static struct ov5640 ov5640_data;
123 static int pwn_gpio, rst_gpio;
124 static int prev_sysclk;
125 static int AE_Target = 52, night_mode;
127 static int AE_high, AE_low;
129 static struct reg_value ov5640_global_init_setting[] = {
130 {0x3008, 0x42, 0, 0},
131 {0x3103, 0x03, 0, 0}, {0x3017, 0xff, 0, 0}, {0x3018, 0xff, 0, 0},
132 {0x3034, 0x1a, 0, 0}, {0x3037, 0x13, 0, 0}, {0x3108, 0x01, 0, 0},
133 {0x3630, 0x36, 0, 0}, {0x3631, 0x0e, 0, 0}, {0x3632, 0xe2, 0, 0},
134 {0x3633, 0x12, 0, 0}, {0x3621, 0xe0, 0, 0}, {0x3704, 0xa0, 0, 0},
135 {0x3703, 0x5a, 0, 0}, {0x3715, 0x78, 0, 0}, {0x3717, 0x01, 0, 0},
136 {0x370b, 0x60, 0, 0}, {0x3705, 0x1a, 0, 0}, {0x3905, 0x02, 0, 0},
137 {0x3906, 0x10, 0, 0}, {0x3901, 0x0a, 0, 0}, {0x3731, 0x12, 0, 0},
138 {0x3600, 0x08, 0, 0}, {0x3601, 0x33, 0, 0}, {0x302d, 0x60, 0, 0},
139 {0x3620, 0x52, 0, 0}, {0x371b, 0x20, 0, 0}, {0x471c, 0x50, 0, 0},
140 {0x3a13, 0x43, 0, 0}, {0x3a18, 0x00, 0, 0}, {0x3a19, 0x7c, 0, 0},
141 {0x3635, 0x13, 0, 0}, {0x3636, 0x03, 0, 0}, {0x3634, 0x40, 0, 0},
142 {0x3622, 0x01, 0, 0}, {0x3c01, 0x34, 0, 0}, {0x3c04, 0x28, 0, 0},
143 {0x3c05, 0x98, 0, 0}, {0x3c06, 0x00, 0, 0}, {0x3c07, 0x07, 0, 0},
144 {0x3c08, 0x00, 0, 0}, {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0},
145 {0x3c0b, 0x40, 0, 0}, {0x3810, 0x00, 0, 0}, {0x3811, 0x10, 0, 0},
146 {0x3812, 0x00, 0, 0}, {0x3708, 0x64, 0, 0}, {0x4001, 0x02, 0, 0},
147 {0x4005, 0x1a, 0, 0}, {0x3000, 0x00, 0, 0}, {0x3004, 0xff, 0, 0},
148 {0x300e, 0x58, 0, 0}, {0x302e, 0x00, 0, 0}, {0x4300, 0x30, 0, 0},
149 {0x501f, 0x00, 0, 0}, {0x440e, 0x00, 0, 0}, {0x5000, 0xa7, 0, 0},
150 {0x3008, 0x02, 0, 0},
153 static struct reg_value ov5640_init_setting_30fps_VGA[] = {
154 {0x3008, 0x42, 0, 0},
155 {0x3103, 0x03, 0, 0}, {0x3017, 0xff, 0, 0}, {0x3018, 0xff, 0, 0},
156 {0x3034, 0x1a, 0, 0}, {0x3035, 0x11, 0, 0}, {0x3036, 0x46, 0, 0},
157 {0x3037, 0x13, 0, 0}, {0x3108, 0x01, 0, 0}, {0x3630, 0x36, 0, 0},
158 {0x3631, 0x0e, 0, 0}, {0x3632, 0xe2, 0, 0}, {0x3633, 0x12, 0, 0},
159 {0x3621, 0xe0, 0, 0}, {0x3704, 0xa0, 0, 0}, {0x3703, 0x5a, 0, 0},
160 {0x3715, 0x78, 0, 0}, {0x3717, 0x01, 0, 0}, {0x370b, 0x60, 0, 0},
161 {0x3705, 0x1a, 0, 0}, {0x3905, 0x02, 0, 0}, {0x3906, 0x10, 0, 0},
162 {0x3901, 0x0a, 0, 0}, {0x3731, 0x12, 0, 0}, {0x3600, 0x08, 0, 0},
163 {0x3601, 0x33, 0, 0}, {0x302d, 0x60, 0, 0}, {0x3620, 0x52, 0, 0},
164 {0x371b, 0x20, 0, 0}, {0x471c, 0x50, 0, 0}, {0x3a13, 0x43, 0, 0},
165 {0x3a18, 0x00, 0, 0}, {0x3a19, 0xf8, 0, 0}, {0x3635, 0x13, 0, 0},
166 {0x3636, 0x03, 0, 0}, {0x3634, 0x40, 0, 0}, {0x3622, 0x01, 0, 0},
167 {0x3c01, 0x34, 0, 0}, {0x3c04, 0x28, 0, 0}, {0x3c05, 0x98, 0, 0},
168 {0x3c06, 0x00, 0, 0}, {0x3c07, 0x08, 0, 0}, {0x3c08, 0x00, 0, 0},
169 {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
170 {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
171 {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
172 {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
173 {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
174 {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0},
175 {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
176 {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
177 {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
178 {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
179 {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
180 {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
181 {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
182 {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
183 {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x3000, 0x00, 0, 0},
184 {0x3002, 0x1c, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3006, 0xc3, 0, 0},
185 {0x300e, 0x58, 0, 0}, {0x302e, 0x00, 0, 0}, {0x4300, 0x30, 0, 0},
186 {0x501f, 0x00, 0, 0}, {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0},
187 {0x440e, 0x00, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
188 {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0}, {0x5000, 0xa7, 0, 0},
189 {0x5001, 0xa3, 0, 0}, {0x5180, 0xff, 0, 0}, {0x5181, 0xf2, 0, 0},
190 {0x5182, 0x00, 0, 0}, {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0},
191 {0x5185, 0x24, 0, 0}, {0x5186, 0x09, 0, 0}, {0x5187, 0x09, 0, 0},
192 {0x5188, 0x09, 0, 0}, {0x5189, 0x88, 0, 0}, {0x518a, 0x54, 0, 0},
193 {0x518b, 0xee, 0, 0}, {0x518c, 0xb2, 0, 0}, {0x518d, 0x50, 0, 0},
194 {0x518e, 0x34, 0, 0}, {0x518f, 0x6b, 0, 0}, {0x5190, 0x46, 0, 0},
195 {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0},
196 {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0},
197 {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0}, {0x5199, 0x6c, 0, 0},
198 {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0}, {0x519c, 0x09, 0, 0},
199 {0x519d, 0x2b, 0, 0}, {0x519e, 0x38, 0, 0}, {0x5381, 0x1e, 0, 0},
200 {0x5382, 0x5b, 0, 0}, {0x5383, 0x08, 0, 0}, {0x5384, 0x0a, 0, 0},
201 {0x5385, 0x7e, 0, 0}, {0x5386, 0x88, 0, 0}, {0x5387, 0x7c, 0, 0},
202 {0x5388, 0x6c, 0, 0}, {0x5389, 0x10, 0, 0}, {0x538a, 0x01, 0, 0},
203 {0x538b, 0x98, 0, 0}, {0x5300, 0x08, 0, 0}, {0x5301, 0x30, 0, 0},
204 {0x5302, 0x10, 0, 0}, {0x5303, 0x00, 0, 0}, {0x5304, 0x08, 0, 0},
205 {0x5305, 0x30, 0, 0}, {0x5306, 0x08, 0, 0}, {0x5307, 0x16, 0, 0},
206 {0x5309, 0x08, 0, 0}, {0x530a, 0x30, 0, 0}, {0x530b, 0x04, 0, 0},
207 {0x530c, 0x06, 0, 0}, {0x5480, 0x01, 0, 0}, {0x5481, 0x08, 0, 0},
208 {0x5482, 0x14, 0, 0}, {0x5483, 0x28, 0, 0}, {0x5484, 0x51, 0, 0},
209 {0x5485, 0x65, 0, 0}, {0x5486, 0x71, 0, 0}, {0x5487, 0x7d, 0, 0},
210 {0x5488, 0x87, 0, 0}, {0x5489, 0x91, 0, 0}, {0x548a, 0x9a, 0, 0},
211 {0x548b, 0xaa, 0, 0}, {0x548c, 0xb8, 0, 0}, {0x548d, 0xcd, 0, 0},
212 {0x548e, 0xdd, 0, 0}, {0x548f, 0xea, 0, 0}, {0x5490, 0x1d, 0, 0},
213 {0x5580, 0x02, 0, 0}, {0x5583, 0x40, 0, 0}, {0x5584, 0x10, 0, 0},
214 {0x5589, 0x10, 0, 0}, {0x558a, 0x00, 0, 0}, {0x558b, 0xf8, 0, 0},
215 {0x5800, 0x23, 0, 0}, {0x5801, 0x14, 0, 0}, {0x5802, 0x0f, 0, 0},
216 {0x5803, 0x0f, 0, 0}, {0x5804, 0x12, 0, 0}, {0x5805, 0x26, 0, 0},
217 {0x5806, 0x0c, 0, 0}, {0x5807, 0x08, 0, 0}, {0x5808, 0x05, 0, 0},
218 {0x5809, 0x05, 0, 0}, {0x580a, 0x08, 0, 0}, {0x580b, 0x0d, 0, 0},
219 {0x580c, 0x08, 0, 0}, {0x580d, 0x03, 0, 0}, {0x580e, 0x00, 0, 0},
220 {0x580f, 0x00, 0, 0}, {0x5810, 0x03, 0, 0}, {0x5811, 0x09, 0, 0},
221 {0x5812, 0x07, 0, 0}, {0x5813, 0x03, 0, 0}, {0x5814, 0x00, 0, 0},
222 {0x5815, 0x01, 0, 0}, {0x5816, 0x03, 0, 0}, {0x5817, 0x08, 0, 0},
223 {0x5818, 0x0d, 0, 0}, {0x5819, 0x08, 0, 0}, {0x581a, 0x05, 0, 0},
224 {0x581b, 0x06, 0, 0}, {0x581c, 0x08, 0, 0}, {0x581d, 0x0e, 0, 0},
225 {0x581e, 0x29, 0, 0}, {0x581f, 0x17, 0, 0}, {0x5820, 0x11, 0, 0},
226 {0x5821, 0x11, 0, 0}, {0x5822, 0x15, 0, 0}, {0x5823, 0x28, 0, 0},
227 {0x5824, 0x46, 0, 0}, {0x5825, 0x26, 0, 0}, {0x5826, 0x08, 0, 0},
228 {0x5827, 0x26, 0, 0}, {0x5828, 0x64, 0, 0}, {0x5829, 0x26, 0, 0},
229 {0x582a, 0x24, 0, 0}, {0x582b, 0x22, 0, 0}, {0x582c, 0x24, 0, 0},
230 {0x582d, 0x24, 0, 0}, {0x582e, 0x06, 0, 0}, {0x582f, 0x22, 0, 0},
231 {0x5830, 0x40, 0, 0}, {0x5831, 0x42, 0, 0}, {0x5832, 0x24, 0, 0},
232 {0x5833, 0x26, 0, 0}, {0x5834, 0x24, 0, 0}, {0x5835, 0x22, 0, 0},
233 {0x5836, 0x22, 0, 0}, {0x5837, 0x26, 0, 0}, {0x5838, 0x44, 0, 0},
234 {0x5839, 0x24, 0, 0}, {0x583a, 0x26, 0, 0}, {0x583b, 0x28, 0, 0},
235 {0x583c, 0x42, 0, 0}, {0x583d, 0xce, 0, 0}, {0x5025, 0x00, 0, 0},
236 {0x3a0f, 0x30, 0, 0}, {0x3a10, 0x28, 0, 0}, {0x3a1b, 0x30, 0, 0},
237 {0x3a1e, 0x26, 0, 0}, {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x14, 0, 0},
238 {0x3008, 0x02, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x11, 0, 0},
239 {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
242 static struct reg_value ov5640_setting_30fps_VGA_640_480[] = {
243 {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
244 {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
245 {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
246 {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
247 {0x3807, 0x9b, 0, 0}, {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0},
248 {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0},
249 {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
250 {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
251 {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
252 {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
253 {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
254 {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
255 {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
256 {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x11, 0, 0},
257 {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0}, {0x3503, 0x00, 0, 0},
260 static struct reg_value ov5640_setting_15fps_VGA_640_480[] = {
261 {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
262 {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
263 {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
264 {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
265 {0x3807, 0x9b, 0, 0}, {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0},
266 {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0},
267 {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
268 {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
269 {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
270 {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
271 {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
272 {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
273 {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
274 {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
275 {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0}, {0x3503, 0x00, 0, 0},
278 static struct reg_value ov5640_setting_30fps_QVGA_320_240[] = {
279 {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
280 {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
281 {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
282 {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
283 {0x3807, 0x9b, 0, 0}, {0x3808, 0x01, 0, 0}, {0x3809, 0x40, 0, 0},
284 {0x380a, 0x00, 0, 0}, {0x380b, 0xf0, 0, 0}, {0x380c, 0x07, 0, 0},
285 {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
286 {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
287 {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
288 {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
289 {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
290 {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
291 {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
292 {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x11, 0, 0},
293 {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
296 static struct reg_value ov5640_setting_15fps_QVGA_320_240[] = {
297 {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
298 {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
299 {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
300 {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
301 {0x3807, 0x9b, 0, 0}, {0x3808, 0x01, 0, 0}, {0x3809, 0x40, 0, 0},
302 {0x380a, 0x00, 0, 0}, {0x380b, 0xf0, 0, 0}, {0x380c, 0x07, 0, 0},
303 {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
304 {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
305 {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
306 {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
307 {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
308 {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
309 {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
310 {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
311 {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
314 static struct reg_value ov5640_setting_30fps_NTSC_720_480[] = {
315 {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
316 {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
317 {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
318 {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x06, 0, 0},
319 {0x3807, 0xd4, 0, 0}, {0x3808, 0x02, 0, 0}, {0x3809, 0xd0, 0, 0},
320 {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0},
321 {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
322 {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
323 {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
324 {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
325 {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
326 {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
327 {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
328 {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x11, 0, 0},
329 {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
332 static struct reg_value ov5640_setting_15fps_NTSC_720_480[] = {
333 {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
334 {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
335 {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
336 {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x06, 0, 0},
337 {0x3807, 0xd4, 0, 0}, {0x3808, 0x02, 0, 0}, {0x3809, 0xd0, 0, 0},
338 {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0},
339 {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
340 {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
341 {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
342 {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
343 {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
344 {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
345 {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
346 {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
347 {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
350 static struct reg_value ov5640_setting_30fps_PAL_720_576[] = {
351 {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
352 {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
353 {0x3801, 0x60, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
354 {0x3804, 0x09, 0, 0}, {0x3805, 0x7e, 0, 0}, {0x3806, 0x07, 0, 0},
355 {0x3807, 0x9b, 0, 0}, {0x3808, 0x02, 0, 0}, {0x3809, 0xd0, 0, 0},
356 {0x380a, 0x02, 0, 0}, {0x380b, 0x40, 0, 0}, {0x380c, 0x07, 0, 0},
357 {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
358 {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
359 {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
360 {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
361 {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
362 {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
363 {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
364 {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x11, 0, 0},
365 {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
368 static struct reg_value ov5640_setting_15fps_PAL_720_576[] = {
369 {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
370 {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
371 {0x3801, 0x60, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
372 {0x3804, 0x09, 0, 0}, {0x3805, 0x7e, 0, 0}, {0x3806, 0x07, 0, 0},
373 {0x3807, 0x9b, 0, 0}, {0x3808, 0x02, 0, 0}, {0x3809, 0xd0, 0, 0},
374 {0x380a, 0x02, 0, 0}, {0x380b, 0x40, 0, 0}, {0x380c, 0x07, 0, 0},
375 {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
376 {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
377 {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
378 {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
379 {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
380 {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
381 {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
382 {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
383 {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
386 static struct reg_value ov5640_setting_30fps_720P_1280_720[] = {
387 {0x3035, 0x21, 0, 0}, {0x3036, 0x69, 0, 0}, {0x3c07, 0x07, 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, 0xfa, 0, 0}, {0x3804, 0x0a, 0, 0},
391 {0x3805, 0x3f, 0, 0}, {0x3806, 0x06, 0, 0}, {0x3807, 0xa9, 0, 0},
392 {0x3808, 0x05, 0, 0}, {0x3809, 0x00, 0, 0}, {0x380a, 0x02, 0, 0},
393 {0x380b, 0xd0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x64, 0, 0},
394 {0x380e, 0x02, 0, 0}, {0x380f, 0xe4, 0, 0}, {0x3813, 0x04, 0, 0},
395 {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3709, 0x52, 0, 0},
396 {0x370c, 0x03, 0, 0}, {0x3a02, 0x02, 0, 0}, {0x3a03, 0xe0, 0, 0},
397 {0x3a14, 0x02, 0, 0}, {0x3a15, 0xe0, 0, 0}, {0x4004, 0x02, 0, 0},
398 {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0}, {0x4713, 0x03, 0, 0},
399 {0x4407, 0x04, 0, 0}, {0x460b, 0x37, 0, 0}, {0x460c, 0x20, 0, 0},
400 {0x4837, 0x16, 0, 0}, {0x3824, 0x04, 0, 0}, {0x5001, 0x83, 0, 0},
401 {0x3503, 0x00, 0, 0},
404 static struct reg_value ov5640_setting_15fps_720P_1280_720[] = {
405 {0x3035, 0x41, 0, 0}, {0x3036, 0x69, 0, 0}, {0x3c07, 0x07, 0, 0},
406 {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
407 {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
408 {0x3802, 0x00, 0, 0}, {0x3803, 0xfa, 0, 0}, {0x3804, 0x0a, 0, 0},
409 {0x3805, 0x3f, 0, 0}, {0x3806, 0x06, 0, 0}, {0x3807, 0xa9, 0, 0},
410 {0x3808, 0x05, 0, 0}, {0x3809, 0x00, 0, 0}, {0x380a, 0x02, 0, 0},
411 {0x380b, 0xd0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x64, 0, 0},
412 {0x380e, 0x02, 0, 0}, {0x380f, 0xe4, 0, 0}, {0x3813, 0x04, 0, 0},
413 {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3709, 0x52, 0, 0},
414 {0x370c, 0x03, 0, 0}, {0x3a02, 0x02, 0, 0}, {0x3a03, 0xe0, 0, 0},
415 {0x3a14, 0x02, 0, 0}, {0x3a15, 0xe0, 0, 0}, {0x4004, 0x02, 0, 0},
416 {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0}, {0x4713, 0x03, 0, 0},
417 {0x4407, 0x04, 0, 0}, {0x460b, 0x37, 0, 0}, {0x460c, 0x20, 0, 0},
418 {0x4837, 0x16, 0, 0}, {0x3824, 0x04, 0, 0}, {0x5001, 0x83, 0, 0},
419 {0x3503, 0x00, 0, 0},
422 static struct reg_value ov5640_setting_30fps_QCIF_176_144[] = {
423 {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
424 {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
425 {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
426 {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
427 {0x3807, 0x9b, 0, 0}, {0x3808, 0x00, 0, 0}, {0x3809, 0xb0, 0, 0},
428 {0x380a, 0x00, 0, 0}, {0x380b, 0x90, 0, 0}, {0x380c, 0x07, 0, 0},
429 {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
430 {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
431 {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
432 {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
433 {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
434 {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
435 {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
436 {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x11, 0, 0},
437 {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
440 static struct reg_value ov5640_setting_15fps_QCIF_176_144[] = {
441 {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
442 {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
443 {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
444 {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
445 {0x3807, 0x9b, 0, 0}, {0x3808, 0x00, 0, 0}, {0x3809, 0xb0, 0, 0},
446 {0x380a, 0x00, 0, 0}, {0x380b, 0x90, 0, 0}, {0x380c, 0x07, 0, 0},
447 {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
448 {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
449 {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
450 {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
451 {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
452 {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
453 {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
454 {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
455 {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
458 static struct reg_value ov5640_setting_30fps_XGA_1024_768[] = {
459 {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
460 {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
461 {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
462 {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
463 {0x3807, 0x9b, 0, 0}, {0x3808, 0x04, 0, 0}, {0x3809, 0x00, 0, 0},
464 {0x380a, 0x03, 0, 0}, {0x380b, 0x00, 0, 0}, {0x380c, 0x07, 0, 0},
465 {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
466 {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
467 {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
468 {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
469 {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
470 {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
471 {0x460c, 0x20, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x01, 0, 0},
472 {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
473 {0x3036, 0x69, 0, 0}, {0x3037, 0x13, 0, 0},
476 static struct reg_value ov5640_setting_15fps_XGA_1024_768[] = {
477 {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
478 {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
479 {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
480 {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
481 {0x3807, 0x9b, 0, 0}, {0x3808, 0x04, 0, 0}, {0x3809, 0x00, 0, 0},
482 {0x380a, 0x03, 0, 0}, {0x380b, 0x00, 0, 0}, {0x380c, 0x07, 0, 0},
483 {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
484 {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
485 {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
486 {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
487 {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
488 {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
489 {0x460c, 0x20, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x01, 0, 0},
490 {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
491 {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
495 static struct reg_value ov5640_setting_15fps_1080P_1920_1080[] = {
496 {0x3c07, 0x07, 0, 0}, {0x3820, 0x40, 0, 0}, {0x3821, 0x06, 0, 0},
497 {0x3814, 0x11, 0, 0}, {0x3815, 0x11, 0, 0}, {0x3800, 0x00, 0, 0},
498 {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0xee, 0, 0},
499 {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x05, 0, 0},
500 {0x3807, 0xc3, 0, 0}, {0x3808, 0x07, 0, 0}, {0x3809, 0x80, 0, 0},
501 {0x380a, 0x04, 0, 0}, {0x380b, 0x38, 0, 0}, {0x380c, 0x0b, 0, 0},
502 {0x380d, 0x1c, 0, 0}, {0x380e, 0x07, 0, 0}, {0x380f, 0xb0, 0, 0},
503 {0x3813, 0x04, 0, 0}, {0x3618, 0x04, 0, 0}, {0x3612, 0x2b, 0, 0},
504 {0x3709, 0x12, 0, 0}, {0x370c, 0x00, 0, 0}, {0x3a02, 0x07, 0, 0},
505 {0x3a03, 0xae, 0, 0}, {0x3a14, 0x07, 0, 0}, {0x3a15, 0xae, 0, 0},
506 {0x4004, 0x06, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
507 {0x4713, 0x02, 0, 0}, {0x4407, 0x0c, 0, 0}, {0x460b, 0x37, 0, 0},
508 {0x460c, 0x20, 0, 0}, {0x4837, 0x2c, 0, 0}, {0x3824, 0x01, 0, 0},
509 {0x5001, 0x83, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
510 {0x3036, 0x69, 0, 0}, {0x3037, 0x13, 0, 0},
513 static struct reg_value ov5640_setting_15fps_QSXGA_2592_1944[] = {
514 {0x3c07, 0x07, 0, 0}, {0x3820, 0x40, 0, 0}, {0x3821, 0x06, 0, 0},
515 {0x3814, 0x11, 0, 0}, {0x3815, 0x11, 0, 0}, {0x3800, 0x00, 0, 0},
516 {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x00, 0, 0},
517 {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
518 {0x3807, 0x9f, 0, 0}, {0x3808, 0x0a, 0, 0}, {0x3809, 0x20, 0, 0},
519 {0x380a, 0x07, 0, 0}, {0x380b, 0x98, 0, 0}, {0x380c, 0x0b, 0, 0},
520 {0x380d, 0x1c, 0, 0}, {0x380e, 0x07, 0, 0}, {0x380f, 0xb0, 0, 0},
521 {0x3813, 0x04, 0, 0}, {0x3618, 0x04, 0, 0}, {0x3612, 0x2b, 0, 0},
522 {0x3709, 0x12, 0, 0}, {0x370c, 0x00, 0, 0}, {0x3a02, 0x07, 0, 0},
523 {0x3a03, 0xae, 0, 0}, {0x3a14, 0x07, 0, 0}, {0x3a15, 0xae, 0, 0},
524 {0x4004, 0x06, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
525 {0x4713, 0x02, 0, 0}, {0x4407, 0x0c, 0, 0}, {0x460b, 0x37, 0, 0},
526 {0x460c, 0x20, 0, 0}, {0x4837, 0x2c, 0, 0}, {0x3824, 0x01, 0, 0},
527 {0x5001, 0x83, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
528 {0x3036, 0x69, 0, 0}, {0x3037, 0x13, 0, 0},
531 static struct ov5640_mode_info ov5640_mode_info_data[2][ov5640_mode_MAX + 1] = {
533 {ov5640_mode_VGA_640_480, 640, 480,
534 ov5640_setting_15fps_VGA_640_480,
535 ARRAY_SIZE(ov5640_setting_15fps_VGA_640_480)},
536 {ov5640_mode_QVGA_320_240, 320, 240,
537 ov5640_setting_15fps_QVGA_320_240,
538 ARRAY_SIZE(ov5640_setting_15fps_QVGA_320_240)},
539 {ov5640_mode_NTSC_720_480, 720, 480,
540 ov5640_setting_15fps_NTSC_720_480,
541 ARRAY_SIZE(ov5640_setting_15fps_NTSC_720_480)},
542 {ov5640_mode_PAL_720_576, 720, 576,
543 ov5640_setting_15fps_PAL_720_576,
544 ARRAY_SIZE(ov5640_setting_15fps_PAL_720_576)},
545 {ov5640_mode_720P_1280_720, 1280, 720,
546 ov5640_setting_15fps_720P_1280_720,
547 ARRAY_SIZE(ov5640_setting_15fps_720P_1280_720)},
548 {ov5640_mode_1080P_1920_1080, 1920, 1080,
549 ov5640_setting_15fps_1080P_1920_1080,
550 ARRAY_SIZE(ov5640_setting_15fps_1080P_1920_1080)},
551 {ov5640_mode_QSXGA_2592_1944, 2592, 1944,
552 ov5640_setting_15fps_QSXGA_2592_1944,
553 ARRAY_SIZE(ov5640_setting_15fps_QSXGA_2592_1944)},
554 {ov5640_mode_QCIF_176_144, 176, 144,
555 ov5640_setting_15fps_QCIF_176_144,
556 ARRAY_SIZE(ov5640_setting_15fps_QCIF_176_144)},
557 {ov5640_mode_XGA_1024_768, 1024, 768,
558 ov5640_setting_15fps_XGA_1024_768,
559 ARRAY_SIZE(ov5640_setting_15fps_XGA_1024_768)},
562 {ov5640_mode_VGA_640_480, 640, 480,
563 ov5640_setting_30fps_VGA_640_480,
564 ARRAY_SIZE(ov5640_setting_30fps_VGA_640_480)},
565 {ov5640_mode_QVGA_320_240, 320, 240,
566 ov5640_setting_30fps_QVGA_320_240,
567 ARRAY_SIZE(ov5640_setting_30fps_QVGA_320_240)},
568 {ov5640_mode_NTSC_720_480, 720, 480,
569 ov5640_setting_30fps_NTSC_720_480,
570 ARRAY_SIZE(ov5640_setting_30fps_NTSC_720_480)},
571 {ov5640_mode_PAL_720_576, 720, 576,
572 ov5640_setting_30fps_PAL_720_576,
573 ARRAY_SIZE(ov5640_setting_30fps_PAL_720_576)},
574 {ov5640_mode_720P_1280_720, 1280, 720,
575 ov5640_setting_30fps_720P_1280_720,
576 ARRAY_SIZE(ov5640_setting_30fps_720P_1280_720)},
577 {ov5640_mode_1080P_1920_1080, 0, 0, NULL, 0},
578 {ov5640_mode_QSXGA_2592_1944, 0, 0, NULL, 0},
579 {ov5640_mode_QCIF_176_144, 176, 144,
580 ov5640_setting_30fps_QCIF_176_144,
581 ARRAY_SIZE(ov5640_setting_30fps_QCIF_176_144)},
582 {ov5640_mode_XGA_1024_768, 1024, 768,
583 ov5640_setting_30fps_XGA_1024_768,
584 ARRAY_SIZE(ov5640_setting_30fps_XGA_1024_768)},
588 static struct regulator *io_regulator;
589 static struct regulator *core_regulator;
590 static struct regulator *analog_regulator;
592 static int ov5640_probe(struct i2c_client *adapter,
593 const struct i2c_device_id *device_id);
594 static int ov5640_remove(struct i2c_client *client);
596 static s32 ov5640_read_reg(u16 reg, u8 *val);
597 static s32 ov5640_write_reg(u16 reg, u8 val);
599 static const struct i2c_device_id ov5640_id[] = {
605 MODULE_DEVICE_TABLE(i2c, ov5640_id);
607 static struct i2c_driver ov5640_i2c_driver = {
609 .owner = THIS_MODULE,
612 .probe = ov5640_probe,
613 .remove = ov5640_remove,
614 .id_table = ov5640_id,
617 static const struct ov5640_datafmt ov5640_colour_fmts[] = {
618 {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG},
621 static struct ov5640 *to_ov5640(const struct i2c_client *client)
623 return container_of(i2c_get_clientdata(client), struct ov5640, subdev);
626 /* Find a data format by a pixel code in an array */
627 static const struct ov5640_datafmt
628 *ov5640_find_datafmt(enum v4l2_mbus_pixelcode code)
632 for (i = 0; i < ARRAY_SIZE(ov5640_colour_fmts); i++)
633 if (ov5640_colour_fmts[i].code == code)
634 return ov5640_colour_fmts + i;
639 static inline void ov5640_power_down(int enable)
641 gpio_set_value(pwn_gpio, enable);
646 static inline void ov5640_reset(void)
649 gpio_set_value(rst_gpio, 1);
651 /* camera power down */
652 gpio_set_value(pwn_gpio, 1);
654 gpio_set_value(pwn_gpio, 0);
656 gpio_set_value(rst_gpio, 0);
658 gpio_set_value(rst_gpio, 1);
660 gpio_set_value(pwn_gpio, 1);
663 static int ov5640_regulator_enable(struct device *dev)
667 io_regulator = devm_regulator_get(dev, "DOVDD");
668 if (!IS_ERR(io_regulator)) {
669 regulator_set_voltage(io_regulator,
670 OV5640_VOLTAGE_DIGITAL_IO,
671 OV5640_VOLTAGE_DIGITAL_IO);
672 ret = regulator_enable(io_regulator);
674 dev_err(dev, "set io voltage failed\n");
677 dev_dbg(dev, "set io voltage ok\n");
681 dev_warn(dev, "cannot get io voltage\n");
684 core_regulator = devm_regulator_get(dev, "DVDD");
685 if (!IS_ERR(core_regulator)) {
686 regulator_set_voltage(core_regulator,
687 OV5640_VOLTAGE_DIGITAL_CORE,
688 OV5640_VOLTAGE_DIGITAL_CORE);
689 ret = regulator_enable(core_regulator);
691 dev_err(dev, "set core voltage failed\n");
694 dev_dbg(dev, "set core voltage ok\n");
697 core_regulator = NULL;
698 dev_warn(dev, "cannot get core voltage\n");
701 analog_regulator = devm_regulator_get(dev, "AVDD");
702 if (!IS_ERR(analog_regulator)) {
703 regulator_set_voltage(analog_regulator,
704 OV5640_VOLTAGE_ANALOG,
705 OV5640_VOLTAGE_ANALOG);
706 ret = regulator_enable(analog_regulator);
708 dev_err(dev, "set analog voltage failed\n");
711 dev_dbg(dev, "set analog voltage ok\n");
714 analog_regulator = NULL;
715 dev_warn(dev, "cannot get analog voltage\n");
721 static s32 ov5640_write_reg(u16 reg, u8 val)
725 au8Buf[0] = reg >> 8;
726 au8Buf[1] = reg & 0xff;
729 if (i2c_master_send(ov5640_data.i2c_client, au8Buf, 3) < 0) {
730 pr_err("%s:write reg error:reg=%x,val=%x\n",
738 static s32 ov5640_read_reg(u16 reg, u8 *val)
740 u8 au8RegBuf[2] = {0};
743 au8RegBuf[0] = reg >> 8;
744 au8RegBuf[1] = reg & 0xff;
746 if (2 != i2c_master_send(ov5640_data.i2c_client, au8RegBuf, 2)) {
747 pr_err("%s:write reg error:reg=%x\n",
752 if (1 != i2c_master_recv(ov5640_data.i2c_client, &u8RdVal, 1)) {
753 pr_err("%s:read reg error:reg=%x,val=%x\n",
754 __func__, reg, u8RdVal);
763 #ifdef CONFIG_VIDEO_ADV_DEBUG
764 static int ov5640_get_register(struct v4l2_subdev *sd,
765 struct v4l2_dbg_register *reg)
767 struct i2c_client *client = v4l2_get_subdevdata(sd);
771 if (reg->reg & ~0xffff)
776 ret = ov5640_read_reg(reg->reg, &val);
778 reg->val = (__u64)val;
783 static int ov5640_set_register(struct v4l2_subdev *sd,
784 const struct v4l2_dbg_register *reg)
786 struct i2c_client *client = v4l2_get_subdevdata(sd);
788 if (reg->reg & ~0xffff || reg->val & ~0xff)
791 return ov5640_write_reg(reg->reg, reg->val);
795 static void ov5640_soft_reset(void)
797 /* sysclk from pad */
798 ov5640_write_reg(0x3103, 0x11);
801 ov5640_write_reg(0x3008, 0x82);
803 /* delay at least 5ms */
807 /* set sensor driver capability
808 * 0x302c[7:6] - strength
814 static int ov5640_driver_capability(int strength)
818 if (strength > 4 || strength < 1) {
819 pr_err("The valid driver capability of ov5640 is 1x~4x\n");
823 ov5640_read_reg(0x302c, &temp);
825 temp &= ~0xc0; /* clear [7:6] */
826 temp |= ((strength - 1) << 6); /* set [7:6] */
828 ov5640_write_reg(0x302c, temp);
833 /* calculate sysclk */
834 static int ov5640_get_sysclk(void)
836 int xvclk = ov5640_data.mclk / 10000;
839 int Multiplier, PreDiv, VCO, SysDiv, Pll_rdiv, Bit_div2x, sclk_rdiv;
840 int sclk_rdiv_map[] = {1, 2, 4, 8};
843 temp1 = ov5640_read_reg(0x3034, ®val);
844 temp2 = temp1 & 0x0f;
845 if (temp2 == 8 || temp2 == 10) {
846 Bit_div2x = temp2 / 2;
848 pr_err("ov5640: unsupported bit mode %d\n", temp2);
852 temp1 = ov5640_read_reg(0x3035, ®val);
857 temp1 = ov5640_read_reg(0x3036, ®val);
859 temp1 = ov5640_read_reg(0x3037, ®val);
860 PreDiv = temp1 & 0x0f;
861 Pll_rdiv = ((temp1 >> 4) & 0x01) + 1;
863 temp1 = ov5640_read_reg(0x3108, ®val);
864 temp2 = temp1 & 0x03;
866 sclk_rdiv = sclk_rdiv_map[temp2];
867 VCO = xvclk * Multiplier / PreDiv;
868 sysclk = VCO / SysDiv / Pll_rdiv * 2 / Bit_div2x / sclk_rdiv;
873 /* read HTS from register settings */
874 static int ov5640_get_HTS(void)
879 HTS = ov5640_read_reg(0x380c, &temp);
880 HTS = (HTS<<8) + ov5640_read_reg(0x380d, &temp);
884 /* read VTS from register settings */
885 static int ov5640_get_VTS(void)
890 VTS = ov5640_read_reg(0x380e, &temp);
891 VTS = (VTS<<8) + ov5640_read_reg(0x380f, &temp);
896 /* write VTS to registers */
897 static int ov5640_set_VTS(int VTS)
902 ov5640_write_reg(0x380f, temp);
905 ov5640_write_reg(0x380e, temp);
909 /* read shutter, in number of line period */
910 static int ov5640_get_shutter(void)
915 shutter = (ov5640_read_reg(0x03500, ®val) & 0x0f);
917 shutter = (shutter<<8) + ov5640_read_reg(0x3501, ®val);
918 shutter = (shutter<<4) + (ov5640_read_reg(0x3502, ®val)>>4);
923 /* write shutter, in number of line period */
924 static int ov5640_set_shutter(int shutter)
928 shutter = shutter & 0xffff;
929 temp = shutter & 0x0f;
931 ov5640_write_reg(0x3502, temp);
933 temp = shutter & 0xfff;
935 ov5640_write_reg(0x3501, temp);
938 ov5640_write_reg(0x3500, temp);
943 /* read gain, 16 = 1x */
944 static int ov5640_get_gain16(void)
949 gain16 = ov5640_read_reg(0x350a, ®val) & 0x03;
950 gain16 = (gain16<<8) + ov5640_read_reg(0x350b, ®val);
955 /* write gain, 16 = 1x */
956 static int ov5640_set_gain16(int gain16)
960 gain16 = gain16 & 0x3ff;
961 temp = gain16 & 0xff;
963 ov5640_write_reg(0x350b, temp);
966 ov5640_write_reg(0x350a, temp);
970 /* get banding filter value */
971 static int ov5640_get_light_freq(void)
973 int temp, temp1, light_frequency;
976 temp = ov5640_read_reg(0x3c01, ®val);
979 temp1 = ov5640_read_reg(0x3c00, ®val);
982 light_frequency = 50;
985 light_frequency = 60;
989 temp1 = ov5640_read_reg(0x3c0c, ®val);
992 light_frequency = 50;
995 light_frequency = 60;
999 return light_frequency;
1002 static void ov5640_set_bandingfilter(void)
1005 int band_step60, max_band60, band_step50, max_band50;
1007 /* read preview PCLK */
1008 prev_sysclk = ov5640_get_sysclk();
1010 /* read preview HTS */
1011 prev_HTS = ov5640_get_HTS();
1013 /* read preview VTS */
1014 prev_VTS = ov5640_get_VTS();
1016 /* calculate banding filter */
1018 band_step60 = prev_sysclk * 100/prev_HTS * 100/120;
1019 ov5640_write_reg(0x3a0a, (band_step60 >> 8));
1020 ov5640_write_reg(0x3a0b, (band_step60 & 0xff));
1022 max_band60 = (int)((prev_VTS-4)/band_step60);
1023 ov5640_write_reg(0x3a0d, max_band60);
1026 band_step50 = prev_sysclk * 100/prev_HTS;
1027 ov5640_write_reg(0x3a08, (band_step50 >> 8));
1028 ov5640_write_reg(0x3a09, (band_step50 & 0xff));
1030 max_band50 = (int)((prev_VTS-4)/band_step50);
1031 ov5640_write_reg(0x3a0e, max_band50);
1034 /* stable in high */
1035 static int ov5640_set_AE_target(int target)
1037 int fast_high, fast_low;
1039 AE_low = target * 23 / 25; /* 0.92 */
1040 AE_high = target * 27 / 25; /* 1.08 */
1041 fast_high = AE_high << 1;
1043 if (fast_high > 255)
1045 fast_low = AE_low >> 1;
1047 ov5640_write_reg(0x3a0f, AE_high);
1048 ov5640_write_reg(0x3a10, AE_low);
1049 ov5640_write_reg(0x3a1b, AE_high);
1050 ov5640_write_reg(0x3a1e, AE_low);
1051 ov5640_write_reg(0x3a11, fast_high);
1052 ov5640_write_reg(0x3a1f, fast_low);
1057 /* enable = 0 to turn off night mode
1058 enable = 1 to turn on night mode */
1059 static int ov5640_set_night_mode(int enable)
1063 ov5640_read_reg(0x3a00, &mode);
1068 ov5640_write_reg(0x3a00, mode);
1070 /* night mode off */
1072 ov5640_write_reg(0x3a00, mode);
1078 /* enable = 0 to turn off AEC/AGC
1079 enable = 1 to turn on AEC/AGC */
1080 void ov5640_turn_on_AE_AG(int enable)
1084 ov5640_read_reg(0x3503, &ae_ag_ctrl);
1086 /* turn on auto AE/AG */
1087 ae_ag_ctrl = ae_ag_ctrl & ~(0x03);
1089 /* turn off AE/AG */
1090 ae_ag_ctrl = ae_ag_ctrl | 0x03;
1092 ov5640_write_reg(0x3503, ae_ag_ctrl);
1095 /* download ov5640 settings to sensor through i2c */
1096 static int ov5640_download_firmware(struct reg_value *pModeSetting, s32 ArySize)
1098 register u32 Delay_ms = 0;
1099 register u16 RegAddr = 0;
1100 register u8 Mask = 0;
1101 register u8 Val = 0;
1105 for (i = 0; i < ArySize; ++i, ++pModeSetting) {
1106 Delay_ms = pModeSetting->u32Delay_ms;
1107 RegAddr = pModeSetting->u16RegAddr;
1108 Val = pModeSetting->u8Val;
1109 Mask = pModeSetting->u8Mask;
1112 retval = ov5640_read_reg(RegAddr, &RegVal);
1116 RegVal &= ~(u8)Mask;
1121 retval = ov5640_write_reg(RegAddr, Val);
1132 static int ov5640_init_mode(void)
1134 struct reg_value *pModeSetting = NULL;
1135 int ArySize = 0, retval = 0;
1137 ov5640_soft_reset();
1139 pModeSetting = ov5640_global_init_setting;
1140 ArySize = ARRAY_SIZE(ov5640_global_init_setting);
1141 retval = ov5640_download_firmware(pModeSetting, ArySize);
1145 pModeSetting = ov5640_init_setting_30fps_VGA;
1146 ArySize = ARRAY_SIZE(ov5640_init_setting_30fps_VGA);
1147 retval = ov5640_download_firmware(pModeSetting, ArySize);
1151 /* change driver capability to 2x according to validation board.
1152 * if the image is not stable, please increase the driver strength.
1154 ov5640_driver_capability(2);
1155 ov5640_set_bandingfilter();
1156 ov5640_set_AE_target(AE_Target);
1157 ov5640_set_night_mode(night_mode);
1159 /* skip 9 vysnc: start capture at 10th vsync */
1162 /* turn off night mode */
1164 ov5640_data.pix.width = 640;
1165 ov5640_data.pix.height = 480;
1170 /* change to or back to subsampling mode set the mode directly
1171 * image size below 1280 * 960 is subsampling mode */
1172 static int ov5640_change_mode_direct(enum ov5640_frame_rate frame_rate,
1173 enum ov5640_mode mode)
1175 struct reg_value *pModeSetting = NULL;
1179 if (mode > ov5640_mode_MAX || mode < ov5640_mode_MIN) {
1180 pr_err("Wrong ov5640 mode detected!\n");
1184 pModeSetting = ov5640_mode_info_data[frame_rate][mode].init_data_ptr;
1186 ov5640_mode_info_data[frame_rate][mode].init_data_size;
1188 ov5640_data.pix.width = ov5640_mode_info_data[frame_rate][mode].width;
1189 ov5640_data.pix.height = ov5640_mode_info_data[frame_rate][mode].height;
1191 if (ov5640_data.pix.width == 0 || ov5640_data.pix.height == 0 ||
1192 pModeSetting == NULL || ArySize == 0)
1195 /* set ov5640 to subsampling mode */
1196 retval = ov5640_download_firmware(pModeSetting, ArySize);
1198 /* turn on AE AG for subsampling mode, in case the firmware didn't */
1199 ov5640_turn_on_AE_AG(1);
1201 /* calculate banding filter */
1202 ov5640_set_bandingfilter();
1205 ov5640_set_AE_target(AE_Target);
1207 /* update night mode setting */
1208 ov5640_set_night_mode(night_mode);
1210 /* skip 9 vysnc: start capture at 10th vsync */
1211 if (mode == ov5640_mode_XGA_1024_768 && frame_rate == ov5640_30_fps) {
1212 pr_warning("ov5640: actual frame rate of XGA is 22.5fps\n");
1218 if (frame_rate == ov5640_15_fps) {
1221 } else if (frame_rate == ov5640_30_fps) {
1229 /* change to scaling mode go through exposure calucation
1230 * image size above 1280 * 960 is scaling mode */
1231 static int ov5640_change_mode_exposure_calc(enum ov5640_frame_rate frame_rate,
1232 enum ov5640_mode mode)
1234 int prev_shutter, prev_gain16, average;
1235 int cap_shutter, cap_gain16;
1236 int cap_sysclk, cap_HTS, cap_VTS;
1237 int light_freq, cap_bandfilt, cap_maxband;
1238 long cap_gain16_shutter;
1240 struct reg_value *pModeSetting = NULL;
1244 /* check if the input mode and frame rate is valid */
1246 ov5640_mode_info_data[frame_rate][mode].init_data_ptr;
1248 ov5640_mode_info_data[frame_rate][mode].init_data_size;
1250 ov5640_data.pix.width =
1251 ov5640_mode_info_data[frame_rate][mode].width;
1252 ov5640_data.pix.height =
1253 ov5640_mode_info_data[frame_rate][mode].height;
1255 if (ov5640_data.pix.width == 0 || ov5640_data.pix.height == 0 ||
1256 pModeSetting == NULL || ArySize == 0)
1259 /* read preview shutter */
1260 prev_shutter = ov5640_get_shutter();
1262 /* read preview gain */
1263 prev_gain16 = ov5640_get_gain16();
1266 average = ov5640_read_reg(0x56a1, &temp);
1268 /* turn off night mode for capture */
1269 ov5640_set_night_mode(0);
1271 /* turn off overlay */
1272 ov5640_write_reg(0x3022, 0x06);
1274 /* Write capture setting */
1275 retval = ov5640_download_firmware(pModeSetting, ArySize);
1279 /* turn off AE AG when capture image. */
1280 ov5640_turn_on_AE_AG(0);
1282 /* read capture VTS */
1283 cap_VTS = ov5640_get_VTS();
1284 cap_HTS = ov5640_get_HTS();
1285 cap_sysclk = ov5640_get_sysclk();
1287 /* calculate capture banding filter */
1288 light_freq = ov5640_get_light_freq();
1289 if (light_freq == 60) {
1291 cap_bandfilt = cap_sysclk * 100 / cap_HTS * 100 / 120;
1294 cap_bandfilt = cap_sysclk * 100 / cap_HTS;
1296 cap_maxband = (int)((cap_VTS - 4)/cap_bandfilt);
1297 /* calculate capture shutter/gain16 */
1298 if (average > AE_low && average < AE_high) {
1299 /* in stable range */
1300 cap_gain16_shutter =
1301 prev_gain16 * prev_shutter * cap_sysclk/prev_sysclk *
1302 prev_HTS/cap_HTS * AE_Target / average;
1304 cap_gain16_shutter =
1305 prev_gain16 * prev_shutter * cap_sysclk/prev_sysclk *
1309 /* gain to shutter */
1310 if (cap_gain16_shutter < (cap_bandfilt * 16)) {
1311 /* shutter < 1/100 */
1312 cap_shutter = cap_gain16_shutter/16;
1313 if (cap_shutter < 1)
1315 cap_gain16 = cap_gain16_shutter/cap_shutter;
1316 if (cap_gain16 < 16)
1319 if (cap_gain16_shutter > (cap_bandfilt*cap_maxband*16)) {
1320 /* exposure reach max */
1321 cap_shutter = cap_bandfilt*cap_maxband;
1322 cap_gain16 = cap_gain16_shutter / cap_shutter;
1324 /* 1/100 < cap_shutter =< max, cap_shutter = n/100 */
1326 ((int)(cap_gain16_shutter/16/cap_bandfilt))
1328 cap_gain16 = cap_gain16_shutter / cap_shutter;
1332 /* write capture gain */
1333 ov5640_set_gain16(cap_gain16);
1335 /* write capture shutter */
1336 if (cap_shutter > (cap_VTS - 4)) {
1337 cap_VTS = cap_shutter + 4;
1338 ov5640_set_VTS(cap_VTS);
1341 ov5640_set_shutter(cap_shutter);
1343 /* skip 2 vysnc: start capture at 3rd vsync
1344 * frame rate of QSXGA and 1080P is 7.5fps: 1/7.5 * 2
1346 pr_warning("ov5640: the actual frame rate of %s is 7.5fps\n",
1347 mode == ov5640_mode_1080P_1920_1080 ? "1080P" : "QSXGA");
1353 static int ov5640_change_mode(enum ov5640_frame_rate frame_rate,
1354 enum ov5640_mode mode)
1358 if (mode > ov5640_mode_MAX || mode < ov5640_mode_MIN) {
1359 pr_err("Wrong ov5640 mode detected!\n");
1363 if (mode == ov5640_mode_1080P_1920_1080 ||
1364 mode == ov5640_mode_QSXGA_2592_1944) {
1365 /* change to scaling mode go through exposure calucation
1366 * image size above 1280 * 960 is scaling mode */
1367 retval = ov5640_change_mode_exposure_calc(frame_rate, mode);
1369 /* change back to subsampling modem download firmware directly
1370 * image size below 1280 * 960 is subsampling mode */
1371 retval = ov5640_change_mode_direct(frame_rate, mode);
1378 * ov5640_s_power - V4L2 sensor interface handler for VIDIOC_S_POWER ioctl
1379 * @s: pointer to standard V4L2 device structure
1380 * @on: indicates power mode (on or off)
1382 * Turns the power on or off, depending on the value of on and returns the
1383 * appropriate error code.
1385 static int ov5640_s_power(struct v4l2_subdev *sd, int on)
1387 struct i2c_client *client = v4l2_get_subdevdata(sd);
1388 struct ov5640 *sensor = to_ov5640(client);
1391 clk_enable(ov5640_data.sensor_clk);
1393 clk_disable(ov5640_data.sensor_clk);
1395 if (on && !sensor->on) {
1397 if (regulator_enable(io_regulator) != 0)
1400 if (regulator_enable(core_regulator) != 0)
1402 if (analog_regulator)
1403 if (regulator_enable(analog_regulator) != 0)
1405 /* Make sure power on */
1406 ov5640_power_down(0);
1407 } else if (!on && sensor->on) {
1408 if (analog_regulator)
1409 regulator_disable(analog_regulator);
1411 regulator_disable(core_regulator);
1413 regulator_disable(io_regulator);
1415 ov5640_power_down(1);
1423 static int ov5640_s_stream(struct v4l2_subdev *sd, int enable)
1426 clk_enable(ov5640_data.sensor_clk);
1427 ov5640_power_down(0);
1429 ov5640_power_down(1);
1430 clk_disable(ov5640_data.sensor_clk);
1436 * ov5640_g_parm - V4L2 sensor interface handler for VIDIOC_G_PARM ioctl
1437 * @s: pointer to standard V4L2 sub device structure
1438 * @a: pointer to standard V4L2 VIDIOC_G_PARM ioctl structure
1440 * Returns the sensor's video CAPTURE parameters.
1442 static int ov5640_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *a)
1444 struct i2c_client *client = v4l2_get_subdevdata(sd);
1445 struct ov5640 *sensor = to_ov5640(client);
1446 struct v4l2_captureparm *cparm = &a->parm.capture;
1450 /* This is the only case currently handled. */
1451 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1452 memset(a, 0, sizeof(*a));
1453 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1454 cparm->capability = sensor->streamcap.capability;
1455 cparm->timeperframe = sensor->streamcap.timeperframe;
1456 cparm->capturemode = sensor->streamcap.capturemode;
1460 /* These are all the possible cases. */
1461 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
1462 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1463 case V4L2_BUF_TYPE_VBI_CAPTURE:
1464 case V4L2_BUF_TYPE_VBI_OUTPUT:
1465 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
1466 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
1471 pr_debug(" type is unknown - %d\n", a->type);
1480 * ov5460_s_parm - V4L2 sensor interface handler for VIDIOC_S_PARM ioctl
1481 * @s: pointer to standard V4L2 sub device structure
1482 * @a: pointer to standard V4L2 VIDIOC_S_PARM ioctl structure
1484 * Configures the sensor to use the input parameters, if possible. If
1485 * not possible, reverts to the old parameters and returns the
1486 * appropriate error code.
1488 static int ov5640_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *a)
1490 struct i2c_client *client = v4l2_get_subdevdata(sd);
1491 struct ov5640 *sensor = to_ov5640(client);
1492 struct v4l2_fract *timeperframe = &a->parm.capture.timeperframe;
1493 u32 tgt_fps; /* target frames per secound */
1494 enum ov5640_frame_rate frame_rate;
1497 /* Make sure power on */
1498 clk_enable(ov5640_data.sensor_clk);
1499 ov5640_power_down(0);
1502 /* This is the only case currently handled. */
1503 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1504 /* Check that the new frame rate is allowed. */
1505 if ((timeperframe->numerator == 0) ||
1506 (timeperframe->denominator == 0)) {
1507 timeperframe->denominator = DEFAULT_FPS;
1508 timeperframe->numerator = 1;
1511 tgt_fps = timeperframe->denominator /
1512 timeperframe->numerator;
1514 if (tgt_fps > MAX_FPS) {
1515 timeperframe->denominator = MAX_FPS;
1516 timeperframe->numerator = 1;
1517 } else if (tgt_fps < MIN_FPS) {
1518 timeperframe->denominator = MIN_FPS;
1519 timeperframe->numerator = 1;
1522 /* Actual frame rate we use */
1523 tgt_fps = timeperframe->denominator /
1524 timeperframe->numerator;
1527 frame_rate = ov5640_15_fps;
1528 else if (tgt_fps == 30)
1529 frame_rate = ov5640_30_fps;
1531 pr_err(" The camera frame rate is not supported!\n");
1535 ret = ov5640_change_mode(frame_rate,
1536 a->parm.capture.capturemode);
1540 sensor->streamcap.timeperframe = *timeperframe;
1541 sensor->streamcap.capturemode = a->parm.capture.capturemode;
1545 /* These are all the possible cases. */
1546 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
1547 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1548 case V4L2_BUF_TYPE_VBI_CAPTURE:
1549 case V4L2_BUF_TYPE_VBI_OUTPUT:
1550 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
1551 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
1552 pr_debug(" type is not " \
1553 "V4L2_BUF_TYPE_VIDEO_CAPTURE but %d\n",
1559 pr_debug(" type is unknown - %d\n", a->type);
1565 ov5640_power_down(1);
1566 clk_disable(ov5640_data.sensor_clk);
1570 static int ov5640_try_fmt(struct v4l2_subdev *sd,
1571 struct v4l2_mbus_framefmt *mf)
1573 const struct ov5640_datafmt *fmt = ov5640_find_datafmt(mf->code);
1576 mf->code = ov5640_colour_fmts[0].code;
1577 mf->colorspace = ov5640_colour_fmts[0].colorspace;
1580 mf->field = V4L2_FIELD_NONE;
1585 static int ov5640_s_fmt(struct v4l2_subdev *sd,
1586 struct v4l2_mbus_framefmt *mf)
1588 struct i2c_client *client = v4l2_get_subdevdata(sd);
1589 struct ov5640 *sensor = to_ov5640(client);
1591 /* MIPI CSI could have changed the format, double-check */
1592 if (!ov5640_find_datafmt(mf->code))
1595 ov5640_try_fmt(sd, mf);
1596 sensor->fmt = ov5640_find_datafmt(mf->code);
1601 static int ov5640_g_fmt(struct v4l2_subdev *sd,
1602 struct v4l2_mbus_framefmt *mf)
1604 struct i2c_client *client = v4l2_get_subdevdata(sd);
1605 struct ov5640 *sensor = to_ov5640(client);
1607 const struct ov5640_datafmt *fmt = sensor->fmt;
1609 mf->code = fmt->code;
1610 mf->colorspace = fmt->colorspace;
1611 mf->field = V4L2_FIELD_NONE;
1616 static int ov5640_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
1617 enum v4l2_mbus_pixelcode *code)
1619 if (index >= ARRAY_SIZE(ov5640_colour_fmts))
1622 *code = ov5640_colour_fmts[index].code;
1627 * ov5640_enum_framesizes - V4L2 sensor interface handler for
1628 * VIDIOC_ENUM_FRAMESIZES ioctl
1629 * @s: pointer to standard V4L2 device structure
1630 * @fsize: standard V4L2 VIDIOC_ENUM_FRAMESIZES ioctl structure
1632 * Return 0 if successful, otherwise -EINVAL.
1634 static int ov5640_enum_framesizes(struct v4l2_subdev *sd,
1635 struct v4l2_frmsizeenum *fsize)
1637 if (fsize->index > ov5640_mode_MAX)
1640 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
1641 fsize->discrete.width =
1642 max(ov5640_mode_info_data[0][fsize->index].width,
1643 ov5640_mode_info_data[1][fsize->index].width);
1644 fsize->discrete.height =
1645 max(ov5640_mode_info_data[0][fsize->index].height,
1646 ov5640_mode_info_data[1][fsize->index].height);
1651 * ov5640_enum_frameintervals - V4L2 sensor interface handler for
1652 * VIDIOC_ENUM_FRAMEINTERVALS ioctl
1653 * @s: pointer to standard V4L2 device structure
1654 * @fival: standard V4L2 VIDIOC_ENUM_FRAMEINTERVALS ioctl structure
1656 * Return 0 if successful, otherwise -EINVAL.
1658 static int ov5640_enum_frameintervals(struct v4l2_subdev *sd,
1659 struct v4l2_frmivalenum *fival)
1663 if (fival->index < 0 || fival->index > ov5640_mode_MAX)
1666 if (fival->width == 0 || fival->height == 0 ||
1667 fival->pixel_format == 0) {
1668 pr_warning("Please assign pixelformat, width and height.\n");
1672 fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
1673 fival->discrete.numerator = 1;
1676 for (i = 0; i < ARRAY_SIZE(ov5640_mode_info_data); i++) {
1677 for (j = 0; j < (ov5640_mode_MAX + 1); j++) {
1678 if (fival->pixel_format == ov5640_data.pix.pixelformat
1679 && fival->width == ov5640_mode_info_data[i][j].width
1680 && fival->height == ov5640_mode_info_data[i][j].height
1681 && ov5640_mode_info_data[i][j].init_data_ptr != NULL) {
1684 if (fival->index == (count - 1)) {
1685 fival->discrete.denominator =
1686 ov5640_framerates[i];
1696 * dev_init - V4L2 sensor init
1697 * @s: pointer to standard V4L2 device structure
1700 static int init_device(void)
1702 u32 tgt_xclk; /* target xclk */
1703 u32 tgt_fps; /* target frames per secound */
1704 enum ov5640_frame_rate frame_rate;
1707 ov5640_data.on = true;
1710 tgt_xclk = ov5640_data.mclk;
1711 tgt_xclk = min(tgt_xclk, (u32)OV5640_XCLK_MAX);
1712 tgt_xclk = max(tgt_xclk, (u32)OV5640_XCLK_MIN);
1713 ov5640_data.mclk = tgt_xclk;
1715 pr_debug(" Setting mclk to %d MHz\n", tgt_xclk / 1000000);
1716 clk_set_rate(ov5640_data.sensor_clk, ov5640_data.mclk);
1718 /* Default camera frame rate is set in probe */
1719 tgt_fps = ov5640_data.streamcap.timeperframe.denominator /
1720 ov5640_data.streamcap.timeperframe.numerator;
1723 frame_rate = ov5640_15_fps;
1724 else if (tgt_fps == 30)
1725 frame_rate = ov5640_30_fps;
1727 return -EINVAL; /* Only support 15fps or 30fps now. */
1729 ret = ov5640_init_mode();
1734 static struct v4l2_subdev_video_ops ov5640_subdev_video_ops = {
1735 .s_stream = ov5640_s_stream,
1736 .g_parm = ov5640_g_parm,
1737 .s_parm = ov5640_s_parm,
1739 .s_mbus_fmt = ov5640_s_fmt,
1740 .g_mbus_fmt = ov5640_g_fmt,
1741 .try_mbus_fmt = ov5640_try_fmt,
1742 .enum_mbus_fmt = ov5640_enum_fmt,
1743 .enum_framesizes = ov5640_enum_framesizes,
1744 .enum_frameintervals = ov5640_enum_frameintervals,
1747 static struct v4l2_subdev_core_ops ov5640_subdev_core_ops = {
1748 .s_power = ov5640_s_power,
1749 #ifdef CONFIG_VIDEO_ADV_DEBUG
1750 .g_register = ov5640_get_register,
1751 .s_register = ov5640_set_register,
1755 static struct v4l2_subdev_ops ov5640_subdev_ops = {
1756 .core = &ov5640_subdev_core_ops,
1757 .video = &ov5640_subdev_video_ops,
1761 * ov5640 I2C probe function
1763 * @param adapter struct i2c_adapter *
1764 * @return Error code indicating success or failure
1766 static int ov5640_probe(struct i2c_client *client,
1767 const struct i2c_device_id *id)
1769 struct pinctrl *pinctrl;
1770 struct device *dev = &client->dev;
1772 u8 chip_id_high, chip_id_low;
1774 /* ov5640 pinctrl */
1775 pinctrl = devm_pinctrl_get_select_default(dev);
1776 if (IS_ERR(pinctrl)) {
1777 dev_err(dev, "setup pinctrl failed\n");
1778 return PTR_ERR(pinctrl);
1781 /* request power down pin */
1782 pwn_gpio = of_get_named_gpio(dev->of_node, "pwn-gpios", 0);
1783 if (!gpio_is_valid(pwn_gpio)) {
1784 dev_err(dev, "no sensor pwdn pin available\n");
1787 retval = devm_gpio_request_one(dev, pwn_gpio, GPIOF_OUT_INIT_HIGH,
1792 /* request reset pin */
1793 rst_gpio = of_get_named_gpio(dev->of_node, "rst-gpios", 0);
1794 if (!gpio_is_valid(rst_gpio)) {
1795 dev_err(dev, "no sensor reset pin available\n");
1798 retval = devm_gpio_request_one(dev, rst_gpio, GPIOF_OUT_INIT_HIGH,
1803 /* Set initial values for the sensor struct. */
1804 memset(&ov5640_data, 0, sizeof(ov5640_data));
1805 ov5640_data.sensor_clk = devm_clk_get(dev, "csi_mclk");
1806 if (IS_ERR(ov5640_data.sensor_clk)) {
1807 dev_err(dev, "get mclk failed\n");
1808 return PTR_ERR(ov5640_data.sensor_clk);
1811 retval = of_property_read_u32(dev->of_node, "mclk",
1814 dev_err(dev, "mclk frequency is invalid\n");
1818 retval = of_property_read_u32(dev->of_node, "mclk_source",
1819 (u32 *) &(ov5640_data.mclk_source));
1821 dev_err(dev, "mclk_source invalid\n");
1825 retval = of_property_read_u32(dev->of_node, "csi_id",
1826 &(ov5640_data.csi));
1828 dev_err(dev, "csi_id invalid\n");
1832 v4l2_i2c_subdev_init(&ov5640_data.subdev, client, &ov5640_subdev_ops);
1834 retval = v4l2_async_register_subdev(&ov5640_data.subdev);
1836 dev_err(&client->dev,
1837 "%s--Async register faialed, ret=%d\n", __func__, retval);
1839 clk_prepare_enable(ov5640_data.sensor_clk);
1841 ov5640_data.io_init = ov5640_reset;
1842 ov5640_data.i2c_client = client;
1843 ov5640_data.pix.pixelformat = V4L2_PIX_FMT_YUYV;
1844 ov5640_data.pix.width = 640;
1845 ov5640_data.pix.height = 480;
1846 ov5640_data.streamcap.capability = V4L2_MODE_HIGHQUALITY |
1847 V4L2_CAP_TIMEPERFRAME;
1848 ov5640_data.streamcap.capturemode = 0;
1849 ov5640_data.streamcap.timeperframe.denominator = DEFAULT_FPS;
1850 ov5640_data.streamcap.timeperframe.numerator = 1;
1852 ov5640_regulator_enable(&client->dev);
1856 ov5640_power_down(0);
1858 retval = ov5640_read_reg(OV5640_CHIP_ID_HIGH_BYTE, &chip_id_high);
1859 if (retval < 0 || chip_id_high != 0x56) {
1860 clk_disable_unprepare(ov5640_data.sensor_clk);
1861 pr_warning("camera ov5640 is not found\n");
1864 retval = ov5640_read_reg(OV5640_CHIP_ID_LOW_BYTE, &chip_id_low);
1865 if (retval < 0 || chip_id_low != 0x40) {
1866 clk_disable_unprepare(ov5640_data.sensor_clk);
1867 pr_warning("camera ov5640 is not found\n");
1871 retval = init_device();
1873 clk_disable_unprepare(ov5640_data.sensor_clk);
1874 pr_warning("camera ov5640 init failed\n");
1875 ov5640_power_down(1);
1879 ov5640_power_down(1);
1881 clk_disable(ov5640_data.sensor_clk);
1883 pr_info("camera ov5640, is found\n");
1888 * ov5640 I2C detach function
1890 * @param client struct i2c_client *
1891 * @return Error code indicating success or failure
1893 static int ov5640_remove(struct i2c_client *client)
1895 struct v4l2_subdev *sd = i2c_get_clientdata(client);
1897 v4l2_async_unregister_subdev(sd);
1899 clk_unprepare(ov5640_data.sensor_clk);
1901 if (analog_regulator)
1902 regulator_disable(analog_regulator);
1905 regulator_disable(core_regulator);
1908 regulator_disable(io_regulator);
1913 module_i2c_driver(ov5640_i2c_driver);
1915 MODULE_AUTHOR("Freescale Semiconductor, Inc.");
1916 MODULE_DESCRIPTION("OV5640 Camera Driver");
1917 MODULE_LICENSE("GPL");
1918 MODULE_VERSION("1.0");
1919 MODULE_ALIAS("CSI");