/*
 * saa7110 - Philips SAA7110(A) video decoder driver
 *
 * Copyright (C) 1998 Pauline Middelink <middelin@polyware.nl>
 *
 * Copyright (C) 1999 Wolfgang Scherr <scherr@net4you.net>
 * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
 *    - some corrections for Pinnacle Systems Inc. DC10plus card.
 *
 * Changes by Ronald Bultje <rbultje@ronald.bitfreak.net>
 *    - moved over to linux>=2.4.x i2c protocol (1/1/2003)
 *
 * 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/types.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/wait.h>
#include <asm/io.h>
#include <asm/uaccess.h>

MODULE_DESCRIPTION("Philips SAA7110 video decoder driver");
MODULE_AUTHOR("Pauline Middelink");
MODULE_LICENSE("GPL");

#include <linux/i2c.h>

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

#include <linux/videodev.h>
#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)

#define SAA7110_MAX_INPUT	9	/* 6 CVBS, 3 SVHS */
#define SAA7110_MAX_OUTPUT	0	/* its a decoder only */

#define	I2C_SAA7110		0x9C	/* or 0x9E */

#define SAA7110_NR_REG		0x35

struct saa7110 {
	u8 reg[SAA7110_NR_REG];

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

	wait_queue_head_t wq;
};

/* ----------------------------------------------------------------------- */
/* I2C support functions						   */
/* ----------------------------------------------------------------------- */

static int
saa7110_write (struct i2c_client *client,
	       u8                 reg,
	       u8                 value)
{
	struct saa7110 *decoder = i2c_get_clientdata(client);

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

static int
saa7110_write_block (struct i2c_client *client,
		     const u8          *data,
		     unsigned int       len)
{
	int ret = -1;
	u8 reg = *data;		/* first register to write to */

	/* Sanity check */
	if (reg + (len - 1) > SAA7110_NR_REG)
		return ret;

	/* the saa7110 has an autoincrement function, use it if
	 * the adapter understands raw I2C */
	if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		struct saa7110 *decoder = i2c_get_clientdata(client);

		ret = i2c_master_send(client, data, len);

		/* Cache the written data */
		memcpy(decoder->reg + reg, data + 1, len - 1);
	} else {
		for (++data, --len; len; len--) {
			if ((ret = saa7110_write(client, reg++,
						 *data++)) < 0)
				break;
		}
	}

	return ret;
}

static inline int
saa7110_read (struct i2c_client *client)
{
	return i2c_smbus_read_byte(client);
}

/* ----------------------------------------------------------------------- */
/* SAA7110 functions							   */
/* ----------------------------------------------------------------------- */

#define FRESP_06H_COMPST 0x03	//0x13
#define FRESP_06H_SVIDEO 0x83	//0xC0


static int
saa7110_selmux (struct i2c_client *client,
		int                chan)
{
	static const unsigned char modes[9][8] = {
		/* mode 0 */
		{FRESP_06H_COMPST, 0xD9, 0x17, 0x40, 0x03,
			      0x44, 0x75, 0x16},
		/* mode 1 */
		{FRESP_06H_COMPST, 0xD8, 0x17, 0x40, 0x03,
			      0x44, 0x75, 0x16},
		/* mode 2 */
		{FRESP_06H_COMPST, 0xBA, 0x07, 0x91, 0x03,
			      0x60, 0xB5, 0x05},
		/* mode 3 */
		{FRESP_06H_COMPST, 0xB8, 0x07, 0x91, 0x03,
			      0x60, 0xB5, 0x05},
		/* mode 4 */
		{FRESP_06H_COMPST, 0x7C, 0x07, 0xD2, 0x83,
			      0x60, 0xB5, 0x03},
		/* mode 5 */
		{FRESP_06H_COMPST, 0x78, 0x07, 0xD2, 0x83,
			      0x60, 0xB5, 0x03},
		/* mode 6 */
		{FRESP_06H_SVIDEO, 0x59, 0x17, 0x42, 0xA3,
			      0x44, 0x75, 0x12},
		/* mode 7 */
		{FRESP_06H_SVIDEO, 0x9A, 0x17, 0xB1, 0x13,
			      0x60, 0xB5, 0x14},
		/* mode 8 */
		{FRESP_06H_SVIDEO, 0x3C, 0x27, 0xC1, 0x23,
			      0x44, 0x75, 0x21}
	};
	struct saa7110 *decoder = i2c_get_clientdata(client);
	const unsigned char *ptr = modes[chan];

	saa7110_write(client, 0x06, ptr[0]);	/* Luminance control    */
	saa7110_write(client, 0x20, ptr[1]);	/* Analog Control #1    */
	saa7110_write(client, 0x21, ptr[2]);	/* Analog Control #2    */
	saa7110_write(client, 0x22, ptr[3]);	/* Mixer Control #1     */
	saa7110_write(client, 0x2C, ptr[4]);	/* Mixer Control #2     */
	saa7110_write(client, 0x30, ptr[5]);	/* ADCs gain control    */
	saa7110_write(client, 0x31, ptr[6]);	/* Mixer Control #3     */
	saa7110_write(client, 0x21, ptr[7]);	/* Analog Control #2    */
	decoder->input = chan;

	return 0;
}

