• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * A V4L2 driver for nvp6158c yuv cameras.
3  *
4  * Copyright (c) 2019 by Allwinnertech Co., Ltd.  http://www.allwinnertech.com
5  *
6  * Authors:  Zheng Zequn<zequnzheng@allwinnertech.com>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 as
10  * published by the Free Software Foundation.
11  */
12 #include <linux/kernel.h>
13 #include <linux/version.h>
14 #include <linux/module.h>
15 #include <linux/types.h>
16 #include <linux/errno.h>
17 #include <linux/fcntl.h>
18 #include <linux/mm.h>
19 #include <linux/proc_fs.h>
20 
21 #include <linux/fs.h>
22 #include <linux/slab.h>
23 #include <linux/init.h>
24 #include <asm/uaccess.h>
25 #include <asm/io.h>
26 #include <linux/interrupt.h>
27 #include <linux/ioport.h>
28 #include <linux/string.h>
29 #include <linux/list.h>
30 #include <asm/delay.h>
31 #include <linux/timer.h>
32 #include <linux/delay.h>
33 #include <linux/proc_fs.h>
34 #include <linux/poll.h>
35 #include <asm/bitops.h>
36 #include <asm/uaccess.h>
37 #include <asm/irq.h>
38 #include <linux/moduleparam.h>
39 #include <linux/ioport.h>
40 #include <linux/interrupt.h>
41 #include <linux/semaphore.h>
42 #include <linux/kthread.h>
43 
44 #include <linux/i2c.h>
45 #include <linux/i2c-dev.h>
46 
47 #include "../camera.h"
48 #include "../sensor_helper.h"
49 #include "video.h"
50 #include "coax_protocol.h"
51 #include "motion.h"
52 #include "common.h"
53 #include "audio.h"
54 #include "video_auto_detect.h"
55 #include "video_eq.h"
56 #include "nvp6158_drv.h"
57 
58 extern struct v4l2_subdev *gl_sd;
59 #define SENSOR_NAME "nvp6158"
60 
61 #define COLORBAR_EN
62 #define HW_REG(reg)  (*((volatile unsigned int *)(reg)))
63 
64 int chip_nvp6158_id[4];
65 int rev_nvp6158_id[4];
66 unsigned int nvp6158_cnt;
67 unsigned int nvp6158_iic_addr[4] = {0x60, 0x62, 0x64, 0x66};
68 
69 /*unsigned int nvp6158_mode = PAL;  //0:ntsc, 1: pal
70 module_param(nvp6158_mode, uint, S_IRUGO);
71 unsigned int kthread = 0;
72 module_param(kthread, uint, S_IRUGO);
73 static struct task_struct *nvp6158_kt = NULL;*/
74 struct semaphore nvp6158_lock;
75 unsigned char det_mode[16] = {NVP6158_DET_MODE_AUTO,};
76 extern unsigned char ch_mode_status[16];
77 extern unsigned char ch_vfmt_status[16];
78 unsigned int gCoaxFirmUpdateFlag[16] = {0,};
79 
gpio_i2c_write(u8 da,u8 reg,u8 val)80 u32 gpio_i2c_write(u8 da, u8 reg, u8 val)
81 {
82 	u8 ret = 0, cnt = 0;
83 
84 	ret = cci_write_a8_d8(gl_sd, reg, val);
85 	while ((ret != 0) && (cnt < 2)) {
86 		ret = cci_write_a8_d8(gl_sd, reg, val);
87 		cnt++;
88 	}
89 	if (cnt > 0)
90 		sensor_print("%s sensor read retry = %d\n", gl_sd->name, cnt);
91 
92 	return ret;
93 }
94 
gpio_i2c_read(u8 da,u8 reg)95  u32 gpio_i2c_read(u8 da, u8 reg)
96 {
97 	u8 ret = 0, cnt = 0;
98 	u8 val = 0;
99 
100 	ret = cci_read_a8_d8(gl_sd, reg, &val);
101 	while ((ret != 0) && (cnt < 2)) {
102 		ret = cci_read_a8_d8(gl_sd, reg, &val);
103 		cnt++;
104 	}
105 	if (cnt > 0)
106 		sensor_print("%s sensor read retry = %d\n", gl_sd->name, cnt);
107 
108 	return val;
109 }
110 
111 /*******************************************************************************
112 *	Description		: Get rev ID
113 *	Argurments		: dec(slave address)
114 *	Return value	: rev ID
115 *	Modify			:
116 *	warning			:
117 *******************************************************************************/
check_nvp6158_rev(unsigned int dec)118 int check_nvp6158_rev(unsigned int dec)
119 {
120 	int ret;
121 
122 	gpio_i2c_write(dec, 0xFF, 0x00);
123 	ret = gpio_i2c_read(dec, 0xf5);
124 	return ret;
125 }
126 
127 /*******************************************************************************
128 *	Description		: Get Device ID
129 *	Argurments		: dec(slave address)
130 *	Return value	: Device ID
131 *	Modify			:
132 *	warning			:
133 *******************************************************************************/
check_nvp6158_id(unsigned int dec)134 int check_nvp6158_id(unsigned int dec)
135 {
136 	int ret = 0;
137 
138 	gpio_i2c_write(dec, 0xFF, 0x00);
139 	ret = gpio_i2c_read(dec, 0xf4);
140 	return ret;
141 }
142 
143 #if 0
144 unsigned int g_vloss = 0xFFFF;
145 
146 long nvp6158_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
147 {
148 	unsigned int __user *argp = (unsigned int __user *)arg;
149 	int cpy2usr_ret;
150 	unsigned char i;
151 	/* unsigned char oCableDistance = 0; */
152 	video_equalizer_info_s s_eq_dist;
153 	nvp6158_opt_mode optmode;
154 	/* nvp6158_video_mode vmode; */
155 	nvp6158_chn_mode schnmode;
156 	nvp6158_video_adjust v_adj;
157 	NVP6158_INFORMATION_S vfmt;
158 	nvp6158_coax_str coax_val;
159 	nvp6158_input_videofmt_ch vfmt_ch;
160 	nvp6124_i2c_mode i2c;
161 	FIRMWARE_UP_FILE_INFO coax_fw_val;
162 	motion_mode motion_set;
163 	//int ret=0;
164 
165 	/* you must skip other command to improve speed of f/w update
166 	 * when you are updating cam's f/w up. we need to review and test */
167 	/* if ( acp_dvr_checkFWUpdateStatus( cmd ) == -1 ) */
168 	{
169 		/*sensor_dbg(">>>>> DRV[%s:%d] Now cam f/w update mode. so Skip other command.\n", __func__, __LINE__ ); */
170 		/*return 0; */
171 	}
172 	down(&nvp6158_lock);
173 	switch (cmd) {
174 	case IOC_VDEC_SET_I2C: /* nextchip demoboard test */
175 		if (copy_from_user(&i2c, argp, sizeof(nvp6124_i2c_mode))) {
176 			up(&nvp6158_lock);
177 			return -1;
178 		}
179 
180 		if (i2c.flag == 0) { /* read */
181 			gpio_i2c_write(i2c.slaveaddr, 0xFF, i2c.bank);
182 			i2c.data = gpio_i2c_read(i2c.slaveaddr, i2c.address);
183 		} else { /*write */
184 			gpio_i2c_write(i2c.slaveaddr, 0xFF, i2c.bank);
185 			gpio_i2c_write(i2c.slaveaddr, i2c.address, i2c.data);
186 		}
187 		if (copy_to_user(argp, &i2c, sizeof(nvp6124_i2c_mode)))
188 			sensor_dbg("IOC_VDEC_I2C error\n");
189 	break;
190 	case IOC_VDEC_GET_VIDEO_LOSS: /* Not use */
191 		/*g_vloss = nvp6158_getvideoloss(); */
192 		if (copy_to_user(argp, &g_vloss, sizeof(unsigned int)))
193 			sensor_dbg("IOC_VDEC_GET_VIDEO_LOSS error\n");
194 		break;
195 	case IOC_VDEC_GET_EQ_DIST:
196 		if  (copy_from_user(&s_eq_dist, argp, sizeof(video_equalizer_info_s))) {
197 			up(&nvp6158_lock);
198 			return -1;
199 		}
200 
201 		s_eq_dist.distance = nvp6158_get_eq_dist(&s_eq_dist);
202 		if (copy_to_user(argp, &s_eq_dist, sizeof(video_equalizer_info_s)))
203 			sensor_dbg("IOC_VDEC_GET_EQ_DIST error\n");
204 		break;
205 	case IOC_VDEC_SET_EQUALIZER:
206 		if (copy_from_user(&s_eq_dist, argp, sizeof(video_equalizer_info_s))) {
207 			up(&nvp6158_lock);
208 			return -1;
209 		}
210 		if (chip_nvp6158_id[0] == NVP6158C_R0_ID || chip_nvp6158_id[0] == NVP6158_R0_ID)
211 			nvp6158_set_equalizer(&s_eq_dist);
212 		else
213 			nvp6168_set_equalizer(&s_eq_dist);
214 		break;
215 	case IOC_VDEC_GET_DRIVERVER:
216 		if (copy_to_user(argp, &DRIVER_VER, sizeof(DRIVER_VER)))
217 			sensor_dbg("IOC_VDEC_GET_DRIVERVER error\n");
218 		break;
219 	case IOC_VDEC_ACP_WRITE:
220 		/*if (copy_from_user(&ispdata, argp, sizeof(nvp6158_acp_rw_data)))
221 			return -1;
222 		if (ispdata.opt == 0)
223 			acp_isp_write(ispdata.ch, ispdata.addr, ispdata.data);
224 		else
225 		{
226 			ispdata.data = acp_isp_read(ispdata.ch, ispdata.addr);
227 			if (copy_to_user(argp, &ispdata, sizeof(nvp6158_acp_rw_data)))
228 				sensor_dbg("IOC_VDEC_ACP_WRITE error\n");
229 		}*/
230 		break;
231 	case IOC_VDEC_ACP_WRITE_EXTENTION:
232 
233 		break;
234 	case IOC_VDEC_PTZ_ACP_READ:
235 		/*
236 		//if (copy_from_user(&vfmt, argp, sizeof(nvp6158_input_videofmt)))
237 		//	return -1;
238 		//for(i=0;i<(4*nvp6158_cnt);i++)
239 		//{
240 		//	if (1)
241 		//	{
242 				// read A-CP
243 				//if (((g_vloss>>i)&0x01) == 0x00)
244 				//	acp_read(&vfmt, i);
245 		//	}
246 		//}
247 		//if (copy_to_user(argp, &vfmt, sizeof(nvp6158_input_videofmt)))
248 		//	sensor_dbg("IOC_VDEC_PTZ_ACP_READ error\n");
249 		*/
250 		break;
251 	case IOC_VDEC_PTZ_ACP_READ_EACH_CH:
252 		if (copy_from_user(&vfmt_ch, argp, sizeof(nvp6158_input_videofmt_ch))) {
253 			up(&nvp6158_lock);
254 			return -1;
255 		}
256 		/* read A-CP */
257 		if (((g_vloss>>vfmt_ch.ch)&0x01) == 0x00) {
258 			/* acp_read(&vfmt_ch.vfmt, vfmt_ch.ch); */
259 		}
260 
261 		if (copy_to_user(argp, &vfmt_ch, sizeof(nvp6158_input_videofmt_ch)))
262 			sensor_dbg("IOC_VDEC_PTZ_ACP_READ_EACH_CH error\n");
263 		break;
264 	case IOC_VDEC_GET_INPUT_VIDEO_FMT:
265 		if (copy_from_user(&vfmt, argp, sizeof(NVP6158_INFORMATION_S))) {
266 			up(&nvp6158_lock);
267 			return -1;
268 		}
269 		if (chip_nvp6158_id[0] == NVP6158C_R0_ID || chip_nvp6158_id[0] == NVP6158_R0_ID)
270 			video_fmt_det(vfmt.ch, &vfmt);
271 		else
272 			nvp6168_video_fmt_det(vfmt.ch, &vfmt);
273 		if (copy_to_user(argp, &vfmt, sizeof(NVP6158_INFORMATION_S)))
274 			sensor_dbg("IOC_VDEC_GET_INPUT_VIDEO_FMT error\n");
275 		break;
276 	case IOC_VDEC_SET_CHDETMODE:
277 			if (copy_from_user(&det_mode, argp, sizeof(unsigned char)*16)) {
278 				up(&nvp6158_lock);
279 				return -1;
280 			}
281 
282 		for (i = 0; i < (nvp6158_cnt*4); i++) {
283 			sensor_dbg("IOC_VDEC_SET_CHNMODE det_mode[%d]==%d\n", i, det_mode[i]);
284 			if (chip_nvp6158_id[0] == NVP6158C_R0_ID || chip_id[0] == NVP6158_R0_ID)
285 				nvp6158_set_chnmode(i, NC_VIVO_CH_FORMATDEF_UNKNOWN);
286 			else
287 				nvp6168_set_chnmode(i, NC_VIVO_CH_FORMATDEF_UNKNOWN);
288 		}
289 		break;
290 	case IOC_VDEC_SET_CHNMODE:
291 		if (copy_from_user(&schnmode, argp, sizeof(nvp6158_chn_mode))) {
292 			up(&nvp6158_lock);
293 			return -1;
294 		}
295 		if (chip_nvp6158_id[0] == NVP6158C_R0_ID || chip_nvp6158_id[0] == NVP6158_R0_ID) {
296 			if (0 == nvp6158_set_chnmode(schnmode.ch, schnmode.chmode))
297 				sensor_dbg("IOC_VDEC_SET_CHNMODE OK\n");
298 		} else {
299 			if (0 == nvp6168_set_chnmode(schnmode.ch, schnmode.chmode))
300 				sensor_dbg("IOC_VDEC_SET_CHNMODE OK\n");
301 		}
302 		break;
303 	case IOC_VDEC_SET_OUTPORTMODE:
304 		if (copy_from_user(&optmode, argp, sizeof(nvp6158_opt_mode))) {
305 			up(&nvp6158_lock);
306 			return -1;
307 		}
308 			nvp6158_set_portmode(optmode.chipsel, optmode.portsel, optmode.portmode, optmode.chid);
309 		break;
310 	case IOC_VDEC_SET_BRIGHTNESS:
311 		if (copy_from_user(&v_adj, argp, sizeof(nvp6158_video_adjust))) {
312 			up(&nvp6158_lock);
313 			return -1;
314 		}
315 		/* nvp6158_video_set_brightness(v_adj.ch, v_adj.value, ch_vfmt_status[v_adj.ch]); */
316 		break;
317 	case IOC_VDEC_SET_CONTRAST:
318 		if (copy_from_user(&v_adj, argp, sizeof(nvp6158_video_adjust))) {
319 			up(&nvp6158_lock);
320 			return -1;
321 		}
322 		/* nvp6158_video_set_contrast(v_adj.ch, v_adj.value, ch_vfmt_status[v_adj.ch]); */
323 		break;
324 	case IOC_VDEC_SET_HUE:
325 		if (copy_from_user(&v_adj, argp, sizeof(nvp6158_video_adjust))) {
326 			up(&nvp6158_lock);
327 			return -1;
328 		}
329 		/* nvp6158_video_set_hue(v_adj.ch, v_adj.value, ch_vfmt_status[v_adj.ch]); */
330 		break;
331 	case IOC_VDEC_SET_SATURATION:
332 		if (copy_from_user(&v_adj, argp, sizeof(nvp6158_video_adjust))) {
333 			up(&nvp6158_lock);
334 			return -1;
335 		}
336 		/* nvp6158_video_set_saturation(v_adj.ch, v_adj.value, ch_vfmt_status[v_adj.ch]); */
337 		break;
338 	case IOC_VDEC_SET_SHARPNESS:
339 		if (copy_from_user(&v_adj, argp, sizeof(nvp6158_video_adjust))) {
340 			up(&nvp6158_lock);
341 			return -1;
342 		}
343 			nvp6158_video_set_sharpness(v_adj.ch, v_adj.value);
344 		break;
345 	/*----------------------- Coaxial Protocol ----------------------*/
346 	case IOC_VDEC_COAX_TX_INIT: /* SK_CHANGE 170703 */
347 		if (copy_from_user(&coax_val, argp, sizeof(nvp6158_coax_str)))
348 			sensor_dbg("IOC_VDEC_COAX_TX_INIT error\n");
349 		coax_tx_init(&coax_val);
350 			break;
351 	case IOC_VDEC_COAX_TX_16BIT_INIT: /* SK_CHANGE 170703 */
352 		if (copy_from_user(&coax_val, argp, sizeof(nvp6158_coax_str)))
353 			sensor_dbg("IOC_VDEC_COAX_TX_INIT error\n");
354 		coax_tx_16bit_init(&coax_val);
355 			break;
356 	case IOC_VDEC_COAX_TX_CMD_SEND: /* SK_CHANGE 170703 */
357 		if (copy_from_user(&coax_val, argp, sizeof(nvp6158_coax_str)))
358 			sensor_dbg(" IOC_VDEC_COAX_TX_CMD_SEND error\n");
359 		coax_tx_cmd_send(&coax_val);
360 			break;
361 	case IOC_VDEC_COAX_TX_16BIT_CMD_SEND: /* SK_CHANGE 170703 */
362 		if (copy_from_user(&coax_val, argp, sizeof(nvp6158_coax_str)))
363 			sensor_dbg(" IOC_VDEC_COAX_TX_CMD_SEND error\n");
364 		coax_tx_16bit_cmd_send(&coax_val);
365 			break;
366 	case IOC_VDEC_COAX_TX_CVI_NEW_CMD_SEND: /* SK_CHANGE 170703 */
367 		if (copy_from_user(&coax_val, argp, sizeof(nvp6158_coax_str)))
368 				sensor_dbg(" IOC_VDEC_COAX_TX_CMD_SEND error\n");
369 		coax_tx_cvi_new_cmd_send(&coax_val);
370 			break;
371 	case IOC_VDEC_COAX_RX_INIT:
372 		if (copy_from_user(&coax_val, argp, sizeof(nvp6158_coax_str)))
373 			sensor_dbg(" IOC_VDEC_COAX_RX_INIT error\n");
374 		coax_rx_init(&coax_val);
375 		break;
376 	case IOC_VDEC_COAX_RX_DATA_READ:
377 		if (copy_from_user(&coax_val, argp, sizeof(nvp6158_coax_str)))
378 		sensor_dbg(" IOC_VDEC_COAX_RX_DATA_READ error\n");
379 		coax_rx_data_get(&coax_val);
380 		cpy2usr_ret = copy_to_user(argp, &coax_val, sizeof(nvp6158_coax_str));
381 		break;
382 	case IOC_VDEC_COAX_RX_BUF_CLEAR:
383 		if (copy_from_user(&coax_val, argp, sizeof(nvp6158_coax_str)))
384 			sensor_dbg(" IOC_VDEC_COAX_RX_BUF_CLEAR error\n");
385 		coax_rx_buffer_clear(&coax_val);
386 		break;
387 	case IOC_VDEC_COAX_RX_DEINIT:
388 		if (copy_from_user(&coax_val, argp, sizeof(nvp6158_coax_str)))
389 			sensor_dbg("IOC_VDEC_COAX_RX_DEINIT error\n");
390 		coax_rx_deinit(&coax_val);
391 		break;
392 	/*=============== Coaxial Protocol A-CP Option ===============*/
393 	case IOC_VDEC_COAX_RT_NRT_MODE_CHANGE_SET:
394 		if (copy_from_user(&coax_val, argp, sizeof(nvp6158_coax_str)))
395 		sensor_dbg(" IOC_VDEC_COAX_SHOT_SET error\n");
396 		coax_option_rt_nrt_mode_change_set(&coax_val);
397 		cpy2usr_ret = copy_to_user(argp, &coax_val, sizeof(nvp6158_coax_str));
398 		break;
399 	/*=========== Coaxial Protocol Firmware Update ==============*/
400 	case IOC_VDEC_COAX_FW_ACP_HEADER_GET:
401 		if (copy_from_user(&coax_fw_val, argp, sizeof(FIRMWARE_UP_FILE_INFO)))
402 						sensor_dbg("IOC_VDEC_COAX_FW_READY_CMD_SET error\n");
403 		coax_fw_ready_header_check_from_isp_recv(&coax_fw_val);
404 		cpy2usr_ret = copy_to_user(argp, &coax_fw_val, sizeof(FIRMWARE_UP_FILE_INFO));
405 		break;
406 	case IOC_VDEC_COAX_FW_READY_CMD_SET:
407 		if (copy_from_user(&coax_fw_val, argp, sizeof(FIRMWARE_UP_FILE_INFO)))
408 						sensor_dbg("IOC_VDEC_COAX_FW_READY_CMD_SET error\n");
409 		coax_fw_ready_cmd_to_isp_send(&coax_fw_val);
410 		cpy2usr_ret = copy_to_user(argp, &coax_fw_val, sizeof(FIRMWARE_UP_FILE_INFO));
411 		break;
412 	case IOC_VDEC_COAX_FW_READY_ACK_GET:
413 		if (copy_from_user(&coax_fw_val, argp, sizeof(FIRMWARE_UP_FILE_INFO)))
414 						sensor_dbg("IOC_VDEC_COAX_FW_READY_ISP_STATUS_GET error\n");
415 		coax_fw_ready_cmd_ack_from_isp_recv(&coax_fw_val);
416 		cpy2usr_ret = copy_to_user(argp, &coax_fw_val, sizeof(FIRMWARE_UP_FILE_INFO));
417 		break;
418 	case IOC_VDEC_COAX_FW_START_CMD_SET:
419 		if (copy_from_user(&coax_fw_val, argp, sizeof(FIRMWARE_UP_FILE_INFO)))
420 						sensor_dbg("IOC_VDEC_COAX_FW_START_CMD_SET error\n");
421 		coax_fw_start_cmd_to_isp_send(&coax_fw_val);
422 		cpy2usr_ret = copy_to_user(argp, &coax_fw_val, sizeof(FIRMWARE_UP_FILE_INFO));
423 		break;
424 	case IOC_VDEC_COAX_FW_START_ACK_GET:
425 		if (copy_from_user(&coax_fw_val, argp, sizeof(FIRMWARE_UP_FILE_INFO)))
426 						sensor_dbg("IOC_VDEC_COAX_FW_START_CMD_SET error\n");
427 		coax_fw_start_cmd_ack_from_isp_recv(&coax_fw_val);
428 		cpy2usr_ret = copy_to_user(argp, &coax_fw_val, sizeof(FIRMWARE_UP_FILE_INFO));
429 		break;
430 	case IOC_VDEC_COAX_FW_SEND_DATA_SET:
431 		if (copy_from_user(&coax_fw_val, argp, sizeof(FIRMWARE_UP_FILE_INFO)))
432 						sensor_dbg("IOC_VDEC_COAX_FW_START_CMD_SET error\n");
433 		coax_fw_one_packet_data_to_isp_send(&coax_fw_val);
434 		cpy2usr_ret = copy_to_user(argp, &coax_fw_val, sizeof(FIRMWARE_UP_FILE_INFO));
435 		break;
436 	case IOC_VDEC_COAX_FW_SEND_ACK_GET:
437 		if (copy_from_user(&coax_fw_val, argp, sizeof(FIRMWARE_UP_FILE_INFO)))
438 						sensor_dbg("IOC_VDEC_COAX_FW_START_CMD_SET error\n");
439 		coax_fw_one_packet_data_ack_from_isp_recv(&coax_fw_val);
440 		cpy2usr_ret = copy_to_user(argp, &coax_fw_val, sizeof(FIRMWARE_UP_FILE_INFO));
441 		break;
442 	case IOC_VDEC_COAX_FW_END_CMD_SET:
443 		if (copy_from_user(&coax_fw_val, argp, sizeof(FIRMWARE_UP_FILE_INFO)))
444 						sensor_dbg("IOC_VDEC_COAX_FW_START_CMD_SET error\n");
445 		coax_fw_end_cmd_to_isp_send(&coax_fw_val);
446 		cpy2usr_ret = copy_to_user(argp, &coax_fw_val, sizeof(FIRMWARE_UP_FILE_INFO));
447 		break;
448 	case IOC_VDEC_COAX_FW_END_ACK_GET:
449 		if (copy_from_user(&coax_fw_val, argp, sizeof(FIRMWARE_UP_FILE_INFO)))
450 						sensor_dbg("IOC_VDEC_COAX_FW_START_CMD_SET error\n");
451 		coax_fw_end_cmd_ack_from_isp_recv(&coax_fw_val);
452 		cpy2usr_ret = copy_to_user(argp, &coax_fw_val, sizeof(FIRMWARE_UP_FILE_INFO));
453 		break;
454 	/*=========== Coaxial Protocol Firmware Update END ==============*/
455 	/*----------------------- MOTION ----------------------*/
456 	case IOC_VDEC_MOTION_DETECTION_GET:
457 		if (copy_from_user(&motion_set, argp, sizeof(motion_set)))
458 			sensor_dbg("IOC_VDEC_MOTION_SET error\n");
459 		motion_detection_get(&motion_set);
460 		cpy2usr_ret = copy_to_user(argp, &motion_set, sizeof(motion_mode));
461 	break;
462 	case IOC_VDEC_MOTION_SET:
463 		if (copy_from_user(&motion_set, argp, sizeof(motion_set)))
464 			sensor_dbg("IOC_VDEC_MOTION_SET error\n");
465 		motion_onoff_set(&motion_set);
466 		break;
467 	case IOC_VDEC_MOTION_PIXEL_SET:
468 		if (copy_from_user(&motion_set, argp, sizeof(motion_set)))
469 			sensor_dbg("IOC_VDEC_MOTION_Pixel_SET error\n");
470 		motion_pixel_onoff_set(&motion_set);
471 	break;
472 	case IOC_VDEC_MOTION_PIXEL_GET:
473 		if (copy_from_user(&motion_set, argp, sizeof(motion_set)))
474 			sensor_dbg("IOC_VDEC_MOTION_Pixel_SET error\n");
475 		motion_pixel_onoff_get(&motion_set);
476 		cpy2usr_ret = copy_to_user(argp, &motion_set, sizeof(motion_mode));
477 		break;
478 	case IOC_VDEC_MOTION_ALL_PIXEL_SET:
479 		if (copy_from_user(&motion_set, argp, sizeof(motion_set)))
480 			sensor_dbg("IOC_VDEC_MOTION_Pixel_SET error\n");
481 		motion_pixel_all_onoff_set(&motion_set);
482 	break;
483 	case IOC_VDEC_MOTION_TSEN_SET:
484 		if (copy_from_user(&motion_set, argp, sizeof(motion_set)))
485 			sensor_dbg("IOC_VDEC_MOTION_TSEN_SET error\n");
486 		motion_tsen_set(&motion_set);
487 	break;
488 	case IOC_VDEC_MOTION_PSEN_SET:
489 		if (copy_from_user(&motion_set, argp, sizeof(motion_set)))
490 			sensor_dbg("IOC_VDEC_MOTION_PSEN_SET error\n");
491 		motion_psen_set(&motion_set);
492 	break;
493 	default:
494 		/* sensor_dbg("drv:invalid nc decoder ioctl cmd[%x]\n", cmd); */
495 		break;
496 	}
497 	up(&nvp6158_lock);
498 	return 0;
499 }
500 #endif
501 
502 #if 0
503 /*******************************************************************************
504 *	Description		: kernel thread for EQ (now, not used)
505 *	Argurments		: void
506 *	Return value	: 0
507 *	Modify			:
508 *	warning			:
509 *******************************************************************************/
510 static int nvp6158_kernel_thread(void *data)
511 {
512 	/* int ch; */
513 	/* nvp6158_input_videofmt videofmt; */
514 	NVP6158_INFORMATION_S s_nvp6158_vfmts;
515 	video_equalizer_info_s s_eq_info;
516 	unsigned char prefmt = 0, curfmt = 0, chvloss = 0;
517 	unsigned char ch = 0;
518 
519 	memset(&s_nvp6158_vfmts, 0, sizeof(NVP6158_INFORMATION_S));
520 
521 	while (!kthread_should_stop()) {
522 		#if 1  /* standard rutine of a process */
523 		down(&nvp6158_lock);
524 		ch = ch % (nvp6158_cnt*4);
525 		nvp6158_getvideoloss();
526 		if (chip_nvp6158_id[0] == NVP6158C_R0_ID || chip_nvp6158_id[0] == NVP6158_R0_ID) {
527 			video_fmt_det(ch, &s_nvp6158_vfmts);
528 			curfmt = s_nvp6158_vfmts.curvideofmt[ch];
529 			prefmt = s_nvp6158_vfmts.prevideofmt[ch];
530 			chvloss = s_nvp6158_vfmts.curvideoloss[ch];
531 			/* sensor_dbg(">>>>>>%s CH[%d] chvloss = %d curfmt = %x prefmt = %x\n", __func__, ch, chvloss, curfmt, prefmt); */
532 
533 			if (chvloss == 0x00) {
534 				if (ch_mode_status[ch] != prefmt) {
535 					nvp6158_set_chnmode(ch, curfmt);
536 					nvp6158_set_portmode(0, ch%4, NVP6158_OUTMODE_1MUX_FHD, ch%4);
537 					s_eq_info.Ch = ch%4;
538 					s_eq_info.devnum = ch/4;
539 					s_eq_info.FmtDef = curfmt;
540 					nvp6158_get_eq_dist(&s_eq_info);
541 					s_nvp6158_vfmts.prevideofmt[ch] = curfmt;
542 					sensor_dbg(">>>>>>%s CH[%d] s_eq_info.distance = %d\n", __func__, ch, s_eq_info.distance);
543 					nvp6158_set_equalizer(&s_eq_info);
544 				}
545 			} else {
546 				if (ch_mode_status[ch] != NC_VIVO_CH_FORMATDEF_UNKNOWN) {
547 					nvp6158_set_chnmode(ch, NC_VIVO_CH_FORMATDEF_UNKNOWN);
548 					nvp6158_set_portmode(0, ch%4, NVP6158_OUTMODE_1MUX_FHD, ch%4);
549 				}
550 			}
551 		} else {
552 			nvp6168_video_fmt_det(ch, &s_nvp6158_vfmts);
553 			curfmt = s_nvp6158_vfmts.curvideofmt[ch];
554 			prefmt = s_nvp6158_vfmts.prevideofmt[ch];
555 			chvloss = s_nvp6158_vfmts.curvideoloss[ch];
556 			/* sensor_dbg(">>>>>>%s CH[%d] chvloss = %d curfmt = %x prefmt = %x ch_mode_status[%d]=%x\n", __func__, ch, chvloss, curfmt, prefmt, ch, ch_mode_status[ch]); */
557 
558 			if (chvloss == 0x00) {
559 				if (ch_mode_status[ch] != prefmt) {
560 					nvp6168_set_chnmode(ch, curfmt);
561 					nvp6158_set_portmode(0, ch%4, NVP6158_OUTMODE_1MUX_FHD, ch%4);
562 					s_eq_info.Ch = ch%4;
563 					s_eq_info.devnum = ch/4;
564 					s_eq_info.FmtDef = curfmt;
565 					nvp6158_get_eq_dist(&s_eq_info);
566 					s_nvp6158_vfmts.prevideofmt[ch] = curfmt;
567 					sensor_dbg(">>>>>>%s CH[%d] s_eq_info.distance = %d\n", __func__, ch, s_eq_info.distance);
568 					nvp6168_set_equalizer(&s_eq_info);
569 				}
570 			} else {
571 				if (ch_mode_status[ch] != NC_VIVO_CH_FORMATDEF_UNKNOWN) {
572 					nvp6168_set_chnmode(ch, NC_VIVO_CH_FORMATDEF_UNKNOWN);
573 					nvp6158_set_portmode(0, ch%4, NVP6158_OUTMODE_1MUX_FHD, ch%4);
574 				}
575 			}
576 		}
577 		ch++;
578 		up(&nvp6158_lock);
579 		#endif
580 		schedule_timeout_interruptible(msecs_to_jiffies(200));
581 		/* sensor_dbg("nvp6158_kernel_thread running\n"); */
582 	}
583 
584 	return 0;
585 }
586 #endif
587 
588 /*******************************************************************************
589 *	Description		: It is called when "insmod nvp61XX_ex.ko" command run
590 *	Argurments		: void
591 *	Return value	: -1(could not register nvp61XX device), 0(success)
592 *	Modify			:
593 *	warning			:
594 *******************************************************************************/
nvp6158_init_hardware(int video_mode)595 int nvp6158_init_hardware(int video_mode)
596 {
597 	int chip = 0;
598 	unsigned char ch = 0;
599 	video_input_auto_detect vin_auto_det;
600 	/* char entry[20]; */
601 
602 	nvp6158_cnt = 1;
603 	chip_nvp6158_id[0] = NVP6158C_R0_ID;
604 	//* hip_id[0] = check_nvp6158_id(0x62); */
605 #if 0
606 	/* check Device ID of maxium 4chip on the slave address,
607 	* manage slave address. chip count. */
608 	for (chip = 0; chip < 4; chip++) {
609 		chip_nvp6158_id[chip] = check_nvp6158_id(nvp6158_iic_addr[chip]);
610 		rev_nvp6158_id[chip]  = check_nvp6158_rev(nvp6158_iic_addr[chip]);
611 		if ((chip_nvp6158_id[chip] != NVP6158_R0_ID) &&
612 			(chip_nvp6158_id[chip] != NVP6158C_R0_ID) &&
613 			(chip_nvp6158_id[chip] != NVP6168_R0_ID) &&
614 			(chip_nvp6158_id[chip] != NVP6168C_R0_ID)) {
615 			sensor_dbg("Device ID Error... %x\n", chip_nvp6158_id[chip]);
616 		} else {
617 			sensor_dbg("Device (0x%x) ID OK... %x\n", nvp6158_iic_addr[chip], chip_nvp6158_id[chip]);
618 			sensor_dbg("Device (0x%x) REV ... %x\n", nvp6158_iic_addr[chip], rev_nvp6158_id[chip]);
619 			nvp6158_iic_addr[nvp6158_cnt] = nvp6158_iic_addr[chip];
620 			if (nvp6158_cnt < chip)
621 				nvp6158_iic_addr[chip] = 0xFF;
622 			chip_nvp6158_id[nvp6158_cnt] = chip_id[chip];
623 			rev_nvp6158_id[nvp6158_cnt]  = rev_nvp6158_id[chip];
624 			nvp6158_cnt++;
625 		}
626 	}
627 
628 	sensor_dbg("Chip Count = %d, [0x%x][0x%x][0x%x][0x%x]\n", \
629 		nvp6158_cnt, nvp6158_iic_addr[0], nvp6158_iic_addr[1],\
630 		nvp6158_iic_addr[2], nvp6158_iic_addr[3]);
631 #endif
632 	/* initialize semaphore */
633 	sema_init(&nvp6158_lock, 1);
634 
635 	/* initialize common value of AHD */
636 	for (chip = 0; chip < nvp6158_cnt; chip++) {
637 		nvp6158_common_init(chip);
638 		if (chip_nvp6158_id[chip] == NVP6158C_R0_ID || chip_nvp6158_id[chip] == NVP6158_R0_ID)
639 			nvp6158_additional_for3MoverDef(chip);
640 		else {
641 			gpio_i2c_write(nvp6158_iic_addr[chip], 0xff, 0x01);
642 			gpio_i2c_write(nvp6158_iic_addr[chip], 0x97, 0x00); /* CH_RST ON */
643 			gpio_i2c_write(nvp6158_iic_addr[chip], 0x97, 0x0f); /* CH_RST OFF */
644 			gpio_i2c_write(nvp6158_iic_addr[chip], 0x7a, 0x0f); /* Clock Auto ON */
645 			gpio_i2c_write(nvp6158_iic_addr[chip], 0xca, 0xff); /* VCLK_EN, VDO_EN */
646 
647 			for (ch = 0; ch < 4; ch++) {
648 				gpio_i2c_write(nvp6158_iic_addr[chip], 0xff, 0x05 + ch);
649 				gpio_i2c_write(nvp6158_iic_addr[chip], 0x00, 0xd0);
650 
651 				gpio_i2c_write(nvp6158_iic_addr[chip], 0x05, 0x04);
652 				gpio_i2c_write(nvp6158_iic_addr[chip], 0x08, 0x55);
653 				gpio_i2c_write(nvp6158_iic_addr[chip], 0x47, 0xEE);
654 				gpio_i2c_write(nvp6158_iic_addr[chip], 0x59, 0x00);
655 				gpio_i2c_write(nvp6158_iic_addr[chip], 0x76, 0x00);
656 				gpio_i2c_write(nvp6158_iic_addr[chip], 0x77, 0x80);
657 				gpio_i2c_write(nvp6158_iic_addr[chip], 0x78, 0x00);
658 				gpio_i2c_write(nvp6158_iic_addr[chip], 0x79, 0x11);
659 				gpio_i2c_write(nvp6158_iic_addr[chip], 0xB8, 0xB8); /* H_PLL_BYPASS */
660 				gpio_i2c_write(nvp6158_iic_addr[chip], 0x7B, 0x11); /* v_rst_on */
661 				gpio_i2c_write(nvp6158_iic_addr[chip], 0xb9, 0x72);
662 				gpio_i2c_write(nvp6158_iic_addr[chip], 0xB8, 0xB8); /* No Video Set */
663 
664 				gpio_i2c_write(nvp6158_iic_addr[chip], 0xff, 0x00);
665 				gpio_i2c_write(nvp6158_iic_addr[chip], 0x00+ch, 0x10);
666 				gpio_i2c_write(nvp6158_iic_addr[chip], 0x22+(ch*0x04), 0x0b);
667 			}
668 			gpio_i2c_write(nvp6158_iic_addr[chip], 0xff, 0x13);
669 			gpio_i2c_write(nvp6158_iic_addr[chip], 0x12, 0x04);
670 			gpio_i2c_write(nvp6158_iic_addr[chip], 0x2E, 0x10);
671 			gpio_i2c_write(nvp6158_iic_addr[chip], 0x30, 0x00);
672 			gpio_i2c_write(nvp6158_iic_addr[chip], 0x77, 0xff);
673 			gpio_i2c_write(nvp6158_iic_addr[chip], 0x3a, 0xff);
674 			gpio_i2c_write(nvp6158_iic_addr[chip], 0x3b, 0xff);
675 			gpio_i2c_write(nvp6158_iic_addr[chip], 0x3c, 0xff);
676 			gpio_i2c_write(nvp6158_iic_addr[chip], 0x3d, 0xff);
677 			gpio_i2c_write(nvp6158_iic_addr[chip], 0x3e, 0xff);
678 			gpio_i2c_write(nvp6158_iic_addr[chip], 0x3f, 0xff);
679 			gpio_i2c_write(nvp6158_iic_addr[chip], 0x70, 0x00);
680 			gpio_i2c_write(nvp6158_iic_addr[chip], 0x72, 0x05);
681 			gpio_i2c_write(nvp6158_iic_addr[chip], 0x7A, 0x10);
682 			/*gpio_i2c_write(nvp6158_iic_addr[chip], 0x61, 0x03);*/
683 			/*gpio_i2c_write(nvp6158_iic_addr[chip], 0x62, 0x00);*/
684 			/*gpio_i2c_write(nvp6158_iic_addr[chip], 0x63, 0x03);*/
685 			/*gpio_i2c_write(nvp6158_iic_addr[chip], 0x64, 0x00);*/
686 			/*gpio_i2c_write(nvp6158_iic_addr[chip], 0x65, 0x03);*/
687 			/*gpio_i2c_write(nvp6158_iic_addr[chip], 0x66, 0x00);*/
688 			/*gpio_ic_write(nvp6158_iic_addr[chip], 0x67, 0x03);*/
689 			/*gpio_i2c_write(nvp6158_iic_addr[chip], 0x68, 0x00);*/
690 			/*gpio_i2c_write(nvp6158_iic_addr[chip], 0x60, 0x0f);*/
691 			/*gpio_i2c_write(nvp6158_iic_addr[chip], 0x60, 0x00);*/
692 			gpio_i2c_write(nvp6158_iic_addr[chip], 0x07, 0x47);
693 			gpio_i2c_write(nvp6158_iic_addr[chip], 0x59, 0x24);
694 
695 			/* SAM Range */
696 			gpio_i2c_write(nvp6158_iic_addr[chip], 0x74, 0x00);
697 			gpio_i2c_write(nvp6158_iic_addr[chip], 0x76, 0x00);
698 			gpio_i2c_write(nvp6158_iic_addr[chip], 0x78, 0x00);
699 			gpio_i2c_write(nvp6158_iic_addr[chip], 0x75, 0xff);
700 			gpio_i2c_write(nvp6158_iic_addr[chip], 0x77, 0xff);
701 			gpio_i2c_write(nvp6158_iic_addr[chip], 0x79, 0xff);
702 
703 			gpio_i2c_write(nvp6158_iic_addr[chip], 0x01, 0x0c);
704 			gpio_i2c_write(nvp6158_iic_addr[chip], 0x2f, 0xc8);
705 
706 			// EQ Stage Get
707 			gpio_i2c_write(nvp6158_iic_addr[chip], 0x73, 0x23);
708 
709 			gpio_i2c_write(nvp6158_iic_addr[chip], 0xff, 0x09);
710 			gpio_i2c_write(nvp6158_iic_addr[chip], 0x96, 0x03);
711 			gpio_i2c_write(nvp6158_iic_addr[chip], 0xB6, 0x03);
712 			gpio_i2c_write(nvp6158_iic_addr[chip], 0xD6, 0x03);
713 			gpio_i2c_write(nvp6158_iic_addr[chip], 0xF6, 0x03);
714 
715 			/********************************************************
716 			 * Audio Default Setting
717 			 ********************************************************/
718 			gpio_i2c_write(nvp6158_iic_addr[chip], 0xff, 0x01);
719 			gpio_i2c_write(nvp6158_iic_addr[chip], 0x05, 0x09);
720 			gpio_i2c_write(nvp6158_iic_addr[chip], 0x58, 0x02);
721 			gpio_i2c_write(nvp6158_iic_addr[chip], 0x59, 0x00);
722 		}
723 	}
724 
725 	for (ch = 0; ch < nvp6158_cnt*4; ch++) {
726 		/* det_mode[ch] = NVP6158_DET_MODE_AUTO; */
727 		det_mode[ch] = NVP6158_DET_MODE_AHD;
728 		vin_auto_det.ch = ch%4;
729 		vin_auto_det.devnum = ch/4;
730 		if (chip_nvp6158_id[0] == NVP6158C_R0_ID || chip_nvp6158_id[0] == NVP6158_R0_ID) {
731 			video_input_auto_detect_set(&vin_auto_det);
732 			/*nvp6158_set_chnmode(ch, NC_VIVO_CH_FORMATDEF_UNKNOWN);*/
733 			nvp6158_set_chnmode(ch, video_mode);
734 		} else {
735 			nvp6168_video_input_auto_detect_set(&vin_auto_det);
736 			nvp6168_set_chnmode(ch, NC_VIVO_CH_FORMATDEF_UNKNOWN);
737 		}
738 	}
739 
740 	for (chip = 0; chip < nvp6158_cnt; chip++) {
741 		if (chip_nvp6158_id[chip] == NVP6158_R0_ID || chip_nvp6158_id[chip] == NVP6168_R0_ID) {
742 			/*setting nvp6158 four port(0~3) being output mode enable*/
743 			nvp6158_set_portmode(chip, 0, NVP6158_OUTMODE_1MUX_FHD, 0);
744 			nvp6158_set_portmode(chip, 1, NVP6158_OUTMODE_1MUX_FHD, 1);
745 			nvp6158_set_portmode(chip, 2, NVP6158_OUTMODE_1MUX_FHD, 2);
746 			nvp6158_set_portmode(chip, 3, NVP6158_OUTMODE_1MUX_FHD, 3);
747 		} else { /*if(chip_nvp6158_id[chip] == NVP6158C_R0_ID) */
748 			/*setting nvp6158 four port(0~3) being output mode enable*/
749 
750 			/*nvp6158_set_portmode(chip, 1, NVP6158_OUTMODE_2MUX_FHD, 0);
751 			nvp6158_set_portmode(chip, 2, NVP6158_OUTMODE_2MUX_FHD, 1);*/
752 			if (video_mode == AHD20_720P_25P) {
753 #if 1 /*BT1120*/
754 				nvp6158_set_portmode(chip, 0, NVP6158_OUTMODE_4MUX_BT1120S, 0);
755 				nvp6158_set_portmode(chip, 1, NVP6158_OUTMODE_4MUX_BT1120S, 1);
756 				nvp6158_set_portmode(chip, 2, NVP6158_OUTMODE_4MUX_BT1120S, 2);
757 				nvp6158_set_portmode(chip, 3, NVP6158_OUTMODE_4MUX_BT1120S, 3);
758 #else /*BT656--NVP6158_OUTMODE_1MUX_HD / NVP6158_OUTMODE_2MUX_HD / NVP6158_OUTMODE_4MUX_HD*/
759 				nvp6158_set_portmode(chip, 0, NVP6158_OUTMODE_1MUX_HD, 0)
760 #endif
761 			} else if (video_mode == AHD20_1080P_25P || video_mode == AHD20_1080P_30P) {
762 				nvp6158_set_portmode(chip, 0, NVP6158_OUTMODE_4MUX_MIX, 0);
763 				nvp6158_set_portmode(chip, 1, NVP6158_OUTMODE_4MUX_MIX, 1);
764 				nvp6158_set_portmode(chip, 2, NVP6158_OUTMODE_4MUX_MIX, 2);
765 				nvp6158_set_portmode(chip, 3, NVP6158_OUTMODE_4MUX_MIX, 3);
766 			}
767 		}
768 		for (ch = 0; ch < 4; ch++) {
769 			printk("nvp6158 reg init chip = %d,ch =  %d\n", chip, ch);
770 			gpio_i2c_write(nvp6158_iic_addr[chip], 0xFF, 0x00);
771 			gpio_i2c_write(nvp6158_iic_addr[chip], 0x23+(ch%4)*4, 0x71);
772 			gpio_i2c_write(nvp6158_iic_addr[chip], 0xFF, 0x05+(ch%4));
773 			gpio_i2c_write(nvp6158_iic_addr[chip], 0x00, 0xd0);
774 			gpio_i2c_write(nvp6158_iic_addr[chip], 0x01, 0x22);
775 			gpio_i2c_write(nvp6158_iic_addr[chip], 0x03, 0x1f);
776 			gpio_i2c_write(nvp6158_iic_addr[chip], 0x47, 0x02);
777 			gpio_i2c_write(nvp6158_iic_addr[chip], 0x5B, 0x41);
778 			gpio_i2c_write(nvp6158_iic_addr[chip], 0x50, 0x82);
779 			gpio_i2c_write(nvp6158_iic_addr[chip], 0xb8, 0xb9);
780 		}
781 
782 	}
783 
784 	/* initialize Audio
785 	 * recmaster, pbmaster, ch_num, samplerate, bits */
786 	if (chip_nvp6158_id[0] == NVP6158C_R0_ID || chip_nvp6158_id[0] == NVP6158_R0_ID)
787 		audio_init(1, 0, 16, 0, 0);
788 	else
789 		nvp6168_audio_init(1, 0, 16, 0, 0);
790 
791 	/* create kernel thread for EQ, But Now not used. */
792 	/*if (kthread == 1)
793 	{
794 		nvp6158_kt = kthread_create(nvp6158_kernel_thread, NULL, "nvp6158_kt");
795 			if (!IS_ERR(nvp6158_kt))
796 				wake_up_process(nvp6158_kt);
797 			else {
798 				sensor_dbg("create nvp6158 watchdog thread failed!!\n");
799 				nvp6158_kt = 0;
800 				return 0;
801 			}
802 	}*/
803 #ifdef COLORBAR_EN
804 	gpio_i2c_write(nvp6158_iic_addr[0], 0xFF, 0x05);
805 	gpio_i2c_write(nvp6158_iic_addr[0], 0x2c, 0x08);
806 	gpio_i2c_write(nvp6158_iic_addr[0], 0xFF, 0x06);
807 	gpio_i2c_write(nvp6158_iic_addr[0], 0x2c, 0x08);
808 	gpio_i2c_write(nvp6158_iic_addr[0], 0xFF, 0x07);
809 	gpio_i2c_write(nvp6158_iic_addr[0], 0x2c, 0x08);
810 	gpio_i2c_write(nvp6158_iic_addr[0], 0xFF, 0x08);
811 	gpio_i2c_write(nvp6158_iic_addr[0], 0x2c, 0x08);
812 
813 	gpio_i2c_write(nvp6158_iic_addr[0], 0xFF, 0x00);
814 	/* gpio_i2c_write(nvp6158_iic_addr[0], 0x78, 0x42);//ch1:Blue */
815 	/* ch2:Yellow ch3:Green ch4:Red */
816 	/* gpio_i2c_write(nvp6158_iic_addr[0], 0x79, 0x76); */
817 	gpio_i2c_write(nvp6158_iic_addr[0], 0x78,
818 				0xce); /* ch1:Blue  ch2:Yellow ch3:Green ch4:Red */
819 	gpio_i2c_write(nvp6158_iic_addr[0], 0x79, 0xba);
820 #endif
821 	return 0;
822 }
823 /*******************************************************************************
824 *	End of file
825 *******************************************************************************/
826 
827