temp revert rk change
[firefly-linux-kernel-4.4.55.git] / drivers / media / video / tegra / soc2030.c
1 /*
2  * soc2030.c - soc2030 sensor driver
3  *
4  * Copyright (C) 2010 Google Inc.
5  *
6  * Contributors:
7  *      Rebecca Schultz Zavin <rebecca@android.com>
8  *
9  * Leverage OV9640.c
10  *
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.
14  */
15
16 #include <linux/delay.h>
17 #include <linux/fs.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>
24
25 struct soc2030_info {
26         int mode;
27         struct mutex lock;
28         struct i2c_client *i2c_client;
29         struct soc2030_platform_data *pdata;
30 };
31
32 /* 10-30fps */
33 #define INDEX_30FPS 4
34 #define INDEX_24FPS 5
35 #define INDEX_20FPS 6
36 #define INDEX_17FPS 7
37 #define INDEX_15FPS 8
38 #define INDEX_13FPS 9
39 #define INDEX_12FPS 10
40 #define INDEX_11FPS 11
41 #define INDEX_10FPS 12
42
43 /*
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)
49  */
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}
146 };
147
148 /*
149  * Refresh Sequencer Mode
150  */
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}
156 };
157
158 /*
159  * Refresh Sequencer State
160  */
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}
166 };
167
168 /*
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.
172  * 800X600 15-30fps
173  */
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}
234 };
235
236 /*
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.
240  * 1600X1200 10-15fps
241  */
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}
254 };
255
256 /*
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.
260  * 1280X720 15-30fps
261  */
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}
338 };
339
340 /*
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.
344  * 24MCLK_81SCLK
345  */
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}
363 };
364
365 /*
366  * SetMode Sequence for errata. Phase 0. Sensor Dependent.
367  * This is usually given by the FAE or the sensor vendor.
368  */
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}
376 };
377
378 /*
379  * SetMode Sequence for errata. Phase 0. Sensor Dependent.
380  * This is usually given by the FAE or the sensor vendor.
381  */
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}
388
389 };
390
391
392 /*
393  * SetMode Sequence for LCC. Phase 0. Sensor Dependent.
394  * This is usually given by the FAE or the sensor vendor.
395  */
396 static struct soc2030_regs SetLensCorrectionSequence[] = {
397         {WRITE_REG_DATA, 0x3210, 0x01B8},       /*Enable gamma/sharpen/ccm/LC*/
398         {REG_TABLE_END, 0x0000, 0x0000}
399
400 };
401 /*
402  * SetMode Sequence for low light. Phase 0. Sensor Dependent.
403  * This is usually given by the FAE or the sensor vendor.
404  */
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}
441
442 };
443 /*
444  * SetMode Sequence for CCM. Phase 0. Sensor Dependent.
445  * This is usually given by the FAE or the sensor vendor.
446  */
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}
457
458 };
459
460 /*
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.
464  */
465 static struct soc2030_regs SetCCMAutoSequence[] = {
466
467         {REG_TABLE_END, 0x0000, 0x0000}
468 };
469
470 /*
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.
475  */
476 static struct soc2030_regs SetDenoiseSequence[] = {
477         {REG_TABLE_END, 0x0000, 0x0000}
478
479 };
480
481 /*
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
486  */
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}
633 };
634
635 /*
636  * Stock AWB CCM from Aptina Demo2 Dev kit.
637  */
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}
684 };
685
686 static struct soc2030_regs WbIncandescentSequence[] = {
687         {REG_TABLE_END, 0x0000, 0x0000}
688 };
689
690 static struct soc2030_regs WbFluorescentSequence[] = {
691         {REG_TABLE_END, 0x0000, 0x0000}
692 };
693
694 static struct soc2030_regs WbDaylightSequence[] = {
695         {REG_TABLE_END, 0x0000, 0x0000}
696 };
697
698 static struct soc2030_regs WbCloudydaylightSequence[] = {
699         {REG_TABLE_END, 0x0000, 0x0000}
700 };
701
702 static struct soc2030_regs WbNightSequence[] = {
703         {REG_TABLE_END, 0x0000, 0x0000}
704 };
705
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,
713 };
714
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}
719 };
720
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}
725 };
726
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}
731 };
732
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}
737 };
738
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}
744 };
745
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}
750 };
751
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}
757 };
758
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,
767 };
768
769 static struct soc2030_mode modes[] = {
770         {800, 600, 30, mode_800x600},
771         {1600, 1200, 15, mode_1600x1200},
772         {1280, 720, 30, mode_1280x720},
773 };
774
775 static int soc2030_read_reg(struct i2c_client *client, u16 addr, u16 *val)
776 {
777         int err;
778         struct i2c_msg msg[2];
779         unsigned char data[4];
780
781         if (!client->adapter)
782                 return -ENODEV;
783
784         msg[0].addr = client->addr;
785         msg[0].flags = 0;
786         msg[0].len = 2;
787         msg[0].buf = data;
788         data[0] = (u8) (addr >> 8);
789         data[1] = (u8) (addr & 0xff);
790
791         msg[1].addr = client->addr;
792         msg[1].flags = I2C_M_RD;
793         msg[1].len = 2;
794         msg[1].buf = data + 2;
795         err = i2c_transfer(client->adapter, msg, 2);
796
797         if (err != 2)
798                 return -EIO;
799
800         *val = ((u16)(data[2] << 8)) | data[3];
801
802         return 0;
803 }
804
805 static int soc2030_write_reg(struct i2c_client *client, u16 addr, u16 val)
806 {
807         int err;
808         struct i2c_msg msg;
809         unsigned char data[4];
810         int retry = 0;
811
812         if (!client->adapter)
813                 return -ENODEV;
814
815         data[0] = (u8) (addr >> 8);
816         data[1] = (u8) (addr & 0xff);
817         data[2] = (u8) (val >> 8);
818         data[3] = (u8) (val & 0xff);
819
820         msg.addr = client->addr;
821         msg.flags = 0;
822         msg.len = 4;
823         msg.buf = data;
824
825         do {
826                 err = i2c_transfer(client->adapter, &msg, 1);
827                 if (err == 1)
828                         return 0;
829                 retry++;
830                 pr_err("soc2030: i2c transfer failed, retrying %x %x\n",
831                        addr, val);
832                 msleep(3);
833         } while (retry <= SOC2030_MAX_RETRIES);
834
835         return retry > SOC2030_MAX_RETRIES ? -EIO : err;
836 }
837
838 static int soc2030_write_bits(struct i2c_client *client, u16 addr, u16 val,
839                               u16 mask)
840 {
841         u16 rval, wval;
842         int err;
843
844         err = soc2030_read_reg(client, addr, &rval);
845         if (err) {
846                 pr_err("soc2030: error reading from %x\n", addr);
847                 return err;
848         }
849         wval = ((~mask) & rval) | val;
850         err = soc2030_write_reg(client, addr, wval);
851         return err;
852 }
853
854 static int soc2030_clear_bits(struct i2c_client *client, u16 addr, u16 bits)
855 {
856         return soc2030_write_bits(client, addr, 0, bits);
857 }
858
859 static int soc2030_set_bits(struct i2c_client *client, u16 addr, u16 bits)
860 {
861         return soc2030_write_bits(client, addr, bits, bits);
862 }
863
864 static int soc2030_poll(struct i2c_client *client, u16 addr, u16 expected,
865                         u16 mask)
866 {
867         u16 val;
868         int try, err;
869
870         for (try = 0; try < SOC2030_POLL_RETRIES; try++) {
871                 err = soc2030_read_reg(client, addr, &val);
872                 if (err)
873                         return err;
874                 if (expected == (val & mask)) {
875                         pr_info("poll success %x: %x == %x & %x\n", addr,
876                                 expected, val, mask);
877                         return 0;
878                 }
879                 msleep(SOC2030_POLL_WAITMS);
880         }
881         pr_err("soc2030: poll for %x == ([%x]=%x) & %x failed\n", expected,
882                addr, val, mask);
883         return -EIO;
884
885 }
886
887 static int soc2030_poll_bit_set(struct i2c_client *client, u16 addr, u16 bit)
888 {
889         return soc2030_poll(client, addr, bit, bit);
890 }
891
892 static int soc2030_poll_bit_clear(struct i2c_client *client, u16 addr, u16 bit)
893 {
894         return soc2030_poll(client, addr, 0, bit);
895 }
896
897 static int soc2030_write_xdma_reg(struct i2c_client *client, u16 addr, u16 val)
898 {
899         int err;
900
901         err = soc2030_write_reg(client, 0x098c, addr);
902         if (err)
903                 return err;
904         err = soc2030_write_reg(client, 0x0990, val);
905         if (err)
906                 return err;
907         return 0;
908 }
909
910 static int soc2030_read_xdma_reg(struct i2c_client *client, u16 addr, u16 *val)
911 {
912         int err;
913
914         err = soc2030_write_reg(client, 0x098c, addr);
915         if (err)
916                 return err;
917         err = soc2030_read_reg(client, 0x0990, val);
918         if (err)
919                 return err;
920         return 0;
921 }
922
923 static int soc2030_poll_xdma_reg(struct i2c_client *client, u16 addr,
924                                  u16 expected)
925 {
926         int try, err;
927         u16 val;
928
929         for (try = 0; try < SOC2030_POLL_RETRIES; try++) {
930                 err = soc2030_read_xdma_reg(client, addr, &val);
931                 if (err)
932                         return err;
933                 if (expected == val) {
934                         pr_info("poll success %x: %x == %x\n", addr,
935                                 expected, val);
936                         return 0;
937                 }
938                 msleep(SOC2030_POLL_WAITMS);
939         }
940         pr_err("soc2030: xdma poll for %x == ([%x]=%x) failed\n", expected,
941                addr, val);
942         return -EINVAL;
943 }
944
945 static int soc2030_write_table(struct i2c_client *client,
946                                const struct soc2030_regs table[])
947 {
948         int err = -EIO;
949         const struct soc2030_regs *next;
950
951         for (next = table; next->op != REG_TABLE_END; next++) {
952
953                 switch (next->op) {
954                 case WRITE_REG_DATA:
955                 {
956                         err = soc2030_write_reg(client, next->addr,
957                                 next->val);
958                         if (err)
959                                 return err;
960                         break;
961                 }
962                 case WRITE_REG_BIT_H:
963                 {
964                         err = soc2030_set_bits(client, next->addr,
965                                 next->val);
966                         if (err)
967                                 return err;
968                         break;
969                 }
970                 case WRITE_REG_BIT_L:
971                 {
972                         err = soc2030_clear_bits(client, next->addr,
973                                 next->val);
974                         if (err)
975                                 return err;
976                         break;
977                 }
978                 case POLL_REG_DATA:
979                 {
980                         err = soc2030_poll(client, next->addr,
981                                 next->val, 0xFFFF);
982                         if (err)
983                                 return err;
984                         break;
985                 }
986                 case POLL_REG_BIT_H:
987                 {
988                         err = soc2030_poll_bit_set(client, next->addr,
989                                 next->val);
990                         if (err)
991                                 return err;
992                         break;
993                 }
994                 case POLL_REG_BIT_L:
995                 {
996                         err = soc2030_poll_bit_clear(client, next->addr,
997                                 next->val);
998                         if (err)
999                                 return err;
1000                         break;
1001                 }
1002                 case WRITE_VAR_DATA:
1003                 {
1004                         err = soc2030_write_xdma_reg(client, next->addr,
1005                                 next->val);
1006                         if (err)
1007                                 return err;
1008                         break;
1009                 }
1010                 case POLL_VAR_DATA:
1011                 {
1012                         err = soc2030_poll_xdma_reg(client, next->addr,
1013                                 next->val);
1014                         if (err)
1015                                 return err;
1016                         break;
1017                 }
1018                 case DELAY_MS:
1019                 {
1020                         msleep(next->val);
1021                         break;
1022                 }
1023                 default:
1024                         pr_err("%s: invalid operation 0x%x\n", __func__,
1025                                 next->op);
1026                         return err;
1027                 }
1028         }
1029         return 0;
1030 }
1031
1032 static int soc2030_set_mode(struct soc2030_info *info,
1033                             struct soc2030_mode *mode)
1034 {
1035         int sensor_mode, err;
1036         int index;
1037         int mode_count;
1038
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))
1044                         break;
1045         }
1046         if (index == mode_count) {
1047                 pr_err("%s: invalid resolution supplied to set mode %d %d\n",
1048                        __func__, mode->xres, mode->yres);
1049                 return -EINVAL;
1050         }
1051         sensor_mode = index;
1052
1053         if (info->mode == -1) {
1054
1055                 /* write the pll table */
1056                 soc2030_write_table(info->i2c_client, pll_table);
1057
1058                 err = soc2030_write_table(info->i2c_client, base_mode);
1059                 if (err)
1060                         return err;
1061
1062                 /* load errata settings */
1063                 err = soc2030_write_table(info->i2c_client,
1064                                                 SetRev2ErrataSequence);
1065                 if (err)
1066                         return err;
1067
1068                 /* load lens correction */
1069                 err = soc2030_write_table(info->i2c_client,
1070                                                 SetLensCorrectionSequence);
1071                 if (err)
1072                         return err;
1073
1074                 /* low light optimization settings */
1075                 err = soc2030_write_table(info->i2c_client,
1076                                                 SetLowLightSequence);
1077                 if (err)
1078                         return err;
1079
1080                 /* Base denoise settings (for all resolutions) */
1081                 err = soc2030_write_table(info->i2c_client,
1082                                                 SetDenoiseSequence);
1083                 if (err)
1084                         return err;
1085
1086                 /* white balance common settings */
1087                 err = soc2030_write_table(info->i2c_client,
1088                                                 SetCCMCommonSequence);
1089                 if (err)
1090                         return err;
1091
1092                 /* auto white balance settings */
1093                 err = soc2030_write_table(info->i2c_client,
1094                                                 SetCCMAutoSequence);
1095                 if (err)
1096                         return err;
1097
1098                 /* load patch */
1099                 err = soc2030_write_table(info->i2c_client,
1100                                                 SetRev3PatchSequence);
1101                 if (err)
1102                         return err;
1103
1104                 /* Wake MCU */
1105                 err = soc2030_write_table(info->i2c_client,
1106                                                 WakeMcuSequence);
1107                 if (err)
1108                         return err;
1109         }
1110
1111         /* set context */
1112         err = soc2030_write_table(info->i2c_client, modes[sensor_mode].regset);
1113         if (err)
1114                 return err;
1115
1116         err = soc2030_write_table(info->i2c_client, refresh_mode);
1117         if (err)
1118                 return err;
1119
1120         err = soc2030_write_table(info->i2c_client, refresh_state);
1121         if (err)
1122                 return err;
1123
1124         info->mode = sensor_mode;
1125         return 0;
1126 }
1127
1128
1129 static int soc2030_get_status(struct soc2030_info *info, u16 *status)
1130 {
1131         int err;
1132
1133         *status = 0;
1134         err = soc2030_read_xdma_reg(info->i2c_client, 0x0, status);
1135         if (err)
1136                 return err;
1137         err = soc2030_read_xdma_reg(info->i2c_client, 0x2104, status + 1);
1138         if (err)
1139                 return err;
1140         err = soc2030_read_xdma_reg(info->i2c_client, 0x2703, status + 2);
1141         if (err)
1142                 return err;
1143         err = soc2030_read_xdma_reg(info->i2c_client, 0x2705, status + 3);
1144         if (err)
1145                 return err;
1146         err = soc2030_read_xdma_reg(info->i2c_client, 0x2737, status + 4);
1147         if (err)
1148                 return err;
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],
1151                 status[4]);
1152         return 0;
1153 }
1154
1155
1156 static long soc2030_ioctl(struct file *file,
1157                           unsigned int cmd, unsigned long arg)
1158 {
1159         int err = 0;
1160         struct soc2030_info *info = file->private_data;
1161
1162         err = mutex_lock_interruptible(&info->lock);
1163         if (err)
1164                 return err;
1165
1166         switch (cmd) {
1167         case SOC2030_IOCTL_SET_MODE:
1168         {
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__);
1174                         err = -EFAULT;
1175                         break;
1176                 }
1177
1178                 err = soc2030_set_mode(info, &mode);
1179                 break;
1180         }
1181         case SOC2030_IOCTL_SET_PRIVATE:
1182         {
1183                 int size = SOC2030_MAX_PRIVATE_SIZE *
1184                         sizeof(struct soc2030_regs);
1185                 struct soc2030_regs *reg_sequence =
1186                         kzalloc(size, GFP_KERNEL);
1187
1188                 if (NULL == reg_sequence) {
1189                         pr_info("%s: Error allocating memory\n", __func__);
1190                         err = -ENOMEM;
1191                         break;
1192                 }
1193
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);
1198                         err = -EFAULT;
1199                         break;
1200                 }
1201                 err = soc2030_write_table(info->i2c_client, reg_sequence);
1202                 kfree(reg_sequence);
1203                 break;
1204         }
1205         case SOC2030_IOCTL_GET_STATUS:
1206         {
1207                 u16 status[5];
1208
1209                 err = soc2030_get_status(info, status);
1210                 if (err)
1211                         break;
1212                 if (copy_to_user((void __user *)arg, &status,
1213                                  10)) {
1214                         pr_info("%s: Error copying to user\n", __func__);
1215                         err = -EFAULT;
1216                 }
1217                 break;
1218         }
1219         case SOC2030_IOCTL_GET_MODES:
1220         {
1221                 if (copy_to_user((void __user *)arg, &modes,
1222                                  sizeof(modes))) {
1223                         pr_info("%s: Error copying to user\n", __func__);
1224                         err = -EFAULT;
1225                 }
1226                 break;
1227         }
1228         case SOC2030_IOCTL_GET_NUM_MODES:
1229         {
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__);
1234                         err = -EFAULT;
1235                 }
1236                 break;
1237         }
1238         case SOC2030_IOCTL_SET_EFFECT:
1239         {
1240
1241                 if ((unsigned int)arg >= EFFECT_MAX) {
1242                         err = -EINVAL;
1243                         break;
1244                 }
1245                 err = soc2030_write_table(info->i2c_client,
1246                                 effect_table[(unsigned int)arg]);
1247                 if (err)
1248                         break;
1249
1250                 err = soc2030_write_table(info->i2c_client, refresh_state);
1251                 break;
1252         }
1253         case SOC2030_IOCTL_SET_WHITEBALANCE:
1254         {
1255
1256                 if ((unsigned int)arg >= WB_MAX) {
1257                         err = -EINVAL;
1258                         break;
1259                 }
1260
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);
1265                 if (err)
1266                         break;
1267
1268                 err = soc2030_write_table(info->i2c_client,
1269                                 SetCCMCommonSequence);
1270                 if (err)
1271                         break;
1272
1273                 err = soc2030_write_table(info->i2c_client,
1274                                 wb_table[(unsigned int)arg]);
1275                 break;
1276         }
1277
1278         case SOC2030_IOCTL_SET_EXP_COMP:
1279         {
1280                 int req_ev = (int)arg;
1281                 int step;
1282                 int step_size = 0;
1283                 int ev_step = 0;
1284                 int new_target = EXP_TARGET;
1285
1286                 if ((req_ev > SOC_EV_MAX) || (req_ev < SOC_EV_MIN)) {
1287                         pr_err("%s: Invalid exposure parameter %i\n",
1288                                 __func__, req_ev);
1289                         err = -EINVAL;
1290                         break;
1291                 }
1292
1293                 if (req_ev < 0) {
1294                         ev_step = -EXP_TARGET;
1295                         /* step a little less than 1 f-stop */
1296                         step_size = 2;
1297                 } else if (req_ev > 0) {
1298                         ev_step = 0x100 - EXP_TARGET;
1299                         /* step 1/2  f-stop */
1300                         step_size = 4;
1301                 }
1302
1303                 new_target = EXP_TARGET;
1304
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;
1309                 }
1310                 if (new_target < 0) {
1311                         pr_err("%s: Bad exposure target %i (0x%x)\n",
1312                                 __func__, new_target,
1313                                (u16)new_target);
1314                         err = -EINVAL;
1315                         break;
1316                 }
1317
1318                 err = soc2030_write_xdma_reg(info->i2c_client,
1319                                                 0xA24F, (u16)new_target);
1320                 if (err) {
1321                         pr_err("%s: Failed to update EV parameter\n", __func__);
1322                         break;
1323                 }
1324                 err = soc2030_write_table(info->i2c_client, refresh_state);
1325                 if (err)
1326                         pr_err("%s: Failed to update EV parameter\n", __func__);
1327                 break;
1328         }
1329
1330         default:
1331                 err = -EINVAL;
1332                 pr_err("%s: unknown IOCTL cmd 0x%x\n", __func__, cmd);
1333                 break;
1334         }
1335
1336         mutex_unlock(&info->lock);
1337         return err;
1338 }
1339
1340 static struct soc2030_info *info;
1341
1342 static int soc2030_open(struct inode *inode, struct file *file)
1343 {
1344         info->mode = -1;
1345         file->private_data = info;
1346         if (info->pdata && info->pdata->power_on)
1347                 info->pdata->power_on();
1348         return 0;
1349 }
1350
1351 int soc2030_release(struct inode *inode, struct file *file)
1352 {
1353         if (info->pdata && info->pdata->power_off)
1354                 info->pdata->power_off();
1355         file->private_data = NULL;
1356         return 0;
1357 }
1358
1359
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,
1365 };
1366
1367 static struct miscdevice soc2030_device = {
1368         .minor = MISC_DYNAMIC_MINOR,
1369         .name = "soc2030",
1370         .fops = &soc2030_fileops,
1371 };
1372
1373 static int soc2030_probe(struct i2c_client *client,
1374                          const struct i2c_device_id *id)
1375 {
1376         int err;
1377
1378         pr_info("soc2030: probing sensor.\n");
1379
1380         info = kzalloc(sizeof(struct soc2030_info), GFP_KERNEL);
1381         if (!info) {
1382                 pr_err("soc2030: Unable to allocate memory!\n");
1383                 return -ENOMEM;
1384         }
1385
1386         err = misc_register(&soc2030_device);
1387         if (err) {
1388                 pr_err("soc2030: Unable to register misc device!\n");
1389                 kfree(info);
1390                 return err;
1391         }
1392
1393         mutex_init(&info->lock);
1394         info->pdata = client->dev.platform_data;
1395         info->i2c_client = client;
1396         i2c_set_clientdata(client, info);
1397         return 0;
1398 }
1399
1400 static int soc2030_remove(struct i2c_client *client)
1401 {
1402         struct soc2030_info *info;
1403         info = i2c_get_clientdata(client);
1404         misc_deregister(&soc2030_device);
1405         kfree(info);
1406         return 0;
1407 }
1408
1409 static const struct i2c_device_id soc2030_id[] = {
1410         { "soc2030", 0 },
1411         { },
1412 };
1413
1414 MODULE_DEVICE_TABLE(i2c, soc2030_id);
1415
1416 static struct i2c_driver soc2030_i2c_driver = {
1417         .driver = {
1418                 .name = "soc2030",
1419                 .owner = THIS_MODULE,
1420         },
1421         .probe = soc2030_probe,
1422         .remove = soc2030_remove,
1423         .id_table = soc2030_id,
1424 };
1425
1426 static int __init soc2030_init(void)
1427 {
1428         return i2c_add_driver(&soc2030_i2c_driver);
1429 }
1430
1431 static void __exit soc2030_exit(void)
1432 {
1433         i2c_del_driver(&soc2030_i2c_driver);
1434 }
1435
1436 module_init(soc2030_init);
1437 module_exit(soc2030_exit);
1438