2 * Copyright (C) 2012-2015 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 <media/v4l2-chip-ident.h>
32 #include "v4l2-int-device.h"
33 #include "mxc_v4l2_capture.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[] = {
80 struct ov5640_mode_info {
81 enum ov5640_mode mode;
84 struct reg_value *init_data_ptr;
89 * Maintains the information on the current state of the sesor.
91 static struct sensor_data ov5640_data;
92 static int pwn_gpio, rst_gpio;
93 static int prev_sysclk;
94 static int AE_Target = 52, night_mode;
96 static int AE_high, AE_low;
98 static struct reg_value ov5640_global_init_setting[] = {
100 {0x3103, 0x03, 0, 0}, {0x3017, 0xff, 0, 0}, {0x3018, 0xff, 0, 0},
101 {0x3034, 0x1a, 0, 0}, {0x3037, 0x13, 0, 0}, {0x3108, 0x01, 0, 0},
102 {0x3630, 0x36, 0, 0}, {0x3631, 0x0e, 0, 0}, {0x3632, 0xe2, 0, 0},
103 {0x3633, 0x12, 0, 0}, {0x3621, 0xe0, 0, 0}, {0x3704, 0xa0, 0, 0},
104 {0x3703, 0x5a, 0, 0}, {0x3715, 0x78, 0, 0}, {0x3717, 0x01, 0, 0},
105 {0x370b, 0x60, 0, 0}, {0x3705, 0x1a, 0, 0}, {0x3905, 0x02, 0, 0},
106 {0x3906, 0x10, 0, 0}, {0x3901, 0x0a, 0, 0}, {0x3731, 0x12, 0, 0},
107 {0x3600, 0x08, 0, 0}, {0x3601, 0x33, 0, 0}, {0x302d, 0x60, 0, 0},
108 {0x3620, 0x52, 0, 0}, {0x371b, 0x20, 0, 0}, {0x471c, 0x50, 0, 0},
109 {0x3a13, 0x43, 0, 0}, {0x3a18, 0x00, 0, 0}, {0x3a19, 0x7c, 0, 0},
110 {0x3635, 0x13, 0, 0}, {0x3636, 0x03, 0, 0}, {0x3634, 0x40, 0, 0},
111 {0x3622, 0x01, 0, 0}, {0x3c01, 0x34, 0, 0}, {0x3c04, 0x28, 0, 0},
112 {0x3c05, 0x98, 0, 0}, {0x3c06, 0x00, 0, 0}, {0x3c07, 0x07, 0, 0},
113 {0x3c08, 0x00, 0, 0}, {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0},
114 {0x3c0b, 0x40, 0, 0}, {0x3810, 0x00, 0, 0}, {0x3811, 0x10, 0, 0},
115 {0x3812, 0x00, 0, 0}, {0x3708, 0x64, 0, 0}, {0x4001, 0x02, 0, 0},
116 {0x4005, 0x1a, 0, 0}, {0x3000, 0x00, 0, 0}, {0x3004, 0xff, 0, 0},
117 {0x300e, 0x58, 0, 0}, {0x302e, 0x00, 0, 0}, {0x4300, 0x30, 0, 0},
118 {0x501f, 0x00, 0, 0}, {0x440e, 0x00, 0, 0}, {0x5000, 0xa7, 0, 0},
119 {0x3008, 0x02, 0, 0},
122 static struct reg_value ov5640_init_setting_30fps_VGA[] = {
123 {0x3008, 0x42, 0, 0},
124 {0x3103, 0x03, 0, 0}, {0x3017, 0xff, 0, 0}, {0x3018, 0xff, 0, 0},
125 {0x3034, 0x1a, 0, 0}, {0x3035, 0x11, 0, 0}, {0x3036, 0x46, 0, 0},
126 {0x3037, 0x13, 0, 0}, {0x3108, 0x01, 0, 0}, {0x3630, 0x36, 0, 0},
127 {0x3631, 0x0e, 0, 0}, {0x3632, 0xe2, 0, 0}, {0x3633, 0x12, 0, 0},
128 {0x3621, 0xe0, 0, 0}, {0x3704, 0xa0, 0, 0}, {0x3703, 0x5a, 0, 0},
129 {0x3715, 0x78, 0, 0}, {0x3717, 0x01, 0, 0}, {0x370b, 0x60, 0, 0},
130 {0x3705, 0x1a, 0, 0}, {0x3905, 0x02, 0, 0}, {0x3906, 0x10, 0, 0},
131 {0x3901, 0x0a, 0, 0}, {0x3731, 0x12, 0, 0}, {0x3600, 0x08, 0, 0},
132 {0x3601, 0x33, 0, 0}, {0x302d, 0x60, 0, 0}, {0x3620, 0x52, 0, 0},
133 {0x371b, 0x20, 0, 0}, {0x471c, 0x50, 0, 0}, {0x3a13, 0x43, 0, 0},
134 {0x3a18, 0x00, 0, 0}, {0x3a19, 0xf8, 0, 0}, {0x3635, 0x13, 0, 0},
135 {0x3636, 0x03, 0, 0}, {0x3634, 0x40, 0, 0}, {0x3622, 0x01, 0, 0},
136 {0x3c01, 0x34, 0, 0}, {0x3c04, 0x28, 0, 0}, {0x3c05, 0x98, 0, 0},
137 {0x3c06, 0x00, 0, 0}, {0x3c07, 0x08, 0, 0}, {0x3c08, 0x00, 0, 0},
138 {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
139 {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
140 {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
141 {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
142 {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
143 {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0},
144 {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
145 {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
146 {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
147 {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
148 {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
149 {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
150 {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
151 {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
152 {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x3000, 0x00, 0, 0},
153 {0x3002, 0x1c, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3006, 0xc3, 0, 0},
154 {0x300e, 0x58, 0, 0}, {0x302e, 0x00, 0, 0}, {0x4300, 0x30, 0, 0},
155 {0x501f, 0x00, 0, 0}, {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0},
156 {0x440e, 0x00, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
157 {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0}, {0x5000, 0xa7, 0, 0},
158 {0x5001, 0xa3, 0, 0}, {0x5180, 0xff, 0, 0}, {0x5181, 0xf2, 0, 0},
159 {0x5182, 0x00, 0, 0}, {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0},
160 {0x5185, 0x24, 0, 0}, {0x5186, 0x09, 0, 0}, {0x5187, 0x09, 0, 0},
161 {0x5188, 0x09, 0, 0}, {0x5189, 0x88, 0, 0}, {0x518a, 0x54, 0, 0},
162 {0x518b, 0xee, 0, 0}, {0x518c, 0xb2, 0, 0}, {0x518d, 0x50, 0, 0},
163 {0x518e, 0x34, 0, 0}, {0x518f, 0x6b, 0, 0}, {0x5190, 0x46, 0, 0},
164 {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0},
165 {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0},
166 {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0}, {0x5199, 0x6c, 0, 0},
167 {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0}, {0x519c, 0x09, 0, 0},
168 {0x519d, 0x2b, 0, 0}, {0x519e, 0x38, 0, 0}, {0x5381, 0x1e, 0, 0},
169 {0x5382, 0x5b, 0, 0}, {0x5383, 0x08, 0, 0}, {0x5384, 0x0a, 0, 0},
170 {0x5385, 0x7e, 0, 0}, {0x5386, 0x88, 0, 0}, {0x5387, 0x7c, 0, 0},
171 {0x5388, 0x6c, 0, 0}, {0x5389, 0x10, 0, 0}, {0x538a, 0x01, 0, 0},
172 {0x538b, 0x98, 0, 0}, {0x5300, 0x08, 0, 0}, {0x5301, 0x30, 0, 0},
173 {0x5302, 0x10, 0, 0}, {0x5303, 0x00, 0, 0}, {0x5304, 0x08, 0, 0},
174 {0x5305, 0x30, 0, 0}, {0x5306, 0x08, 0, 0}, {0x5307, 0x16, 0, 0},
175 {0x5309, 0x08, 0, 0}, {0x530a, 0x30, 0, 0}, {0x530b, 0x04, 0, 0},
176 {0x530c, 0x06, 0, 0}, {0x5480, 0x01, 0, 0}, {0x5481, 0x08, 0, 0},
177 {0x5482, 0x14, 0, 0}, {0x5483, 0x28, 0, 0}, {0x5484, 0x51, 0, 0},
178 {0x5485, 0x65, 0, 0}, {0x5486, 0x71, 0, 0}, {0x5487, 0x7d, 0, 0},
179 {0x5488, 0x87, 0, 0}, {0x5489, 0x91, 0, 0}, {0x548a, 0x9a, 0, 0},
180 {0x548b, 0xaa, 0, 0}, {0x548c, 0xb8, 0, 0}, {0x548d, 0xcd, 0, 0},
181 {0x548e, 0xdd, 0, 0}, {0x548f, 0xea, 0, 0}, {0x5490, 0x1d, 0, 0},
182 {0x5580, 0x02, 0, 0}, {0x5583, 0x40, 0, 0}, {0x5584, 0x10, 0, 0},
183 {0x5589, 0x10, 0, 0}, {0x558a, 0x00, 0, 0}, {0x558b, 0xf8, 0, 0},
184 {0x5800, 0x23, 0, 0}, {0x5801, 0x14, 0, 0}, {0x5802, 0x0f, 0, 0},
185 {0x5803, 0x0f, 0, 0}, {0x5804, 0x12, 0, 0}, {0x5805, 0x26, 0, 0},
186 {0x5806, 0x0c, 0, 0}, {0x5807, 0x08, 0, 0}, {0x5808, 0x05, 0, 0},
187 {0x5809, 0x05, 0, 0}, {0x580a, 0x08, 0, 0}, {0x580b, 0x0d, 0, 0},
188 {0x580c, 0x08, 0, 0}, {0x580d, 0x03, 0, 0}, {0x580e, 0x00, 0, 0},
189 {0x580f, 0x00, 0, 0}, {0x5810, 0x03, 0, 0}, {0x5811, 0x09, 0, 0},
190 {0x5812, 0x07, 0, 0}, {0x5813, 0x03, 0, 0}, {0x5814, 0x00, 0, 0},
191 {0x5815, 0x01, 0, 0}, {0x5816, 0x03, 0, 0}, {0x5817, 0x08, 0, 0},
192 {0x5818, 0x0d, 0, 0}, {0x5819, 0x08, 0, 0}, {0x581a, 0x05, 0, 0},
193 {0x581b, 0x06, 0, 0}, {0x581c, 0x08, 0, 0}, {0x581d, 0x0e, 0, 0},
194 {0x581e, 0x29, 0, 0}, {0x581f, 0x17, 0, 0}, {0x5820, 0x11, 0, 0},
195 {0x5821, 0x11, 0, 0}, {0x5822, 0x15, 0, 0}, {0x5823, 0x28, 0, 0},
196 {0x5824, 0x46, 0, 0}, {0x5825, 0x26, 0, 0}, {0x5826, 0x08, 0, 0},
197 {0x5827, 0x26, 0, 0}, {0x5828, 0x64, 0, 0}, {0x5829, 0x26, 0, 0},
198 {0x582a, 0x24, 0, 0}, {0x582b, 0x22, 0, 0}, {0x582c, 0x24, 0, 0},
199 {0x582d, 0x24, 0, 0}, {0x582e, 0x06, 0, 0}, {0x582f, 0x22, 0, 0},
200 {0x5830, 0x40, 0, 0}, {0x5831, 0x42, 0, 0}, {0x5832, 0x24, 0, 0},
201 {0x5833, 0x26, 0, 0}, {0x5834, 0x24, 0, 0}, {0x5835, 0x22, 0, 0},
202 {0x5836, 0x22, 0, 0}, {0x5837, 0x26, 0, 0}, {0x5838, 0x44, 0, 0},
203 {0x5839, 0x24, 0, 0}, {0x583a, 0x26, 0, 0}, {0x583b, 0x28, 0, 0},
204 {0x583c, 0x42, 0, 0}, {0x583d, 0xce, 0, 0}, {0x5025, 0x00, 0, 0},
205 {0x3a0f, 0x30, 0, 0}, {0x3a10, 0x28, 0, 0}, {0x3a1b, 0x30, 0, 0},
206 {0x3a1e, 0x26, 0, 0}, {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x14, 0, 0},
207 {0x3008, 0x02, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x11, 0, 0},
208 {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
211 static struct reg_value ov5640_setting_30fps_VGA_640_480[] = {
212 {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
213 {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
214 {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
215 {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
216 {0x3807, 0x9b, 0, 0}, {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0},
217 {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0},
218 {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
219 {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
220 {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
221 {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
222 {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
223 {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
224 {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
225 {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x11, 0, 0},
226 {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0}, {0x3503, 0x00, 0, 0},
229 static struct reg_value ov5640_setting_15fps_VGA_640_480[] = {
230 {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
231 {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
232 {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
233 {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
234 {0x3807, 0x9b, 0, 0}, {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0},
235 {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0},
236 {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
237 {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
238 {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
239 {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
240 {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
241 {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
242 {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
243 {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
244 {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0}, {0x3503, 0x00, 0, 0},
247 static struct reg_value ov5640_setting_30fps_QVGA_320_240[] = {
248 {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
249 {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
250 {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
251 {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
252 {0x3807, 0x9b, 0, 0}, {0x3808, 0x01, 0, 0}, {0x3809, 0x40, 0, 0},
253 {0x380a, 0x00, 0, 0}, {0x380b, 0xf0, 0, 0}, {0x380c, 0x07, 0, 0},
254 {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
255 {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
256 {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
257 {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
258 {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
259 {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
260 {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
261 {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x11, 0, 0},
262 {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
265 static struct reg_value ov5640_setting_15fps_QVGA_320_240[] = {
266 {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
267 {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
268 {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
269 {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
270 {0x3807, 0x9b, 0, 0}, {0x3808, 0x01, 0, 0}, {0x3809, 0x40, 0, 0},
271 {0x380a, 0x00, 0, 0}, {0x380b, 0xf0, 0, 0}, {0x380c, 0x07, 0, 0},
272 {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
273 {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
274 {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
275 {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
276 {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
277 {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
278 {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
279 {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
280 {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
283 static struct reg_value ov5640_setting_30fps_NTSC_720_480[] = {
284 {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
285 {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
286 {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
287 {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x06, 0, 0},
288 {0x3807, 0xd4, 0, 0}, {0x3808, 0x02, 0, 0}, {0x3809, 0xd0, 0, 0},
289 {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0},
290 {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
291 {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
292 {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
293 {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
294 {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
295 {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
296 {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
297 {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x11, 0, 0},
298 {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
301 static struct reg_value ov5640_setting_15fps_NTSC_720_480[] = {
302 {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
303 {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
304 {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
305 {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x06, 0, 0},
306 {0x3807, 0xd4, 0, 0}, {0x3808, 0x02, 0, 0}, {0x3809, 0xd0, 0, 0},
307 {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0},
308 {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
309 {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
310 {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
311 {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
312 {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
313 {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
314 {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
315 {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
316 {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
319 static struct reg_value ov5640_setting_30fps_PAL_720_576[] = {
320 {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
321 {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
322 {0x3801, 0x60, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
323 {0x3804, 0x09, 0, 0}, {0x3805, 0x7e, 0, 0}, {0x3806, 0x07, 0, 0},
324 {0x3807, 0x9b, 0, 0}, {0x3808, 0x02, 0, 0}, {0x3809, 0xd0, 0, 0},
325 {0x380a, 0x02, 0, 0}, {0x380b, 0x40, 0, 0}, {0x380c, 0x07, 0, 0},
326 {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
327 {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
328 {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
329 {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
330 {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
331 {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
332 {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
333 {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x11, 0, 0},
334 {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
337 static struct reg_value ov5640_setting_15fps_PAL_720_576[] = {
338 {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
339 {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
340 {0x3801, 0x60, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
341 {0x3804, 0x09, 0, 0}, {0x3805, 0x7e, 0, 0}, {0x3806, 0x07, 0, 0},
342 {0x3807, 0x9b, 0, 0}, {0x3808, 0x02, 0, 0}, {0x3809, 0xd0, 0, 0},
343 {0x380a, 0x02, 0, 0}, {0x380b, 0x40, 0, 0}, {0x380c, 0x07, 0, 0},
344 {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
345 {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
346 {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
347 {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
348 {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
349 {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
350 {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
351 {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
352 {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
355 static struct reg_value ov5640_setting_30fps_720P_1280_720[] = {
356 {0x3035, 0x21, 0, 0}, {0x3036, 0x69, 0, 0}, {0x3c07, 0x07, 0, 0},
357 {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
358 {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
359 {0x3802, 0x00, 0, 0}, {0x3803, 0xfa, 0, 0}, {0x3804, 0x0a, 0, 0},
360 {0x3805, 0x3f, 0, 0}, {0x3806, 0x06, 0, 0}, {0x3807, 0xa9, 0, 0},
361 {0x3808, 0x05, 0, 0}, {0x3809, 0x00, 0, 0}, {0x380a, 0x02, 0, 0},
362 {0x380b, 0xd0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x64, 0, 0},
363 {0x380e, 0x02, 0, 0}, {0x380f, 0xe4, 0, 0}, {0x3813, 0x04, 0, 0},
364 {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3709, 0x52, 0, 0},
365 {0x370c, 0x03, 0, 0}, {0x3a02, 0x02, 0, 0}, {0x3a03, 0xe0, 0, 0},
366 {0x3a14, 0x02, 0, 0}, {0x3a15, 0xe0, 0, 0}, {0x4004, 0x02, 0, 0},
367 {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0}, {0x4713, 0x03, 0, 0},
368 {0x4407, 0x04, 0, 0}, {0x460b, 0x37, 0, 0}, {0x460c, 0x20, 0, 0},
369 {0x4837, 0x16, 0, 0}, {0x3824, 0x04, 0, 0}, {0x5001, 0x83, 0, 0},
370 {0x3503, 0x00, 0, 0},
373 static struct reg_value ov5640_setting_15fps_720P_1280_720[] = {
374 {0x3035, 0x41, 0, 0}, {0x3036, 0x69, 0, 0}, {0x3c07, 0x07, 0, 0},
375 {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
376 {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
377 {0x3802, 0x00, 0, 0}, {0x3803, 0xfa, 0, 0}, {0x3804, 0x0a, 0, 0},
378 {0x3805, 0x3f, 0, 0}, {0x3806, 0x06, 0, 0}, {0x3807, 0xa9, 0, 0},
379 {0x3808, 0x05, 0, 0}, {0x3809, 0x00, 0, 0}, {0x380a, 0x02, 0, 0},
380 {0x380b, 0xd0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x64, 0, 0},
381 {0x380e, 0x02, 0, 0}, {0x380f, 0xe4, 0, 0}, {0x3813, 0x04, 0, 0},
382 {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3709, 0x52, 0, 0},
383 {0x370c, 0x03, 0, 0}, {0x3a02, 0x02, 0, 0}, {0x3a03, 0xe0, 0, 0},
384 {0x3a14, 0x02, 0, 0}, {0x3a15, 0xe0, 0, 0}, {0x4004, 0x02, 0, 0},
385 {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0}, {0x4713, 0x03, 0, 0},
386 {0x4407, 0x04, 0, 0}, {0x460b, 0x37, 0, 0}, {0x460c, 0x20, 0, 0},
387 {0x4837, 0x16, 0, 0}, {0x3824, 0x04, 0, 0}, {0x5001, 0x83, 0, 0},
388 {0x3503, 0x00, 0, 0},
391 static struct reg_value ov5640_setting_30fps_QCIF_176_144[] = {
392 {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
393 {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
394 {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
395 {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
396 {0x3807, 0x9b, 0, 0}, {0x3808, 0x00, 0, 0}, {0x3809, 0xb0, 0, 0},
397 {0x380a, 0x00, 0, 0}, {0x380b, 0x90, 0, 0}, {0x380c, 0x07, 0, 0},
398 {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
399 {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
400 {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
401 {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
402 {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
403 {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
404 {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
405 {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x11, 0, 0},
406 {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
409 static struct reg_value ov5640_setting_15fps_QCIF_176_144[] = {
410 {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
411 {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
412 {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
413 {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
414 {0x3807, 0x9b, 0, 0}, {0x3808, 0x00, 0, 0}, {0x3809, 0xb0, 0, 0},
415 {0x380a, 0x00, 0, 0}, {0x380b, 0x90, 0, 0}, {0x380c, 0x07, 0, 0},
416 {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
417 {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
418 {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
419 {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
420 {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
421 {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
422 {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
423 {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
424 {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
427 static struct reg_value ov5640_setting_30fps_XGA_1024_768[] = {
428 {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
429 {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
430 {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
431 {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
432 {0x3807, 0x9b, 0, 0}, {0x3808, 0x04, 0, 0}, {0x3809, 0x00, 0, 0},
433 {0x380a, 0x03, 0, 0}, {0x380b, 0x00, 0, 0}, {0x380c, 0x07, 0, 0},
434 {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
435 {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
436 {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
437 {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
438 {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
439 {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
440 {0x460c, 0x20, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x01, 0, 0},
441 {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
442 {0x3036, 0x69, 0, 0}, {0x3037, 0x13, 0, 0},
445 static struct reg_value ov5640_setting_15fps_XGA_1024_768[] = {
446 {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
447 {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
448 {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
449 {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
450 {0x3807, 0x9b, 0, 0}, {0x3808, 0x04, 0, 0}, {0x3809, 0x00, 0, 0},
451 {0x380a, 0x03, 0, 0}, {0x380b, 0x00, 0, 0}, {0x380c, 0x07, 0, 0},
452 {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
453 {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
454 {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
455 {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
456 {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
457 {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
458 {0x460c, 0x20, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x01, 0, 0},
459 {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
460 {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
464 static struct reg_value ov5640_setting_15fps_1080P_1920_1080[] = {
465 {0x3c07, 0x07, 0, 0}, {0x3820, 0x40, 0, 0}, {0x3821, 0x06, 0, 0},
466 {0x3814, 0x11, 0, 0}, {0x3815, 0x11, 0, 0}, {0x3800, 0x00, 0, 0},
467 {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0xee, 0, 0},
468 {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x05, 0, 0},
469 {0x3807, 0xc3, 0, 0}, {0x3808, 0x07, 0, 0}, {0x3809, 0x80, 0, 0},
470 {0x380a, 0x04, 0, 0}, {0x380b, 0x38, 0, 0}, {0x380c, 0x0b, 0, 0},
471 {0x380d, 0x1c, 0, 0}, {0x380e, 0x07, 0, 0}, {0x380f, 0xb0, 0, 0},
472 {0x3813, 0x04, 0, 0}, {0x3618, 0x04, 0, 0}, {0x3612, 0x2b, 0, 0},
473 {0x3709, 0x12, 0, 0}, {0x370c, 0x00, 0, 0}, {0x3a02, 0x07, 0, 0},
474 {0x3a03, 0xae, 0, 0}, {0x3a14, 0x07, 0, 0}, {0x3a15, 0xae, 0, 0},
475 {0x4004, 0x06, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
476 {0x4713, 0x02, 0, 0}, {0x4407, 0x0c, 0, 0}, {0x460b, 0x37, 0, 0},
477 {0x460c, 0x20, 0, 0}, {0x4837, 0x2c, 0, 0}, {0x3824, 0x01, 0, 0},
478 {0x5001, 0x83, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
479 {0x3036, 0x69, 0, 0}, {0x3037, 0x13, 0, 0},
482 static struct reg_value ov5640_setting_15fps_QSXGA_2592_1944[] = {
483 {0x3c07, 0x07, 0, 0}, {0x3820, 0x40, 0, 0}, {0x3821, 0x06, 0, 0},
484 {0x3814, 0x11, 0, 0}, {0x3815, 0x11, 0, 0}, {0x3800, 0x00, 0, 0},
485 {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x00, 0, 0},
486 {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
487 {0x3807, 0x9f, 0, 0}, {0x3808, 0x0a, 0, 0}, {0x3809, 0x20, 0, 0},
488 {0x380a, 0x07, 0, 0}, {0x380b, 0x98, 0, 0}, {0x380c, 0x0b, 0, 0},
489 {0x380d, 0x1c, 0, 0}, {0x380e, 0x07, 0, 0}, {0x380f, 0xb0, 0, 0},
490 {0x3813, 0x04, 0, 0}, {0x3618, 0x04, 0, 0}, {0x3612, 0x2b, 0, 0},
491 {0x3709, 0x12, 0, 0}, {0x370c, 0x00, 0, 0}, {0x3a02, 0x07, 0, 0},
492 {0x3a03, 0xae, 0, 0}, {0x3a14, 0x07, 0, 0}, {0x3a15, 0xae, 0, 0},
493 {0x4004, 0x06, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
494 {0x4713, 0x02, 0, 0}, {0x4407, 0x0c, 0, 0}, {0x460b, 0x37, 0, 0},
495 {0x460c, 0x20, 0, 0}, {0x4837, 0x2c, 0, 0}, {0x3824, 0x01, 0, 0},
496 {0x5001, 0x83, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
497 {0x3036, 0x69, 0, 0}, {0x3037, 0x13, 0, 0},
500 static struct ov5640_mode_info ov5640_mode_info_data[2][ov5640_mode_MAX + 1] = {
502 {ov5640_mode_VGA_640_480, 640, 480,
503 ov5640_setting_15fps_VGA_640_480,
504 ARRAY_SIZE(ov5640_setting_15fps_VGA_640_480)},
505 {ov5640_mode_QVGA_320_240, 320, 240,
506 ov5640_setting_15fps_QVGA_320_240,
507 ARRAY_SIZE(ov5640_setting_15fps_QVGA_320_240)},
508 {ov5640_mode_NTSC_720_480, 720, 480,
509 ov5640_setting_15fps_NTSC_720_480,
510 ARRAY_SIZE(ov5640_setting_15fps_NTSC_720_480)},
511 {ov5640_mode_PAL_720_576, 720, 576,
512 ov5640_setting_15fps_PAL_720_576,
513 ARRAY_SIZE(ov5640_setting_15fps_PAL_720_576)},
514 {ov5640_mode_720P_1280_720, 1280, 720,
515 ov5640_setting_15fps_720P_1280_720,
516 ARRAY_SIZE(ov5640_setting_15fps_720P_1280_720)},
517 {ov5640_mode_1080P_1920_1080, 1920, 1080,
518 ov5640_setting_15fps_1080P_1920_1080,
519 ARRAY_SIZE(ov5640_setting_15fps_1080P_1920_1080)},
520 {ov5640_mode_QSXGA_2592_1944, 2592, 1944,
521 ov5640_setting_15fps_QSXGA_2592_1944,
522 ARRAY_SIZE(ov5640_setting_15fps_QSXGA_2592_1944)},
523 {ov5640_mode_QCIF_176_144, 176, 144,
524 ov5640_setting_15fps_QCIF_176_144,
525 ARRAY_SIZE(ov5640_setting_15fps_QCIF_176_144)},
526 {ov5640_mode_XGA_1024_768, 1024, 768,
527 ov5640_setting_15fps_XGA_1024_768,
528 ARRAY_SIZE(ov5640_setting_15fps_XGA_1024_768)},
531 {ov5640_mode_VGA_640_480, 640, 480,
532 ov5640_setting_30fps_VGA_640_480,
533 ARRAY_SIZE(ov5640_setting_30fps_VGA_640_480)},
534 {ov5640_mode_QVGA_320_240, 320, 240,
535 ov5640_setting_30fps_QVGA_320_240,
536 ARRAY_SIZE(ov5640_setting_30fps_QVGA_320_240)},
537 {ov5640_mode_NTSC_720_480, 720, 480,
538 ov5640_setting_30fps_NTSC_720_480,
539 ARRAY_SIZE(ov5640_setting_30fps_NTSC_720_480)},
540 {ov5640_mode_PAL_720_576, 720, 576,
541 ov5640_setting_30fps_PAL_720_576,
542 ARRAY_SIZE(ov5640_setting_30fps_PAL_720_576)},
543 {ov5640_mode_720P_1280_720, 1280, 720,
544 ov5640_setting_30fps_720P_1280_720,
545 ARRAY_SIZE(ov5640_setting_30fps_720P_1280_720)},
546 {ov5640_mode_1080P_1920_1080, 0, 0, NULL, 0},
547 {ov5640_mode_QSXGA_2592_1944, 0, 0, NULL, 0},
548 {ov5640_mode_QCIF_176_144, 176, 144,
549 ov5640_setting_30fps_QCIF_176_144,
550 ARRAY_SIZE(ov5640_setting_30fps_QCIF_176_144)},
551 {ov5640_mode_XGA_1024_768, 1024, 768,
552 ov5640_setting_30fps_XGA_1024_768,
553 ARRAY_SIZE(ov5640_setting_30fps_XGA_1024_768)},
557 static struct regulator *io_regulator;
558 static struct regulator *core_regulator;
559 static struct regulator *analog_regulator;
561 static int ov5640_probe(struct i2c_client *adapter,
562 const struct i2c_device_id *device_id);
563 static int ov5640_remove(struct i2c_client *client);
565 static s32 ov5640_read_reg(u16 reg, u8 *val);
566 static s32 ov5640_write_reg(u16 reg, u8 val);
568 static const struct i2c_device_id ov5640_id[] = {
573 MODULE_DEVICE_TABLE(i2c, ov5640_id);
575 static struct i2c_driver ov5640_i2c_driver = {
577 .owner = THIS_MODULE,
580 .probe = ov5640_probe,
581 .remove = ov5640_remove,
582 .id_table = ov5640_id,
585 static inline void ov5640_power_down(int enable)
587 gpio_set_value(pwn_gpio, enable);
592 static inline void ov5640_reset(void)
595 gpio_set_value(rst_gpio, 1);
597 /* camera power down */
598 gpio_set_value(pwn_gpio, 1);
600 gpio_set_value(pwn_gpio, 0);
602 gpio_set_value(rst_gpio, 0);
604 gpio_set_value(rst_gpio, 1);
606 gpio_set_value(pwn_gpio, 1);
609 static int ov5640_regulator_enable(struct device *dev)
613 io_regulator = devm_regulator_get(dev, "DOVDD");
614 if (!IS_ERR(io_regulator)) {
615 regulator_set_voltage(io_regulator,
616 OV5640_VOLTAGE_DIGITAL_IO,
617 OV5640_VOLTAGE_DIGITAL_IO);
618 ret = regulator_enable(io_regulator);
620 dev_err(dev, "set io voltage failed\n");
623 dev_dbg(dev, "set io voltage ok\n");
627 dev_warn(dev, "cannot get io voltage\n");
630 core_regulator = devm_regulator_get(dev, "DVDD");
631 if (!IS_ERR(core_regulator)) {
632 regulator_set_voltage(core_regulator,
633 OV5640_VOLTAGE_DIGITAL_CORE,
634 OV5640_VOLTAGE_DIGITAL_CORE);
635 ret = regulator_enable(core_regulator);
637 dev_err(dev, "set core voltage failed\n");
640 dev_dbg(dev, "set core voltage ok\n");
643 core_regulator = NULL;
644 dev_warn(dev, "cannot get core voltage\n");
647 analog_regulator = devm_regulator_get(dev, "AVDD");
648 if (!IS_ERR(analog_regulator)) {
649 regulator_set_voltage(analog_regulator,
650 OV5640_VOLTAGE_ANALOG,
651 OV5640_VOLTAGE_ANALOG);
652 ret = regulator_enable(analog_regulator);
654 dev_err(dev, "set analog voltage failed\n");
657 dev_dbg(dev, "set analog voltage ok\n");
660 analog_regulator = NULL;
661 dev_warn(dev, "cannot get analog voltage\n");
667 static s32 ov5640_write_reg(u16 reg, u8 val)
671 au8Buf[0] = reg >> 8;
672 au8Buf[1] = reg & 0xff;
675 if (i2c_master_send(ov5640_data.i2c_client, au8Buf, 3) < 0) {
676 pr_err("%s:write reg error:reg=%x,val=%x\n",
684 static s32 ov5640_read_reg(u16 reg, u8 *val)
686 u8 au8RegBuf[2] = {0};
689 au8RegBuf[0] = reg >> 8;
690 au8RegBuf[1] = reg & 0xff;
692 if (2 != i2c_master_send(ov5640_data.i2c_client, au8RegBuf, 2)) {
693 pr_err("%s:write reg error:reg=%x\n",
698 if (1 != i2c_master_recv(ov5640_data.i2c_client, &u8RdVal, 1)) {
699 pr_err("%s:read reg error:reg=%x,val=%x\n",
700 __func__, reg, u8RdVal);
709 static void ov5640_soft_reset(void)
711 /* sysclk from pad */
712 ov5640_write_reg(0x3103, 0x11);
715 ov5640_write_reg(0x3008, 0x82);
717 /* delay at least 5ms */
721 /* set sensor driver capability
722 * 0x302c[7:6] - strength
728 static int ov5640_driver_capability(int strength)
732 if (strength > 4 || strength < 1) {
733 pr_err("The valid driver capability of ov5640 is 1x~4x\n");
737 ov5640_read_reg(0x302c, &temp);
739 temp &= ~0xc0; /* clear [7:6] */
740 temp |= ((strength - 1) << 6); /* set [7:6] */
742 ov5640_write_reg(0x302c, temp);
747 /* calculate sysclk */
748 static int ov5640_get_sysclk(void)
750 int xvclk = ov5640_data.mclk / 10000;
753 int Multiplier, PreDiv, VCO, SysDiv, Pll_rdiv, Bit_div2x, sclk_rdiv;
754 int sclk_rdiv_map[] = {1, 2, 4, 8};
757 temp1 = ov5640_read_reg(0x3034, ®val);
758 temp2 = temp1 & 0x0f;
759 if (temp2 == 8 || temp2 == 10) {
760 Bit_div2x = temp2 / 2;
762 pr_err("ov5640: unsupported bit mode %d\n", temp2);
766 temp1 = ov5640_read_reg(0x3035, ®val);
771 temp1 = ov5640_read_reg(0x3036, ®val);
773 temp1 = ov5640_read_reg(0x3037, ®val);
774 PreDiv = temp1 & 0x0f;
775 Pll_rdiv = ((temp1 >> 4) & 0x01) + 1;
777 temp1 = ov5640_read_reg(0x3108, ®val);
778 temp2 = temp1 & 0x03;
780 sclk_rdiv = sclk_rdiv_map[temp2];
781 VCO = xvclk * Multiplier / PreDiv;
782 sysclk = VCO / SysDiv / Pll_rdiv * 2 / Bit_div2x / sclk_rdiv;
787 /* read HTS from register settings */
788 static int ov5640_get_HTS(void)
793 HTS = ov5640_read_reg(0x380c, &temp);
794 HTS = (HTS<<8) + ov5640_read_reg(0x380d, &temp);
798 /* read VTS from register settings */
799 static int ov5640_get_VTS(void)
804 VTS = ov5640_read_reg(0x380e, &temp);
805 VTS = (VTS<<8) + ov5640_read_reg(0x380f, &temp);
810 /* write VTS to registers */
811 static int ov5640_set_VTS(int VTS)
816 ov5640_write_reg(0x380f, temp);
819 ov5640_write_reg(0x380e, temp);
823 /* read shutter, in number of line period */
824 static int ov5640_get_shutter(void)
829 shutter = (ov5640_read_reg(0x03500, ®val) & 0x0f);
831 shutter = (shutter<<8) + ov5640_read_reg(0x3501, ®val);
832 shutter = (shutter<<4) + (ov5640_read_reg(0x3502, ®val)>>4);
837 /* write shutter, in number of line period */
838 static int ov5640_set_shutter(int shutter)
842 shutter = shutter & 0xffff;
843 temp = shutter & 0x0f;
845 ov5640_write_reg(0x3502, temp);
847 temp = shutter & 0xfff;
849 ov5640_write_reg(0x3501, temp);
852 ov5640_write_reg(0x3500, temp);
857 /* read gain, 16 = 1x */
858 static int ov5640_get_gain16(void)
863 gain16 = ov5640_read_reg(0x350a, ®val) & 0x03;
864 gain16 = (gain16<<8) + ov5640_read_reg(0x350b, ®val);
869 /* write gain, 16 = 1x */
870 static int ov5640_set_gain16(int gain16)
874 gain16 = gain16 & 0x3ff;
875 temp = gain16 & 0xff;
877 ov5640_write_reg(0x350b, temp);
880 ov5640_write_reg(0x350a, temp);
884 /* get banding filter value */
885 static int ov5640_get_light_freq(void)
887 int temp, temp1, light_frequency;
890 temp = ov5640_read_reg(0x3c01, ®val);
893 temp1 = ov5640_read_reg(0x3c00, ®val);
896 light_frequency = 50;
899 light_frequency = 60;
903 temp1 = ov5640_read_reg(0x3c0c, ®val);
906 light_frequency = 50;
909 light_frequency = 60;
913 return light_frequency;
916 static void ov5640_set_bandingfilter(void)
919 int band_step60, max_band60, band_step50, max_band50;
921 /* read preview PCLK */
922 prev_sysclk = ov5640_get_sysclk();
924 /* read preview HTS */
925 prev_HTS = ov5640_get_HTS();
927 /* read preview VTS */
928 prev_VTS = ov5640_get_VTS();
930 /* calculate banding filter */
932 band_step60 = prev_sysclk * 100/prev_HTS * 100/120;
933 ov5640_write_reg(0x3a0a, (band_step60 >> 8));
934 ov5640_write_reg(0x3a0b, (band_step60 & 0xff));
936 max_band60 = (int)((prev_VTS-4)/band_step60);
937 ov5640_write_reg(0x3a0d, max_band60);
940 band_step50 = prev_sysclk * 100/prev_HTS;
941 ov5640_write_reg(0x3a08, (band_step50 >> 8));
942 ov5640_write_reg(0x3a09, (band_step50 & 0xff));
944 max_band50 = (int)((prev_VTS-4)/band_step50);
945 ov5640_write_reg(0x3a0e, max_band50);
949 static int ov5640_set_AE_target(int target)
951 int fast_high, fast_low;
953 AE_low = target * 23 / 25; /* 0.92 */
954 AE_high = target * 27 / 25; /* 1.08 */
955 fast_high = AE_high << 1;
959 fast_low = AE_low >> 1;
961 ov5640_write_reg(0x3a0f, AE_high);
962 ov5640_write_reg(0x3a10, AE_low);
963 ov5640_write_reg(0x3a1b, AE_high);
964 ov5640_write_reg(0x3a1e, AE_low);
965 ov5640_write_reg(0x3a11, fast_high);
966 ov5640_write_reg(0x3a1f, fast_low);
971 /* enable = 0 to turn off night mode
972 enable = 1 to turn on night mode */
973 static int ov5640_set_night_mode(int enable)
977 ov5640_read_reg(0x3a00, &mode);
982 ov5640_write_reg(0x3a00, mode);
986 ov5640_write_reg(0x3a00, mode);
992 /* enable = 0 to turn off AEC/AGC
993 enable = 1 to turn on AEC/AGC */
994 void ov5640_turn_on_AE_AG(int enable)
998 ov5640_read_reg(0x3503, &ae_ag_ctrl);
1000 /* turn on auto AE/AG */
1001 ae_ag_ctrl = ae_ag_ctrl & ~(0x03);
1003 /* turn off AE/AG */
1004 ae_ag_ctrl = ae_ag_ctrl | 0x03;
1006 ov5640_write_reg(0x3503, ae_ag_ctrl);
1009 /* download ov5640 settings to sensor through i2c */
1010 static int ov5640_download_firmware(struct reg_value *pModeSetting, s32 ArySize)
1012 register u32 Delay_ms = 0;
1013 register u16 RegAddr = 0;
1014 register u8 Mask = 0;
1015 register u8 Val = 0;
1019 for (i = 0; i < ArySize; ++i, ++pModeSetting) {
1020 Delay_ms = pModeSetting->u32Delay_ms;
1021 RegAddr = pModeSetting->u16RegAddr;
1022 Val = pModeSetting->u8Val;
1023 Mask = pModeSetting->u8Mask;
1026 retval = ov5640_read_reg(RegAddr, &RegVal);
1030 RegVal &= ~(u8)Mask;
1035 retval = ov5640_write_reg(RegAddr, Val);
1046 static int ov5640_init_mode(void)
1048 struct reg_value *pModeSetting = NULL;
1049 int ArySize = 0, retval = 0;
1051 ov5640_soft_reset();
1053 pModeSetting = ov5640_global_init_setting;
1054 ArySize = ARRAY_SIZE(ov5640_global_init_setting);
1055 retval = ov5640_download_firmware(pModeSetting, ArySize);
1059 pModeSetting = ov5640_init_setting_30fps_VGA;
1060 ArySize = ARRAY_SIZE(ov5640_init_setting_30fps_VGA);
1061 retval = ov5640_download_firmware(pModeSetting, ArySize);
1065 /* change driver capability to 2x according to validation board.
1066 * if the image is not stable, please increase the driver strength.
1068 ov5640_driver_capability(2);
1069 ov5640_set_bandingfilter();
1070 ov5640_set_AE_target(AE_Target);
1071 ov5640_set_night_mode(night_mode);
1073 /* skip 9 vysnc: start capture at 10th vsync */
1076 /* turn off night mode */
1078 ov5640_data.pix.width = 640;
1079 ov5640_data.pix.height = 480;
1084 /* change to or back to subsampling mode set the mode directly
1085 * image size below 1280 * 960 is subsampling mode */
1086 static int ov5640_change_mode_direct(enum ov5640_frame_rate frame_rate,
1087 enum ov5640_mode mode)
1089 struct reg_value *pModeSetting = NULL;
1093 if (mode > ov5640_mode_MAX || mode < ov5640_mode_MIN) {
1094 pr_err("Wrong ov5640 mode detected!\n");
1098 pModeSetting = ov5640_mode_info_data[frame_rate][mode].init_data_ptr;
1100 ov5640_mode_info_data[frame_rate][mode].init_data_size;
1102 ov5640_data.pix.width = ov5640_mode_info_data[frame_rate][mode].width;
1103 ov5640_data.pix.height = ov5640_mode_info_data[frame_rate][mode].height;
1105 if (ov5640_data.pix.width == 0 || ov5640_data.pix.height == 0 ||
1106 pModeSetting == NULL || ArySize == 0)
1109 /* set ov5640 to subsampling mode */
1110 retval = ov5640_download_firmware(pModeSetting, ArySize);
1112 /* turn on AE AG for subsampling mode, in case the firmware didn't */
1113 ov5640_turn_on_AE_AG(1);
1115 /* calculate banding filter */
1116 ov5640_set_bandingfilter();
1119 ov5640_set_AE_target(AE_Target);
1121 /* update night mode setting */
1122 ov5640_set_night_mode(night_mode);
1124 /* skip 9 vysnc: start capture at 10th vsync */
1125 if (mode == ov5640_mode_XGA_1024_768 && frame_rate == ov5640_30_fps) {
1126 pr_warning("ov5640: actual frame rate of XGA is 22.5fps\n");
1132 if (frame_rate == ov5640_15_fps) {
1135 } else if (frame_rate == ov5640_30_fps) {
1143 /* change to scaling mode go through exposure calucation
1144 * image size above 1280 * 960 is scaling mode */
1145 static int ov5640_change_mode_exposure_calc(enum ov5640_frame_rate frame_rate,
1146 enum ov5640_mode mode)
1148 int prev_shutter, prev_gain16, average;
1149 int cap_shutter, cap_gain16;
1150 int cap_sysclk, cap_HTS, cap_VTS;
1151 int light_freq, cap_bandfilt, cap_maxband;
1152 long cap_gain16_shutter;
1154 struct reg_value *pModeSetting = NULL;
1158 /* check if the input mode and frame rate is valid */
1160 ov5640_mode_info_data[frame_rate][mode].init_data_ptr;
1162 ov5640_mode_info_data[frame_rate][mode].init_data_size;
1164 ov5640_data.pix.width =
1165 ov5640_mode_info_data[frame_rate][mode].width;
1166 ov5640_data.pix.height =
1167 ov5640_mode_info_data[frame_rate][mode].height;
1169 if (ov5640_data.pix.width == 0 || ov5640_data.pix.height == 0 ||
1170 pModeSetting == NULL || ArySize == 0)
1173 /* read preview shutter */
1174 prev_shutter = ov5640_get_shutter();
1176 /* read preview gain */
1177 prev_gain16 = ov5640_get_gain16();
1180 average = ov5640_read_reg(0x56a1, &temp);
1182 /* turn off night mode for capture */
1183 ov5640_set_night_mode(0);
1185 /* turn off overlay */
1186 ov5640_write_reg(0x3022, 0x06);
1188 /* Write capture setting */
1189 retval = ov5640_download_firmware(pModeSetting, ArySize);
1193 /* turn off AE AG when capture image. */
1194 ov5640_turn_on_AE_AG(0);
1196 /* read capture VTS */
1197 cap_VTS = ov5640_get_VTS();
1198 cap_HTS = ov5640_get_HTS();
1199 cap_sysclk = ov5640_get_sysclk();
1201 /* calculate capture banding filter */
1202 light_freq = ov5640_get_light_freq();
1203 if (light_freq == 60) {
1205 cap_bandfilt = cap_sysclk * 100 / cap_HTS * 100 / 120;
1208 cap_bandfilt = cap_sysclk * 100 / cap_HTS;
1210 cap_maxband = (int)((cap_VTS - 4)/cap_bandfilt);
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;
1218 cap_gain16_shutter =
1219 prev_gain16 * prev_shutter * cap_sysclk/prev_sysclk *
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)
1229 cap_gain16 = cap_gain16_shutter/cap_shutter;
1230 if (cap_gain16 < 16)
1233 if (cap_gain16_shutter > (cap_bandfilt*cap_maxband*16)) {
1234 /* exposure reach max */
1235 cap_shutter = cap_bandfilt*cap_maxband;
1236 cap_gain16 = cap_gain16_shutter / cap_shutter;
1238 /* 1/100 < cap_shutter =< max, cap_shutter = n/100 */
1240 ((int)(cap_gain16_shutter/16/cap_bandfilt))
1242 cap_gain16 = cap_gain16_shutter / cap_shutter;
1246 /* write capture gain */
1247 ov5640_set_gain16(cap_gain16);
1249 /* write capture shutter */
1250 if (cap_shutter > (cap_VTS - 4)) {
1251 cap_VTS = cap_shutter + 4;
1252 ov5640_set_VTS(cap_VTS);
1255 ov5640_set_shutter(cap_shutter);
1257 /* skip 2 vysnc: start capture at 3rd vsync
1258 * frame rate of QSXGA and 1080P is 7.5fps: 1/7.5 * 2
1260 pr_warning("ov5640: the actual frame rate of %s is 7.5fps\n",
1261 mode == ov5640_mode_1080P_1920_1080 ? "1080P" : "QSXGA");
1267 static int ov5640_change_mode(enum ov5640_frame_rate frame_rate,
1268 enum ov5640_mode mode)
1272 if (mode > ov5640_mode_MAX || mode < ov5640_mode_MIN) {
1273 pr_err("Wrong ov5640 mode detected!\n");
1277 if (mode == ov5640_mode_1080P_1920_1080 ||
1278 mode == ov5640_mode_QSXGA_2592_1944) {
1279 /* change to scaling mode go through exposure calucation
1280 * image size above 1280 * 960 is scaling mode */
1281 retval = ov5640_change_mode_exposure_calc(frame_rate, mode);
1283 /* change back to subsampling modem download firmware directly
1284 * image size below 1280 * 960 is subsampling mode */
1285 retval = ov5640_change_mode_direct(frame_rate, mode);
1291 /* --------------- IOCTL functions from v4l2_int_ioctl_desc --------------- */
1293 static int ioctl_g_ifparm(struct v4l2_int_device *s, struct v4l2_ifparm *p)
1296 pr_err(" ERROR!! no slave device set!\n");
1300 memset(p, 0, sizeof(*p));
1301 p->u.bt656.clock_curr = ov5640_data.mclk;
1302 pr_debug(" clock_curr=mclk=%d\n", ov5640_data.mclk);
1303 p->if_type = V4L2_IF_TYPE_BT656;
1304 p->u.bt656.mode = V4L2_IF_TYPE_BT656_MODE_NOBT_8BIT;
1305 p->u.bt656.clock_min = OV5640_XCLK_MIN;
1306 p->u.bt656.clock_max = OV5640_XCLK_MAX;
1307 p->u.bt656.bt_sync_correct = 1; /* Indicate external vsync */
1313 * ioctl_s_power - V4L2 sensor interface handler for VIDIOC_S_POWER ioctl
1314 * @s: pointer to standard V4L2 device structure
1315 * @on: indicates power mode (on or off)
1317 * Turns the power on or off, depending on the value of on and returns the
1318 * appropriate error code.
1320 static int ioctl_s_power(struct v4l2_int_device *s, int on)
1322 struct sensor_data *sensor = s->priv;
1324 if (on && !sensor->on) {
1326 if (regulator_enable(io_regulator) != 0)
1329 if (regulator_enable(core_regulator) != 0)
1331 if (analog_regulator)
1332 if (regulator_enable(analog_regulator) != 0)
1334 /* Make sure power on */
1335 ov5640_power_down(0);
1336 } else if (!on && sensor->on) {
1337 if (analog_regulator)
1338 regulator_disable(analog_regulator);
1340 regulator_disable(core_regulator);
1342 regulator_disable(io_regulator);
1344 ov5640_power_down(1);
1353 * ioctl_g_parm - V4L2 sensor interface handler for VIDIOC_G_PARM ioctl
1354 * @s: pointer to standard V4L2 device structure
1355 * @a: pointer to standard V4L2 VIDIOC_G_PARM ioctl structure
1357 * Returns the sensor's video CAPTURE parameters.
1359 static int ioctl_g_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
1361 struct sensor_data *sensor = s->priv;
1362 struct v4l2_captureparm *cparm = &a->parm.capture;
1366 /* This is the only case currently handled. */
1367 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1368 memset(a, 0, sizeof(*a));
1369 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1370 cparm->capability = sensor->streamcap.capability;
1371 cparm->timeperframe = sensor->streamcap.timeperframe;
1372 cparm->capturemode = sensor->streamcap.capturemode;
1376 /* These are all the possible cases. */
1377 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
1378 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1379 case V4L2_BUF_TYPE_VBI_CAPTURE:
1380 case V4L2_BUF_TYPE_VBI_OUTPUT:
1381 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
1382 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
1387 pr_debug(" type is unknown - %d\n", a->type);
1396 * ioctl_s_parm - V4L2 sensor interface handler for VIDIOC_S_PARM ioctl
1397 * @s: pointer to standard V4L2 device structure
1398 * @a: pointer to standard V4L2 VIDIOC_S_PARM ioctl structure
1400 * Configures the sensor to use the input parameters, if possible. If
1401 * not possible, reverts to the old parameters and returns the
1402 * appropriate error code.
1404 static int ioctl_s_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
1406 struct sensor_data *sensor = s->priv;
1407 struct v4l2_fract *timeperframe = &a->parm.capture.timeperframe;
1408 u32 tgt_fps; /* target frames per secound */
1409 enum ov5640_frame_rate frame_rate;
1412 /* Make sure power on */
1413 ov5640_power_down(0);
1416 /* This is the only case currently handled. */
1417 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1418 /* Check that the new frame rate is allowed. */
1419 if ((timeperframe->numerator == 0) ||
1420 (timeperframe->denominator == 0)) {
1421 timeperframe->denominator = DEFAULT_FPS;
1422 timeperframe->numerator = 1;
1425 tgt_fps = timeperframe->denominator /
1426 timeperframe->numerator;
1428 if (tgt_fps > MAX_FPS) {
1429 timeperframe->denominator = MAX_FPS;
1430 timeperframe->numerator = 1;
1431 } else if (tgt_fps < MIN_FPS) {
1432 timeperframe->denominator = MIN_FPS;
1433 timeperframe->numerator = 1;
1436 /* Actual frame rate we use */
1437 tgt_fps = timeperframe->denominator /
1438 timeperframe->numerator;
1441 frame_rate = ov5640_15_fps;
1442 else if (tgt_fps == 30)
1443 frame_rate = ov5640_30_fps;
1445 pr_err(" The camera frame rate is not supported!\n");
1449 ret = ov5640_change_mode(frame_rate,
1450 a->parm.capture.capturemode);
1454 sensor->streamcap.timeperframe = *timeperframe;
1455 sensor->streamcap.capturemode = a->parm.capture.capturemode;
1459 /* These are all the possible cases. */
1460 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
1461 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1462 case V4L2_BUF_TYPE_VBI_CAPTURE:
1463 case V4L2_BUF_TYPE_VBI_OUTPUT:
1464 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
1465 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
1466 pr_debug(" type is not " \
1467 "V4L2_BUF_TYPE_VIDEO_CAPTURE but %d\n",
1473 pr_debug(" type is unknown - %d\n", a->type);
1482 * ioctl_g_fmt_cap - V4L2 sensor interface handler for ioctl_g_fmt_cap
1483 * @s: pointer to standard V4L2 device structure
1484 * @f: pointer to standard V4L2 v4l2_format structure
1486 * Returns the sensor's current pixel format in the v4l2_format
1489 static int ioctl_g_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f)
1491 struct sensor_data *sensor = s->priv;
1493 f->fmt.pix = sensor->pix;
1499 * ioctl_g_ctrl - V4L2 sensor interface handler for VIDIOC_G_CTRL ioctl
1500 * @s: pointer to standard V4L2 device structure
1501 * @vc: standard V4L2 VIDIOC_G_CTRL ioctl structure
1503 * If the requested control is supported, returns the control's current
1504 * value from the video_control[] array. Otherwise, returns -EINVAL
1505 * if the control is not supported.
1507 static int ioctl_g_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc)
1512 case V4L2_CID_BRIGHTNESS:
1513 vc->value = ov5640_data.brightness;
1516 vc->value = ov5640_data.hue;
1518 case V4L2_CID_CONTRAST:
1519 vc->value = ov5640_data.contrast;
1521 case V4L2_CID_SATURATION:
1522 vc->value = ov5640_data.saturation;
1524 case V4L2_CID_RED_BALANCE:
1525 vc->value = ov5640_data.red;
1527 case V4L2_CID_BLUE_BALANCE:
1528 vc->value = ov5640_data.blue;
1530 case V4L2_CID_EXPOSURE:
1531 vc->value = ov5640_data.ae_mode;
1541 * ioctl_s_ctrl - V4L2 sensor interface handler for VIDIOC_S_CTRL ioctl
1542 * @s: pointer to standard V4L2 device structure
1543 * @vc: standard V4L2 VIDIOC_S_CTRL ioctl structure
1545 * If the requested control is supported, sets the control's current
1546 * value in HW (and updates the video_control[] array). Otherwise,
1547 * returns -EINVAL if the control is not supported.
1549 static int ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc)
1553 pr_debug("In ov5640:ioctl_s_ctrl %d\n",
1557 case V4L2_CID_BRIGHTNESS:
1559 case V4L2_CID_CONTRAST:
1561 case V4L2_CID_SATURATION:
1565 case V4L2_CID_AUTO_WHITE_BALANCE:
1567 case V4L2_CID_DO_WHITE_BALANCE:
1569 case V4L2_CID_RED_BALANCE:
1571 case V4L2_CID_BLUE_BALANCE:
1573 case V4L2_CID_GAMMA:
1575 case V4L2_CID_EXPOSURE:
1577 case V4L2_CID_AUTOGAIN:
1581 case V4L2_CID_HFLIP:
1583 case V4L2_CID_VFLIP:
1594 * ioctl_enum_framesizes - V4L2 sensor interface handler for
1595 * VIDIOC_ENUM_FRAMESIZES ioctl
1596 * @s: pointer to standard V4L2 device structure
1597 * @fsize: standard V4L2 VIDIOC_ENUM_FRAMESIZES ioctl structure
1599 * Return 0 if successful, otherwise -EINVAL.
1601 static int ioctl_enum_framesizes(struct v4l2_int_device *s,
1602 struct v4l2_frmsizeenum *fsize)
1604 if (fsize->index > ov5640_mode_MAX)
1607 fsize->pixel_format = ov5640_data.pix.pixelformat;
1608 fsize->discrete.width =
1609 max(ov5640_mode_info_data[0][fsize->index].width,
1610 ov5640_mode_info_data[1][fsize->index].width);
1611 fsize->discrete.height =
1612 max(ov5640_mode_info_data[0][fsize->index].height,
1613 ov5640_mode_info_data[1][fsize->index].height);
1618 * ioctl_enum_frameintervals - V4L2 sensor interface handler for
1619 * VIDIOC_ENUM_FRAMEINTERVALS ioctl
1620 * @s: pointer to standard V4L2 device structure
1621 * @fival: standard V4L2 VIDIOC_ENUM_FRAMEINTERVALS ioctl structure
1623 * Return 0 if successful, otherwise -EINVAL.
1625 static int ioctl_enum_frameintervals(struct v4l2_int_device *s,
1626 struct v4l2_frmivalenum *fival)
1630 if (fival->index < 0 || fival->index > ov5640_mode_MAX)
1633 if (fival->width == 0 || fival->height == 0 ||
1634 fival->pixel_format == 0) {
1635 pr_warning("Please assign pixelformat, width and height.\n");
1639 fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
1640 fival->discrete.numerator = 1;
1643 for (i = 0; i < ARRAY_SIZE(ov5640_mode_info_data); i++) {
1644 for (j = 0; j < (ov5640_mode_MAX + 1); j++) {
1645 if (fival->pixel_format == ov5640_data.pix.pixelformat
1646 && fival->width == ov5640_mode_info_data[i][j].width
1647 && fival->height == ov5640_mode_info_data[i][j].height
1648 && ov5640_mode_info_data[i][j].init_data_ptr != NULL) {
1651 if (fival->index == (count - 1)) {
1652 fival->discrete.denominator =
1653 ov5640_framerates[i];
1663 * ioctl_g_chip_ident - V4L2 sensor interface handler for
1664 * VIDIOC_DBG_G_CHIP_IDENT ioctl
1665 * @s: pointer to standard V4L2 device structure
1666 * @id: pointer to int
1670 static int ioctl_g_chip_ident(struct v4l2_int_device *s, int *id)
1672 ((struct v4l2_dbg_chip_ident *)id)->match.type =
1673 V4L2_CHIP_MATCH_I2C_DRIVER;
1674 strcpy(((struct v4l2_dbg_chip_ident *)id)->match.name, "ov5640_camera");
1680 * ioctl_init - V4L2 sensor interface handler for VIDIOC_INT_INIT
1681 * @s: pointer to standard V4L2 device structure
1683 static int ioctl_init(struct v4l2_int_device *s)
1690 * ioctl_enum_fmt_cap - V4L2 sensor interface handler for VIDIOC_ENUM_FMT
1691 * @s: pointer to standard V4L2 device structure
1692 * @fmt: pointer to standard V4L2 fmt description structure
1696 static int ioctl_enum_fmt_cap(struct v4l2_int_device *s,
1697 struct v4l2_fmtdesc *fmt)
1699 if (fmt->index > ov5640_mode_MAX)
1702 fmt->pixelformat = ov5640_data.pix.pixelformat;
1708 * ioctl_dev_init - V4L2 sensor interface handler for vidioc_int_dev_init_num
1709 * @s: pointer to standard V4L2 device structure
1711 * Initialise the device when slave attaches to the master.
1713 static int ioctl_dev_init(struct v4l2_int_device *s)
1715 struct sensor_data *sensor = s->priv;
1716 u32 tgt_xclk; /* target xclk */
1717 u32 tgt_fps; /* target frames per secound */
1718 enum ov5640_frame_rate frame_rate;
1721 ov5640_data.on = true;
1724 tgt_xclk = ov5640_data.mclk;
1725 tgt_xclk = min(tgt_xclk, (u32)OV5640_XCLK_MAX);
1726 tgt_xclk = max(tgt_xclk, (u32)OV5640_XCLK_MIN);
1727 ov5640_data.mclk = tgt_xclk;
1729 pr_debug(" Setting mclk to %d MHz\n", tgt_xclk / 1000000);
1730 clk_set_rate(ov5640_data.sensor_clk, ov5640_data.mclk);
1732 /* Default camera frame rate is set in probe */
1733 tgt_fps = sensor->streamcap.timeperframe.denominator /
1734 sensor->streamcap.timeperframe.numerator;
1737 frame_rate = ov5640_15_fps;
1738 else if (tgt_fps == 30)
1739 frame_rate = ov5640_30_fps;
1741 return -EINVAL; /* Only support 15fps or 30fps now. */
1743 ret = ov5640_init_mode();
1748 * ioctl_dev_exit - V4L2 sensor interface handler for vidioc_int_dev_exit_num
1749 * @s: pointer to standard V4L2 device structure
1751 * Delinitialise the device when slave detaches to the master.
1753 static int ioctl_dev_exit(struct v4l2_int_device *s)
1759 * This structure defines all the ioctls for this module and links them to the
1762 static struct v4l2_int_ioctl_desc ov5640_ioctl_desc[] = {
1763 { vidioc_int_dev_init_num,
1764 (v4l2_int_ioctl_func *)ioctl_dev_init },
1765 { vidioc_int_dev_exit_num,
1767 { vidioc_int_s_power_num,
1768 (v4l2_int_ioctl_func *)ioctl_s_power },
1769 { vidioc_int_g_ifparm_num,
1770 (v4l2_int_ioctl_func *)ioctl_g_ifparm },
1771 { vidioc_int_init_num,
1772 (v4l2_int_ioctl_func *)ioctl_init },
1773 { vidioc_int_enum_fmt_cap_num,
1774 (v4l2_int_ioctl_func *)ioctl_enum_fmt_cap },
1775 { vidioc_int_g_fmt_cap_num,
1776 (v4l2_int_ioctl_func *)ioctl_g_fmt_cap },
1777 { vidioc_int_g_parm_num,
1778 (v4l2_int_ioctl_func *)ioctl_g_parm },
1779 { vidioc_int_s_parm_num,
1780 (v4l2_int_ioctl_func *)ioctl_s_parm },
1781 { vidioc_int_g_ctrl_num,
1782 (v4l2_int_ioctl_func *)ioctl_g_ctrl },
1783 { vidioc_int_s_ctrl_num,
1784 (v4l2_int_ioctl_func *)ioctl_s_ctrl },
1785 { vidioc_int_enum_framesizes_num,
1786 (v4l2_int_ioctl_func *)ioctl_enum_framesizes },
1787 { vidioc_int_enum_frameintervals_num,
1788 (v4l2_int_ioctl_func *)ioctl_enum_frameintervals },
1789 { vidioc_int_g_chip_ident_num,
1790 (v4l2_int_ioctl_func *)ioctl_g_chip_ident },
1793 static struct v4l2_int_slave ov5640_slave = {
1794 .ioctls = ov5640_ioctl_desc,
1795 .num_ioctls = ARRAY_SIZE(ov5640_ioctl_desc),
1798 static struct v4l2_int_device ov5640_int_device = {
1799 .module = THIS_MODULE,
1801 .type = v4l2_int_type_slave,
1803 .slave = &ov5640_slave,
1808 * ov5640 I2C probe function
1810 * @param adapter struct i2c_adapter *
1811 * @return Error code indicating success or failure
1813 static int ov5640_probe(struct i2c_client *client,
1814 const struct i2c_device_id *id)
1816 struct pinctrl *pinctrl;
1817 struct device *dev = &client->dev;
1819 u8 chip_id_high, chip_id_low;
1821 /* ov5640 pinctrl */
1822 pinctrl = devm_pinctrl_get_select_default(dev);
1823 if (IS_ERR(pinctrl)) {
1824 dev_err(dev, "setup pinctrl failed\n");
1825 return PTR_ERR(pinctrl);
1828 /* request power down pin */
1829 pwn_gpio = of_get_named_gpio(dev->of_node, "pwn-gpios", 0);
1830 if (!gpio_is_valid(pwn_gpio)) {
1831 dev_err(dev, "no sensor pwdn pin available\n");
1834 retval = devm_gpio_request_one(dev, pwn_gpio, GPIOF_OUT_INIT_HIGH,
1839 /* request reset pin */
1840 rst_gpio = of_get_named_gpio(dev->of_node, "rst-gpios", 0);
1841 if (!gpio_is_valid(rst_gpio)) {
1842 dev_err(dev, "no sensor reset pin available\n");
1845 retval = devm_gpio_request_one(dev, rst_gpio, GPIOF_OUT_INIT_HIGH,
1850 /* Set initial values for the sensor struct. */
1851 memset(&ov5640_data, 0, sizeof(ov5640_data));
1852 ov5640_data.sensor_clk = devm_clk_get(dev, "csi_mclk");
1853 if (IS_ERR(ov5640_data.sensor_clk)) {
1854 dev_err(dev, "get mclk failed\n");
1855 return PTR_ERR(ov5640_data.sensor_clk);
1858 retval = of_property_read_u32(dev->of_node, "mclk",
1861 dev_err(dev, "mclk frequency is invalid\n");
1865 retval = of_property_read_u32(dev->of_node, "mclk_source",
1866 (u32 *) &(ov5640_data.mclk_source));
1868 dev_err(dev, "mclk_source invalid\n");
1872 retval = of_property_read_u32(dev->of_node, "csi_id",
1873 &(ov5640_data.csi));
1875 dev_err(dev, "csi_id invalid\n");
1879 clk_prepare_enable(ov5640_data.sensor_clk);
1881 ov5640_data.io_init = ov5640_reset;
1882 ov5640_data.i2c_client = client;
1883 ov5640_data.pix.pixelformat = V4L2_PIX_FMT_YUYV;
1884 ov5640_data.pix.width = 640;
1885 ov5640_data.pix.height = 480;
1886 ov5640_data.streamcap.capability = V4L2_MODE_HIGHQUALITY |
1887 V4L2_CAP_TIMEPERFRAME;
1888 ov5640_data.streamcap.capturemode = 0;
1889 ov5640_data.streamcap.timeperframe.denominator = DEFAULT_FPS;
1890 ov5640_data.streamcap.timeperframe.numerator = 1;
1892 ov5640_regulator_enable(&client->dev);
1896 ov5640_power_down(0);
1898 retval = ov5640_read_reg(OV5640_CHIP_ID_HIGH_BYTE, &chip_id_high);
1899 if (retval < 0 || chip_id_high != 0x56) {
1900 clk_disable_unprepare(ov5640_data.sensor_clk);
1901 pr_warning("camera ov5640 is not found\n");
1904 retval = ov5640_read_reg(OV5640_CHIP_ID_LOW_BYTE, &chip_id_low);
1905 if (retval < 0 || chip_id_low != 0x40) {
1906 clk_disable_unprepare(ov5640_data.sensor_clk);
1907 pr_warning("camera ov5640 is not found\n");
1911 ov5640_power_down(1);
1913 clk_disable_unprepare(ov5640_data.sensor_clk);
1915 ov5640_int_device.priv = &ov5640_data;
1916 retval = v4l2_int_device_register(&ov5640_int_device);
1918 pr_info("camera ov5640 is found\n");
1923 * ov5640 I2C detach function
1925 * @param client struct i2c_client *
1926 * @return Error code indicating success or failure
1928 static int ov5640_remove(struct i2c_client *client)
1930 v4l2_int_device_unregister(&ov5640_int_device);
1932 if (analog_regulator)
1933 regulator_disable(analog_regulator);
1936 regulator_disable(core_regulator);
1939 regulator_disable(io_regulator);
1944 module_i2c_driver(ov5640_i2c_driver);
1946 MODULE_AUTHOR("Freescale Semiconductor, Inc.");
1947 MODULE_DESCRIPTION("OV5640 Camera Driver");
1948 MODULE_LICENSE("GPL");
1949 MODULE_VERSION("1.0");
1950 MODULE_ALIAS("CSI");