xref: /OK3568_Linux_fs/kernel/drivers/video/rockchip/vehicle/vehicle_ad_tp2825.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * vehicle sensor tp2825
4  *
5  * Copyright (C) 2020 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 "vehicle_cfg.h"
29 #include "vehicle_main.h"
30 #include "vehicle_ad.h"
31 #include "vehicle_ad_tp2825.h"
32 
33 enum {
34 	CVSTD_720P60 = 0,
35 	CVSTD_720P50,
36 	CVSTD_1080P30,
37 	CVSTD_1080P25,
38 	CVSTD_720P30,
39 	CVSTD_720P25,
40 	CVSTD_SD,
41 	CVSTD_NTSC,
42 	CVSTD_PAL
43 };
44 
45 enum {
46 	FORCE_PAL_WIDTH = 960,
47 	FORCE_PAL_HEIGHT = 576,
48 	FORCE_NTSC_WIDTH = 960,
49 	FORCE_NTSC_HEIGHT = 480,
50 	FORCE_CIF_OUTPUT_FORMAT = CIF_OUTPUT_FORMAT_420,
51 };
52 
53 enum {
54 	VIDEO_UNPLUG,
55 	VIDEO_IN,
56 	VIDEO_LOCKED,
57 	VIDEO_UNLOCK
58 };
59 #define FLAG_LOSS				(0x1 << 7)
60 #define FLAG_V_LOCKED			(0x1 << 6)
61 #define FLAG_H_LOCKED			(0x1 << 5)
62 #define FLAG_CARRIER_PLL_LOCKED	(0x1 << 4)
63 #define FLAG_VIDEO_DETECTED		(0x1 << 3)
64 #define FLAG_EQ_SD_DETECTED		(0x1 << 2)
65 #define FLAG_PROGRESSIVE		(0x1 << 1)
66 #define FLAG_NO_CARRIER			(0x1 << 0)
67 #define FLAG_LOCKED		(FLAG_V_LOCKED | FLAG_H_LOCKED)
68 
69 static struct vehicle_ad_dev *tp2825_g_addev;
70 static int cvstd_mode = CVSTD_720P50;
71 static int cvstd_old = CVSTD_720P50;
72 static int cvstd_sd = CVSTD_NTSC;
73 static int cvstd_state = VIDEO_UNPLUG;
74 static int cvstd_old_state = VIDEO_UNPLUG;
75 
76 #define SENSOR_REGISTER_LEN	1	/* sensor register address bytes*/
77 #define SENSOR_VALUE_LEN	1	/* sensor register value bytes*/
78 
79 struct rk_sensor_reg {
80 	unsigned int reg;
81 	unsigned int val;
82 };
83 
84 #define SENSOR_CHANNEL_REG		0x41
85 
86 #define SEQCMD_END  0xFF000000
87 #define SensorEnd   {SEQCMD_END, 0x00}
88 
89 #define SENSOR_DG VEHICLE_DG
90 
91 /* Preview resolution setting*/
92 static struct rk_sensor_reg sensor_preview_data_ntsc[] = {
93 	{0x02, 0xCF},
94 	{0x06, 0x32},
95 	{0x07, 0xC0},
96 	{0x08, 0x00},
97 	{0x09, 0x24},
98 	{0x0A, 0x48},
99 	{0x0B, 0xC0},
100 	{0x0C, 0x53},
101 	{0x0D, 0x10},
102 	{0x0E, 0x00},
103 	{0x0F, 0x00},
104 	{0x10, 0x5e},
105 	{0x11, 0x40},
106 	{0x12, 0x44},
107 	{0x13, 0x00},
108 	{0x14, 0x00},
109 	{0x15, 0x13},
110 	{0x16, 0x4E},
111 	{0x17, 0xBC},
112 	{0x18, 0x15},
113 	{0x19, 0xF0},
114 	{0x1A, 0x07},
115 	{0x1B, 0x00},
116 	{0x1C, 0x09},
117 	{0x1D, 0x38},
118 	{0x1E, 0x80},
119 	{0x1F, 0x80},
120 	{0x20, 0xA0},
121 	{0x21, 0x86},
122 	{0x22, 0x38},
123 	{0x23, 0x3C},
124 	{0x24, 0x56},
125 	{0x25, 0xFF},
126 	{0x26, 0x12},
127 	{0x27, 0x2D},
128 	{0x28, 0x00},
129 	{0x29, 0x48},
130 	{0x2A, 0x30},
131 	{0x2B, 0x70},
132 	{0x2C, 0x1A},
133 	{0x2D, 0x68},
134 	{0x2E, 0x5E},
135 	{0x2F, 0x00},
136 	{0x30, 0x62},
137 	{0x31, 0xBB},
138 	{0x32, 0x96},
139 	{0x33, 0xC0},
140 	{0x34, 0x00},
141 	{0x35, 0x65},
142 	{0x36, 0xDC},
143 	{0x37, 0x00},
144 	{0x38, 0x40},
145 	{0x39, 0x84},
146 	{0x3A, 0x00},
147 	{0x3B, 0x03},
148 	{0x3C, 0x00},
149 	{0x3D, 0x60},
150 	{0x3E, 0x00},
151 	{0x3F, 0x00},
152 	{0x40, 0x00},
153 	{0x41, 0x00},
154 	{0x42, 0x00},
155 	{0x43, 0x12},
156 	{0x44, 0x07},
157 	{0x45, 0x49},
158 	{0x46, 0x00},
159 	{0x47, 0x00},
160 	{0x48, 0x00},
161 	{0x49, 0x00},
162 	{0x4A, 0x00},
163 	{0x4B, 0x00},
164 	{0x4C, 0x03},
165 	{0x4D, 0x00},
166 	{0x4E, 0x37},
167 	{0x4F, 0x01},
168 	{0xB5, 0x01},
169 	{0xB8, 0x00},
170 	{0xBA, 0x00},
171 	{0xF3, 0x00},
172 	{0xF4, 0x00},
173 	{0xF5, 0x00},
174 	{0xF6, 0x00},
175 	{0xF7, 0x00},
176 	{0xF8, 0x00},
177 	{0xF9, 0x00},
178 	{0xFA, 0x00},
179 	{0xFB, 0x00},
180 	{0xFC, 0xC0},
181 	{0xFD, 0x00},
182 	SensorEnd
183 };
184 
185 static struct rk_sensor_reg sensor_preview_data_pal[] = {
186 	{0x02, 0xCE},
187 	{0x06, 0x32},
188 	{0x07, 0xC0},
189 	{0x08, 0x00},
190 	{0x09, 0x24},
191 	{0x0A, 0x48},
192 	{0x0B, 0xC0},
193 	{0x0C, 0x53},
194 	{0x0D, 0x11},
195 	{0x0E, 0x00},
196 	{0x0F, 0x00},
197 	{0x10, 0x70},
198 	{0x11, 0x4D},
199 	{0x12, 0x40},
200 	{0x13, 0x00},
201 	{0x14, 0x00},
202 	{0x15, 0x13},
203 	{0x16, 0x67},
204 	{0x17, 0xBC},
205 	{0x18, 0x16},
206 	{0x19, 0x20},
207 	{0x1A, 0x17},
208 	{0x1B, 0x00},
209 	{0x1C, 0x09},
210 	{0x1D, 0x48},
211 	{0x1E, 0x80},
212 	{0x1F, 0x80},
213 	{0x20, 0xB0},
214 	{0x21, 0x86},
215 	{0x22, 0x38},
216 	{0x23, 0x3C},
217 	{0x24, 0x56},
218 	{0x25, 0xFF},
219 	{0x26, 0x02},
220 	{0x27, 0x2D},
221 	{0x28, 0x00},
222 	{0x29, 0x48},
223 	{0x2A, 0x30},
224 	{0x2B, 0x70},
225 	{0x2C, 0x1A},
226 	{0x2D, 0x60},
227 	{0x2E, 0x5E},
228 	{0x2F, 0x00},
229 	{0x30, 0x7A},
230 	{0x31, 0x4A},
231 	{0x32, 0x4D},
232 	{0x33, 0xF0},
233 	{0x34, 0x00},
234 	{0x35, 0x65},
235 	{0x36, 0xDC},
236 	{0x37, 0x00},
237 	{0x38, 0x40},
238 	{0x39, 0x84},
239 	{0x3A, 0x00},
240 	{0x3B, 0x03},
241 	{0x3C, 0x00},
242 	{0x3D, 0x60},
243 	{0x3E, 0x00},
244 	{0x3F, 0x00},
245 	{0x40, 0x00},
246 	{0x41, 0x00},
247 	{0x42, 0x00},
248 	{0x43, 0x12},
249 	{0x44, 0x07},
250 	{0x45, 0x49},
251 	{0x46, 0x00},
252 	{0x47, 0x00},
253 	{0x48, 0x00},
254 	{0x49, 0x00},
255 	{0x4A, 0x00},
256 	{0x4B, 0x00},
257 	{0x4C, 0x03},
258 	{0x4D, 0x00},
259 	{0x4E, 0x37},
260 	{0x4F, 0x00},
261 	{0xB5, 0x01},
262 	{0xB8, 0x00},
263 	{0xBA, 0x00},
264 	{0xF3, 0x00},
265 	{0xF4, 0x00},
266 	{0xF5, 0x00},
267 	{0xF6, 0x00},
268 	{0xF7, 0x00},
269 	{0xF8, 0x00},
270 	{0xF9, 0x00},
271 	{0xFA, 0x00},
272 	{0xFB, 0x00},
273 	{0xFC, 0xC0},
274 	{0xFD, 0x00},
275 	SensorEnd
276 };
277 
278 static struct rk_sensor_reg sensor_preview_data_720p_50hz[] = {
279 	{0x02, 0xCA},
280 	{0x06, 0x32},
281 	{0x07, 0xC0},
282 	{0x08, 0x00},
283 	{0x09, 0x24},
284 	{0x0A, 0x48},
285 	{0x0B, 0xC0},
286 	{0x0C, 0x43},
287 	{0x0D, 0x10},
288 	{0x0E, 0x00},
289 	{0x0F, 0x00},
290 	{0x10, 0xf0},
291 	{0x11, 0x50},
292 	{0x12, 0x60},
293 	{0x13, 0x00},
294 	{0x14, 0x08},
295 	{0x15, 0x13},
296 	{0x16, 0x16},
297 	{0x17, 0x00},
298 	{0x18, 0x18},
299 	{0x19, 0xD0},
300 	{0x1A, 0x25},
301 	{0x1B, 0x00},
302 	{0x1C, 0x07},
303 	{0x1D, 0xBC},
304 	{0x1E, 0x80},
305 	{0x1F, 0x80},
306 	{0x20, 0x60},
307 	{0x21, 0x86},
308 	{0x22, 0x38},
309 	{0x23, 0x3C},
310 	{0x24, 0x56},
311 	{0x25, 0xFF},
312 	{0x26, 0x02},
313 	{0x27, 0x2D},
314 	{0x28, 0x00},
315 	{0x29, 0x48},
316 	{0x2A, 0x30},
317 	{0x2B, 0x4A},
318 	{0x2C, 0x1A},
319 	{0x2D, 0x30},
320 	{0x2E, 0x70},
321 	{0x2F, 0x00},
322 	{0x30, 0x48},
323 	{0x31, 0xBB},
324 	{0x32, 0x2E},
325 	{0x33, 0x90},
326 	{0x34, 0x00},
327 	{0x35, 0x05},
328 	{0x36, 0xDC},
329 	{0x37, 0x00},
330 	{0x38, 0x40},
331 	{0x39, 0x8C},
332 	{0x3A, 0x00},
333 	{0x3B, 0x03},
334 	{0x3C, 0x00},
335 	{0x3D, 0x60},
336 	{0x3E, 0x00},
337 	{0x3F, 0x00},
338 	{0x40, 0x00},
339 	{0x41, 0x00},
340 	{0x42, 0x00},
341 	{0x43, 0x12},
342 	{0x44, 0x07},
343 	{0x45, 0x49},
344 	{0x46, 0x00},
345 	{0x47, 0x00},
346 	{0x48, 0x00},
347 	{0x49, 0x00},
348 	{0x4A, 0x00},
349 	{0x4B, 0x00},
350 	{0x4C, 0x03},
351 	{0x4D, 0x00},
352 	{0x4E, 0x03},
353 	{0x4F, 0x01},
354 	{0xB5, 0x01},
355 	{0xB8, 0x00},
356 	{0xBA, 0x00},
357 	{0xF3, 0x00},
358 	{0xF4, 0x00},
359 	{0xF5, 0x00},
360 	{0xF6, 0x00},
361 	{0xF7, 0x00},
362 	{0xF8, 0x00},
363 	{0xF9, 0x00},
364 	{0xFA, 0x00},
365 	{0xFB, 0x00},
366 	{0xFC, 0xC0},
367 	{0xFD, 0x00},
368 	SensorEnd
369 };
370 
371 static struct rk_sensor_reg sensor_preview_data_720p_30hz[] = {
372 	{0x02, 0xDA},
373 	{0x06, 0x32},
374 	{0x07, 0xC0},
375 	{0x08, 0x00},
376 	{0x09, 0x24},
377 	{0x0A, 0x48},
378 	{0x0B, 0xC0},
379 	{0x0C, 0x53},
380 	{0x0D, 0x10},
381 	{0x0E, 0x00},
382 	{0x0F, 0x00},
383 	{0x10, 0xf0},
384 	{0x11, 0x50},
385 	{0x12, 0x60},
386 	{0x13, 0x00},
387 	{0x14, 0x08},
388 	{0x15, 0x13},
389 	{0x16, 0x16},
390 	{0x17, 0x00},
391 	{0x18, 0x19},
392 	{0x19, 0xD0},
393 	{0x1A, 0x25},
394 	{0x1B, 0x00},
395 	{0x1C, 0x06},
396 	{0x1D, 0x72},
397 	{0x1E, 0x80},
398 	{0x1F, 0x80},
399 	{0x20, 0x60},
400 	{0x21, 0x86},
401 	{0x22, 0x38},
402 	{0x23, 0x3C},
403 	{0x24, 0x56},
404 	{0x25, 0xFF},
405 	{0x26, 0x02},
406 	{0x27, 0x2D},
407 	{0x28, 0x00},
408 	{0x29, 0x48},
409 	{0x2A, 0x30},
410 	{0x2B, 0x4A},
411 	{0x2C, 0x1A},
412 	{0x2D, 0x30},
413 	{0x2E, 0x70},
414 	{0x2F, 0x00},
415 	{0x30, 0x48},
416 	{0x31, 0xBB},
417 	{0x32, 0x2E},
418 	{0x33, 0x90},
419 	{0x34, 0x00},
420 	{0x35, 0x25},
421 	{0x36, 0xDC},
422 	{0x37, 0x00},
423 	{0x38, 0x40},
424 	{0x39, 0x88},
425 	{0x3A, 0x00},
426 	{0x3B, 0x03},
427 	{0x3C, 0x00},
428 	{0x3D, 0x60},
429 	{0x3E, 0x00},
430 	{0x3F, 0x00},
431 	{0x40, 0x03},
432 	{0x41, 0x00},
433 	{0x42, 0x00},
434 	{0x43, 0x12},
435 	{0x44, 0x07},
436 	{0x45, 0x49},
437 	{0x46, 0x00},
438 	{0x47, 0x00},
439 	{0x48, 0x00},
440 	{0x49, 0x00},
441 	{0x4A, 0x00},
442 	{0x4B, 0x00},
443 	{0x4C, 0x03},
444 	{0x4D, 0x00},
445 	{0x4E, 0x17},
446 	{0x4F, 0x01},
447 	{0x85, 0x00},
448 	{0x88, 0x00},
449 	{0x8A, 0x00},
450 	{0xF3, 0x00},
451 	{0xF4, 0x00},
452 	{0xF5, 0x00},
453 	{0xF6, 0x00},
454 	{0xF7, 0x00},
455 	{0xF8, 0x00},
456 	{0xF9, 0x00},
457 	{0xFA, 0x00},
458 	{0xFB, 0x00},
459 	{0xFC, 0xC0},
460 	{0xFD, 0x00},
461 	SensorEnd
462 };
463 
464 static struct rk_sensor_reg sensor_preview_data_720p_25hz[] = {
465 	{0x02, 0xCA},
466 	{0x06, 0x32},
467 	{0x07, 0xC0},
468 	{0x08, 0x00},
469 	{0x09, 0x24},
470 	{0x0A, 0x48},
471 	{0x0B, 0xC0},
472 	{0x0C, 0x53},
473 	{0x0D, 0x10},
474 	{0x0E, 0x00},
475 	{0x0F, 0x00},
476 	{0x10, 0xf0},
477 	{0x11, 0x50},
478 	{0x12, 0x60},
479 	{0x13, 0x00},
480 	{0x14, 0x08},
481 	{0x15, 0x13},
482 	{0x16, 0x16},
483 	{0x17, 0x00},
484 	{0x18, 0x19},
485 	{0x19, 0xD0},
486 	{0x1A, 0x25},
487 	{0x1B, 0x00},
488 	{0x1C, 0x07},
489 	{0x1D, 0xBC},
490 	{0x1E, 0x80},
491 	{0x1F, 0x80},
492 	{0x20, 0x60},
493 	{0x21, 0x86},
494 	{0x22, 0x38},
495 	{0x23, 0x3C},
496 	{0x24, 0x56},
497 	{0x25, 0xFF},
498 	{0x26, 0x02},
499 	{0x27, 0x2D},
500 	{0x28, 0x00},
501 	{0x29, 0x48},
502 	{0x2A, 0x30},
503 	{0x2B, 0x70},
504 	{0x2C, 0x1A},
505 	{0x2D, 0x30},
506 	{0x2E, 0x70},
507 	{0x2F, 0x00},
508 	{0x30, 0x48},
509 	{0x31, 0xBB},
510 	{0x32, 0x2E},
511 	{0x33, 0x90},
512 	{0x34, 0x00},
513 	{0x35, 0x25},
514 	{0x36, 0xDC},
515 	{0x37, 0x00},
516 	{0x38, 0x40},
517 	{0x39, 0x88},
518 	{0x3A, 0x00},
519 	{0x3B, 0x03},
520 	{0x3C, 0x00},
521 	{0x3D, 0x60},
522 	{0x3E, 0x00},
523 	{0x3F, 0x00},
524 	{0x40, 0x00},
525 	{0x41, 0x00},
526 	{0x42, 0x00},
527 	{0x43, 0x12},
528 	{0x44, 0x07},
529 	{0x45, 0x49},
530 	{0x46, 0x00},
531 	{0x47, 0x00},
532 	{0x48, 0x00},
533 	{0x49, 0x00},
534 	{0x4A, 0x00},
535 	{0x4B, 0x00},
536 	{0x4C, 0x03},
537 	{0x4D, 0x00},
538 	{0x4E, 0x17},
539 	{0x4F, 0x01},
540 	{0xB5, 0x01},
541 	{0xB8, 0x00},
542 	{0xBA, 0x00},
543 	{0xF3, 0x00},
544 	{0xF4, 0x00},
545 	{0xF5, 0x00},
546 	{0xF6, 0x00},
547 	{0xF7, 0x00},
548 	{0xF8, 0x00},
549 	{0xF9, 0x00},
550 	{0xFA, 0x00},
551 	{0xFB, 0x00},
552 	{0xFC, 0xC0},
553 	{0xFD, 0x00},
554 	SensorEnd
555 };
556 
tp2825_reinit_parameter(struct vehicle_ad_dev * ad,unsigned char cvstd)557 static void tp2825_reinit_parameter(struct vehicle_ad_dev *ad, unsigned char cvstd)
558 {
559 	int i = 0, defrect_index = 0;
560 
561 	switch (cvstd) {
562 	case CVSTD_PAL:
563 		ad->cfg.width = FORCE_PAL_WIDTH;
564 		ad->cfg.height = FORCE_PAL_HEIGHT;
565 		ad->cfg.start_x = 0;
566 		ad->cfg.start_y = 0;
567 		ad->cfg.input_format = CIF_INPUT_FORMAT_PAL;
568 		ad->cfg.output_format = FORCE_CIF_OUTPUT_FORMAT;
569 		ad->cfg.field_order = 0;
570 		ad->cfg.yuv_order = 0;
571 		ad->cfg.href = 0;
572 		ad->cfg.vsync = 0;
573 		ad->cfg.frame_rate = 25;
574 		ad->cfg.type = V4L2_MBUS_PARALLEL;
575 		ad->cfg.mbus_flags = V4L2_MBUS_HSYNC_ACTIVE_LOW |
576 					V4L2_MBUS_VSYNC_ACTIVE_LOW |
577 					V4L2_MBUS_PCLK_SAMPLE_RISING;
578 		break;
579 	case CVSTD_NTSC:
580 		ad->cfg.width = FORCE_NTSC_WIDTH;
581 		ad->cfg.height = FORCE_NTSC_HEIGHT;
582 		ad->cfg.start_x = 0;
583 		ad->cfg.start_y = 0;
584 		ad->cfg.input_format = CIF_INPUT_FORMAT_NTSC;
585 		ad->cfg.output_format = FORCE_CIF_OUTPUT_FORMAT;
586 		ad->cfg.field_order = 0;
587 		ad->cfg.yuv_order = 0;
588 		ad->cfg.href = 0;
589 		ad->cfg.vsync = 0;
590 		ad->cfg.frame_rate = 30;
591 		ad->cfg.type = V4L2_MBUS_PARALLEL;
592 		ad->cfg.mbus_flags = V4L2_MBUS_HSYNC_ACTIVE_LOW |
593 					V4L2_MBUS_VSYNC_ACTIVE_LOW |
594 					V4L2_MBUS_PCLK_SAMPLE_RISING;
595 		break;
596 	default:
597 		ad->cfg.width = 1280;
598 		ad->cfg.height = 720;
599 		ad->cfg.start_x = 8;
600 		ad->cfg.start_y = 20;
601 		ad->cfg.input_format = CIF_INPUT_FORMAT_YUV;
602 		ad->cfg.output_format = FORCE_CIF_OUTPUT_FORMAT;
603 		ad->cfg.field_order = 0;
604 		ad->cfg.yuv_order = 0;/*00 - UYVY*/
605 		ad->cfg.href = 0;
606 		ad->cfg.vsync = 1;
607 		ad->cfg.frame_rate = 50;
608 		ad->cfg.type = V4L2_MBUS_PARALLEL;
609 		ad->cfg.mbus_flags = V4L2_MBUS_HSYNC_ACTIVE_LOW |
610 					V4L2_MBUS_VSYNC_ACTIVE_HIGH |
611 					V4L2_MBUS_PCLK_SAMPLE_RISING;
612 		break;
613 	}
614 
615 	/* fix crop info from dts config */
616 	for (i = 0; i < 4; i++) {
617 		if ((ad->defrects[i].width == ad->cfg.width) &&
618 		    (ad->defrects[i].height == ad->cfg.height)) {
619 			ad->cfg.start_x = ad->defrects[i].crop_x;
620 			ad->cfg.start_y = ad->defrects[i].crop_y;
621 			ad->cfg.width = ad->defrects[i].crop_width;
622 			ad->cfg.height = ad->defrects[i].crop_height;
623 			defrect_index = i;
624 		}
625 	}
626 
627 #ifdef CVBS_DOUBLE_FPS_MODE
628 	switch (cvstd) {
629 	case CVSTD_PAL:
630 		if (!strstr(ad->defrects[defrect_index].interface, "pal")) {
631 			ad->cfg.height /= 2;
632 			ad->cfg.input_format =
633 				CIF_INPUT_FORMAT_PAL_SW_COMPOSITE;
634 			ad->cfg.href = 0;
635 			ad->cfg.vsync = 1;
636 			ad->cfg.frame_rate = 50;
637 		}
638 	break;
639 	case CVSTD_NTSC:
640 		if (!strstr(ad->defrects[defrect_index].interface, "ntsc")) {
641 			ad->cfg.height /= 2;
642 			ad->cfg.input_format =
643 				CIF_INPUT_FORMAT_NTSC_SW_COMPOSITE;
644 			ad->cfg.href = 0;
645 			ad->cfg.vsync = 1;
646 			ad->cfg.frame_rate = 60;
647 		}
648 	break;
649 	}
650 #endif
651 	SENSOR_DG("%s,crop(%d,%d)", __func__, ad->cfg.start_x, ad->cfg.start_y);
652 }
653 
tp2825_reg_init(struct vehicle_ad_dev * ad,unsigned char cvstd)654 static void tp2825_reg_init(struct vehicle_ad_dev *ad, unsigned char cvstd)
655 {
656 	struct rk_sensor_reg *sensor;
657 	int i;
658 	unsigned char val[2];
659 
660 	switch (cvstd) {
661 	case CVSTD_720P50:
662 		sensor = sensor_preview_data_720p_50hz;
663 		break;
664 	case CVSTD_720P30:
665 		sensor = sensor_preview_data_720p_30hz;
666 		break;
667 	case CVSTD_720P25:
668 		sensor = sensor_preview_data_720p_25hz;
669 		break;
670 	case CVSTD_PAL:
671 		sensor = sensor_preview_data_pal;
672 		break;
673 	case CVSTD_NTSC:
674 		sensor = sensor_preview_data_ntsc;
675 		break;
676 	default:
677 		sensor = sensor_preview_data_720p_50hz;
678 		break;
679 	}
680 	i = 0;
681 	while ((sensor[i].reg != SEQCMD_END) && (sensor[i].reg != 0xFC000000)) {
682 		if (sensor[i].reg == SENSOR_CHANNEL_REG)
683 			sensor[i].val = ad->ad_chl;
684 
685 		val[0] = sensor[i].val;
686 		vehicle_generic_sensor_write(ad, sensor[i].reg, val);
687 		i++;
688 	}
689 }
690 
tp2825_channel_set(struct vehicle_ad_dev * ad,int channel)691 void tp2825_channel_set(struct vehicle_ad_dev *ad, int channel)
692 {
693 	unsigned int reg = 0x41;
694 	unsigned char val[0];
695 
696 	val[0] = channel;
697 	ad->ad_chl = channel;
698 
699 	vehicle_generic_sensor_write(ad, reg, val);
700 }
701 
tp2825_ad_get_cfg(struct vehicle_cfg ** cfg)702 int tp2825_ad_get_cfg(struct vehicle_cfg **cfg)
703 {
704 	if (!tp2825_g_addev)
705 		return -1;
706 
707 	switch (cvstd_state) {
708 	case VIDEO_UNPLUG:
709 		tp2825_g_addev->cfg.ad_ready = false;
710 		break;
711 	case VIDEO_LOCKED:
712 		tp2825_g_addev->cfg.ad_ready = true;
713 		break;
714 	case VIDEO_IN:
715 		tp2825_g_addev->cfg.ad_ready = false;
716 		break;
717 	}
718 
719 	*cfg = &tp2825_g_addev->cfg;
720 
721 	return 0;
722 }
723 
tp2825_ad_check_cif_error(struct vehicle_ad_dev * ad,int last_line)724 void tp2825_ad_check_cif_error(struct vehicle_ad_dev *ad, int last_line)
725 {
726 	SENSOR_DG("%s, last_line %d\n", __func__, last_line);
727 	if (last_line < 1)
728 		return;
729 
730 	ad->cif_error_last_line = last_line;
731 	if (cvstd_mode == CVSTD_PAL) {
732 		if (last_line == FORCE_NTSC_HEIGHT) {
733 			if (ad->state_check_work.state_check_wq)
734 				queue_delayed_work(
735 					ad->state_check_work.state_check_wq,
736 					&ad->state_check_work.work,
737 					msecs_to_jiffies(0));
738 		}
739 	} else if (cvstd_mode == CVSTD_NTSC) {
740 		if (last_line == FORCE_PAL_HEIGHT) {
741 			if (ad->state_check_work.state_check_wq)
742 				queue_delayed_work(
743 					ad->state_check_work.state_check_wq,
744 					&ad->state_check_work.work,
745 					msecs_to_jiffies(0));
746 		}
747 	}
748 }
749 
tp2825_check_id(struct vehicle_ad_dev * ad)750 int tp2825_check_id(struct vehicle_ad_dev *ad)
751 {
752 	int ret = 0;
753 	int pidh, pidl;
754 
755 	pidh = vehicle_generic_sensor_read(ad, 0xfe);
756 	pidl = vehicle_generic_sensor_read(ad, 0xff);
757 	if (pidh != 0x28 || pidl != 0x25) {
758 		SENSOR_DG("%s: expected 0x2825, detected 0x%02x 0x%02x\n",
759 		    ad->ad_name, pidh, pidl);
760 		ret = -EINVAL;
761 	}
762 
763 	return ret;
764 }
765 
tp2825_check_cvstd(struct vehicle_ad_dev * ad,bool activate_check)766 static int tp2825_check_cvstd(struct vehicle_ad_dev *ad, bool activate_check)
767 {
768 	unsigned char cvstd = 0;
769 	unsigned char status = 0;
770 	static bool is_first = true;
771 	static int state = VIDEO_UNPLUG;
772 	int check_count = 20;
773 	unsigned char v[2];
774 
775 check_continue:
776 	status = vehicle_generic_sensor_read(ad, 0x01);
777 
778 	if (status & FLAG_LOSS) {
779 		state = VIDEO_UNPLUG;
780 		v[0] = 0x01;
781 		vehicle_generic_sensor_write(ad, 0x26, v);
782 	} else if (FLAG_LOCKED == (status & FLAG_LOCKED)) {
783 		/* video locked */
784 		state = VIDEO_LOCKED;
785 		v[0] = 0x02;
786 		vehicle_generic_sensor_write(ad, 0x26, v);
787 	} else {
788 		/* video in but unlocked */
789 		state = VIDEO_IN;
790 		v[0] = 0x02;
791 		vehicle_generic_sensor_write(ad, 0x26, v);
792 	}
793 
794 	if (state == VIDEO_IN) {
795 		cvstd = vehicle_generic_sensor_read(ad, 0x03);
796 		SENSOR_DG("%s(%d): cvstd_old %d, read 0x03 return 0x%x",
797 			  __func__, __LINE__, cvstd_old, cvstd);
798 
799 		cvstd &= 0x07;
800 		if (cvstd == cvstd_old)
801 			goto check_end;
802 
803 		if (cvstd == CVSTD_720P30) {
804 			cvstd_mode = CVSTD_720P30;
805 			SENSOR_DG("%s(%d): 720P30\n", __func__, __LINE__);
806 		} else if (cvstd == CVSTD_720P25) {
807 			cvstd_mode = CVSTD_720P25;
808 			SENSOR_DG("%s(%d): 720P25\n", __func__, __LINE__);
809 		} else if (cvstd == CVSTD_720P60) {
810 			SENSOR_DG("%s(%d): 720P60", __func__, __LINE__);
811 		} else if (cvstd == CVSTD_720P50) {
812 			cvstd_mode = CVSTD_720P50;
813 			SENSOR_DG("%s(%d): 720P50\n", __func__, __LINE__);
814 		} else if (cvstd == CVSTD_1080P30) {
815 			SENSOR_DG("%s(%d): 1080P30", __func__, __LINE__);
816 		} else if (cvstd == CVSTD_1080P25) {
817 			SENSOR_DG("%s(%d): 1080P25", __func__, __LINE__);
818 		} else if (cvstd == CVSTD_SD) {
819 			msleep(80);
820 			status = vehicle_generic_sensor_read(ad, 0x01);
821 			SENSOR_DG("%s(%d): read 0x01 return 0x%x\n",
822 				  __func__, __LINE__, status);
823 
824 			/*
825 			 * 1: pal  0: ntsc
826 			 */
827 			if ((status >> 2) & 0x01)
828 				cvstd_sd = CVSTD_PAL;
829 			else
830 				cvstd_sd = CVSTD_NTSC;
831 
832 			SENSOR_DG("%s(%d): cvstd_sd is %s\n",
833 				  __func__, __LINE__,
834 				  (cvstd_sd == CVSTD_PAL) ? "PAL" : "NTSC");
835 			cvstd_mode = cvstd_sd;
836 		}
837 		tp2825_reinit_parameter(ad, cvstd_mode);
838 	} else if (state == VIDEO_LOCKED) {
839 		goto check_end;
840 	} else {
841 		SENSOR_DG("%s: check sensor statue failed!\n", __func__);
842 		goto check_end;
843 	}
844 
845 	tp2825_reg_init(ad, cvstd_mode);
846 check_end:
847 	if (check_count && is_first && (state != VIDEO_LOCKED)) {
848 		check_count--;
849 		if (cvstd == CVSTD_SD)
850 			mdelay(100);
851 		else
852 			mdelay(100);
853 		goto check_continue;
854 	}
855 	is_first = false;
856 	cvstd_state = state;
857 
858 	return 0;
859 }
tp2825_stream(struct vehicle_ad_dev * ad,int enable)860 int tp2825_stream(struct vehicle_ad_dev *ad, int enable)
861 {
862 	char val;
863 
864 	if (enable)
865 		val = 0x03; //stream on
866 	else
867 		val = 0x00; //stream off
868 	SENSOR_DG("stream write 0x%x to reg 0x4D\n", val);
869 	vehicle_generic_sensor_write(ad, 0x4D, &val);
870 
871 	return 0;
872 }
power_on(struct vehicle_ad_dev * ad)873 static void power_on(struct vehicle_ad_dev *ad)
874 {
875 	/* gpio_direction_output(ad->power, ad->pwr_active); */
876 
877 	if (gpio_is_valid(ad->powerdown)) {
878 		gpio_request(ad->powerdown, "ad_powerdown");
879 		gpio_direction_output(ad->powerdown, !ad->pwdn_active);
880 		/* gpio_set_value(ad->powerdown, !ad->pwdn_active); */
881 	}
882 
883 	if (gpio_is_valid(ad->power)) {
884 		gpio_request(ad->power, "ad_power");
885 		gpio_direction_output(ad->power, ad->pwr_active);
886 		/* gpio_set_value(ad->power, ad->pwr_active); */
887 	}
888 }
889 
power_off(struct vehicle_ad_dev * ad)890 static void power_off(struct vehicle_ad_dev *ad)
891 {
892 	if (gpio_is_valid(ad->power))
893 		gpio_free(ad->power);
894 	if (gpio_is_valid(ad->powerdown))
895 		gpio_free(ad->powerdown);
896 }
897 
tp2825_check_state_work(struct work_struct * work)898 static void tp2825_check_state_work(struct work_struct *work)
899 {
900 	struct vehicle_ad_dev *ad;
901 
902 	ad = tp2825_g_addev;
903 
904 	if (ad->cif_error_last_line > 0) {
905 		tp2825_check_cvstd(ad, true);
906 		ad->cif_error_last_line = 0;
907 	} else {
908 		tp2825_check_cvstd(ad, false);
909 	}
910 
911 	if (cvstd_old != cvstd_mode || cvstd_old_state != cvstd_state) {
912 		cvstd_old = cvstd_mode;
913 		cvstd_old_state = cvstd_state;
914 		SENSOR_DG("ad signal change notify\n");
915 		vehicle_ad_stat_change_notify();
916 	}
917 
918 	queue_delayed_work(ad->state_check_work.state_check_wq,
919 			   &ad->state_check_work.work, msecs_to_jiffies(100));
920 }
921 
tp2825_ad_deinit(void)922 int tp2825_ad_deinit(void)
923 {
924 	struct vehicle_ad_dev *ad;
925 
926 	ad = tp2825_g_addev;
927 
928 	if (!ad)
929 		return -1;
930 
931 	if (ad->state_check_work.state_check_wq) {
932 		cancel_delayed_work_sync(&ad->state_check_work.work);
933 		flush_delayed_work(&ad->state_check_work.work);
934 		flush_workqueue(ad->state_check_work.state_check_wq);
935 		destroy_workqueue(ad->state_check_work.state_check_wq);
936 	}
937 	if (ad->irq)
938 		free_irq(ad->irq, ad);
939 	power_off(ad);
940 
941 	return 0;
942 }
943 
get_ad_mode_from_fix_format(int fix_format)944 static int get_ad_mode_from_fix_format(int fix_format)
945 {
946 	int mode = -1;
947 
948 	switch (fix_format) {
949 	case AD_FIX_FORMAT_PAL:
950 		mode = CVSTD_PAL;
951 		break;
952 	case AD_FIX_FORMAT_NTSC:
953 		mode = CVSTD_NTSC;
954 		break;
955 	case AD_FIX_FORMAT_720P_50FPS:
956 		mode = CVSTD_720P50;
957 		break;
958 	case AD_FIX_FORMAT_720P_30FPS:
959 		mode = CVSTD_720P30;
960 		break;
961 	case AD_FIX_FORMAT_720P_25FPS:
962 		mode = CVSTD_720P25;
963 		break;
964 	default:
965 		mode = -1;
966 		break;
967 	}
968 
969 	return mode;
970 }
971 
tp2825_ad_init(struct vehicle_ad_dev * ad)972 int tp2825_ad_init(struct vehicle_ad_dev *ad)
973 {
974 	int val = 0;
975 	int i = 0;
976 	int mode;
977 
978 	tp2825_g_addev = ad;
979 
980 	/*  1. i2c init */
981 	while (ad->adapter == NULL) {
982 		ad->adapter = i2c_get_adapter(ad->i2c_chl);
983 		usleep_range(10000, 12000);
984 	}
985 	if (ad->adapter == NULL)
986 		return -ENODEV;
987 
988 	if (!i2c_check_functionality(ad->adapter, I2C_FUNC_I2C))
989 		return -EIO;
990 
991 	/*  2. ad power on sequence */
992 	power_on(ad);
993 
994 	while (++i < 5) {
995 		usleep_range(1000, 1200);
996 		val = vehicle_generic_sensor_read(ad, 0x12);
997 		if (val != 0xff)
998 			break;
999 		SENSOR_DG("tp2825_init i2c_reg_read fail\n");
1000 	}
1001 
1002 	/* fix mode */
1003 	mode = get_ad_mode_from_fix_format(ad->fix_format);
1004 	if (mode > 0) {
1005 		SENSOR_DG("fix format %d, fix cvxtd mode %d\n", ad->fix_format, mode);
1006 		tp2825_reg_init(ad, mode);
1007 		tp2825_reinit_parameter(ad, mode);
1008 		SENSOR_DG("%s after init\n", __func__);
1009 		/* wait for signal locked; */
1010 		i = 0;
1011 		while (++i < 10) {
1012 			msleep(100);
1013 			val = vehicle_generic_sensor_read(ad, 0x01);
1014 			if ((FLAG_LOCKED == (val & FLAG_LOCKED)))
1015 				break;
1016 		}
1017 		cvstd_state = VIDEO_LOCKED;
1018 		return 0;
1019 	}
1020 
1021 	/*  3 .init default format params */
1022 	tp2825_reg_init(ad, cvstd_mode);
1023 	tp2825_reinit_parameter(ad, cvstd_mode);
1024 	SENSOR_DG("%s after reinit init\n", __func__);
1025 
1026 	/*  5. create workqueue to detect signal change */
1027 	INIT_DELAYED_WORK(&ad->state_check_work.work, tp2825_check_state_work);
1028 	ad->state_check_work.state_check_wq =
1029 		create_singlethread_workqueue("vehicle-ad-tp2825");
1030 
1031 	/* tp2825_check_cvstd(ad, true); */
1032 
1033 	queue_delayed_work(ad->state_check_work.state_check_wq,
1034 			   &ad->state_check_work.work, msecs_to_jiffies(100));
1035 
1036 	return 0;
1037 }
1038 
1039 
1040