2 * soc2030.c - soc2030 sensor driver
4 * Copyright (C) 2010 Google Inc.
7 * Rebecca Schultz Zavin <rebecca@android.com>
11 * This file is licensed under the terms of the GNU General Public License
12 * version 2. This program is licensed "as is" without any warranty of any
13 * kind, whether express or implied.
16 #include <linux/delay.h>
18 #include <linux/i2c.h>
19 #include <linux/miscdevice.h>
20 #include <linux/slab.h>
21 #include <linux/mutex.h>
22 #include <linux/uaccess.h>
23 #include <media/soc2030.h>
28 struct i2c_client *i2c_client;
29 struct soc2030_platform_data *pdata;
39 #define INDEX_12FPS 10
40 #define INDEX_11FPS 11
41 #define INDEX_10FPS 12
44 * SetMode Sequence for 1600X1200/800X600 base settings.
45 * Phase 0. Sensor Dependent.
46 * This sequence should set sensor for Full/Qtr res
47 * This is usually given by the FAE or the sensor vendor.
48 * 1600X1200 15fps (Max), 800X600 30fps (Max)
50 static struct soc2030_regs base_mode[] = {
51 {WRITE_REG_DATA, 0x98C, 0x2703}, /*Output Width (A)*/
52 {WRITE_REG_DATA, 0x990, 0x0320}, /* = 800*/
53 {WRITE_REG_DATA, 0x98C, 0x2705}, /*Output Height (A)*/
54 {WRITE_REG_DATA, 0x990, 0x0258}, /* = 600*/
55 {WRITE_REG_DATA, 0x98C, 0x2707}, /*Output Width (B)*/
56 {WRITE_REG_DATA, 0x990, 0x0640}, /* = 1600*/
57 {WRITE_REG_DATA, 0x98C, 0x2709}, /*Output Height (B)*/
58 {WRITE_REG_DATA, 0x990, 0x04B0}, /* = 1200*/
59 {WRITE_REG_DATA, 0x98C, 0x270D}, /*Row Start (A)*/
60 {WRITE_REG_DATA, 0x990, 0x0000}, /* = 0*/
61 {WRITE_REG_DATA, 0x98C, 0x270F}, /*Column Start (A)*/
62 {WRITE_REG_DATA, 0x990, 0x0000}, /* = 0*/
63 {WRITE_REG_DATA, 0x98C, 0x2711}, /*Row End (A)*/
64 {WRITE_REG_DATA, 0x990, 0x04BD}, /* = 1213*/
65 {WRITE_REG_DATA, 0x98C, 0x2713}, /*Column End (A)*/
66 {WRITE_REG_DATA, 0x990, 0x064D}, /* = 1613*/
67 {WRITE_REG_DATA, 0x98C, 0x2715}, /*Row Speed (A)*/
68 {WRITE_REG_DATA, 0x990, 0x0111}, /* = 273*/
69 {WRITE_REG_DATA, 0x98C, 0x2717}, /*Read Mode (A)*/
70 {WRITE_REG_DATA, 0x990, 0x046C}, /* = 1132*/
71 {WRITE_REG_DATA, 0x98C, 0x2719}, /*fine_corr (A)*/
72 {WRITE_REG_DATA, 0x990, 0x005A}, /* = 90*/
73 {WRITE_REG_DATA, 0x98C, 0x271B}, /*sensor_fine_IT_min (A)*/
74 {WRITE_REG_DATA, 0x990, 0x01BE}, /* = 446*/
75 {WRITE_REG_DATA, 0x98C, 0x271D}, /*fine_IT_max_mrgn (A)*/
76 {WRITE_REG_DATA, 0x990, 0x0131}, /* = 305*/
77 {WRITE_REG_DATA, 0x98C, 0x271F}, /*Frame Lines (A)*/
78 {WRITE_REG_DATA, 0x990, 0x02B3}, /* = 691*/
79 {WRITE_REG_DATA, 0x98C, 0x2721}, /*Line Length (A)*/
80 {WRITE_REG_DATA, 0x990, 0x07EA}, /* = 2026*/
81 {WRITE_REG_DATA, 0x98C, 0x2723}, /*Row Start (B)*/
82 {WRITE_REG_DATA, 0x990, 0x0004}, /* = 4*/
83 {WRITE_REG_DATA, 0x98C, 0x2725}, /*Column Start (B)*/
84 {WRITE_REG_DATA, 0x990, 0x0004}, /* = 4*/
85 {WRITE_REG_DATA, 0x98C, 0x2727}, /*Row End (B)*/
86 {WRITE_REG_DATA, 0x990, 0x04BB}, /* = 1211*/
87 {WRITE_REG_DATA, 0x98C, 0x2729}, /*Column End (B)*/
88 {WRITE_REG_DATA, 0x990, 0x064B}, /* = 1611*/
89 {WRITE_REG_DATA, 0x98C, 0x272B}, /*Row Speed (B)*/
90 {WRITE_REG_DATA, 0x990, 0x0111}, /* = 273*/
91 {WRITE_REG_DATA, 0x98C, 0x272D}, /*Read Mode (B)*/
92 {WRITE_REG_DATA, 0x990, 0x0024}, /* = 36*/
93 {WRITE_REG_DATA, 0x98C, 0x272F}, /*sfine_corr (B)*/
94 {WRITE_REG_DATA, 0x990, 0x003A}, /* = 58*/
95 {WRITE_REG_DATA, 0x98C, 0x2731}, /*fine_IT_min (B)*/
96 {WRITE_REG_DATA, 0x990, 0x00F6}, /* = 246*/
97 {WRITE_REG_DATA, 0x98C, 0x2733}, /*fine_IT_max_mrgn (B)*/
98 {WRITE_REG_DATA, 0x990, 0x008B}, /* = 139*/
99 {WRITE_REG_DATA, 0x98C, 0x2735}, /*Frame Lines (B)*/
100 {WRITE_REG_DATA, 0x990, 0x050D}, /* = 1293*/
101 {WRITE_REG_DATA, 0x98C, 0x2737}, /*Line Length (B)*/
102 {WRITE_REG_DATA, 0x990, 0x08A9}, /* = 2217*/
103 {WRITE_REG_DATA, 0x98C, 0x2739}, /*Crop_X0 (A)*/
104 {WRITE_REG_DATA, 0x990, 0x0000}, /* = 0*/
105 {WRITE_REG_DATA, 0x98C, 0x273B}, /*Crop_X1 (A)*/
106 {WRITE_REG_DATA, 0x990, 0x031F}, /* = 799*/
107 {WRITE_REG_DATA, 0x98C, 0x273D}, /*Crop_Y0 (A)*/
108 {WRITE_REG_DATA, 0x990, 0x0000}, /* = 0*/
109 {WRITE_REG_DATA, 0x98C, 0x273F}, /*Crop_Y1 (A)*/
110 {WRITE_REG_DATA, 0x990, 0x0257}, /* = 599*/
111 {WRITE_REG_DATA, 0x98C, 0x2747}, /*Crop_X0 (B)*/
112 {WRITE_REG_DATA, 0x990, 0x0000}, /* = 0*/
113 {WRITE_REG_DATA, 0x98C, 0x2749}, /*Crop_X1 (B)*/
114 {WRITE_REG_DATA, 0x990, 0x063F}, /* = 1599*/
115 {WRITE_REG_DATA, 0x98C, 0x274B}, /*Crop_Y0 (B)*/
116 {WRITE_REG_DATA, 0x990, 0x0000}, /* = 0*/
117 {WRITE_REG_DATA, 0x98C, 0x274D}, /*Crop_Y1 (B)*/
118 {WRITE_REG_DATA, 0x990, 0x04AF}, /* = 1199*/
119 {WRITE_REG_DATA, 0x98C, 0x222D}, /*R9 Step*/
120 {WRITE_REG_DATA, 0x990, 0x00AD}, /* = 173*/
121 {WRITE_REG_DATA, 0x98C, 0xA408}, /*search_f1_50*/
122 {WRITE_REG_DATA, 0x990, 0x002A}, /* = 42*/
123 {WRITE_REG_DATA, 0x98C, 0xA409}, /*search_f2_50*/
124 {WRITE_REG_DATA, 0x990, 0x002C}, /* = 44*/
125 {WRITE_REG_DATA, 0x98C, 0xA40A}, /*search_f1_60*/
126 {WRITE_REG_DATA, 0x990, 0x0032}, /* = 50*/
127 {WRITE_REG_DATA, 0x98C, 0xA40B}, /*search_f2_60*/
128 {WRITE_REG_DATA, 0x990, 0x0034}, /* = 52*/
129 {WRITE_REG_DATA, 0x98C, 0x2411}, /*R9_Step_60 (A)*/
130 {WRITE_REG_DATA, 0x990, 0x00AD}, /* = 173*/
131 {WRITE_REG_DATA, 0x98C, 0x2413}, /*R9_Step_50 (A)*/
132 {WRITE_REG_DATA, 0x990, 0x00CF}, /* = 207*/
133 {WRITE_REG_DATA, 0x98C, 0x2415}, /*R9_Step_60 (B)*/
134 {WRITE_REG_DATA, 0x990, 0x009E}, /* = 158*/
135 {WRITE_REG_DATA, 0x98C, 0x2417}, /*R9_Step_50 (B)*/
136 {WRITE_REG_DATA, 0x990, 0x00BD}, /* = 189*/
137 {WRITE_REG_DATA, 0x98C, 0xA404}, /*FD Mode*/
138 {WRITE_REG_DATA, 0x990, 0x0010}, /* = 16*/
139 {WRITE_REG_DATA, 0x98C, 0xA40D}, /*Stat_min*/
140 {WRITE_REG_DATA, 0x990, 0x0002}, /* = 2*/
141 {WRITE_REG_DATA, 0x98C, 0xA40E}, /*Stat_max*/
142 {WRITE_REG_DATA, 0x990, 0x0003}, /* = 3*/
143 {WRITE_REG_DATA, 0x98C, 0xA410}, /*Min_amplitude*/
144 {WRITE_REG_DATA, 0x990, 0x000A}, /* = 10*/
145 {REG_TABLE_END, 0x0000, 0x0000}
149 * Refresh Sequencer Mode
151 static struct soc2030_regs refresh_mode[] = {
152 {WRITE_REG_DATA, 0x098C, 0xa103}, /* Refresh Mode */
153 {WRITE_REG_DATA, 0x0990, 0x0006},
154 {POLL_VAR_DATA, 0xa103, 0x0000},
155 {REG_TABLE_END, 0x0000, 0x0000}
159 * Refresh Sequencer State
161 static struct soc2030_regs refresh_state[] = {
162 {WRITE_REG_DATA, 0x098C, 0xa103}, /* Refresh Seq */
163 {WRITE_REG_DATA, 0x0990, 0x0005},
164 {POLL_VAR_DATA, 0xa103, 0x0000},
165 {REG_TABLE_END, 0x0000, 0x0000}
169 * SetMode Sequence for context A (800X600, preview).
170 * Phase 0. Sensor Dependent.
171 * This is usually given by the FAE or the sensor vendor.
174 static struct soc2030_regs mode_800x600[] = {
175 {WRITE_REG_DATA, 0x98C, 0x2703}, /*Output Width (A)*/
176 {WRITE_REG_DATA, 0x990, 0x0320}, /* = 800*/
177 {WRITE_REG_DATA, 0x98C, 0x2705}, /*Output Height (A)*/
178 {WRITE_REG_DATA, 0x990, 0x0258}, /* = 600*/
179 {WRITE_REG_DATA, 0x98C, 0x270D}, /*Row Start (A)*/
180 {WRITE_REG_DATA, 0x990, 0x0000}, /* = 0*/
181 {WRITE_REG_DATA, 0x98C, 0x270F}, /*Column Start (A)*/
182 {WRITE_REG_DATA, 0x990, 0x0000}, /* = 0*/
183 {WRITE_REG_DATA, 0x98C, 0x2711}, /*Row End (A)*/
184 {WRITE_REG_DATA, 0x990, 0x04BD}, /* = 1213*/
185 {WRITE_REG_DATA, 0x98C, 0x2713}, /*Column End (A)*/
186 {WRITE_REG_DATA, 0x990, 0x064D}, /* = 1613*/
187 {WRITE_REG_DATA, 0x98C, 0x2715}, /*Row Speed (A)*/
188 {WRITE_REG_DATA, 0x990, 0x0111}, /* = 273*/
189 {WRITE_REG_DATA, 0x98C, 0x2717}, /*Read Mode (A)*/
190 {WRITE_REG_DATA, 0x990, 0x046C}, /* = 1132*/
191 {WRITE_REG_DATA, 0x98C, 0x2719}, /*fine_corr (A)*/
192 {WRITE_REG_DATA, 0x990, 0x005A}, /* = 90*/
193 {WRITE_REG_DATA, 0x98C, 0x271B}, /*_fine_IT_min (A)*/
194 {WRITE_REG_DATA, 0x990, 0x01BE}, /* = 446*/
195 {WRITE_REG_DATA, 0x98C, 0x271D}, /*fine_IT_max_mrgn (A)*/
196 {WRITE_REG_DATA, 0x990, 0x0131}, /* = 305*/
197 {WRITE_REG_DATA, 0x98C, 0x271F}, /*Frame Lines (A)*/
198 {WRITE_REG_DATA, 0x990, 0x02B3}, /* = 691*/
199 {WRITE_REG_DATA, 0x98C, 0x2721}, /*Line Length (A)*/
200 {WRITE_REG_DATA, 0x990, 0x07EA}, /* = 2026*/
201 {WRITE_REG_DATA, 0x98C, 0x2739}, /*Crop_X0 (A)*/
202 {WRITE_REG_DATA, 0x990, 0x0000}, /* = 0*/
203 {WRITE_REG_DATA, 0x98C, 0x273B}, /*Crop_X1 (A)*/
204 {WRITE_REG_DATA, 0x990, 0x031F}, /* = 799*/
205 {WRITE_REG_DATA, 0x98C, 0x273D}, /*Crop_Y0 (A)*/
206 {WRITE_REG_DATA, 0x990, 0x0000}, /* = 0*/
207 {WRITE_REG_DATA, 0x98C, 0x273F}, /*Crop_Y1 (A)*/
208 {WRITE_REG_DATA, 0x990, 0x0257}, /* = 599*/
209 {WRITE_REG_DATA, 0x98C, 0x222D}, /*R9 Step*/
210 {WRITE_REG_DATA, 0x990, 0x00AD}, /* = 173*/
211 {WRITE_REG_DATA, 0x98C, 0xA408}, /*search_f1_50*/
212 {WRITE_REG_DATA, 0x990, 0x002A}, /* = 42*/
213 {WRITE_REG_DATA, 0x98C, 0xA409}, /*search_f2_50*/
214 {WRITE_REG_DATA, 0x990, 0x002C}, /* = 44*/
215 {WRITE_REG_DATA, 0x98C, 0xA40A}, /*search_f1_60*/
216 {WRITE_REG_DATA, 0x990, 0x0032}, /* = 50*/
217 {WRITE_REG_DATA, 0x98C, 0xA40B}, /*search_f2_60*/
218 {WRITE_REG_DATA, 0x990, 0x0034}, /* = 52*/
219 {WRITE_REG_DATA, 0x98C, 0x2411}, /*R9_Step_60 (A)*/
220 {WRITE_REG_DATA, 0x990, 0x00AD}, /* = 173*/
221 {WRITE_REG_DATA, 0x98C, 0x2413}, /*R9_Step_50 (A)*/
222 {WRITE_REG_DATA, 0x990, 0x00CF}, /* = 207*/
223 {WRITE_REG_BIT_L, 0x3040, 0x1000}, /* Disable Bin Sum */
224 {WRITE_REG_DATA, 0x098C, 0xA215}, /* Fix FPS */
225 {WRITE_REG_DATA, 0x0990, INDEX_15FPS},
226 {WRITE_REG_DATA, 0x098C, 0xA20C}, /* AE_MAX_INDEX */
227 {WRITE_REG_DATA, 0x0990, INDEX_15FPS}, /* 15-30 FPS */
228 {WRITE_REG_DATA, 0x098C, 0xA115}, /* ISP off in cntx B */
229 {WRITE_REG_DATA, 0x0990, 0x0000},
230 {WRITE_REG_DATA, 0x098C, 0xA103}, /* Context A preview */
231 {WRITE_REG_DATA, 0x0990, 0x0001},
232 {POLL_VAR_DATA, 0xa104, 0x0003},
233 {REG_TABLE_END, 0x0000, 0x0000}
237 * SetMode Sequence for context B (1600X1200, capture).
238 * Phase 0. Sensor Dependent.
239 * This is usually given by the FAE or the sensor vendor.
242 static struct soc2030_regs mode_1600x1200[] = {
243 {WRITE_REG_DATA, 0x098C, 0xA215}, /* Fix FPS */
244 {WRITE_REG_DATA, 0x0990, INDEX_10FPS},
245 {WRITE_REG_DATA, 0x098C, 0xA20C}, /* AE_MAX_INDEX */
246 {WRITE_REG_DATA, 0x0990, INDEX_10FPS}, /* 10-15 fps */
247 {WRITE_REG_DATA, 0x098C, 0xA115}, /* ISP in Context B */
248 {WRITE_REG_DATA, 0x0990, 0x0072},
249 {WRITE_REG_DATA, 0x098C, 0xA103}, /* Context B full */
250 {WRITE_REG_DATA, 0x0990, 0x0002},
251 {POLL_VAR_DATA, 0xa104, 0x0007},
252 {POLL_VAR_DATA, 0xa103, 0x0000},
253 {REG_TABLE_END, 0x0000, 0x0000}
257 * SetMode Sequence for 720P in context A (1280X720).
258 * Phase 0. Sensor Dependent.
259 * This is usually given by the FAE or the sensor vendor.
262 static struct soc2030_regs mode_1280x720[] = {
263 {WRITE_REG_DATA, 0x98C, 0x2703}, /*Output Width (A)*/
264 {WRITE_REG_DATA, 0x990, 0x0500}, /* = 1280*/
265 {WRITE_REG_DATA, 0x98C, 0x2705}, /*Output Height (A)*/
266 {WRITE_REG_DATA, 0x990, 0x02D0}, /* = 720*/
267 {WRITE_REG_DATA, 0x98C, 0x270D}, /*Row Start (A)*/
268 {WRITE_REG_DATA, 0x990, 0x00F6}, /* = 246*/
269 {WRITE_REG_DATA, 0x98C, 0x270F}, /*Column Start (A)*/
270 {WRITE_REG_DATA, 0x990, 0x00A6}, /* = 166*/
271 {WRITE_REG_DATA, 0x98C, 0x2711}, /*Row End (A)*/
272 {WRITE_REG_DATA, 0x990, 0x03CD}, /* = 973*/
273 {WRITE_REG_DATA, 0x98C, 0x2713}, /*Column End (A)*/
274 {WRITE_REG_DATA, 0x990, 0x05AD}, /* = 1453*/
275 {WRITE_REG_DATA, 0x98C, 0x2715}, /*Row Speed (A)*/
276 {WRITE_REG_DATA, 0x990, 0x0111}, /* = 273*/
277 {WRITE_REG_DATA, 0x98C, 0x2717}, /*Read Mode (A)*/
278 {WRITE_REG_DATA, 0x990, 0x0024}, /* = 36*/
279 {WRITE_REG_DATA, 0x98C, 0x2719}, /*_fine_correction (A)*/
280 {WRITE_REG_DATA, 0x990, 0x003A}, /* = 58*/
281 {WRITE_REG_DATA, 0x98C, 0x271B}, /*fine_IT_min (A)*/
282 {WRITE_REG_DATA, 0x990, 0x00F6}, /* = 246*/
283 {WRITE_REG_DATA, 0x98C, 0x271D}, /*fine_IT_max_mrgn (A)*/
284 {WRITE_REG_DATA, 0x990, 0x008B}, /* = 139*/
285 {WRITE_REG_DATA, 0x98C, 0x271F}, /*Frame Lines (A)*/
286 {WRITE_REG_DATA, 0x990, 0x032D}, /* = 813*/
287 {WRITE_REG_DATA, 0x98C, 0x2721}, /*Line Length (A)*/
288 {WRITE_REG_DATA, 0x990, 0x06BA}, /* = 1722*/
289 {WRITE_REG_DATA, 0x98C, 0x2739}, /*Crop_X0 (A)*/
290 {WRITE_REG_DATA, 0x990, 0x0000}, /* = 0*/
291 {WRITE_REG_DATA, 0x98C, 0x273B}, /*Crop_X1 (A)*/
292 {WRITE_REG_DATA, 0x990, 0x04FF}, /* = 1279*/
293 {WRITE_REG_DATA, 0x98C, 0x273D}, /*Crop_Y0 (A)*/
294 {WRITE_REG_DATA, 0x990, 0x0000}, /* = 0*/
295 {WRITE_REG_DATA, 0x98C, 0x273F}, /*Crop_Y1 (A)*/
296 {WRITE_REG_DATA, 0x990, 0x02CF}, /* = 719*/
297 {WRITE_REG_DATA, 0x98C, 0x2747}, /*Crop_X0 (B)*/
298 {WRITE_REG_DATA, 0x990, 0x0000}, /* = 0*/
299 {WRITE_REG_DATA, 0x98C, 0x2749}, /*Crop_X1 (B)*/
300 {WRITE_REG_DATA, 0x990, 0x063F}, /* = 1599*/
301 {WRITE_REG_DATA, 0x98C, 0x274B}, /*Crop_Y0 (B)*/
302 {WRITE_REG_DATA, 0x990, 0x0000}, /* = 0*/
303 {WRITE_REG_DATA, 0x98C, 0x274D}, /*Crop_Y1 (B)*/
304 {WRITE_REG_DATA, 0x990, 0x04AF}, /* = 1199*/
305 {WRITE_REG_DATA, 0x98C, 0x222D}, /*R9 Step*/
306 {WRITE_REG_DATA, 0x990, 0x00CB}, /* = 203*/
307 {WRITE_REG_DATA, 0x98C, 0xA408}, /*search_f1_50*/
308 {WRITE_REG_DATA, 0x990, 0x0031}, /* = 49*/
309 {WRITE_REG_DATA, 0x98C, 0xA409}, /*search_f2_50*/
310 {WRITE_REG_DATA, 0x990, 0x0033}, /* = 51*/
311 {WRITE_REG_DATA, 0x98C, 0xA40A}, /*search_f1_60*/
312 {WRITE_REG_DATA, 0x990, 0x003C}, /* = 60*/
313 {WRITE_REG_DATA, 0x98C, 0xA40B}, /*search_f2_60*/
314 {WRITE_REG_DATA, 0x990, 0x003E}, /* = 62*/
315 {WRITE_REG_DATA, 0x98C, 0x2411}, /*R9_Step_60 (A)*/
316 {WRITE_REG_DATA, 0x990, 0x00CB}, /* = 203*/
317 {WRITE_REG_DATA, 0x98C, 0x2413}, /*R9_Step_50 (A)*/
318 {WRITE_REG_DATA, 0x990, 0x00F4}, /* = 244*/
319 {WRITE_REG_DATA, 0x98C, 0xA404}, /*FD Mode*/
320 {WRITE_REG_DATA, 0x990, 0x0010}, /* = 16*/
321 {WRITE_REG_DATA, 0x98C, 0xA40D}, /*Stat_min*/
322 {WRITE_REG_DATA, 0x990, 0x0002}, /* = 2*/
323 {WRITE_REG_DATA, 0x98C, 0xA40E}, /*Stat_max*/
324 {WRITE_REG_DATA, 0x990, 0x0003}, /* = 3*/
325 {WRITE_REG_DATA, 0x98C, 0xA410}, /*Min_amplitude*/
326 {WRITE_REG_DATA, 0x990, 0x000A}, /* = 10*/
327 {WRITE_REG_BIT_H, 0x3040, 0x1000}, /* Enable Bin Summing */
328 {WRITE_REG_DATA, 0x098C, 0xA215}, /* Fix FPS */
329 {WRITE_REG_DATA, 0x0990, INDEX_15FPS},
330 {WRITE_REG_DATA, 0x098C, 0xA20C}, /* AE_MAX_INDEX */
331 {WRITE_REG_DATA, 0x0990, INDEX_15FPS}, /* 15-30 FPS */
332 {WRITE_REG_DATA, 0x098C, 0xA115}, /* ISP off in cntx B */
333 {WRITE_REG_DATA, 0x0990, 0x0000},
334 {WRITE_REG_DATA, 0x098C, 0xA103}, /* Context A preview */
335 {WRITE_REG_DATA, 0x0990, 0x0001},
336 {POLL_VAR_DATA, 0xa104, 0x0003},
337 {REG_TABLE_END, 0x0000, 0x0000}
341 * SetMode Sequence for PLL. Phase 0. Sensor Dependent.
342 * This sequence should configure the PLL.
343 * This is usually given by the FAE or the sensor vendor.
346 static struct soc2030_regs pll_table[] = {
347 {WRITE_REG_DATA, 0x001e, 0x0503}, /*Pad Slew rate*/
348 {WRITE_REG_DATA, 0x0014, 0x2545}, /*PLL_CONTROL*/
349 {WRITE_REG_DATA, 0x0010, 0x0a56}, /*PLL_DIVIDERS 43mhz*/
350 {WRITE_REG_DATA, 0x0012, 0x10F7}, /*PLL_P_DIVIDERS*/
351 {WRITE_REG_DATA, 0x0014, 0x2547}, /*PLL_CONTROL*/
352 {WRITE_REG_DATA, 0x0014, 0x2447}, /*PLL_CONTROL*/
353 {DELAY_MS, 0x0000, 0x0010}, /*wait for pll lck*/
354 {WRITE_REG_DATA, 0x0014, 0x2047}, /*PLL_CONTROL*/
355 {WRITE_REG_BIT_L, 0x0014, 0x0001}, /*enable the pll*/
356 {WRITE_REG_BIT_H, 0x001a, 0x0200}, /*en parallel out*/
357 {WRITE_REG_BIT_L, 0x001a, 0x0004}, /*disable mipi*/
358 {WRITE_REG_BIT_H, 0x0018, 0x0004}, /*disable mcu*/
359 {WRITE_REG_BIT_L, 0x0018, 0x0001}, /*leave standby*/
360 {POLL_REG_BIT_L, 0x0018, 0x4000}, /*wait for !stdby*/
361 {WRITE_REG_DATA, 0x321C, 0x0000}, /*By Pass TxFIFO = 0*/
362 {REG_TABLE_END, 0x0000, 0x0000}
366 * SetMode Sequence for errata. Phase 0. Sensor Dependent.
367 * This is usually given by the FAE or the sensor vendor.
369 static struct soc2030_regs WakeMcuSequence[] = {
370 {WRITE_VAR_DATA, 0x2755, 0x0200}, /*Invert Pclk*/
371 {WRITE_VAR_DATA, 0x2757, 0x0200}, /*Invert Pclk*/
372 {WRITE_REG_BIT_L, 0x0018, 0x0004}, /*enable the MCU*/
373 {POLL_VAR_DATA, 0xa104, 0x0003}, /*wait for preview*/
374 {POLL_REG_BIT_L, 0x0018, 0x4000}, /*wait for !stdby*/
375 {REG_TABLE_END, 0x0000, 0x0000}
379 * SetMode Sequence for errata. Phase 0. Sensor Dependent.
380 * This is usually given by the FAE or the sensor vendor.
382 static struct soc2030_regs SetRev2ErrataSequence[] = {
383 {WRITE_REG_DATA, 0x3084, 0x240C},
384 {WRITE_REG_DATA, 0x3092, 0x0A4C},
385 {WRITE_REG_DATA, 0x3094, 0x4C4C},
386 {WRITE_REG_DATA, 0x3096, 0x4C54},
387 {REG_TABLE_END, 0x0000, 0x0000}
393 * SetMode Sequence for LCC. Phase 0. Sensor Dependent.
394 * This is usually given by the FAE or the sensor vendor.
396 static struct soc2030_regs SetLensCorrectionSequence[] = {
397 {WRITE_REG_DATA, 0x3210, 0x01B8}, /*Enable gamma/sharpen/ccm/LC*/
398 {REG_TABLE_END, 0x0000, 0x0000}
402 * SetMode Sequence for low light. Phase 0. Sensor Dependent.
403 * This is usually given by the FAE or the sensor vendor.
405 static struct soc2030_regs SetLowLightSequence[] = {
406 {WRITE_REG_DATA, 0x098C, 0x2B28}, /*MCU_ADDRESS[HG_LL_BRTNSTRT]*/
407 {WRITE_REG_DATA, 0x0990, 0x35E8}, /*MCU_DATA_0*/
408 {WRITE_REG_DATA, 0x098C, 0x2B2A}, /*MCU_ADDRESS [HG_LL_BRTNSSTP]*/
409 {WRITE_REG_DATA, 0x0990, 0xB3B0}, /*MCU_DATA_0*/
410 {WRITE_REG_DATA, 0x098C, 0xAB20}, /*MCU_ADDRESS [HG_LL_SAT1]*/
411 {WRITE_REG_DATA, 0x0990, 0x004B}, /*MCU_DATA_0*/
412 {WRITE_REG_DATA, 0x098C, 0xAB24}, /*MCU_ADDRESS [HG_LL_SAT2]*/
413 {WRITE_REG_DATA, 0x0990, 0x0000}, /*MCU_DATA_0*/
414 {WRITE_REG_DATA, 0x098C, 0xAB25}, /*MCU_ADDRESS[HG_LL_INTRPTHR2]*/
415 {WRITE_REG_DATA, 0x0990, 0x00FF}, /*MCU_DATA_0*/
416 {WRITE_REG_DATA, 0x098C, 0xAB30}, /*MCU_ADDRESS [HG_NR_STOP_R]*/
417 {WRITE_REG_DATA, 0x0990, 0x00FF}, /*MCU_DATA_0*/
418 {WRITE_REG_DATA, 0x098C, 0xAB31}, /*MCU_ADDRESS [HG_NR_STOP_G]*/
419 {WRITE_REG_DATA, 0x0990, 0x00FF}, /*MCU_DATA_0*/
420 {WRITE_REG_DATA, 0x098C, 0xAB32}, /*MCU_ADDRESS [HG_NR_STOP_B]*/
421 {WRITE_REG_DATA, 0x0990, 0x00FF}, /*MCU_DATA_0*/
422 {WRITE_REG_DATA, 0x098C, 0xAB33}, /*MCU_ADDRESS [HG_NR_STOP_OL]*/
423 {WRITE_REG_DATA, 0x0990, 0x0057}, /*MCU_DATA_0*/
424 {WRITE_REG_DATA, 0x098C, 0xAB34}, /*MCU_ADDRESS[HG_NR_GAINSTRT]*/
425 {WRITE_REG_DATA, 0x0990, 0x0080}, /*MCU_DATA_0*/
426 {WRITE_REG_DATA, 0x098C, 0xAB35}, /*MCU_ADDRESS [HG_NR_GAINSTP]*/
427 {WRITE_REG_DATA, 0x0990, 0x00FF}, /*MCU_DATA_0*/
428 {WRITE_REG_DATA, 0x098C, 0xAB36}, /*MCU_ADDRESS[HG_CLSTERDC_TH]*/
429 {WRITE_REG_DATA, 0x0990, 0x0014}, /*MCU_DATA_0*/
430 {WRITE_REG_DATA, 0x098C, 0xAB37}, /*MCU_ADDR[HG_GAMA_MORPH_CTRL]*/
431 {WRITE_REG_DATA, 0x0990, 0x0003}, /*MCU_DATA_0*/
432 {WRITE_REG_DATA, 0x098C, 0x2B38}, /*MCU_ADDR[HG_GAMASTARTMORPH]*/
433 {WRITE_REG_DATA, 0x0990, 0x32C8}, /*MCU_DATA_0*/
434 {WRITE_REG_DATA, 0x098C, 0x2B3A}, /*MCU_ADDRESS[HG_GAMASTPMORPH]*/
435 {WRITE_REG_DATA, 0x0990, 0x7918}, /*MCU_DATA_0*/
436 {WRITE_REG_DATA, 0x098C, 0x2B62}, /*MCU_ADDRESS[HG_FTB_STRT_BM]*/
437 {WRITE_REG_DATA, 0x0990, 0xFFFE}, /*MCU_DATA_0*/
438 {WRITE_REG_DATA, 0x098C, 0x2B64}, /*MCU_ADDRESS[HG_FTB_STP_BM]*/
439 {WRITE_REG_DATA, 0x0990, 0xFFFF}, /*MCU_DATA_0 {SEQ_END,0x0000}*/
440 {REG_TABLE_END, 0x0000, 0x0000}
444 * SetMode Sequence for CCM. Phase 0. Sensor Dependent.
445 * This is usually given by the FAE or the sensor vendor.
447 static struct soc2030_regs SetCCMCommonSequence[] = {
448 {WRITE_REG_DATA, 0x098c, 0xA11F}, /*turn on AWB in preview*/
449 {WRITE_REG_DATA, 0x0990, 0x0001},
450 {WRITE_REG_DATA, 0x098c, 0xA20B}, /*AE_MIN_INDEX*/
451 {WRITE_REG_DATA, 0x0990, 0x0000},
452 {WRITE_REG_DATA, 0x098C, 0xA215}, /* Fix FPS */
453 {WRITE_REG_DATA, 0x0990, INDEX_15FPS},
454 {WRITE_REG_DATA, 0x098C, 0xA20C}, /* AE_MAX_INDEX */
455 {WRITE_REG_DATA, 0x0990, INDEX_15FPS}, /* 15-30 FPS */
456 {REG_TABLE_END, 0x0000, 0x0000}
461 * SetMode Sequence for AWB. Phase 0. Sensor Dependent.
462 * Place your module specific tuning here.
463 * This is usually given by the FAE or the sensor vendor.
465 static struct soc2030_regs SetCCMAutoSequence[] = {
467 {REG_TABLE_END, 0x0000, 0x0000}
471 * SetMode Sequence for noise optimizations.
472 * Phase 0. Sensor Dependent.
473 * Place your module specific tuning here.
474 * This is usually given by the FAE or the sensor vendor.
476 static struct soc2030_regs SetDenoiseSequence[] = {
477 {REG_TABLE_END, 0x0000, 0x0000}
482 * SetMode Sequence for vendor's patch.
483 * Phase 0. Sensor Dependent.
484 * This is usually given by the FAE or the sensor vendor.
485 * K25A_REV03_PATCH01_REV3
487 static struct soc2030_regs SetRev3PatchSequence[] = {
488 {WRITE_REG_DATA, 0x098C, 0x0415}, /*MCU_ADDRESS*/
489 {WRITE_REG_DATA, 0x0990, 0xF601},
490 {WRITE_REG_DATA, 0x0992, 0x42C1},
491 {WRITE_REG_DATA, 0x0994, 0x0326},
492 {WRITE_REG_DATA, 0x0996, 0x11F6},
493 {WRITE_REG_DATA, 0x0998, 0x0143},
494 {WRITE_REG_DATA, 0x099A, 0xC104},
495 {WRITE_REG_DATA, 0x099C, 0x260A},
496 {WRITE_REG_DATA, 0x099E, 0xCC04},
497 {WRITE_REG_DATA, 0x098C, 0x0425}, /*MCU_ADDRESS*/
498 {WRITE_REG_DATA, 0x0990, 0x33BD},
499 {WRITE_REG_DATA, 0x0992, 0xA362},
500 {WRITE_REG_DATA, 0x0994, 0xBD04},
501 {WRITE_REG_DATA, 0x0996, 0x3339},
502 {WRITE_REG_DATA, 0x0998, 0xC6FF},
503 {WRITE_REG_DATA, 0x099A, 0xF701},
504 {WRITE_REG_DATA, 0x099C, 0x6439},
505 {WRITE_REG_DATA, 0x099E, 0xFE01},
506 {WRITE_REG_DATA, 0x098C, 0x0435}, /*MCU_ADDRESS*/
507 {WRITE_REG_DATA, 0x0990, 0x6918},
508 {WRITE_REG_DATA, 0x0992, 0xCE03},
509 {WRITE_REG_DATA, 0x0994, 0x25CC},
510 {WRITE_REG_DATA, 0x0996, 0x0013},
511 {WRITE_REG_DATA, 0x0998, 0xBDC2},
512 {WRITE_REG_DATA, 0x099A, 0xB8CC},
513 {WRITE_REG_DATA, 0x099C, 0x0489},
514 {WRITE_REG_DATA, 0x099E, 0xFD03},
515 {WRITE_REG_DATA, 0x098C, 0x0445}, /*MCU_ADDRESS*/
516 {WRITE_REG_DATA, 0x0990, 0x27CC},
517 {WRITE_REG_DATA, 0x0992, 0x0325},
518 {WRITE_REG_DATA, 0x0994, 0xFD01},
519 {WRITE_REG_DATA, 0x0996, 0x69FE},
520 {WRITE_REG_DATA, 0x0998, 0x02BD},
521 {WRITE_REG_DATA, 0x099A, 0x18CE},
522 {WRITE_REG_DATA, 0x099C, 0x0339},
523 {WRITE_REG_DATA, 0x099E, 0xCC00},
524 {WRITE_REG_DATA, 0x098C, 0x0455}, /*MCU_ADDRESS*/
525 {WRITE_REG_DATA, 0x0990, 0x11BD},
526 {WRITE_REG_DATA, 0x0992, 0xC2B8},
527 {WRITE_REG_DATA, 0x0994, 0xCC04},
528 {WRITE_REG_DATA, 0x0996, 0xC8FD},
529 {WRITE_REG_DATA, 0x0998, 0x0347},
530 {WRITE_REG_DATA, 0x099A, 0xCC03},
531 {WRITE_REG_DATA, 0x099C, 0x39FD},
532 {WRITE_REG_DATA, 0x099E, 0x02BD},
533 {WRITE_REG_DATA, 0x098C, 0x0465}, /*MCU_ADDRESS*/
534 {WRITE_REG_DATA, 0x0990, 0xDE00},
535 {WRITE_REG_DATA, 0x0992, 0x18CE},
536 {WRITE_REG_DATA, 0x0994, 0x00C2},
537 {WRITE_REG_DATA, 0x0996, 0xCC00},
538 {WRITE_REG_DATA, 0x0998, 0x37BD},
539 {WRITE_REG_DATA, 0x099A, 0xC2B8},
540 {WRITE_REG_DATA, 0x099C, 0xCC04},
541 {WRITE_REG_DATA, 0x099E, 0xEFDD},
542 {WRITE_REG_DATA, 0x098C, 0x0475}, /*MCU_ADDRESS*/
543 {WRITE_REG_DATA, 0x0990, 0xE6CC},
544 {WRITE_REG_DATA, 0x0992, 0x00C2},
545 {WRITE_REG_DATA, 0x0994, 0xDD00},
546 {WRITE_REG_DATA, 0x0996, 0xC601},
547 {WRITE_REG_DATA, 0x0998, 0xF701},
548 {WRITE_REG_DATA, 0x099A, 0x64C6},
549 {WRITE_REG_DATA, 0x099C, 0x03F7},
550 {WRITE_REG_DATA, 0x099E, 0x0165},
551 {WRITE_REG_DATA, 0x098C, 0x0485}, /*MCU_ADDRESS*/
552 {WRITE_REG_DATA, 0x0990, 0x7F01},
553 {WRITE_REG_DATA, 0x0992, 0x6639},
554 {WRITE_REG_DATA, 0x0994, 0x3C3C},
555 {WRITE_REG_DATA, 0x0996, 0x3C34},
556 {WRITE_REG_DATA, 0x0998, 0xCC32},
557 {WRITE_REG_DATA, 0x099A, 0x3EBD},
558 {WRITE_REG_DATA, 0x099C, 0xA558},
559 {WRITE_REG_DATA, 0x099E, 0x30ED},
560 {WRITE_REG_DATA, 0x098C, 0x0495}, /*MCU_ADDRESS*/
561 {WRITE_REG_DATA, 0x0990, 0x04BD},
562 {WRITE_REG_DATA, 0x0992, 0xB2D7},
563 {WRITE_REG_DATA, 0x0994, 0x30E7},
564 {WRITE_REG_DATA, 0x0996, 0x06CC},
565 {WRITE_REG_DATA, 0x0998, 0x323E},
566 {WRITE_REG_DATA, 0x099A, 0xED00},
567 {WRITE_REG_DATA, 0x099C, 0xEC04},
568 {WRITE_REG_DATA, 0x099E, 0xBDA5},
569 {WRITE_REG_DATA, 0x098C, 0x04A5}, /*MCU_ADDRESS*/
570 {WRITE_REG_DATA, 0x0990, 0x44CC},
571 {WRITE_REG_DATA, 0x0992, 0x3244},
572 {WRITE_REG_DATA, 0x0994, 0xBDA5},
573 {WRITE_REG_DATA, 0x0996, 0x585F},
574 {WRITE_REG_DATA, 0x0998, 0x30ED},
575 {WRITE_REG_DATA, 0x099A, 0x02CC},
576 {WRITE_REG_DATA, 0x099C, 0x3244},
577 {WRITE_REG_DATA, 0x099E, 0xED00},
578 {WRITE_REG_DATA, 0x098C, 0x04B5}, /*MCU_ADDRESS*/
579 {WRITE_REG_DATA, 0x0990, 0xF601},
580 {WRITE_REG_DATA, 0x0992, 0xD54F},
581 {WRITE_REG_DATA, 0x0994, 0xEA03},
582 {WRITE_REG_DATA, 0x0996, 0xAA02},
583 {WRITE_REG_DATA, 0x0998, 0xBDA5},
584 {WRITE_REG_DATA, 0x099A, 0x4430},
585 {WRITE_REG_DATA, 0x099C, 0xE606},
586 {WRITE_REG_DATA, 0x099E, 0x3838},
587 {WRITE_REG_DATA, 0x098C, 0x04C5}, /*MCU_ADDRESS*/
588 {WRITE_REG_DATA, 0x0990, 0x3831},
589 {WRITE_REG_DATA, 0x0992, 0x39BD},
590 {WRITE_REG_DATA, 0x0994, 0xD661},
591 {WRITE_REG_DATA, 0x0996, 0xF602},
592 {WRITE_REG_DATA, 0x0998, 0xF4C1},
593 {WRITE_REG_DATA, 0x099A, 0x0126},
594 {WRITE_REG_DATA, 0x099C, 0x0BFE},
595 {WRITE_REG_DATA, 0x099E, 0x02BD},
596 {WRITE_REG_DATA, 0x098C, 0x04D5}, /*MCU_ADDRESS*/
597 {WRITE_REG_DATA, 0x0990, 0xEE10},
598 {WRITE_REG_DATA, 0x0992, 0xFC02},
599 {WRITE_REG_DATA, 0x0994, 0xF5AD},
600 {WRITE_REG_DATA, 0x0996, 0x0039},
601 {WRITE_REG_DATA, 0x0998, 0xF602},
602 {WRITE_REG_DATA, 0x099A, 0xF4C1},
603 {WRITE_REG_DATA, 0x099C, 0x0226},
604 {WRITE_REG_DATA, 0x099E, 0x0AFE},
605 {WRITE_REG_DATA, 0x098C, 0x04E5}, /*MCU_ADDRESS*/
606 {WRITE_REG_DATA, 0x0990, 0x02BD},
607 {WRITE_REG_DATA, 0x0992, 0xEE10},
608 {WRITE_REG_DATA, 0x0994, 0xFC02},
609 {WRITE_REG_DATA, 0x0996, 0xF7AD},
610 {WRITE_REG_DATA, 0x0998, 0x0039},
611 {WRITE_REG_DATA, 0x099A, 0x3CBD},
612 {WRITE_REG_DATA, 0x099C, 0xB059},
613 {WRITE_REG_DATA, 0x099E, 0xCC00},
614 {WRITE_REG_DATA, 0x098C, 0x04F5}, /*MCU_ADDRESS*/
615 {WRITE_REG_DATA, 0x0990, 0x28BD},
616 {WRITE_REG_DATA, 0x0992, 0xA558},
617 {WRITE_REG_DATA, 0x0994, 0x8300},
618 {WRITE_REG_DATA, 0x0996, 0x0027},
619 {WRITE_REG_DATA, 0x0998, 0x0BCC},
620 {WRITE_REG_DATA, 0x099A, 0x0026},
621 {WRITE_REG_DATA, 0x099C, 0x30ED},
622 {WRITE_REG_DATA, 0x099E, 0x00C6},
623 {WRITE_REG_DATA, 0x098C, 0x0505}, /*MCU_ADDRESS*/
624 {WRITE_REG_DATA, 0x0990, 0x03BD},
625 {WRITE_REG_DATA, 0x0992, 0xA544},
626 {WRITE_REG_DATA, 0x0994, 0x3839},
627 {WRITE_REG_DATA, 0x098C, 0x2006}, /*MCU_ADDRESS [MON_ARG1]*/
628 {WRITE_REG_DATA, 0x0990, 0x0415}, /*MCU_DATA_0*/
629 {WRITE_REG_DATA, 0x098C, 0xA005}, /*MCU_ADDRESS [MON_CMD]*/
630 {WRITE_REG_DATA, 0x0990, 0x0001}, /*MCU_DATA_0*/
631 {DELAY_MS, 0x0000, 100},
632 {REG_TABLE_END, 0x0000, 0x0000}
636 * Stock AWB CCM from Aptina Demo2 Dev kit.
638 static struct soc2030_regs WbAutoSequence[] = {
639 {WRITE_REG_DATA, 0x098C, 0x2306}, /* [AWB_CCM_L_0] */
640 {WRITE_REG_DATA, 0x0990, 0x0180}, /* MCU_DATA_0 */
641 {WRITE_REG_DATA, 0x098C, 0x2308}, /* [AWB_CCM_L_1] */
642 {WRITE_REG_DATA, 0x0990, 0xFF00}, /* MCU_DATA_0 */
643 {WRITE_REG_DATA, 0x098C, 0x230A}, /* [AWB_CCM_L_2] */
644 {WRITE_REG_DATA, 0x0990, 0x0080}, /* MCU_DATA_0 */
645 {WRITE_REG_DATA, 0x098C, 0x230C}, /* [AWB_CCM_L_3] */
646 {WRITE_REG_DATA, 0x0990, 0xFF66}, /* MCU_DATA_0 */
647 {WRITE_REG_DATA, 0x098C, 0x230E}, /* [AWB_CCM_L_4] */
648 {WRITE_REG_DATA, 0x0990, 0x0180}, /* MCU_DATA_0 */
649 {WRITE_REG_DATA, 0x098C, 0x2310}, /* [AWB_CCM_L_5] */
650 {WRITE_REG_DATA, 0x0990, 0xFFEE}, /* MCU_DATA_0 */
651 {WRITE_REG_DATA, 0x098C, 0x2312}, /* [AWB_CCM_L_6] */
652 {WRITE_REG_DATA, 0x0990, 0xFFCD}, /* MCU_DATA_0 */
653 {WRITE_REG_DATA, 0x098C, 0x2314}, /* [AWB_CCM_L_7] */
654 {WRITE_REG_DATA, 0x0990, 0xFECD}, /* MCU_DATA_0 */
655 {WRITE_REG_DATA, 0x098C, 0x2316}, /* [AWB_CCM_L_8] */
656 {WRITE_REG_DATA, 0x0990, 0x019A}, /* MCU_DATA_0 */
657 {WRITE_REG_DATA, 0x098C, 0x2318}, /* [AWB_CCM_L_9] */
658 {WRITE_REG_DATA, 0x0990, 0x0020}, /* MCU_DATA_0 */
659 {WRITE_REG_DATA, 0x098C, 0x231A}, /* [AWB_CCM_L_10] */
660 {WRITE_REG_DATA, 0x0990, 0x0033}, /* MCU_DATA_0 */
661 {WRITE_REG_DATA, 0x098C, 0x231C}, /* [AWB_CCM_RL_0] */
662 {WRITE_REG_DATA, 0x0990, 0x0100}, /* MCU_DATA_0 */
663 {WRITE_REG_DATA, 0x098C, 0x231E}, /* [AWB_CCM_RL_1] */
664 {WRITE_REG_DATA, 0x0990, 0xFF9A}, /* MCU_DATA_0 */
665 {WRITE_REG_DATA, 0x098C, 0x2320}, /* [AWB_CCM_RL_2] */
666 {WRITE_REG_DATA, 0x0990, 0x0000}, /* MCU_DATA_0 */
667 {WRITE_REG_DATA, 0x098C, 0x2322}, /* [AWB_CCM_RL_3] */
668 {WRITE_REG_DATA, 0x0990, 0x004D}, /* MCU_DATA_0 */
669 {WRITE_REG_DATA, 0x098C, 0x2324}, /* [AWB_CCM_RL_4] */
670 {WRITE_REG_DATA, 0x0990, 0xFFCD}, /* MCU_DATA_0 */
671 {WRITE_REG_DATA, 0x098C, 0x2326}, /* [AWB_CCM_RL_5] */
672 {WRITE_REG_DATA, 0x0990, 0xFFB8}, /* MCU_DATA_0 */
673 {WRITE_REG_DATA, 0x098C, 0x2328}, /* [AWB_CCM_RL_6] */
674 {WRITE_REG_DATA, 0x0990, 0x004D}, /* MCU_DATA_0 */
675 {WRITE_REG_DATA, 0x098C, 0x232A}, /* [AWB_CCM_RL_7] */
676 {WRITE_REG_DATA, 0x0990, 0x0080}, /* MCU_DATA_0 */
677 {WRITE_REG_DATA, 0x098C, 0x232C}, /* [AWB_CCM_RL_8] */
678 {WRITE_REG_DATA, 0x0990, 0xFF66}, /* MCU_DATA_0 */
679 {WRITE_REG_DATA, 0x098C, 0x232E}, /* [AWB_CCM_RL_9] */
680 {WRITE_REG_DATA, 0x0990, 0x0008}, /* MCU_DATA_0 */
681 {WRITE_REG_DATA, 0x098C, 0x2330}, /* [AWB_CCM_RL_10] */
682 {WRITE_REG_DATA, 0x0990, 0xFFF7}, /* MCU_DATA_0 */
683 {REG_TABLE_END, 0x0000, 0x0000}
686 static struct soc2030_regs WbIncandescentSequence[] = {
687 {REG_TABLE_END, 0x0000, 0x0000}
690 static struct soc2030_regs WbFluorescentSequence[] = {
691 {REG_TABLE_END, 0x0000, 0x0000}
694 static struct soc2030_regs WbDaylightSequence[] = {
695 {REG_TABLE_END, 0x0000, 0x0000}
698 static struct soc2030_regs WbCloudydaylightSequence[] = {
699 {REG_TABLE_END, 0x0000, 0x0000}
702 static struct soc2030_regs WbNightSequence[] = {
703 {REG_TABLE_END, 0x0000, 0x0000}
706 static struct soc2030_regs *wb_table[] = {
707 [WB_AUTO] = WbAutoSequence,
708 [WB_INCANDESCENT] = WbIncandescentSequence,
709 [WB_FLUORESCENT] = WbFluorescentSequence,
710 [WB_DAYLIGHT] = WbDaylightSequence,
711 [WB_CLOUDYDAYLIGHT] = WbCloudydaylightSequence,
712 [WB_NIGHT] = WbNightSequence,
715 static struct soc2030_regs EffectNoneSequence[] = {
716 {WRITE_VAR_DATA, 0x2759, 0x6440}, /*EFFECTS_A*/
717 {WRITE_VAR_DATA, 0x275B, 0x6440}, /*EFFECTS_B*/
718 {REG_TABLE_END, 0x0000, 0x0000}
721 static struct soc2030_regs EffectBwSequence[] = {
722 {WRITE_VAR_DATA, 0x2759, 0x6441}, /*EFFECTS_A*/
723 {WRITE_VAR_DATA, 0x275B, 0x6441}, /*EFFECTS_B*/
724 {REG_TABLE_END, 0x0000, 0x0000}
727 static struct soc2030_regs EffectNegativeSequence[] = {
728 {WRITE_VAR_DATA, 0x2759, 0x6443}, /*EFFECTS_A*/
729 {WRITE_VAR_DATA, 0x275B, 0x6443}, /*EFFECTS_B*/
730 {REG_TABLE_END, 0x0000, 0x0000}
733 static struct soc2030_regs EffectPosterizeSequence[] = {
734 {WRITE_VAR_DATA, 0x2759, 0x2044}, /*EFFECTS_A*/
735 {WRITE_VAR_DATA, 0x275B, 0x2044}, /*EFFECTS_B*/
736 {REG_TABLE_END, 0x0000, 0x0000}
739 static struct soc2030_regs EffectSepiaSequence[] = {
740 {WRITE_VAR_DATA, 0x2759, 0x6442}, /*EFFECTS_A*/
741 {WRITE_VAR_DATA, 0x275B, 0x6442}, /*EFFECTS_B*/
742 {WRITE_VAR_DATA, 0x2763, 0xB023},
743 {REG_TABLE_END, 0x0000, 0x0000}
746 static struct soc2030_regs EffectSolarizeSequence[] = {
747 {WRITE_VAR_DATA, 0x2759, 0x4444}, /*EFFECTS_A*/
748 {WRITE_VAR_DATA, 0x275B, 0x4444}, /*EFFECTS_B*/
749 {REG_TABLE_END, 0x0000, 0x0000}
752 static struct soc2030_regs EffectAquaSequence[] = {
753 {WRITE_VAR_DATA, 0x2759, 0x6442}, /*EFFECTS_A*/
754 {WRITE_VAR_DATA, 0x275B, 0x6442}, /*EFFECTS_B*/
755 {WRITE_VAR_DATA, 0x2763, 0x1DE3},
756 {REG_TABLE_END, 0x0000, 0x0000}
759 static struct soc2030_regs *effect_table[] = {
760 [EFFECT_NONE] = EffectNoneSequence,
761 [EFFECT_BW] = EffectBwSequence,
762 [EFFECT_NEGATIVE] = EffectNegativeSequence,
763 [EFFECT_POSTERIZE] = EffectPosterizeSequence,
764 [EFFECT_SEPIA] = EffectSepiaSequence,
765 [EFFECT_SOLARIZE] = EffectSolarizeSequence,
766 [EFFECT_AQUA] = EffectAquaSequence,
769 static struct soc2030_mode modes[] = {
770 {800, 600, 30, mode_800x600},
771 {1600, 1200, 15, mode_1600x1200},
772 {1280, 720, 30, mode_1280x720},
775 static int soc2030_read_reg(struct i2c_client *client, u16 addr, u16 *val)
778 struct i2c_msg msg[2];
779 unsigned char data[4];
781 if (!client->adapter)
784 msg[0].addr = client->addr;
788 data[0] = (u8) (addr >> 8);
789 data[1] = (u8) (addr & 0xff);
791 msg[1].addr = client->addr;
792 msg[1].flags = I2C_M_RD;
794 msg[1].buf = data + 2;
795 err = i2c_transfer(client->adapter, msg, 2);
800 *val = ((u16)(data[2] << 8)) | data[3];
805 static int soc2030_write_reg(struct i2c_client *client, u16 addr, u16 val)
809 unsigned char data[4];
812 if (!client->adapter)
815 data[0] = (u8) (addr >> 8);
816 data[1] = (u8) (addr & 0xff);
817 data[2] = (u8) (val >> 8);
818 data[3] = (u8) (val & 0xff);
820 msg.addr = client->addr;
826 err = i2c_transfer(client->adapter, &msg, 1);
830 pr_err("soc2030: i2c transfer failed, retrying %x %x\n",
833 } while (retry <= SOC2030_MAX_RETRIES);
835 return retry > SOC2030_MAX_RETRIES ? -EIO : err;
838 static int soc2030_write_bits(struct i2c_client *client, u16 addr, u16 val,
844 err = soc2030_read_reg(client, addr, &rval);
846 pr_err("soc2030: error reading from %x\n", addr);
849 wval = ((~mask) & rval) | val;
850 err = soc2030_write_reg(client, addr, wval);
854 static int soc2030_clear_bits(struct i2c_client *client, u16 addr, u16 bits)
856 return soc2030_write_bits(client, addr, 0, bits);
859 static int soc2030_set_bits(struct i2c_client *client, u16 addr, u16 bits)
861 return soc2030_write_bits(client, addr, bits, bits);
864 static int soc2030_poll(struct i2c_client *client, u16 addr, u16 expected,
870 for (try = 0; try < SOC2030_POLL_RETRIES; try++) {
871 err = soc2030_read_reg(client, addr, &val);
874 if (expected == (val & mask)) {
875 pr_info("poll success %x: %x == %x & %x\n", addr,
876 expected, val, mask);
879 msleep(SOC2030_POLL_WAITMS);
881 pr_err("soc2030: poll for %x == ([%x]=%x) & %x failed\n", expected,
887 static int soc2030_poll_bit_set(struct i2c_client *client, u16 addr, u16 bit)
889 return soc2030_poll(client, addr, bit, bit);
892 static int soc2030_poll_bit_clear(struct i2c_client *client, u16 addr, u16 bit)
894 return soc2030_poll(client, addr, 0, bit);
897 static int soc2030_write_xdma_reg(struct i2c_client *client, u16 addr, u16 val)
901 err = soc2030_write_reg(client, 0x098c, addr);
904 err = soc2030_write_reg(client, 0x0990, val);
910 static int soc2030_read_xdma_reg(struct i2c_client *client, u16 addr, u16 *val)
914 err = soc2030_write_reg(client, 0x098c, addr);
917 err = soc2030_read_reg(client, 0x0990, val);
923 static int soc2030_poll_xdma_reg(struct i2c_client *client, u16 addr,
929 for (try = 0; try < SOC2030_POLL_RETRIES; try++) {
930 err = soc2030_read_xdma_reg(client, addr, &val);
933 if (expected == val) {
934 pr_info("poll success %x: %x == %x\n", addr,
938 msleep(SOC2030_POLL_WAITMS);
940 pr_err("soc2030: xdma poll for %x == ([%x]=%x) failed\n", expected,
945 static int soc2030_write_table(struct i2c_client *client,
946 const struct soc2030_regs table[])
949 const struct soc2030_regs *next;
951 for (next = table; next->op != REG_TABLE_END; next++) {
956 err = soc2030_write_reg(client, next->addr,
962 case WRITE_REG_BIT_H:
964 err = soc2030_set_bits(client, next->addr,
970 case WRITE_REG_BIT_L:
972 err = soc2030_clear_bits(client, next->addr,
980 err = soc2030_poll(client, next->addr,
988 err = soc2030_poll_bit_set(client, next->addr,
996 err = soc2030_poll_bit_clear(client, next->addr,
1002 case WRITE_VAR_DATA:
1004 err = soc2030_write_xdma_reg(client, next->addr,
1012 err = soc2030_poll_xdma_reg(client, next->addr,
1024 pr_err("%s: invalid operation 0x%x\n", __func__,
1032 static int soc2030_set_mode(struct soc2030_info *info,
1033 struct soc2030_mode *mode)
1035 int sensor_mode, err;
1039 mode_count = ARRAY_SIZE(modes);
1040 for (index = 0; index < mode_count; index++) {
1041 if ((mode->fps == modes[index].fps) &&
1042 (mode->xres == modes[index].xres) &&
1043 (mode->yres == modes[index].yres))
1046 if (index == mode_count) {
1047 pr_err("%s: invalid resolution supplied to set mode %d %d\n",
1048 __func__, mode->xres, mode->yres);
1051 sensor_mode = index;
1053 if (info->mode == -1) {
1055 /* write the pll table */
1056 soc2030_write_table(info->i2c_client, pll_table);
1058 err = soc2030_write_table(info->i2c_client, base_mode);
1062 /* load errata settings */
1063 err = soc2030_write_table(info->i2c_client,
1064 SetRev2ErrataSequence);
1068 /* load lens correction */
1069 err = soc2030_write_table(info->i2c_client,
1070 SetLensCorrectionSequence);
1074 /* low light optimization settings */
1075 err = soc2030_write_table(info->i2c_client,
1076 SetLowLightSequence);
1080 /* Base denoise settings (for all resolutions) */
1081 err = soc2030_write_table(info->i2c_client,
1082 SetDenoiseSequence);
1086 /* white balance common settings */
1087 err = soc2030_write_table(info->i2c_client,
1088 SetCCMCommonSequence);
1092 /* auto white balance settings */
1093 err = soc2030_write_table(info->i2c_client,
1094 SetCCMAutoSequence);
1099 err = soc2030_write_table(info->i2c_client,
1100 SetRev3PatchSequence);
1105 err = soc2030_write_table(info->i2c_client,
1112 err = soc2030_write_table(info->i2c_client, modes[sensor_mode].regset);
1116 err = soc2030_write_table(info->i2c_client, refresh_mode);
1120 err = soc2030_write_table(info->i2c_client, refresh_state);
1124 info->mode = sensor_mode;
1129 static int soc2030_get_status(struct soc2030_info *info, u16 *status)
1134 err = soc2030_read_xdma_reg(info->i2c_client, 0x0, status);
1137 err = soc2030_read_xdma_reg(info->i2c_client, 0x2104, status + 1);
1140 err = soc2030_read_xdma_reg(info->i2c_client, 0x2703, status + 2);
1143 err = soc2030_read_xdma_reg(info->i2c_client, 0x2705, status + 3);
1146 err = soc2030_read_xdma_reg(info->i2c_client, 0x2737, status + 4);
1149 pr_info("%s: [0]=%x [2104]=%x [2703]=%x [2705]=%x [2737]=%x\n"
1150 , __func__, status[0], status[1], status[2], status[3],
1156 static long soc2030_ioctl(struct file *file,
1157 unsigned int cmd, unsigned long arg)
1160 struct soc2030_info *info = file->private_data;
1162 err = mutex_lock_interruptible(&info->lock);
1167 case SOC2030_IOCTL_SET_MODE:
1169 struct soc2030_mode mode;
1170 if (copy_from_user(&mode,
1171 (const void __user *)arg,
1172 sizeof(struct soc2030_mode))) {
1173 pr_info("%s: Error copying from user\n", __func__);
1178 err = soc2030_set_mode(info, &mode);
1181 case SOC2030_IOCTL_SET_PRIVATE:
1183 int size = SOC2030_MAX_PRIVATE_SIZE *
1184 sizeof(struct soc2030_regs);
1185 struct soc2030_regs *reg_sequence =
1186 kzalloc(size, GFP_KERNEL);
1188 if (NULL == reg_sequence) {
1189 pr_info("%s: Error allocating memory\n", __func__);
1194 if (copy_from_user(reg_sequence,
1195 (const void __user *)arg, size)) {
1196 pr_info("%s: Error copying from user\n", __func__);
1197 kfree(reg_sequence);
1201 err = soc2030_write_table(info->i2c_client, reg_sequence);
1202 kfree(reg_sequence);
1205 case SOC2030_IOCTL_GET_STATUS:
1209 err = soc2030_get_status(info, status);
1212 if (copy_to_user((void __user *)arg, &status,
1214 pr_info("%s: Error copying to user\n", __func__);
1219 case SOC2030_IOCTL_GET_MODES:
1221 if (copy_to_user((void __user *)arg, &modes,
1223 pr_info("%s: Error copying to user\n", __func__);
1228 case SOC2030_IOCTL_GET_NUM_MODES:
1230 unsigned int num_modes = ARRAY_SIZE(modes);
1231 if (copy_to_user((void __user *)arg, &num_modes,
1232 sizeof(num_modes))) {
1233 pr_info("%s: Error copying to user\n", __func__);
1238 case SOC2030_IOCTL_SET_EFFECT:
1241 if ((unsigned int)arg >= EFFECT_MAX) {
1245 err = soc2030_write_table(info->i2c_client,
1246 effect_table[(unsigned int)arg]);
1250 err = soc2030_write_table(info->i2c_client, refresh_state);
1253 case SOC2030_IOCTL_SET_WHITEBALANCE:
1256 if ((unsigned int)arg >= WB_MAX) {
1261 /* Re-set context, this insures MAX AE Index is set correctly */
1262 /* As night mode may have been previously set */
1263 err = soc2030_write_table(info->i2c_client,
1264 modes[info->mode].regset);
1268 err = soc2030_write_table(info->i2c_client,
1269 SetCCMCommonSequence);
1273 err = soc2030_write_table(info->i2c_client,
1274 wb_table[(unsigned int)arg]);
1278 case SOC2030_IOCTL_SET_EXP_COMP:
1280 int req_ev = (int)arg;
1284 int new_target = EXP_TARGET;
1286 if ((req_ev > SOC_EV_MAX) || (req_ev < SOC_EV_MIN)) {
1287 pr_err("%s: Invalid exposure parameter %i\n",
1294 ev_step = -EXP_TARGET;
1295 /* step a little less than 1 f-stop */
1297 } else if (req_ev > 0) {
1298 ev_step = 0x100 - EXP_TARGET;
1299 /* step 1/2 f-stop */
1303 new_target = EXP_TARGET;
1305 /* adjust exposure target by 1 f-stop for each requested step */
1306 for (step = 1; step <= abs(req_ev); step++) {
1307 ev_step /= step_size;
1308 new_target += ev_step;
1310 if (new_target < 0) {
1311 pr_err("%s: Bad exposure target %i (0x%x)\n",
1312 __func__, new_target,
1318 err = soc2030_write_xdma_reg(info->i2c_client,
1319 0xA24F, (u16)new_target);
1321 pr_err("%s: Failed to update EV parameter\n", __func__);
1324 err = soc2030_write_table(info->i2c_client, refresh_state);
1326 pr_err("%s: Failed to update EV parameter\n", __func__);
1332 pr_err("%s: unknown IOCTL cmd 0x%x\n", __func__, cmd);
1336 mutex_unlock(&info->lock);
1340 static struct soc2030_info *info;
1342 static int soc2030_open(struct inode *inode, struct file *file)
1345 file->private_data = info;
1346 if (info->pdata && info->pdata->power_on)
1347 info->pdata->power_on();
1351 int soc2030_release(struct inode *inode, struct file *file)
1353 if (info->pdata && info->pdata->power_off)
1354 info->pdata->power_off();
1355 file->private_data = NULL;
1360 static const struct file_operations soc2030_fileops = {
1361 .owner = THIS_MODULE,
1362 .open = soc2030_open,
1363 .unlocked_ioctl = soc2030_ioctl,
1364 .release = soc2030_release,
1367 static struct miscdevice soc2030_device = {
1368 .minor = MISC_DYNAMIC_MINOR,
1370 .fops = &soc2030_fileops,
1373 static int soc2030_probe(struct i2c_client *client,
1374 const struct i2c_device_id *id)
1378 pr_info("soc2030: probing sensor.\n");
1380 info = kzalloc(sizeof(struct soc2030_info), GFP_KERNEL);
1382 pr_err("soc2030: Unable to allocate memory!\n");
1386 err = misc_register(&soc2030_device);
1388 pr_err("soc2030: Unable to register misc device!\n");
1393 mutex_init(&info->lock);
1394 info->pdata = client->dev.platform_data;
1395 info->i2c_client = client;
1396 i2c_set_clientdata(client, info);
1400 static int soc2030_remove(struct i2c_client *client)
1402 struct soc2030_info *info;
1403 info = i2c_get_clientdata(client);
1404 misc_deregister(&soc2030_device);
1409 static const struct i2c_device_id soc2030_id[] = {
1414 MODULE_DEVICE_TABLE(i2c, soc2030_id);
1416 static struct i2c_driver soc2030_i2c_driver = {
1419 .owner = THIS_MODULE,
1421 .probe = soc2030_probe,
1422 .remove = soc2030_remove,
1423 .id_table = soc2030_id,
1426 static int __init soc2030_init(void)
1428 return i2c_add_driver(&soc2030_i2c_driver);
1431 static void __exit soc2030_exit(void)
1433 i2c_del_driver(&soc2030_i2c_driver);
1436 module_init(soc2030_init);
1437 module_exit(soc2030_exit);