• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * A V4L2 driver for nvp6324 cameras and AHD Coax protocol.
3  *
4  * Copyright (c) 2017 by Allwinnertech Co., Ltd.  http://www.allwinnertech.com
5  *
6  * Authors:  Li Huiyu <lihuiyu@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 
13 #include <linux/clk.h>
14 #include <linux/delay.h>
15 #include <linux/i2c.h>
16 #include <linux/init.h>
17 #include <linux/io.h>
18 #include <linux/module.h>
19 #include <linux/slab.h>
20 #include <linux/videodev2.h>
21 #include <media/v4l2-device.h>
22 #include <media/v4l2-mediabus.h>
23 #include <media/v4l2-subdev.h>
24 #include "type.h"
25 
26 #include "jaguar1_video.h"
27 #include "jaguar1_mipi.h"
28 
29 #include "../camera.h"
30 #include "../sensor_helper.h"
31 
32 #define JAGUAR1_4PORT_R0_ID 0xB0
33 #define JAGUAR1_2PORT_R0_ID 0xA0
34 #define JAGUAR1_1PORT_R0_ID 0xA2
35 #define AFE_NVP6134E_R0_ID 	0x80
36 
37 #define JAGUAR1_4PORT_REV_ID 0x00
38 #define JAGUAR1_2PORT_REV_ID 0x00
39 #define JAGUAR1_1PORT_REV_ID 0x00
40 
41 
42 
43 int chip_id[4];
44 int rev_id[4];
45 static int jaguar1_cnt;
46 unsigned int jaguar1_i2c_addr[4] = {0x60, 0x62, 0x64, 0x66};
47 decoder_get_information_str decoder_inform;
48 unsigned int bit8 = 1;
49 unsigned int chn = 4;
50 
51 
52 extern struct v4l2_subdev *nvp6324_sd;
53 
54 #define FMT_SETTING_SAMPLE
55 #define SENSOR_NAME "nvp6324_mipi"
56 
57 
nvp6324_i2c_write(u8 da,u8 reg,u8 val)58 u32 nvp6324_i2c_write(u8 da, u8 reg, u8 val)
59 {
60 	u32 ret;
61 
62 	ret = cci_write_a8_d8(nvp6324_sd, reg, val);
63 	/* u_twi_wr_8_8(reg, val, da>>1,3); */
64 
65 	return ret;
66 }
67 
nvp6324_i2c_read(u8 da,u8 reg)68 u32 nvp6324_i2c_read(u8 da, u8 reg)
69 {
70 	u8 ret;
71 	u8 val = 0;
72 	ret = cci_read_a8_d8(nvp6324_sd, reg, &val);
73 	/* ret = u_twi_rd_8_8(reg, &val, da>>1,3); */
74 
75 	return val;
76 }
77 
78 /*******************************************************************************
79 *	Description		: Get Device ID
80 *	Argurments		: dec(slave address)
81 *	Return value	: Device ID
82 *	Modify			:
83 *	warning			:
84 *******************************************************************************/
check_id(unsigned int dec)85 int check_id(unsigned int dec)
86 {
87 	int ret;
88 
89 	nvp6324_i2c_write(dec, 0xFF, 0x00);
90 	ret = nvp6324_i2c_read(dec, 0xf4);
91 	return ret;
92 }
93 
94 /*******************************************************************************
95 *	Description		: Get rev ID
96 *	Argurments		: dec(slave address)
97 *	Return value	: rev ID
98 *	Modify			:
99 *	warning			:
100 *******************************************************************************/
check_rev(unsigned int dec)101 int check_rev(unsigned int dec)
102 {
103 	int ret;
104 	nvp6324_i2c_write(dec, 0xFF, 0x00);
105 	ret = nvp6324_i2c_read(dec, 0xf5);
106 	return ret;
107 }
108 
vd_pattern_enable(void)109 static void vd_pattern_enable(void)
110 {
111 	nvp6324_i2c_write(0x60, 0xFF, 0x00);
112 	nvp6324_i2c_write(0x60, 0x1C, 0x1A);
113 	nvp6324_i2c_write(0x60, 0x1D, 0x1A);
114 	nvp6324_i2c_write(0x60, 0x1E, 0x1A);
115 	nvp6324_i2c_write(0x60, 0x1F, 0x1A);
116 
117 	nvp6324_i2c_write(0x60, 0xFF, 0x05);
118 	nvp6324_i2c_write(0x60, 0x6A, 0x80);
119 	nvp6324_i2c_write(0x60, 0xFF, 0x06);
120 	nvp6324_i2c_write(0x60, 0x6A, 0x80);
121 	nvp6324_i2c_write(0x60, 0xFF, 0x07);
122 	nvp6324_i2c_write(0x60, 0x6A, 0x80);
123 	nvp6324_i2c_write(0x60, 0xFF, 0x08);
124 	nvp6324_i2c_write(0x60, 0x6A, 0x80);
125 }
126 
127 
128 /******************************************************************************
129 *
130  *	Description		: Check ID
131  *	Argurments		: dec(slave address)
132  *	Return value	: Device ID
133  *	Modify			:
134  *	warning			:
135 
136 *******************************************************************************/
vd_set_all(video_init_all * param)137 static void vd_set_all(video_init_all *param)
138 {
139 		int i, dev_num = 0;
140 		video_input_init  video_val[4];
141 
142 #if 0
143 		for (i = 0; i < 4; i++) {
144 			sensor_dbg("[DRV || %s] ch%d / fmt:%d / input:%d / interface:%d\n", __func__
145 					, param->ch_param[i].ch
146 					, param->ch_param[i].format
147 					, param->ch_param[i].input
148 					, param->ch_param[i].interface);
149 		}
150 #endif
151 		mipi_datatype_set(VD_DATA_TYPE_YUV422);
152 		mipi_tx_init(dev_num);
153 
154 		for (i = 0; i < 4; i++) {
155 			video_val[i].ch = param->ch_param[i].ch;
156 			video_val[i].format = param->ch_param[i].format;
157 			video_val[i].input = param->ch_param[i].input;
158 			if (i < chn)
159 				video_val[i].interface = param->ch_param[i].interface;
160 			else
161 				video_val[i].interface = DISABLE;
162 
163 			vd_jaguar1_init_set(&video_val[i]);
164 			mipi_video_format_set(&video_val[i]);
165 #ifdef FOR_IMX6
166 			set_imx_video_format(&video_val[i]);
167 			if (video_val[i].interface == DISABLE) {
168 				sensor_dbg("[DRV] Nothing selected [video ch : %d]\n", i);
169 			} else {
170 				init_imx_mipi(i);
171 			}
172 #endif
173 		}
174 		arb_init(dev_num);
175 		disable_parallel(dev_num);
176 		vd_pattern_enable();
177 
178 }
179 
180 
181 /*******************************************************************************
182  *	Description		: Sample function - for select video format
183  *	Argurments		: int dev_num(i2c_address array's num)
184  *	Return value	: void
185  *	Modify			:
186  *	warning			:
187  *******************************************************************************/
188 #ifdef FMT_SETTING_SAMPLE
set_default_video_fmt(int dev_num)189 void set_default_video_fmt(int dev_num)
190 {
191 
192 #if 0
193 	int i;
194 	video_input_init  video_val;
195 
196 	for (i = 0; i < 4; i++) {
197 		video_val.ch = i;
198 
199 		/* select video format, include struct'vd_vi_init_list' in jaguar1_video_table.h
200 		 *  ex > AHD20_1080P_30P / AHD20_720P_25P_EX_Btype / AHD20_SD_H960_2EX_Btype_NT */
201 		video_val.format = AHD20_720P_30P_EX_Btype;
202 
203 		// select analog input type, SINGLE_ENDED or DIFFERENTIAL
204 		video_val.input = SINGLE_ENDED;
205 
206 		// select decoder to soc interface
207 		video_val.interface = MIPI;
208 
209 		// run video setting
210 		vd_jaguar1_init_set(&video_val);
211 
212 		// run video format setting for mipi/arbiter
213 		mipi_video_format_set(&video_val);
214 	}
215 	arb_init(dev_num);
216 	disable_parallel(dev_num);
217 #endif
218 #if 0
219 	video_val.ch = 0;
220 	video_val.format = AHD20_1080P_30P;
221 	video_val.input = SINGLE_ENDED;
222 	vd_jaguar1_init_set(&video_val);
223 
224 	mipi_video_format_set(&video_val);
225 
226 	arb_init(dev_num);
227 #endif
228 }
229 #endif
230 
231 
232 /******************************************************************************
233 *
234  *	Description		: Check decoder count
235  *	Argurments		: void
236  *	Return value	: (total chip count - 1) or -1(not found any chip)
237  *	Modify			:
238  *	warning			:
239 
240 *******************************************************************************/
check_decoder_count(void)241 int check_decoder_count(void)
242 {
243 	int chip, i;
244 	int ret = -1;
245 
246 	jaguar1_cnt = 0;
247 	for (chip = 0; chip < 4; chip++) {
248 		chip_id[chip] = check_id(jaguar1_i2c_addr[chip]);
249 		rev_id[chip]  = check_rev(jaguar1_i2c_addr[chip]);
250 		if ((chip_id[chip] != JAGUAR1_4PORT_R0_ID)  	&&
251 				(chip_id[chip] != JAGUAR1_2PORT_R0_ID) 		&&
252 				(chip_id[chip] != JAGUAR1_1PORT_R0_ID)		&&
253 				(chip_id[chip] != AFE_NVP6134E_R0_ID)
254 		  ) {
255 			sensor_err("Device ID Error... %x, Chip Count:[%d]\n", chip_id[chip], chip);
256 			jaguar1_i2c_addr[chip] = 0xFF;
257 			chip_id[chip] = 0xFF;
258 		} else {
259 			sensor_dbg("Device (0x%x) ID OK... %x , Chip Count:[%d]\n",
260 				jaguar1_i2c_addr[chip], chip_id[chip], chip);
261 			sensor_dbg("Device (0x%x) REV %x\n", jaguar1_i2c_addr[chip], rev_id[chip]);
262 				jaguar1_i2c_addr[jaguar1_cnt] = jaguar1_i2c_addr[chip];
263 
264 			if (jaguar1_cnt < chip) {
265 				jaguar1_i2c_addr[chip] = 0xFF;
266 			}
267 
268 			chip_id[jaguar1_cnt] = chip_id[chip];
269 			rev_id[jaguar1_cnt]  = rev_id[chip];
270 
271 			jaguar1_cnt++;
272 		}
273 
274 		if ((chip == 3) && (jaguar1_cnt < chip)) {
275 			for (i = jaguar1_cnt; i < 4; i++) {
276 				chip_id[i] = 0xff;
277 				rev_id[i]  = 0xff;
278 			}
279 		}
280 	}
281 	sensor_dbg("Chip Count = %d\n", jaguar1_cnt);
282 	sensor_dbg("Address [0x%x][0x%x][0x%x][0x%x]\n", jaguar1_i2c_addr[0], jaguar1_i2c_addr[1], jaguar1_i2c_addr[2], jaguar1_i2c_addr[3]);
283 	sensor_dbg("Chip Id [0x%x][0x%x][0x%x][0x%x]\n", chip_id[0], chip_id[1], chip_id[2], chip_id[3]);
284 	sensor_dbg("Rev Id  [0x%x][0x%x][0x%x][0x%x]\n", rev_id[0], rev_id[1], rev_id[2], rev_id[3]);
285 
286 	for (i = 0; i < 4; i++) {
287 		decoder_inform.chip_id[i] = chip_id[i];
288 		decoder_inform.chip_rev[i] = rev_id[i];
289 		decoder_inform.chip_addr[i] = jaguar1_i2c_addr[i];
290 	}
291 	decoder_inform.Total_Chip_Cnt = jaguar1_cnt;
292 	ret = jaguar1_cnt;
293 
294 	return ret;
295 }
296 
297 /******************************************************************************
298 *
299  *	Description		: Video decoder initial
300  *	Argurments		: void
301  *	Return value	: void
302  *	Modify			:
303  *	warning			:
304 
305 *******************************************************************************/
video_decoder_init(void)306 void video_decoder_init(void)
307 {
308 		int ii = 0;
309 
310 		nvp6324_i2c_write(jaguar1_i2c_addr[0], 0xff, 0x04);
311 
312 		for (ii = 0; ii < 36; ii++) {
313 			nvp6324_i2c_write(jaguar1_i2c_addr[0], 0xa0 + ii, 0x24);
314 		}
315 
316 		nvp6324_i2c_write(jaguar1_i2c_addr[0], 0xff, 0x01);
317 		for (ii = 0; ii < 4; ii++) {
318 			nvp6324_i2c_write(jaguar1_i2c_addr[0], 0xcc + ii, 0x64);
319 		}
320 #if 1
321 		nvp6324_i2c_write(jaguar1_i2c_addr[0], 0xff, 0x21);
322 		nvp6324_i2c_write(jaguar1_i2c_addr[0], 0x07, 0x80);
323 		nvp6324_i2c_write(jaguar1_i2c_addr[0], 0x07, 0x00);
324 #endif
325 
326 #if 1
327 		nvp6324_i2c_write(jaguar1_i2c_addr[0], 0xff, 0x0A);
328 		nvp6324_i2c_write(jaguar1_i2c_addr[0], 0x77, 0x8F);
329 		nvp6324_i2c_write(jaguar1_i2c_addr[0], 0xF7, 0x8F);
330 		nvp6324_i2c_write(jaguar1_i2c_addr[0], 0xff, 0x0B);
331 		nvp6324_i2c_write(jaguar1_i2c_addr[0], 0x77, 0x8F);
332 		nvp6324_i2c_write(jaguar1_i2c_addr[0], 0xF7, 0x8F);
333 #endif
334 
335 }
336 
337 
338 /* For 0, 1, 5 */
nvp6324_dump_bank(int bank)339 void nvp6324_dump_bank(int bank)
340 {
341 	int i = 0;
342 	u32 ret = 0;
343 	printk("\n----------------- Bank%d Start ---------------------\n", bank);
344 	nvp6324_i2c_write(jaguar1_i2c_addr[0], 0xFF, bank);
345 	for (i = 0; i < 0xF6; i++) {
346 
347 		if (i == 0 || i % 16 == 0)
348 			printk("0x%02x-0x%02x: ", i, i + 15);
349 		ret = nvp6324_i2c_read(jaguar1_i2c_addr[0], i);
350 		printk("0x%02x ", ret);
351 		if ((i > 0) && ((i + 1) % 16) == 0)
352 			printk("\n");
353 	}
354 	printk("\n\t\t----------------- Bank%d End  ---------------------\n",
355 	       bank);
356 }
357 EXPORT_SYMBOL(nvp6324_dump_bank);
358 
nvp6324_read_bank_value(void)359 void nvp6324_read_bank_value(void)
360 {
361 
362 	u8 ret = 0;
363 	u8 i = 0;
364 
365 	nvp6324_i2c_write(jaguar1_i2c_addr[0], 0xFF, 0x00);
366 	for (i = 0; i < 0xF6; i++) {
367 		ret = nvp6324_i2c_read(jaguar1_i2c_addr[0], i);
368 		printk("Bank0[0x%2.2x] = 0x%2.2x \n", i, ret);
369 	}
370 	printk("\n");
371 
372 	nvp6324_i2c_write(jaguar1_i2c_addr[0], 0xFF, 0x01);
373 	for (i = 0; i < 0xF6; i++) {
374 		ret = nvp6324_i2c_read(jaguar1_i2c_addr[0], i);
375 		printk("Bank1[0x%2.2x] = 0x%2.2x \n", i, ret);
376 	}
377 	printk("\n");
378 
379 	nvp6324_i2c_write(jaguar1_i2c_addr[0], 0xFF, 0x05);
380 	for (i = 0; i < 0xF0; i++) {
381 		ret = nvp6324_i2c_read(jaguar1_i2c_addr[0], i);
382 		printk("Bank5[0x%2.2x] = 0x%2.2x \n", i, ret);
383 	}
384 }
385 
nvp6324_init(int Format)386 int  nvp6324_init(int Format)
387 {
388 	int ret = 0;
389 	int ch = 0;
390 	video_init_all sVideoall;
391 
392 	/* decoder count function */
393 	ret = check_decoder_count();
394 	if (ret == -1) {
395 		sensor_err("ERROR: could not find jaguar1 devices:%#x \n", ret);
396 		return ret;
397 	} else {
398 		sensor_dbg("check_decoder_count ok! ret=%d\n", ret);
399 	}
400 
401 	video_decoder_init();
402 #ifdef FMT_SETTING_SAMPLE
403 		for (ch = 0; ch < jaguar1_cnt; ch++) {
404 			sVideoall.ch_param[ch].ch = ch;
405 			sVideoall.ch_param[ch].format = Format;
406 			sVideoall.ch_param[ch].input = SINGLE_ENDED;
407 			sVideoall.ch_param[ch].interface = YUV_422;
408 		}
409 	vd_set_all(&sVideoall);
410 #endif
411 
412 	return 0;
413 }
414