• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * A V4L2 driver for ofilm0092 tof cameras.
3  *
4  * Copyright (c) 2020 by Allwinnertech Co., Ltd.  http://www.allwinnertech.com
5  *
6  * Authors:  Zhao Wei <zhaowei@allwinnertech.com>
7  *    Liang WeiJie <liangweijie@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 ofilm0092 tof sensors");
30 MODULE_LICENSE("GPL");
31 
32 #define MCLK              (24 * 1000 * 1000)
33 #define V4L2_IDENT_SENSOR 0x0B12
34 
35 /*
36  * Our nominal (default) frame rate.
37  */
38 /* i2c clk 100k */
39 #define SENSOR_FRAME_RATE 15
40 
41 /*
42  * The ofilm0092 i2c address
43  */
44 #define I2C_ADDR 0x7A
45 
46 #define SENSOR_NAME "ofilm0092"
47 
48 /*
49  * The default register settings
50  */
51 static struct regval_list sensor_default_regs[] = {
52 	{0x8423, 0x00A2},	 /* FRAMEBLANK */
53 	/* S00_EXPOTIME 0.128 ms @ 60.24 MHz (Grey-Scale) */
54 	{0x9000, 0x1E1E},
55 	{0x9001, 0x0000},	 /* S00_FRAMETIME */
56 	{0x9002, 0x6992},	 /* S01_EXPOTIME 1.060 ms @ 80.32 MHz */
57 	{0x9003, 0x0000},	 /* S01_FRAMETIME */
58 	{0x9004, 0x6992},	 /* S02_EXPOTIME 1.060 ms @ 80.32 MHz */
59 	{0x9005, 0x0000},	 /* S02_FRAMETIME */
60 	{0x9006, 0x6992},	 /* S03_EXPOTIME 1.060 ms @ 80.32 MHz */
61 	{0x9007, 0x0000},	 /* S03_FRAMETIME */
62 	{0x9008, 0x6992},	 /* S04_EXPOTIME 1.060 ms @ 80.32 MHz */
63 	{0x9009, 0x0000},	 /* S04_FRAMETIME */
64 	{0x900A, 0x5F2D},	 /* S05_EXPOTIME 1.060 ms @ 60.24 MHz */
65 	{0x900B, 0x0000},	 /* S05_FRAMETIME */
66 	{0x900C, 0x5F2D},	 /* S06_EXPOTIME 1.060 ms @ 60.24 MHz */
67 	{0x900D, 0x0000},	 /* S06_FRAMETIME */
68 	{0x900E, 0x5F2D},	 /* S07_EXPOTIME 1.060 ms @ 60.24 MHz */
69 	{0x900F, 0x0000},	 /* S07_FRAMETIME */
70 	{0x9010, 0x5F2D},	 /* S08_EXPOTIME 1.060 ms @ 60.24 MHz */
71 	{0x9011, 0x0000},	 /* S08_FRAMETIME */
72 	/* S00_EXPOTIMEMAX 0.128 ms @ 60.24 MHz (Grey-Scale) */
73 	{0x9080, 0x1E1E},
74 	{0x9081, 0x0000},	 /* S00_FRAMETIMEMIN */
75 	{0x9082, 0x10A0},	 /* S00_ILLUCFG Gray-Scale @ 60.24 MHz (LUT1) */
76 	{0x9083, 0x00A0},	 /* S00_SENSORCFG (Greyscale) */
77 	{0x9084, 0x8000},	 /* S00_ROCFG (Reconfig allowed) */
78 	{0x9085, 0x6992},	 /* S01_EXPOTIMEMAX 1.060 ms @ 80.32 MHz */
79 	{0x9086, 0x0000},	 /* S01_FRAMETIMEMIN */
80 	{0x9087, 0x0000},	 /* S01_ILLUCFG 0° @ 80.32 MHz (LUT0) */
81 	{0x9088, 0x0000},	 /* S01_SENSORCFG */
82 	{0x9089, 0x0000},	 /* S01_ROCFG (Reconfig forbidden) */
83 	{0x908A, 0x6992},	 /* S02_EXPOTIMEMAX 1.060 ms @ 80.32 MHz */
84 	{0x908B, 0x0000},	 /* S02_FRAMETIMEMIN */
85 	{0x908C, 0x0020},	 /* S02_ILLUCFG 90° @ 80.32 MHz (LUT0) */
86 	{0x908D, 0x0000},	 /* S02_SENSORCFG */
87 	{0x908E, 0x0000},	 /* S02_ROCFG (Reconfig forbidden) */
88 	{0x908F, 0x6992},	 /* S03_EXPOTIMEMAX 1.060 ms @ 80.32 MHz */
89 	{0x9090, 0x0000},	 /* S03_FRAMETIMEMIN */
90 	{0x9091, 0x0040},	 /* S03_ILLUCFG 180° @ 80.32 MHz (LUT0) */
91 	{0x9092, 0x0000},	 /* S03_SENSORCFG */
92 	{0x9093, 0x0000},	 /* S03_ROCFG (Reconfig forbidden) */
93 	{0x9094, 0x6992},	 /* S04_EXPOTIMEMAX 1.060 ms @ 80.32 MHz */
94 	{0x9095, 0x0000},	 /* S04_FRAMETIMEMIN */
95 	{0x9096, 0x0060},	 /* S04_ILLUCFG 270° @ 80.32 MHz (LUT0) */
96 	{0x9097, 0x0000},	 /* S04_SENSORCFG */
97 	{0x9098, 0x0000},	 /* S04_ROCFG (Reconfig forbidden) */
98 	{0x9099, 0x5F2D},	 /* S05_EXPOTIMEMAX 1.060 ms @ 60.24 MHz */
99 	{0x909A, 0x0000},	 /* S05_FRAMETIMEMIN */
100 	{0x909B, 0x1000},	 /* S05_ILLUCFG 0° @ 60.24 MHz (LUT1) */
101 	{0x909C, 0x0000},	 /* S05_SENSORCFG */
102 	{0x909D, 0x0000},	 /* S05_ROCFG (Reconfig forbidden) */
103 	{0x909E, 0x5F2D},	 /* S06_EXPOTIMEMAX 1.060 ms @ 60.24 MHz */
104 	{0x909F, 0x0000},	 /* S06_FRAMETIMEMIN */
105 	{0x90A0, 0x1020},	 /* S06_ILLUCFG 90° @ 60.24 MHz (LUT1) */
106 	{0x90A1, 0x0000},	 /* S06_SENSORCFG */
107 	{0x90A2, 0x0000},	 /* S06_ROCFG (Reconfig forbidden) */
108 	{0x90A3, 0x5F2D},	 /* S07_EXPOTIMEMAX 1.060 ms @ 60.24 MHz */
109 	{0x90A4, 0x0000},	 /* S07_FRAMETIMEMIN */
110 	{0x90A5, 0x1040},	 /* S07_ILLUCFG 180° @ 60.24 MHz (LUT1) */
111 	{0x90A6, 0x0000},	 /* S07_SENSORCFG */
112 	{0x90A7, 0x0000},	 /* S07_ROCFG (Reconfig forbidden) */
113 	{0x90A8, 0x5F2D},	 /* S08_EXPOTIMEMAX 1.060 ms @ 60.24 MHz */
114 	{0x90A9, 0x0000},	 /* S08_FRAMETIMEMIN */
115 	{0x90AA, 0x1060},	 /* S08_ILLUCFG 270° @ 60.24 MHz (LUT1) */
116 	{0x90AB, 0x0000},	 /* S08_SENSORCFG */
117 	/* S08_ROCFG (Reconfig & Usecase Switch allowed) */
118 	{0x90AC, 0xC000},
119 	{0x91C0, 0x0592},	 /* CSICFG */
120 	{0x91C1, 0xDF00},	 /* ROICOL */
121 	{0x91C2, 0xAB00},	 /* ROIROW */
122 	{0x91C3, 0x0508},	 /* ROS */
123 	{0x91C4, 0x0008},	 /* EXPCFG0 */
124 	{0x91C5, 0x0020},	 /* EXPCFG1 */
125 	{0x91C6, 0x8008},	 /* PSOUT (SE enabled) */
126 	{0x91CF, 0x0009},	 /* MB_CFG0 (9 sequences to execute) */
127 	{0x91D3, 0x0C35},	 /* MB0_FRAMETIME (15 fps) */
128 	{0x91DB, 0x0008},	 /* MBSEQ0_CFG0 (MB0 Repetitions = 1) */
129 	/* PLL_MODLUT0_CFG0 (for f_illu = 80.32 MHz [f_mod = 321.28 MHz]) */
130 	{0x91EA, 0x1EA1},
131 	/* PLL_MODLUT0_CFG1 (for f_illu = 80.32 MHz [f_mod = 321.28 MHz]) */
132 	{0x91EB, 0xBF26},
133 	/* PLL_MODLUT0_CFG2 (for f_illu = 80.32 MHz [f_mod = 321.28 MHz]) */
134 	{0x91EC, 0x0008},
135 	/* PLL_MODLUT0_CFG3 (for f_illu = 80.32 MHz [f_mod = 321.28 MHz]) */
136 	{0x91ED, 0x0D01},
137 	/* PLL_MODLUT0_CFG4 (for f_illu = 80.32 MHz [f_mod = 321.28 MHz]) */
138 	{0x91EE, 0x5555},
139 	/* PLL_MODLUT0_CFG5 (for f_illu = 80.32 MHz [f_mod = 321.28 MHz]) */
140 	{0x91EF, 0x02F5},
141 	/* PLL_MODLUT0_CFG6 (for f_illu = 80.32 MHz [f_mod = 321.28 MHz]) */
142 	{0x91F0, 0x0009},
143 	/* PLL_MODLUT0_CFG7 (for f_illu = 80.32 MHz [f_mod = 321.28 MHz]) */
144 	{0x91F1, 0x0031},
145 	/* PLL_MODLUT1_CFG0 (for f_illu = 60.24 MHz [f_mod = 240.96 MHz]) */
146 	{0x91F2, 0x16A1},
147 	/* PLL_MODLUT1_CFG1 (for f_illu = 60.24 MHz [f_mod = 240.96 MHz]) */
148 	{0x91F3, 0x1EB8},
149 	/* PLL_MODLUT1_CFG2 (for f_illu = 60.24 MHz [f_mod = 240.96 MHz]) */
150 	{0x91F4, 0x0005},
151 	/* PLL_MODLUT1_CFG3 (for f_illu = 60.24 MHz [f_mod = 240.96 MHz]) */
152 	{0x91F5, 0x0C01},
153 	/* PLL_MODLUT1_CFG4 (for f_illu = 60.24 MHz [f_mod = 240.96 MHz]) */
154 	{0x91F6, 0xFCBF},
155 	/* PLL_MODLUT1_CFG5 (for f_illu = 60.24 MHz [f_mod = 240.96 MHz]) */
156 	{0x91F7, 0x04A7},
157 	/* PLL_MODLUT1_CFG6 (for f_illu = 60.24 MHz [f_mod = 240.96 MHz]) */
158 	{0x91F8, 0x000D},
159 	/* PLL_MODLUT1_CFG7 (for f_illu = 60.24 MHz [f_mod = 240.96 MHz]) */
160 	{0x91F9, 0x0022},
161 	{0x9220, 0x0003},	 /* SENSOR_LENGTH_CODE0 (length = 4) */
162 	{0x9221, 0x000C},	 /* SENSOR_CODE0_0 (code = 1100) */
163 	{0x9244, 0x0003},	 /* ILLU_LENGTH_CODE0 (length = 4) */
164 	{0x9245, 0x0008},	 /* ILLU_CODE0_0 (code = 1000) */
165 	/* DIGCLKDIV_S0_PLL0 (for f_illu = 80.32 MHz [f_mod = 321.28 MHz]) */
166 	{0x9268, 0x0001},
167 	/* DIGCLKDIV_S0_PLL1 (for f_illu = 60.24 MHz [f_mod = 240.96 MHz]) */
168 	{0x9269, 0x0001},
169 	/* DLLREGDELAY_S0_PLL0 (for f_illu = 80.32 MHz [f_mod = 321.28 MHz]) */
170 	{0x9278, 0x0B01},
171 	/* DLLREGDELAY_S0_PLL1 (for f_illu = 60.24 MHz [f_mod = 240.96 MHz]) */
172 	{0x9279, 0x0001},
173 	{0x9288, 0x0242},	 /* Filter Stage initializaiton Value 611 */
174 	{0x9289, 0x0246},	 /* Filter Stage initializaiton Value 610 */
175 	{0x928A, 0x0246},	 /* Filter Stage initializaiton Value 69 */
176 	{0x928B, 0x0242},	 /* Filter Stage initializaiton Value 68 */
177 	{0x928C, 0x0246},	 /* Filter Stage initializaiton Value 67 */
178 	{0x928D, 0x0246},	 /* Filter Stage initializaiton Value 66 */
179 	{0x928E, 0x0242},	 /* Filter Stage initializaiton Value 65 */
180 	{0x928F, 0x0246},	 /* Filter Stage initializaiton Value 64 */
181 	{0x9290, 0x0246},	 /* Filter Stage initializaiton Value 63 */
182 	{0x9291, 0x0242},	 /* Filter Stage initializaiton Value 62 */
183 	{0x9292, 0x0246},	 /* Filter Stage initializaiton Value 61 */
184 	{0x9293, 0x0246},	 /* Filter Stage initializaiton Value 60 */
185 	{0x9294, 0x011C},	 /* Filter Stage initializaiton Value 57 */
186 	{0x9295, 0x012A},	 /* Filter Stage initializaiton Value 56 */
187 	{0x9296, 0x011C},	 /* Filter Stage initializaiton Value 55 */
188 	{0x9297, 0x012A},	 /* Filter Stage initializaiton Value 54 */
189 	{0x9298, 0x011C},	 /* Filter Stage initializaiton Value 53 */
190 	{0x9299, 0x012A},	 /* Filter Stage initializaiton Value 52 */
191 	{0x929A, 0x011C},	 /* Filter Stage initializaiton Value 51 */
192 	{0x929B, 0x012A},	 /* Filter Stage initializaiton Value 50 */
193 	{0x929C, 0x008E},	 /* Filter Stage initializaiton Value 47 */
194 	{0x929D, 0x00AA},	 /* Filter Stage initializaiton Value 46 */
195 	{0x929E, 0x0080},	 /* Filter Stage initializaiton Value 45 */
196 	{0x929F, 0x0080},	 /* Filter Stage initializaiton Value 44 */
197 	{0x92A0, 0x00B8},	 /* Filter Stage initializaiton Value 43 */
198 	{0x92A1, 0x0080},	 /* Filter Stage initializaiton Value 42 */
199 	{0x92A2, 0x0080},	 /* Filter Stage initializaiton Value 41 */
200 	{0x92A3, 0x0080},	 /* Filter Stage initializaiton Value 40 */
201 	{0x92A4, 0x0040},	 /* Filter Stage initializaiton Value 37 */
202 	{0x92A5, 0x0040},	 /* Filter Stage initializaiton Value 36 */
203 	{0x92A6, 0x0040},	 /* Filter Stage initializaiton Value 35 */
204 	{0x92A7, 0x0040},	 /* Filter Stage initializaiton Value 34 */
205 	{0x92A8, 0x0040},	 /* Filter Stage initializaiton Value 33 */
206 	{0x92A9, 0x0040},	 /* Filter Stage initializaiton Value 32 */
207 	{0x92AA, 0x0040},	 /* Filter Stage initializaiton Value 31 */
208 	{0x92AB, 0x0040},	 /* Filter Stage initializaiton Value 30 */
209 	{0x92AC, 0x0040},	 /* Filter Stage initializaiton Value 27 */
210 	{0x92AD, 0x0040},	 /* Filter Stage initializaiton Value 26 */
211 	{0x92AE, 0x0040},	 /* Filter Stage initializaiton Value 25 */
212 	{0x92AF, 0x0040},	 /* Filter Stage initializaiton Value 24 */
213 	{0x92B0, 0x0040},	 /* Filter Stage initializaiton Value 23 */
214 	{0x92B1, 0x0040},	 /* Filter Stage initializaiton Value 22 */
215 	{0x92B2, 0x0040},	 /* Filter Stage initializaiton Value 21 */
216 	{0x92B3, 0x0040},	 /* Filter Stage initializaiton Value 20 */
217 	{0x92B4, 0x0040},	 /* Filter Stage initializaiton Value 17 */
218 	{0x92B5, 0x0040},	 /* Filter Stage initializaiton Value 16 */
219 	{0x92B6, 0x0040},	 /* Filter Stage initializaiton Value 15 */
220 	{0x92B7, 0x0040},	 /* Filter Stage initializaiton Value 14 */
221 	{0x92B8, 0x0040},	 /* Filter Stage initializaiton Value 13 */
222 	{0x92B9, 0x0040},	 /* Filter Stage initializaiton Value 12 */
223 	{0x92BA, 0x0040},	 /* Filter Stage initializaiton Value 11 */
224 	{0x92BB, 0x0040},	 /* Filter Stage initializaiton Value 10 */
225 	{0x92BC, 0x0040},	 /* Filter Stage initializaiton Value 07 */
226 	{0x92BD, 0x0040},	 /* Filter Stage initializaiton Value 06 */
227 	{0x92BE, 0x0040},	 /* Filter Stage initializaiton Value 05 */
228 	{0x92BF, 0x0040},	 /* Filter Stage initializaiton Value 04 */
229 	{0x92C0, 0x0040},	 /* Filter Stage initializaiton Value 03 */
230 	{0x92C1, 0x0040},	 /* Filter Stage initializaiton Value 02 */
231 	{0x92C2, 0x0040},	 /* Filter Stage initializaiton Value 01 */
232 	{0x92C3, 0x0040},	 /* Filter Stage initializaiton Value 00 */
233 	{0x92C4, 0x5633},	 /* TH0 */
234 	{0x92C5, 0x9175},	 /* TH1 */
235 	{0x92C6, 0xC5AB},	 /* TH2 */
236 	{0x92C7, 0xF5DD},	 /* TH3 */
237 	{0x92C8, 0x4633},	 /* TH4 */
238 	{0x92C9, 0x6857},	 /* TH5 */
239 	{0x92CA, 0x8677},	 /* TH6 */
240 	{0x92CB, 0x0095},	 /* TH7 */
241 	{0x92CC, 0x2B1F},	 /* TH8 */
242 	{0x92CD, 0x3F35},	 /* TH9 */
243 	{0x92CE, 0x5249},	 /* TH10 */
244 	{0x92CF, 0x005B},	 /* TH11 */
245 	{0x92D0, 0x1A13},	 /* TH12 */
246 	{0x92D1, 0x1F1E},	 /* TH13 */
247 	{0x92D2, 0x2120},	 /* TH14 */
248 	{0x92D3, 0x0022},	 /* TH15 */
249 	{0x92D4, 0x322A},	 /* TH16 */
250 	{0x92D5, 0x534B},	 /* TH17 */
251 	{0x92D6, 0x735B},	 /* TH18 */
252 	{0x92D7, 0x007B},	 /* TH19 */
253 	{0x92D8, 0x4E35},	 /* TH20 */
254 	{0x92D9, 0x7C64},	 /* TH21 */
255 	{0x92DA, 0xA891},	 /* TH22 */
256 	{0x92DB, 0x00BD},	 /* TH23 */
257 	{0x92DC, 0x100B},	 /* TH24 */
258 	{0x92DD, 0x1915},	 /* TH25 */
259 	{0x92DE, 0x221E},	 /* TH26 */
260 	{0x92DF, 0x2C27},	 /* TH27 */
261 	{0x92E0, 0x3530},	 /* TH28 */
262 	{0x92E1, 0x003A},	 /* TH29 */
263 	{0x92E2, 0x0500},	 /* CMPMUX */
264 	{0x92E3, 0x08D8},	 /* HH */
265 	{0x92E4, 0x0872},	 /* HL */
266 	{0x92E5, 0x084A},	 /* LH */
267 	{0x92E6, 0x0835},	 /* LL */
268 	{0x92E7, 0x0001},	 /* PlausiCheck ; Idle Mode enable */
269 	{0x92E8, 0x00D0},	 /* Idle Counter */
270 	{0x92E9, 0x0300},	 /* Module ID 0 */
271 	{0x92EA, 0x0000},	 /* Module ID 1 */
272 	{0x92EB, 0x0000},	 /* Module ID 2 */
273 	{0x92EC, 0x0000},	 /* Module ID 3 */
274 	{0x92ED, 0x0000},	 /* Module ID 4 */
275 	{0x92EE, 0x0000},	 /* Module ID 5 */
276 	{0x92EF, 0x0000},	 /* Module ID 6 */
277 	{0x92F0, 0x002E},	 /* Module ID 7 */
278 	{0x92F1, 0x960E},	 /* CRC */
279 	{0x9401, 0x0002},	 /* Mode */
280 	{0xA001, 0x0007},	 /* DMUX1 */
281 	{0xA008, 0x1513},	 /* PADGPIOCFG1 */
282 	{0xA00C, 0x0135},	 /* PADMODCFG */
283 	{0xA039, 0x1AA1},	 /* PLL_SYSLUT_CFG0 (for fref = 24.00 MHz) */
284 	{0xA03A, 0xAAAB},	 /* PLL_SYSLUT_CFG1 (for fref = 24.00 MHz) */
285 	{0xA03B, 0x000A},	 /* PLL_SYSLUT_CFG2 (for fref = 24.00 MHz) */
286 	{0xA03C, 0x0000},	 /* PLL_SYSLUT_CFG3 (for fref = 24.00 MHz) */
287 	{0xA03D, 0x03C0},	 /* PLL_SYSLUT_CFG4 (for fref = 24.00 MHz) */
288 	{0xA03E, 0x0000},	 /* PLL_SYSLUT_CFG5 (for fref = 24.00 MHz) */
289 	{0xA03F, 0x0017},	 /* PLL_SYSLUT_CFG6 (for fref = 24.00 MHz) */
290 	{0x9400, 0x0001},	 /* stream on */
291 };
292 
293 /*
294  * Here we'll try to encapsulate the changes for just the output
295  * video format.
296  *
297  */
298 
299 static struct regval_list sensor_fmt_raw[] = {
300 };
301 
302 /*
303  * Code for dealing with controls.
304  * fill with different sensor module
305  * different sensor module has different settings here
306  * if not support the follow function ,retrun -EINVAL
307  */
308 
sensor_g_exp(struct v4l2_subdev * sd,__s32 * value)309 static int sensor_g_exp(struct v4l2_subdev *sd, __s32 *value)
310 {
311 	struct sensor_info *info = to_state(sd);
312 
313 	*value = info->exp;
314 	sensor_dbg("sensor_get_exposure = %d\n", info->exp);
315 
316 	return 0;
317 }
318 
sensor_s_exp(struct v4l2_subdev * sd,unsigned int exp_val)319 static int sensor_s_exp(struct v4l2_subdev *sd, unsigned int exp_val)
320 {
321 	struct sensor_info *info = to_state(sd);
322 
323 	info->exp = exp_val;
324 
325 	return 0;
326 }
327 
sensor_g_gain(struct v4l2_subdev * sd,__s32 * value)328 static int sensor_g_gain(struct v4l2_subdev *sd, __s32 *value)
329 {
330 	struct sensor_info *info = to_state(sd);
331 
332 	*value = info->gain;
333 	sensor_dbg("sensor_get_gain = %d\n", info->gain);
334 
335 	return 0;
336 }
337 
sensor_s_gain(struct v4l2_subdev * sd,int gain_val)338 static int sensor_s_gain(struct v4l2_subdev *sd, int gain_val)
339 {
340 	struct sensor_info *info = to_state(sd);
341 
342 	info->gain = gain_val;
343 
344 	return 0;
345 }
346 
sensor_s_exp_gain(struct v4l2_subdev * sd,struct sensor_exp_gain * exp_gain)347 static int sensor_s_exp_gain(struct v4l2_subdev *sd,
348 			     struct sensor_exp_gain *exp_gain)
349 {
350 	return 0;
351 }
352 
sensor_s_fps(struct v4l2_subdev * sd,struct sensor_fps * fps)353 static int sensor_s_fps(struct v4l2_subdev *sd,
354 			struct sensor_fps *fps)
355 {
356 	return 0;
357 }
358 
sensor_s_sw_stby(struct v4l2_subdev * sd,int on_off)359 static int sensor_s_sw_stby(struct v4l2_subdev *sd, int on_off)
360 {
361 	int ret = 0;
362 
363 	return ret;
364 }
365 
366 /*
367  * Stuff that knows about the sensor.
368  */
sensor_power(struct v4l2_subdev * sd,int on)369 static int sensor_power(struct v4l2_subdev *sd, int on)
370 {
371 	int ret = 0;
372 
373 	switch (on) {
374 	case STBY_ON:
375 		sensor_dbg("STBY_ON!\n");
376 		cci_lock(sd);
377 		ret = sensor_s_sw_stby(sd, STBY_ON);
378 		if (ret < 0)
379 			sensor_err("soft stby falied!\n");
380 		usleep_range(1000, 1200);
381 		cci_unlock(sd);
382 		break;
383 	case STBY_OFF:
384 		sensor_dbg("STBY_OFF!\n");
385 		cci_lock(sd);
386 		usleep_range(1000, 1200);
387 		ret = sensor_s_sw_stby(sd, STBY_OFF);
388 		if (ret < 0)
389 			sensor_err("soft stby off falied!\n");
390 		cci_unlock(sd);
391 		break;
392 	case PWR_ON:
393 		sensor_dbg("PWR_ON!\n");
394 		cci_lock(sd);
395 
396 		vin_gpio_set_status(sd, RESET, 1);
397 
398 		vin_gpio_write(sd, RESET, CSI_GPIO_HIGH);
399 
400 		vin_set_pmu_channel(sd, CAMERAVDD, ON);
401 		vin_set_pmu_channel(sd, IOVDD, ON);
402 		vin_set_pmu_channel(sd, AVDD, ON);
403 		vin_set_pmu_channel(sd, DVDD, ON);
404 		usleep_range(1000, 1200);
405 
406 		vin_set_mclk_freq(sd, MCLK);
407 		vin_set_mclk(sd, ON);
408 		usleep_range(3000, 3200);
409 
410 		vin_gpio_write(sd, RESET, CSI_GPIO_LOW);
411 		usleep_range(20000, 22000);
412 
413 		vin_gpio_write(sd, RESET, CSI_GPIO_HIGH);
414 		usleep_range(20000, 22000);
415 
416 		cci_unlock(sd);
417 		break;
418 	case PWR_OFF:
419 		sensor_dbg("PWR_OFF!\n");
420 		cci_lock(sd);
421 
422 		vin_gpio_set_status(sd, RESET, 1);
423 		vin_gpio_write(sd, RESET, CSI_GPIO_LOW);
424 
425 		vin_set_mclk(sd, OFF);
426 
427 		vin_set_pmu_channel(sd, AVDD, OFF);
428 		vin_set_pmu_channel(sd, IOVDD, OFF);
429 		vin_set_pmu_channel(sd, DVDD, OFF);
430 		vin_set_pmu_channel(sd, CAMERAVDD, OFF);
431 
432 		vin_gpio_set_status(sd, RESET, 0);
433 
434 		cci_unlock(sd);
435 		break;
436 	default:
437 		return -EINVAL;
438 	}
439 
440 	return 0;
441 }
442 
sensor_reset(struct v4l2_subdev * sd,u32 val)443 static int sensor_reset(struct v4l2_subdev *sd, u32 val)
444 {
445 	switch (val) {
446 	case 0:
447 		vin_gpio_write(sd, RESET, CSI_GPIO_HIGH);
448 		usleep_range(100, 120);
449 		break;
450 	case 1:
451 		vin_gpio_write(sd, RESET, CSI_GPIO_LOW);
452 		usleep_range(100, 120);
453 		break;
454 	default:
455 		return -EINVAL;
456 	}
457 	return 0;
458 }
459 
sensor_detect(struct v4l2_subdev * sd)460 static int sensor_detect(struct v4l2_subdev *sd)
461 {
462 	data_type rdval = 0;
463 
464 	sensor_read(sd, 0xA0A5, &rdval);
465 	if (rdval != V4L2_IDENT_SENSOR)
466 		return -ENODEV;
467 
468 	return 0;
469 }
470 
sensor_init(struct v4l2_subdev * sd,u32 val)471 static int sensor_init(struct v4l2_subdev *sd, u32 val)
472 {
473 	int ret;
474 	struct sensor_info *info = to_state(sd);
475 
476 	sensor_dbg("sensor_init\n");
477 
478 	/*Make sure it is a target sensor */
479 	ret = sensor_detect(sd);
480 	if (ret) {
481 		sensor_err("chip found is not an target chip.\n");
482 		return ret;
483 	}
484 
485 	info->focus_status = 0;
486 	info->low_speed = 0;
487 	info->width = 224;
488 	info->height = 1557;
489 	info->hflip = 0;
490 	info->vflip = 0;
491 	info->gain = 0;
492 	info->exp = 0;
493 
494 	info->tpf.numerator = 1;
495 	info->tpf.denominator = SENSOR_FRAME_RATE;
496 
497 	info->preview_first_flag = 1;
498 
499 	return 0;
500 }
501 
sensor_ioctl(struct v4l2_subdev * sd,unsigned int cmd,void * arg)502 static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
503 {
504 	int ret = 0;
505 	struct sensor_info *info = to_state(sd);
506 
507 	switch (cmd) {
508 	case GET_CURRENT_WIN_CFG:
509 		if (info->current_wins) {
510 			memcpy(arg, info->current_wins,
511 			       sizeof(struct sensor_win_size));
512 			ret = 0;
513 		} else {
514 			sensor_err("empty wins!\n");
515 			ret = -1;
516 		}
517 		break;
518 	case SET_FPS:
519 		ret = 0;
520 		break;
521 	case VIDIOC_VIN_SENSOR_EXP_GAIN:
522 		ret = sensor_s_exp_gain(sd, (struct sensor_exp_gain *)arg);
523 		break;
524 	case VIDIOC_VIN_SENSOR_SET_FPS:
525 		ret = sensor_s_fps(sd, (struct sensor_fps *)arg);
526 		break;
527 	case VIDIOC_VIN_SENSOR_CFG_REQ:
528 		sensor_cfg_req(sd, (struct sensor_config *)arg);
529 		break;
530 	default:
531 		return -EINVAL;
532 	}
533 	return ret;
534 }
535 
536 /*
537  * Store information about the video data format.
538  */
539 static struct sensor_format_struct sensor_formats[] = {
540 	{
541 		.desc = "Raw RGB Bayer",
542 		.mbus_code = MEDIA_BUS_FMT_SGRBG12_1X12,
543 		.regs = sensor_fmt_raw,
544 		.regs_size = ARRAY_SIZE(sensor_fmt_raw),
545 		.bpp = 1
546 	},
547 };
548 
549 #define N_FMTS ARRAY_SIZE(sensor_formats)
550 
551 /*
552  * Then there is the issue of window sizes.  Try to capture the info here.
553  */
554 
555 static struct sensor_win_size sensor_win_sizes[] = {
556 	{
557 		.width      = 224,
558 		.height     = 1557,
559 		.hoffset    = 0,
560 		.voffset    = 0,
561 		.hts        = 2496,
562 		.vts        = 1308,
563 		.pclk       = 48 * 1000 * 1000,
564 		.fps_fixed  = SENSOR_FRAME_RATE,
565 		.bin_factor = 1,
566 		.intg_min   = 1 << 4,
567 		.intg_max   = 1900 << 4,
568 		.gain_min   = 1 << 4,
569 		.gain_max   = 10 << 4,
570 		.regs       = NULL,
571 		.regs_size  = 0,
572 		.set_size   = NULL,
573 	},
574 };
575 
576 #define N_WIN_SIZES (ARRAY_SIZE(sensor_win_sizes))
577 
sensor_g_mbus_config(struct v4l2_subdev * sd,struct v4l2_mbus_config * cfg)578 static int sensor_g_mbus_config(struct v4l2_subdev *sd,
579 				struct v4l2_mbus_config *cfg)
580 {
581 	cfg->type = V4L2_MBUS_CSI2_DPHY;
582 	cfg->flags = 0 | V4L2_MBUS_CSI2_2_LANE | V4L2_MBUS_CSI2_CHANNEL_0;
583 
584 	return 0;
585 }
586 
sensor_g_ctrl(struct v4l2_ctrl * ctrl)587 static int sensor_g_ctrl(struct v4l2_ctrl *ctrl)
588 {
589 	struct sensor_info *info = container_of(ctrl->handler,
590 						struct sensor_info, handler);
591 	struct v4l2_subdev *sd = &info->sd;
592 
593 	switch (ctrl->id) {
594 	case V4L2_CID_GAIN:
595 		return sensor_g_gain(sd, &ctrl->val);
596 	case V4L2_CID_EXPOSURE:
597 		return sensor_g_exp(sd, &ctrl->val);
598 	}
599 	return -EINVAL;
600 }
601 
sensor_s_ctrl(struct v4l2_ctrl * ctrl)602 static int sensor_s_ctrl(struct v4l2_ctrl *ctrl)
603 {
604 	struct sensor_info *info = container_of(ctrl->handler,
605 						struct sensor_info, handler);
606 	struct v4l2_subdev *sd = &info->sd;
607 
608 	switch (ctrl->id) {
609 	case V4L2_CID_GAIN:
610 		return sensor_s_gain(sd, ctrl->val);
611 	case V4L2_CID_EXPOSURE:
612 		return sensor_s_exp(sd, ctrl->val);
613 	}
614 	return -EINVAL;
615 }
616 
sensor_reg_init(struct sensor_info * info)617 static int sensor_reg_init(struct sensor_info *info)
618 {
619 	int ret;
620 	struct v4l2_subdev *sd = &info->sd;
621 	struct sensor_format_struct *sensor_fmt = info->fmt;
622 	struct sensor_win_size *wsize = info->current_wins;
623 
624 	ret = sensor_write_array(sd, sensor_default_regs,
625 				 ARRAY_SIZE(sensor_default_regs));
626 	if (ret < 0) {
627 		sensor_err("write sensor_default_regs error\n");
628 		return ret;
629 	}
630 
631 	sensor_dbg("sensor_reg_init\n");
632 
633 	sensor_write_array(sd, sensor_fmt->regs, sensor_fmt->regs_size);
634 
635 	if (wsize->regs)
636 		sensor_write_array(sd, wsize->regs, wsize->regs_size);
637 
638 	if (wsize->set_size)
639 		wsize->set_size(sd);
640 
641 	info->width = wsize->width;
642 	info->height = wsize->height;
643 
644 	return 0;
645 }
646 
sensor_s_stream(struct v4l2_subdev * sd,int enable)647 static int sensor_s_stream(struct v4l2_subdev *sd, int enable)
648 {
649 	struct sensor_info *info = to_state(sd);
650 
651 	sensor_dbg("%s on = %d, %d*%d fps: %d code: %x\n", __func__, enable,
652 		   info->current_wins->width, info->current_wins->height,
653 		   info->current_wins->fps_fixed, info->fmt->mbus_code);
654 
655 	if (!enable)
656 		return 0;
657 
658 	return sensor_reg_init(info);
659 }
660 
661 /* ----------------------------------------------------------------------- */
662 static const struct v4l2_ctrl_ops sensor_ctrl_ops = {
663 	.g_volatile_ctrl = sensor_g_ctrl,
664 	.s_ctrl = sensor_s_ctrl,
665 };
666 
667 static const struct v4l2_subdev_core_ops sensor_core_ops = {
668 	.reset = sensor_reset,
669 	.init = sensor_init,
670 	.s_power = sensor_power,
671 	.ioctl = sensor_ioctl,
672 #ifdef CONFIG_COMPAT
673 	.compat_ioctl32 = sensor_compat_ioctl32,
674 #endif
675 };
676 
677 static const struct v4l2_subdev_video_ops sensor_video_ops = {
678 	.s_stream = sensor_s_stream,
679 	.g_mbus_config = sensor_g_mbus_config,
680 };
681 
682 static const struct v4l2_subdev_pad_ops sensor_pad_ops = {
683 	.enum_mbus_code = sensor_enum_mbus_code,
684 	.enum_frame_size = sensor_enum_frame_size,
685 	.get_fmt = sensor_get_fmt,
686 	.set_fmt = sensor_set_fmt,
687 };
688 
689 static const struct v4l2_subdev_ops sensor_ops = {
690 	.core = &sensor_core_ops,
691 	.video = &sensor_video_ops,
692 	.pad = &sensor_pad_ops,
693 };
694 
695 /* ----------------------------------------------------------------------- */
696 static struct cci_driver cci_drv = {
697 	.name = SENSOR_NAME,
698 	.addr_width = CCI_BITS_16,
699 	.data_width = CCI_BITS_16,
700 };
701 
sensor_init_controls(struct v4l2_subdev * sd,const struct v4l2_ctrl_ops * ops)702 static int sensor_init_controls(struct v4l2_subdev *sd,
703 				const struct v4l2_ctrl_ops *ops)
704 {
705 	struct sensor_info *info = to_state(sd);
706 	struct v4l2_ctrl_handler *handler = &info->handler;
707 	struct v4l2_ctrl *ctrl;
708 	int ret = 0;
709 
710 	v4l2_ctrl_handler_init(handler, 2);
711 
712 	v4l2_ctrl_new_std(handler, ops, V4L2_CID_GAIN, 1 * 16,
713 			  256 * 16, 1, 1 * 16);
714 	ctrl = v4l2_ctrl_new_std(handler, ops, V4L2_CID_EXPOSURE, 0,
715 				 65536 * 16, 1, 0);
716 	if (ctrl)
717 		ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
718 
719 	if (handler->error) {
720 		ret = handler->error;
721 		v4l2_ctrl_handler_free(handler);
722 	}
723 
724 	sd->ctrl_handler = handler;
725 
726 	return ret;
727 }
728 
sensor_probe(struct i2c_client * client,const struct i2c_device_id * id)729 static int sensor_probe(struct i2c_client *client,
730 			const struct i2c_device_id *id)
731 {
732 	struct v4l2_subdev *sd = NULL;
733 	struct sensor_info *info = NULL;
734 
735 	info = kzalloc(sizeof(*info), GFP_KERNEL);
736 	if (!info)
737 		return -ENOMEM;
738 
739 	sd = &info->sd;
740 
741 	cci_dev_probe_helper(sd, client, &sensor_ops, &cci_drv);
742 
743 	sensor_init_controls(sd, &sensor_ctrl_ops);
744 
745 	mutex_init(&info->lock);
746 
747 	info->fmt = &sensor_formats[0];
748 	info->fmt_pt = &sensor_formats[0];
749 	info->win_pt = &sensor_win_sizes[0];
750 	info->fmt_num = N_FMTS;
751 	info->win_size_num = N_WIN_SIZES;
752 	info->sensor_field = V4L2_FIELD_NONE;
753 	info->stream_seq = MIPI_BEFORE_SENSOR;
754 	info->combo_mode = CMB_TERMINAL_RES | CMB_PHYA_OFFSET2 |
755 				MIPI_NORMAL_MODE;
756 	info->time_hs = 0x30;
757 	info->af_first_flag = 1;
758 	info->exp = 0;
759 	info->gain = 0;
760 
761 	return 0;
762 }
763 
sensor_remove(struct i2c_client * client)764 static int sensor_remove(struct i2c_client *client)
765 {
766 	struct v4l2_subdev *sd;
767 
768 	sd = cci_dev_remove_helper(client, &cci_drv);
769 	kfree(to_state(sd));
770 
771 	return 0;
772 }
773 
774 static const struct i2c_device_id sensor_id[] = {
775 	{SENSOR_NAME, 0},
776 	{}
777 };
778 
779 MODULE_DEVICE_TABLE(i2c, sensor_id);
780 
781 static struct i2c_driver sensor_driver = {
782 	.driver = {
783 		.owner = THIS_MODULE,
784 		.name = SENSOR_NAME,
785 	},
786 	.probe = sensor_probe,
787 	.remove = sensor_remove,
788 	.id_table = sensor_id,
789 };
790 
init_sensor(void)791 static __init int init_sensor(void)
792 {
793 	return cci_dev_init_helper(&sensor_driver);
794 }
795 
exit_sensor(void)796 static __exit void exit_sensor(void)
797 {
798 	cci_dev_exit_helper(&sensor_driver);
799 }
800 
801 module_init(init_sensor);
802 module_exit(exit_sensor);
803