xref: /OK3568_Linux_fs/kernel/drivers/video/rockchip/vehicle/vehicle_main.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * drivers/video/rockchip/video/vehicle_main.c
4  *
5  * Copyright (C) 2022 Rockchip Electronics Co.Ltd
6  * Authors:
7  *	Zhiqin Wei <wzq@rock-chips.com>
8  *      <randy.wang@rock-chips.com>
9  *	Jianwei Fan <jianwei.fan@rock-chips.com>
10  *
11  */
12 
13 #define CAMMODULE_NAME    "vehicle_main"
14 
15 #include <linux/module.h>
16 #include <linux/delay.h>
17 #include <linux/errno.h>
18 #include <linux/kernel.h>
19 #include <linux/time.h>
20 #include <linux/platform_device.h>
21 #include <linux/init.h>
22 #include <linux/kthread.h>
23 #include <linux/fb.h>
24 #include <linux/clk.h>
25 #include <linux/clkdev.h>
26 #include <linux/completion.h>
27 #include <linux/wakelock.h>
28 #include <linux/of_gpio.h>
29 #include <linux/of_address.h>
30 #include <linux/of_irq.h>
31 #include <linux/pm_runtime.h>
32 #include <linux/interrupt.h>
33 #include "vehicle_flinger.h"
34 #include "vehicle_cfg.h"
35 #include "vehicle_ad.h"
36 #include "vehicle_main.h"
37 #include "vehicle_cif.h"
38 #include "vehicle_gpio.h"
39 #include <linux/version.h>
40 #include "../../../media/platform/rockchip/cif/dev.h"
41 #include "../../../phy/rockchip/phy-rockchip-csi2-dphy-common.h"
42 
43 #define DRIVER_VERSION		KERNEL_VERSION(0, 0x03, 0x02)
44 
45 static bool flinger_inited;
46 static bool TEST_GPIO = true;
47 static bool dvr_apk_need_start;
48 
49 enum {
50 	STATE_CLOSE = 0,
51 	STATE_OPEN,
52 };
53 
54 struct vehicle {
55 	struct device	*dev;
56 	struct pinctrl *pinctrl;
57 	struct pinctrl_state *pins_default;
58 	struct wake_lock wake_lock;
59 	struct gpio_detect gpio_data;
60 	struct vehicle_cif cif;
61 	struct vehicle_ad_dev ad;
62 	int mirror;
63 	wait_queue_head_t vehicle_wait;
64 	atomic_t vehicle_atomic;
65 	int state;
66 	bool android_is_ready;
67 	bool gpio_over;
68 };
69 
70 static struct vehicle *g_vehicle;
71 
vehicle_parse_dt(struct vehicle * vehicle_info)72 static int vehicle_parse_dt(struct vehicle *vehicle_info)
73 {
74 	struct device	*dev = vehicle_info->dev;
75 
76 	/*  1. pinctrl */
77 	vehicle_info->pinctrl = devm_pinctrl_get(dev);
78 
79 	if (IS_ERR(vehicle_info->pinctrl)) {
80 		dev_err(dev, "pinctrl get failed, maybe unuse\n");
81 	} else {
82 		vehicle_info->pins_default = pinctrl_lookup_state(vehicle_info->pinctrl,
83 				"default");
84 
85 		if (IS_ERR(vehicle_info->pins_default))
86 			dev_err(dev, "get default pinstate failed\n");
87 	}
88 
89 	return 0;
90 }
91 
vehicle_ad_stat_change_notify(void)92 void vehicle_ad_stat_change_notify(void)
93 {
94 	if (g_vehicle) {
95 		VEHICLE_INFO("ad state change! set atpmic to 1!\n");
96 		atomic_set(&g_vehicle->vehicle_atomic, 1);
97 	}
98 }
99 
vehicle_cif_stat_change_notify(void)100 void vehicle_cif_stat_change_notify(void)
101 {
102 	if (g_vehicle) {
103 		VEHICLE_INFO("cif state change! set atpmic to 1!\n");
104 		atomic_set(&g_vehicle->vehicle_atomic, 1);
105 	}
106 }
107 
vehicle_gpio_stat_change_notify(void)108 void vehicle_gpio_stat_change_notify(void)
109 {
110 	if (g_vehicle && !g_vehicle->gpio_over) {
111 		VEHICLE_INFO("reverse gpio state change! set atpmic to 1!\n");
112 		atomic_set(&g_vehicle->vehicle_atomic, 1);
113 	}
114 }
115 
vehicle_cif_error_notify(int last_line)116 void vehicle_cif_error_notify(int last_line)
117 {
118 	if (g_vehicle) {
119 		VEHICLE_INFO("cif error notify\n");
120 		vehicle_ad_check_cif_error(&g_vehicle->ad, last_line);
121 	}
122 }
123 
vehicle_open(struct vehicle_cfg * v_cfg)124 static void vehicle_open(struct vehicle_cfg *v_cfg)
125 {
126 	VEHICLE_INFO("%s enter: android_is_ready ?= %d",
127 			__func__, g_vehicle->android_is_ready);
128 	vehicle_flinger_reverse_open(v_cfg, g_vehicle->android_is_ready);
129 	vehicle_cif_reverse_open(v_cfg);
130 }
131 
vehicle_close(void)132 static void vehicle_close(void)
133 {
134 	vehicle_cif_reverse_close();
135 	vehicle_flinger_reverse_close(g_vehicle->android_is_ready);
136 }
137 
vehicle_open_close(void)138 static void vehicle_open_close(void)
139 {
140 	vehicle_cif_reverse_close();
141 }
142 
vehicle_state_change(struct vehicle * v)143 static int vehicle_state_change(struct vehicle *v)
144 {
145 	struct vehicle_cfg *v_cfg;
146 	struct gpio_detect *gpiod = &v->gpio_data;
147 	bool gpio_reverse_on;
148 	int ret = 0;
149 
150 	/*  1. get ad sensor cfg */
151 	v_cfg = vehicle_ad_get_vehicle_cfg();
152 
153 	if (!v_cfg) {
154 		VEHICLE_DGERR("v_cfg is NULL, if for test continue.\n");
155 		return -ENODEV;
156 	}
157 
158 	if (!flinger_inited) {
159 		do {
160 			/*  2. flinger */
161 			VEHICLE_DG("%s: flinger init start\r\n", __func__);
162 			ret = vehicle_flinger_init(v->dev, v_cfg);
163 			if (ret < 0) {
164 				VEHICLE_DG("rk_vehicle_system_main: flinger init failed\r\n");
165 				msleep(20);
166 			}
167 		} while (ret);
168 	}
169 	VEHICLE_DG("%s: flinger init success\r\n", __func__);
170 	flinger_inited = true;
171 
172 	gpio_reverse_on = vehicle_gpio_reverse_check(gpiod);
173 	gpio_reverse_on = TEST_GPIO & gpio_reverse_on;
174 	VEHICLE_INFO(
175 	"%s, gpio = reverse %s, width = %d, sensor_ready = %d, state=%d dvr_apk_need_start = %d\n",
176 	__func__, gpio_reverse_on ? "on" : "over",
177 	v_cfg->width, v_cfg->ad_ready, v->state, dvr_apk_need_start);
178 	if (v_cfg->mbus_flags & V4L2_MBUS_CSI2_CONTINUOUS_CLOCK) {
179 		switch (v->state) {
180 		case STATE_CLOSE:
181 			if (dvr_apk_need_start) {
182 				vehicle_open(v_cfg);
183 				msleep(20);
184 				vehicle_ad_stream(&v->ad, 0);
185 				vehicle_ad_channel_set(&g_vehicle->ad, 0);
186 				vehicle_ad_stream(&v->ad, 1);
187 				v->state = STATE_OPEN;
188 			}
189 			if (gpio_reverse_on) {
190 				vehicle_open(v_cfg);
191 				msleep(20);
192 				vehicle_ad_stream(&v->ad, 0);
193 				vehicle_ad_channel_set(&g_vehicle->ad, 0);
194 				vehicle_ad_stream(&v->ad, 1);
195 				v->state = STATE_OPEN;
196 			}
197 			break;
198 		case STATE_OPEN:
199 			/*  reverse exit || video loss */
200 			if (!dvr_apk_need_start && (!gpio_reverse_on || !v_cfg->ad_ready)) {
201 				vehicle_close();
202 				vehicle_ad_stream(&v->ad, 0);
203 				v->state = STATE_CLOSE;
204 			} else if (gpio_reverse_on && !v->android_is_ready) { //video fmt change
205 				vehicle_open_close();
206 				vehicle_open(v_cfg);
207 				msleep(100);
208 				vehicle_ad_stream(&v->ad, 0);
209 				vehicle_ad_channel_set(&g_vehicle->ad, 0);
210 				vehicle_ad_stream(&v->ad, 1);
211 			} else if (!gpio_reverse_on && dvr_apk_need_start) {
212 				vehicle_close();
213 				vehicle_open(v_cfg);
214 				msleep(20);
215 				vehicle_ad_stream(&v->ad, 0);
216 				vehicle_ad_channel_set(&g_vehicle->ad, 0);
217 				vehicle_ad_stream(&v->ad, 1);
218 			}
219 			break;
220 		}
221 	} else if (v_cfg->mbus_flags & V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK) {
222 		switch (v->state) {
223 		case STATE_CLOSE:
224 			if (dvr_apk_need_start) {
225 				vehicle_ad_stream(&v->ad, 0);
226 				vehicle_ad_channel_set(&g_vehicle->ad, 0);
227 				vehicle_ad_stream(&v->ad, 1);
228 				msleep(20);
229 				vehicle_open(v_cfg);
230 				v->state = STATE_OPEN;
231 			}
232 			if (gpio_reverse_on) {
233 				vehicle_ad_stream(&v->ad, 0);
234 				vehicle_ad_channel_set(&g_vehicle->ad, 0);
235 				vehicle_ad_stream(&v->ad, 1);
236 				msleep(20);
237 				vehicle_open(v_cfg);
238 				v->state = STATE_OPEN;
239 			}
240 			break;
241 		case STATE_OPEN:
242 			/*  reverse exit || video loss */
243 			if (!dvr_apk_need_start && (!gpio_reverse_on || !v_cfg->ad_ready)) {
244 				vehicle_close();
245 				vehicle_ad_stream(&v->ad, 0);
246 				v->state = STATE_CLOSE;
247 			} else if (gpio_reverse_on && !v->android_is_ready) { //video fmt change
248 				vehicle_open_close();
249 				vehicle_ad_stream(&v->ad, 0);
250 				vehicle_ad_channel_set(&g_vehicle->ad, 0);
251 				vehicle_ad_stream(&v->ad, 1);
252 				msleep(100);
253 				vehicle_open(v_cfg);
254 			} else if (!gpio_reverse_on && dvr_apk_need_start) {
255 				vehicle_close();
256 				vehicle_ad_stream(&v->ad, 0);
257 				vehicle_ad_channel_set(&g_vehicle->ad, 0);
258 				vehicle_ad_stream(&v->ad, 1);
259 				msleep(20);
260 				vehicle_open(v_cfg);
261 			}
262 			break;
263 		}
264 	} else {
265 		switch (v->state) {
266 		case STATE_CLOSE:
267 			if (dvr_apk_need_start) {
268 				vehicle_ad_stream(&v->ad, 0);
269 				vehicle_ad_channel_set(&g_vehicle->ad, 0);
270 				vehicle_ad_stream(&v->ad, 1);
271 				msleep(20);
272 				vehicle_open(v_cfg);
273 				v->state = STATE_OPEN;
274 			}
275 			if (gpio_reverse_on) {
276 				vehicle_ad_stream(&v->ad, 0);
277 				vehicle_ad_channel_set(&g_vehicle->ad, 0);
278 				vehicle_ad_stream(&v->ad, 1);
279 				msleep(20);
280 				vehicle_open(v_cfg);
281 				v->state = STATE_OPEN;
282 			}
283 			break;
284 		case STATE_OPEN:
285 			/*  reverse exit || video loss */
286 			if (!dvr_apk_need_start && (!gpio_reverse_on || !v_cfg->ad_ready)) {
287 				vehicle_close();
288 				vehicle_ad_stream(&v->ad, 0);
289 				v->state = STATE_CLOSE;
290 			} else if (gpio_reverse_on && !v->android_is_ready) { //video fmt change
291 				vehicle_open_close();
292 				vehicle_ad_stream(&v->ad, 0);
293 				vehicle_ad_channel_set(&g_vehicle->ad, 0);
294 				vehicle_ad_stream(&v->ad, 1);
295 				msleep(100);
296 				vehicle_open(v_cfg);
297 			} else if (!gpio_reverse_on && dvr_apk_need_start) {
298 				vehicle_close();
299 				vehicle_ad_stream(&v->ad, 0);
300 				vehicle_ad_channel_set(&g_vehicle->ad, 0);
301 				vehicle_ad_stream(&v->ad, 1);
302 				msleep(20);
303 				vehicle_open(v_cfg);
304 			}
305 			break;
306 		}
307 	}
308 
309 	return 0;
310 }
311 
vehicle_probe(struct platform_device * pdev)312 static int vehicle_probe(struct platform_device *pdev)
313 {
314 	struct vehicle *vehicle_info;
315 
316 	dev_info(&pdev->dev, "driver version: %02x.%02x.%02x",
317 		 DRIVER_VERSION >> 16,
318 		 (DRIVER_VERSION & 0xff00) >> 8,
319 		 DRIVER_VERSION & 0x00ff);
320 
321 	vehicle_info = devm_kzalloc(&pdev->dev,
322 				    sizeof(struct vehicle), GFP_KERNEL);
323 	if (!vehicle_info)
324 		return -ENOMEM;
325 
326 	vehicle_info->dev = &pdev->dev;
327 	vehicle_info->gpio_data.dev = &pdev->dev;
328 	vehicle_info->cif.dev = &pdev->dev;
329 	vehicle_info->ad.dev = &pdev->dev;
330 
331 	dev_set_name(vehicle_info->dev, "vehicle_main");
332 	if (!pdev->dev.of_node)
333 		return -EINVAL;
334 
335 	vehicle_parse_dt(vehicle_info);
336 
337 	if (vehicle_parse_sensor(&vehicle_info->ad) < 0) {
338 		VEHICLE_DGERR("parse sensor failed!\n");
339 		return -EINVAL;
340 	}
341 
342 	wake_lock_init(&vehicle_info->wake_lock, WAKE_LOCK_SUSPEND, "vehicle");
343 
344 	dev_info(vehicle_info->dev, "vehicle driver probe success\n");
345 
346 	init_waitqueue_head(&vehicle_info->vehicle_wait);
347 	atomic_set(&vehicle_info->vehicle_atomic, 0);
348 	vehicle_info->state = STATE_CLOSE;
349 	vehicle_info->android_is_ready = false;
350 	vehicle_info->gpio_over = false;
351 
352 	g_vehicle = vehicle_info;
353 
354 	return 0;
355 }
356 
357 #if defined(CONFIG_OF)
358 static const struct of_device_id vehicle_of_match[] = {
359 	{ .compatible = "rockchip,vehicle", },
360 	{},
361 };
362 #endif
363 
364 static struct platform_driver vehicle_driver = {
365 	.driver     = {
366 		.name   = "vehicle",
367 		.owner  = THIS_MODULE,
368 		.of_match_table = of_match_ptr(vehicle_of_match),
369 	},
370 	.probe      = vehicle_probe,
371 };
372 
vehicle_android_is_ready_notify(void)373 void vehicle_android_is_ready_notify(void)
374 {
375 	if (g_vehicle)
376 		g_vehicle->android_is_ready = true;
377 	TEST_GPIO = !TEST_GPIO;
378 	atomic_set(&g_vehicle->vehicle_atomic, 1);
379 }
380 
vehicle_apk_state_change(char data[22])381 void vehicle_apk_state_change(char data[22])
382 {
383 	if (memcmp(data, "11", 2) == 0)
384 		dvr_apk_need_start = true;
385 	else if (memcmp(data, "10", 2) == 0)
386 		dvr_apk_need_start = false;
387 
388 	if (g_vehicle)
389 		atomic_set(&g_vehicle->vehicle_atomic, 1);
390 }
391 
vehicle_exit_complete_notify(struct vehicle * v)392 static void vehicle_exit_complete_notify(struct vehicle *v)
393 {
394 	char *status = NULL;
395 	char *envp[2];
396 
397 	if (!v)
398 		return;
399 	status = kasprintf(GFP_KERNEL, "vehicle_exit=done");
400 	envp[0] = status;
401 	envp[1] = NULL;
402 	wake_lock_timeout(&v->wake_lock, 5 * HZ);
403 	kobject_uevent_env(&v->dev->kobj, KOBJ_CHANGE, envp);
404 
405 	kfree(status);
406 }
407 
rk_vehicle_system_main(void * arg)408 static int rk_vehicle_system_main(void *arg)
409 {
410 	int ret = -1;
411 	struct vehicle *v = g_vehicle;
412 	int loop_times = 0;
413 
414 	if (!g_vehicle) {
415 		VEHICLE_DGERR("vehicle probe failed, g_vehicle is NULL.\n");
416 		goto VEHICLE_EXIT;
417 	}
418 
419 	/*  0. gpio init and check state */
420 	ret = vehicle_gpio_init(&v->gpio_data, v->ad.ad_name);
421 	if (ret < 0) {
422 		VEHICLE_DGERR("%s: gpio init failed\r\n", __func__);
423 		goto VEHICLE_GPIO_DEINIT;
424 	}
425 	VEHICLE_DG("vehicle_gpio_init ok!\n");
426 
427 	/*  1.ad */
428 	VEHICLE_DG("%s: vehicle_ad_init start\r\n", __func__);
429 	/* config mclk first */
430 	ret = vehicle_cif_init_mclk(&v->cif);
431 	ret |= vehicle_ad_init(&v->ad);
432 	if (ret < 0) {
433 		VEHICLE_DGERR("%s: ad init failed\r\n", __func__);
434 		goto VEHICLE_AD_DEINIT;
435 	}
436 	VEHICLE_DG("vehicle_ad_init ok!\r\n");
437 
438 	/*  3. cif init */
439 	ret = vehicle_cif_init(&v->cif);
440 	if (ret < 0) {
441 		VEHICLE_DGERR("%s: cif init failed\r\n", __func__);
442 		goto VEHICLE_CIF_DEINIT;
443 	}
444 	VEHICLE_DG("%s: vehicle_cif_init ok!\r\n", __func__);
445 	pm_runtime_enable(v->dev);
446 	pm_runtime_get_sync(v->dev);
447 
448 	//while (STATE_OPEN == v->state || !v->vehicle_need_exit) {
449 	while (v->state == STATE_OPEN || !v->android_is_ready) {
450 		if (v->android_is_ready && !v->state)
451 			v->gpio_over = true;
452 		wait_event_timeout(v->vehicle_wait,
453 				   atomic_read(&v->vehicle_atomic),
454 				   msecs_to_jiffies(100));
455 		if (atomic_read(&v->vehicle_atomic)) {
456 			atomic_set(&v->vehicle_atomic, 0);
457 			vehicle_state_change(v);
458 		}
459 		VEHICLE_DG("loop time(%d) \r\n", loop_times);
460 		loop_times++;
461 	}
462 
463 VEHICLE_CIF_DEINIT:
464 	vehicle_cif_deinit(&v->cif);
465 
466 VEHICLE_AD_DEINIT:
467 	vehicle_ad_deinit();
468 
469 VEHICLE_GPIO_DEINIT:
470 	vehicle_gpio_deinit(&v->gpio_data);
471 
472 	/*Init normal drivers*/
473 VEHICLE_EXIT:
474 	if (flinger_inited)
475 		vehicle_flinger_deinit();
476 	// if (v && v->pinctrl)
477 	//	pinctrl_put(v->pinctrl);
478 	vehicle_to_v4l2_drv_init();
479 	msleep(500);
480 	rockchip_csi2_dphy_hw_init();
481 	rockchip_csi2_dphy_init();
482 	rk_cif_plat_drv_init();
483 	// rkcif_csi2_plat_drv_init();
484 	rkcif_clr_unready_dev();
485 #ifdef CONFIG_GPIO_DET
486 	//gpio_det_init();
487 #endif
488 	// msleep(1000);
489 	vehicle_exit_complete_notify(v);
490 	return 0;
491 }
492 
vehicle_system_start(void)493 static int __init vehicle_system_start(void)
494 {
495 	platform_driver_register(&vehicle_driver);
496 	kthread_run(rk_vehicle_system_main, NULL, "vehicle main");
497 
498 	return 0;
499 }
500 
501 subsys_initcall_sync(vehicle_system_start);
502