static const unsigned char initseq[1 + SAA7110_NR_REG] = {
	0, 0x4C, 0x3C, 0x0D, 0xEF, 0xBD, 0xF2, 0x03, 0x00,
	/* 0x08 */ 0xF8, 0xF8, 0x60, 0x60, 0x00, 0x86, 0x18, 0x90,
	/* 0x10 */ 0x00, 0x59, 0x40, 0x46, 0x42, 0x1A, 0xFF, 0xDA,
	/* 0x18 */ 0xF2, 0x8B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	/* 0x20 */ 0xD9, 0x16, 0x40, 0x41, 0x80, 0x41, 0x80, 0x4F,
	/* 0x28 */ 0xFE, 0x01, 0xCF, 0x0F, 0x03, 0x01, 0x03, 0x0C,
	/* 0x30 */ 0x44, 0x71, 0x02, 0x8C, 0x02
};

static int
determine_norm (struct i2c_client *client)
{
	DEFINE_WAIT(wait);
	struct saa7110 *decoder = i2c_get_clientdata(client);
	int status;

	/* mode changed, start automatic detection */
	saa7110_write_block(client, initseq, sizeof(initseq));
	saa7110_selmux(client, decoder->input);
	prepare_to_wait(&decoder->wq, &wait, TASK_UNINTERRUPTIBLE);
	schedule_timeout(HZ/4);
	finish_wait(&decoder->wq, &wait);
	status = saa7110_read(client);
	if (status & 0x40) {
		dprintk(1, KERN_INFO "%s: status=0x%02x (no signal)\n",
			I2C_NAME(client), status);
		return decoder->norm;	// no change
	}
	if ((status & 3) == 0) {
		saa7110_write(client, 0x06, 0x83);
		if (status & 0x20) {
			dprintk(1,
				KERN_INFO
				"%s: status=0x%02x (NTSC/no color)\n",
				I2C_NAME(client), status);
			//saa7110_write(client,0x2E,0x81);
			return VIDEO_MODE_NTSC;
		}
		dprintk(1, KERN_INFO "%s: status=0x%02x (PAL/no color)\n",
			I2C_NAME(client), status);
		//saa7110_write(client,0x2E,0x9A);
		return VIDEO_MODE_PAL;
	}
	//saa7110_write(client,0x06,0x03);
	if (status & 0x20) {	/* 60Hz */
		dprintk(1, KERN_INFO "%s: status=0x%02x (NTSC)\n",
			I2C_NAME(client), status);
		saa7110_write(client, 0x0D, 0x86);
		saa7110_write(client, 0x0F, 0x50);
		saa7110_write(client, 0x11, 0x2C);
		//saa7110_write(client,0x2E,0x81);
		return VIDEO_MODE_NTSC;
	}

	/* 50Hz -> PAL/SECAM */
	saa7110_write(client, 0x0D, 0x86);
	saa7110_write(client, 0x0F, 0x10);
	saa7110_write(client, 0x11, 0x59);
	//saa7110_write(client,0x2E,0x9A);

	prepare_to_wait(&decoder->wq, &wait, TASK_UNINTERRUPTIBLE);
	schedule_timeout(HZ/4);
	finish_wait(&decoder->wq, &wait);

	status = saa7110_read(client);
	if ((status & 0x03) == 0x01) {
		dprintk(1, KERN_INFO "%s: status=0x%02x (SECAM)\n",
			I2C_NAME(client), status);
		saa7110_write(client, 0x0D, 0x87);
		return VIDEO_MODE_SECAM;
	}
	dprintk(1, KERN_INFO "%s: status=0x%02x (PAL)\n", I2C_NAME(client),
		status);
	return VIDEO_MODE_PAL;
}

