1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * drivers/video/rockchip/video/vehicle_generic_sensor.c
4 *
5 * Copyright (C) 2020 Rockchip Electronics Co.Ltd
6 * Authors:
7 * Zhiqin Wei <wzq@rock-chips.com>
8 *
9 */
10
11 #include <linux/kernel.h>
12 #include <linux/slab.h>
13 #include <linux/i2c.h>
14 #include <linux/of_gpio.h>
15 #include "vehicle_ad.h"
16 #include "vehicle_ad_7181.h"
17 #include "vehicle_ad_tp2825.h"
18 #include "vehicle_ad_gc2145.h"
19 #include "vehicle_ad_nvp6324.h"
20 #include "vehicle_ad_nvp6188.h"
21 #include "vehicle_ad_max96714.h"
22 #include <linux/moduleparam.h>
23 #include "../../../../drivers/media/i2c/jaguar1_drv/jaguar1_v4l2.h"
24 #include "../../../../drivers/media/i2c/nvp6188.h"
25 #include "../../../../drivers/media/i2c/max96714.h"
26
27 struct vehicle_sensor_ops {
28 const char *name;
29 int (*sensor_init)(struct vehicle_ad_dev *ad);
30 int (*sensor_deinit)(void);
31 int (*sensor_stream)(struct vehicle_ad_dev *ad, int value);
32 int (*sensor_get_cfg)(struct vehicle_cfg **cfg);
33 void (*sensor_check_cif_error)(struct vehicle_ad_dev *ad, int last_line);
34 int (*sensor_check_id_cb)(struct vehicle_ad_dev *ad);
35 void (*sensor_set_channel)(struct vehicle_ad_dev *ad, int channel);
36 int (*sensor_mod_init)(void);
37 };
38 static struct vehicle_sensor_ops *sensor_cb;
39
40 static struct vehicle_sensor_ops sensor_cb_series[] = {
41 {
42 .name = "adv7181",
43 #ifdef CONFIG_VIDEO_REVERSE_AD7181
44 .sensor_init = adv7181_ad_init,
45 .sensor_deinit = adv7181_ad_deinit,
46 .sensor_stream = adv7181_stream,
47 .sensor_get_cfg = adv7181_ad_get_cfg,
48 .sensor_check_cif_error = adv7181_ad_check_cif_error,
49 .sensor_check_id_cb = adv7181_check_id,
50 .sensor_set_channel = adv7181_channel_set
51 #endif
52 },
53 {
54 .name = "tp2825",
55 #ifdef CONFIG_VIDEO_REVERSE_TP2825
56 .sensor_init = tp2825_ad_init,
57 .sensor_deinit = tp2825_ad_deinit,
58 .sensor_stream = tp2825_stream,
59 .sensor_get_cfg = tp2825_ad_get_cfg,
60 .sensor_check_cif_error = tp2825_ad_check_cif_error,
61 .sensor_check_id_cb = tp2825_check_id,
62 .sensor_set_channel = tp2825_channel_set
63 #endif
64 },
65 {
66 .name = "gc2145",
67 #ifdef CONFIG_VIDEO_REVERSE_GC2145
68 .sensor_init = gc2145_ad_init,
69 .sensor_deinit = gc2145_ad_deinit,
70 .sensor_stream = gc2145_stream,
71 .sensor_get_cfg = gc2145_ad_get_cfg,
72 .sensor_check_cif_error = gc2145_ad_check_cif_error,
73 .sensor_check_id_cb = gc2145_check_id,
74 .sensor_set_channel = gc2145_channel_set,
75 #endif
76 },
77 {
78 .name = "nvp6324",
79 #ifdef CONFIG_VIDEO_REVERSE_NVP6324
80 .sensor_init = nvp6324_ad_init,
81 .sensor_deinit = nvp6324_ad_deinit,
82 .sensor_stream = nvp6324_stream,
83 .sensor_get_cfg = nvp6324_ad_get_cfg,
84 .sensor_check_cif_error = nvp6324_ad_check_cif_error,
85 .sensor_check_id_cb = nvp6324_check_id,
86 .sensor_set_channel = nvp6324_channel_set,
87 #ifdef CONFIG_VIDEO_NVP6324
88 .sensor_mod_init = nvp6324_sensor_mod_init
89 #endif
90 #endif
91 },
92 {
93 .name = "max96714",
94 #ifdef CONFIG_VIDEO_REVERSE_MAX96714
95 .sensor_init = max96714_ad_init,
96 .sensor_deinit = max96714_ad_deinit,
97 .sensor_stream = max96714_stream,
98 .sensor_get_cfg = max96714_ad_get_cfg,
99 .sensor_check_cif_error = max96714_ad_check_cif_error,
100 .sensor_check_id_cb = max96714_check_id,
101 .sensor_set_channel = max96714_channel_set,
102 #ifdef CONFIG_VIDEO_MAX96714
103 .sensor_mod_init = max96714_sensor_mod_init
104 #endif
105 #endif
106 },
107 {
108 .name = "nvp6188",
109 #ifdef CONFIG_VIDEO_REVERSE_NVP6188
110 .sensor_init = nvp6188_ad_init,
111 .sensor_deinit = nvp6188_ad_deinit,
112 .sensor_stream = nvp6188_stream,
113 .sensor_get_cfg = nvp6188_ad_get_cfg,
114 .sensor_check_cif_error = nvp6188_ad_check_cif_error,
115 .sensor_check_id_cb = nvp6188_check_id,
116 .sensor_set_channel = nvp6188_channel_set,
117 #ifdef CONFIG_VIDEO_NVP6188
118 .sensor_mod_init = nvp6188_sensor_mod_init
119 #endif
120 #endif
121 }
122 };
123
vehicle_generic_sensor_write(struct vehicle_ad_dev * ad,char reg,char * pval)124 int vehicle_generic_sensor_write(struct vehicle_ad_dev *ad, char reg, char *pval)
125 {
126 struct i2c_msg msg;
127 int ret;
128
129 char *tx_buf = kmalloc(2, GFP_KERNEL);
130
131 if (!tx_buf)
132 return -ENOMEM;
133
134 memcpy(tx_buf, ®, 1);
135 memcpy(tx_buf+1, (char *)pval, 1);
136
137 msg.addr = ad->i2c_add;
138 msg.flags = 0;
139 msg.len = 2;
140 msg.buf = (char *)tx_buf;
141 // msg.scl_rate = ad->i2c_rate;
142
143 ret = i2c_transfer(ad->adapter, &msg, 1);
144 kfree(tx_buf);
145
146 return (ret == 1) ? 4 : ret;
147 }
148
vehicle_sensor_write(struct vehicle_ad_dev * ad,u8 reg,u8 val)149 int vehicle_sensor_write(struct vehicle_ad_dev *ad, u8 reg, u8 val)
150 {
151 struct i2c_msg msg;
152 u8 buf[2];
153 int ret;
154
155 //SENSOR_DG("write reg(0x%x val:0x%x)!\n", reg, val);
156 buf[0] = reg & 0xFF;
157 buf[1] = val;
158
159 msg.addr = ad->i2c_add;
160 msg.flags = 0;
161 msg.buf = buf;
162 msg.len = sizeof(buf);
163
164 ret = i2c_transfer(ad->adapter, &msg, 1);
165 if (ret >= 0)
166 return 0;
167
168 VEHICLE_DGERR("write reg(0x%x val:0x%x) failed !\n", reg, val);
169 return ret;
170 }
171
vehicle_generic_sensor_read(struct vehicle_ad_dev * ad,char reg)172 int vehicle_generic_sensor_read(struct vehicle_ad_dev *ad, char reg)
173 {
174 struct i2c_msg msgs[2];
175 int ret;
176 char reg_buf[2];
177 char pval;
178
179 memcpy(reg_buf, ®, 1);
180
181 msgs[0].addr = ad->i2c_add;
182 msgs[0].flags = 0;
183 msgs[0].len = 1;
184 msgs[0].buf = reg_buf;
185 // msgs[0].scl_rate = ad->i2c_rate;
186
187 msgs[1].addr = ad->i2c_add;
188 msgs[1].flags = I2C_M_RD;
189 msgs[1].len = 1;
190 msgs[1].buf = &pval;
191 // msgs[1].scl_rate = ad->i2c_rate;
192
193 ret = i2c_transfer(ad->adapter, msgs, 2);
194 if (ret)
195 return ret;
196
197 return pval;
198 }
199
200 /* sensor register read */
vehicle_sensor_read(struct vehicle_ad_dev * ad,u8 reg,u8 * val)201 int vehicle_sensor_read(struct vehicle_ad_dev *ad, u8 reg, u8 *val)
202 {
203 struct i2c_msg msg[2];
204 u8 buf[1];
205 int ret;
206
207 buf[0] = reg & 0xFF;
208
209 msg[0].addr = ad->i2c_add;
210 msg[0].flags = 0;
211 msg[0].buf = buf;
212 msg[0].len = sizeof(buf);
213
214 msg[1].addr = ad->i2c_add;
215 msg[1].flags = I2C_M_RD;
216 msg[1].buf = buf;
217 msg[1].len = 1;
218
219 ret = i2c_transfer(ad->adapter, msg, 2);
220 if (ret >= 0) {
221 *val = buf[0];
222 return 0;
223 }
224
225 dev_err(ad->dev,
226 "read reg:0x%x failed !\n", reg);
227
228 return ret;
229 }
230
vehicle_ad_stream(struct vehicle_ad_dev * ad,int val)231 int vehicle_ad_stream(struct vehicle_ad_dev *ad, int val)
232 {
233 int ret = 0;
234
235 if (sensor_cb && sensor_cb->sensor_stream) {
236 ret = sensor_cb->sensor_stream(ad, val);
237 if (ret < 0)
238 VEHICLE_DGERR("%s sensor_init failed!\n", ad->ad_name);
239 }
240
241 return ret;
242 }
243
vehicle_parse_sensor(struct vehicle_ad_dev * ad)244 int vehicle_parse_sensor(struct vehicle_ad_dev *ad)
245 {
246 struct device *dev = ad->dev;
247 struct device_node *node = NULL;
248 struct device_node *cp = NULL;
249 enum of_gpio_flags flags;
250 const char *status = NULL;
251 int i;
252 int ret = 0;
253
254 if (of_property_read_u32(dev->of_node, "ad,fix-format",
255 &ad->fix_format))
256 VEHICLE_DGERR("get fix-format failed!\n");
257
258 if (of_property_read_u32(dev->of_node, "vehicle,rotate-mirror",
259 &ad->cfg.rotate_mirror))
260 VEHICLE_DGERR("get rotate-mirror failed!\n");
261
262 node = of_parse_phandle(dev->of_node, "rockchip,cif-sensor", 0);
263 if (!node) {
264 VEHICLE_DGERR("get cif-sensor dts failed\n");
265 return -ENODEV;
266 }
267
268 for_each_child_of_node(node, cp) {
269 of_property_read_string(cp, "status", &status);
270 if (status && !strcmp(status, "disabled"))
271 continue;
272 VEHICLE_DG("status: %s\n", status);
273
274 // if (of_property_read_u32(cp, "i2c_rata", &ad->i2c_rate))
275 // SENSOR_DG("Get %s i2c_rata failed!\n", cp->name);
276 if (of_property_read_u32(cp, "i2c_chl", &ad->i2c_chl))
277 VEHICLE_DGERR("Get %s i2c_chl failed!", cp->name);
278 if (of_property_read_u32(cp, "ad_chl", &ad->ad_chl))
279 VEHICLE_DGERR("Get %s ad_chl failed!", cp->name);
280
281 if (ad->ad_chl > 4 || ad->ad_chl < 0) {
282 VEHICLE_DGERR("error, ad_chl %d !\n", ad->ad_chl);
283 ad->ad_chl = 0;
284 }
285 if (of_property_read_u32(cp, "mclk_rate", &ad->mclk_rate))
286 VEHICLE_DGERR("Get %s mclk_rate failed!\n", cp->name);
287
288 if (of_property_read_u32(cp, "drop_frames",
289 &ad->drop_frames)) {
290 VEHICLE_DGERR("%s:Get sensor, drop-frames failed!\n", __func__);
291 ad->drop_frames = 0; //default drop frames;
292 }
293
294 if (of_property_read_u32(cp, "rst_active", &ad->rst_active))
295 VEHICLE_DGERR("Get %s rst_active failed!", cp->name);
296
297 ad->reset = of_get_named_gpio_flags(cp, "reset-gpios",
298 0, &flags);
299
300 if (of_property_read_u32(cp, "pwr_active", &ad->pwr_active))
301 VEHICLE_DGERR("Get %s pwr_active failed!\n", cp->name);
302
303 if (of_property_read_u32(cp, "pwdn_active", &ad->pwdn_active))
304 VEHICLE_DGERR("Get %s pwdn_active failed!\n", cp->name);
305
306 ad->power = of_get_named_gpio_flags(cp, "power-gpios",
307 0, &flags);
308 ad->powerdown = of_get_named_gpio_flags(cp,
309 "powerdown-gpios",
310 0, &flags);
311 ad->reset = of_get_named_gpio_flags(cp, "reset-gpios",
312 0, &flags);
313
314 if (of_property_read_u32(cp, "i2c_add", &ad->i2c_add))
315 VEHICLE_DGERR("Get %s i2c_add failed!\n", cp->name);
316
317 ad->i2c_add = (ad->i2c_add >> 1);
318
319 if (of_property_read_u32(cp, "resolution", &ad->resolution))
320 VEHICLE_DGERR("Get %s resolution failed!\n", cp->name);
321
322 of_property_read_u32_array(cp,
323 "rockchip,camera-module-defrect0",
324 (unsigned int *)&ad->defrects[0], 6);
325 of_property_read_u32_array(cp,
326 "rockchip,camera-module-defrect1",
327 (unsigned int *)&ad->defrects[1], 6);
328 of_property_read_u32_array(cp,
329 "rockchip,camera-module-defrect2",
330 (unsigned int *)&ad->defrects[2], 6);
331 of_property_read_u32_array(cp,
332 "rockchip,camera-module-defrect3",
333 (unsigned int *)&ad->defrects[3], 6);
334
335 of_property_read_string(cp,
336 "rockchip,camera-module-interface0",
337 &ad->defrects[0].interface);
338 of_property_read_string(cp,
339 "rockchip,camera-module-interface1",
340 &ad->defrects[1].interface);
341 of_property_read_string(cp,
342 "rockchip,camera-module-interface2",
343 &ad->defrects[2].interface);
344 of_property_read_string(cp,
345 "rockchip,camera-module-interface3",
346 &ad->defrects[3].interface);
347
348 ad->ad_name = cp->name;
349 for (i = 0; i < ARRAY_SIZE(sensor_cb_series); i++) {
350 if (!strcmp(ad->ad_name, sensor_cb_series[i].name))
351 sensor_cb = sensor_cb_series + i;
352 }
353
354 VEHICLE_DG("%s: ad_chl=%d,,ad_addr=%x,fix_for=%d\n", ad->ad_name,
355 ad->ad_chl, ad->i2c_add, ad->fix_format);
356 VEHICLE_DG("gpio power:%d, active:%d\n", ad->power, ad->pwr_active);
357 VEHICLE_DG("gpio powerdown:%d, active:%d\n",
358 ad->powerdown, ad->pwdn_active);
359 break;
360 }
361
362 if (!ad->ad_name)
363 ret = -EINVAL;
364
365 return ret;
366 }
367
vehicle_ad_channel_set(struct vehicle_ad_dev * ad,int channel)368 void vehicle_ad_channel_set(struct vehicle_ad_dev *ad, int channel)
369 {
370 if (sensor_cb->sensor_set_channel)
371 sensor_cb->sensor_set_channel(ad, channel);
372 }
373
vehicle_ad_init(struct vehicle_ad_dev * ad)374 int vehicle_ad_init(struct vehicle_ad_dev *ad)
375 {
376 int ret = 0;
377 //WARN_ON(1);
378 VEHICLE_DGERR("%s(%d) ad_name:%s!", __func__, __LINE__, ad->ad_name);
379
380 if (sensor_cb->sensor_init) {
381 ret = sensor_cb->sensor_init(ad);
382 if (ret < 0) {
383 VEHICLE_DGERR("%s sensor_init failed!\n", ad->ad_name);
384 goto end;
385 }
386 } else {
387 VEHICLE_DGERR("%s sensor_init is NULL!\n", ad->ad_name);
388 ret = -1;
389 goto end;
390 }
391
392 if (sensor_cb->sensor_check_id_cb) {
393 ret = sensor_cb->sensor_check_id_cb(ad);
394 if (ret < 0)
395 VEHICLE_DGERR("%s check id failed!\n", ad->ad_name);
396 }
397
398 end:
399 return ret;
400 }
401
vehicle_ad_deinit(void)402 int vehicle_ad_deinit(void)
403 {
404 int ret = 0;
405
406 if (sensor_cb->sensor_deinit)
407 ret = sensor_cb->sensor_deinit();
408 else
409 ret = -EINVAL;
410
411 return ret;
412 }
413
vehicle_to_v4l2_drv_init(void)414 int vehicle_to_v4l2_drv_init(void)
415 {
416 int ret = 0;
417
418 VEHICLE_DG("%s(%d) enter!", __func__, __LINE__);
419 if (sensor_cb && sensor_cb->sensor_mod_init)
420 ret = sensor_cb->sensor_mod_init();
421 else
422 ret = -EINVAL;
423
424 return ret;
425 }
426
vehicle_ad_get_vehicle_cfg(void)427 struct vehicle_cfg *vehicle_ad_get_vehicle_cfg(void)
428 {
429 struct vehicle_cfg *cfg = NULL;
430
431 if (sensor_cb->sensor_get_cfg)
432 sensor_cb->sensor_get_cfg(&cfg);
433
434 return cfg;
435 }
436
vehicle_ad_check_cif_error(struct vehicle_ad_dev * ad,int last_line)437 void vehicle_ad_check_cif_error(struct vehicle_ad_dev *ad, int last_line)
438 {
439 if (sensor_cb->sensor_get_cfg)
440 sensor_cb->sensor_check_cif_error(ad, last_line);
441 }
442