xref: /openbmc/linux/drivers/media/i2c/bt819.c (revision 8c0b9ee8)
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 = pstd ? *pstd : V4L2_STD_ALL;
219 
220 	if ((status & 0x80))
221 		res = 0;
222 	else
223 		std = V4L2_STD_UNKNOWN;
224 
225 	if ((status & 0x10))
226 		std &= V4L2_STD_PAL;
227 	else
228 		std &= V4L2_STD_NTSC;
229 	if (pstd)
230 		*pstd = std;
231 	if (pstatus)
232 		*pstatus = res;
233 
234 	v4l2_dbg(1, debug, sd, "get status %x\n", status);
235 	return 0;
236 }
237 
238 static int bt819_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
239 {
240 	return bt819_status(sd, NULL, std);
241 }
242 
243 static int bt819_g_input_status(struct v4l2_subdev *sd, u32 *status)
244 {
245 	return bt819_status(sd, status, NULL);
246 }
247 
248 static int bt819_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
249 {
250 	struct bt819 *decoder = to_bt819(sd);
251 	struct timing *timing = NULL;
252 
253 	v4l2_dbg(1, debug, sd, "set norm %llx\n", (unsigned long long)std);
254 
255 	if (sd->v4l2_dev == NULL || sd->v4l2_dev->notify == NULL)
256 		v4l2_err(sd, "no notify found!\n");
257 
258 	if (std & V4L2_STD_NTSC) {
259 		v4l2_subdev_notify(sd, BT819_FIFO_RESET_LOW, NULL);
260 		bt819_setbit(decoder, 0x01, 0, 1);
261 		bt819_setbit(decoder, 0x01, 1, 0);
262 		bt819_setbit(decoder, 0x01, 5, 0);
263 		bt819_write(decoder, 0x18, 0x68);
264 		bt819_write(decoder, 0x19, 0x5d);
265 		/* bt819_setbit(decoder, 0x1a,  5, 1); */
266 		timing = &timing_data[1];
267 	} else if (std & V4L2_STD_PAL) {
268 		v4l2_subdev_notify(sd, BT819_FIFO_RESET_LOW, NULL);
269 		bt819_setbit(decoder, 0x01, 0, 1);
270 		bt819_setbit(decoder, 0x01, 1, 1);
271 		bt819_setbit(decoder, 0x01, 5, 1);
272 		bt819_write(decoder, 0x18, 0x7f);
273 		bt819_write(decoder, 0x19, 0x72);
274 		/* bt819_setbit(decoder, 0x1a,  5, 0); */
275 		timing = &timing_data[0];
276 	} else {
277 		v4l2_dbg(1, debug, sd, "unsupported norm %llx\n",
278 				(unsigned long long)std);
279 		return -EINVAL;
280 	}
281 	bt819_write(decoder, 0x03,
282 			(((timing->vdelay >> 8) & 0x03) << 6) |
283 			(((timing->vactive >> 8) & 0x03) << 4) |
284 			(((timing->hdelay >> 8) & 0x03) << 2) |
285 			((timing->hactive >> 8) & 0x03));
286 	bt819_write(decoder, 0x04, timing->vdelay & 0xff);
287 	bt819_write(decoder, 0x05, timing->vactive & 0xff);
288 	bt819_write(decoder, 0x06, timing->hdelay & 0xff);
289 	bt819_write(decoder, 0x07, timing->hactive & 0xff);
290 	bt819_write(decoder, 0x08, (timing->hscale >> 8) & 0xff);
291 	bt819_write(decoder, 0x09, timing->hscale & 0xff);
292 	decoder->norm = std;
293 	v4l2_subdev_notify(sd, BT819_FIFO_RESET_HIGH, NULL);
294 	return 0;
295 }
296 
297 static int bt819_s_routing(struct v4l2_subdev *sd,
298 			   u32 input, u32 output, u32 config)
299 {
300 	struct bt819 *decoder = to_bt819(sd);
301 
302 	v4l2_dbg(1, debug, sd, "set input %x\n", input);
303 
304 	if (input > 7)
305 		return -EINVAL;
306 
307 	if (sd->v4l2_dev == NULL || sd->v4l2_dev->notify == NULL)
308 		v4l2_err(sd, "no notify found!\n");
309 
310 	if (decoder->input != input) {
311 		v4l2_subdev_notify(sd, BT819_FIFO_RESET_LOW, NULL);
312 		decoder->input = input;
313 		/* select mode */
314 		if (decoder->input == 0) {
315 			bt819_setbit(decoder, 0x0b, 6, 0);
316 			bt819_setbit(decoder, 0x1a, 1, 1);
317 		} else {
318 			bt819_setbit(decoder, 0x0b, 6, 1);
319 			bt819_setbit(decoder, 0x1a, 1, 0);
320 		}
321 		v4l2_subdev_notify(sd, BT819_FIFO_RESET_HIGH, NULL);
322 	}
323 	return 0;
324 }
325 
326 static int bt819_s_stream(struct v4l2_subdev *sd, int enable)
327 {
328 	struct bt819 *decoder = to_bt819(sd);
329 
330 	v4l2_dbg(1, debug, sd, "enable output %x\n", enable);
331 
332 	if (decoder->enable != enable) {
333 		decoder->enable = enable;
334 		bt819_setbit(decoder, 0x16, 7, !enable);
335 	}
336 	return 0;
337 }
338 
339 static int bt819_s_ctrl(struct v4l2_ctrl *ctrl)
340 {
341 	struct v4l2_subdev *sd = to_sd(ctrl);
342 	struct bt819 *decoder = to_bt819(sd);
343 	int temp;
344 
345 	switch (ctrl->id) {
346 	case V4L2_CID_BRIGHTNESS:
347 		bt819_write(decoder, 0x0a, ctrl->val);
348 		break;
349 
350 	case V4L2_CID_CONTRAST:
351 		bt819_write(decoder, 0x0c, ctrl->val & 0xff);
352 		bt819_setbit(decoder, 0x0b, 2, ((ctrl->val >> 8) & 0x01));
353 		break;
354 
355 	case V4L2_CID_SATURATION:
356 		bt819_write(decoder, 0x0d, (ctrl->val >> 7) & 0xff);
357 		bt819_setbit(decoder, 0x0b, 1, ((ctrl->val >> 15) & 0x01));
358 
359 		/* Ratio between U gain and V gain must stay the same as
360 		   the ratio between the default U and V gain values. */
361 		temp = (ctrl->val * 180) / 254;
362 		bt819_write(decoder, 0x0e, (temp >> 7) & 0xff);
363 		bt819_setbit(decoder, 0x0b, 0, (temp >> 15) & 0x01);
364 		break;
365 
366 	case V4L2_CID_HUE:
367 		bt819_write(decoder, 0x0f, ctrl->val);
368 		break;
369 
370 	default:
371 		return -EINVAL;
372 	}
373 	return 0;
374 }
375 
376 /* ----------------------------------------------------------------------- */
377 
378 static const struct v4l2_ctrl_ops bt819_ctrl_ops = {
379 	.s_ctrl = bt819_s_ctrl,
380 };
381 
382 static const struct v4l2_subdev_core_ops bt819_core_ops = {
383 	.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
384 	.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
385 	.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
386 	.g_ctrl = v4l2_subdev_g_ctrl,
387 	.s_ctrl = v4l2_subdev_s_ctrl,
388 	.queryctrl = v4l2_subdev_queryctrl,
389 	.querymenu = v4l2_subdev_querymenu,
390 };
391 
392 static const struct v4l2_subdev_video_ops bt819_video_ops = {
393 	.s_std = bt819_s_std,
394 	.s_routing = bt819_s_routing,
395 	.s_stream = bt819_s_stream,
396 	.querystd = bt819_querystd,
397 	.g_input_status = bt819_g_input_status,
398 };
399 
400 static const struct v4l2_subdev_ops bt819_ops = {
401 	.core = &bt819_core_ops,
402 	.video = &bt819_video_ops,
403 };
404 
405 /* ----------------------------------------------------------------------- */
406 
407 static int bt819_probe(struct i2c_client *client,
408 			const struct i2c_device_id *id)
409 {
410 	int i, ver;
411 	struct bt819 *decoder;
412 	struct v4l2_subdev *sd;
413 	const char *name;
414 
415 	/* Check if the adapter supports the needed features */
416 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
417 		return -ENODEV;
418 
419 	decoder = devm_kzalloc(&client->dev, sizeof(*decoder), GFP_KERNEL);
420 	if (decoder == NULL)
421 		return -ENOMEM;
422 	sd = &decoder->sd;
423 	v4l2_i2c_subdev_init(sd, client, &bt819_ops);
424 
425 	ver = bt819_read(decoder, 0x17);
426 	switch (ver & 0xf0) {
427 	case 0x70:
428 		name = "bt819a";
429 		break;
430 	case 0x60:
431 		name = "bt817a";
432 		break;
433 	case 0x20:
434 		name = "bt815a";
435 		break;
436 	default:
437 		v4l2_dbg(1, debug, sd,
438 			"unknown chip version 0x%02x\n", ver);
439 		return -ENODEV;
440 	}
441 
442 	v4l_info(client, "%s found @ 0x%x (%s)\n", name,
443 			client->addr << 1, client->adapter->name);
444 
445 	decoder->norm = V4L2_STD_NTSC;
446 	decoder->input = 0;
447 	decoder->enable = 1;
448 
449 	i = bt819_init(sd);
450 	if (i < 0)
451 		v4l2_dbg(1, debug, sd, "init status %d\n", i);
452 
453 	v4l2_ctrl_handler_init(&decoder->hdl, 4);
454 	v4l2_ctrl_new_std(&decoder->hdl, &bt819_ctrl_ops,
455 			V4L2_CID_BRIGHTNESS, -128, 127, 1, 0);
456 	v4l2_ctrl_new_std(&decoder->hdl, &bt819_ctrl_ops,
457 			V4L2_CID_CONTRAST, 0, 511, 1, 0xd8);
458 	v4l2_ctrl_new_std(&decoder->hdl, &bt819_ctrl_ops,
459 			V4L2_CID_SATURATION, 0, 511, 1, 0xfe);
460 	v4l2_ctrl_new_std(&decoder->hdl, &bt819_ctrl_ops,
461 			V4L2_CID_HUE, -128, 127, 1, 0);
462 	sd->ctrl_handler = &decoder->hdl;
463 	if (decoder->hdl.error) {
464 		int err = decoder->hdl.error;
465 
466 		v4l2_ctrl_handler_free(&decoder->hdl);
467 		return err;
468 	}
469 	v4l2_ctrl_handler_setup(&decoder->hdl);
470 	return 0;
471 }
472 
473 static int bt819_remove(struct i2c_client *client)
474 {
475 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
476 	struct bt819 *decoder = to_bt819(sd);
477 
478 	v4l2_device_unregister_subdev(sd);
479 	v4l2_ctrl_handler_free(&decoder->hdl);
480 	return 0;
481 }
482 
483 /* ----------------------------------------------------------------------- */
484 
485 static const struct i2c_device_id bt819_id[] = {
486 	{ "bt819a", 0 },
487 	{ "bt817a", 0 },
488 	{ "bt815a", 0 },
489 	{ }
490 };
491 MODULE_DEVICE_TABLE(i2c, bt819_id);
492 
493 static struct i2c_driver bt819_driver = {
494 	.driver = {
495 		.owner	= THIS_MODULE,
496 		.name	= "bt819",
497 	},
498 	.probe		= bt819_probe,
499 	.remove		= bt819_remove,
500 	.id_table	= bt819_id,
501 };
502 
503 module_i2c_driver(bt819_driver);
504