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