/*
 * 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 <media/v4l2-common.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(msecs_to_jiffies(250));
	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(msecs_to_jiffies(250));
	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)
		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) {
		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);
