/* 
 *  bt819 - BT819A VideoStream Decoder (Rockwell Part)
 *
 * Copyright (C) 1999 Mike Bernson <mike@mlb.org>
 * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
 *
 * Modifications for LML33/DC10plus unified driver
 * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
 *  
 * Changes by Ronald Bultje <rbultje@ronald.bitfreak.net>
 *    - moved over to linux>=2.4.x i2c protocol (9/9/2002)
 *
 * This code was modify/ported from the saa7111 driver written
 * by Dave Perks.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <linux/module.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/pci.h>
#include <linux/signal.h>
#include <asm/io.h>
#include <asm/pgtable.h>
#include <asm/page.h>
#include <linux/sched.h>
#include <linux/types.h>

#include <linux/videodev.h>
#include <asm/uaccess.h>

MODULE_DESCRIPTION("Brooktree-819 video decoder driver");
MODULE_AUTHOR("Mike Bernson & Dave Perks");
MODULE_LICENSE("GPL");

#include <linux/i2c.h>

#define I2C_NAME(s) (s)->name

#include <linux/video_decoder.h>

static int debug = 0;
module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "Debug level (0-1)");

#define dprintk(num, format, args...) \
	do { \
		if (debug >= num) \
			printk(format, ##args); \
	} while (0)

/* ----------------------------------------------------------------------- */

struct bt819 {
	unsigned char reg[32];

	int initialized;
	int norm;
	int input;
	int enable;
	int bright;
	int contrast;
	int hue;
	int sat;
};

struct timing {
	int hactive;
	int hdelay;
	int vactive;
	int vdelay;
	int hscale;
	int vscale;
};

/* for values, see the bt819 datasheet */
static struct timing timing_data[] = {
	{864 - 24, 20, 625 - 2, 1, 0x0504, 0x0000},
	{858 - 24, 20, 525 - 2, 1, 0x00f8, 0x0000},
};

#define   I2C_BT819        0x8a

/* ----------------------------------------------------------------------- */

static inline int
bt819_write (struct i2c_client *client,
	     u8                 reg,
	     u8                 value)
{
	struct bt819 *decoder = i2c_get_clientdata(client);

	decoder->reg[reg] = value;
	return i2c_smbus_write_byte_data(client, reg, value);
}

static inline int
bt819_setbit (struct i2c_client *client,
	      u8                 reg,
	      u8                 bit,
	      u8                 value)
{
	struct bt819 *decoder = i2c_get_clientdata(client);

	return bt819_write(client, reg,
			   (decoder->
			    reg[reg] & ~(1 << bit)) |
			    (value ? (1 << bit) : 0));
}

static int
bt819_write_block (struct i2c_client *client,
		   const u8          *data,
		   unsigned int       len)
{
	int ret = -1;
	u8 reg;

	/* the bt819 has an autoincrement function, use it if
	 * the adapter understands raw I2C */
	if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		/* do raw I2C, not smbus compatible */
		struct bt819 *decoder = i2c_get_clientdata(client);
		u8 block_data[32];
		int block_len;

		while (len >= 2) {
			block_len = 0;
			block_data[block_len++] = reg = data[0];
			do {
				block_data[block_len++] =
				    decoder->reg[reg++] = data[1];
				len -= 2;
				data += 2;
			} while (len >= 2 && data[0] == reg &&
				 block_len < 32);
			if ((ret = i2c_master_send(client, block_data,
						   block_len)) < 0)
				break;
		}
	} else {
		/* do some slow I2C emulation kind of thing */
		while (len >= 2) {
			reg = *data++;
			if ((ret = bt819_write(client, reg, *data++)) < 0)
				break;
			len -= 2;
		}
	}

	return ret;
}

static inline int
bt819_read (struct i2c_client *client,
	    u8                 reg)
{
	return i2c_smbus_read_byte_data(client, reg);
}

