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/init.h>
33#include <linux/delay.h>
34#include <linux/errno.h>
35#include <linux/fs.h>
36#include <linux/kernel.h>
37#include <linux/major.h>
38#include <linux/slab.h>
39#include <linux/mm.h>
40#include <linux/signal.h>
41#include <asm/io.h>
42#include <asm/pgtable.h>
43#include <asm/page.h>
44#include <linux/types.h>
45
46#include <linux/videodev.h>
47#include <asm/uaccess.h>
48
49MODULE_DESCRIPTION("Brooktree-819 video decoder driver");
50MODULE_AUTHOR("Mike Bernson & Dave Perks");
51MODULE_LICENSE("GPL");
52
53#include <linux/i2c.h>
54
55#define I2C_NAME(s) (s)->name
56
57#include <linux/video_decoder.h>
58
59static int debug = 0;
60module_param(debug, int, 0);
61MODULE_PARM_DESC(debug, "Debug level (0-1)");
62
63#define dprintk(num, format, args...) \
64	do { \
65		if (debug >= num) \
66			printk(format, ##args); \
67	} while (0)
68
69/* ----------------------------------------------------------------------- */
70
71struct bt819 {
72	unsigned char reg[32];
73
74	int initialized;
75	int norm;
76	int input;
77	int enable;
78	int bright;
79	int contrast;
80	int hue;
81	int sat;
82};
83
84struct timing {
85	int hactive;
86	int hdelay;
87	int vactive;
88	int vdelay;
89	int hscale;
90	int vscale;
91};
92
93/* for values, see the bt819 datasheet */
94static struct timing timing_data[] = {
95	{864 - 24, 20, 625 - 2, 1, 0x0504, 0x0000},
96	{858 - 24, 20, 525 - 2, 1, 0x00f8, 0x0000},
97};
98
99#define   I2C_BT819        0x8a
100
101/* ----------------------------------------------------------------------- */
102
103static inline int
104bt819_write (struct i2c_client *client,
105	     u8                 reg,
106	     u8                 value)
107{
108	struct bt819 *decoder = i2c_get_clientdata(client);
109
110	decoder->reg[reg] = value;
111	return i2c_smbus_write_byte_data(client, reg, value);
112}
113
114static inline int
115bt819_setbit (struct i2c_client *client,
116	      u8                 reg,
117	      u8                 bit,
118	      u8                 value)
119{
120	struct bt819 *decoder = i2c_get_clientdata(client);
121
122	return bt819_write(client, reg,
123			   (decoder->
124			    reg[reg] & ~(1 << bit)) |
125			    (value ? (1 << bit) : 0));
126}
127
128static int
129bt819_write_block (struct i2c_client *client,
130		   const u8          *data,
131		   unsigned int       len)
132{
133	int ret = -1;
134	u8 reg;
135
136	/* the bt819 has an autoincrement function, use it if
137	 * the adapter understands raw I2C */
138	if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
139		/* do raw I2C, not smbus compatible */
140		struct bt819 *decoder = i2c_get_clientdata(client);
141		u8 block_data[32];
142		int block_len;
143
144		while (len >= 2) {
145			block_len = 0;
146			block_data[block_len++] = reg = data[0];
147			do {
148				block_data[block_len++] =
149				    decoder->reg[reg++] = data[1];
150				len -= 2;
151				data += 2;
152			} while (len >= 2 && data[0] == reg &&
153				 block_len < 32);
154			if ((ret = i2c_master_send(client, block_data,
155						   block_len)) < 0)
156				break;
157		}
158	} else {
159		/* do some slow I2C emulation kind of thing */
160		while (len >= 2) {
161			reg = *data++;
162			if ((ret = bt819_write(client, reg, *data++)) < 0)
163				break;
164			len -= 2;
165		}
166	}
167
168	return ret;
169}
170
171static inline int
172bt819_read (struct i2c_client *client,
173	    u8                 reg)
174{
175	return i2c_smbus_read_byte_data(client, reg);
176}
177
178static int
179bt819_init (struct i2c_client *client)
180{
181	struct bt819 *decoder = i2c_get_clientdata(client);
182
183	static unsigned char init[] = {
184		//0x1f, 0x00,     /* Reset */
185		0x01, 0x59,	/* 0x01 input format */
186		0x02, 0x00,	/* 0x02 temporal decimation */
187		0x03, 0x12,	/* 0x03 Cropping msb */
188		0x04, 0x16,	/* 0x04 Vertical Delay, lsb */
189		0x05, 0xe0,	/* 0x05 Vertical Active lsb */
190		0x06, 0x80,	/* 0x06 Horizontal Delay lsb */
191		0x07, 0xd0,	/* 0x07 Horizontal Active lsb */
192		0x08, 0x00,	/* 0x08 Horizontal Scaling msb */
193		0x09, 0xf8,	/* 0x09 Horizontal Scaling lsb */
194		0x0a, 0x00,	/* 0x0a Brightness control */
195		0x0b, 0x30,	/* 0x0b Miscellaneous control */
196		0x0c, 0xd8,	/* 0x0c Luma Gain lsb */
197		0x0d, 0xfe,	/* 0x0d Chroma Gain (U) lsb */
198		0x0e, 0xb4,	/* 0x0e Chroma Gain (V) msb */
199		0x0f, 0x00,	/* 0x0f Hue control */
200		0x12, 0x04,	/* 0x12 Output Format */
201		0x13, 0x20,	/* 0x13 Vertial Scaling msb 0x00
202					   chroma comb OFF, line drop scaling, interlace scaling
203					   BUG? Why does turning the chroma comb on fuck up color?
204					   Bug in the bt819 stepping on my board?
205					*/
206		0x14, 0x00,	/* 0x14 Vertial Scaling lsb */
207		0x16, 0x07,	/* 0x16 Video Timing Polarity
208					   ACTIVE=active low
209					   FIELD: high=odd,
210					   vreset=active high,
211					   hreset=active high */
212		0x18, 0x68,	/* 0x18 AGC Delay */
213		0x19, 0x5d,	/* 0x19 Burst Gate Delay */
214		0x1a, 0x80,	/* 0x1a ADC Interface */
215	};
216
217	struct timing *timing = &timing_data[decoder->norm];
218
219	init[0x03 * 2 - 1] =
220	    (((timing->vdelay >> 8) & 0x03) << 6) | (((timing->
221						       vactive >> 8) &
222						      0x03) << 4) |
223	    (((timing->hdelay >> 8) & 0x03) << 2) | ((timing->
224						      hactive >> 8) &
225						     0x03);
226	init[0x04 * 2 - 1] = timing->vdelay & 0xff;
227	init[0x05 * 2 - 1] = timing->vactive & 0xff;
228	init[0x06 * 2 - 1] = timing->hdelay & 0xff;
229	init[0x07 * 2 - 1] = timing->hactive & 0xff;
230	init[0x08 * 2 - 1] = timing->hscale >> 8;
231	init[0x09 * 2 - 1] = timing->hscale & 0xff;
232	/* 0x15 in array is address 0x19 */
233	init[0x15 * 2 - 1] = (decoder->norm == 0) ? 115 : 93;	/* Chroma burst delay */
234	/* reset */
235	bt819_write(client, 0x1f, 0x00);
236	mdelay(1);
237
238	/* init */
239	return bt819_write_block(client, init, sizeof(init));
240
241}
242
243/* ----------------------------------------------------------------------- */
244
245static int
246bt819_command (struct i2c_client *client,
247	       unsigned int       cmd,
248	       void              *arg)
249{
250	int temp;
251
252	struct bt819 *decoder = i2c_get_clientdata(client);
253
254	if (!decoder->initialized) {	// First call to bt819_init could be
255		bt819_init(client);	// without #FRST = 0
256		decoder->initialized = 1;
257	}
258
259	switch (cmd) {
260
261	case 0:
262		/* This is just for testing!!! */
263		bt819_init(client);
264		break;
265
266	case DECODER_GET_CAPABILITIES:
267	{
268		struct video_decoder_capability *cap = arg;
269
270		cap->flags = VIDEO_DECODER_PAL |
271			     VIDEO_DECODER_NTSC |
272			     VIDEO_DECODER_AUTO |
273			     VIDEO_DECODER_CCIR;
274		cap->inputs = 8;
275		cap->outputs = 1;
276	}
277		break;
278
279	case DECODER_GET_STATUS:
280	{
281		int *iarg = arg;
282		int status;
283		int res;
284
285		status = bt819_read(client, 0x00);
286		res = 0;
287		if ((status & 0x80)) {
288			res |= DECODER_STATUS_GOOD;
289		}
290		switch (decoder->norm) {
291		case VIDEO_MODE_NTSC:
292			res |= DECODER_STATUS_NTSC;
293			break;
294		case VIDEO_MODE_PAL:
295			res |= DECODER_STATUS_PAL;
296			break;
297		default:
298		case VIDEO_MODE_AUTO:
299			if ((status & 0x10)) {
300				res |= DECODER_STATUS_PAL;
301			} else {
302				res |= DECODER_STATUS_NTSC;
303			}
304			break;
305		}
306		res |= DECODER_STATUS_COLOR;
307		*iarg = res;
308
309		dprintk(1, KERN_INFO "%s: get status %x\n", I2C_NAME(client),
310			*iarg);
311	}
312		break;
313
314	case DECODER_SET_NORM:
315	{
316		int *iarg = arg;
317		struct timing *timing = NULL;
318
319		dprintk(1, KERN_INFO "%s: set norm %x\n", I2C_NAME(client),
320			*iarg);
321
322		switch (*iarg) {
323		case VIDEO_MODE_NTSC:
324			bt819_setbit(client, 0x01, 0, 1);
325			bt819_setbit(client, 0x01, 1, 0);
326			bt819_setbit(client, 0x01, 5, 0);
327			bt819_write(client, 0x18, 0x68);
328			bt819_write(client, 0x19, 0x5d);
329			//bt819_setbit(client, 0x1a,  5, 1);
330			timing = &timing_data[VIDEO_MODE_NTSC];
331			break;
332		case VIDEO_MODE_PAL:
333			bt819_setbit(client, 0x01, 0, 1);
334			bt819_setbit(client, 0x01, 1, 1);
335			bt819_setbit(client, 0x01, 5, 1);
336			bt819_write(client, 0x18, 0x7f);
337			bt819_write(client, 0x19, 0x72);
338			//bt819_setbit(client, 0x1a,  5, 0);
339			timing = &timing_data[VIDEO_MODE_PAL];
340			break;
341		case VIDEO_MODE_AUTO:
342			bt819_setbit(client, 0x01, 0, 0);
343			bt819_setbit(client, 0x01, 1, 0);
344			break;
345		default:
346			dprintk(1,
347				KERN_ERR
348				"%s: unsupported norm %d\n",
349				I2C_NAME(client), *iarg);
350			return -EINVAL;
351		}
352
353		if (timing) {
354			bt819_write(client, 0x03,
355				    (((timing->vdelay >> 8) & 0x03) << 6) |
356				    (((timing->vactive >> 8) & 0x03) << 4) |
357				    (((timing->hdelay >> 8) & 0x03) << 2) |
358				     ((timing->hactive >> 8) & 0x03) );
359			bt819_write(client, 0x04, timing->vdelay & 0xff);
360			bt819_write(client, 0x05, timing->vactive & 0xff);
361			bt819_write(client, 0x06, timing->hdelay & 0xff);
362			bt819_write(client, 0x07, timing->hactive & 0xff);
363			bt819_write(client, 0x08, (timing->hscale >> 8) & 0xff);
364			bt819_write(client, 0x09, timing->hscale & 0xff);
365		}
366
367		decoder->norm = *iarg;
368	}
369		break;
370
371	case DECODER_SET_INPUT:
372	{
373		int *iarg = arg;
374
375		dprintk(1, KERN_INFO "%s: set input %x\n", I2C_NAME(client),
376			*iarg);
377
378		if (*iarg < 0 || *iarg > 7) {
379			return -EINVAL;
380		}
381
382		if (decoder->input != *iarg) {
383			decoder->input = *iarg;
384			/* select mode */
385			if (decoder->input == 0) {
386				bt819_setbit(client, 0x0b, 6, 0);
387				bt819_setbit(client, 0x1a, 1, 1);
388			} else {
389				bt819_setbit(client, 0x0b, 6, 1);
390				bt819_setbit(client, 0x1a, 1, 0);
391			}
392		}
393	}
394		break;
395
396	case DECODER_SET_OUTPUT:
397	{
398		int *iarg = arg;
399
400		dprintk(1, KERN_INFO "%s: set output %x\n", I2C_NAME(client),
401			*iarg);
402
403		/* not much choice of outputs */
404		if (*iarg != 0) {
405			return -EINVAL;
406		}
407	}
408		break;
409
410	case DECODER_ENABLE_OUTPUT:
411	{
412		int *iarg = arg;
413		int enable = (*iarg != 0);
414
415		dprintk(1, KERN_INFO "%s: enable output %x\n",
416			I2C_NAME(client), *iarg);
417
418		if (decoder->enable != enable) {
419			decoder->enable = enable;
420
421			if (decoder->enable) {
422				bt819_setbit(client, 0x16, 7, 0);
423			} else {
424				bt819_setbit(client, 0x16, 7, 1);
425			}
426		}
427	}
428		break;
429
430	case DECODER_SET_PICTURE:
431	{
432		struct video_picture *pic = arg;
433
434		dprintk(1,
435			KERN_INFO
436			"%s: set picture brightness %d contrast %d colour %d\n",
437			I2C_NAME(client), pic->brightness, pic->contrast,
438			pic->colour);
439
440
441		if (decoder->bright != pic->brightness) {
442			/* We want -128 to 127 we get 0-65535 */
443			decoder->bright = pic->brightness;
444			bt819_write(client, 0x0a,
445				    (decoder->bright >> 8) - 128);
446		}
447
448		if (decoder->contrast != pic->contrast) {
449			/* We want 0 to 511 we get 0-65535 */
450			decoder->contrast = pic->contrast;
451			bt819_write(client, 0x0c,
452				    (decoder->contrast >> 7) & 0xff);
453			bt819_setbit(client, 0x0b, 2,
454				     ((decoder->contrast >> 15) & 0x01));
455		}
456
457		if (decoder->sat != pic->colour) {
458			/* We want 0 to 511 we get 0-65535 */
459			decoder->sat = pic->colour;
460			bt819_write(client, 0x0d,
461				    (decoder->sat >> 7) & 0xff);
462			bt819_setbit(client, 0x0b, 1,
463				     ((decoder->sat >> 15) & 0x01));
464
465			temp = (decoder->sat * 201) / 237;
466			bt819_write(client, 0x0e, (temp >> 7) & 0xff);
467			bt819_setbit(client, 0x0b, 0, (temp >> 15) & 0x01);
468		}
469
470		if (decoder->hue != pic->hue) {
471			/* We want -128 to 127 we get 0-65535 */
472			decoder->hue = pic->hue;
473			bt819_write(client, 0x0f,
474				    128 - (decoder->hue >> 8));
475		}
476	}
477		break;
478
479	default:
480		return -EINVAL;
481	}
482
483	return 0;
484}
485
486/* ----------------------------------------------------------------------- */
487
488/*
489 * Generic i2c probe
490 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
491 */
492static unsigned short normal_i2c[] = {
493	I2C_BT819 >> 1,
494	I2C_CLIENT_END,
495};
496
497static unsigned short ignore = I2C_CLIENT_END;
498
499static struct i2c_client_address_data addr_data = {
500	.normal_i2c		= normal_i2c,
501	.probe			= &ignore,
502	.ignore			= &ignore,
503};
504
505static struct i2c_driver i2c_driver_bt819;
506
507static int
508bt819_detect_client (struct i2c_adapter *adapter,
509		     int                 address,
510		     int                 kind)
511{
512	int i, id;
513	struct bt819 *decoder;
514	struct i2c_client *client;
515
516	dprintk(1,
517		KERN_INFO
518		"saa7111.c: detecting bt819 client on address 0x%x\n",
519		address << 1);
520
521	/* Check if the adapter supports the needed features */
522	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
523		return 0;
524
525	client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
526	if (client == 0)
527		return -ENOMEM;
528	client->addr = address;
529	client->adapter = adapter;
530	client->driver = &i2c_driver_bt819;
531
532	decoder = kzalloc(sizeof(struct bt819), GFP_KERNEL);
533	if (decoder == NULL) {
534		kfree(client);
535		return -ENOMEM;
536	}
537	decoder->norm = VIDEO_MODE_NTSC;
538	decoder->input = 0;
539	decoder->enable = 1;
540	decoder->bright = 32768;
541	decoder->contrast = 32768;
542	decoder->hue = 32768;
543	decoder->sat = 32768;
544	decoder->initialized = 0;
545	i2c_set_clientdata(client, decoder);
546
547	id = bt819_read(client, 0x17);
548	switch (id & 0xf0) {
549	case 0x70:
550		strlcpy(I2C_NAME(client), "bt819a", sizeof(I2C_NAME(client)));
551		break;
552	case 0x60:
553		strlcpy(I2C_NAME(client), "bt817a", sizeof(I2C_NAME(client)));
554		break;
555	case 0x20:
556		strlcpy(I2C_NAME(client), "bt815a", sizeof(I2C_NAME(client)));
557		break;
558	default:
559		dprintk(1,
560			KERN_ERR
561			"bt819: unknown chip version 0x%x (ver 0x%x)\n",
562			id & 0xf0, id & 0x0f);
563		kfree(decoder);
564		kfree(client);
565		return 0;
566	}
567
568	i = i2c_attach_client(client);
569	if (i) {
570		kfree(client);
571		kfree(decoder);
572		return i;
573	}
574
575	i = bt819_init(client);
576	if (i < 0) {
577		dprintk(1, KERN_ERR "%s_attach: init status %d\n",
578			I2C_NAME(client), i);
579	} else {
580		dprintk(1,
581			KERN_INFO
582			"%s_attach: chip version 0x%x at address 0x%x\n",
583			I2C_NAME(client), id & 0x0f,
584			client->addr << 1);
585	}
586
587	return 0;
588}
589
590static int
591bt819_attach_adapter (struct i2c_adapter *adapter)
592{
593	return i2c_probe(adapter, &addr_data, &bt819_detect_client);
594}
595
596static int
597bt819_detach_client (struct i2c_client *client)
598{
599	struct bt819 *decoder = i2c_get_clientdata(client);
600	int err;
601
602	err = i2c_detach_client(client);
603	if (err) {
604		return err;
605	}
606
607	kfree(decoder);
608	kfree(client);
609
610	return 0;
611}
612
613/* ----------------------------------------------------------------------- */
614
615static struct i2c_driver i2c_driver_bt819 = {
616	.driver = {
617		.name = "bt819",
618	},
619
620	.id = I2C_DRIVERID_BT819,
621
622	.attach_adapter = bt819_attach_adapter,
623	.detach_client = bt819_detach_client,
624	.command = bt819_command,
625};
626
627static int __init
628bt819_init_module (void)
629{
630	return i2c_add_driver(&i2c_driver_bt819);
631}
632
633static void __exit
634bt819_exit (void)
635{
636	i2c_del_driver(&i2c_driver_bt819);
637}
638
639module_init(bt819_init_module);
640module_exit(bt819_exit);
641