aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/tegra/ar0832_main.c
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
commitfcc9d2e5a6c89d22b8b773a64fb4ad21ac318446 (patch)
treea57612d1888735a2ec7972891b68c1ac5ec8faea /drivers/media/video/tegra/ar0832_main.c
parent8dea78da5cee153b8af9c07a2745f6c55057fe12 (diff)
Added missing tegra files.HEADmaster
Diffstat (limited to 'drivers/media/video/tegra/ar0832_main.c')
-rw-r--r--drivers/media/video/tegra/ar0832_main.c2549
1 files changed, 2549 insertions, 0 deletions
diff --git a/drivers/media/video/tegra/ar0832_main.c b/drivers/media/video/tegra/ar0832_main.c
new file mode 100644
index 00000000000..129825cd5f8
--- /dev/null
+++ b/drivers/media/video/tegra/ar0832_main.c
@@ -0,0 +1,2549 @@
1/*
2* ar0832_main.c - Aptina AR0832 8M Bayer type sensor driver
3*
4* Copyright (c) 2011, NVIDIA, All Rights Reserved.
5*
6* This file is licensed under the terms of the GNU General Public License
7* version 2. This program is licensed "as is" without any warranty of any
8* kind, whether express or implied.
9*/
10
11#include <linux/kernel.h>
12#include <linux/delay.h>
13#include <linux/fs.h>
14#include <linux/i2c.h>
15#include <linux/miscdevice.h>
16#include <linux/slab.h>
17#include <linux/uaccess.h>
18#include <mach/hardware.h>
19#include <linux/gpio.h>
20#include <linux/debugfs.h>
21#include <linux/seq_file.h>
22#include <asm/atomic.h>
23#include <linux/regulator/consumer.h>
24#include <media/ar0832_main.h>
25
26#define POS_LOW 0
27#define POS_HIGH 1000
28#define SETTLETIME_MS 100
29
30struct ar0832_sensor_info {
31 int mode;
32 struct ar0832_stereo_region region;
33};
34
35struct ar0832_focuser_info {
36 struct ar0832_focuser_config config;
37 int focuser_init_flag;
38 u16 last_position;
39};
40
41struct ar0832_power_rail {
42 struct regulator *sen_1v8_reg;
43 struct regulator *sen_2v8_reg;
44};
45
46struct ar0832_dev {
47 struct ar0832_sensor_info *sensor_info;
48 struct ar0832_focuser_info *focuser_info;
49 struct ar0832_platform_data *pdata;
50 struct i2c_client *i2c_client;
51 struct mutex ar0832_camera_lock;
52 struct miscdevice misc_dev;
53 struct ar0832_power_rail power_rail;
54 int brd_power_cnt;
55 atomic_t in_use;
56 char dname[20];
57 int is_stereo;
58 u16 sensor_id_data;
59 struct dentry *debugdir;
60};
61
62#define UpperByte16to8(x) ((u8)((x & 0xFF00) >> 8))
63#define LowerByte16to8(x) ((u8)(x & 0x00FF))
64
65#define ar0832_TABLE_WAIT_MS 0
66#define ar0832_TABLE_END 1
67#define ar0832_MAX_RETRIES 3
68
69/* AR0832 Register */
70#define AR0832_SENSORID_REG 0x0002
71#define AR0832_RESET_REG 0x301A
72#define AR0832_ID_REG 0x31FC
73#define AR0832_GLOBAL_GAIN_REG 0x305E
74#define AR0832_TEST_PATTERN_REG 0x0600
75#define AR0832_GROUP_HOLD_REG 0x0104
76#define AR0832_TEST_RED_REG 0x0602
77#define AR0832_TEST_GREENR_REG 0x0604
78#define AR0832_TEST_BLUE_REG 0x0606
79#define AR0832_TEST_GREENB_REG 0x0608
80
81
82
83/* AR0832_RESET_REG */
84#define AR0832_RESET_REG_GROUPED_PARAMETER_HOLD (1 << 15)
85#define AR0832_RESET_REG_GAIN_INSERT (1 << 14)
86#define AR0832_RESET_REG_SMIA_SERIALIZER_DIS (1 << 12)
87#define AR0832_RESET_REG_RESTART_BAD (1 << 10)
88#define AR0832_RESET_REG_MASK_BAD (1 << 9)
89#define AR0832_RESET_REG_GPI_EN (1 << 8)
90#define AR0832_RESET_REG_PARALLEL_EN (1 << 7)
91#define AR0832_RESET_REG_DRIVE_PINS (1 << 6)
92#define AR0832_RESET_REG_STDBY_EOF (1 << 4)
93#define AR0832_RESET_REG_LOCK_REG (1 << 3)
94#define AR0832_RESET_REG_STREAM (1 << 2)
95#define AR0832_RESET_REG_RESTART (1 << 1)
96#define AR0832_RESET_REG_RESET (1 << 0)
97
98static struct ar0832_reg mode_start[] = {
99 {ar0832_TABLE_END, 0x0000}
100};
101
102static struct ar0832_reg mode_3264X2448_8140[] = {
103 /* mode start */
104 {0x301A, 0x0058}, /* RESET_REGISTER */
105 {0x301A, 0x0050}, /* RESET_REGISTER */
106 {0x0104, 0x0100}, /* GROUPED_PARAMETER_HOLD */
107 {0x3064, 0x7800}, /* RESERVED_MFR_3064 */
108 {0x31AE, 0x0202}, /* SERIAL_FORMAT */
109 /* MT9E013 Recommended Settings */
110 {0x31B0, 0x0083}, /* FRAME_PREAMBLE */
111 {0x31B2, 0x004D}, /* LINE_PREAMBLE */
112 {0x31B4, 0x0E77}, /* MIPI_TIMING_0 */
113 {0x31B6, 0x0D20}, /* MIPI_TIMING_1 */
114 {0x31B8, 0x020E}, /* MIPI_TIMING_2 */
115 {0x31BA, 0x0710}, /* MIPI_TIMING_3 */
116 {0x31BC, 0x2A0D}, /* MIPI_TIMING_4 */
117 {ar0832_TABLE_WAIT_MS, 0x0005},
118 {0x0112, 0x0A0A}, /* CCP_DATA_FORMAT */
119 {0x3044, 0x0590},
120 {0x306E, 0xFC80},
121 {0x30B2, 0xC000},
122 {0x30D6, 0x0800},
123 {0x316C, 0xB42F},
124 {0x316E, 0x869A},
125 {0x3170, 0x210E},
126 {0x317A, 0x010E},
127 {0x31E0, 0x1FB9},
128 {0x31E6, 0x07FC},
129 {0x37C0, 0x0000},
130 {0x37C2, 0x0000},
131 {0x37C4, 0x0000},
132 {0x37C6, 0x0000},
133 {0x3E00, 0x0011},
134 {0x3E02, 0x8801},
135 {0x3E04, 0x2801},
136 {0x3E06, 0x8449},
137 {0x3E08, 0x6841},
138 {0x3E0A, 0x400C},
139 {0x3E0C, 0x1001},
140 {0x3E0E, 0x2603},
141 {0x3E10, 0x4B41},
142 {0x3E12, 0x4B24},
143 {0x3E14, 0xA3CF},
144 {0x3E16, 0x8802},
145 {0x3E18, 0x8401},
146 {0x3E1A, 0x8601},
147 {0x3E1C, 0x8401},
148 {0x3E1E, 0x840A},
149 {0x3E20, 0xFF00},
150 {0x3E22, 0x8401},
151 {0x3E24, 0x00FF},
152 {0x3E26, 0x0088},
153 {0x3E28, 0x2E8A},
154 {0x3E30, 0x0000},
155 {0x3E32, 0x8801},
156 {0x3E34, 0x4029},
157 {0x3E36, 0x00FF},
158 {0x3E38, 0x8469},
159 {0x3E3A, 0x00FF},
160 {0x3E3C, 0x2801},
161 {0x3E3E, 0x3E2A},
162 {0x3E40, 0x1C01},
163 {0x3E42, 0xFF84},
164 {0x3E44, 0x8401},
165 {0x3E46, 0x0C01},
166 {0x3E48, 0x8401},
167 {0x3E4A, 0x00FF},
168 {0x3E4C, 0x8402},
169 {0x3E4E, 0x8984},
170 {0x3E50, 0x6628},
171 {0x3E52, 0x8340},
172 {0x3E54, 0x00FF},
173 {0x3E56, 0x4A42},
174 {0x3E58, 0x2703},
175 {0x3E5A, 0x6752},
176 {0x3E5C, 0x3F2A},
177 {0x3E5E, 0x846A},
178 {0x3E60, 0x4C01},
179 {0x3E62, 0x8401},
180 {0x3E66, 0x3901},
181 {0x3E90, 0x2C01},
182 {0x3E98, 0x2B02},
183 {0x3E92, 0x2A04},
184 {0x3E94, 0x2509},
185 {0x3E96, 0x0000},
186 {0x3E9A, 0x2905},
187 {0x3E9C, 0x00FF},
188 {0x3ECC, 0x00EB},
189 {0x3ED0, 0x1E24},
190 {0x3ED4, 0xAFC4},
191 {0x3ED6, 0x909B},
192 {0x3EE0, 0x2424},
193 {0x3EE2, 0x9797},
194 {0x3EE4, 0xC100},
195 {0x3EE6, 0x0540},
196 {0x3174, 0x8000},
197
198 /* mode end */
199 {0x0300, 0x0004}, /* VT_PIX_CLK_DIV */
200 {0x0302, 0x0001}, /* VT_SYS_CLK_DIV */
201 {0x0304, 0x0002}, /* PRE_PLL_CLK_DIV */
202 {0x0306, 0x0040}, /* PLL_MULTIPLIER */
203 {0x0308, 0x000A}, /* OP_PIX_CLK_DIV */
204 {0x030A, 0x0001}, /* OP_SYS_CLK_DIV */
205 {ar0832_TABLE_WAIT_MS, 0x0001},
206 {0x3064, 0x7400}, /* RESERVED_MFR_3064 */
207 {0x0104, 0x0100}, /* GROUPED_PARAMETER_HOLD */
208 {0x0344, 0x0004}, /* X_ADDR_START */
209 {0x0348, 0x0CCB}, /* X_ADDR_END */
210 {0x0346, 0x0004}, /* Y_ADDR_START */
211 {0x034A, 0x099B}, /* Y_ADDR_END */
212 {0x034C, 0x0CC8}, /* X_OUTPUT_SIZE */
213 {0x034E, 0x0998}, /* Y_OUTPUT_SIZE */
214 {0x3040, 0xC041}, /* READ_MODE */
215 {0x306E, 0xFC80}, /* DATAPATH_SELECT */
216 {0x0400, 0x0000}, /* SCALING_MODE */
217 {0x0404, 0x0010}, /* SCALE_M */
218 {0x3178, 0x0000}, /* RESERVED_MFR_3178 */
219 {0x3ED0, 0x1E24}, /* RESERVED_MFR_3ED0 */
220 {0x0400, 0x0000}, /* SCALING_MODE */
221 {0x0404, 0x0010}, /* SCALE_M */
222 {0x0342, 0x133C}, /* LINE_LENGTH_PCK */
223 {0x0340, 0x0A27}, /* FRAME_LENGTH_LINES */
224 {0x0202, 0x0A27}, /* COARSE_INTEGRATION_TIME */
225 {0x3014, 0x09DC}, /* FINE_INTEGRATION_TIME */
226 {0x3010, 0x0078}, /* FINE_CORRECTION */
227 {0x301A, 0x8250}, /* RESET_REGISTER */
228 {0x301A, 0x8650}, /* RESET_REGISTER */
229 {0x301A, 0x8658}, /* RESET_REGISTER */
230 /* gain */
231 {0x305e, 0x10AA}, /* gain */
232 {0x0104, 0x0000}, /* GROUPED_PARAMETER_HOLD */
233 {0x301A, 0x065C}, /* RESET_REGISTER */
234 {ar0832_TABLE_END, 0x0000}
235};
236
237static struct ar0832_reg mode_3264X2448_8141[] = {
238 /* mode start */
239 {0x301A, 0x0058}, /* RESET_REGISTER */
240 {0x301A, 0x0050}, /* RESET_REGISTER */
241 {0x0104, 0x0100}, /* GROUPED_PARAMETER_HOLD */
242 {0x3064, 0x7800}, /* RESERVED_MFR_3064 */
243 {0x31AE, 0x0202}, /* SERIAL_FORMAT */
244 /* AR0832 Recommended Settings */
245 {0x3044, 0x0590},
246 {0x306E, 0xFC80},
247 {0x30B2, 0xC000},
248 {0x30D6, 0x0800},
249 {0x316C, 0xB42F},
250 {0x316E, 0x869A},
251 {0x3170, 0x210E},
252 {0x317A, 0x010E},
253 {0x31E0, 0x1FB9},
254 {0x31E6, 0x07FC},
255 {0x37C0, 0x0000},
256 {0x37C2, 0x0000},
257 {0x37C4, 0x0000},
258 {0x37C6, 0x0000},
259 {0x3E00, 0x0011},
260 {0x3E02, 0x8801},
261 {0x3E04, 0x2801},
262 {0x3E06, 0x8449},
263 {0x3E08, 0x6841},
264 {0x3E0A, 0x400C},
265 {0x3E0C, 0x1001},
266 {0x3E0E, 0x2603},
267 {0x3E10, 0x4B41},
268 {0x3E12, 0x4B24},
269 {0x3E14, 0xA3CF},
270 {0x3E16, 0x8802},
271 {0x3E18, 0x8401},
272 {0x3E1A, 0x8601},
273 {0x3E1C, 0x8401},
274 {0x3E1E, 0x840A},
275 {0x3E20, 0xFF00},
276 {0x3E22, 0x8401},
277 {0x3E24, 0x00FF},
278 {0x3E26, 0x0088},
279 {0x3E28, 0x2E8A},
280 {0x3E30, 0x0000},
281 {0x3E32, 0x8801},
282 {0x3E34, 0x4029},
283 {0x3E36, 0x00FF},
284 {0x3E38, 0x8469},
285 {0x3E3A, 0x00FF},
286 {0x3E3C, 0x2801},
287 {0x3E3E, 0x3E2A},
288 {0x3E40, 0x1C01},
289 {0x3E42, 0xFF84},
290 {0x3E44, 0x8401},
291 {0x3E46, 0x0C01},
292 {0x3E48, 0x8401},
293 {0x3E4A, 0x00FF},
294 {0x3E4C, 0x8402},
295 {0x3E4E, 0x8984},
296 {0x3E50, 0x6628},
297 {0x3E52, 0x8340},
298 {0x3E54, 0x00FF},
299 {0x3E56, 0x4A42},
300 {0x3E58, 0x2703},
301 {0x3E5A, 0x6752},
302 {0x3E5C, 0x3F2A},
303 {0x3E5E, 0x846A},
304 {0x3E60, 0x4C01},
305 {0x3E62, 0x8401},
306 {0x3E66, 0x3901},
307 {0x3E90, 0x2C01},
308 {0x3E98, 0x2B02},
309 {0x3E92, 0x2A04},
310 {0x3E94, 0x2509},
311 {0x3E96, 0x0000},
312 {0x3E9A, 0x2905},
313 {0x3E9C, 0x00FF},
314 {0x3ECC, 0x00EB},
315 {0x3ED0, 0x1E24},
316 {0x3ED4, 0xAFC4},
317 {0x3ED6, 0x909B},
318 {0x3EE0, 0x2424},
319 {0x3EE2, 0x9797},
320 {0x3EE4, 0xC100},
321 {0x3EE6, 0x0540},
322 {0x3174, 0x8000},
323
324 /* mode end */
325 {0x0300, 0x0004}, /* VT_PIX_CLK_DIV */
326 {0x0302, 0x0001}, /* VT_SYS_CLK_DIV */
327 {0x0304, 0x0002}, /* PRE_PLL_CLK_DIV */
328 {0x0306, 0x0040}, /* PLL_MULTIPLIER */
329 {0x0308, 0x000A}, /* OP_PIX_CLK_DIV */
330 {0x030A, 0x0001}, /* OP_SYS_CLK_DIV */
331 {ar0832_TABLE_WAIT_MS, 0x0001},
332 {0x3064, 0x7400}, /* RESERVED_MFR_3064 */
333 {0x0104, 0x0100}, /* GROUPED_PARAMETER_HOLD */
334 {0x0344, 0x0004}, /* X_ADDR_START */
335 {0x0348, 0x0CCB}, /* X_ADDR_END */
336 {0x0346, 0x0004}, /* Y_ADDR_START */
337 {0x034A, 0x099B}, /* Y_ADDR_END */
338 {0x034C, 0x0CC8}, /* X_OUTPUT_SIZE */
339 {0x034E, 0x0998}, /* Y_OUTPUT_SIZE */
340 {0x3040, 0xC041}, /* READ_MODE */
341 {0x306E, 0xFC80}, /* DATAPATH_SELECT */
342 {0x0400, 0x0000}, /* SCALING_MODE */
343 {0x0404, 0x0010}, /* SCALE_M */
344 {0x3178, 0x0000}, /* RESERVED_MFR_3178 */
345 {0x3ED0, 0x1E24}, /* RESERVED_MFR_3ED0 */
346 {0x0400, 0x0000}, /* SCALING_MODE */
347 {0x0404, 0x0010}, /* SCALE_M */
348 {0x0342, 0x133C}, /* LINE_LENGTH_PCK */
349 {0x0340, 0x0A27}, /* FRAME_LENGTH_LINES */
350 {0x0202, 0x0A27}, /* COARSE_INTEGRATION_TIME */
351 {0x3014, 0x09DC}, /* FINE_INTEGRATION_TIME */
352 {0x3010, 0x0078}, /* FINE_CORRECTION */
353 {0x301A, 0x8250}, /* RESET_REGISTER */
354 {0x301A, 0x8650}, /* RESET_REGISTER */
355 {0x301A, 0x8658}, /* RESET_REGISTER */
356 /* gain */
357 {0x305e, 0x10AA}, /* gain */
358 {0x0104, 0x0000}, /* GROUPED_PARAMETER_HOLD */
359 {0x301A, 0x065C}, /* RESET_REGISTER */
360 {ar0832_TABLE_END, 0x0000}
361};
362
363static struct ar0832_reg mode_2880X1620_8140[] = {
364 /* mode start */
365 {0x301A, 0x0058}, /* RESET_REGISTER */
366 {0x301A, 0x0050}, /* RESET_REGISTER */
367 {0x0104, 0x0100}, /* GROUPED_PARAMETER_HOLD */
368 {0x3064, 0x7800}, /* RESERVED_MFR_3064 */
369 {0x31AE, 0x0202}, /* SERIAL_FORMAT */
370 /* MT9E013 Recommended Settings */
371 {0x31B0, 0x0083}, /* FRAME_PREAMBLE */
372 {0x31B2, 0x004D}, /* LINE_PREAMBLE */
373 {0x31B4, 0x0E77}, /* MIPI_TIMING_0 */
374 {0x31B6, 0x0D20}, /* MIPI_TIMING_1 */
375 {0x31B8, 0x020E}, /* MIPI_TIMING_2 */
376 {0x31BA, 0x0710}, /* MIPI_TIMING_3 */
377 {0x31BC, 0x2A0D}, /* MIPI_TIMING_4 */
378 {ar0832_TABLE_WAIT_MS, 0x0005},
379 {0x0112, 0x0A0A}, /* CCP_DATA_FORMAT */
380 {0x3044, 0x0590},
381 {0x306E, 0xFC80},
382 {0x30B2, 0xC000},
383 {0x30D6, 0x0800},
384 {0x316C, 0xB42F},
385 {0x316E, 0x869A},
386 {0x3170, 0x210E},
387 {0x317A, 0x010E},
388 {0x31E0, 0x1FB9},
389 {0x31E6, 0x07FC},
390 {0x37C0, 0x0000},
391 {0x37C2, 0x0000},
392 {0x37C4, 0x0000},
393 {0x37C6, 0x0000},
394 {0x3E00, 0x0011},
395 {0x3E02, 0x8801},
396 {0x3E04, 0x2801},
397 {0x3E06, 0x8449},
398 {0x3E08, 0x6841},
399 {0x3E0A, 0x400C},
400 {0x3E0C, 0x1001},
401 {0x3E0E, 0x2603},
402 {0x3E10, 0x4B41},
403 {0x3E12, 0x4B24},
404 {0x3E14, 0xA3CF},
405 {0x3E16, 0x8802},
406 {0x3E18, 0x8401},
407 {0x3E1A, 0x8601},
408 {0x3E1C, 0x8401},
409 {0x3E1E, 0x840A},
410 {0x3E20, 0xFF00},
411 {0x3E22, 0x8401},
412 {0x3E24, 0x00FF},
413 {0x3E26, 0x0088},
414 {0x3E28, 0x2E8A},
415 {0x3E30, 0x0000},
416 {0x3E32, 0x8801},
417 {0x3E34, 0x4029},
418 {0x3E36, 0x00FF},
419 {0x3E38, 0x8469},
420 {0x3E3A, 0x00FF},
421 {0x3E3C, 0x2801},
422 {0x3E3E, 0x3E2A},
423 {0x3E40, 0x1C01},
424 {0x3E42, 0xFF84},
425 {0x3E44, 0x8401},
426 {0x3E46, 0x0C01},
427 {0x3E48, 0x8401},
428 {0x3E4A, 0x00FF},
429 {0x3E4C, 0x8402},
430 {0x3E4E, 0x8984},
431 {0x3E50, 0x6628},
432 {0x3E52, 0x8340},
433 {0x3E54, 0x00FF},
434 {0x3E56, 0x4A42},
435 {0x3E58, 0x2703},
436 {0x3E5A, 0x6752},
437 {0x3E5C, 0x3F2A},
438 {0x3E5E, 0x846A},
439 {0x3E60, 0x4C01},
440 {0x3E62, 0x8401},
441 {0x3E66, 0x3901},
442 {0x3E90, 0x2C01},
443 {0x3E98, 0x2B02},
444 {0x3E92, 0x2A04},
445 {0x3E94, 0x2509},
446 {0x3E96, 0x0000},
447 {0x3E9A, 0x2905},
448 {0x3E9C, 0x00FF},
449 {0x3ECC, 0x00EB},
450 {0x3ED0, 0x1E24},
451 {0x3ED4, 0xAFC4},
452 {0x3ED6, 0x909B},
453 {0x3EE0, 0x2424},
454 {0x3EE2, 0x9797},
455 {0x3EE4, 0xC100},
456 {0x3EE6, 0x0540},
457 {0x3174, 0x8000},
458
459 /* mode end */
460 {0x0300, 0x0004}, /* VT_PIX_CLK_DIV */
461 {0x0302, 0x0001}, /* VT_SYS_CLK_DIV */
462 {0x0304, 0x0002}, /* PRE_PLL_CLK_DIV */
463 {0x0306, 0x0040}, /* PLL_MULTIPLIER */
464 {0x0308, 0x000A}, /* OP_PIX_CLK_DIV */
465 {0x030A, 0x0001}, /* OP_SYS_CLK_DIV */
466 {ar0832_TABLE_WAIT_MS, 0x0001},
467 {0x3064, 0x7400}, /* RESERVED_MFR_3064 */
468 {0x0104, 0x0100}, /* GROUPED_PARAMETER_HOLD */
469 {0x0344, 0x00C8}, /* X_ADDR_START */
470 {0x0348, 0x0C07}, /* X_ADDR_END */
471 {0x0346, 0x01A6}, /* Y_ADDR_START */
472 {0x034A, 0x07F9}, /* Y_ADDR_END */
473 {0x034C, 0x0B40}, /* X_OUTPUT_SIZE */
474 {0x034E, 0x0654}, /* Y_OUTPUT_SIZE */
475 {0x3040, 0xC041}, /* READ_MODE */
476 {0x306E, 0xFC80}, /* DATAPATH_SELECT */
477 {0x0400, 0x0000}, /* SCALING_MODE */
478 {0x0404, 0x0010}, /* SCALE_M */
479 {0x3178, 0x0000}, /* RESERVED_MFR_3178 */
480 {0x3ED0, 0x1E24}, /* RESERVED_MFR_3ED0 */
481
482 {0x0342, 0x11B8}, /* LINE_LENGTH_PCK */
483 {0x0340, 0x06E3}, /* FRAME_LENGTH_LINES */
484 {0x0202, 0x06E3}, /* COARSE_INTEGRATION_TIME */
485 {0x3014, 0x0BD8}, /* FINE_INTEGRATION_TIME */
486 {0x3010, 0x0078}, /* FINE_CORRECTION */
487 {0x301A, 0x8250}, /* RESET_REGISTER */
488 {0x301A, 0x8650}, /* RESET_REGISTER */
489 {0x301A, 0x8658}, /* RESET_REGISTER */
490 /* gain */
491 {0x305e, 0x10AA}, /* gain */
492 {0x0104, 0x0000}, /* GROUPED_PARAMETER_HOLD */
493 {0x301A, 0x065C}, /* RESET_REGISTER */
494 {ar0832_TABLE_END, 0x0000}
495};
496
497static struct ar0832_reg mode_2880X1620_8141[] = {
498 /* mode start */
499 {0x301A, 0x0058}, /* RESET_REGISTER */
500 {0x301A, 0x0050}, /* RESET_REGISTER */
501 {0x0104, 0x0100}, /* GROUPED_PARAMETER_HOLD */
502 {0x3064, 0x7800}, /* RESERVED_MFR_3064 */
503 {0x31AE, 0x0202}, /* SERIAL_FORMAT */
504 /* AR0832 Recommended Settings */
505 {0x3044, 0x0590},
506 {0x306E, 0xFC80},
507 {0x30B2, 0xC000},
508 {0x30D6, 0x0800},
509 {0x316C, 0xB42F},
510 {0x316E, 0x869A},
511 {0x3170, 0x210E},
512 {0x317A, 0x010E},
513 {0x31E0, 0x1FB9},
514 {0x31E6, 0x07FC},
515 {0x37C0, 0x0000},
516 {0x37C2, 0x0000},
517 {0x37C4, 0x0000},
518 {0x37C6, 0x0000},
519 {0x3E00, 0x0011},
520 {0x3E02, 0x8801},
521 {0x3E04, 0x2801},
522 {0x3E06, 0x8449},
523 {0x3E08, 0x6841},
524 {0x3E0A, 0x400C},
525 {0x3E0C, 0x1001},
526 {0x3E0E, 0x2603},
527 {0x3E10, 0x4B41},
528 {0x3E12, 0x4B24},
529 {0x3E14, 0xA3CF},
530 {0x3E16, 0x8802},
531 {0x3E18, 0x8401},
532 {0x3E1A, 0x8601},
533 {0x3E1C, 0x8401},
534 {0x3E1E, 0x840A},
535 {0x3E20, 0xFF00},
536 {0x3E22, 0x8401},
537 {0x3E24, 0x00FF},
538 {0x3E26, 0x0088},
539 {0x3E28, 0x2E8A},
540 {0x3E30, 0x0000},
541 {0x3E32, 0x8801},
542 {0x3E34, 0x4029},
543 {0x3E36, 0x00FF},
544 {0x3E38, 0x8469},
545 {0x3E3A, 0x00FF},
546 {0x3E3C, 0x2801},
547 {0x3E3E, 0x3E2A},
548 {0x3E40, 0x1C01},
549 {0x3E42, 0xFF84},
550 {0x3E44, 0x8401},
551 {0x3E46, 0x0C01},
552 {0x3E48, 0x8401},
553 {0x3E4A, 0x00FF},
554 {0x3E4C, 0x8402},
555 {0x3E4E, 0x8984},
556 {0x3E50, 0x6628},
557 {0x3E52, 0x8340},
558 {0x3E54, 0x00FF},
559 {0x3E56, 0x4A42},
560 {0x3E58, 0x2703},
561 {0x3E5A, 0x6752},
562 {0x3E5C, 0x3F2A},
563 {0x3E5E, 0x846A},
564 {0x3E60, 0x4C01},
565 {0x3E62, 0x8401},
566 {0x3E66, 0x3901},
567 {0x3E90, 0x2C01},
568 {0x3E98, 0x2B02},
569 {0x3E92, 0x2A04},
570 {0x3E94, 0x2509},
571 {0x3E96, 0x0000},
572 {0x3E9A, 0x2905},
573 {0x3E9C, 0x00FF},
574 {0x3ECC, 0x00EB},
575 {0x3ED0, 0x1E24},
576 {0x3ED4, 0xAFC4},
577 {0x3ED6, 0x909B},
578 {0x3EE0, 0x2424},
579 {0x3EE2, 0x9797},
580 {0x3EE4, 0xC100},
581 {0x3EE6, 0x0540},
582 {0x3174, 0x8000},
583
584 /* mode end */
585 {0x0300, 0x0004}, /* VT_PIX_CLK_DIV */
586 {0x0302, 0x0001}, /* VT_SYS_CLK_DIV */
587 {0x0304, 0x0002}, /* PRE_PLL_CLK_DIV */
588 {0x0306, 0x0040}, /* PLL_MULTIPLIER */
589 {0x0308, 0x000A}, /* OP_PIX_CLK_DIV */
590 {0x030A, 0x0001}, /* OP_SYS_CLK_DIV */
591 {ar0832_TABLE_WAIT_MS, 0x0001},
592 {0x3064, 0x7400}, /* RESERVED_MFR_3064 */
593 {0x0104, 0x0100}, /* GROUPED_PARAMETER_HOLD */
594 {0x0344, 0x00C8}, /* X_ADDR_START */
595 {0x0348, 0x0C07}, /* X_ADDR_END */
596 {0x0346, 0x01A6}, /* Y_ADDR_START */
597 {0x034A, 0x07F9}, /* Y_ADDR_END */
598 {0x034C, 0x0B40}, /* X_OUTPUT_SIZE */
599 {0x034E, 0x0654}, /* Y_OUTPUT_SIZE */
600 {0x3040, 0xC041}, /* READ_MODE */
601 {0x306E, 0xFC80}, /* DATAPATH_SELECT */
602 {0x0400, 0x0000}, /* SCALING_MODE */
603 {0x0404, 0x0010}, /* SCALE_M */
604 {0x3178, 0x0000}, /* RESERVED_MFR_3178 */
605 {0x3ED0, 0x1E24}, /* RESERVED_MFR_3ED0 */
606
607 {0x0342, 0x11B8}, /* LINE_LENGTH_PCK */
608 {0x0340, 0x06E3}, /* FRAME_LENGTH_LINES */
609 {0x0202, 0x06E3}, /* COARSE_INTEGRATION_TIME */
610 {0x3014, 0x0BD8}, /* FINE_INTEGRATION_TIME */
611 {0x3010, 0x0078}, /* FINE_CORRECTION */
612 {0x301A, 0x8250}, /* RESET_REGISTER */
613 {0x301A, 0x8650}, /* RESET_REGISTER */
614 {0x301A, 0x8658}, /* RESET_REGISTER */
615 /* gain */
616 {0x305e, 0x10AA}, /* gain */
617 {0x0104, 0x0000}, /* GROUPED_PARAMETER_HOLD */
618 {0x301A, 0x065C}, /* RESET_REGISTER */
619 {ar0832_TABLE_END, 0x0000}
620};
621
622static struct ar0832_reg mode_1920X1080_8140[] = {
623 /* mode start */
624 {0x301A, 0x0058}, /* RESET_REGISTER */
625 {0x301A, 0x0050}, /* RESET_REGISTER */
626 {0x0104, 0x0100}, /* GROUPED_PARAMETER_HOLD */
627 {0x3064, 0x7800}, /* RESERVED_MFR_3064 */
628 {0x31AE, 0x0202}, /* SERIAL_FORMAT */
629 /* MT9E013 Recommended Settings */
630 {0x31B0, 0x0083}, /* FRAME_PREAMBLE */
631 {0x31B2, 0x004D}, /* LINE_PREAMBLE */
632 {0x31B4, 0x0E77}, /* MIPI_TIMING_0 */
633 {0x31B6, 0x0D20}, /* MIPI_TIMING_1 */
634 {0x31B8, 0x020E}, /* MIPI_TIMING_2 */
635 {0x31BA, 0x0710}, /* MIPI_TIMING_3 */
636 {0x31BC, 0x2A0D}, /* MIPI_TIMING_4 */
637 {ar0832_TABLE_WAIT_MS, 0x0005},
638 {0x0112, 0x0A0A}, /* CCP_DATA_FORMAT */
639 {0x3044, 0x0590},
640 {0x306E, 0xFC80},
641 {0x30B2, 0xC000},
642 {0x30D6, 0x0800},
643 {0x316C, 0xB42F},
644 {0x316E, 0x869A},
645 {0x3170, 0x210E},
646 {0x317A, 0x010E},
647 {0x31E0, 0x1FB9},
648 {0x31E6, 0x07FC},
649 {0x37C0, 0x0000},
650 {0x37C2, 0x0000},
651 {0x37C4, 0x0000},
652 {0x37C6, 0x0000},
653 {0x3E00, 0x0011},
654 {0x3E02, 0x8801},
655 {0x3E04, 0x2801},
656 {0x3E06, 0x8449},
657 {0x3E08, 0x6841},
658 {0x3E0A, 0x400C},
659 {0x3E0C, 0x1001},
660 {0x3E0E, 0x2603},
661 {0x3E10, 0x4B41},
662 {0x3E12, 0x4B24},
663 {0x3E14, 0xA3CF},
664 {0x3E16, 0x8802},
665 {0x3E18, 0x8401},
666 {0x3E1A, 0x8601},
667 {0x3E1C, 0x8401},
668 {0x3E1E, 0x840A},
669 {0x3E20, 0xFF00},
670 {0x3E22, 0x8401},
671 {0x3E24, 0x00FF},
672 {0x3E26, 0x0088},
673 {0x3E28, 0x2E8A},
674 {0x3E30, 0x0000},
675 {0x3E32, 0x8801},
676 {0x3E34, 0x4029},
677 {0x3E36, 0x00FF},
678 {0x3E38, 0x8469},
679 {0x3E3A, 0x00FF},
680 {0x3E3C, 0x2801},
681 {0x3E3E, 0x3E2A},
682 {0x3E40, 0x1C01},
683 {0x3E42, 0xFF84},
684 {0x3E44, 0x8401},
685 {0x3E46, 0x0C01},
686 {0x3E48, 0x8401},
687 {0x3E4A, 0x00FF},
688 {0x3E4C, 0x8402},
689 {0x3E4E, 0x8984},
690 {0x3E50, 0x6628},
691 {0x3E52, 0x8340},
692 {0x3E54, 0x00FF},
693 {0x3E56, 0x4A42},
694 {0x3E58, 0x2703},
695 {0x3E5A, 0x6752},
696 {0x3E5C, 0x3F2A},
697 {0x3E5E, 0x846A},
698 {0x3E60, 0x4C01},
699 {0x3E62, 0x8401},
700 {0x3E66, 0x3901},
701 {0x3E90, 0x2C01},
702 {0x3E98, 0x2B02},
703 {0x3E92, 0x2A04},
704 {0x3E94, 0x2509},
705 {0x3E96, 0x0000},
706 {0x3E9A, 0x2905},
707 {0x3E9C, 0x00FF},
708 {0x3ECC, 0x00EB},
709 {0x3ED0, 0x1E24},
710 {0x3ED4, 0xAFC4},
711 {0x3ED6, 0x909B},
712 {0x3EE0, 0x2424},
713 {0x3EE2, 0x9797},
714 {0x3EE4, 0xC100},
715 {0x3EE6, 0x0540},
716 {0x3174, 0x8000},
717
718 /* mode end */
719 {0x0300, 0x0004}, /* VT_PIX_CLK_DIV */
720 {0x0302, 0x0001}, /* VT_SYS_CLK_DIV */
721 {0x0304, 0x0002}, /* PRE_PLL_CLK_DIV */
722 {0x0306, 0x0040}, /* PLL_MULTIPLIER */
723 {0x0308, 0x000A}, /* OP_PIX_CLK_DIV */
724 {0x030A, 0x0001}, /* OP_SYS_CLK_DIV */
725 {ar0832_TABLE_WAIT_MS, 0x0001},
726 {0x3064, 0x7400}, /* RESERVED_MFR_3064 */
727 {0x0104, 0x0100}, /* GROUPED_PARAMETER_HOLD */
728 {0x0344, 0x028C}, /* X_ADDR_START */
729 {0x0348, 0x0A0B}, /* X_ADDR_END */
730 {0x0346, 0x006E}, /* Y_ADDR_START */
731 {0x034A, 0x04A5}, /* Y_ADDR_END */
732 {0x034C, 0x0780}, /* X_OUTPUT_SIZE */
733 {0x034E, 0x0438}, /* Y_OUTPUT_SIZE */
734 {0x3040, 0xC041}, /* READ_MODE */
735 {0x306E, 0xFC80}, /* DATAPATH_SELECT */
736 {0x0400, 0x0000}, /* SCALING_MODE */
737 {0x0404, 0x0010}, /* SCALE_M */
738 {0x3178, 0x0000}, /* RESERVED_MFR_3178 */
739 {0x3ED0, 0x1E24}, /* RESERVED_MFR_3ED0 */
740
741 {0x0342, 0x103B}, /* LINE_LENGTH_PCK */
742 {0x0340, 0x05C4}, /* FRAME_LENGTH_LINES */
743 {0x0202, 0x05C4}, /* COARSE_INTEGRATION_TIME */
744 {0x3014, 0x0702}, /* FINE_INTEGRATION_TIME */
745 {0x3010, 0x0078}, /* FINE_CORRECTION */
746 {0x301A, 0x8250}, /* RESET_REGISTER */
747 {0x301A, 0x8650}, /* RESET_REGISTER */
748 {0x301A, 0x8658}, /* RESET_REGISTER */
749 /* gain */
750 {0x305e, 0x10AA}, /* gain */
751 {0x0104, 0x0000}, /* GROUPED_PARAMETER_HOLD */
752 {0x301A, 0x065C}, /* RESET_REGISTER */
753 {ar0832_TABLE_END, 0x0000}
754};
755
756static struct ar0832_reg mode_1920X1080_8141[] = {
757 /* mode start */
758 {0x301A, 0x0058}, /* RESET_REGISTER */
759 {0x301A, 0x0050}, /* RESET_REGISTER */
760 {0x0104, 0x0100}, /* GROUPED_PARAMETER_HOLD */
761 {0x3064, 0x7800}, /* RESERVED_MFR_3064 */
762 {0x31AE, 0x0202}, /* SERIAL_FORMAT */
763 /* AR0832 Recommended Settings */
764 {0x3044, 0x0590},
765 {0x306E, 0xFC80},
766 {0x30B2, 0xC000},
767 {0x30D6, 0x0800},
768 {0x316C, 0xB42F},
769 {0x316E, 0x869A},
770 {0x3170, 0x210E},
771 {0x317A, 0x010E},
772 {0x31E0, 0x1FB9},
773 {0x31E6, 0x07FC},
774 {0x37C0, 0x0000},
775 {0x37C2, 0x0000},
776 {0x37C4, 0x0000},
777 {0x37C6, 0x0000},
778 {0x3E00, 0x0011},
779 {0x3E02, 0x8801},
780 {0x3E04, 0x2801},
781 {0x3E06, 0x8449},
782 {0x3E08, 0x6841},
783 {0x3E0A, 0x400C},
784 {0x3E0C, 0x1001},
785 {0x3E0E, 0x2603},
786 {0x3E10, 0x4B41},
787 {0x3E12, 0x4B24},
788 {0x3E14, 0xA3CF},
789 {0x3E16, 0x8802},
790 {0x3E18, 0x8401},
791 {0x3E1A, 0x8601},
792 {0x3E1C, 0x8401},
793 {0x3E1E, 0x840A},
794 {0x3E20, 0xFF00},
795 {0x3E22, 0x8401},
796 {0x3E24, 0x00FF},
797 {0x3E26, 0x0088},
798 {0x3E28, 0x2E8A},
799 {0x3E30, 0x0000},
800 {0x3E32, 0x8801},
801 {0x3E34, 0x4029},
802 {0x3E36, 0x00FF},
803 {0x3E38, 0x8469},
804 {0x3E3A, 0x00FF},
805 {0x3E3C, 0x2801},
806 {0x3E3E, 0x3E2A},
807 {0x3E40, 0x1C01},
808 {0x3E42, 0xFF84},
809 {0x3E44, 0x8401},
810 {0x3E46, 0x0C01},
811 {0x3E48, 0x8401},
812 {0x3E4A, 0x00FF},
813 {0x3E4C, 0x8402},
814 {0x3E4E, 0x8984},
815 {0x3E50, 0x6628},
816 {0x3E52, 0x8340},
817 {0x3E54, 0x00FF},
818 {0x3E56, 0x4A42},
819 {0x3E58, 0x2703},
820 {0x3E5A, 0x6752},
821 {0x3E5C, 0x3F2A},
822 {0x3E5E, 0x846A},
823 {0x3E60, 0x4C01},
824 {0x3E62, 0x8401},
825 {0x3E66, 0x3901},
826 {0x3E90, 0x2C01},
827 {0x3E98, 0x2B02},
828 {0x3E92, 0x2A04},
829 {0x3E94, 0x2509},
830 {0x3E96, 0x0000},
831 {0x3E9A, 0x2905},
832 {0x3E9C, 0x00FF},
833 {0x3ECC, 0x00EB},
834 {0x3ED0, 0x1E24},
835 {0x3ED4, 0xAFC4},
836 {0x3ED6, 0x909B},
837 {0x3EE0, 0x2424},
838 {0x3EE2, 0x9797},
839 {0x3EE4, 0xC100},
840 {0x3EE6, 0x0540},
841 {0x3174, 0x8000},
842
843 /* mode end */
844 {0x0300, 0x0004}, /* VT_PIX_CLK_DIV */
845 {0x0302, 0x0001}, /* VT_SYS_CLK_DIV */
846 {0x0304, 0x0002}, /* PRE_PLL_CLK_DIV */
847 {0x0306, 0x0040}, /* PLL_MULTIPLIER */
848 {0x0308, 0x000A}, /* OP_PIX_CLK_DIV */
849 {0x030A, 0x0001}, /* OP_SYS_CLK_DIV */
850 {ar0832_TABLE_WAIT_MS, 0x0001},
851 {0x3064, 0x7400}, /* RESERVED_MFR_3064 */
852 {0x0104, 0x0100}, /* GROUPED_PARAMETER_HOLD */
853 {0x0344, 0x028C}, /* X_ADDR_START */
854 {0x0348, 0x0A0B}, /* X_ADDR_END */
855 {0x0346, 0x006E}, /* Y_ADDR_START */
856 {0x034A, 0x04A5}, /* Y_ADDR_END */
857 {0x034C, 0x0780}, /* X_OUTPUT_SIZE */
858 {0x034E, 0x0438}, /* Y_OUTPUT_SIZE */
859 {0x3040, 0xC041}, /* READ_MODE */
860 {0x306E, 0xFC80}, /* DATAPATH_SELECT */
861 {0x0400, 0x0000}, /* SCALING_MODE */
862 {0x0404, 0x0010}, /* SCALE_M */
863 {0x3178, 0x0000}, /* RESERVED_MFR_3178 */
864 {0x3ED0, 0x1E24}, /* RESERVED_MFR_3ED0 */
865
866 {0x0342, 0x103B}, /* LINE_LENGTH_PCK */
867 {0x0340, 0x05C4}, /* FRAME_LENGTH_LINES */
868 {0x0202, 0x05C4}, /* COARSE_INTEGRATION_TIME */
869 {0x3014, 0x0702}, /* FINE_INTEGRATION_TIME */
870 {0x3010, 0x0078}, /* FINE_CORRECTION */
871 {0x301A, 0x8250}, /* RESET_REGISTER */
872 {0x301A, 0x8650}, /* RESET_REGISTER */
873 {0x301A, 0x8658}, /* RESET_REGISTER */
874 /* gain */
875 {0x305e, 0x10AA}, /* gain */
876 {0x0104, 0x0000}, /* GROUPED_PARAMETER_HOLD */
877 {0x301A, 0x065C}, /* RESET_REGISTER */
878 {ar0832_TABLE_END, 0x0000}
879};
880
881static struct ar0832_reg mode_1632X1224_8140[] = {
882 /* mode start */
883 {0x301A, 0x0058}, /* RESET_REGISTER */
884 {0x301A, 0x0050}, /* RESET_REGISTER */
885
886 /* SC-CHANGE: to-do 8 bit write */
887 {0x0104, 0x0100}, /* GROUPED_PARAMETER_HOLD */
888
889 {0x3064, 0x7800}, /* RESERVED_MFR_3064 */
890 {0x31AE, 0x0202}, /* SERIAL_FORMAT */
891 /* MT9E013 Recommended Settings */
892 {0x31B0, 0x0083}, /* FRAME_PREAMBLE */
893 {0x31B2, 0x004D}, /* LINE_PREAMBLE */
894 {0x31B4, 0x0E77}, /* MIPI_TIMING_0 */
895 {0x31B6, 0x0D20}, /* MIPI_TIMING_1 */
896 {0x31B8, 0x020E}, /* MIPI_TIMING_2 */
897 {0x31BA, 0x0710}, /* MIPI_TIMING_3 */
898 {0x31BC, 0x2A0D}, /* MIPI_TIMING_4 */
899 {ar0832_TABLE_WAIT_MS, 0x0005},
900 {0x0112, 0x0A0A}, /* CCP_DATA_FORMAT */
901 {0x3044, 0x0590},
902 {0x306E, 0xFC80},
903 {0x30B2, 0xC000},
904 {0x30D6, 0x0800},
905 {0x316C, 0xB42F},
906 {0x316E, 0x869A},
907 {0x3170, 0x210E},
908 {0x317A, 0x010E},
909 {0x31E0, 0x1FB9},
910 {0x31E6, 0x07FC},
911 {0x37C0, 0x0000},
912 {0x37C2, 0x0000},
913 {0x37C4, 0x0000},
914 {0x37C6, 0x0000},
915 {0x3E00, 0x0011},
916 {0x3E02, 0x8801},
917 {0x3E04, 0x2801},
918 {0x3E06, 0x8449},
919 {0x3E08, 0x6841},
920 {0x3E0A, 0x400C},
921 {0x3E0C, 0x1001},
922 {0x3E0E, 0x2603},
923 {0x3E10, 0x4B41},
924 {0x3E12, 0x4B24},
925 {0x3E14, 0xA3CF},
926 {0x3E16, 0x8802},
927 {0x3E18, 0x8401},
928 {0x3E1A, 0x8601},
929 {0x3E1C, 0x8401},
930 {0x3E1E, 0x840A},
931 {0x3E20, 0xFF00},
932 {0x3E22, 0x8401},
933 {0x3E24, 0x00FF},
934 {0x3E26, 0x0088},
935 {0x3E28, 0x2E8A},
936 {0x3E30, 0x0000},
937 {0x3E32, 0x8801},
938 {0x3E34, 0x4029},
939 {0x3E36, 0x00FF},
940 {0x3E38, 0x8469},
941 {0x3E3A, 0x00FF},
942 {0x3E3C, 0x2801},
943 {0x3E3E, 0x3E2A},
944 {0x3E40, 0x1C01},
945 {0x3E42, 0xFF84},
946 {0x3E44, 0x8401},
947 {0x3E46, 0x0C01},
948 {0x3E48, 0x8401},
949 {0x3E4A, 0x00FF},
950 {0x3E4C, 0x8402},
951 {0x3E4E, 0x8984},
952 {0x3E50, 0x6628},
953 {0x3E52, 0x8340},
954 {0x3E54, 0x00FF},
955 {0x3E56, 0x4A42},
956 {0x3E58, 0x2703},
957 {0x3E5A, 0x6752},
958 {0x3E5C, 0x3F2A},
959 {0x3E5E, 0x846A},
960 {0x3E60, 0x4C01},
961 {0x3E62, 0x8401},
962 {0x3E66, 0x3901},
963 {0x3E90, 0x2C01},
964 {0x3E98, 0x2B02},
965 {0x3E92, 0x2A04},
966 {0x3E94, 0x2509},
967 {0x3E96, 0x0000},
968 {0x3E9A, 0x2905},
969 {0x3E9C, 0x00FF},
970 {0x3ECC, 0x00EB},
971 {0x3ED0, 0x1E24},
972 {0x3ED4, 0xAFC4},
973 {0x3ED6, 0x909B},
974 {0x3EE0, 0x2424},
975 {0x3EE2, 0x9797},
976 {0x3EE4, 0xC100},
977 {0x3EE6, 0x0540},
978 {0x3174, 0x8000},
979
980 /* mode end */
981 {0x0300, 0x0004}, /* VT_PIX_CLK_DIV */
982 {0x0302, 0x0001}, /* VT_SYS_CLK_DIV */
983 {0x0304, 0x0002}, /* PRE_PLL_CLK_DIV */
984
985 {0x0306, 0x0040}, /* PLL_MULTIPLIER */
986
987 {0x0308, 0x000A}, /* OP_PIX_CLK_DIV */
988 {0x030A, 0x0001}, /* OP_SYS_CLK_DIV */
989 {ar0832_TABLE_WAIT_MS, 0x0001}, /* waitmsec 1 */
990
991 {0x3064, 0x7400}, /* RESERVED_MFR_3064 */
992
993 {0x0104, 0x0100}, /* GROUPED_PARAMETER_HOLD */
994
995 {0x0344, 0x0008}, /* X_ADDR_START */
996 {0x0348, 0x0CC9}, /* X_ADDR_END */
997 {0x0346, 0x0008}, /* Y_ADDR_START */
998 {0x034A, 0x0999}, /* Y_ADDR_END */
999 {0x034C, 0x0660}, /* X_OUTPUT_SIZE */
1000 {0x034E, 0x04C8}, /* Y_OUTPUT_SIZE */
1001 {0x3040, 0xC4C3}, /* READ_MODE */
1002 {0x306E, 0xFC80}, /* DATAPATH_SELECT */
1003 {0x3178, 0x0000}, /* RESERVED_MFR_3178 */
1004 {0x3ED0, 0x1E24}, /* RESERVED_MFR_3ED0 */
1005 {0x0400, 0x0002}, /* SCALING_MODE */
1006 {0x0404, 0x0010}, /* SCALE_M */
1007 {0x0342, 0x101A}, /* LINE_LENGTH_PCK */
1008 {0x0340, 0x0610}, /* FRAME_LENGTH_LINES */
1009 {0x0202, 0x0557}, /* COARSE_INTEGRATION_TIME */
1010 {0x3014, 0x0988}, /* FINE_INTEGRATION_TIME */
1011 {0x3010, 0x0130}, /* FINE_CORRECTION */
1012 {0x301A, 0x8250}, /* RESET_REGISTER */
1013 {0x301A, 0x8650}, /* RESET_REGISTER */
1014 {0x301A, 0x8658}, /* RESET_REGISTER */
1015
1016 /* gain */
1017 {0x305e, 0x10AA}, /* gain */
1018
1019 /* todo 8-bit write */
1020 {0x0104, 0x0000}, /* GROUPED_PARAMETER_HOLD */
1021 {0x301A, 0x065C}, /* RESET_REGISTER */
1022 {ar0832_TABLE_END, 0x0000}
1023};
1024
1025static struct ar0832_reg mode_1632X1224_8141[] = {
1026 /* mode start */
1027 {0x301A, 0x0058}, /* RESET_REGISTER */
1028 {0x301A, 0x0050}, /* RESET_REGISTER */
1029
1030 /* SC-CHANGE: to-do 8 bit write */
1031 {0x0104, 0x0100}, /* GROUPED_PARAMETER_HOLD */
1032
1033 {0x3064, 0x7800}, /* RESERVED_MFR_3064 */
1034 {0x31AE, 0x0202}, /* SERIAL_FORMAT */
1035 /* AR0832 Recommended Settings */
1036 {0x31B0, 0x0083}, /* FRAME_PREAMBLE */
1037 {0x31B2, 0x004D}, /* LINE_PREAMBLE */
1038 {0x31B4, 0x0E77}, /* MIPI_TIMING_0 */
1039 {0x31B6, 0x0D20}, /* MIPI_TIMING_1 */
1040 {0x31B8, 0x020E}, /* MIPI_TIMING_2 */
1041 {0x31BA, 0x0710}, /* MIPI_TIMING_3 */
1042 {0x31BC, 0x2A0D}, /* MIPI_TIMING_4 */
1043 {ar0832_TABLE_WAIT_MS, 0x0005},
1044 {0x0112, 0x0A0A}, /* CCP_DATA_FORMAT */
1045 {0x3044, 0x0590},
1046 {0x306E, 0xFC80},
1047 {0x30B2, 0xC000},
1048 {0x30D6, 0x0800},
1049 {0x316C, 0xB42F},
1050 {0x316E, 0x869A},
1051 {0x3170, 0x210E},
1052 {0x317A, 0x010E},
1053 {0x31E0, 0x1FB9},
1054 {0x31E6, 0x07FC},
1055 {0x37C0, 0x0000},
1056 {0x37C2, 0x0000},
1057 {0x37C4, 0x0000},
1058 {0x37C6, 0x0000},
1059 {0x3E00, 0x0011},
1060 {0x3E02, 0x8801},
1061 {0x3E04, 0x2801},
1062 {0x3E06, 0x8449},
1063 {0x3E08, 0x6841},
1064 {0x3E0A, 0x400C},
1065 {0x3E0C, 0x1001},
1066 {0x3E0E, 0x2603},
1067 {0x3E10, 0x4B41},
1068 {0x3E12, 0x4B24},
1069 {0x3E14, 0xA3CF},
1070 {0x3E16, 0x8802},
1071 {0x3E18, 0x8401},
1072 {0x3E1A, 0x8601},
1073 {0x3E1C, 0x8401},
1074 {0x3E1E, 0x840A},
1075 {0x3E20, 0xFF00},
1076 {0x3E22, 0x8401},
1077 {0x3E24, 0x00FF},
1078 {0x3E26, 0x0088},
1079 {0x3E28, 0x2E8A},
1080 {0x3E30, 0x0000},
1081 {0x3E32, 0x8801},
1082 {0x3E34, 0x4029},
1083 {0x3E36, 0x00FF},
1084 {0x3E38, 0x8469},
1085 {0x3E3A, 0x00FF},
1086 {0x3E3C, 0x2801},
1087 {0x3E3E, 0x3E2A},
1088 {0x3E40, 0x1C01},
1089 {0x3E42, 0xFF84},
1090 {0x3E44, 0x8401},
1091 {0x3E46, 0x0C01},
1092 {0x3E48, 0x8401},
1093 {0x3E4A, 0x00FF},
1094 {0x3E4C, 0x8402},
1095 {0x3E4E, 0x8984},
1096 {0x3E50, 0x6628},
1097 {0x3E52, 0x8340},
1098 {0x3E54, 0x00FF},
1099 {0x3E56, 0x4A42},
1100 {0x3E58, 0x2703},
1101 {0x3E5A, 0x6752},
1102 {0x3E5C, 0x3F2A},
1103 {0x3E5E, 0x846A},
1104 {0x3E60, 0x4C01},
1105 {0x3E62, 0x8401},
1106 {0x3E66, 0x3901},
1107 {0x3E90, 0x2C01},
1108 {0x3E98, 0x2B02},
1109 {0x3E92, 0x2A04},
1110 {0x3E94, 0x2509},
1111 {0x3E96, 0x0000},
1112 {0x3E9A, 0x2905},
1113 {0x3E9C, 0x00FF},
1114 {0x3ECC, 0x00EB},
1115 {0x3ED0, 0x1E24},
1116 {0x3ED4, 0xAFC4},
1117 {0x3ED6, 0x909B},
1118 {0x3EE0, 0x2424},
1119 {0x3EE2, 0x9797},
1120 {0x3EE4, 0xC100},
1121 {0x3EE6, 0x0540},
1122 {0x3174, 0x8000},
1123
1124 /* mode end */
1125 {0x0300, 0x0004}, /* VT_PIX_CLK_DIV */
1126 {0x0302, 0x0001}, /* VT_SYS_CLK_DIV */
1127 {0x0304, 0x0002}, /* PRE_PLL_CLK_DIV */
1128
1129 {0x0306, 0x0040}, /* PLL_MULTIPLIER */
1130
1131 {0x0308, 0x000A}, /* OP_PIX_CLK_DIV */
1132 {0x030A, 0x0001}, /* OP_SYS_CLK_DIV */
1133 {ar0832_TABLE_WAIT_MS, 0x0001}, /* waitmsec 1 */
1134
1135 {0x3064, 0x7400}, /* RESERVED_MFR_3064 */
1136
1137 {0x0104, 0x0100}, /* GROUPED_PARAMETER_HOLD */
1138
1139 {0x0344, 0x0008}, /* X_ADDR_START */
1140 {0x0348, 0x0CC9}, /* X_ADDR_END */
1141 {0x0346, 0x0008}, /* Y_ADDR_START */
1142 {0x034A, 0x0999}, /* Y_ADDR_END */
1143 {0x034C, 0x0660}, /* X_OUTPUT_SIZE */
1144 {0x034E, 0x04C8}, /* Y_OUTPUT_SIZE */
1145 {0x3040, 0xC4C3}, /* READ_MODE */
1146 {0x306E, 0xFC80}, /* DATAPATH_SELECT */
1147 {0x3178, 0x0000}, /* RESERVED_MFR_3178 */
1148 {0x3ED0, 0x1E24}, /* RESERVED_MFR_3ED0 */
1149 {0x0400, 0x0002}, /* SCALING_MODE */
1150 {0x0404, 0x0010}, /* SCALE_M */
1151 {0x0342, 0x101A}, /* LINE_LENGTH_PCK */
1152 {0x0340, 0x0610}, /* FRAME_LENGTH_LINES */
1153 {0x0202, 0x0557}, /* COARSE_INTEGRATION_TIME */
1154 {0x3014, 0x0988}, /* FINE_INTEGRATION_TIME */
1155 {0x3010, 0x0130}, /* FINE_CORRECTION */
1156 {0x301A, 0x8250}, /* RESET_REGISTER */
1157 {0x301A, 0x8650}, /* RESET_REGISTER */
1158 {0x301A, 0x8658}, /* RESET_REGISTER */
1159
1160 /* gain */
1161 {0x305e, 0x10AA}, /* gain */
1162
1163 /* todo 8-bit write */
1164 {0x0104, 0x0000}, /* GROUPED_PARAMETER_HOLD */
1165 {0x301A, 0x065C}, /* RESET_REGISTER */
1166 {ar0832_TABLE_END, 0x0000}
1167};
1168
1169static struct ar0832_reg mode_800X600_8140[] = {
1170 /* mode start */
1171 {0x301A, 0x0058},
1172 {0x301A, 0x0050},
1173 {0x0104, 0x0100},
1174 {0x3064, 0x7800},
1175 {0x31AE, 0x0202},
1176 {0x31B8, 0x0E3F},
1177 {0x31BE, 0xC003},
1178 {0x3070, 0x0000},
1179 {ar0832_TABLE_WAIT_MS, 0x0005},
1180
1181 /* MT9E013 Recommended Settings */
1182 {0x3044, 0x0590},
1183 {0x306E, 0xFC80},
1184 {0x30B2, 0xC000},
1185 {0x30D6, 0x0800},
1186 {0x316C, 0xB42F},
1187 {0x316E, 0x869A},
1188 {0x3170, 0x210E},
1189 {0x317A, 0x010E},
1190 {0x31E0, 0x1FB9},
1191 {0x31E6, 0x07FC},
1192 {0x37C0, 0x0000},
1193 {0x37C2, 0x0000},
1194 {0x37C4, 0x0000},
1195 {0x37C6, 0x0000},
1196 {0x3E00, 0x0011},
1197 {0x3E02, 0x8801},
1198 {0x3E04, 0x2801},
1199 {0x3E06, 0x8449},
1200 {0x3E08, 0x6841},
1201 {0x3E0A, 0x400C},
1202 {0x3E0C, 0x1001},
1203 {0x3E0E, 0x2603},
1204 {0x3E10, 0x4B41},
1205 {0x3E12, 0x4B24},
1206 {0x3E14, 0xA3CF},
1207 {0x3E16, 0x8802},
1208 {0x3E18, 0x8401},
1209 {0x3E1A, 0x8601},
1210 {0x3E1C, 0x8401},
1211 {0x3E1E, 0x840A},
1212 {0x3E20, 0xFF00},
1213 {0x3E22, 0x8401},
1214 {0x3E24, 0x00FF},
1215 {0x3E26, 0x0088},
1216 {0x3E28, 0x2E8A},
1217 {0x3E30, 0x0000},
1218 {0x3E32, 0x8801},
1219 {0x3E34, 0x4029},
1220 {0x3E36, 0x00FF},
1221 {0x3E38, 0x8469},
1222 {0x3E3A, 0x00FF},
1223 {0x3E3C, 0x2801},
1224 {0x3E3E, 0x3E2A},
1225 {0x3E40, 0x1C01},
1226 {0x3E42, 0xFF84},
1227 {0x3E44, 0x8401},
1228 {0x3E46, 0x0C01},
1229 {0x3E48, 0x8401},
1230 {0x3E4A, 0x00FF},
1231 {0x3E4C, 0x8402},
1232 {0x3E4E, 0x8984},
1233 {0x3E50, 0x6628},
1234 {0x3E52, 0x8340},
1235 {0x3E54, 0x00FF},
1236 {0x3E56, 0x4A42},
1237 {0x3E58, 0x2703},
1238 {0x3E5A, 0x6752},
1239 {0x3E5C, 0x3F2A},
1240 {0x3E5E, 0x846A},
1241 {0x3E60, 0x4C01},
1242 {0x3E62, 0x8401},
1243 {0x3E66, 0x3901},
1244 {0x3E90, 0x2C01},
1245 {0x3E98, 0x2B02},
1246 {0x3E92, 0x2A04},
1247 {0x3E94, 0x2509},
1248 {0x3E96, 0x0000},
1249 {0x3E9A, 0x2905},
1250 {0x3E9C, 0x00FF},
1251 {0x3ECC, 0x00EB},
1252 {0x3ED0, 0x1E24},
1253 {0x3ED4, 0xAFC4},
1254 {0x3ED6, 0x909B},
1255 {0x3EE0, 0x2424},
1256 {0x3EE2, 0x9797},
1257 {0x3EE4, 0xC100},
1258 {0x3EE6, 0x0540},
1259
1260 /* mode end */
1261 {0x3174, 0x8000},
1262
1263 /* [RAW10] */
1264 {0x0112, 0x0A0A},
1265
1266 /* PLL Configuration Ext=24MHz */
1267 {0x0300, 0x0004},
1268 {0x0302, 0x0001},
1269 {0x0304, 0x0002},
1270 {0x0306, 0x0042},
1271 {0x0308, 0x000A},
1272 {0x030A, 0x0001},
1273 {ar0832_TABLE_WAIT_MS, 0x0001},
1274
1275 /* Output size */
1276 {0x0344, 0x04D8},
1277 {0x0348, 0x07F7},
1278 {0x0346, 0x03A4},
1279 {0x034A, 0x05FB},
1280 {0x034C, 0x0320},
1281 {0x034E, 0x0258},
1282 {0x3040, 0xC041},
1283
1284 {0x306E, 0xFC80},
1285 {0x3178, 0x0000},
1286 {0x3ED0, 0x1E24},
1287
1288 /* Scale Configuration */
1289 {0x0400, 0x0000},
1290 {0x0404, 0x0010},
1291
1292 /* Timing Configuration */
1293 {0x0342, 0x08A8},
1294 {0x0340, 0x02E7},
1295 {0x0202, 0x02E7},
1296 {0x3014, 0x03F6},
1297 {0x3010, 0x0078},
1298
1299 {0x301A, 0x8250},
1300 {0x301A, 0x8650},
1301 {0x301A, 0x8658},
1302 /* STATE= Minimum Gain, 1500 */
1303 {0x305E, 0x13AF},
1304
1305 {0x0104, 0x0000},
1306 {0x301A, 0x065C},
1307 {ar0832_TABLE_END, 0x0000}
1308};
1309
1310static struct ar0832_reg mode_800X600_8141[] = {
1311 /* mode start */
1312 {0x301A, 0x0058}, /* RESET_REGISTER */
1313 {0x301A, 0x0050}, /* RESET_REGISTER */
1314
1315 /* SC-CHANGE: to-do 8 bit write */
1316 {0x0104, 0x0100}, /* GROUPED_PARAMETER_HOLD */
1317
1318 {0x3064, 0x7800}, /* RESERVED_MFR_3064 */
1319 {0x31AE, 0x0202}, /* SERIAL_FORMAT */
1320 /* AR0832 Recommended Settings */
1321 {0x31B0, 0x0083}, /* FRAME_PREAMBLE */
1322 {0x31B2, 0x004D}, /* LINE_PREAMBLE */
1323 {0x31B4, 0x0E88}, /* MIPI_TIMING_0 */
1324 {0x31B6, 0x0D24}, /* MIPI_TIMING_1 */
1325 {0x31B8, 0x020E}, /* MIPI_TIMING_2 */
1326 {0x31BA, 0x0710}, /* MIPI_TIMING_3 */
1327 {0x31BC, 0x2A0D}, /* MIPI_TIMING_4 */
1328 {ar0832_TABLE_WAIT_MS, 0x0005},
1329 {0x0112, 0x0A0A}, /* CCP_DATA_FORMAT */
1330 {0x3044, 0x0590}, /* RESERVED_MFR_3044 */
1331 {0x306E, 0xFC80}, /* DATAPATH_SELECT */
1332 {0x30B2, 0xC000}, /* RESERVED_MFR_30B2 */
1333 {0x30D6, 0x0800}, /* RESERVED_MFR_30D6 */
1334 {0x316C, 0xB42F}, /* RESERVED_MFR_316C */
1335 {0x316E, 0x869A}, /* RESERVED_MFR_316E */
1336 {0x3170, 0x210E}, /* RESERVED_MFR_3170 */
1337 {0x317A, 0x010E}, /* RESERVED_MFR_317A */
1338 {0x31E0, 0x1FB9}, /* RESERVED_MFR_31E0 */
1339 {0x31E6, 0x07FC}, /* RESERVED_MFR_31E6 */
1340 {0x37C0, 0x0000}, /* P_GR_Q5 */
1341 {0x37C2, 0x0000}, /* P_RD_Q5 */
1342 {0x37C4, 0x0000}, /* P_BL_Q5 */
1343 {0x37C6, 0x0000}, /* P_GB_Q5 */
1344 {0x3E00, 0x0011}, /* RESERVED_MFR_3E00 */
1345 {0x3E02, 0x8801}, /* RESERVED_MFR_3E02 */
1346 {0x3E04, 0x2801}, /* RESERVED_MFR_3E04 */
1347 {0x3E06, 0x8449}, /* RESERVED_MFR_3E06 */
1348 {0x3E08, 0x6841}, /* RESERVED_MFR_3E08 */
1349 {0x3E0A, 0x400C}, /* RESERVED_MFR_3E0A */
1350 {0x3E0C, 0x1001}, /* RESERVED_MFR_3E0C */
1351 {0x3E0E, 0x2603}, /* RESERVED_MFR_3E0E */
1352 {0x3E10, 0x4B41}, /* RESERVED_MFR_3E10 */
1353 {0x3E12, 0x4B24}, /* RESERVED_MFR_3E12 */
1354 {0x3E14, 0xA3CF}, /* RESERVED_MFR_3E14 */
1355 {0x3E16, 0x8802}, /* RESERVED_MFR_3E16 */
1356 {0x3E18, 0x84FF}, /* RESERVED_MFR_3E18 */
1357 {0x3E1A, 0x8601}, /* RESERVED_MFR_3E1A */
1358 {0x3E1C, 0x8401}, /* RESERVED_MFR_3E1C */
1359 {0x3E1E, 0x840A}, /* RESERVED_MFR_3E1E */
1360 {0x3E20, 0xFF00}, /* RESERVED_MFR_3E20 */
1361 {0x3E22, 0x8401}, /* RESERVED_MFR_3E22 */
1362 {0x3E24, 0x00FF}, /* RESERVED_MFR_3E24 */
1363 {0x3E26, 0x0088}, /* RESERVED_MFR_3E26 */
1364 {0x3E28, 0x2E8A}, /* RESERVED_MFR_3E28 */
1365 {0x3E30, 0x0000}, /* RESERVED_MFR_3E30 */
1366 {0x3E32, 0x8801}, /* RESERVED_MFR_3E32 */
1367 {0x3E34, 0x4029}, /* RESERVED_MFR_3E34 */
1368 {0x3E36, 0x00FF}, /* RESERVED_MFR_3E36 */
1369 {0x3E38, 0x8469}, /* RESERVED_MFR_3E38 */
1370 {0x3E3A, 0x00FF}, /* RESERVED_MFR_3E3A */
1371 {0x3E3C, 0x2801}, /* RESERVED_MFR_3E3C */
1372 {0x3E3E, 0x3E2A}, /* RESERVED_MFR_3E3E */
1373 {0x3E40, 0x1C01}, /* RESERVED_MFR_3E40 */
1374 {0x3E42, 0xFF84}, /* RESERVED_MFR_3E42 */
1375 {0x3E44, 0x8401}, /* RESERVED_MFR_3E44 */
1376 {0x3E46, 0x0C01}, /* RESERVED_MFR_3E46 */
1377 {0x3E48, 0x8401}, /* RESERVED_MFR_3E48 */
1378 {0x3E4A, 0x00FF}, /* RESERVED_MFR_3E4A */
1379 {0x3E4C, 0x8402}, /* RESERVED_MFR_3E4C */
1380 {0x3E4E, 0x8984}, /* RESERVED_MFR_3E4E */
1381 {0x3E50, 0x6628}, /* RESERVED_MFR_3E50 */
1382 {0x3E52, 0x8340}, /* RESERVED_MFR_3E52 */
1383 {0x3E54, 0x00FF}, /* RESERVED_MFR_3E54 */
1384 {0x3E56, 0x4A42}, /* RESERVED_MFR_3E56 */
1385 {0x3E58, 0x2703}, /* RESERVED_MFR_3E58 */
1386 {0x3E5A, 0x6752}, /* RESERVED_MFR_3E5A */
1387 {0x3E5C, 0x3F2A}, /* RESERVED_MFR_3E5C */
1388 {0x3E5E, 0x846A}, /* RESERVED_MFR_3E5E */
1389 {0x3E60, 0x4C01}, /* RESERVED_MFR_3E60 */
1390 {0x3E62, 0x8401}, /* RESERVED_MFR_3E62 */
1391 {0x3E66, 0x3901}, /* RESERVED_MFR_3E66 */
1392 {0x3E90, 0x2C01}, /* RESERVED_MFR_3E90 */
1393 {0x3E98, 0x2B02}, /* RESERVED_MFR_3E98 */
1394 {0x3E92, 0x2A04}, /* RESERVED_MFR_3E92 */
1395 {0x3E94, 0x2509}, /* RESERVED_MFR_3E94 */
1396 {0x3E96, 0x0000}, /* RESERVED_MFR_3E96 */
1397 {0x3E9A, 0x2905}, /* RESERVED_MFR_3E9A */
1398 {0x3E9C, 0x00FF}, /* RESERVED_MFR_3E9C */
1399 {0x3ECC, 0x00EB}, /* RESERVED_MFR_3ECC */
1400 {0x3ED0, 0x1E24}, /* RESERVED_MFR_3ED0 */
1401 {0x3ED4, 0xAFC4}, /* RESERVED_MFR_3ED4 */
1402 {0x3ED6, 0x909B}, /* RESERVED_MFR_3ED6 */
1403 {0x3EE0, 0x2424}, /* RESERVED_MFR_3EE0 */
1404 {0x3EE2, 0x9797}, /* RESERVED_MFR_3EE2 */
1405 {0x3EE4, 0xC100}, /* RESERVED_MFR_3EE4 */
1406 {0x3EE6, 0x0540}, /* RESERVED_MFR_3EE6 */
1407
1408 /* mode end */
1409 {0x3174, 0x8000}, /* RESERVED_MFR_3174 */
1410 {0x0300, 0x0004}, /* VT_PIX_CLK_DIV */
1411 {0x0302, 0x0001}, /* VT_SYS_CLK_DIV */
1412 {0x0304, 0x0002}, /* PRE_PLL_CLK_DIV */
1413
1414 {0x0306, 0x0042}, /* PLL_MULTIPLIER */
1415
1416 {0x0308, 0x000A}, /* OP_PIX_CLK_DIV */
1417 {0x030A, 0x0001}, /* OP_SYS_CLK_DIV */
1418 {ar0832_TABLE_WAIT_MS, 0x0001}, /* waitmsec 1 */
1419
1420 {0x3064, 0x7400}, /* RESERVED_MFR_3064 */
1421
1422 {0x0104, 0x0100}, /* GROUPED_PARAMETER_HOLD */
1423
1424 {0x0344, 0x04D8}, /* X_ADDR_START */
1425 {0x0348, 0x07F7}, /* X_ADDR_END */
1426 {0x0346, 0x03A4}, /* Y_ADDR_START */
1427 {0x034A, 0x05FB}, /* Y_ADDR_END */
1428 {0x034C, 0x0320}, /* X_OUTPUT_SIZE */
1429 {0x034E, 0x0260}, /* Y_OUTPUT_SIZE */
1430 {0x3040, 0xC041}, /* READ_MODE */
1431 {0x306E, 0xFC80}, /* DATAPATH_SELECT */
1432 {0x3178, 0x0000}, /* RESERVED_MFR_3178 */
1433 {0x3ED0, 0x1E24}, /* RESERVED_MFR_3ED0 */
1434 {0x0400, 0x0000}, /* SCALING_MODE */
1435 {0x0404, 0x0010}, /* SCALE_M */
1436 {0x0342, 0x08A8}, /* LINE_LENGTH_PCK */
1437 {0x0340, 0x02E7}, /* FRAME_LENGTH_LINES */
1438 {0x0202, 0x02E7}, /* COARSE_INTEGRATION_TIME */
1439 {0x3014, 0x03F6}, /* FINE_INTEGRATION_TIME */
1440 {0x3010, 0x0078}, /* FINE_CORRECTION */
1441 {0x301A, 0x8250}, /* RESET_REGISTER */
1442 {0x301A, 0x8650}, /* RESET_REGISTER */
1443 {0x301A, 0x8658}, /* RESET_REGISTER */
1444
1445 /* gain */
1446 {0x305e, 0x10AA}, /* gain */
1447
1448 /* todo 8-bit write */
1449 {0x0104, 0x0000}, /* GROUPED_PARAMETER_HOLD */
1450 {0x301A, 0x065C}, /* RESET_REGISTER */
1451 {ar0832_TABLE_END, 0x0000}
1452};
1453
1454static struct ar0832_reg mode_end[] = {
1455 {ar0832_TABLE_END, 0x0000}
1456};
1457
1458enum {
1459 ar0832_MODE_3264X2448,
1460 ar0832_MODE_2880X1620,
1461 ar0832_MODE_1920X1080,
1462 ar0832_MODE_1632X1224,
1463 ar0832_MODE_800X600
1464};
1465
1466static struct ar0832_reg *mode_table_8140[] = {
1467 [ar0832_MODE_3264X2448] = mode_3264X2448_8140,
1468 [ar0832_MODE_2880X1620] = mode_2880X1620_8140,
1469 [ar0832_MODE_1920X1080] = mode_1920X1080_8140,
1470 [ar0832_MODE_1632X1224] = mode_1632X1224_8140,
1471 [ar0832_MODE_800X600] = mode_800X600_8140,
1472};
1473
1474static struct ar0832_reg *mode_table_8141[] = {
1475 [ar0832_MODE_3264X2448] = mode_3264X2448_8141,
1476 [ar0832_MODE_2880X1620] = mode_2880X1620_8141,
1477 [ar0832_MODE_1920X1080] = mode_1920X1080_8141,
1478 [ar0832_MODE_1632X1224] = mode_1632X1224_8141,
1479 [ar0832_MODE_800X600] = mode_800X600_8141,
1480};
1481
1482static inline void ar0832_msleep(u32 t)
1483{
1484 /*
1485 why usleep_range() instead of msleep() ?
1486 Read Documentation/timers/timers-howto.txt
1487 */
1488 usleep_range(t*1000, t*1000 + 500);
1489}
1490
1491/* 16 bit reg to program frame length */
1492static inline void ar0832_get_frame_length_regs(struct ar0832_reg *regs,
1493 u32 frame_length)
1494{
1495 regs->addr = 0x0340;
1496 regs->val = (frame_length) & 0xFFFF;
1497}
1498
1499static inline void ar0832_get_coarse_time_regs(struct ar0832_reg *regs,
1500 u32 coarse_time)
1501{
1502 regs->addr = 0x0202;
1503 regs->val = (coarse_time) & 0xFFFF;
1504}
1505
1506static inline void ar0832_get_focuser_vcm_control_regs(struct ar0832_reg *regs,
1507 u16 value)
1508{
1509 regs->addr = 0x30F0;
1510 regs->val = (value) & 0xFFFF;
1511}
1512
1513static inline void ar0832_get_focuser_vcm_step_time_regs
1514 (struct ar0832_reg *regs, u16 value)
1515{
1516 regs->addr = 0x30F4;
1517 regs->val = (value) & 0xFFFF;
1518}
1519
1520static inline void ar0832_get_focuser_data_regs(struct ar0832_reg *regs,
1521 u16 value)
1522{
1523 regs->addr = 0x30F2;
1524 regs->val = (value) & 0xFFFF;
1525}
1526
1527static inline void ar0832_get_gain_regs(struct ar0832_reg *regs, u16 gain)
1528{
1529 /* global_gain register*/
1530 regs->addr = AR0832_GLOBAL_GAIN_REG;
1531 regs->val = gain;
1532}
1533
1534static int ar0832_write_reg8(struct i2c_client *client, u16 addr, u8 val)
1535{
1536 int err;
1537 struct i2c_msg msg;
1538 unsigned char data[3];
1539 int retry = 0;
1540
1541 if (!client->adapter)
1542 return -ENODEV;
1543
1544 data[0] = (u8) (addr >> 8);;
1545 data[1] = (u8) (addr & 0xff);
1546 data[2] = (u8) (val & 0xff);
1547
1548 msg.addr = client->addr;
1549 msg.flags = 0;
1550 msg.len = 3;
1551 msg.buf = data;
1552
1553 dev_dbg(&client->dev, "0x%x = 0x%x\n", addr, val);
1554
1555 do {
1556 err = i2c_transfer(client->adapter, &msg, 1);
1557 if (err > 0)
1558 return 0;
1559 retry++;
1560 dev_err(&client->dev,
1561 "%s: i2c transfer failed, retrying %x %x\n",
1562 __func__, addr, val);
1563 ar0832_msleep(3);
1564 } while (retry < ar0832_MAX_RETRIES);
1565
1566 return err;
1567}
1568
1569static int ar0832_write_reg16(struct i2c_client *client, u16 addr, u16 val)
1570{
1571 int count;
1572 struct i2c_msg msg;
1573 unsigned char data[4];
1574 int retry = 0;
1575
1576 if (!client->adapter)
1577 return -ENODEV;
1578
1579 data[0] = (u8) (addr >> 8);
1580 data[1] = (u8) (addr & 0xff);
1581 data[2] = (u8) (val >> 8);
1582 data[3] = (u8) (val & 0xff);
1583
1584 msg.addr = client->addr;
1585 msg.flags = 0;
1586 msg.len = 4;
1587 msg.buf = data;
1588
1589 dev_dbg(&client->dev, "0x%x = 0x%x\n", addr, val);
1590
1591 do {
1592 count = i2c_transfer(client->adapter, &msg, 1);
1593 if (count == 1)
1594 return 0;
1595 retry++;
1596 dev_err(&client->dev,
1597 "%s: i2c transfer failed, retrying %x %x\n",
1598 __func__, addr, val);
1599 ar0832_msleep(3);
1600 } while (retry <= ar0832_MAX_RETRIES);
1601
1602 return -EIO;
1603}
1604
1605static int ar0832_read_reg16(struct i2c_client *client, u16 addr, u16 *val)
1606{
1607 struct i2c_msg msg[2];
1608 u8 data[4];
1609
1610 msg[0].addr = client->addr;
1611 msg[0].flags = 0;
1612 msg[0].len = 2;
1613 msg[0].buf = data;
1614 data[0] = (addr >> 8);
1615 data[1] = (addr & 0xff);
1616 msg[1].addr = client->addr;
1617 msg[1].flags = I2C_M_RD;
1618 msg[1].len = 2;
1619 msg[1].buf = data + 2;
1620
1621 if (i2c_transfer(client->adapter, msg, 2) == 2) {
1622 *val = ((data[2] << 8) | data[3]);
1623 dev_dbg(&client->dev, "0x%x = 0x%x\n", addr, *val);
1624 return 0;
1625 } else {
1626 *val = 0;
1627 dev_err(&client->dev,
1628 "%s: i2c read failed.\n", __func__);
1629 return -1;
1630 }
1631}
1632
1633static int ar0832_write_reg_helper(struct ar0832_dev *dev,
1634 u16 addr,
1635 u16 val)
1636{
1637 int ret;
1638
1639 if (addr == 0x104)
1640 ret = ar0832_write_reg8(dev->i2c_client, addr,
1641 (val >> 8 & 0xff));
1642 else
1643 ret = ar0832_write_reg16(dev->i2c_client, addr, val);
1644
1645 return ret;
1646}
1647
1648static int ar0832_write_table(struct ar0832_dev *dev,
1649 const struct ar0832_reg table[],
1650 const struct ar0832_reg override_list[],
1651 int num_override_regs)
1652{
1653 int err;
1654 const struct ar0832_reg *next;
1655 u16 val;
1656 int i;
1657
1658 for (next = table; next->addr != ar0832_TABLE_END; next++) {
1659 if (next->addr == ar0832_TABLE_WAIT_MS) {
1660 ar0832_msleep(next->val);
1661 continue;
1662 }
1663
1664 val = next->val;
1665 /* When an override list is passed in, replace the reg */
1666 /* value to write if the reg is in the list */
1667 if (override_list) {
1668 for (i = 0; i < num_override_regs; i++) {
1669 if (next->addr == override_list[i].addr) {
1670 val = override_list[i].val;
1671 break;
1672 }
1673 }
1674 }
1675
1676 err = ar0832_write_reg_helper(dev, next->addr, val);
1677 if (err)
1678 return err;
1679 }
1680 return 0;
1681}
1682
1683static int ar0832_set_frame_length(struct ar0832_dev *dev,
1684 u32 frame_length)
1685{
1686 struct ar0832_reg reg_list;
1687 struct i2c_client *i2c_client = dev->i2c_client;
1688 int ret;
1689
1690 dev_dbg(&i2c_client->dev, "[%s] (0x%08x)\n", __func__, frame_length);
1691
1692 ar0832_get_frame_length_regs(&reg_list, frame_length);
1693 ret = ar0832_write_reg8(i2c_client, AR0832_GROUP_HOLD_REG, 0x1);
1694 if (ret)
1695 return ret;
1696
1697 ret = ar0832_write_reg16(i2c_client, reg_list.addr,
1698 reg_list.val);
1699 if (ret)
1700 return ret;
1701
1702 ret = ar0832_write_reg8(i2c_client, AR0832_GROUP_HOLD_REG, 0x0);
1703 if (ret)
1704 return ret;
1705
1706 return 0;
1707}
1708
1709static int ar0832_set_coarse_time(struct ar0832_dev *dev,
1710 u32 coarse_time)
1711{
1712 int ret;
1713 struct ar0832_reg reg_list;
1714 struct i2c_client *i2c_client = dev->i2c_client;
1715
1716 dev_dbg(&i2c_client->dev, "[%s] (0x%08x)\n", __func__, coarse_time);
1717 ar0832_get_coarse_time_regs(&reg_list, coarse_time);
1718
1719 ret = ar0832_write_reg8(i2c_client, AR0832_GROUP_HOLD_REG, 0x1);
1720 if (ret)
1721 return ret;
1722
1723 ret = ar0832_write_reg16(i2c_client, reg_list.addr,
1724 reg_list.val);
1725 if (ret)
1726 return ret;
1727
1728 ret = ar0832_write_reg8(i2c_client, AR0832_GROUP_HOLD_REG, 0x0);
1729 if (ret)
1730 return ret;
1731
1732 return 0;
1733}
1734
1735static int ar0832_set_gain(struct ar0832_dev *dev, u16 gain)
1736{
1737 int ret = 0;
1738 struct ar0832_reg reg_list_gain;
1739
1740 ret = ar0832_write_reg8(dev->i2c_client, AR0832_GROUP_HOLD_REG, 0x1);
1741 /* Gain Registers Start */
1742 ar0832_get_gain_regs(&reg_list_gain, gain);
1743 ret |= ar0832_write_reg16(dev->i2c_client,
1744 reg_list_gain.addr,
1745 reg_list_gain.val);
1746 if (ret)
1747 return ret;
1748
1749 /* Gain register End */
1750 ret |= ar0832_write_reg8(dev->i2c_client, AR0832_GROUP_HOLD_REG, 0x0);
1751
1752 return ret;
1753}
1754
1755static int ar0832_set_mode(struct ar0832_dev *dev,
1756 struct ar0832_mode *mode)
1757{
1758 int sensor_mode;
1759 int err;
1760 struct i2c_client *i2c_client = dev->i2c_client;
1761 struct ar0832_reg reg_ovr[3];
1762 struct ar0832_reg *mode_seq;
1763
1764 dev_dbg(&i2c_client->dev, "%s: ++\n", __func__);
1765
1766 if (mode->xres == 3264 && mode->yres == 2448)
1767 sensor_mode = ar0832_MODE_3264X2448;
1768 else if (mode->xres == 2880 && mode->yres == 1620)
1769 sensor_mode = ar0832_MODE_2880X1620;
1770 else if (mode->xres == 1920 && mode->yres == 1080)
1771 sensor_mode = ar0832_MODE_1920X1080;
1772 else if (mode->xres == 1632 && mode->yres == 1224)
1773 sensor_mode = ar0832_MODE_1632X1224;
1774 else if (mode->xres == 800 && mode->yres == 600)
1775 sensor_mode = ar0832_MODE_800X600;
1776 else {
1777 dev_err(&i2c_client->dev,
1778 "%s: invalid resolution supplied to set mode %d %d\n",
1779 __func__ , mode->xres, mode->yres);
1780 return -EINVAL;
1781 }
1782
1783 if (dev->sensor_id_data == AR0832_SENSOR_ID_8141)
1784 mode_seq = mode_table_8141[sensor_mode];
1785 else
1786 mode_seq = mode_table_8140[sensor_mode];
1787 /* get a list of override regs for the asking frame length, */
1788 /* coarse integration time, and gain.*/
1789 err = ar0832_write_table(dev, mode_start, NULL, 0);
1790 if (err)
1791 return err;
1792
1793 /* When we change the resolution */
1794 ar0832_get_frame_length_regs(&reg_ovr[0], mode->frame_length);
1795 ar0832_get_coarse_time_regs(&reg_ovr[1], mode->coarse_time);
1796 ar0832_get_gain_regs(&reg_ovr[2], mode->gain);
1797 err = ar0832_write_table(dev, mode_seq, reg_ovr, ARRAY_SIZE(reg_ovr));
1798 if (err)
1799 return err;
1800
1801 err = ar0832_write_table(dev, mode_end, NULL, 0);
1802 if (err)
1803 return err;
1804
1805 dev->sensor_info->mode = sensor_mode;
1806 dev_dbg(&i2c_client->dev, "%s: --\n", __func__);
1807
1808 return 0;
1809}
1810
1811static int ar0832_get_status(struct ar0832_dev *dev, u8 *status)
1812{
1813 int err = 0;
1814 struct i2c_client *i2c_client = dev->i2c_client;
1815
1816 *status = 0;
1817 /* FixMe */
1818 /*
1819 err = ar0832_read_reg(dev->i2c_client, 0x001, status);
1820 */
1821 dev_dbg(&i2c_client->dev, "%s: %u %d\n", __func__, *status, err);
1822 return err;
1823}
1824
1825static int ar0832_set_alternate_addr(struct i2c_client *client)
1826{
1827 int ret = 0;
1828 u8 new_addr = client->addr;
1829 u16 val;
1830
1831 /* Default slave address of ar0832 is 0x36 */
1832 client->addr = 0x36;
1833 ret = ar0832_read_reg16(client, AR0832_RESET_REG, &val);
1834 val &= ~AR0832_RESET_REG_LOCK_REG;
1835 ret |= ar0832_write_reg16(client, AR0832_RESET_REG, val);
1836 ret |= ar0832_write_reg16(client, AR0832_ID_REG, new_addr << 1);
1837
1838 if (!ret) {
1839 client->addr = new_addr;
1840 dev_dbg(&client->dev,
1841 "new slave address is set to 0x%x\n", new_addr);
1842 }
1843
1844 ret |= ar0832_read_reg16(client, AR0832_RESET_REG, &val);
1845 val |= AR0832_RESET_REG_LOCK_REG;
1846 ret |= ar0832_write_reg16(client, AR0832_RESET_REG, val);
1847
1848 return ret;
1849}
1850
1851static int ar0832_power_on(struct ar0832_dev *dev)
1852{
1853 struct i2c_client *i2c_client = dev->i2c_client;
1854 int ret = 0;
1855
1856 dev_dbg(&i2c_client->dev, "%s: ++ %d %d\n",
1857 __func__, dev->is_stereo,
1858 dev->brd_power_cnt);
1859
1860 /* Board specific power-on sequence */
1861 mutex_lock(&dev->ar0832_camera_lock);
1862 if (dev->brd_power_cnt == 0) {
1863 /* Plug 1.8V and 2.8V power to sensor */
1864 if (dev->power_rail.sen_1v8_reg) {
1865 ret = regulator_enable(dev->power_rail.sen_1v8_reg);
1866 if (ret) {
1867 dev_err(&i2c_client->dev,
1868 "%s: failed to enable vdd\n",
1869 __func__);
1870 goto fail_regulator_1v8_reg;
1871 }
1872 }
1873
1874 if (dev->power_rail.sen_2v8_reg) {
1875 ret = regulator_enable(dev->power_rail.sen_2v8_reg);
1876 if (ret) {
1877 dev_err(&i2c_client->dev,
1878 "%s: failed to enable vaa\n",
1879 __func__);
1880 goto fail_regulator_2v8_reg;
1881 }
1882 }
1883 dev->pdata->power_on(dev->is_stereo);
1884 }
1885 dev->brd_power_cnt++;
1886 mutex_unlock(&dev->ar0832_camera_lock);
1887
1888 /* Change slave address */
1889 if (i2c_client->addr)
1890 ret = ar0832_set_alternate_addr(i2c_client);
1891
1892 return 0;
1893
1894fail_regulator_2v8_reg:
1895 regulator_put(dev->power_rail.sen_2v8_reg);
1896 dev->power_rail.sen_2v8_reg = NULL;
1897 regulator_disable(dev->power_rail.sen_1v8_reg);
1898fail_regulator_1v8_reg:
1899 regulator_put(dev->power_rail.sen_1v8_reg);
1900 dev->power_rail.sen_1v8_reg = NULL;
1901 return ret;
1902}
1903
1904static void ar0832_power_off(struct ar0832_dev *dev)
1905{
1906 struct i2c_client *i2c_client = dev->i2c_client;
1907 dev_dbg(&i2c_client->dev, "%s: ++ %d\n", __func__, dev->brd_power_cnt);
1908
1909 /* Board specific power-down sequence */
1910 mutex_lock(&dev->ar0832_camera_lock);
1911
1912 if (dev->brd_power_cnt <= 0)
1913 goto ar0832_pwdn_exit;
1914
1915 if (dev->brd_power_cnt-- == 1) {
1916 /* Unplug 1.8V and 2.8V power from sensor */
1917 if (dev->power_rail.sen_2v8_reg)
1918 regulator_disable(dev->power_rail.sen_2v8_reg);
1919 if (dev->power_rail.sen_1v8_reg)
1920 regulator_disable(dev->power_rail.sen_1v8_reg);
1921 dev->pdata->power_off(dev->is_stereo);
1922 }
1923
1924ar0832_pwdn_exit:
1925 mutex_unlock(&dev->ar0832_camera_lock);
1926}
1927
1928static int ar0832_focuser_set_config(struct ar0832_dev *dev)
1929{
1930 struct i2c_client *i2c_client = dev->i2c_client;
1931 struct ar0832_reg reg_vcm_ctrl, reg_vcm_step_time;
1932 int ret = 0;
1933 u8 vcm_slew = 1;
1934
1935 /* bit15(0x80) means that VCM driver enable bit. */
1936 /* bit3(0x08) means that keep VCM(AF position) */
1937 /* while sensor is in soft standby mode during mode transitions. */
1938 u16 vcm_control_data = (0x80 << 8 | (0x08 | (vcm_slew & 0x07)));
1939 u16 vcm_step_time = 1024;
1940
1941 ar0832_get_focuser_vcm_control_regs(&reg_vcm_ctrl, vcm_control_data);
1942 ret = ar0832_write_reg16(dev->i2c_client, reg_vcm_ctrl.addr,
1943 reg_vcm_ctrl.val);
1944
1945 dev_dbg(&i2c_client->dev, "%s Reg 0x%X Value 0x%X\n", __func__,
1946 reg_vcm_ctrl.addr, reg_vcm_ctrl.val);
1947
1948 if (ret) {
1949 dev_dbg(&i2c_client->dev, "%s Error writing to register 0x%X\n",
1950 __func__, reg_vcm_ctrl.addr);
1951 return ret;
1952 }
1953
1954 ar0832_get_focuser_vcm_step_time_regs(&reg_vcm_step_time,
1955 vcm_step_time);
1956 ret = ar0832_write_reg16(dev->i2c_client, reg_vcm_step_time.addr,
1957 reg_vcm_step_time.val);
1958
1959 dev_dbg(&i2c_client->dev, "%s Reg step_time 0x%X Value 0x%X\n",
1960 __func__, reg_vcm_step_time.addr,
1961 reg_vcm_step_time.val);
1962
1963 return ret;
1964}
1965
1966static int ar0832_focuser_set_position(struct ar0832_dev *dev,
1967 u32 position)
1968{
1969 int ret = 0;
1970 struct ar0832_reg reg_data;
1971
1972 ar0832_get_focuser_data_regs(&reg_data, position);
1973 ret = ar0832_write_reg16(dev->i2c_client, reg_data.addr,
1974 reg_data.val);
1975 dev->focuser_info->last_position = position;
1976
1977 return ret;
1978}
1979
1980
1981/*
1982 * This function is not currently called as we have the hardcoded
1983 * step time in ar0832_focuser_set_config function. If we need to
1984 * compute the actual step time based on a number of clocks, we need
1985 * to use this function. The formula for computing the clock-based
1986 * step time is obtained from Aptina and is not part of external
1987 * documentation and hence this code needs to be saved.
1988 */
1989static u16 ar0832_get_focuser_vcm_step_time(struct ar0832_dev *dev)
1990{
1991 struct i2c_client *i2c_client = dev->i2c_client;
1992 int ret;
1993 u16 pll_multiplier = 0;
1994 u16 pre_pll_clk_div = 0;
1995 u16 vt_sys_clk_div = 0;
1996 u16 vt_pix_clk_div = 0;
1997 u16 vt_pix_clk_freq_mhz = 0;
1998
1999 ret = ar0832_read_reg16(dev->i2c_client, 0x306, &pll_multiplier);
2000 if (ret) {
2001 dev_err(&i2c_client->dev, "%s pll_multiplier read failed\n",
2002 __func__);
2003 }
2004
2005 ret = ar0832_read_reg16(dev->i2c_client, 0x304, &pre_pll_clk_div);
2006 if (ret) {
2007 dev_err(&i2c_client->dev, "%s pre_pll_clk_div read failed\n",
2008 __func__);
2009 }
2010
2011 ret = ar0832_read_reg16(dev->i2c_client, 0x302, &vt_sys_clk_div);
2012 if (ret) {
2013 dev_err(&i2c_client->dev, "%s vt_sys_clk_div read failed\n",
2014 __func__);
2015 }
2016
2017 ret = ar0832_read_reg16(dev->i2c_client, 0x300, &vt_pix_clk_div);
2018 if (ret) {
2019 dev_err(&i2c_client->dev, "%s vt_pix_clk_div read failed\n",
2020 __func__);
2021 }
2022
2023 vt_pix_clk_freq_mhz =
2024 (24 * pll_multiplier) / (pre_pll_clk_div * vt_sys_clk_div *
2025 vt_pix_clk_div);
2026
2027 dev_dbg(&i2c_client->dev, "%s pll_multiplier 0x%X pre_pll_clk_div 0x%X "
2028 "vt_sys_clk_div 0x%X vt_pix_clk_div 0x%X vt_pix_clk_freq_mhz 0x%X\n",
2029 __func__, pll_multiplier,
2030 pre_pll_clk_div, vt_sys_clk_div,
2031 vt_pix_clk_div, vt_pix_clk_freq_mhz);
2032
2033 return vt_pix_clk_freq_mhz;
2034
2035}
2036
2037static inline
2038int ar0832_get_sensorid(struct ar0832_dev *dev, u16 *sensor_id)
2039{
2040 int ret;
2041 struct i2c_client *i2c_client = dev->i2c_client;
2042
2043 ret = ar0832_power_on(dev);
2044 if (ret)
2045 return ret;
2046
2047 ret = ar0832_read_reg16(i2c_client, AR0832_SENSORID_REG, sensor_id);
2048 dev_dbg(&i2c_client->dev,
2049 "%s: sensor_id - %04x\n", __func__, *sensor_id);
2050
2051 ar0832_power_off(dev);
2052
2053 return ret;
2054}
2055
2056static long ar0832_ioctl(struct file *file,
2057 unsigned int cmd, unsigned long arg)
2058{
2059 int err;
2060 struct ar0832_dev *dev = file->private_data;
2061 struct i2c_client *i2c_client = dev->i2c_client;
2062 struct ar0832_mode mode;
2063 u16 pos;
2064
2065 switch (cmd) {
2066 case AR0832_IOCTL_SET_POWER_ON:
2067 dev_dbg(&i2c_client->dev, "AR0832_IOCTL_SET_POWER_ON\n");
2068 if (copy_from_user(&mode,
2069 (const void __user *)arg,
2070 sizeof(struct ar0832_mode))) {
2071 dev_err(&i2c_client->dev,
2072 "%s: AR0832_IOCTL_SET_POWER_ON failed\n",
2073 __func__);
2074 return -EFAULT;
2075 }
2076 dev->is_stereo = mode.stereo;
2077 return ar0832_power_on(dev);
2078 case AR0832_IOCTL_SET_MODE:
2079 {
2080 dev_dbg(&i2c_client->dev, "AR0832_IOCTL_SET_MODE\n");
2081 if (copy_from_user(&mode,
2082 (const void __user *)arg,
2083 sizeof(struct ar0832_mode))) {
2084 dev_err(&i2c_client->dev,
2085 "%s: AR0832_IOCTL_SET_MODE failed\n",
2086 __func__);
2087 return -EFAULT;
2088 }
2089 mutex_lock(&dev->ar0832_camera_lock);
2090 err = ar0832_set_mode(dev, &mode);
2091
2092 /*
2093 * We need to re-initialize the Focuser registers during mode
2094 * switch due to the known issue of focuser retracting
2095 */
2096 ar0832_focuser_set_config(dev);
2097 dev->focuser_info->focuser_init_flag = true;
2098
2099 /*
2100 * If the last focuser position is not at infinity when we
2101 * did the mode switch, we need to go there. Before that,
2102 * we need to come back to 0.
2103 */
2104 if (dev->focuser_info->last_position > 0) {
2105 pos = dev->focuser_info->last_position;
2106 dev_dbg(&i2c_client->dev, "%s: AR0832_IOCTL_SET_MODE: "
2107 " Move to 0, restore the backedup focuser position of %d\n",
2108 __func__, pos);
2109 ar0832_focuser_set_position(dev, 0);
2110 ar0832_msleep(10);
2111
2112 ar0832_focuser_set_position(dev, pos);
2113 ar0832_msleep(10);
2114 }
2115 mutex_unlock(&dev->ar0832_camera_lock);
2116 return err;
2117 }
2118 case AR0832_IOCTL_SET_FRAME_LENGTH:
2119 mutex_lock(&dev->ar0832_camera_lock);
2120 err = ar0832_set_frame_length(dev, (u32)arg);
2121 mutex_unlock(&dev->ar0832_camera_lock);
2122 return err;
2123 case AR0832_IOCTL_SET_COARSE_TIME:
2124 mutex_lock(&dev->ar0832_camera_lock);
2125 err = ar0832_set_coarse_time(dev, (u32)arg);
2126 mutex_unlock(&dev->ar0832_camera_lock);
2127 return err;
2128 case AR0832_IOCTL_SET_GAIN:
2129 mutex_lock(&dev->ar0832_camera_lock);
2130 err = ar0832_set_gain(dev, (u16)arg);
2131 mutex_unlock(&dev->ar0832_camera_lock);
2132 return err;
2133 case AR0832_IOCTL_GET_STATUS:
2134 {
2135 u8 status;
2136 dev_dbg(&i2c_client->dev, "AR0832_IOCTL_GET_STATUS\n");
2137 err = ar0832_get_status(dev, &status);
2138 if (err)
2139 return err;
2140 if (copy_to_user((void __user *)arg, &status,
2141 2)) {
2142 dev_err(&i2c_client->dev,
2143 "%s: AR0832_IOCTL_GET_STATUS failed\n",
2144 __func__);
2145 return -EFAULT;
2146 }
2147 return 0;
2148 }
2149 case AR0832_IOCTL_SET_SENSOR_REGION:
2150 {
2151 struct ar0832_stereo_region region;
2152 dev_dbg(&i2c_client->dev, "AR0832_IOCTL_SET_SENSOR_REGION\n");
2153 /* Right now, it doesn't do anything */
2154
2155 return 0;
2156 }
2157
2158 case AR0832_FOCUSER_IOCTL_GET_CONFIG:
2159 dev_dbg(&i2c_client->dev,
2160 "%s AR0832_FOCUSER_IOCTL_GET_CONFIG\n", __func__);
2161 if (copy_to_user((void __user *) arg,
2162 &dev->focuser_info->config,
2163 sizeof(dev->focuser_info->config))) {
2164 dev_err(&i2c_client->dev,
2165 "%s: AR0832_FOCUSER_IOCTL_GET_CONFIG failed\n",
2166 __func__);
2167 return -EFAULT;
2168 }
2169 return 0;
2170
2171 case AR0832_FOCUSER_IOCTL_SET_POSITION:
2172 dev_dbg(&i2c_client->dev,
2173 "%s AR0832_FOCUSER_IOCTL_SET_POSITION\n", __func__);
2174 mutex_lock(&dev->ar0832_camera_lock);
2175 if (dev->focuser_info->focuser_init_flag == false) {
2176 ar0832_focuser_set_config(dev);
2177 dev->focuser_info->focuser_init_flag = true;
2178 }
2179 err = ar0832_focuser_set_position(dev, (u32)arg);
2180 mutex_unlock(&dev->ar0832_camera_lock);
2181 return err;
2182
2183 case AR0832_IOCTL_GET_SENSOR_ID:
2184 dev_dbg(&i2c_client->dev,
2185 "%s AR0832_IOCTL_GET_SENSOR_ID\n", __func__);
2186
2187 if (!dev->sensor_id_data) {
2188 err = ar0832_get_sensorid(dev, &dev->sensor_id_data);
2189 if (err) {
2190 dev_err(&i2c_client->dev,
2191 "%s: failed to get sensor id\n",
2192 __func__);
2193 return -EFAULT;
2194 }
2195 }
2196
2197 if (copy_to_user((void __user *) arg,
2198 &dev->sensor_id_data,
2199 sizeof(dev->sensor_id_data))) {
2200 dev_err(&i2c_client->dev,
2201 "%s: AR0832_IOCTL_GET_SENSOR_ID failed\n",
2202 __func__);
2203 return -EFAULT;
2204 }
2205 return 0;
2206
2207 default:
2208 dev_err(&i2c_client->dev, "(error) %s NONE IOCTL\n",
2209 __func__);
2210 return -EINVAL;
2211 }
2212 return 0;
2213}
2214
2215static int ar0832_open(struct inode *inode, struct file *file)
2216{
2217 struct miscdevice *miscdev = file->private_data;
2218 struct ar0832_dev *dev = dev_get_drvdata(miscdev->parent);
2219 struct i2c_client *i2c_client = dev->i2c_client;
2220
2221 dev_dbg(&i2c_client->dev, "%s: ++\n", __func__);
2222 if (atomic_xchg(&dev->in_use, 1))
2223 return -EBUSY;
2224
2225 dev->focuser_info->focuser_init_flag = false;
2226 file->private_data = dev;
2227
2228 return 0;
2229}
2230
2231static int ar0832_release(struct inode *inode, struct file *file)
2232{
2233 struct ar0832_dev *dev = file->private_data;
2234 struct i2c_client *i2c_client = dev->i2c_client;
2235
2236 dev_dbg(&i2c_client->dev, "%s: ++\n", __func__);
2237
2238 ar0832_power_off(dev);
2239
2240 file->private_data = NULL;
2241
2242 dev->focuser_info->focuser_init_flag = false;
2243
2244 WARN_ON(!atomic_xchg(&dev->in_use, 0));
2245 return 0;
2246}
2247
2248static const struct file_operations ar0832_fileops = {
2249 .owner = THIS_MODULE,
2250 .open = ar0832_open,
2251 .unlocked_ioctl = ar0832_ioctl,
2252 .release = ar0832_release,
2253};
2254
2255static int ar0832_debugfs_show(struct seq_file *s, void *unused)
2256{
2257 struct ar0832_dev *dev = s->private;
2258 struct i2c_client *i2c_client = dev->i2c_client;
2259 int ret;
2260 u16 test_pattern_reg;
2261
2262 dev_dbg(&dev->i2c_client->dev, "%s: ++\n", __func__);
2263 if (!dev->brd_power_cnt) {
2264 dev_info(&i2c_client->dev,
2265 "%s: camera is off\n", __func__);
2266 return 0;
2267 }
2268
2269 mutex_lock(&dev->ar0832_camera_lock);
2270 ret = ar0832_read_reg16(i2c_client,
2271 AR0832_TEST_PATTERN_REG, &test_pattern_reg);
2272 mutex_unlock(&dev->ar0832_camera_lock);
2273
2274 if (ret) {
2275 dev_err(&i2c_client->dev,
2276 "%s: test pattern write failed\n", __func__);
2277 return -EFAULT;
2278 }
2279
2280 seq_printf(s, "%d\n", test_pattern_reg);
2281 return 0;
2282}
2283
2284static ssize_t ar0832_debugfs_write(
2285 struct file *file,
2286 char const __user *buf,
2287 size_t count,
2288 loff_t *offset)
2289{
2290 struct ar0832_dev *dev = ((struct seq_file *)file->private_data)->private;
2291 struct i2c_client *i2c_client = dev->i2c_client;
2292 int ret = 0;
2293 char buffer[10];
2294 u16 input, val, red = 0, green = 0, blue = 0;
2295
2296 dev_dbg(&i2c_client->dev, "%s: ++\n", __func__);
2297 if (!dev->brd_power_cnt) {
2298 dev_info(&i2c_client->dev,
2299 "%s: camera is off\n", __func__);
2300 return count;
2301 }
2302
2303 if (copy_from_user(&buffer, buf, sizeof(buffer)))
2304 goto debugfs_write_fail;
2305
2306 input = (u16)simple_strtoul(buffer, NULL, 10);
2307
2308 mutex_lock(&dev->ar0832_camera_lock);
2309 ret = ar0832_write_reg8(i2c_client, AR0832_GROUP_HOLD_REG, 0x1);
2310
2311 switch (input) {
2312 case 1: /* color bar */
2313 val = 2;
2314 break;
2315 case 2: /* Red */
2316 val = 1;
2317 red = 0x300; /* 10 bit value */
2318 green = 0;
2319 blue = 0;
2320 break;
2321 case 3: /* Green */
2322 val = 1;
2323 red = 0;
2324 green = 0x300; /* 10 bit value */
2325 blue = 0;
2326 break;
2327 case 4: /* Blue */
2328 val = 1;
2329 red = 0;
2330 green = 0;
2331 blue = 0x300; /* 10 bit value */
2332 break;
2333 default:
2334 val = 0;
2335 break;
2336 }
2337
2338 if (input == 2 || input == 3 || input == 4) {
2339 ret |= ar0832_write_reg_helper(dev,
2340 AR0832_TEST_RED_REG, red);
2341 ret |= ar0832_write_reg_helper(dev,
2342 AR0832_TEST_GREENR_REG, green);
2343 ret |= ar0832_write_reg_helper(dev,
2344 AR0832_TEST_GREENR_REG, green);
2345 ret |= ar0832_write_reg_helper(dev,
2346 AR0832_TEST_BLUE_REG, blue);
2347 }
2348
2349 ret |= ar0832_write_reg_helper(dev, AR0832_TEST_PATTERN_REG, val);
2350 ret |= ar0832_write_reg8(i2c_client, AR0832_GROUP_HOLD_REG, 0x0);
2351 mutex_unlock(&dev->ar0832_camera_lock);
2352
2353 if (ret)
2354 goto debugfs_write_fail;
2355
2356 return count;
2357
2358debugfs_write_fail:
2359 dev_err(&i2c_client->dev,
2360 "%s: test pattern write failed\n", __func__);
2361 return -EFAULT;
2362}
2363
2364static int ar0832_debugfs_open(struct inode *inode, struct file *file)
2365{
2366 struct ar0832_dev *dev = inode->i_private;
2367 struct i2c_client *i2c_client = dev->i2c_client;
2368
2369 dev_dbg(&i2c_client->dev, "%s: ++\n", __func__);
2370
2371 return single_open(file, ar0832_debugfs_show, inode->i_private);
2372}
2373
2374static const struct file_operations ar0832_debugfs_fops = {
2375 .open = ar0832_debugfs_open,
2376 .read = seq_read,
2377 .write = ar0832_debugfs_write,
2378 .llseek = seq_lseek,
2379 .release = single_release,
2380};
2381
2382static void __devexit ar0832_remove_debugfs(struct ar0832_dev *dev)
2383{
2384 struct i2c_client *i2c_client = dev->i2c_client;
2385
2386 dev_dbg(&i2c_client->dev, "%s: ++\n", __func__);
2387
2388 if (dev->debugdir)
2389 debugfs_remove_recursive(dev->debugdir);
2390 dev->debugdir = NULL;
2391}
2392
2393static void ar0832_create_debugfs(struct ar0832_dev *dev)
2394{
2395 struct dentry *ret;
2396 struct i2c_client *i2c_client = dev->i2c_client;
2397
2398 dev_dbg(&i2c_client->dev, "%s\n", __func__);
2399
2400 dev->debugdir = debugfs_create_dir(dev->dname, NULL);
2401 if (!dev->debugdir)
2402 goto remove_debugfs;
2403
2404 ret = debugfs_create_file("test_pattern",
2405 S_IWUGO | S_IRUGO,
2406 dev->debugdir, dev,
2407 &ar0832_debugfs_fops);
2408 if (!ret)
2409 goto remove_debugfs;
2410
2411 return;
2412remove_debugfs:
2413 dev_err(&i2c_client->dev, "couldn't create debugfs\n");
2414 ar0832_remove_debugfs(dev);
2415}
2416
2417static int ar0832_probe(struct i2c_client *client,
2418 const struct i2c_device_id *id)
2419{
2420 int err;
2421 struct ar0832_dev *dev = NULL;
2422 int ret;
2423
2424 dev_info(&client->dev, "ar0832: probing sensor.(id:%s)\n",
2425 id->name);
2426
2427 dev = kzalloc(sizeof(struct ar0832_dev), GFP_KERNEL);
2428 if (!dev)
2429 goto probe_fail_release;
2430
2431 dev->sensor_info = kzalloc(sizeof(struct ar0832_sensor_info),
2432 GFP_KERNEL);
2433 if (!dev->sensor_info)
2434 goto probe_fail_release;
2435
2436 dev->focuser_info = kzalloc(sizeof(struct ar0832_focuser_info),
2437 GFP_KERNEL);
2438 if (!dev->focuser_info)
2439 goto probe_fail_release;
2440
2441 /* sensor */
2442 dev->pdata = client->dev.platform_data;
2443 dev->i2c_client = client;
2444
2445 /* focuser */
2446 dev->focuser_info->config.settle_time = SETTLETIME_MS;
2447 dev->focuser_info->config.pos_low = POS_LOW;
2448 dev->focuser_info->config.pos_high = POS_HIGH;
2449
2450 snprintf(dev->dname, sizeof(dev->dname), "%s-%s",
2451 id->name, dev->pdata->id);
2452 dev->misc_dev.minor = MISC_DYNAMIC_MINOR;
2453 dev->misc_dev.name = dev->dname;
2454 dev->misc_dev.fops = &ar0832_fileops;
2455 dev->misc_dev.mode = S_IRWXUGO;
2456 dev->misc_dev.parent = &client->dev;
2457 err = misc_register(&dev->misc_dev);
2458 if (err) {
2459 dev_err(&client->dev, "Unable to register misc device!\n");
2460 ret = -ENOMEM;
2461 goto probe_fail_free;
2462 }
2463
2464 i2c_set_clientdata(client, dev);
2465 mutex_init(&dev->ar0832_camera_lock);
2466
2467 dev->power_rail.sen_1v8_reg = regulator_get(&client->dev, "vdd");
2468 if (IS_ERR_OR_NULL(dev->power_rail.sen_1v8_reg)) {
2469 dev_err(&client->dev, "%s: failed to get vdd\n",
2470 __func__);
2471 ret = PTR_ERR(dev->power_rail.sen_1v8_reg);
2472 goto probe_fail_free;
2473 }
2474
2475 dev->power_rail.sen_2v8_reg = regulator_get(&client->dev, "vaa");
2476 if (IS_ERR_OR_NULL(dev->power_rail.sen_2v8_reg)) {
2477 dev_err(&client->dev, "%s: failed to get vaa\n",
2478 __func__);
2479 ret = PTR_ERR(dev->power_rail.sen_2v8_reg);
2480 regulator_put(dev->power_rail.sen_1v8_reg);
2481 dev->power_rail.sen_1v8_reg = NULL;
2482 goto probe_fail_free;
2483 }
2484 /* create debugfs interface */
2485 ar0832_create_debugfs(dev);
2486
2487 return 0;
2488
2489probe_fail_release:
2490 dev_err(&client->dev, "%s: unable to allocate memory!\n", __func__);
2491 ret = -ENOMEM;
2492probe_fail_free:
2493 if (dev) {
2494 kfree(dev->focuser_info);
2495 kfree(dev->sensor_info);
2496 }
2497 kfree(dev);
2498 return ret;
2499}
2500
2501static int ar0832_remove(struct i2c_client *client)
2502{
2503 struct ar0832_dev *dev = i2c_get_clientdata(client);
2504
2505 if (dev->power_rail.sen_1v8_reg)
2506 regulator_put(dev->power_rail.sen_1v8_reg);
2507 if (dev->power_rail.sen_2v8_reg)
2508 regulator_put(dev->power_rail.sen_2v8_reg);
2509
2510 misc_deregister(&dev->misc_dev);
2511 if (dev) {
2512 kfree(dev->sensor_info);
2513 kfree(dev->focuser_info);
2514 }
2515
2516 ar0832_remove_debugfs(dev);
2517
2518 kfree(dev);
2519 return 0;
2520}
2521
2522static const struct i2c_device_id ar0832_id[] = {
2523 { "ar0832", 0 },
2524 { }
2525};
2526
2527static struct i2c_driver ar0832_i2c_driver = {
2528 .probe = ar0832_probe,
2529 .remove = ar0832_remove,
2530 .id_table = ar0832_id,
2531 .driver = {
2532 .name = "ar0832",
2533 .owner = THIS_MODULE,
2534 },
2535};
2536
2537static int __init ar0832_init(void)
2538{
2539 pr_info("%s: ++\n", __func__);
2540 return i2c_add_driver(&ar0832_i2c_driver);
2541}
2542
2543static void __exit ar0832_exit(void)
2544{
2545 i2c_del_driver(&ar0832_i2c_driver);
2546}
2547
2548module_init(ar0832_init);
2549module_exit(ar0832_exit);