xref: /openbmc/linux/drivers/media/i2c/bt819.c (revision a2cce7a9)
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_video_ops bt819_video_ops = {
383 	.s_std = bt819_s_std,
384 	.s_routing = bt819_s_routing,
385 	.s_stream = bt819_s_stream,
386 	.querystd = bt819_querystd,
387 	.g_input_status = bt819_g_input_status,
388 };
389 
390 static const struct v4l2_subdev_ops bt819_ops = {
391 	.video = &bt819_video_ops,
392 };
393 
394 /* ----------------------------------------------------------------------- */
395 
396 static int bt819_probe(struct i2c_client *client,
397 			const struct i2c_device_id *id)
398 {
399 	int i, ver;
400 	struct bt819 *decoder;
401 	struct v4l2_subdev *sd;
402 	const char *name;
403 
404 	/* Check if the adapter supports the needed features */
405 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
406 		return -ENODEV;
407 
408 	decoder = devm_kzalloc(&client->dev, sizeof(*decoder), GFP_KERNEL);
409 	if (decoder == NULL)
410 		return -ENOMEM;
411 	sd = &decoder->sd;
412 	v4l2_i2c_subdev_init(sd, client, &bt819_ops);
413 
414 	ver = bt819_read(decoder, 0x17);
415 	switch (ver & 0xf0) {
416 	case 0x70:
417 		name = "bt819a";
418 		break;
419 	case 0x60:
420 		name = "bt817a";
421 		break;
422 	case 0x20:
423 		name = "bt815a";
424 		break;
425 	default:
426 		v4l2_dbg(1, debug, sd,
427 			"unknown chip version 0x%02x\n", ver);
428 		return -ENODEV;
429 	}
430 
431 	v4l_info(client, "%s found @ 0x%x (%s)\n", name,
432 			client->addr << 1, client->adapter->name);
433 
434 	decoder->norm = V4L2_STD_NTSC;
435 	decoder->input = 0;
436 	decoder->enable = 1;
437 
438 	i = bt819_init(sd);
439 	if (i < 0)
440 		v4l2_dbg(1, debug, sd, "init status %d\n", i);
441 
442 	v4l2_ctrl_handler_init(&decoder->hdl, 4);
443 	v4l2_ctrl_new_std(&decoder->hdl, &bt819_ctrl_ops,
444 			V4L2_CID_BRIGHTNESS, -128, 127, 1, 0);
445 	v4l2_ctrl_new_std(&decoder->hdl, &bt819_ctrl_ops,
446 			V4L2_CID_CONTRAST, 0, 511, 1, 0xd8);
447 	v4l2_ctrl_new_std(&decoder->hdl, &bt819_ctrl_ops,
448 			V4L2_CID_SATURATION, 0, 511, 1, 0xfe);
449 	v4l2_ctrl_new_std(&decoder->hdl, &bt819_ctrl_ops,
450 			V4L2_CID_HUE, -128, 127, 1, 0);
451 	sd->ctrl_handler = &decoder->hdl;
452 	if (decoder->hdl.error) {
453 		int err = decoder->hdl.error;
454 
455 		v4l2_ctrl_handler_free(&decoder->hdl);
456 		return err;
457 	}
458 	v4l2_ctrl_handler_setup(&decoder->hdl);
459 	return 0;
460 }
461 
462 static int bt819_remove(struct i2c_client *client)
463 {
464 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
465 	struct bt819 *decoder = to_bt819(sd);
466 
467 	v4l2_device_unregister_subdev(sd);
468 	v4l2_ctrl_handler_free(&decoder->hdl);
469 	return 0;
470 }
471 
472 /* ----------------------------------------------------------------------- */
473 
474 static const struct i2c_device_id bt819_id[] = {
475 	{ "bt819a", 0 },
476 	{ "bt817a", 0 },
477 	{ "bt815a", 0 },
478 	{ }
479 };
480 MODULE_DEVICE_TABLE(i2c, bt819_id);
481 
482 static struct i2c_driver bt819_driver = {
483 	.driver = {
484 		.name	= "bt819",
485 	},
486 	.probe		= bt819_probe,
487 	.remove		= bt819_remove,
488 	.id_table	= bt819_id,
489 };
490 
491 module_i2c_driver(bt819_driver);
492