static int
bt819_init (struct i2c_client *client)
{
	struct bt819 *decoder = i2c_get_clientdata(client);

	static unsigned char init[] = {
		//0x1f, 0x00,     /* Reset */
		0x01, 0x59,	/* 0x01 input format */
		0x02, 0x00,	/* 0x02 temporal decimation */
		0x03, 0x12,	/* 0x03 Cropping msb */
		0x04, 0x16,	/* 0x04 Vertical Delay, lsb */
		0x05, 0xe0,	/* 0x05 Vertical Active lsb */
		0x06, 0x80,	/* 0x06 Horizontal Delay lsb */
		0x07, 0xd0,	/* 0x07 Horizontal Active lsb */
		0x08, 0x00,	/* 0x08 Horizontal Scaling msb */
		0x09, 0xf8,	/* 0x09 Horizontal Scaling lsb */
		0x0a, 0x00,	/* 0x0a Brightness control */
		0x0b, 0x30,	/* 0x0b Miscellaneous control */
		0x0c, 0xd8,	/* 0x0c Luma Gain lsb */
		0x0d, 0xfe,	/* 0x0d Chroma Gain (U) lsb */
		0x0e, 0xb4,	/* 0x0e Chroma Gain (V) msb */
		0x0f, 0x00,	/* 0x0f Hue control */
		0x12, 0x04,	/* 0x12 Output Format */
		0x13, 0x20,	/* 0x13 Vertial Scaling msb 0x00
					   chroma comb OFF, line drop scaling, interlace scaling
					   BUG? Why does turning the chroma comb on fuck up color?
					   Bug in the bt819 stepping on my board?
					*/
		0x14, 0x00,	/* 0x14 Vertial Scaling lsb */
		0x16, 0x07,	/* 0x16 Video Timing Polarity 
					   ACTIVE=active low
					   FIELD: high=odd, 
					   vreset=active high,
					   hreset=active high */
		0x18, 0x68,	/* 0x18 AGC Delay */
		0x19, 0x5d,	/* 0x19 Burst Gate Delay */
		0x1a, 0x80,	/* 0x1a ADC Interface */
	};

	struct timing *timing = &timing_data[decoder->norm];

	init[0x03 * 2 - 1] =
	    (((timing->vdelay >> 8) & 0x03) << 6) | (((timing->
						       vactive >> 8) &
						      0x03) << 4) |
	    (((timing->hdelay >> 8) & 0x03) << 2) | ((timing->
						      hactive >> 8) &
						     0x03);
	init[0x04 * 2 - 1] = timing->vdelay & 0xff;
	init[0x05 * 2 - 1] = timing->vactive & 0xff;
	init[0x06 * 2 - 1] = timing->hdelay & 0xff;
	init[0x07 * 2 - 1] = timing->hactive & 0xff;
	init[0x08 * 2 - 1] = timing->hscale >> 8;
	init[0x09 * 2 - 1] = timing->hscale & 0xff;
	/* 0x15 in array is address 0x19 */
	init[0x15 * 2 - 1] = (decoder->norm == 0) ? 115 : 93;	/* Chroma burst delay */
	/* reset */
	bt819_write(client, 0x1f, 0x00);
	mdelay(1);

	/* init */
	return bt819_write_block(client, init, sizeof(init));

}

/* ----------------------------------------------------------------------- */

