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