1
2 /*
3 * A V4L2 driver for AR0238 Raw cameras.
4 *
5 * Copyright (c) 2017 by Allwinnertech Co., Ltd. http://www.allwinnertech.com
6 *
7 * Authors: Zhao Wei <zhaowei@allwinnertech.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14 #include <linux/init.h>
15 #include <linux/module.h>
16 #include <linux/slab.h>
17 #include <linux/i2c.h>
18 #include <linux/delay.h>
19 #include <linux/videodev2.h>
20 #include <linux/clk.h>
21 #include <media/v4l2-device.h>
22 #include <media/v4l2-mediabus.h>
23 #include <linux/io.h>
24
25 #include "camera.h"
26 #include "sensor_helper.h"
27
28 MODULE_AUTHOR("lwj");
29 MODULE_DESCRIPTION("A low-level driver for AR0238 sensors");
30 MODULE_LICENSE("GPL");
31
32 /* define module timing */
33 #define MCLK (27*1000*1000)
34 #define VREF_POL V4L2_MBUS_VSYNC_ACTIVE_HIGH
35 #define HREF_POL V4L2_MBUS_HSYNC_ACTIVE_HIGH
36 #define CLK_POL V4L2_MBUS_PCLK_SAMPLE_FALLING
37 #define V4L2_IDENT_SENSOR 0x1256
38
39 /* 1106 for 27Mhz */
40 #define VMAX 1106
41
42 #define HDR 0
43 /*
44 * Our nominal (default) frame rate.
45 */
46
47 #define SENSOR_FRAME_RATE 30
48
49 /*
50 * The AR0238 i2c address
51 */
52 #define I2C_ADDR 0x20
53
54 #define SENSOR_NUM 0x2
55 #define SENSOR_NAME "ar0238"
56 #define SENSOR_NAME_2 "ar0238_2"
57
58 struct cfg_array { /* coming later */
59 struct regval_list *regs;
60 int size;
61 };
62
63 /*
64 * The default register settings
65 *
66 */
67
68 static struct regval_list sensor_default_regs[] = {
69
70 };
71
72 #if HDR
73 static struct regval_list sensor_hdr_regs[] = {
74 /*HDR*/ {0x301A, 0x0001},
75 {REG_DLY, 0xd0},
76 {0x301A, 0x10D8},
77 {REG_DLY, 0x64},
78 {0x3088, 0x816A},
79 {0x3086, 0x4558},
80 {0x3086, 0x729B},
81 {0x3086, 0x4A31},
82 {0x3086, 0x4342},
83 {0x3086, 0x8E03},
84 {0x3086, 0x2A14},
85 {0x3086, 0x4578},
86 {0x3086, 0x7B3D},
87 {0x3086, 0xFF3D},
88 {0x3086, 0xFF3D},
89 {0x3086, 0xEA2A},
90 {0x3086, 0x043D},
91 {0x3086, 0x102A},
92 {0x3086, 0x052A},
93 {0x3086, 0x1535},
94 {0x3086, 0x2A05},
95 {0x3086, 0x3D10},
96 {0x3086, 0x4558},
97 {0x3086, 0x2A04},
98 {0x3086, 0x2A14},
99 {0x3086, 0x3DFF},
100 {0x3086, 0x3DFF},
101 {0x3086, 0x3DEA},
102 {0x3086, 0x2A04},
103 {0x3086, 0x622A},
104 {0x3086, 0x288E},
105 {0x3086, 0x0036},
106 {0x3086, 0x2A08},
107 {0x3086, 0x3D64},
108 {0x3086, 0x7A3D},
109 {0x3086, 0x0444},
110 {0x3086, 0x2C4B},
111 {0x3086, 0x8F00},
112 {0x3086, 0x430C},
113 {0x3086, 0x2D63},
114 {0x3086, 0x4316},
115 {0x3086, 0x2A90},
116 {0x3086, 0x3E06},
117 {0x3086, 0x2A98},
118 {0x3086, 0x168E},
119 {0x3086, 0x032A},
120 {0x3086, 0xFC5C},
121 {0x3086, 0x1D57},
122 {0x3086, 0x5449},
123 {0x3086, 0x5F53},
124 {0x3086, 0x0553},
125 {0x3086, 0x074D},
126 {0x3086, 0x2BF8},
127 {0x3086, 0x1016},
128 {0x3086, 0x4C08},
129 {0x3086, 0x5556},
130 {0x3086, 0x2BB8},
131 {0x3086, 0x2B98},
132 {0x3086, 0x4E11},
133 {0x3086, 0x2904},
134 {0x3086, 0x2984},
135 {0x3086, 0x2994},
136 {0x3086, 0x605C},
137 {0x3086, 0x195C},
138 {0x3086, 0x1B45},
139 {0x3086, 0x4845},
140 {0x3086, 0x0845},
141 {0x3086, 0x8829},
142 {0x3086, 0xB68E},
143 {0x3086, 0x012A},
144 {0x3086, 0xF83E},
145 {0x3086, 0x022A},
146 {0x3086, 0xFA3F},
147 {0x3086, 0x095C},
148 {0x3086, 0x1B29},
149 {0x3086, 0xB23F},
150 {0x3086, 0x0C3E},
151 {0x3086, 0x023E},
152 {0x3086, 0x135C},
153 {0x3086, 0x133F},
154 {0x3086, 0x113E},
155 {0x3086, 0x0B5F},
156 {0x3086, 0x2B90},
157 {0x3086, 0x2B80},
158 {0x3086, 0x3E06},
159 {0x3086, 0x162A},
160 {0x3086, 0xF23F},
161 {0x3086, 0x103E},
162 {0x3086, 0x0160},
163 {0x3086, 0x29A2},
164 {0x3086, 0x29A3},
165 {0x3086, 0x5F4D},
166 {0x3086, 0x192A},
167 {0x3086, 0xFA29},
168 {0x3086, 0x8345},
169 {0x3086, 0xA83E},
170 {0x3086, 0x072A},
171 {0x3086, 0xFB3E},
172 {0x3086, 0x2945},
173 {0x3086, 0x8821},
174 {0x3086, 0x3E08},
175 {0x3086, 0x2AFA},
176 {0x3086, 0x5D29},
177 {0x3086, 0x9288},
178 {0x3086, 0x102B},
179 {0x3086, 0x048B},
180 {0x3086, 0x1685},
181 {0x3086, 0x8D48},
182 {0x3086, 0x4D4E},
183 {0x3086, 0x2B80},
184 {0x3086, 0x4C0B},
185 {0x3086, 0x3F2B},
186 {0x3086, 0x2AF2},
187 {0x3086, 0x3F10},
188 {0x3086, 0x3E01},
189 {0x3086, 0x6029},
190 {0x3086, 0x8229},
191 {0x3086, 0x8329},
192 {0x3086, 0x435C},
193 {0x3086, 0x155F},
194 {0x3086, 0x4D19},
195 {0x3086, 0x2AFA},
196 {0x3086, 0x4558},
197 {0x3086, 0x8E00},
198 {0x3086, 0x2A98},
199 {0x3086, 0x3F06},
200 {0x3086, 0x1244},
201 {0x3086, 0x4A04},
202 {0x3086, 0x4316},
203 {0x3086, 0x0543},
204 {0x3086, 0x1658},
205 {0x3086, 0x4316},
206 {0x3086, 0x5A43},
207 {0x3086, 0x1606},
208 {0x3086, 0x4316},
209 {0x3086, 0x0743},
210 {0x3086, 0x168E},
211 {0x3086, 0x032A},
212 {0x3086, 0x9C45},
213 {0x3086, 0x787B},
214 {0x3086, 0x3F07},
215 {0x3086, 0x2A9D},
216 {0x3086, 0x3E2E},
217 {0x3086, 0x4558},
218 {0x3086, 0x253E},
219 {0x3086, 0x068E},
220 {0x3086, 0x012A},
221 {0x3086, 0x988E},
222 {0x3086, 0x0012},
223 {0x3086, 0x444B},
224 {0x3086, 0x0343},
225 {0x3086, 0x2D46},
226 {0x3086, 0x4316},
227 {0x3086, 0xA343},
228 {0x3086, 0x165D},
229 {0x3086, 0x0D29},
230 {0x3086, 0x4488},
231 {0x3086, 0x102B},
232 {0x3086, 0x0453},
233 {0x3086, 0x0D8B},
234 {0x3086, 0x1685},
235 {0x3086, 0x448E},
236 {0x3086, 0x032A},
237 {0x3086, 0xFC5C},
238 {0x3086, 0x1D8D},
239 {0x3086, 0x6057},
240 {0x3086, 0x5417},
241 {0x3086, 0xFF17},
242 {0x3086, 0x4B2A},
243 {0x3086, 0xF43E},
244 {0x3086, 0x062A},
245 {0x3086, 0xFC49},
246 {0x3086, 0x5F53},
247 {0x3086, 0x0553},
248 {0x3086, 0x074D},
249 {0x3086, 0x2BF8},
250 {0x3086, 0x1016},
251 {0x3086, 0x4C08},
252 {0x3086, 0x5556},
253 {0x3086, 0x2BB8},
254 {0x3086, 0x2B98},
255 {0x3086, 0x4E11},
256 {0x3086, 0x2904},
257 {0x3086, 0x2984},
258 {0x3086, 0x2994},
259 {0x3086, 0x605C},
260 {0x3086, 0x195C},
261 {0x3086, 0x1B45},
262 {0x3086, 0x4845},
263 {0x3086, 0x0845},
264 {0x3086, 0x8829},
265 {0x3086, 0xB68E},
266 {0x3086, 0x012A},
267 {0x3086, 0xF83E},
268 {0x3086, 0x022A},
269 {0x3086, 0xFA3F},
270 {0x3086, 0x095C},
271 {0x3086, 0x1B29},
272 {0x3086, 0xB23F},
273 {0x3086, 0x0C3E},
274 {0x3086, 0x023E},
275 {0x3086, 0x135C},
276 {0x3086, 0x133F},
277 {0x3086, 0x113E},
278 {0x3086, 0x0B5F},
279 {0x3086, 0x2B90},
280 {0x3086, 0x2B80},
281 {0x3086, 0x3E10},
282 {0x3086, 0x2AF2},
283 {0x3086, 0x3F10},
284 {0x3086, 0x3E01},
285 {0x3086, 0x6029},
286 {0x3086, 0xA229},
287 {0x3086, 0xA35F},
288 {0x3086, 0x4D1C},
289 {0x3086, 0x2AFA},
290 {0x3086, 0x2983},
291 {0x3086, 0x45A8},
292 {0x3086, 0x3E07},
293 {0x3086, 0x2AFB},
294 {0x3086, 0x3E29},
295 {0x3086, 0x4588},
296 {0x3086, 0x243E},
297 {0x3086, 0x082A},
298 {0x3086, 0xFA5D},
299 {0x3086, 0x2992},
300 {0x3086, 0x8810},
301 {0x3086, 0x2B04},
302 {0x3086, 0x8B16},
303 {0x3086, 0x868D},
304 {0x3086, 0x484D},
305 {0x3086, 0x4E2B},
306 {0x3086, 0x804C},
307 {0x3086, 0x0B3F},
308 {0x3086, 0x332A},
309 {0x3086, 0xF23F},
310 {0x3086, 0x103E},
311 {0x3086, 0x0160},
312 {0x3086, 0x2982},
313 {0x3086, 0x2983},
314 {0x3086, 0x2943},
315 {0x3086, 0x5C15},
316 {0x3086, 0x5F4D},
317 {0x3086, 0x1C2A},
318 {0x3086, 0xFA45},
319 {0x3086, 0x588E},
320 {0x3086, 0x002A},
321 {0x3086, 0x983F},
322 {0x3086, 0x064A},
323 {0x3086, 0x739D},
324 {0x3086, 0x0A43},
325 {0x3086, 0x160B},
326 {0x3086, 0x4316},
327 {0x3086, 0x8E03},
328 {0x3086, 0x2A9C},
329 {0x3086, 0x4578},
330 {0x3086, 0x3F07},
331 {0x3086, 0x2A9D},
332 {0x3086, 0x3E12},
333 {0x3086, 0x4558},
334 {0x3086, 0x3F04},
335 {0x3086, 0x8E01},
336 {0x3086, 0x2A98},
337 {0x3086, 0x8E00},
338 {0x3086, 0x9176},
339 {0x3086, 0x9C77},
340 {0x3086, 0x9C46},
341 {0x3086, 0x4416},
342 {0x3086, 0x1690},
343 {0x3086, 0x7A12},
344 {0x3086, 0x444B},
345 {0x3086, 0x4A00},
346 {0x3086, 0x4316},
347 {0x3086, 0x6343},
348 {0x3086, 0x1608},
349 {0x3086, 0x4316},
350 {0x3086, 0x5043},
351 {0x3086, 0x1665},
352 {0x3086, 0x4316},
353 {0x3086, 0x6643},
354 {0x3086, 0x168E},
355 {0x3086, 0x032A},
356 {0x3086, 0x9C45},
357 {0x3086, 0x783F},
358 {0x3086, 0x072A},
359 {0x3086, 0x9D5D},
360 {0x3086, 0x0C29},
361 {0x3086, 0x4488},
362 {0x3086, 0x102B},
363 {0x3086, 0x0453},
364 {0x3086, 0x0D8B},
365 {0x3086, 0x1686},
366 {0x3086, 0x3E1F},
367 {0x3086, 0x4558},
368 {0x3086, 0x283E},
369 {0x3086, 0x068E},
370 {0x3086, 0x012A},
371 {0x3086, 0x988E},
372 {0x3086, 0x008D},
373 {0x3086, 0x6012},
374 {0x3086, 0x444B},
375 {0x3086, 0xB92C},
376 {0x3086, 0x2C2C},
377 {0x3086, 0x2C2C},
378 {0x3086, 0x2C2C},
379 {0x30B0, 0x1A38},
380 {0x31AC, 0x100C},
381 {0x302A, 0x0008},
382 {0x302C, 0x0001},
383 {0x302E, 0x0002},
384 {0x3030, 0x002C},
385 {0x3036, 0x000C},
386 {0x3038, 0x0001},
387 {0x3002, 0x0000},
388 {0x3004, 0x0000},
389 {0x3006, 0x0437},
390 {0x3008, 0x0787},
391 {0x300A, 0x04BE},
392 {0x300C, 0x07F8},
393 {0x3012, 0x0440},
394 {0x30A2, 0x0001},
395 {0x30A6, 0x0001},
396 {0x30AE, 0x0001},
397 {0x30A8, 0x0001},
398 {0x3082, 0x0008},
399 {0x3040, 0x0000},
400 {0x31AE, 0x0301},
401 {0x3064, 0x1802},
402 {0x3EEE, 0xA0AA},
403 {0x30BA, 0x762C},
404 {0x3F4A, 0x0F70},
405 {0x309E, 0x016C},
406 {0x3092, 0x006F},
407 {0x3EE4, 0x9937},
408 {0x3EE6, 0x3863},
409 {0x3EEC, 0x3B0C},
410 {0x30B0, 0x1A3A},
411 {0x30B0, 0x1A3A},
412 {0x30BA, 0x762C},
413 {0x30B0, 0x1A3A},
414 {0x30B0, 0x0A3A},
415 {0x3EEA, 0x2837},
416 {0x3ECC, 0x4E2D},
417 {0x3ED2, 0xFEA6},
418 {0x3ED6, 0x2CB3},
419 {0x3EEA, 0x2819},
420 {0x30B0, 0x1A3A},
421 {0x306E, 0x2418},
422 {0x3064, 0x1802},
423 {0x31AC, 0x0C0C},
424 {0x31D0, 0x0000},
425 {0x318E, 0x9000},
426 {0x301A, 0x10DC},
427 {0x3100, 0x0000},
428 };
429 #endif
430
431 static struct regval_list sensor_1080p30_regs[] = {
432 {0x301A, 0x0001},
433 {0x301A, 0x10D8},
434 {REG_DLY, 0x0020},
435 {0x3088, 0x8000},
436 {0x3086, 0x4558},
437 {0x3086, 0x72A6},
438 {0x3086, 0x4A31},
439 {0x3086, 0x4342},
440 {0x3086, 0x8E03},
441 {0x3086, 0x2A14},
442 {0x3086, 0x4578},
443 {0x3086, 0x7B3D},
444 {0x3086, 0xFF3D},
445 {0x3086, 0xFF3D},
446 {0x3086, 0xEA2A},
447 {0x3086, 0x043D},
448 {0x3086, 0x102A},
449 {0x3086, 0x052A},
450 {0x3086, 0x1535},
451 {0x3086, 0x2A05},
452 {0x3086, 0x3D10},
453 {0x3086, 0x4558},
454 {0x3086, 0x2A04},
455 {0x3086, 0x2A14},
456 {0x3086, 0x3DFF},
457 {0x3086, 0x3DFF},
458 {0x3086, 0x3DEA},
459 {0x3086, 0x2A04},
460 {0x3086, 0x622A},
461 {0x3086, 0x288E},
462 {0x3086, 0x0036},
463 {0x3086, 0x2A08},
464 {0x3086, 0x3D64},
465 {0x3086, 0x7A3D},
466 {0x3086, 0x0444},
467 {0x3086, 0x2C4B},
468 {0x3086, 0xA403},
469 {0x3086, 0x430D},
470 {0x3086, 0x2D46},
471 {0x3086, 0x4316},
472 {0x3086, 0x2A90},
473 {0x3086, 0x3E06},
474 {0x3086, 0x2A98},
475 {0x3086, 0x5F16},
476 {0x3086, 0x530D},
477 {0x3086, 0x1660},
478 {0x3086, 0x3E4C},
479 {0x3086, 0x2904},
480 {0x3086, 0x2984},
481 {0x3086, 0x8E03},
482 {0x3086, 0x2AFC},
483 {0x3086, 0x5C1D},
484 {0x3086, 0x5754},
485 {0x3086, 0x495F},
486 {0x3086, 0x5305},
487 {0x3086, 0x5307},
488 {0x3086, 0x4D2B},
489 {0x3086, 0xF810},
490 {0x3086, 0x164C},
491 {0x3086, 0x0955},
492 {0x3086, 0x562B},
493 {0x3086, 0xB82B},
494 {0x3086, 0x984E},
495 {0x3086, 0x1129},
496 {0x3086, 0x9460},
497 {0x3086, 0x5C19},
498 {0x3086, 0x5C1B},
499 {0x3086, 0x4548},
500 {0x3086, 0x4508},
501 {0x3086, 0x4588},
502 {0x3086, 0x29B6},
503 {0x3086, 0x8E01},
504 {0x3086, 0x2AF8},
505 {0x3086, 0x3E02},
506 {0x3086, 0x2AFA},
507 {0x3086, 0x3F09},
508 {0x3086, 0x5C1B},
509 {0x3086, 0x29B2},
510 {0x3086, 0x3F0C},
511 {0x3086, 0x3E03},
512 {0x3086, 0x3E15},
513 {0x3086, 0x5C13},
514 {0x3086, 0x3F11},
515 {0x3086, 0x3E0F},
516 {0x3086, 0x5F2B},
517 {0x3086, 0x902B},
518 {0x3086, 0x803E},
519 {0x3086, 0x062A},
520 {0x3086, 0xF23F},
521 {0x3086, 0x103E},
522 {0x3086, 0x0160},
523 {0x3086, 0x29A2},
524 {0x3086, 0x29A3},
525 {0x3086, 0x5F4D},
526 {0x3086, 0x1C2A},
527 {0x3086, 0xFA29},
528 {0x3086, 0x8345},
529 {0x3086, 0xA83E},
530 {0x3086, 0x072A},
531 {0x3086, 0xFB3E},
532 {0x3086, 0x6745},
533 {0x3086, 0x8824},
534 {0x3086, 0x3E08},
535 {0x3086, 0x2AFA},
536 {0x3086, 0x5D29},
537 {0x3086, 0x9288},
538 {0x3086, 0x102B},
539 {0x3086, 0x048B},
540 {0x3086, 0x1686},
541 {0x3086, 0x8D48},
542 {0x3086, 0x4D4E},
543 {0x3086, 0x2B80},
544 {0x3086, 0x4C0B},
545 {0x3086, 0x3F36},
546 {0x3086, 0x2AF2},
547 {0x3086, 0x3F10},
548 {0x3086, 0x3E01},
549 {0x3086, 0x6029},
550 {0x3086, 0x8229},
551 {0x3086, 0x8329},
552 {0x3086, 0x435C},
553 {0x3086, 0x155F},
554 {0x3086, 0x4D1C},
555 {0x3086, 0x2AFA},
556 {0x3086, 0x4558},
557 {0x3086, 0x8E00},
558 {0x3086, 0x2A98},
559 {0x3086, 0x3F0A},
560 {0x3086, 0x4A0A},
561 {0x3086, 0x4316},
562 {0x3086, 0x0B43},
563 {0x3086, 0x168E},
564 {0x3086, 0x032A},
565 {0x3086, 0x9C45},
566 {0x3086, 0x783F},
567 {0x3086, 0x072A},
568 {0x3086, 0x9D3E},
569 {0x3086, 0x305D},
570 {0x3086, 0x2944},
571 {0x3086, 0x8810},
572 {0x3086, 0x2B04},
573 {0x3086, 0x530D},
574 {0x3086, 0x4558},
575 {0x3086, 0x3E08},
576 {0x3086, 0x8E01},
577 {0x3086, 0x2A98},
578 {0x3086, 0x8E00},
579 {0x3086, 0x76A7},
580 {0x3086, 0x77A7},
581 {0x3086, 0x4644},
582 {0x3086, 0x1616},
583 {0x3086, 0xA57A},
584 {0x3086, 0x1244},
585 {0x3086, 0x4B18},
586 {0x3086, 0x4A04},
587 {0x3086, 0x4316},
588 {0x3086, 0x0643},
589 {0x3086, 0x1605},
590 {0x3086, 0x4316},
591 {0x3086, 0x0743},
592 {0x3086, 0x1658},
593 {0x3086, 0x4316},
594 {0x3086, 0x5A43},
595 {0x3086, 0x1645},
596 {0x3086, 0x588E},
597 {0x3086, 0x032A},
598 {0x3086, 0x9C45},
599 {0x3086, 0x787B},
600 {0x3086, 0x3F07},
601 {0x3086, 0x2A9D},
602 {0x3086, 0x530D},
603 {0x3086, 0x8B16},
604 {0x3086, 0x863E},
605 {0x3086, 0x2345},
606 {0x3086, 0x5825},
607 {0x3086, 0x3E10},
608 {0x3086, 0x8E01},
609 {0x3086, 0x2A98},
610 {0x3086, 0x8E00},
611 {0x3086, 0x3E10},
612 {0x3086, 0x8D60},
613 {0x3086, 0x1244},
614 {0x3086, 0x4BB9},
615 {0x3086, 0x2C2C},
616 {0x3086, 0x2C2C},
617 {0x301A, 0x10D8},
618 {0x30B0, 0x1A38},
619 {0x31AC, 0x0C0C},
620 {0x302A, 0x0008},
621 {0x302C, 0x0001},
622 {0x302E, 0x0002},
623 {0x3030, 0x002C},
624 {0x3036, 0x000C},
625 {0x3038, 0x0001},
626 {0x3002, 0x0000},
627 {0x3004, 0x0000},
628 {0x3006, 0x043F},
629 {0x3008, 0x0787},
630 {0x300A, 0x0452},
631 {0x300C, 0x045E},
632 {0x3012, 0x0416},
633 {0x30A2, 0x0001},
634 {0x30A6, 0x0001},
635 {0x30AE, 0x0001},
636 {0x30A8, 0x0001},
637 {0x3040, 0x0000},
638 {0x31AE, 0x0301},
639 {0x3082, 0x0009},
640 {0x30BA, 0x760C},
641 {0x3100, 0x0000},
642 {0x3060, 0x000B},
643 {0x31D0, 0x0000},
644 {0x3064, 0x1802},
645 {0x3EEE, 0xA0AA},
646 {0x30BA, 0x762C},
647 {0x3F4A, 0x0F70},
648 {0x309E, 0x016C},
649 {0x3092, 0x006F},
650 {0x3EE4, 0x9937},
651 {0x3EE6, 0x3863},
652 {0x3EEC, 0x3B0C},
653 {0x30B0, 0x1A3A},
654 {0x30B0, 0x1A3A},
655 {0x30BA, 0x762C},
656 {0x30B0, 0x1A3A},
657 {0x30B0, 0x0A3A},
658 {0x3EEA, 0x2838},
659 {0x3ECC, 0x4E2D},
660 {0x3ED2, 0xFEA6},
661 {0x3ED6, 0x2CB3},
662 {0x3EEA, 0x2819},
663 {0x30B0, 0x1A3A},
664 {0x306E, 0x2418},
665 {0x301A, 0x10DC},
666
667 /*slave mode*/
668 /*{0x30CE, 0x0010},
669 {0x301A, 0x19DC},*/
670 };
671
672 /*
673 * Here we'll try to encapsulate the changes for just the output
674 * video format.
675 *
676 */
677
678 static struct regval_list sensor_fmt_raw[] = {
679
680 };
681
682 /*
683 * Code for dealing with controls.
684 * fill with different sensor module
685 * different sensor module has different settings here
686 * if not support the follow function ,retrun -EINVAL
687 */
688
sensor_g_exp(struct v4l2_subdev * sd,__s32 * value)689 static int sensor_g_exp(struct v4l2_subdev *sd, __s32 *value)
690 {
691 struct sensor_info *info = to_state(sd);
692
693 *value = info->exp;
694 sensor_dbg("sensor_get_exposure = %d\n", info->exp);
695 return 0;
696 }
697
sensor_s_exp(struct v4l2_subdev * sd,unsigned int exp_val)698 static int sensor_s_exp(struct v4l2_subdev *sd, unsigned int exp_val)
699 {
700 struct sensor_info *info = to_state(sd);
701
702 sensor_dbg("sensor_set_exposure = %d\n", exp_val);
703 if (exp_val > 0xffffff)
704 exp_val = 0xfffff0;
705 if (exp_val < 16)
706 exp_val = 16;
707
708 exp_val = (exp_val) >> 4; /* rounding to 1 */
709
710 sensor_write(sd, 0x3012, exp_val); /* coarse integration time */
711
712 info->exp = exp_val;
713 return 0;
714 }
715
sensor_g_gain(struct v4l2_subdev * sd,__s32 * value)716 static int sensor_g_gain(struct v4l2_subdev *sd, __s32 *value)
717 {
718 struct sensor_info *info = to_state(sd);
719
720 *value = info->gain;
721 sensor_dbg("sensor_get_gain = %d\n", info->gain);
722 return 0;
723 }
724
sensor_s_gain(struct v4l2_subdev * sd,int gain_val)725 static int sensor_s_gain(struct v4l2_subdev *sd, int gain_val)
726 {
727 struct sensor_info *info = to_state(sd);
728 unsigned short dig_gain = 0x80; /* 1 times digital gain */
729
730 if (gain_val < 16)
731 gain_val = 16;
732
733 gain_val = gain_val * 100;
734
735 if (16 * 100 <= gain_val && gain_val < (103 * 16))
736 sensor_write(sd, 0x3060, 0x0000);
737 else if ((103 * 16) <= gain_val && gain_val < (107 * 16))
738 sensor_write(sd, 0x3060, 0x0001);
739 else if ((107 * 16) <= gain_val && gain_val < (110 * 16))
740 sensor_write(sd, 0x3060, 0x0002);
741 else if ((110 * 16) <= gain_val && gain_val < (114 * 16))
742 sensor_write(sd, 0x3060, 0x0003);
743 else if ((114 * 16) <= gain_val && gain_val < (119 * 16))
744 sensor_write(sd, 0x3060, 0x0004);
745 else if ((119 * 16) <= gain_val && gain_val < (123 * 16))
746 sensor_write(sd, 0x3060, 0x0005);
747 else if ((123 * 16) <= gain_val && gain_val < (128 * 16))
748 sensor_write(sd, 0x3060, 0x0006);
749 else if ((128 * 16) <= gain_val && gain_val < (133 * 16))
750 sensor_write(sd, 0x3060, 0x0007);
751 else if ((133 * 16) <= gain_val && gain_val < (139 * 16))
752 sensor_write(sd, 0x3060, 0x0008);
753 else if ((139 * 16) <= gain_val && gain_val < (145 * 16))
754 sensor_write(sd, 0x3060, 0x0009);
755 else if ((145 * 16) <= gain_val && gain_val < (152 * 16))
756 sensor_write(sd, 0x3060, 0x000a);
757 else if ((152 * 16) <= gain_val && gain_val < (160 * 16))
758 sensor_write(sd, 0x3060, 0x000b);
759 else if ((160 * 16) <= gain_val && gain_val < (168 * 16))
760 sensor_write(sd, 0x3060, 0x000c);
761 else if ((168 * 16) <= gain_val && gain_val < (178 * 16))
762 sensor_write(sd, 0x3060, 0x000d);
763 else if ((178 * 16) <= gain_val && gain_val < (188 * 16))
764 sensor_write(sd, 0x3060, 0x000e);
765 else if ((188 * 16) <= gain_val && gain_val < (200 * 16))
766 sensor_write(sd, 0x3060, 0x000f);
767 else if ((200 * 16) <= gain_val && gain_val < (213 * 16)) {
768 sensor_write(sd, 0x3060, 0x0010);
769 dig_gain = gain_val * 128 / (200 * 16);
770 } else if ((213 * 16) <= gain_val && gain_val < (229 * 16)) {
771 sensor_write(sd, 0x3060, 0x0012);
772 dig_gain = gain_val * 128 / (213 * 16);
773 } else if ((229 * 16) <= gain_val && gain_val < (246 * 16)) {
774 sensor_write(sd, 0x3060, 0x0014);
775 dig_gain = gain_val * 128 / (229 * 16);
776 } else if ((246 * 16) <= gain_val && gain_val < (267 * 16)) {
777 sensor_write(sd, 0x3060, 0x0016);
778 dig_gain = gain_val * 128 / (246 * 16);
779 } else if ((267 * 16) <= gain_val && gain_val < (291 * 16)) {
780 sensor_write(sd, 0x3060, 0x0018);
781 dig_gain = gain_val * 128 / (267 * 16);
782 } else if ((291 * 16) <= gain_val && gain_val < (320 * 16)) {
783 sensor_write(sd, 0x3060, 0x001a);
784 dig_gain = gain_val * 128 / (291 * 16);
785 } else if ((320 * 16) <= gain_val && gain_val < (356 * 16)) {
786 sensor_write(sd, 0x3060, 0x001c);
787 dig_gain = gain_val * 128 / (320 * 16);
788 } else if ((356 * 16) <= gain_val && gain_val < (400 * 16)) {
789 sensor_write(sd, 0x3060, 0x001e);
790 dig_gain = gain_val * 128 / (356 * 16);
791 } else if ((400 * 16) <= gain_val && gain_val < (457 * 16)) {
792 sensor_write(sd, 0x3060, 0x0020);
793 dig_gain = gain_val * 128 / (400 * 16);
794 } else if ((457 * 16) <= gain_val && gain_val < (533 * 16)) {
795 sensor_write(sd, 0x3060, 0x0024);
796 dig_gain = gain_val * 128 / (457 * 16);
797 } else if ((533 * 16) <= gain_val && gain_val < (640 * 16)) {
798 sensor_write(sd, 0x3060, 0x0028);
799 dig_gain = gain_val * 128 / (533 * 16);
800 } else if ((640 * 16) <= gain_val && gain_val < (800 * 16)) {
801 sensor_write(sd, 0x3060, 0x002c);
802 dig_gain = gain_val * 128 / (640 * 16);
803 } else if ((800 * 16) <= gain_val) {
804 sensor_write(sd, 0x3060, 0x0030);
805 dig_gain = gain_val * 128 / (800 * 16);
806 }
807
808 sensor_write(sd, 0x305e, dig_gain);
809
810 info->gain = gain_val;
811 return 0;
812 }
813
814 static int ar0238_sensor_vts;
sensor_s_exp_gain(struct v4l2_subdev * sd,struct sensor_exp_gain * exp_gain)815 static int sensor_s_exp_gain(struct v4l2_subdev *sd,
816 struct sensor_exp_gain *exp_gain)
817 {
818 int exp_val, gain_val, shutter, frame_length;
819 struct sensor_info *info = to_state(sd);
820
821 exp_val = exp_gain->exp_val;
822 gain_val = exp_gain->gain_val;
823 if (gain_val < 1 * 16)
824 gain_val = 16;
825 if (gain_val > 64 * 16 - 1)
826 gain_val = 64 * 16 - 1;
827 if (exp_val > 0xfffff)
828 exp_val = 0xfffff;
829
830 shutter = exp_val / 16;
831 if (shutter > ar0238_sensor_vts - 4)
832 frame_length = shutter + 4;
833 else
834 frame_length = ar0238_sensor_vts;
835
836 sensor_s_exp(sd, exp_val);
837 sensor_s_gain(sd, gain_val);
838 info->exp = exp_val;
839 info->gain = gain_val;
840 return 0;
841 }
sensor_s_sw_stby(struct v4l2_subdev * sd,int on_off)842 static int sensor_s_sw_stby(struct v4l2_subdev *sd, int on_off)
843 {
844 int ret;
845 unsigned short rdtmp;
846 ret = sensor_read(sd, 0x301a, &rdtmp);
847 if (ret != 0)
848 return ret;
849 if (on_off == 1)
850 sensor_write(sd, 0x301a, (rdtmp & 0xfffb));
851 else
852 sensor_write(sd, 0x301a, rdtmp | 0x04);
853 return ret;
854 }
855
856 /*
857 * Stuff that knows about the sensor.
858 */
sensor_power(struct v4l2_subdev * sd,int on)859 static int sensor_power(struct v4l2_subdev *sd, int on)
860 {
861 int ret = 0;
862
863 switch (on) {
864 case STBY_ON:
865 sensor_dbg("CSI_SUBDEV_STBY_ON!\n");
866 ret = sensor_s_sw_stby(sd, CSI_GPIO_HIGH);
867 if (ret < 0)
868 sensor_err("soft stby falied!\n");
869 usleep_range(10000, 12000);
870 cci_lock(sd);
871 vin_gpio_write(sd, PWDN, CSI_GPIO_HIGH);
872 cci_unlock(sd);
873 vin_set_mclk(sd, OFF);
874 break;
875 case STBY_OFF:
876 sensor_dbg("CSI_SUBDEV_STBY_OFF!\n");
877 cci_lock(sd);
878 vin_set_mclk_freq(sd, MCLK);
879 vin_set_mclk(sd, ON);
880 usleep_range(10000, 12000);
881 vin_gpio_write(sd, PWDN, CSI_GPIO_LOW);
882 usleep_range(10000, 12000);
883 ret = sensor_s_sw_stby(sd, CSI_GPIO_LOW);
884 if (ret < 0)
885 sensor_err("soft stby off falied!\n");
886 cci_unlock(sd);
887 break;
888 case PWR_ON:
889 sensor_dbg("CSI_SUBDEV_PWR_ON!\n");
890 cci_lock(sd);
891 vin_gpio_set_status(sd, RESET, 1);
892 vin_gpio_set_status(sd, POWER_EN, 1);
893 vin_gpio_write(sd, RESET, CSI_GPIO_HIGH);
894 vin_gpio_write(sd, POWER_EN, CSI_GPIO_LOW);
895 usleep_range(1000, 1200);
896 vin_set_pmu_channel(sd, AVDD, ON);
897 vin_gpio_write(sd, POWER_EN, CSI_GPIO_HIGH);
898 vin_set_pmu_channel(sd, IOVDD, ON);
899 vin_set_pmu_channel(sd, DVDD, ON);
900 usleep_range(1000, 1200);
901 vin_set_mclk_freq(sd, MCLK);
902 vin_set_mclk(sd, ON);
903 usleep_range(2000, 2200);
904 vin_gpio_write(sd, RESET, CSI_GPIO_LOW);
905 usleep_range(2000, 2200);
906 vin_gpio_write(sd, RESET, CSI_GPIO_HIGH);
907 usleep_range(1000, 1200);
908 sensor_dbg("CSI_SUBDEV_STBY_OFF!\n");
909 cci_unlock(sd);
910 break;
911 case PWR_OFF:
912 sensor_dbg("CSI_SUBDEV_PWR_OFF!\n");
913 cci_lock(sd);
914 vin_set_pmu_channel(sd, DVDD, OFF);
915 vin_gpio_write(sd, POWER_EN, CSI_GPIO_LOW);
916 vin_set_pmu_channel(sd, IOVDD, OFF);
917 vin_set_pmu_channel(sd, AVDD, OFF);
918 vin_set_mclk(sd, OFF);
919 cci_unlock(sd);
920 usleep_range(10000, 12000);
921 break;
922 default:
923 return -EINVAL;
924 }
925
926 return 0;
927 }
928
sensor_reset(struct v4l2_subdev * sd,u32 val)929 static int sensor_reset(struct v4l2_subdev *sd, u32 val)
930 {
931 switch (val) {
932 case 0:
933 vin_gpio_write(sd, RESET, CSI_GPIO_LOW);
934 usleep_range(10000, 12000);
935 break;
936 case 1:
937 vin_gpio_write(sd, RESET, CSI_GPIO_HIGH);
938 usleep_range(10000, 12000);
939 break;
940 default:
941 return -EINVAL;
942 }
943 return 0;
944 }
945
sensor_detect(struct v4l2_subdev * sd)946 static int sensor_detect(struct v4l2_subdev *sd)
947 {
948 unsigned short rdval = 0;
949 int cnt = 0;
950
951 sensor_read(sd, 0x3000, &rdval);
952 sensor_print("V4L2_IDENT_SENSOR = 0x%x\n", rdval);
953
954 while ((rdval != V4L2_IDENT_SENSOR) && (cnt < 5)) {
955 sensor_read(sd, 0x3000, &rdval);
956 sensor_print("retry = %d, V4L2_IDENT_SENSOR = %x\n", cnt, rdval);
957 cnt++;
958 }
959
960 if (rdval != V4L2_IDENT_SENSOR)
961 return -ENODEV;
962
963 return 0;
964 }
965
sensor_init(struct v4l2_subdev * sd,u32 val)966 static int sensor_init(struct v4l2_subdev *sd, u32 val)
967 {
968 int ret;
969 struct sensor_info *info = to_state(sd);
970 sensor_dbg("sensor_init\n");
971
972 /*Make sure it is a target sensor */
973 ret = sensor_detect(sd);
974 if (ret) {
975 sensor_err("chip found is not an target chip.\n");
976 return ret;
977 }
978
979 info->focus_status = 0;
980 info->low_speed = 0;
981 info->width = HD1080_WIDTH;
982 info->height = HD1080_HEIGHT;
983 info->hflip = 0;
984 info->vflip = 0;
985 info->gain = 0;
986
987 info->tpf.numerator = 1;
988 info->tpf.denominator = 30; /* 30fps */
989 info->preview_first_flag = 1;
990
991 return 0;
992 }
993
sensor_ioctl(struct v4l2_subdev * sd,unsigned int cmd,void * arg)994 static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
995 {
996 int ret = 0;
997 struct sensor_info *info = to_state(sd);
998 switch (cmd) {
999 case GET_CURRENT_WIN_CFG:
1000 if (info->current_wins != NULL) {
1001 memcpy(arg,
1002 info->current_wins,
1003 sizeof(struct sensor_win_size));
1004 ret = 0;
1005 } else {
1006 sensor_err("empty wins!\n");
1007 ret = -1;
1008 }
1009 break;
1010 case SET_FPS:
1011 ret = 0;
1012 break;
1013 case VIDIOC_VIN_SENSOR_EXP_GAIN:
1014 ret = sensor_s_exp_gain(sd, (struct sensor_exp_gain *)arg);
1015 break;
1016 case VIDIOC_VIN_SENSOR_CFG_REQ:
1017 sensor_cfg_req(sd, (struct sensor_config *)arg);
1018 break;
1019 default:
1020 return -EINVAL;
1021 }
1022 return ret;
1023 }
1024
1025 /*
1026 * Store information about the video data format.
1027 */
1028 static struct sensor_format_struct sensor_formats[] = {
1029 {
1030 .desc = "Raw RGB Bayer",
1031 .mbus_code = MEDIA_BUS_FMT_SGRBG12_1X12,
1032 .regs = sensor_fmt_raw,
1033 .regs_size = ARRAY_SIZE(sensor_fmt_raw),
1034 .bpp = 1,
1035 },
1036 };
1037
1038 #define N_FMTS ARRAY_SIZE(sensor_formats)
1039
1040 /*
1041 * Then there is the issue of window sizes. Try to capture the info here.
1042 */
1043
1044 static struct sensor_win_size sensor_win_sizes[] = {
1045 /* 1080P */
1046 {
1047 .width = HD1080_WIDTH,
1048 .height = HD1080_HEIGHT,
1049 .hoffset = 0,
1050 .voffset = 0,
1051 .hts = 2236,
1052 .vts = VMAX,
1053 .pclk = 18562500,
1054 .fps_fixed = 30,
1055 .bin_factor = 1,
1056 .intg_min = 1 << 4,
1057 .intg_max = (VMAX - 4) << 4,
1058 .gain_min = 1 << 4,
1059 .gain_max = 32 << 4,
1060 .regs = sensor_1080p30_regs,
1061 .regs_size = ARRAY_SIZE(sensor_1080p30_regs),
1062 .set_size = NULL,
1063 },
1064 };
1065
1066 #define N_WIN_SIZES (ARRAY_SIZE(sensor_win_sizes))
1067
sensor_g_mbus_config(struct v4l2_subdev * sd,unsigned int pad,struct v4l2_mbus_config * cfg)1068 static int sensor_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad,
1069 struct v4l2_mbus_config *cfg)
1070 {
1071 cfg->type = V4L2_MBUS_PARALLEL;
1072 cfg->flags = V4L2_MBUS_MASTER | VREF_POL | HREF_POL | CLK_POL;
1073
1074 return 0;
1075 }
1076
sensor_g_ctrl(struct v4l2_ctrl * ctrl)1077 static int sensor_g_ctrl(struct v4l2_ctrl *ctrl)
1078 {
1079 struct sensor_info *info =
1080 container_of(ctrl->handler, struct sensor_info, handler);
1081 struct v4l2_subdev *sd = &info->sd;
1082
1083 switch (ctrl->id) {
1084 case V4L2_CID_GAIN:
1085 return sensor_g_gain(sd, &ctrl->val);
1086 case V4L2_CID_EXPOSURE:
1087 return sensor_g_exp(sd, &ctrl->val);
1088 }
1089 return -EINVAL;
1090 }
1091
sensor_s_ctrl(struct v4l2_ctrl * ctrl)1092 static int sensor_s_ctrl(struct v4l2_ctrl *ctrl)
1093 {
1094 struct sensor_info *info =
1095 container_of(ctrl->handler, struct sensor_info, handler);
1096 struct v4l2_subdev *sd = &info->sd;
1097
1098 switch (ctrl->id) {
1099 case V4L2_CID_GAIN:
1100 return sensor_s_gain(sd, ctrl->val);
1101 case V4L2_CID_EXPOSURE:
1102 return sensor_s_exp(sd, ctrl->val);
1103 }
1104 return -EINVAL;
1105 }
1106
sensor_reg_init(struct sensor_info * info)1107 static int sensor_reg_init(struct sensor_info *info)
1108 {
1109 int ret;
1110 struct v4l2_subdev *sd = &info->sd;
1111 struct sensor_format_struct *sensor_fmt = info->fmt;
1112 struct sensor_win_size *wsize = info->current_wins;
1113
1114 ret = sensor_write_array(sd, sensor_default_regs,
1115 ARRAY_SIZE(sensor_default_regs));
1116 if (ret < 0) {
1117 sensor_err("write sensor_default_regs error\n");
1118 return ret;
1119 }
1120
1121 sensor_dbg("sensor_reg_init\n");
1122 sensor_write_array(sd, sensor_fmt->regs, sensor_fmt->regs_size);
1123
1124 if (wsize->regs)
1125 sensor_write_array(sd, wsize->regs, wsize->regs_size);
1126
1127 if (wsize->set_size)
1128 wsize->set_size(sd);
1129
1130 info->width = wsize->width;
1131 info->height = wsize->height;
1132 ar0238_sensor_vts = wsize->vts;
1133
1134 sensor_print("s_fmt set width = %d, height = %d\n", wsize->width,
1135 wsize->height);
1136
1137 return 0;
1138 }
1139
sensor_s_stream(struct v4l2_subdev * sd,int enable)1140 static int sensor_s_stream(struct v4l2_subdev *sd, int enable)
1141 {
1142 struct sensor_info *info = to_state(sd);
1143 sensor_print("%s on = %d, %d*%d %x\n", __func__, enable,
1144 info->current_wins->width,
1145 info->current_wins->height, info->fmt->mbus_code);
1146
1147 if (!enable) {
1148 vin_gpio_set_status(sd, SM_HS, 0);
1149 vin_gpio_set_status(sd, SM_VS, 0);
1150 return 0;
1151 } else {
1152 vin_gpio_set_status(sd, SM_VS, 2);
1153 vin_gpio_set_status(sd, SM_HS, 2);
1154 }
1155 return sensor_reg_init(info);
1156 }
1157
1158 /* ----------------------------------------------------------------------- */
1159
1160 static const struct v4l2_ctrl_ops sensor_ctrl_ops = {
1161 .g_volatile_ctrl = sensor_g_ctrl,
1162 .s_ctrl = sensor_s_ctrl,
1163 };
1164
1165 static const struct v4l2_subdev_core_ops sensor_core_ops = {
1166 .reset = sensor_reset,
1167 .init = sensor_init,
1168 .s_power = sensor_power,
1169 .ioctl = sensor_ioctl,
1170 #ifdef CONFIG_COMPAT
1171 .compat_ioctl32 = sensor_compat_ioctl32,
1172 #endif
1173 };
1174
1175 static const struct v4l2_subdev_video_ops sensor_video_ops = {
1176 .s_stream = sensor_s_stream,
1177 };
1178
1179 static const struct v4l2_subdev_pad_ops sensor_pad_ops = {
1180 .enum_mbus_code = sensor_enum_mbus_code,
1181 .enum_frame_size = sensor_enum_frame_size,
1182 .get_fmt = sensor_get_fmt,
1183 .set_fmt = sensor_set_fmt,
1184 .get_mbus_config = sensor_g_mbus_config,
1185 };
1186
1187 static const struct v4l2_subdev_ops sensor_ops = {
1188 .core = &sensor_core_ops,
1189 .video = &sensor_video_ops,
1190 .pad = &sensor_pad_ops,
1191 };
1192
1193 /* ----------------------------------------------------------------------- */
1194 static struct cci_driver cci_drv[] = {
1195 {
1196 .name = SENSOR_NAME,
1197 .addr_width = CCI_BITS_16,
1198 .data_width = CCI_BITS_16,
1199 }, {
1200 .name = SENSOR_NAME_2,
1201 .addr_width = CCI_BITS_16,
1202 .data_width = CCI_BITS_16,
1203 }
1204 };
1205
sensor_init_controls(struct v4l2_subdev * sd,const struct v4l2_ctrl_ops * ops)1206 static int sensor_init_controls(struct v4l2_subdev *sd, const struct v4l2_ctrl_ops *ops)
1207 {
1208 struct sensor_info *info = to_state(sd);
1209 struct v4l2_ctrl_handler *handler = &info->handler;
1210 struct v4l2_ctrl *ctrl;
1211 int ret = 0;
1212
1213 v4l2_ctrl_handler_init(handler, 2);
1214
1215 v4l2_ctrl_new_std(handler, ops, V4L2_CID_GAIN, 1 * 1600,
1216 256 * 1600, 1, 1 * 1600);
1217 ctrl = v4l2_ctrl_new_std(handler, ops, V4L2_CID_EXPOSURE, 0,
1218 65536 * 16, 1, 0);
1219 if (ctrl != NULL)
1220 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
1221
1222 if (handler->error) {
1223 ret = handler->error;
1224 v4l2_ctrl_handler_free(handler);
1225 }
1226
1227 sd->ctrl_handler = handler;
1228
1229 return ret;
1230 }
1231
1232 static int sensor_dev_id;
1233
sensor_probe(struct i2c_client * client,const struct i2c_device_id * id)1234 static int sensor_probe(struct i2c_client *client,
1235 const struct i2c_device_id *id)
1236 {
1237 struct v4l2_subdev *sd;
1238 struct sensor_info *info;
1239 int i;
1240
1241 info = kzalloc(sizeof(struct sensor_info), GFP_KERNEL);
1242 if (info == NULL)
1243 return -ENOMEM;
1244 sd = &info->sd;
1245
1246 if (client) {
1247 for (i = 0; i < SENSOR_NUM; i++) {
1248 if (!strcmp(cci_drv[i].name, client->name))
1249 break;
1250 }
1251 cci_dev_probe_helper(sd, client, &sensor_ops, &cci_drv[i]);
1252 } else {
1253 cci_dev_probe_helper(sd, client, &sensor_ops, &cci_drv[sensor_dev_id++]);
1254 }
1255
1256 sensor_init_controls(sd, &sensor_ctrl_ops);
1257
1258 mutex_init(&info->lock);
1259
1260 #ifdef CONFIG_SAME_I2C
1261 info->sensor_i2c_addr = I2C_ADDR >> 1;
1262 #endif
1263 info->fmt = &sensor_formats[0];
1264 info->fmt_pt = &sensor_formats[0];
1265 info->win_pt = &sensor_win_sizes[0];
1266 info->fmt_num = N_FMTS;
1267 info->win_size_num = N_WIN_SIZES;
1268 info->sensor_field = V4L2_FIELD_NONE;
1269 info->af_first_flag = 1;
1270 info->exp = 0;
1271 info->gain = 0;
1272
1273 return 0;
1274 }
1275
sensor_remove(struct i2c_client * client)1276 static int sensor_remove(struct i2c_client *client)
1277 {
1278 struct v4l2_subdev *sd;
1279 int i;
1280
1281 if (client) {
1282 for (i = 0; i < SENSOR_NUM; i++) {
1283 if (!strcmp(cci_drv[i].name, client->name))
1284 break;
1285 }
1286 sd = cci_dev_remove_helper(client, &cci_drv[i]);
1287 } else {
1288 sd = cci_dev_remove_helper(client, &cci_drv[sensor_dev_id++]);
1289 }
1290 kfree(to_state(sd));
1291 return 0;
1292 }
1293
1294 static const struct i2c_device_id sensor_id[] = {
1295 {SENSOR_NAME, 0},
1296 {}
1297 };
1298
1299 static const struct i2c_device_id sensor_id_2[] = {
1300 {SENSOR_NAME_2, 0},
1301 {}
1302 };
1303
1304 MODULE_DEVICE_TABLE(i2c, sensor_id);
1305 MODULE_DEVICE_TABLE(i2c, sensor_id_2);
1306
1307 static struct i2c_driver sensor_driver[] = {
1308 {
1309 .driver = {
1310 .owner = THIS_MODULE,
1311 .name = SENSOR_NAME,
1312 },
1313 .probe = sensor_probe,
1314 .remove = sensor_remove,
1315 .id_table = sensor_id,
1316 }, {
1317 .driver = {
1318 .owner = THIS_MODULE,
1319 .name = SENSOR_NAME_2,
1320 },
1321 .probe = sensor_probe,
1322 .remove = sensor_remove,
1323 .id_table = sensor_id_2,
1324 },
1325 };
init_sensor(void)1326 static __init int init_sensor(void)
1327 {
1328 int i, ret = 0;
1329
1330 sensor_dev_id = 0;
1331
1332 for (i = 0; i < SENSOR_NUM; i++)
1333 ret = cci_dev_init_helper(&sensor_driver[i]);
1334
1335 return ret;
1336 }
1337
exit_sensor(void)1338 static __exit void exit_sensor(void)
1339 {
1340 int i;
1341
1342 sensor_dev_id = 0;
1343
1344 for (i = 0; i < SENSOR_NUM; i++)
1345 cci_dev_exit_helper(&sensor_driver[i]);
1346 }
1347
1348 module_init(init_sensor);
1349 module_exit(exit_sensor);
1350