static int
saa7110_command (struct i2c_client *client,
		 unsigned int       cmd,
		 void              *arg)
{
	struct saa7110 *decoder = i2c_get_clientdata(client);
	int v;

	switch (cmd) {
	case 0:
		//saa7110_write_block(client, initseq, sizeof(initseq));
		break;

	case DECODER_GET_CAPABILITIES:
	{
		struct video_decoder_capability *dc = arg;

		dc->flags =
		    VIDEO_DECODER_PAL | VIDEO_DECODER_NTSC |
		    VIDEO_DECODER_SECAM | VIDEO_DECODER_AUTO;
		dc->inputs = SAA7110_MAX_INPUT;
		dc->outputs = SAA7110_MAX_OUTPUT;
	}
		break;

	case DECODER_GET_STATUS:
	{
		int status;
		int res = 0;

		status = saa7110_read(client);
		dprintk(1, KERN_INFO "%s: status=0x%02x norm=%d\n",
			I2C_NAME(client), status, decoder->norm);
		if (!(status & 0x40))
			res |= DECODER_STATUS_GOOD;
		if (status & 0x03)
			res |= DECODER_STATUS_COLOR;

		switch (decoder->norm) {
		case VIDEO_MODE_NTSC:
			res |= DECODER_STATUS_NTSC;
			break;
		case VIDEO_MODE_PAL:
			res |= DECODER_STATUS_PAL;
			break;
		case VIDEO_MODE_SECAM:
			res |= DECODER_STATUS_SECAM;
			break;
		}
		*(int *) arg = res;
	}
		break;

	case DECODER_SET_NORM:
		v = *(int *) arg;
		if (decoder->norm != v) {
			decoder->norm = v;
			//saa7110_write(client, 0x06, 0x03);
			switch (v) {
			case VIDEO_MODE_NTSC:
				saa7110_write(client, 0x0D, 0x86);
				saa7110_write(client, 0x0F, 0x50);
				saa7110_write(client, 0x11, 0x2C);
				//saa7110_write(client, 0x2E, 0x81);
				dprintk(1,
					KERN_INFO "%s: switched to NTSC\n",
					I2C_NAME(client));
				break;
			case VIDEO_MODE_PAL:
				saa7110_write(client, 0x0D, 0x86);
				saa7110_write(client, 0x0F, 0x10);
				saa7110_write(client, 0x11, 0x59);
				//saa7110_write(client, 0x2E, 0x9A);
				dprintk(1,
					KERN_INFO "%s: switched to PAL\n",
					I2C_NAME(client));
				break;
			case VIDEO_MODE_SECAM:
				saa7110_write(client, 0x0D, 0x87);
				saa7110_write(client, 0x0F, 0x10);
				saa7110_write(client, 0x11, 0x59);
				//saa7110_write(client, 0x2E, 0x9A);
				dprintk(1,
					KERN_INFO
					"%s: switched to SECAM\n",
					I2C_NAME(client));
				break;
			case VIDEO_MODE_AUTO:
				dprintk(1,
					KERN_INFO
					"%s: TV standard detection...\n",
					I2C_NAME(client));
				decoder->norm = determine_norm(client);
				*(int *) arg = decoder->norm;
				break;
			default:
				return -EPERM;
			}
		}
		break;

	case DECODER_SET_INPUT:
		v = *(int *) arg;
		if (v < 0 || v > SAA7110_MAX_INPUT) {
			dprintk(1,
				KERN_INFO "%s: input=%d not available\n",
				I2C_NAME(client), v);
			return -EINVAL;
		}
		if (decoder->input != v) {
			saa7110_selmux(client, v);
			dprintk(1, KERN_INFO "%s: switched to input=%d\n",
				I2C_NAME(client), v);
		}
		break;

	case DECODER_SET_OUTPUT:
		v = *(int *) arg;
		/* not much choice of outputs */
		if (v != 0)
			return -EINVAL;
		break;

	case DECODER_ENABLE_OUTPUT:
		v = *(int *) arg;
		if (decoder->enable != v) {
			decoder->enable = v;
			saa7110_write(client, 0x0E, v ? 0x18 : 0x80);
			dprintk(1, KERN_INFO "%s: YUV %s\n", I2C_NAME(client),
				v ? "on" : "off");
		}
		break;

	case DECODER_SET_PICTURE:
	{
		struct video_picture *pic = arg;

		if (decoder->bright != pic->brightness) {
			/* We want 0 to 255 we get 0-65535 */
			decoder->bright = pic->brightness;
			saa7110_write(client, 0x19, decoder->bright >> 8);
		}
		if (decoder->contrast != pic->contrast) {
			/* We want 0 to 127 we get 0-65535 */
			decoder->contrast = pic->contrast;
			saa7110_write(client, 0x13,
				      decoder->contrast >> 9);
		}
		if (decoder->sat != pic->colour) {
			/* We want 0 to 127 we get 0-65535 */
			decoder->sat = pic->colour;
			saa7110_write(client, 0x12, decoder->sat >> 9);
		}
		if (decoder->hue != pic->hue) {
			/* We want -128 to 127 we get 0-65535 */
			decoder->hue = pic->hue;
			saa7110_write(client, 0x07,
				      (decoder->hue >> 8) - 128);
		}
	}
		break;

	case DECODER_DUMP:
		for (v = 0; v < SAA7110_NR_REG; v += 16) {
			int j;
			dprintk(1, KERN_DEBUG "%s: %02x:", I2C_NAME(client),
				v);
			for (j = 0; j < 16 && v + j < SAA7110_NR_REG; j++)
				dprintk(1, " %02x", decoder->reg[v + j]);
			dprintk(1, "\n");
		}
		break;

	default:
		dprintk(1, KERN_INFO "unknown saa7110_command??(%d)\n",
			cmd);
		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_SAA7110 >> 1,
	(I2C_SAA7110 >> 1) + 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_saa7110;

static int
saa7110_detect_client (struct i2c_adapter *adapter,
		       int                 address,
		       int                 kind)
{
	struct i2c_client *client;
	struct saa7110 *decoder;
	int rv;

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

	/* Check if the adapter supports the needed features */
	if (!i2c_check_functionality
	    (adapter,
	     I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_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_saa7110;
	strlcpy(I2C_NAME(client), "saa7110", sizeof(I2C_NAME(client)));

	decoder = kzalloc(sizeof(struct saa7110), GFP_KERNEL);
	if (decoder == 0) {
		kfree(client);
		return -ENOMEM;
	}
	decoder->norm = VIDEO_MODE_PAL;
	decoder->input = 0;
	decoder->enable = 1;
	decoder->bright = 32768;
	decoder->contrast = 32768;
	decoder->hue = 32768;
	decoder->sat = 32768;
	init_waitqueue_head(&decoder->wq);
	i2c_set_clientdata(client, decoder);

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

	rv = saa7110_write_block(client, initseq, sizeof(initseq));
	if (rv < 0)
		dprintk(1, KERN_ERR "%s_attach: init status %d\n",
			I2C_NAME(client), rv);
	else {
		int ver, status;
		saa7110_write(client, 0x21, 0x10);
		saa7110_write(client, 0x0e, 0x18);
		saa7110_write(client, 0x0D, 0x04);
		ver = saa7110_read(client);
		saa7110_write(client, 0x0D, 0x06);
		//mdelay(150);
		status = saa7110_read(client);
		dprintk(1,
			KERN_INFO
			"%s_attach: SAA7110A version %x at 0x%02x, status=0x%02x\n",
			I2C_NAME(client), ver, client->addr << 1, status);
		saa7110_write(client, 0x0D, 0x86);
		saa7110_write(client, 0x0F, 0x10);
		saa7110_write(client, 0x11, 0x59);
		//saa7110_write(client, 0x2E, 0x9A);
	}

	//saa7110_selmux(client,0);
	//determine_norm(client);
	/* setup and implicit mode 0 select has been performed */

	return 0;
}

static int
saa7110_attach_adapter (struct i2c_adapter *adapter)
{
	dprintk(1,
		KERN_INFO
		"saa7110.c: starting probe for adapter %s (0x%x)\n",
		I2C_NAME(adapter), adapter->id);
	return i2c_probe(adapter, &addr_data, &saa7110_detect_client);
}

static int
saa7110_detach_client (struct i2c_client *client)
{
	struct saa7110 *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_saa7110 = {
	.driver = {
		.name = "saa7110",
	},

	.id = I2C_DRIVERID_SAA7110,

	.attach_adapter = saa7110_attach_adapter,
	.detach_client = saa7110_detach_client,
	.command = saa7110_command,
};

static int __init
saa7110_init (void)
{
	return i2c_add_driver(&i2c_driver_saa7110);
}

static void __exit
saa7110_exit (void)
{
	i2c_del_driver(&i2c_driver_saa7110);
}

module_init(saa7110_init);
module_exit(saa7110_exit);
