/* 
 *  adv7175 - adv7175a video encoder driver version 0.0.3
 *
 * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
 * 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 (9/9/2002)
 *
 * 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("Analog Devices ADV7175 video encoder driver");
MODULE_AUTHOR("Dave Perks");
MODULE_LICENSE("GPL");

#include <linux/i2c.h>
#include <linux/i2c-dev.h>

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

#include <linux/video_encoder.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 adv7175 {
	unsigned char reg[128];

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

#define   I2C_ADV7175        0xd4
#define   I2C_ADV7176        0x54

static char adv7175_name[] = "adv7175";
static char adv7176_name[] = "adv7176";

static char *inputs[] = { "pass_through", "play_back", "color_bar" };
static char *norms[] = { "PAL", "NTSC", "SECAM->PAL (may not work!)" };

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

static inline int
adv7175_write (struct i2c_client *client,
	       u8                 reg,
	       u8                 value)
{
	struct adv7175 *encoder = i2c_get_clientdata(client);

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

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

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

	/* the adv7175 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 adv7175 *encoder = i2c_get_clientdata(client);
		struct i2c_msg msg;
		u8 block_data[32];

		msg.addr = client->addr;
		msg.flags = 0;
		while (len >= 2) {
			msg.buf = (char *) block_data;
			msg.len = 0;
			block_data[msg.len++] = reg = data[0];
			do {
				block_data[msg.len++] =
				    encoder->reg[reg++] = data[1];
				len -= 2;
				data += 2;
			} while (len >= 2 && data[0] == reg &&
				 msg.len < 32);
			if ((ret = i2c_transfer(client->adapter,
						&msg, 1)) < 0)
				break;
		}
	} else {
		/* do some slow I2C emulation kind of thing */
		while (len >= 2) {
			reg = *data++;
			if ((ret = adv7175_write(client, reg,
						 *data++)) < 0)
				break;
			len -= 2;
		}
	}

	return ret;
}

static void
set_subcarrier_freq (struct i2c_client *client,
		     int                pass_through)
{
	/* for some reason pass_through NTSC needs
	 * a different sub-carrier freq to remain stable. */
	if(pass_through)
		adv7175_write(client, 0x02, 0x00);
	else
		adv7175_write(client, 0x02, 0x55);

	adv7175_write(client, 0x03, 0x55);
	adv7175_write(client, 0x04, 0x55);
	adv7175_write(client, 0x05, 0x25);
}

#ifdef ENCODER_DUMP
static void
dump (struct i2c_client *client)
{
	struct adv7175 *encoder = i2c_get_clientdata(client);
	int i, j;

	printk(KERN_INFO "%s: registry dump\n", I2C_NAME(client));
	for (i = 0; i < 182 / 8; i++) {
		printk("%s: 0x%02x -", I2C_NAME(client), i * 8);
		for (j = 0; j < 8; j++) {
			printk(" 0x%02x", encoder->reg[i * 8 + j]);
		}
		printk("\n");
	}
}
#endif

/* ----------------------------------------------------------------------- */
// Output filter:  S-Video  Composite

#define MR050       0x11	//0x09
#define MR060       0x14	//0x0c

//---------------------------------------------------------------------------

#define TR0MODE     0x46
#define TR0RST	    0x80

#define TR1CAPT	    0x80
#define TR1PLAY	    0x00

static const unsigned char init_common[] = {

	0x00, MR050,		/* MR0, PAL enabled */
	0x01, 0x00,		/* MR1 */
	0x02, 0x0c,		/* subc. freq. */
	0x03, 0x8c,		/* subc. freq. */
	0x04, 0x79,		/* subc. freq. */
	0x05, 0x26,		/* subc. freq. */
	0x06, 0x40,		/* subc. phase */

	0x07, TR0MODE,		/* TR0, 16bit */
	0x08, 0x21,		/*  */
	0x09, 0x00,		/*  */
	0x0a, 0x00,		/*  */
	0x0b, 0x00,		/*  */
	0x0c, TR1CAPT,		/* TR1 */
	0x0d, 0x4f,		/* MR2 */
	0x0e, 0x00,		/*  */
	0x0f, 0x00,		/*  */
	0x10, 0x00,		/*  */
	0x11, 0x00,		/*  */
};