static int
bt819_command (struct i2c_client *client,
	       unsigned int       cmd,
	       void              *arg)
{
	int temp;

	struct bt819 *decoder = i2c_get_clientdata(client);

	if (!decoder->initialized) {	// First call to bt819_init could be
		bt819_init(client);	// without #FRST = 0
		decoder->initialized = 1;
	}

	switch (cmd) {

	case 0:
		/* This is just for testing!!! */
		bt819_init(client);
		break;

	case DECODER_GET_CAPABILITIES:
	{
		struct video_decoder_capability *cap = arg;

		cap->flags = VIDEO_DECODER_PAL |
			     VIDEO_DECODER_NTSC |
			     VIDEO_DECODER_AUTO |
			     VIDEO_DECODER_CCIR;
		cap->inputs = 8;
		cap->outputs = 1;
	}
		break;

	case DECODER_GET_STATUS:
	{
		int *iarg = arg;
		int status;
		int res;

		status = bt819_read(client, 0x00);
		res = 0;
		if ((status & 0x80)) {
			res |= DECODER_STATUS_GOOD;
		}
		switch (decoder->norm) {
		case VIDEO_MODE_NTSC:
			res |= DECODER_STATUS_NTSC;
			break;
		case VIDEO_MODE_PAL:
			res |= DECODER_STATUS_PAL;
			break;
		default:
		case VIDEO_MODE_AUTO:
			if ((status & 0x10)) {
				res |= DECODER_STATUS_PAL;
			} else {
				res |= DECODER_STATUS_NTSC;
			}
			break;
		}
		res |= DECODER_STATUS_COLOR;
		*iarg = res;

		dprintk(1, KERN_INFO "%s: get status %x\n", I2C_NAME(client),
			*iarg);
	}
		break;

	case DECODER_SET_NORM:
	{
		int *iarg = arg;
		struct timing *timing = NULL;

		dprintk(1, KERN_INFO "%s: set norm %x\n", I2C_NAME(client),
			*iarg);

		switch (*iarg) {
		case VIDEO_MODE_NTSC:
			bt819_setbit(client, 0x01, 0, 1);
			bt819_setbit(client, 0x01, 1, 0);
			bt819_setbit(client, 0x01, 5, 0);
			bt819_write(client, 0x18, 0x68);
			bt819_write(client, 0x19, 0x5d);
			//bt819_setbit(client, 0x1a,  5, 1);
			timing = &timing_data[VIDEO_MODE_NTSC];
			break;
		case VIDEO_MODE_PAL:
			bt819_setbit(client, 0x01, 0, 1);
			bt819_setbit(client, 0x01, 1, 1);
			bt819_setbit(client, 0x01, 5, 1);
			bt819_write(client, 0x18, 0x7f);
			bt819_write(client, 0x19, 0x72);
			//bt819_setbit(client, 0x1a,  5, 0);
			timing = &timing_data[VIDEO_MODE_PAL];
			break;
		case VIDEO_MODE_AUTO:
			bt819_setbit(client, 0x01, 0, 0);
			bt819_setbit(client, 0x01, 1, 0);
			break;
		default:
			dprintk(1,
				KERN_ERR
				"%s: unsupported norm %d\n",
				I2C_NAME(client), *iarg);
			return -EINVAL;
		}

		if (timing) {
			bt819_write(client, 0x03,
				    (((timing->vdelay >> 8) & 0x03) << 6) |
				    (((timing->vactive >> 8) & 0x03) << 4) |
				    (((timing->hdelay >> 8) & 0x03) << 2) |
				     ((timing->hactive >> 8) & 0x03) );
			bt819_write(client, 0x04, timing->vdelay & 0xff);
			bt819_write(client, 0x05, timing->vactive & 0xff);
			bt819_write(client, 0x06, timing->hdelay & 0xff);
			bt819_write(client, 0x07, timing->hactive & 0xff);
			bt819_write(client, 0x08, (timing->hscale >> 8) & 0xff);
			bt819_write(client, 0x09, timing->hscale & 0xff);
		}

		decoder->norm = *iarg;
	}
		break;

	case DECODER_SET_INPUT:
	{
		int *iarg = arg;

		dprintk(1, KERN_INFO "%s: set input %x\n", I2C_NAME(client),
			*iarg);

		if (*iarg < 0 || *iarg > 7) {
			return -EINVAL;
		}

		if (decoder->input != *iarg) {
			decoder->input = *iarg;
			/* select mode */
			if (decoder->input == 0) {
				bt819_setbit(client, 0x0b, 6, 0);
				bt819_setbit(client, 0x1a, 1, 1);
			} else {
				bt819_setbit(client, 0x0b, 6, 1);
				bt819_setbit(client, 0x1a, 1, 0);
			}
		}
	}
		break;

	case DECODER_SET_OUTPUT:
	{
		int *iarg = arg;

		dprintk(1, KERN_INFO "%s: set output %x\n", I2C_NAME(client),
			*iarg);

		/* not much choice of outputs */
		if (*iarg != 0) {
			return -EINVAL;
		}
	}
		break;

	case DECODER_ENABLE_OUTPUT:
	{
		int *iarg = arg;
		int enable = (*iarg != 0);

		dprintk(1, KERN_INFO "%s: enable output %x\n",
			I2C_NAME(client), *iarg);

		if (decoder->enable != enable) {
			decoder->enable = enable;

			if (decoder->enable) {
				bt819_setbit(client, 0x16, 7, 0);
			} else {
				bt819_setbit(client, 0x16, 7, 1);
			}
		}
	}
		break;

	case DECODER_SET_PICTURE:
	{
		struct video_picture *pic = arg;

		dprintk(1,
			KERN_INFO
			"%s: set picture brightness %d contrast %d colour %d\n",
			I2C_NAME(client), pic->brightness, pic->contrast,
			pic->colour);


		if (decoder->bright != pic->brightness) {
			/* We want -128 to 127 we get 0-65535 */
			decoder->bright = pic->brightness;
			bt819_write(client, 0x0a,
				    (decoder->bright >> 8) - 128);
		}

		if (decoder->contrast != pic->contrast) {
			/* We want 0 to 511 we get 0-65535 */
			decoder->contrast = pic->contrast;
			bt819_write(client, 0x0c,
				    (decoder->contrast >> 7) & 0xff);
			bt819_setbit(client, 0x0b, 2,
				     ((decoder->contrast >> 15) & 0x01));
		}

		if (decoder->sat != pic->colour) {
			/* We want 0 to 511 we get 0-65535 */
			decoder->sat = pic->colour;
			bt819_write(client, 0x0d,
				    (decoder->sat >> 7) & 0xff);
			bt819_setbit(client, 0x0b, 1,
				     ((decoder->sat >> 15) & 0x01));

			temp = (decoder->sat * 201) / 237;
			bt819_write(client, 0x0e, (temp >> 7) & 0xff);
			bt819_setbit(client, 0x0b, 0, (temp >> 15) & 0x01);
		}

		if (decoder->hue != pic->hue) {
			/* We want -128 to 127 we get 0-65535 */
			decoder->hue = pic->hue;
			bt819_write(client, 0x0f,
				    128 - (decoder->hue >> 8));
		}
	}
		break;

	default:
		return -EINVAL;
	}

	return 0;
}

