1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * vehicle sensor adv7181
4 *
5 * Copyright (C) 2022 Rockchip Electronics Co.Ltd
6 * Authors:
7 * Zhiqin Wei <wzq@rock-chips.com>
8 *
9 */
10
11 #include <linux/init.h>
12 #include <linux/module.h>
13 #include <linux/kernel.h>
14 #include <linux/delay.h>
15 #include <linux/sched.h>
16 #include <linux/errno.h>
17 #include <linux/sysctl.h>
18 #include <linux/interrupt.h>
19 #include <linux/platform_device.h>
20 #include <linux/proc_fs.h>
21 #include <linux/suspend.h>
22 #include <linux/delay.h>
23 #include <linux/io.h>
24 #include <linux/irq.h>
25 #include <linux/uaccess.h>
26 #include <linux/of_gpio.h>
27 #include <linux/of_irq.h>
28 #include <linux/videodev2.h>
29 #include "vehicle_cfg.h"
30 #include "vehicle_main.h"
31 #include "vehicle_ad.h"
32 #include "vehicle_ad_7181.h"
33
34 enum {
35 FORCE_PAL_WIDTH = 720,
36 FORCE_PAL_HEIGHT = 576,
37 FORCE_NTSC_WIDTH = 720,
38 FORCE_NTSC_HEIGHT = 480,
39 FORCE_CIF_OUTPUT_FORMAT = CIF_OUTPUT_FORMAT_420,
40 };
41
42 static struct vehicle_ad_dev *ad7181_g_addev;
43 static v4l2_std_id std_old = V4L2_STD_NTSC;
44
45 #define SENSOR_REGISTER_LEN 1 /* sensor register address bytes*/
46 #define SENSOR_VALUE_LEN 1 /* sensor register value bytes*/
47
48 struct rk_sensor_reg {
49 unsigned int reg;
50 unsigned int val;
51 };
52
53 #define ADV7181_STATUS1_REG 0x10
54 #define ADV7181_STATUS1_IN_LOCK 0x01
55 #define ADV7181_STATUS1_AUTOD_MASK 0x70
56 #define ADV7181_STATUS1_AUTOD_NTSM_M_J 0x00
57 #define ADV7181_STATUS1_AUTOD_NTSC_4_43 0x10
58 #define ADV7181_STATUS1_AUTOD_PAL_M 0x20
59 #define ADV7181_STATUS1_AUTOD_PAL_60 0x30
60 #define ADV7181_STATUS1_AUTOD_PAL_B_G 0x40
61 #define ADV7181_STATUS1_AUTOD_SECAM 0x50
62 #define ADV7181_STATUS1_AUTOD_PAL_COMB 0x60
63 #define ADV7181_STATUS1_AUTOD_SECAM_525 0x70
64
65 #define ADV7181_INPUT_CONTROL 0x00
66 #define ADV7181_INPUT_DEFAULT 0x00
67 #define ADV7181_INPUT_CVBS_AIN2 0x00
68 #define ADV7181_INPUT_CVBS_AIN3 0x01
69 #define ADV7181_INPUT_CVBS_AIN5 0x02
70 #define ADV7181_INPUT_CVBS_AIN6 0x03
71 #define ADV7181_INPUT_CVBS_AIN8 0x04
72 #define ADV7181_INPUT_CVBS_AIN10 0x05
73 #define ADV7181_INPUT_CVBS_AIN1 0x0B
74 #define ADV7181_INPUT_CVBS_AIN4 0x0D
75 #define ADV7181_INPUT_CVBS_AIN7 0x0F
76 #define ADV7181_INPUT_YPRPB_AIN6_8_10 0x00
77
78 #define SEQCMD_END 0xFF000000
79 #define SensorEnd {SEQCMD_END, 0x00}
80
81 #define SENSOR_DG VEHICLE_DG
82
83 /* Preview resolution setting*/
84 static struct rk_sensor_reg sensor_preview_data[] = {
85 /* autodetect cvbs in ntsc/pal/secam 8-bit 422 encode */
86 {0x00, 0x0B}, /*cvbs in AIN1*/
87 {0x04, 0x77},
88 {0x17, 0x41},
89 {0x1D, 0x47},
90 {0x31, 0x02},
91 {0x3A, 0x17},
92 {0x3B, 0x81},
93 {0x3D, 0xA2},
94 {0x3E, 0x6A},
95 {0x3F, 0xA0},
96 {0x86, 0x0B},
97 {0xF3, 0x01},
98 {0xF9, 0x03},
99 {0x0E, 0x80},
100 {0x52, 0x46},
101 {0x54, 0x80},
102 {0x7F, 0xFF},
103 {0x81, 0x30},
104 {0x90, 0xC9},
105 {0x91, 0x40},
106 {0x92, 0x3C},
107 {0x93, 0xCA},
108 {0x94, 0xD5},
109 {0xB1, 0xFF},
110 {0xB6, 0x08},
111 {0xC0, 0x9A},
112 {0xCF, 0x50},
113 {0xD0, 0x4E},
114 {0xD1, 0xB9},
115 {0xD6, 0xDD},
116 {0xD7, 0xE2},
117 {0xE5, 0x51},
118 {0xF6, 0x3B},
119 {0x0E, 0x00},
120 {0x03, 0x4C}, //stream off
121 {0xDF, 0X46},
122 {0xC9, 0x04},
123 {0xC5, 0x81},
124 {0xC4, 0x34},
125 {0xBf, 0x02},
126 {0xB5, 0x83},
127 {0xB6, 0x00},
128 {0xaf, 0x03},
129 {0xae, 0x00},
130 {0xac, 0x00},
131 {0xAB, 0x00},
132 {0xa1, 0xFF},
133 {0xA2, 0x00},
134 {0xA3, 0x00},
135 {0xA4, 0x00},
136 {0xa5, 0x01},
137 {0xA6, 0x00},
138 {0xA6, 0x00},
139 {0xA7, 0x00},
140 {0xA8, 0x00},
141 {0xa0, 0x03},
142 {0x98, 0X00},
143 {0x97, 0X00},
144 {0X90, 0X00},
145 {0X85, 0X02},
146 {0x7B, 0x1E},
147 {0x74, 0x04},
148 {0x75, 0x01},
149 {0x76, 0x00},
150 {0x6B, 0xC0},
151 {0x67, 0x03},
152 {0x3C, 0x58},
153 {0x30, 0x4C},
154 {0x2E, 0X9F},
155 {0x12, 0XC0},
156 {0x10, 0X0D},
157 {0x05, 0X00},
158 {0x06, 0X02},
159 {0x60, 0x01},
160 SensorEnd
161 };
162
163 static struct rk_sensor_reg sensor_preview_data_yprpb_p[] = {
164 {0x05, 0x01},
165 {0x06, 0x06},
166 {0xc3, 0x56},
167 {0xc4, 0xb4},
168 {0x1d, 0x47},
169 {0x3a, 0x11},
170 {0x3b, 0x81},
171 {0x3c, 0x3b},
172 {0x6b, 0x83},
173 {0xc9, 0x00},
174 {0x73, 0x10},
175 {0x74, 0xa3},
176 {0x75, 0xe8},
177 {0x76, 0xfa},
178 {0x7b, 0x1c},
179 {0x85, 0x19},
180 {0x86, 0x0b},
181 {0xbf, 0x06},
182 {0xc0, 0x40},
183 {0xc1, 0xf0},
184 {0xc2, 0x80},
185 {0xc5, 0x01},
186 {0xc9, 0x08},
187 {0x0e, 0x80},
188 {0x52, 0x46},
189 {0x54, 0x80},
190 {0x57, 0x01},
191 {0xf6, 0x3b},
192 {0x0e, 0x00},
193 {0x67, 0x2f},
194 {0x03, 0x4C}, //disable out put
195 SensorEnd
196 };
197
adv7181_std_to_v4l2(u8 status1)198 static v4l2_std_id adv7181_std_to_v4l2(u8 status1)
199 {
200 /* in case V4L2_IN_ST_NO_SIGNAL */
201 if (!(status1 & ADV7181_STATUS1_IN_LOCK))
202 return V4L2_STD_UNKNOWN;
203
204 switch (status1 & ADV7181_STATUS1_AUTOD_MASK) {
205 case ADV7181_STATUS1_AUTOD_PAL_M:
206 case ADV7181_STATUS1_AUTOD_NTSM_M_J:
207 return V4L2_STD_NTSC;
208 case ADV7181_STATUS1_AUTOD_NTSC_4_43:
209 return V4L2_STD_NTSC_443;
210 case ADV7181_STATUS1_AUTOD_PAL_60:
211 return V4L2_STD_PAL_60;
212 case ADV7181_STATUS1_AUTOD_PAL_B_G:
213 return V4L2_STD_PAL;
214 case ADV7181_STATUS1_AUTOD_SECAM:
215 return V4L2_STD_SECAM;
216 case ADV7181_STATUS1_AUTOD_PAL_COMB:
217 return V4L2_STD_PAL_Nc | V4L2_STD_PAL_N;
218 case ADV7181_STATUS1_AUTOD_SECAM_525:
219 return V4L2_STD_SECAM;
220 default:
221 return V4L2_STD_UNKNOWN;
222 }
223 }
224
adv7181_status_to_v4l2(u8 status1)225 static u32 adv7181_status_to_v4l2(u8 status1)
226 {
227 if (!(status1 & ADV7181_STATUS1_IN_LOCK))
228 return V4L2_IN_ST_NO_SIGNAL;
229
230 return 0;
231 }
232
adv7181_vehicle_status(struct vehicle_ad_dev * ad,u32 * status,v4l2_std_id * std)233 static int adv7181_vehicle_status(struct vehicle_ad_dev *ad,
234 u32 *status,
235 v4l2_std_id *std)
236 {
237 unsigned char status1 = 0;
238
239 status1 = vehicle_generic_sensor_read(ad, ADV7181_STATUS1_REG);
240 if (status1)
241 return status1;
242
243 if (status)
244 *status = adv7181_status_to_v4l2(status1);
245
246 if (std)
247 *std = adv7181_std_to_v4l2(status1);
248
249 return 0;
250 }
251
adv7181_reinit_parameter(struct vehicle_ad_dev * ad,v4l2_std_id std)252 static void adv7181_reinit_parameter(struct vehicle_ad_dev *ad, v4l2_std_id std)
253 {
254 int i;
255
256 if (ad7181_g_addev->ad_chl == 0) {
257 ad->cfg.width = 1024;
258 ad->cfg.height = 500;
259 ad->cfg.start_x = 56;
260 ad->cfg.start_y = 0;
261 ad->cfg.input_format = CIF_INPUT_FORMAT_YUV;
262 ad->cfg.output_format = FORCE_CIF_OUTPUT_FORMAT;
263 ad->cfg.field_order = 0;
264 ad->cfg.yuv_order = 1;
265 ad->cfg.href = 0;
266 ad->cfg.vsync = 0;
267 ad->cfg.frame_rate = 60;
268 ad->cfg.type = V4L2_MBUS_PARALLEL;
269 ad->cfg.mbus_flags = V4L2_MBUS_HSYNC_ACTIVE_LOW |
270 V4L2_MBUS_VSYNC_ACTIVE_LOW |
271 V4L2_MBUS_PCLK_SAMPLE_RISING;
272 } else if (std == V4L2_STD_PAL) {
273 ad->cfg.width = FORCE_PAL_WIDTH;
274 ad->cfg.height = FORCE_PAL_HEIGHT;
275 ad->cfg.start_x = 0;
276 ad->cfg.start_y = 0;
277 ad->cfg.input_format = CIF_INPUT_FORMAT_PAL;
278 ad->cfg.output_format = FORCE_CIF_OUTPUT_FORMAT;
279 ad->cfg.field_order = 0;
280 ad->cfg.yuv_order = 0;
281 ad->cfg.href = 0;
282 ad->cfg.vsync = 0;
283 ad->cfg.frame_rate = 25;
284 ad->cfg.type = V4L2_MBUS_PARALLEL;
285 ad->cfg.mbus_flags = V4L2_MBUS_HSYNC_ACTIVE_LOW |
286 V4L2_MBUS_VSYNC_ACTIVE_LOW |
287 V4L2_MBUS_PCLK_SAMPLE_RISING;
288 } else {
289 ad->cfg.width = FORCE_NTSC_WIDTH;
290 ad->cfg.height = FORCE_NTSC_HEIGHT;
291 ad->cfg.start_x = 0;
292 ad->cfg.start_y = 0;
293 ad->cfg.input_format = CIF_INPUT_FORMAT_NTSC;
294 ad->cfg.output_format = FORCE_CIF_OUTPUT_FORMAT;
295 ad->cfg.field_order = 0;
296 ad->cfg.yuv_order = 2;
297 ad->cfg.href = 0;
298 ad->cfg.vsync = 0;
299 ad->cfg.frame_rate = 30;
300 ad->cfg.type = V4L2_MBUS_PARALLEL;
301 ad->cfg.mbus_flags = V4L2_MBUS_HSYNC_ACTIVE_LOW |
302 V4L2_MBUS_VSYNC_ACTIVE_LOW |
303 V4L2_MBUS_PCLK_SAMPLE_RISING;
304 }
305
306 /* fix crop info from dts config */
307 for (i = 0; i < 4; i++) {
308 if ((ad->defrects[i].width == ad->cfg.width) &&
309 (ad->defrects[i].height == ad->cfg.height)) {
310 ad->cfg.start_x = ad->defrects[i].crop_x;
311 ad->cfg.start_y = ad->defrects[i].crop_y;
312 ad->cfg.width = ad->defrects[i].crop_width;
313 ad->cfg.height = ad->defrects[i].crop_height;
314 }
315 }
316
317 SENSOR_DG("size %dx%d, crop(%d,%d)\n",
318 ad->cfg.width, ad->cfg.height,
319 ad->cfg.start_x, ad->cfg.start_y);
320 }
321
adv7181_reg_init(struct vehicle_ad_dev * ad,unsigned char cvstd)322 static void adv7181_reg_init(struct vehicle_ad_dev *ad, unsigned char cvstd)
323 {
324 struct rk_sensor_reg *sensor;
325 int i = 0;
326 unsigned char val[2];
327
328 switch (ad->ad_chl) {
329 case 0:
330 ad->ad_chl = ADV7181_INPUT_CVBS_AIN1;
331 break;
332 case 1:
333 ad->ad_chl = ADV7181_INPUT_CVBS_AIN6;
334 break;
335 case 2:
336 ad->ad_chl = ADV7181_INPUT_CVBS_AIN8;
337 break;
338 case 3:
339 ad->ad_chl = ADV7181_INPUT_CVBS_AIN10;
340 break;
341 case 4:
342 ad->ad_chl = ADV7181_INPUT_YPRPB_AIN6_8_10;
343 break;
344 default:
345 ad->ad_chl = ADV7181_INPUT_CVBS_AIN1;
346 }
347 val[0] = ad->ad_chl;
348 vehicle_generic_sensor_write(ad, ADV7181_INPUT_CONTROL, val);
349
350 if (ad->ad_chl == ADV7181_INPUT_YPRPB_AIN6_8_10) {
351 SENSOR_DG("%s %d set sensor_preview_data_yprpb_p/p", __func__, __LINE__);
352 sensor = sensor_preview_data_yprpb_p;
353 } else {
354 SENSOR_DG("%s %d set n/p", __func__, __LINE__);
355 sensor = sensor_preview_data;
356 }
357 while ((sensor[i].reg != SEQCMD_END) && (sensor[i].reg != 0xFC000000)) {
358 if (sensor[i].reg == ADV7181_INPUT_CONTROL) {
359 SENSOR_DG("%s %d lkg test ad channel = %d\n",
360 __func__, __LINE__, ad->ad_chl);
361 } else {
362 val[0] = sensor[i].val;
363 vehicle_generic_sensor_write(ad, sensor[i].reg, val);
364 }
365 i++;
366 }
367
368 val[0] = ad->ad_chl;
369 vehicle_generic_sensor_write(ad, ADV7181_INPUT_CONTROL, val);
370 }
371
adv7181_ad_get_cfg(struct vehicle_cfg ** cfg)372 int adv7181_ad_get_cfg(struct vehicle_cfg **cfg)
373 {
374 u32 status;
375
376 if (!ad7181_g_addev)
377 return -1;
378
379 adv7181_vehicle_status(ad7181_g_addev, &status, NULL);
380
381 ad7181_g_addev->cfg.ad_ready = true;
382
383 *cfg = &ad7181_g_addev->cfg;
384
385 return 0;
386 }
387
adv7181_ad_check_cif_error(struct vehicle_ad_dev * ad,int last_line)388 void adv7181_ad_check_cif_error(struct vehicle_ad_dev *ad, int last_line)
389 {
390 SENSOR_DG("%s, last_line %d\n", __func__, last_line);
391 if (last_line < 1)
392 return;
393
394 ad->cif_error_last_line = last_line;
395 if (std_old == V4L2_STD_PAL) {
396 if (last_line == FORCE_NTSC_HEIGHT) {
397 if (ad->state_check_work.state_check_wq)
398 queue_delayed_work(
399 ad->state_check_work.state_check_wq,
400 &ad->state_check_work.work,
401 msecs_to_jiffies(0));
402 }
403 } else if (std_old == V4L2_STD_NTSC) {
404 if (last_line == FORCE_PAL_HEIGHT) {
405 if (ad->state_check_work.state_check_wq)
406 queue_delayed_work(
407 ad->state_check_work.state_check_wq,
408 &ad->state_check_work.work,
409 msecs_to_jiffies(0));
410 }
411 }
412 }
413
adv7181_check_id(struct vehicle_ad_dev * ad)414 int adv7181_check_id(struct vehicle_ad_dev *ad)
415 {
416 int ret = 0;
417 int val;
418
419 val = vehicle_generic_sensor_read(ad, 0x11);
420 SENSOR_DG("%s vehicle read 0x11 --> 0x%02x\n", ad->ad_name, val);
421 if (val != 0x20) {
422 SENSOR_DG("%s vehicle wrong camera ID, expected 0x20, detected 0x%02x\n",
423 ad->ad_name, val);
424 ret = -EINVAL;
425 }
426
427 return ret;
428 }
429
adv7181_check_std(struct vehicle_ad_dev * ad,v4l2_std_id * std)430 static int adv7181_check_std(struct vehicle_ad_dev *ad, v4l2_std_id *std)
431 {
432 u32 status = 0;
433
434 adv7181_vehicle_status(ad, &status, std);
435
436 if (status != 0) { /* No signal */
437 mdelay(30);
438 adv7181_vehicle_status(ad, &status, std);
439 SENSOR_DG("status 0x%x\n", status);
440 }
441
442 return 0;
443 }
adv7181_channel_set(struct vehicle_ad_dev * ad,int channel)444 void adv7181_channel_set(struct vehicle_ad_dev *ad, int channel)
445 {
446 static int channel_change = 11;
447 v4l2_std_id std = 0;
448
449 ad->ad_chl = channel;
450 adv7181_reg_init(ad, std);
451 adv7181_check_std(ad, &std);
452 adv7181_reinit_parameter(ad, std);
453 if (channel_change != ad->ad_chl) {
454 SENSOR_DG("%s %d channel changed now channel = %d old_channel = %d\n",
455 __func__, __LINE__, ad->ad_chl, channel);
456 channel_change = ad->ad_chl;
457 vehicle_ad_stat_change_notify();
458 }
459 }
460
adv7181_stream(struct vehicle_ad_dev * ad,int value)461 int adv7181_stream(struct vehicle_ad_dev *ad, int value)
462 {
463 char val;
464
465 if (value)
466 val = 0x0c; //on
467 else
468 val = 0x4c;
469
470 SENSOR_DG("stream write 0x%x to reg 0x03\n", val);
471 vehicle_generic_sensor_write(ad, 0x03, &val);
472 if (value)
473 val = 0x47; //on
474 else
475 val = 0x87;
476
477 SENSOR_DG("stream write 0x%x to reg 0x01d\n", val);
478 vehicle_generic_sensor_write(ad, 0x1d, &val);
479
480 return 0;
481 }
482
power_on(struct vehicle_ad_dev * ad)483 static void power_on(struct vehicle_ad_dev *ad)
484 {
485 /* gpio_direction_output(ad->power, ad->pwr_active); */
486
487 if (gpio_is_valid(ad->powerdown)) {
488 gpio_request(ad->powerdown, "ad_powerdown");
489 gpio_direction_output(ad->powerdown, !ad->pwdn_active);
490 /* gpio_set_value(ad->powerdown, !ad->pwdn_active); */
491 }
492
493 if (gpio_is_valid(ad->power)) {
494 gpio_request(ad->power, "ad_power");
495 gpio_direction_output(ad->power, ad->pwr_active);
496 /* gpio_set_value(ad->power, ad->pwr_active); */
497 }
498
499 if (gpio_is_valid(ad->reset)) {
500 gpio_request(ad->reset, "ad_reset");
501 gpio_direction_output(ad->reset, 0);
502 usleep_range(10000, 12000);
503 gpio_set_value(ad->reset, 1);
504 usleep_range(10000, 12000);
505 }
506 }
507
power_off(struct vehicle_ad_dev * ad)508 static void power_off(struct vehicle_ad_dev *ad)
509 {
510 if (gpio_is_valid(ad->powerdown))
511 gpio_free(ad->powerdown);
512
513 if (gpio_is_valid(ad->power))
514 gpio_free(ad->power);
515
516 if (gpio_is_valid(ad->reset))
517 gpio_free(ad->reset);
518 }
519
adv7181_check_state_work(struct work_struct * work)520 static void adv7181_check_state_work(struct work_struct *work)
521 {
522 struct vehicle_ad_dev *ad;
523 v4l2_std_id std;
524
525 ad = ad7181_g_addev;
526
527 if (ad->cif_error_last_line > 0)
528 ad->cif_error_last_line = 0;
529
530 adv7181_check_std(ad, &std);
531 SENSOR_DG("%s:new std(%llx), std_old(%llx)\n", __func__, std, std_old);
532 if (std != std_old) {
533 std_old = std;
534 adv7181_reinit_parameter(ad, std);
535 SENSOR_DG("%s:ad signal change notify\n", __func__);
536 vehicle_ad_stat_change_notify();
537 }
538
539 queue_delayed_work(ad->state_check_work.state_check_wq,
540 &ad->state_check_work.work, msecs_to_jiffies(3000));
541 }
542
adv7181_ad_deinit(void)543 int adv7181_ad_deinit(void)
544 {
545 struct vehicle_ad_dev *ad;
546
547 ad = ad7181_g_addev;
548
549 if (!ad)
550 return -ENODEV;
551
552 if (ad->state_check_work.state_check_wq) {
553 cancel_delayed_work_sync(&ad->state_check_work.work);
554 flush_delayed_work(&ad->state_check_work.work);
555 flush_workqueue(ad->state_check_work.state_check_wq);
556 destroy_workqueue(ad->state_check_work.state_check_wq);
557 }
558 if (ad->irq)
559 free_irq(ad->irq, ad);
560 power_off(ad);
561
562 return 0;
563 }
564
adv7181_ad_init(struct vehicle_ad_dev * ad)565 int adv7181_ad_init(struct vehicle_ad_dev *ad)
566 {
567 v4l2_std_id std = V4L2_STD_NTSC;
568
569 if (!ad)
570 return -1;
571
572 ad7181_g_addev = ad;
573
574 /* 1. i2c init */
575 while (ad->adapter == NULL) {
576 ad->adapter = i2c_get_adapter(ad->i2c_chl);
577 usleep_range(10000, 12000);
578 }
579
580 if (!i2c_check_functionality(ad->adapter, I2C_FUNC_I2C))
581 return -EIO;
582
583 /* 2. ad power on sequence */
584 power_on(ad);
585
586 /* fix mode */
587 adv7181_check_std(ad, &std);
588 std_old = std;
589 SENSOR_DG("std: %s\n", (std == V4L2_STD_NTSC) ? "ntsc" : "pal");
590 SENSOR_DG("std_old: %s\n", (std_old == V4L2_STD_NTSC) ? "ntsc" : "pal");
591
592 /* 3 .init default format params */
593 adv7181_reg_init(ad, std);
594 adv7181_reinit_parameter(ad, std);
595 vehicle_ad_stat_change_notify();
596
597 /* 5. create workqueue to detect signal change */
598 INIT_DELAYED_WORK(&ad->state_check_work.work, adv7181_check_state_work);
599 ad->state_check_work.state_check_wq =
600 create_singlethread_workqueue("vehicle-ad-adv7181");
601
602 queue_delayed_work(ad->state_check_work.state_check_wq,
603 &ad->state_check_work.work, msecs_to_jiffies(100));
604
605 return 0;
606 }
607
608
609