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