xref: /openbmc/linux/drivers/media/i2c/bt819.c (revision e1277110)
1 /*
2  *  bt819 - BT819A VideoStream Decoder (Rockwell Part)
3  *
4  * Copyright (C) 1999 Mike Bernson <mike@mlb.org>
5  * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
6  *
7  * Modifications for LML33/DC10plus unified driver
8  * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
9  *
10  * Changes by Ronald Bultje <rbultje@ronald.bitfreak.net>
11  *    - moved over to linux>=2.4.x i2c protocol (9/9/2002)
12  *
13  * This code was modify/ported from the saa7111 driver written
14  * by Dave Perks.
15  *
16  * This program is free software; you can redistribute it and/or modify
17  * it under the terms of the GNU General Public License as published by
18  * the Free Software Foundation; either version 2 of the License, or
19  * (at your option) any later version.
20  *
21  * This program is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24  * GNU General Public License for more details.
25  *
26  * You should have received a copy of the GNU General Public License
27  * along with this program; if not, write to the Free Software
28  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29  */
30 
31 #include <linux/module.h>
32 #include <linux/types.h>
33 #include <linux/ioctl.h>
34 #include <linux/delay.h>
35 #include <linux/i2c.h>
36 #include <linux/videodev2.h>
37 #include <linux/slab.h>
38 #include <media/v4l2-device.h>
39 #include <media/v4l2-ctrls.h>
40 #include <media/bt819.h>
41 
42 MODULE_DESCRIPTION("Brooktree-819 video decoder driver");
43 MODULE_AUTHOR("Mike Bernson & Dave Perks");
44 MODULE_LICENSE("GPL");
45 
46 static int debug;
47 module_param(debug, int, 0);
48 MODULE_PARM_DESC(debug, "Debug level (0-1)");
49 
50 
51 /* ----------------------------------------------------------------------- */
52 
53 struct bt819 {
54 	struct v4l2_subdev sd;
55 	struct v4l2_ctrl_handler hdl;
56 	unsigned char reg[32];
57 
58 	v4l2_std_id norm;
59 	int input;
60 	int enable;
61 };
62 
63 static inline struct bt819 *to_bt819(struct v4l2_subdev *sd)
64 {
65 	return container_of(sd, struct bt819, sd);
66 }
67 
68 static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
69 {
70 	return &container_of(ctrl->handler, struct bt819, hdl)->sd;
71 }
72 
73 struct timing {
74 	int hactive;
75 	int hdelay;
76 	int vactive;
77 	int vdelay;
78 	int hscale;
79 	int vscale;
80 };
81 
82 /* for values, see the bt819 datasheet */
83 static struct timing timing_data[] = {
84 	{864 - 24, 20, 625 - 2, 1, 0x0504, 0x0000},
85 	{858 - 24, 20, 525 - 2, 1, 0x00f8, 0x0000},
86 };
87 
88 /* ----------------------------------------------------------------------- */
89 
90 static inline int bt819_write(struct bt819 *decoder, u8 reg, u8 value)
91 {
92 	struct i2c_client *client = v4l2_get_subdevdata(&decoder->sd);
93 
94 	decoder->reg[reg] = value;
95 	return i2c_smbus_write_byte_data(client, reg, value);
96 }
97 
98 static inline int bt819_setbit(struct bt819 *decoder, u8 reg, u8 bit, u8 value)
99 {
100 	return bt819_write(decoder, reg,
101 		(decoder->reg[reg] & ~(1 << bit)) | (value ? (1 << bit) : 0));
102 }
103 
104 static int bt819_write_block(struct bt819 *decoder, const u8 *data, unsigned int len)
105 {
106 	struct i2c_client *client = v4l2_get_subdevdata(&decoder->sd);
107 	int ret = -1;
108 	u8 reg;
109 
110 	/* the bt819 has an autoincrement function, use it if
111 	 * the adapter understands raw I2C */
112 	if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
113 		/* do raw I2C, not smbus compatible */
114 		u8 block_data[32];
115 		int block_len;
116 
117 		while (len >= 2) {
118 			block_len = 0;
119 			block_data[block_len++] = reg = data[0];
120 			do {
121 				block_data[block_len++] =
122 				    decoder->reg[reg++] = data[1];
123 				len -= 2;
124 				data += 2;
125 			} while (len >= 2 && data[0] == reg && block_len < 32);
126 			ret = i2c_master_send(client, block_data, block_len);
127 			if (ret < 0)
128 				break;
129 		}
130 	} else {
131 		/* do some slow I2C emulation kind of thing */
132 		while (len >= 2) {
133 			reg = *data++;
134 			ret = bt819_write(decoder, reg, *data++);
135 			if (ret < 0)
136 				break;
137 			len -= 2;
138 		}
139 	}
140 
141 	return ret;
142 }
143 
144 static inline int bt819_read(struct bt819 *decoder, u8 reg)
145 {
146 	struct i2c_client *client = v4l2_get_subdevdata(&decoder->sd);
147 
148 	return i2c_smbus_read_byte_data(client, reg);
149 }
150 
151 static int bt819_init(struct v4l2_subdev *sd)
152 {
153 	static unsigned char init[] = {
154 		/*0x1f, 0x00,*/     /* Reset */
155 		0x01, 0x59,	/* 0x01 input format */
156 		0x02, 0x00,	/* 0x02 temporal decimation */
157 		0x03, 0x12,	/* 0x03 Cropping msb */
158 		0x04, 0x16,	/* 0x04 Vertical Delay, lsb */
159 		0x05, 0xe0,	/* 0x05 Vertical Active lsb */
160 		0x06, 0x80,	/* 0x06 Horizontal Delay lsb */
161 		0x07, 0xd0,	/* 0x07 Horizontal Active lsb */
162 		0x08, 0x00,	/* 0x08 Horizontal Scaling msb */
163 		0x09, 0xf8,	/* 0x09 Horizontal Scaling lsb */
164 		0x0a, 0x00,	/* 0x0a Brightness control */
165 		0x0b, 0x30,	/* 0x0b Miscellaneous control */
166 		0x0c, 0xd8,	/* 0x0c Luma Gain lsb */
167 		0x0d, 0xfe,	/* 0x0d Chroma Gain (U) lsb */
168 		0x0e, 0xb4,	/* 0x0e Chroma Gain (V) msb */
169 		0x0f, 0x00,	/* 0x0f Hue control */
170 		0x12, 0x04,	/* 0x12 Output Format */
171 		0x13, 0x20,	/* 0x13 Vertial Scaling msb 0x00
172 					   chroma comb OFF, line drop scaling, interlace scaling
173 					   BUG? Why does turning the chroma comb on fuck up color?
174 					   Bug in the bt819 stepping on my board?
175 					*/
176 		0x14, 0x00,	/* 0x14 Vertial Scaling lsb */
177 		0x16, 0x07,	/* 0x16 Video Timing Polarity
178 					   ACTIVE=active low
179 					   FIELD: high=odd,
180 					   vreset=active high,
181 					   hreset=active high */
182 		0x18, 0x68,	/* 0x18 AGC Delay */
183 		0x19, 0x5d,	/* 0x19 Burst Gate Delay */
184 		0x1a, 0x80,	/* 0x1a ADC Interface */
185 	};
186 
187 	struct bt819 *decoder = to_bt819(sd);
188 	struct timing *timing = &timing_data[(decoder->norm & V4L2_STD_525_60) ? 1 : 0];
189 
190 	init[0x03 * 2 - 1] =
191 	    (((timing->vdelay >> 8) & 0x03) << 6) |
192 	    (((timing->vactive >> 8) & 0x03) << 4) |
193 	    (((timing->hdelay >> 8) & 0x03) << 2) |
194 	    ((timing->hactive >> 8) & 0x03);
195 	init[0x04 * 2 - 1] = timing->vdelay & 0xff;
196 	init[0x05 * 2 - 1] = timing->vactive & 0xff;
197 	init[0x06 * 2 - 1] = timing->hdelay & 0xff;
198 	init[0x07 * 2 - 1] = timing->hactive & 0xff;
199 	init[0x08 * 2 - 1] = timing->hscale >> 8;
200 	init[0x09 * 2 - 1] = timing->hscale & 0xff;
201 	/* 0x15 in array is address 0x19 */
202 	init[0x15 * 2 - 1] = (decoder->norm & V4L2_STD_625_50) ? 115 : 93;	/* Chroma burst delay */
203 	/* reset */
204 	bt819_write(decoder, 0x1f, 0x00);
205 	mdelay(1);
206 
207 	/* init */
208 	return bt819_write_block(decoder, init, sizeof(init));
209 }
210 
211 /* ----------------------------------------------------------------------- */
212 
213 static int bt819_status(struct v4l2_subdev *sd, u32 *pstatus, v4l2_std_id *pstd)
214 {
215 	struct bt819 *decoder = to_bt819(sd);
216 	int status = bt819_read(decoder, 0x00);
217 	int res = V4L2_IN_ST_NO_SIGNAL;
218 	v4l2_std_id std;
219 
220 	if ((status & 0x80))
221 		res = 0;
222 
223 	if ((status & 0x10))
224 		std = V4L2_STD_PAL;
225 	else
226 		std = V4L2_STD_NTSC;
227 	if (pstd)
228 		*pstd = std;
229 	if (pstatus)
230 		*pstatus = res;
231 
232 	v4l2_dbg(1, debug, sd, "get status %x\n", status);
233 	return 0;
234 }
235 
236 static int bt819_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
237 {
238 	return bt819_status(sd, NULL, std);
239 }
240 
241 static int bt819_g_input_status(struct v4l2_subdev *sd, u32 *status)
242 {
243 	return bt819_status(sd, status, NULL);
244 }
245 
246 static int bt819_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
247 {
248 	struct bt819 *decoder = to_bt819(sd);
249 	struct timing *timing = NULL;
250 
251 	v4l2_dbg(1, debug, sd, "set norm %llx\n", (unsigned long long)std);
252 
253 	if (sd->v4l2_dev == NULL || sd->v4l2_dev->notify == NULL)
254 		v4l2_err(sd, "no notify found!\n");
255 
256 	if (std & V4L2_STD_NTSC) {
257 		v4l2_subdev_notify(sd, BT819_FIFO_RESET_LOW, NULL);
258 		bt819_setbit(decoder, 0x01, 0, 1);
259 		bt819_setbit(decoder, 0x01, 1, 0);
260 		bt819_setbit(decoder, 0x01, 5, 0);
261 		bt819_write(decoder, 0x18, 0x68);
262 		bt819_write(decoder, 0x19, 0x5d);
263 		/* bt819_setbit(decoder, 0x1a,  5, 1); */
264 		timing = &timing_data[1];
265 	} else if (std & V4L2_STD_PAL) {
266 		v4l2_subdev_notify(sd, BT819_FIFO_RESET_LOW, NULL);
267 		bt819_setbit(decoder, 0x01, 0, 1);
268 		bt819_setbit(decoder, 0x01, 1, 1);
269 		bt819_setbit(decoder, 0x01, 5, 1);
270 		bt819_write(decoder, 0x18, 0x7f);
271 		bt819_write(decoder, 0x19, 0x72);
272 		/* bt819_setbit(decoder, 0x1a,  5, 0); */
273 		timing = &timing_data[0];
274 	} else {
275 		v4l2_dbg(1, debug, sd, "unsupported norm %llx\n",
276 				(unsigned long long)std);
277 		return -EINVAL;
278 	}
279 	bt819_write(decoder, 0x03,
280 			(((timing->vdelay >> 8) & 0x03) << 6) |
281 			(((timing->vactive >> 8) & 0x03) << 4) |
282 			(((timing->hdelay >> 8) & 0x03) << 2) |
283 			((timing->hactive >> 8) & 0x03));
284 	bt819_write(decoder, 0x04, timing->vdelay & 0xff);
285 	bt819_write(decoder, 0x05, timing->vactive & 0xff);
286 	bt819_write(decoder, 0x06, timing->hdelay & 0xff);
287 	bt819_write(decoder, 0x07, timing->hactive & 0xff);
288 	bt819_write(decoder, 0x08, (timing->hscale >> 8) & 0xff);
289 	bt819_write(decoder, 0x09, timing->hscale & 0xff);
290 	decoder->norm = std;
291 	v4l2_subdev_notify(sd, BT819_FIFO_RESET_HIGH, NULL);
292 	return 0;
293 }
294 
295 static int bt819_s_routing(struct v4l2_subdev *sd,
296 			   u32 input, u32 output, u32 config)
297 {
298 	struct bt819 *decoder = to_bt819(sd);
299 
300 	v4l2_dbg(1, debug, sd, "set input %x\n", input);
301 
302 	if (input > 7)
303 		return -EINVAL;
304 
305 	if (sd->v4l2_dev == NULL || sd->v4l2_dev->notify == NULL)
306 		v4l2_err(sd, "no notify found!\n");
307 
308 	if (decoder->input != input) {
309 		v4l2_subdev_notify(sd, BT819_FIFO_RESET_LOW, NULL);
310 		decoder->input = input;
311 		/* select mode */
312 		if (decoder->input == 0) {
313 			bt819_setbit(decoder, 0x0b, 6, 0);
314 			bt819_setbit(decoder, 0x1a, 1, 1);
315 		} else {
316 			bt819_setbit(decoder, 0x0b, 6, 1);
317 			bt819_setbit(decoder, 0x1a, 1, 0);
318 		}
319 		v4l2_subdev_notify(sd, BT819_FIFO_RESET_HIGH, NULL);
320 	}
321 	return 0;
322 }
323 
324 static int bt819_s_stream(struct v4l2_subdev *sd, int enable)
325 {
326 	struct bt819 *decoder = to_bt819(sd);
327 
328 	v4l2_dbg(1, debug, sd, "enable output %x\n", enable);
329 
330 	if (decoder->enable != enable) {
331 		decoder->enable = enable;
332 		bt819_setbit(decoder, 0x16, 7, !enable);
333 	}
334 	return 0;
335 }
336 
337 static int bt819_s_ctrl(struct v4l2_ctrl *ctrl)
338 {
339 	struct v4l2_subdev *sd = to_sd(ctrl);
340 	struct bt819 *decoder = to_bt819(sd);
341 	int temp;
342 
343 	switch (ctrl->id) {
344 	case V4L2_CID_BRIGHTNESS:
345 		bt819_write(decoder, 0x0a, ctrl->val);
346 		break;
347 
348 	case V4L2_CID_CONTRAST:
349 		bt819_write(decoder, 0x0c, ctrl->val & 0xff);
350 		bt819_setbit(decoder, 0x0b, 2, ((ctrl->val >> 8) & 0x01));
351 		break;
352 
353 	case V4L2_CID_SATURATION:
354 		bt819_write(decoder, 0x0d, (ctrl->val >> 7) & 0xff);
355 		bt819_setbit(decoder, 0x0b, 1, ((ctrl->val >> 15) & 0x01));
356 
357 		/* Ratio between U gain and V gain must stay the same as
358 		   the ratio between the default U and V gain values. */
359 		temp = (ctrl->val * 180) / 254;
360 		bt819_write(decoder, 0x0e, (temp >> 7) & 0xff);
361 		bt819_setbit(decoder, 0x0b, 0, (temp >> 15) & 0x01);
362 		break;
363 
364 	case V4L2_CID_HUE:
365 		bt819_write(decoder, 0x0f, ctrl->val);
366 		break;
367 
368 	default:
369 		return -EINVAL;
370 	}
371 	return 0;
372 }
373 
374 /* ----------------------------------------------------------------------- */
375 
376 static const struct v4l2_ctrl_ops bt819_ctrl_ops = {
377 	.s_ctrl = bt819_s_ctrl,
378 };
379 
380 static const struct v4l2_subdev_core_ops bt819_core_ops = {
381 	.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
382 	.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
383 	.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
384 	.g_ctrl = v4l2_subdev_g_ctrl,
385 	.s_ctrl = v4l2_subdev_s_ctrl,
386 	.queryctrl = v4l2_subdev_queryctrl,
387 	.querymenu = v4l2_subdev_querymenu,
388 	.s_std = bt819_s_std,
389 };
390 
391 static const struct v4l2_subdev_video_ops bt819_video_ops = {
392 	.s_routing = bt819_s_routing,
393 	.s_stream = bt819_s_stream,
394 	.querystd = bt819_querystd,
395 	.g_input_status = bt819_g_input_status,
396 };
397 
398 static const struct v4l2_subdev_ops bt819_ops = {
399 	.core = &bt819_core_ops,
400 	.video = &bt819_video_ops,
401 };
402 
403 /* ----------------------------------------------------------------------- */
404 
405 static int bt819_probe(struct i2c_client *client,
406 			const struct i2c_device_id *id)
407 {
408 	int i, ver;
409 	struct bt819 *decoder;
410 	struct v4l2_subdev *sd;
411 	const char *name;
412 
413 	/* Check if the adapter supports the needed features */
414 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
415 		return -ENODEV;
416 
417 	decoder = devm_kzalloc(&client->dev, sizeof(*decoder), GFP_KERNEL);
418 	if (decoder == NULL)
419 		return -ENOMEM;
420 	sd = &decoder->sd;
421 	v4l2_i2c_subdev_init(sd, client, &bt819_ops);
422 
423 	ver = bt819_read(decoder, 0x17);
424 	switch (ver & 0xf0) {
425 	case 0x70:
426 		name = "bt819a";
427 		break;
428 	case 0x60:
429 		name = "bt817a";
430 		break;
431 	case 0x20:
432 		name = "bt815a";
433 		break;
434 	default:
435 		v4l2_dbg(1, debug, sd,
436 			"unknown chip version 0x%02x\n", ver);
437 		return -ENODEV;
438 	}
439 
440 	v4l_info(client, "%s found @ 0x%x (%s)\n", name,
441 			client->addr << 1, client->adapter->name);
442 
443 	decoder->norm = V4L2_STD_NTSC;
444 	decoder->input = 0;
445 	decoder->enable = 1;
446 
447 	i = bt819_init(sd);
448 	if (i < 0)
449 		v4l2_dbg(1, debug, sd, "init status %d\n", i);
450 
451 	v4l2_ctrl_handler_init(&decoder->hdl, 4);
452 	v4l2_ctrl_new_std(&decoder->hdl, &bt819_ctrl_ops,
453 			V4L2_CID_BRIGHTNESS, -128, 127, 1, 0);
454 	v4l2_ctrl_new_std(&decoder->hdl, &bt819_ctrl_ops,
455 			V4L2_CID_CONTRAST, 0, 511, 1, 0xd8);
456 	v4l2_ctrl_new_std(&decoder->hdl, &bt819_ctrl_ops,
457 			V4L2_CID_SATURATION, 0, 511, 1, 0xfe);
458 	v4l2_ctrl_new_std(&decoder->hdl, &bt819_ctrl_ops,
459 			V4L2_CID_HUE, -128, 127, 1, 0);
460 	sd->ctrl_handler = &decoder->hdl;
461 	if (decoder->hdl.error) {
462 		int err = decoder->hdl.error;
463 
464 		v4l2_ctrl_handler_free(&decoder->hdl);
465 		return err;
466 	}
467 	v4l2_ctrl_handler_setup(&decoder->hdl);
468 	return 0;
469 }
470 
471 static int bt819_remove(struct i2c_client *client)
472 {
473 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
474 	struct bt819 *decoder = to_bt819(sd);
475 
476 	v4l2_device_unregister_subdev(sd);
477 	v4l2_ctrl_handler_free(&decoder->hdl);
478 	return 0;
479 }
480 
481 /* ----------------------------------------------------------------------- */
482 
483 static const struct i2c_device_id bt819_id[] = {
484 	{ "bt819a", 0 },
485 	{ "bt817a", 0 },
486 	{ "bt815a", 0 },
487 	{ }
488 };
489 MODULE_DEVICE_TABLE(i2c, bt819_id);
490 
491 static struct i2c_driver bt819_driver = {
492 	.driver = {
493 		.owner	= THIS_MODULE,
494 		.name	= "bt819",
495 	},
496 	.probe		= bt819_probe,
497 	.remove		= bt819_remove,
498 	.id_table	= bt819_id,
499 };
500 
501 module_i2c_driver(bt819_driver);
502