/* ----------------------------------------------------------------------- */

/*
 * Generic i2c probe
 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
 */
static unsigned short normal_i2c[] = {
	I2C_BT819 >> 1,
	I2C_CLIENT_END,
};

static unsigned short ignore = I2C_CLIENT_END;
                                                                                
static struct i2c_client_address_data addr_data = {
	.normal_i2c		= normal_i2c,
	.probe			= &ignore,
	.ignore			= &ignore,
};

static struct i2c_driver i2c_driver_bt819;

static int
bt819_detect_client (struct i2c_adapter *adapter,
		     int                 address,
		     int                 kind)
{
	int i, id;
	struct bt819 *decoder;
	struct i2c_client *client;

	dprintk(1,
		KERN_INFO
		"saa7111.c: detecting bt819 client on address 0x%x\n",
		address << 1);

	/* Check if the adapter supports the needed features */
	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
		return 0;

	client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
	if (client == 0)
		return -ENOMEM;
	client->addr = address;
	client->adapter = adapter;
	client->driver = &i2c_driver_bt819;

	decoder = kzalloc(sizeof(struct bt819), GFP_KERNEL);
	if (decoder == NULL) {
		kfree(client);
		return -ENOMEM;
	}
	decoder->norm = VIDEO_MODE_NTSC;
	decoder->input = 0;
	decoder->enable = 1;
	decoder->bright = 32768;
	decoder->contrast = 32768;
	decoder->hue = 32768;
	decoder->sat = 32768;
	decoder->initialized = 0;
	i2c_set_clientdata(client, decoder);

	id = bt819_read(client, 0x17);
	switch (id & 0xf0) {
	case 0x70:
		strlcpy(I2C_NAME(client), "bt819a", sizeof(I2C_NAME(client)));
		break;
	case 0x60:
		strlcpy(I2C_NAME(client), "bt817a", sizeof(I2C_NAME(client)));
		break;
	case 0x20:
		strlcpy(I2C_NAME(client), "bt815a", sizeof(I2C_NAME(client)));
		break;
	default:
		dprintk(1,
			KERN_ERR
			"bt819: unknown chip version 0x%x (ver 0x%x)\n",
			id & 0xf0, id & 0x0f);
		kfree(decoder);
		kfree(client);
		return 0;
	}

	i = i2c_attach_client(client);
	if (i) {
		kfree(client);
		kfree(decoder);
		return i;
	}

	i = bt819_init(client);
	if (i < 0) {
		dprintk(1, KERN_ERR "%s_attach: init status %d\n",
			I2C_NAME(client), i);
	} else {
		dprintk(1,
			KERN_INFO
			"%s_attach: chip version 0x%x at address 0x%x\n",
			I2C_NAME(client), id & 0x0f,
			client->addr << 1);
	}

	return 0;
}

static int
bt819_attach_adapter (struct i2c_adapter *adapter)
{
	return i2c_probe(adapter, &addr_data, &bt819_detect_client);
}

static int
bt819_detach_client (struct i2c_client *client)
{
	struct bt819 *decoder = i2c_get_clientdata(client);
	int err;

	err = i2c_detach_client(client);
	if (err) {
		return err;
	}

	kfree(decoder);
	kfree(client);

	return 0;
}

/* ----------------------------------------------------------------------- */

static struct i2c_driver i2c_driver_bt819 = {
	.driver = {
		.name = "bt819",
	},

	.id = I2C_DRIVERID_BT819,

	.attach_adapter = bt819_attach_adapter,
	.detach_client = bt819_detach_client,
	.command = bt819_command,
};

static int __init
bt819_init_module (void)
{
	return i2c_add_driver(&i2c_driver_bt819);
}

static void __exit
bt819_exit (void)
{
	i2c_del_driver(&i2c_driver_bt819);
}

module_init(bt819_init_module);
module_exit(bt819_exit);
