/*
    bt866 - BT866 Digital Video Encoder (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>

    This code was modify/ported from the saa7111 driver written
    by Dave Perks.

    This code was adapted for the bt866 by Christer Weinigel and ported
    to 2.6 by Martin Samuelsson.

    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/types.h>
#include <linux/slab.h>
#include <linux/ioctl.h>
#include <asm/uaccess.h>
#include <linux/i2c.h>
#include <linux/videodev2.h>
#include <media/v4l2-device.h>

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

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


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

struct bt866 {
	struct v4l2_subdev sd;
	u8 reg[256];
};

static inline struct bt866 *to_bt866(struct v4l2_subdev *sd)
{
	return container_of(sd, struct bt866, sd);
}

static int bt866_write(struct bt866 *encoder, u8 subaddr, u8 data)
{
	struct i2c_client *client = v4l2_get_subdevdata(&encoder->sd);
	u8 buffer[2];
	int err;

	buffer[0] = subaddr;
	buffer[1] = data;

	encoder->reg[subaddr] = data;

	v4l_dbg(1, debug, client, "write 0x%02x = 0x%02x\n", subaddr, data);

	for (err = 0; err < 3;) {
		if (i2c_master_send(client, buffer, 2) == 2)
			break;
		err++;
		v4l_warn(client, "error #%d writing to 0x%02x\n",
				err, subaddr);
		schedule_timeout_interruptible(msecs_to_jiffies(100));
	}
	if (err == 3) {
		v4l_warn(client, "giving up\n");
		return -1;
	}

	return 0;
}

static int bt866_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std)
{
	v4l2_dbg(1, debug, sd, "set norm %llx\n", (unsigned long long)std);

	/* Only PAL supported by this driver at the moment! */
	if (!(std & V4L2_STD_NTSC))
		return -EINVAL;
	return 0;
}

static int bt866_s_routing(struct v4l2_subdev *sd,
			   u32 input, u32 output, u32 config)
{
	static const __u8 init[] = {
		0xc8, 0xcc, /* CRSCALE */
		0xca, 0x91, /* CBSCALE */
		0xcc, 0x24, /* YC16 | OSDNUM */
		0xda, 0x00, /*  */
		0xdc, 0x24, /* SETMODE | PAL */
		0xde, 0x02, /* EACTIVE */

		/* overlay colors */
		0x70, 0xEB, 0x90, 0x80, 0xB0, 0x80, /* white */
		0x72, 0xA2, 0x92, 0x8E, 0xB2, 0x2C, /* yellow */
		0x74, 0x83, 0x94, 0x2C, 0xB4, 0x9C, /* cyan */
		0x76, 0x70, 0x96, 0x3A, 0xB6, 0x48, /* green */
		0x78, 0x54, 0x98, 0xC6, 0xB8, 0xB8, /* magenta */
		0x7A, 0x41, 0x9A, 0xD4, 0xBA, 0x64, /* red */
		0x7C, 0x23, 0x9C, 0x72, 0xBC, 0xD4, /* blue */
		0x7E, 0x10, 0x9E, 0x80, 0xBE, 0x80, /* black */

		0x60, 0xEB, 0x80, 0x80, 0xc0, 0x80, /* white */
		0x62, 0xA2, 0x82, 0x8E, 0xc2, 0x2C, /* yellow */
		0x64, 0x83, 0x84, 0x2C, 0xc4, 0x9C, /* cyan */
		0x66, 0x70, 0x86, 0x3A, 0xc6, 0x48, /* green */
		0x68, 0x54, 0x88, 0xC6, 0xc8, 0xB8, /* magenta */
		0x6A, 0x41, 0x8A, 0xD4, 0xcA, 0x64, /* red */
		0x6C, 0x23, 0x8C, 0x72, 0xcC, 0xD4, /* blue */
		0x6E, 0x10, 0x8E, 0x80, 0xcE, 0x80, /* black */
	};
	struct bt866 *encoder = to_bt866(sd);
	u8 val;
	int i;

	for (i = 0; i < ARRAY_SIZE(init) / 2; i += 2)
		bt866_write(encoder, init[i], init[i+1]);

	val = encoder->reg[0xdc];

	if (input == 0)
		val |= 0x40; /* CBSWAP */
	else
		val &= ~0x40; /* !CBSWAP */

	bt866_write(encoder, 0xdc, val);

	val = encoder->reg[0xcc];
	if (input == 2)
		val |= 0x01; /* OSDBAR */
	else
		val &= ~0x01; /* !OSDBAR */
	bt866_write(encoder, 0xcc, val);

	v4l2_dbg(1, debug, sd, "set input %d\n", input);

	switch (input) {
	case 0:
	case 1:
	case 2:
		break;
	default:
		return -EINVAL;
	}
	return 0;
}

#if 0
/* Code to setup square pixels, might be of some use in the future,
   but is currently unused. */
	val = encoder->reg[0xdc];
	if (*iarg)
		val |= 1; /* SQUARE */
	else
		val &= ~1; /* !SQUARE */
	bt866_write(client, 0xdc, val);
#endif

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

static const struct v4l2_subdev_video_ops bt866_video_ops = {
	.s_std_output = bt866_s_std_output,
	.s_routing = bt866_s_routing,
};

static const struct v4l2_subdev_ops bt866_ops = {
	.video = &bt866_video_ops,
};

static int bt866_probe(struct i2c_client *client,
			const struct i2c_device_id *id)
{
	struct bt866 *encoder;
	struct v4l2_subdev *sd;

	v4l_info(client, "chip found @ 0x%x (%s)\n",
			client->addr << 1, client->adapter->name);

	encoder = devm_kzalloc(&client->dev, sizeof(*encoder), GFP_KERNEL);
	if (encoder == NULL)
		return -ENOMEM;
	sd = &encoder->sd;
	v4l2_i2c_subdev_init(sd, client, &bt866_ops);
	return 0;
}

static int bt866_remove(struct i2c_client *client)
{
	struct v4l2_subdev *sd = i2c_get_clientdata(client);

	v4l2_device_unregister_subdev(sd);
	return 0;
}

static const struct i2c_device_id bt866_id[] = {
	{ "bt866", 0 },
	{ }
};
MODULE_DEVICE_TABLE(i2c, bt866_id);

static struct i2c_driver bt866_driver = {
	.driver = {
		.name	= "bt866",
	},
	.probe		= bt866_probe,
	.remove		= bt866_remove,
	.id_table	= bt866_id,
};

module_i2c_driver(bt866_driver);