static const unsigned char init_pal[] = {
	0x00, MR050,		/* MR0, PAL enabled */
	0x01, 0x00,		/* MR1 */
	0x02, 0x0c,		/* subc. freq. */
	0x03, 0x8c,		/* subc. freq. */
	0x04, 0x79,		/* subc. freq. */
	0x05, 0x26,		/* subc. freq. */
	0x06, 0x40,		/* subc. phase */
};

static const unsigned char init_ntsc[] = {
	0x00, MR060,		/* MR0, NTSC enabled */
	0x01, 0x00,		/* MR1 */
	0x02, 0x55,		/* subc. freq. */
	0x03, 0x55,		/* subc. freq. */
	0x04, 0x55,		/* subc. freq. */
	0x05, 0x25,		/* subc. freq. */
	0x06, 0x1a,		/* subc. phase */
};

static int
adv7175_command (struct i2c_client *client,
		 unsigned int       cmd,
		 void              *arg)
{
	struct adv7175 *encoder = i2c_get_clientdata(client);

	switch (cmd) {

	case 0:
		/* This is just for testing!!! */
		adv7175_write_block(client, init_common,
				    sizeof(init_common));
		adv7175_write(client, 0x07, TR0MODE | TR0RST);
		adv7175_write(client, 0x07, TR0MODE);
	        break;

	case ENCODER_GET_CAPABILITIES:
	{
		struct video_encoder_capability *cap = arg;

		cap->flags = VIDEO_ENCODER_PAL |
			     VIDEO_ENCODER_NTSC |
			     VIDEO_ENCODER_SECAM; /* well, hacky */
		cap->inputs = 2;
		cap->outputs = 1;
	}
		break;

	case ENCODER_SET_NORM:
	{
		int iarg = *(int *) arg;

		switch (iarg) {

		case VIDEO_MODE_NTSC:
			adv7175_write_block(client, init_ntsc,
					    sizeof(init_ntsc));
			if (encoder->input == 0)
				adv7175_write(client, 0x0d, 0x4f);	// Enable genlock
			adv7175_write(client, 0x07, TR0MODE | TR0RST);
			adv7175_write(client, 0x07, TR0MODE);
			break;

		case VIDEO_MODE_PAL:
			adv7175_write_block(client, init_pal,
					    sizeof(init_pal));
			if (encoder->input == 0)
				adv7175_write(client, 0x0d, 0x4f);	// Enable genlock
			adv7175_write(client, 0x07, TR0MODE | TR0RST);
			adv7175_write(client, 0x07, TR0MODE);
			break;

		case VIDEO_MODE_SECAM:	// WARNING! ADV7176 does not support SECAM.
			/* This is an attempt to convert
			 * SECAM->PAL (typically it does not work
			 * due to genlock: when decoder is in SECAM
			 * and encoder in in PAL the subcarrier can
			 * not be syncronized with horizontal
			 * quency) */
			adv7175_write_block(client, init_pal,
					    sizeof(init_pal));
			if (encoder->input == 0)
				adv7175_write(client, 0x0d, 0x49);	// Disable genlock
			adv7175_write(client, 0x07, TR0MODE | TR0RST);
			adv7175_write(client, 0x07, TR0MODE);
			break;
		default:
			dprintk(1, KERN_ERR "%s: illegal norm: %d\n",
				I2C_NAME(client), iarg);
			return -EINVAL;

		}
		dprintk(1, KERN_INFO "%s: switched to %s\n", I2C_NAME(client),
			norms[iarg]);
		encoder->norm = iarg;
	}
		break;

	case ENCODER_SET_INPUT:
	{
		int iarg = *(int *) arg;

		/* RJ: *iarg = 0: input is from SAA7110
		 *iarg = 1: input is from ZR36060
		 *iarg = 2: color bar */

		switch (iarg) {

		case 0:
			adv7175_write(client, 0x01, 0x00);

			if (encoder->norm == VIDEO_MODE_NTSC)
				set_subcarrier_freq(client, 1);

			adv7175_write(client, 0x0c, TR1CAPT);	/* TR1 */
			if (encoder->norm == VIDEO_MODE_SECAM)
				adv7175_write(client, 0x0d, 0x49);	// Disable genlock
			else
				adv7175_write(client, 0x0d, 0x4f);	// Enable genlock
			adv7175_write(client, 0x07, TR0MODE | TR0RST);
			adv7175_write(client, 0x07, TR0MODE);
			//udelay(10);
			break;

		case 1:
			adv7175_write(client, 0x01, 0x00);

			if (encoder->norm == VIDEO_MODE_NTSC)
				set_subcarrier_freq(client, 0);

			adv7175_write(client, 0x0c, TR1PLAY);	/* TR1 */
			adv7175_write(client, 0x0d, 0x49);
			adv7175_write(client, 0x07, TR0MODE | TR0RST);
			adv7175_write(client, 0x07, TR0MODE);
			//udelay(10);
			break;

		case 2:
			adv7175_write(client, 0x01, 0x80);

			if (encoder->norm == VIDEO_MODE_NTSC)
				set_subcarrier_freq(client, 0);

			adv7175_write(client, 0x0d, 0x49);
			adv7175_write(client, 0x07, TR0MODE | TR0RST);
			adv7175_write(client, 0x07, TR0MODE);
			//udelay(10);
			break;

		default:
			dprintk(1, KERN_ERR "%s: illegal input: %d\n",
				I2C_NAME(client), iarg);
			return -EINVAL;

		}
		dprintk(1, KERN_INFO "%s: switched to %s\n", I2C_NAME(client),
			inputs[iarg]);
		encoder->input = iarg;
	}
		break;

	case ENCODER_SET_OUTPUT:
	{
		int *iarg = arg;

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

	case ENCODER_ENABLE_OUTPUT:
	{
		int *iarg = arg;

		encoder->enable = !!*iarg;
	}
		break;

#ifdef ENCODER_DUMP
	case ENCODER_DUMP:
	{
		dump(client);
	}
		break;
#endif

	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_ADV7175 >> 1, (I2C_ADV7175 >> 1) + 1,
	I2C_ADV7176 >> 1, (I2C_ADV7176 >> 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_adv7175;

static int
adv7175_detect_client (struct i2c_adapter *adapter,
		       int                 address,
		       int                 kind)
{
	int i;
	struct i2c_client *client;
	struct adv7175 *encoder;
	char *dname;

	dprintk(1,
		KERN_INFO
		"adv7175.c: detecting adv7175 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_adv7175;
	if ((client->addr == I2C_ADV7175 >> 1) ||
	    (client->addr == (I2C_ADV7175 >> 1) + 1)) {
		dname = adv7175_name;
	} else if ((client->addr == I2C_ADV7176 >> 1) ||
		   (client->addr == (I2C_ADV7176 >> 1) + 1)) {
		dname = adv7176_name;
	} else {
		/* We should never get here!!! */
		kfree(client);
		return 0;
	}
	strlcpy(I2C_NAME(client), dname, sizeof(I2C_NAME(client)));

	encoder = kzalloc(sizeof(struct adv7175), GFP_KERNEL);
	if (encoder == NULL) {
		kfree(client);
		return -ENOMEM;
	}
	encoder->norm = VIDEO_MODE_PAL;
	encoder->input = 0;
	encoder->enable = 1;
	i2c_set_clientdata(client, encoder);

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

	i = adv7175_write_block(client, init_common, sizeof(init_common));
	if (i >= 0) {
		i = adv7175_write(client, 0x07, TR0MODE | TR0RST);
		i = adv7175_write(client, 0x07, TR0MODE);
		i = adv7175_read(client, 0x12);
		dprintk(1, KERN_INFO "%s_attach: rev. %d at 0x%x\n",
			I2C_NAME(client), i & 1, client->addr << 1);
	}
	if (i < 0) {
		dprintk(1, KERN_ERR "%s_attach: init error 0x%x\n",
			I2C_NAME(client), i);
	}

	return 0;
}

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

static int
adv7175_detach_client (struct i2c_client *client)
{
	struct adv7175 *encoder = i2c_get_clientdata(client);
	int err;

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

	kfree(encoder);
	kfree(client);

	return 0;
}

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

static struct i2c_driver i2c_driver_adv7175 = {
	.driver = {
		.name = "adv7175",	/* name */
	},

	.id = I2C_DRIVERID_ADV7175,

	.attach_adapter = adv7175_attach_adapter,
	.detach_client = adv7175_detach_client,
	.command = adv7175_command,
};

static int __init
adv7175_init (void)
{
	return i2c_add_driver(&i2c_driver_adv7175);
}

static void __exit
adv7175_exit (void)
{
	i2c_del_driver(&i2c_driver_adv7175);
}

module_init(adv7175_init);
module_exit(adv7175_exit);
