xref: /OK3568_Linux_fs/kernel/drivers/video/rockchip/vehicle/vehicle_generic_sensor.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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, &reg, 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, &reg, 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