• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /*
3  * A V4L2 driver for TW2866 YUV cameras.
4  *
5  * Copyright (c) 2017 by Allwinnertech Co., Ltd.  http://www.allwinnertech.com
6  *
7  * Authors:  Zhao Wei <zhaowei@allwinnertech.com>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License version 2 as
11  * published by the Free Software Foundation.
12  */
13 
14 
15 #include <linux/init.h>
16 #include <linux/module.h>
17 #include <linux/slab.h>
18 #include <linux/i2c.h>
19 #include <linux/delay.h>
20 #include <linux/videodev2.h>
21 #include <linux/clk.h>
22 #include <media/v4l2-device.h>
23 #include <media/v4l2-mediabus.h>
24 #include <linux/io.h>
25 
26 #include "camera.h"
27 #include "sensor_helper.h"
28 
29 MODULE_AUTHOR("zw");
30 MODULE_DESCRIPTION("A low-level driver for TW2866 sensors");
31 MODULE_LICENSE("GPL");
32 
33 #define MCLK              (24*1000*1000)
34 #define CLK_POL           V4L2_MBUS_PCLK_SAMPLE_FALLING
35 #define V4L2_IDENT_SENSOR 0xc8
36 
37 /*
38  * Our nominal (default) frame rate.
39  */
40 #define SENSOR_FRAME_RATE 30
41 
42 /*
43  * The TW2866 sits on i2c with ID 0x50
44  */
45 #define I2C_ADDR 0x50 /* tw2866 work when CCI in 100k speed */
46 #define SENSOR_NAME "tw2866"
47 
48 
49 #if 0
50 static struct regval_list read_reg[] = {
51 	{0x00, 0x00},
52 	{0x01, 0x00},
53 	{0x02, 0x00},
54 	{0x03, 0x00},
55 	{0xFA, 0x00},		/*output clock, base of pclk, 1ch*d1 = 27m */
56 	{0xFB, 0x00},
57 	{0xFC, 0x00},
58 	{0x9C, 0x00},		/*A0 */
59 	{0x9E, 0x00},
60 	{0xF9, 0x00},		/*Video misc */
61 	{0xAA, 0x00},		/*Video AGC */
62 	{0x6A, 0x00},		/*CLKPO2/CLKNO2 off */
63 	{0x6B, 0x00},		/*CLKPO3/CLKNO3 off */
64 	{0x6C, 0x00},		/*CLKPO4/CLKNO4 off */
65 	{0x60, 0x00},		/*0x15/0x05�� */
66 	{0x61, 0x00},
67 	{0xca, 0x00},		/*chmd: 0=1ch 1=2ch 2=4ch */
68 	{0xcd, 0x00},		/*1st */
69 	{0x42, 0x00},		/*testpattern 75%color bar */
70 };
71 
72 #endif
73 
74 #if 0
75 static struct regval_list reg_d1_1ch[] = {
76 	{0x00, 0x00},
77 	{0x01, 0x00},
78 	{0x02, 0x64},
79 	{0x03, 0x11},
80 	{0xFA, 0x40},		/*output clock, base of pclk, 1ch*d1 = 27m */
81 	{0xFB, 0x2F},
82 	{0xFC, 0xFF},
83 	{0x9C, 0x20},		/*A0 */
84 	{0x9E, 0x52},
85 	{0xF9, 0x11},		/*Video misc */
86 	{0xAA, 0x00},		/*Video AGC */
87 	{0x6A, 0x0f},		/*CLKPO2/CLKNO2 off */
88 	{0x6B, 0x0f},		/*CLKPO3/CLKNO3 off */
89 	{0x6C, 0x0f},		/*CLKPO4/CLKNO4 off */
90 	{0x60, 0x15},		/*0x15/0x05*/
91 	{0x61, 0x03},
92 	{0xca, 0x00},		/*chmd: 0=1ch 1=2ch 2=4ch */
93 	{0xcd, 0xe4},		/*1st */
94 	{0x5b, 0x11},		/*pad drive set */
95 };
96 #endif
97 
98 #if 0
99 static struct regval_list reg_d1_2ch[] = {
100 	{0x00, 0x00},
101 	{0x01, 0x00},
102 	{0x02, 0x64},
103 	{0x03, 0x11},
104 	{0xFA, 0x45},		/*0x45 *//*[7]:v-scale output clock, base of pclk, 2ch*d1 = 54m */
105 	{0xFB, 0x2F},
106 	{0xFC, 0xFF},
107 	{0x9C, 0x20},		/*A0 */
108 	{0x9E, 0x52},
109 	{0xF9, 0x11},		/*Video misc */
110 	{0xAA, 0x00},		/*Video AGC */
111 	{0xca, 0x01},		/*chmd: 0=1ch 1=2ch 2=4ch */
112 	{0xcd, 0xe4},		/*1st */
113 	{0xcc, 0x39},		/*2nd */
114 	{0xcb, 0x00},		/*4ch cif */
115 	{0x60, 0x15},		/*0x15/0x05*/
116 	{0x61, 0x03},
117 	{0x5b, 0x00},		/*pad drive set */
118 };
119 #endif
120 
121 #if 1
122 static struct regval_list reg_d1_4ch[] = {
123 	{0x00, 0x00},
124 	{0x01, 0x00},
125 	{0x02, 0x64},
126 	{0x03, 0x11},
127 	{0xFA, 0x4a},		/*output clock, base of pclk, 4ch*cif = 54m  4ch*d1 = 108m */
128 	{0xFB, 0x2F},
129 	{0xFC, 0xFF},
130 	{0x9C, 0x20},		/*A0 */
131 	{0x9E, 0x52},
132 	{0x6A, 0x05},
133 	{0x6B, 0x05},
134 	{0x6C, 0x05},
135 	{0xF9, 0x11},		/*Video misc */
136 	{0xAA, 0x00},		/*Video AGC */
137 	{0xca, 0x02},		/*chmd: 0=1ch 1=2ch 2=4ch */
138 	{0xcd, 0xe4},		/*1st */
139 	{0xcc, 0x39},		/*2nd */
140 	{0xcb, 0x00},		/*4ch cif */
141 	{0x60, 0x15},		/*0x15/0x05*/
142 	{0x61, 0x03},
143 	{REG_DLY, 0x20},
144 	{0x5b, 0xFF},		/*pad drive set */
145 };
146 #endif
147 
148 #if 0
149 static struct regval_list reg_cif_4ch[] = {
150 	/*CSI_MODE==CSI_MODE_TW2866_4CH_CIF */
151 	{0x00, 0x00},
152 	{0x01, 0x00},
153 	{0x02, 0x64},
154 	{0x03, 0x11},
155 	{0xFA, 0x45},		/*output clock, base of pclk, 4ch*cif = 54m  4ch*cif = 54m */
156 	{0xFB, 0x2F},
157 	{0xFC, 0xFF},
158 	{0x9C, 0x20},		/*A0 */
159 	{0x9E, 0x52},
160 	{0xF9, 0x11},		/*Video misc */
161 	{0xAA, 0x00},		/*Video AGC */
162 	{0xca, 0x00},		/*chmd: 0=1ch or 4ch-cif 1=2ch 2=4ch-d1 */
163 	{0xcd, 0xe4},		/*1st */
164 	{0xcc, 0x39},		/*2nd */
165 	{0xcb, 0x01},		/*4ch cif */
166 	{0x60, 0x17},		/*0x37/0x15/0x05*/
167 	{0x61, 0x03},
168 	{0x5b, 0x11},		/*pad drive set */
169 	{0x9f, 0x00},		/*p clock delay 7ns */
170 };
171 #endif
172 
sensor_s_sw_stby(struct v4l2_subdev * sd,int on_off)173 static int sensor_s_sw_stby(struct v4l2_subdev *sd, int on_off)
174 {
175 	if (on_off)
176 		vin_gpio_write(sd, RESET, CSI_GPIO_LOW);
177 	else
178 		vin_gpio_write(sd, RESET, CSI_GPIO_HIGH);
179 	return 0;
180 }
181 
sensor_power(struct v4l2_subdev * sd,int on)182 static int sensor_power(struct v4l2_subdev *sd, int on)
183 {
184 	switch (on) {
185 	case STBY_ON:
186 		sensor_dbg("CSI_SUBDEV_STBY_ON!\n");
187 		sensor_s_sw_stby(sd, ON);
188 		break;
189 	case STBY_OFF:
190 		sensor_dbg("CSI_SUBDEV_STBY_OFF!\n");
191 		sensor_s_sw_stby(sd, OFF);
192 		break;
193 	case PWR_ON:
194 		sensor_dbg("CSI_SUBDEV_PWR_ON!\n");
195 		sensor_print("CSI_SUBDEV_PWR_ON!\n");
196 		cci_lock(sd);
197 		vin_gpio_set_status(sd, PWDN, 1);
198 		vin_gpio_set_status(sd, RESET, 1);
199 		vin_gpio_write(sd, PWDN, CSI_GPIO_HIGH);
200 		vin_gpio_write(sd, RESET, CSI_GPIO_LOW);
201 		usleep_range(1000, 1200);
202 		vin_set_mclk_freq(sd, MCLK);
203 		vin_set_mclk(sd, ON);
204 		usleep_range(10000, 12000);
205 		vin_gpio_write(sd, POWER_EN, CSI_GPIO_HIGH);
206 		vin_set_pmu_channel(sd, IOVDD, ON);
207 		vin_set_pmu_channel(sd, AVDD, ON);
208 		vin_set_pmu_channel(sd, DVDD, ON);
209 		vin_set_pmu_channel(sd, AFVDD, ON);
210 		vin_gpio_write(sd, PWDN, CSI_GPIO_LOW);
211 		usleep_range(10000, 12000);
212 		vin_gpio_write(sd, RESET, CSI_GPIO_HIGH);
213 		usleep_range(30000, 31000);
214 		cci_unlock(sd);
215 		break;
216 	case PWR_OFF:
217 		sensor_dbg("CSI_SUBDEV_PWR_OFF!\n");
218 		sensor_print("CSI_SUBDEV_PWR_OFF!\n");
219 		cci_lock(sd);
220 		vin_set_mclk(sd, OFF);
221 		vin_gpio_write(sd, POWER_EN, CSI_GPIO_LOW);
222 		vin_set_pmu_channel(sd, AFVDD, OFF);
223 		vin_set_pmu_channel(sd, DVDD, OFF);
224 		vin_set_pmu_channel(sd, AVDD, OFF);
225 		vin_set_pmu_channel(sd, IOVDD, OFF);
226 		usleep_range(10000, 12000);
227 		vin_gpio_write(sd, PWDN, CSI_GPIO_HIGH);
228 		vin_gpio_write(sd, RESET, CSI_GPIO_LOW);
229 		vin_gpio_set_status(sd, RESET, 0);
230 		vin_gpio_set_status(sd, PWDN, 0);
231 		cci_unlock(sd);
232 		break;
233 	default:
234 		return -EINVAL;
235 	}
236 
237 	return 0;
238 }
239 
sensor_reset(struct v4l2_subdev * sd,u32 val)240 static int sensor_reset(struct v4l2_subdev *sd, u32 val)
241 {
242 	vin_gpio_write(sd, RESET, CSI_GPIO_LOW);
243 	usleep_range(5000, 6000);
244 	vin_gpio_write(sd, RESET, CSI_GPIO_HIGH);
245 	usleep_range(5000, 6000);
246 	return 0;
247 }
248 
sensor_detect(struct v4l2_subdev * sd)249 static int sensor_detect(struct v4l2_subdev *sd)
250 {
251 	data_type rdval = 0;
252 	int cnt = 0;
253 
254 	sensor_read(sd, 0xff, &rdval);
255 	sensor_print("V4L2_IDENT_SENSOR = 0x%x\n", rdval);
256 
257 	while ((rdval != V4L2_IDENT_SENSOR) && (cnt < 5)) {
258 		sensor_read(sd, 0xff, &rdval);
259 		sensor_print("retry = %d, V4L2_IDENT_SENSOR = %x\n", cnt, rdval);
260 		cnt++;
261 	}
262 
263 	if (rdval != V4L2_IDENT_SENSOR)
264 		return -ENODEV;
265 
266 	return 0;
267 }
268 
sensor_init(struct v4l2_subdev * sd,u32 val)269 static int sensor_init(struct v4l2_subdev *sd, u32 val)
270 {
271 	int ret;
272 	struct sensor_info *info = to_state(sd);
273 
274 	sensor_dbg("sensor_init\n");
275 
276 	/*Make sure it is a target sensor */
277 	ret = sensor_detect(sd);
278 	if (ret) {
279 		sensor_err("chip found is not an target chip.\n");
280 		return ret;
281 	}
282 
283 	info->focus_status = 0;
284 	info->low_speed = 0;
285 	info->width = VGA_WIDTH;
286 	info->height = VGA_HEIGHT;
287 	info->hflip = 0;
288 	info->vflip = 0;
289 
290 	info->tpf.numerator = 1;
291 	info->tpf.denominator = 30;	/* 30fps */
292 
293 	info->preview_first_flag = 1;
294 	return 0;
295 }
296 
sensor_ioctl(struct v4l2_subdev * sd,unsigned int cmd,void * arg)297 static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
298 {
299 	int ret = 0;
300 	struct sensor_info *info = to_state(sd);
301 
302 	switch (cmd) {
303 	case GET_CURRENT_WIN_CFG:
304 		if (info->current_wins != NULL) {
305 			memcpy(arg,
306 			       info->current_wins,
307 			       sizeof(struct sensor_win_size));
308 			ret = 0;
309 		} else {
310 			sensor_err("empty wins!\n");
311 			ret = -1;
312 		}
313 		break;
314 	case SET_FPS:
315 		break;
316 	case VIDIOC_VIN_SENSOR_CFG_REQ:
317 		sensor_cfg_req(sd, (struct sensor_config *)arg);
318 		break;
319 	default:
320 		return -EINVAL;
321 	}
322 	return ret;
323 }
324 
325 /*
326  * Store information about the video data format.
327  */
328 static struct sensor_format_struct sensor_formats[] = {
329 	{
330 	.desc = "BT656 4CH",
331 	.mbus_code = MEDIA_BUS_FMT_UYVY8_2X8,
332 	.regs = NULL,
333 	.regs_size = 0,
334 	.bpp = 2,
335 	},
336 };
337 #define N_FMTS ARRAY_SIZE(sensor_formats)
338 
339 /*
340  * Then there is the issue of window sizes.  Try to capture the info here.
341  */
342 
343 static struct sensor_win_size sensor_win_sizes[] = {
344 	{
345 	 .width = 704,
346 	 .height = 576,
347 	 .hoffset = 0,
348 	 .voffset = 0,
349 	 .regs = reg_d1_4ch,
350 	 .regs_size = ARRAY_SIZE(reg_d1_4ch),
351 	 .set_size = NULL,
352 	 },
353 };
354 
355 #define N_WIN_SIZES (ARRAY_SIZE(sensor_win_sizes))
356 
sensor_g_mbus_config(struct v4l2_subdev * sd,unsigned int pad,struct v4l2_mbus_config * cfg)357 static int sensor_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad,
358 				struct v4l2_mbus_config *cfg)
359 {
360 	cfg->type = V4L2_MBUS_BT656;
361 	cfg->flags = CLK_POL | CSI_CH_0 | CSI_CH_1 | CSI_CH_2 | CSI_CH_3;
362 	//cfg->flags = CLK_POL | CSI_CH_0;
363 	return 0;
364 }
365 
sensor_g_ctrl(struct v4l2_ctrl * ctrl)366 static int sensor_g_ctrl(struct v4l2_ctrl *ctrl)
367 {
368 	return -EINVAL;
369 }
370 
sensor_s_ctrl(struct v4l2_ctrl * ctrl)371 static int sensor_s_ctrl(struct v4l2_ctrl *ctrl)
372 {
373 	return -EINVAL;
374 }
375 
sensor_reg_init(struct sensor_info * info)376 static int sensor_reg_init(struct sensor_info *info)
377 {
378 	struct v4l2_subdev *sd = &info->sd;
379 	struct sensor_format_struct *sensor_fmt = info->fmt;
380 	struct sensor_win_size *wsize = info->current_wins;
381 
382 	sensor_dbg("sensor_reg_init\n");
383 
384 	sensor_write_array(sd, sensor_fmt->regs, sensor_fmt->regs_size);
385 
386 	if (wsize->regs)
387 		sensor_write_array(sd, wsize->regs, wsize->regs_size);
388 
389 	if (wsize->set_size)
390 		wsize->set_size(sd);
391 
392 	info->fmt = sensor_fmt;
393 	info->width = wsize->width;
394 	info->height = wsize->height;
395 
396 	return 0;
397 }
398 
sensor_s_stream(struct v4l2_subdev * sd,int enable)399 static int sensor_s_stream(struct v4l2_subdev *sd, int enable)
400 {
401 	struct sensor_info *info = to_state(sd);
402 
403 	sensor_print("%s on = %d, %d*%d %x\n", __func__, enable,
404 		  info->current_wins->width,
405 		  info->current_wins->height, info->fmt->mbus_code);
406 
407 	if (!enable)
408 		return 0;
409 	return sensor_reg_init(info);
410 }
411 
412 /* ----------------------------------------------------------------------- */
413 static const struct v4l2_ctrl_ops sensor_ctrl_ops = {
414 	.g_volatile_ctrl = sensor_g_ctrl,
415 	.s_ctrl = sensor_s_ctrl,
416 };
417 
418 static const struct v4l2_subdev_core_ops sensor_core_ops = {
419 	.s_power = sensor_power,
420 	.ioctl = sensor_ioctl,
421 };
422 
423 static const struct v4l2_subdev_video_ops sensor_video_ops = {
424 	.s_parm = sensor_s_parm,
425 	.g_parm = sensor_g_parm,
426 	.s_stream = sensor_s_stream,
427 };
428 
429 static const struct v4l2_subdev_pad_ops sensor_pad_ops = {
430 	.enum_mbus_code = sensor_enum_mbus_code,
431 	.enum_frame_size = sensor_enum_frame_size,
432 	.get_fmt = sensor_get_fmt,
433 	.set_fmt = sensor_set_fmt,
434 	.get_mbus_config = sensor_g_mbus_config,
435 };
436 
437 static const struct v4l2_subdev_ops sensor_ops = {
438 	.core = &sensor_core_ops,
439 	.video = &sensor_video_ops,
440 	.pad = &sensor_pad_ops,
441 };
442 
443 
444 /* ----------------------------------------------------------------------- */
445 static struct cci_driver cci_drv = {
446 	.name = SENSOR_NAME,
447 	.addr_width = CCI_BITS_8,
448 	.data_width = CCI_BITS_8,
449 };
450 
sensor_init_controls(struct v4l2_subdev * sd,const struct v4l2_ctrl_ops * ops)451 static int sensor_init_controls(struct v4l2_subdev *sd, const struct v4l2_ctrl_ops *ops)
452 {
453 	struct sensor_info *info = to_state(sd);
454 	struct v4l2_ctrl_handler *handler = &info->handler;
455 	struct v4l2_ctrl *ctrl;
456 	int ret = 0;
457 
458 	v4l2_ctrl_handler_init(handler, 2);
459 
460 	v4l2_ctrl_new_std(handler, ops, V4L2_CID_GAIN, 1 * 1600,
461 			      256 * 1600, 1, 1 * 1600);
462 	ctrl = v4l2_ctrl_new_std(handler, ops, V4L2_CID_EXPOSURE, 0,
463 			      65536 * 16, 1, 0);
464 	if (ctrl != NULL)
465 		ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
466 
467 	if (handler->error) {
468 		ret = handler->error;
469 		v4l2_ctrl_handler_free(handler);
470 	}
471 
472 	sd->ctrl_handler = handler;
473 
474 	return ret;
475 }
476 
477 
sensor_probe(struct i2c_client * client,const struct i2c_device_id * id)478 static int sensor_probe(struct i2c_client *client,
479 			const struct i2c_device_id *id)
480 {
481 	struct v4l2_subdev *sd;
482 	struct sensor_info *info;
483 
484 	info = kzalloc(sizeof(struct sensor_info), GFP_KERNEL);
485 	if (info == NULL)
486 		return -ENOMEM;
487 	sd = &info->sd;
488 	cci_dev_probe_helper(sd, client, &sensor_ops, &cci_drv);
489 	sensor_init_controls(sd, &sensor_ctrl_ops);
490 	mutex_init(&info->lock);
491 #ifdef CONFIG_SAME_I2C
492 	info->sensor_i2c_addr = I2C_ADDR >> 1;
493 #endif
494 	info->fmt = &sensor_formats[0];
495 	info->fmt_pt = &sensor_formats[0];
496 	info->win_pt = &sensor_win_sizes[0];
497 	info->fmt_num = N_FMTS;
498 	info->win_size_num = N_WIN_SIZES;
499 	info->sensor_field = V4L2_FIELD_INTERLACED;
500 	return 0;
501 }
502 
sensor_remove(struct i2c_client * client)503 static int sensor_remove(struct i2c_client *client)
504 {
505 	struct v4l2_subdev *sd;
506 
507 	sd = cci_dev_remove_helper(client, &cci_drv);
508 	kfree(to_state(sd));
509 	return 0;
510 }
511 
512 static const struct i2c_device_id sensor_id[] = {
513 	{SENSOR_NAME, 0},
514 	{}
515 };
516 
517 MODULE_DEVICE_TABLE(i2c, sensor_id);
518 
519 static struct i2c_driver sensor_driver = {
520 	.driver = {
521 		   .owner = THIS_MODULE,
522 		   .name = SENSOR_NAME,
523 		   },
524 	.probe = sensor_probe,
525 	.remove = sensor_remove,
526 	.id_table = sensor_id,
527 };
init_sensor(void)528 static __init int init_sensor(void)
529 {
530 	return cci_dev_init_helper(&sensor_driver);
531 }
532 
exit_sensor(void)533 static __exit void exit_sensor(void)
534 {
535 	cci_dev_exit_helper(&sensor_driver);
536 }
537 
538 module_init(init_sensor);
539 module_exit(exit_sensor);
540