/*
 * Driver for AK8813 / AK8814 TV-ecoders from Asahi Kasei Microsystems Co., Ltd. (AKM)
 *
 * Copyright (C) 2010, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/videodev2.h>
#include <linux/module.h>

#include <media/ak881x.h>
#include <media/v4l2-common.h>
#include <media/v4l2-device.h>

#define AK881X_INTERFACE_MODE	0
#define AK881X_VIDEO_PROCESS1	1
#define AK881X_VIDEO_PROCESS2	2
#define AK881X_VIDEO_PROCESS3	3
#define AK881X_DAC_MODE		5
#define AK881X_STATUS		0x24
#define AK881X_DEVICE_ID	0x25
#define AK881X_DEVICE_REVISION	0x26

struct ak881x {
	struct v4l2_subdev subdev;
	struct ak881x_pdata *pdata;
	unsigned int lines;
	char revision;	/* DEVICE_REVISION content */
};

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

static int reg_write(struct i2c_client *client, const u8 reg,
		     const u8 data)
{
	return i2c_smbus_write_byte_data(client, reg, data);
}

static int reg_set(struct i2c_client *client, const u8 reg,
		   const u8 data, u8 mask)
{
	int ret = reg_read(client, reg);
	if (ret < 0)
		return ret;
	return reg_write(client, reg, (ret & ~mask) | (data & mask));
}

static struct ak881x *to_ak881x(const struct i2c_client *client)
{
	return container_of(i2c_get_clientdata(client), struct ak881x, subdev);
}

#ifdef CPTCFG_VIDEO_ADV_DEBUG
static int ak881x_g_register(struct v4l2_subdev *sd,
			     struct v4l2_dbg_register *reg)
{
	struct i2c_client *client = v4l2_get_subdevdata(sd);

	if (reg->reg > 0x26)
		return -EINVAL;

	reg->size = 1;
	reg->val = reg_read(client, reg->reg);

	if (reg->val > 0xffff)
		return -EIO;

	return 0;
}

static int ak881x_s_register(struct v4l2_subdev *sd,
			     const struct v4l2_dbg_register *reg)
{
	struct i2c_client *client = v4l2_get_subdevdata(sd);

	if (reg->reg > 0x26)
		return -EINVAL;

	if (reg_write(client, reg->reg, reg->val) < 0)
		return -EIO;

	return 0;
}
#endif

static int ak881x_fill_fmt(struct v4l2_subdev *sd,
		struct v4l2_subdev_pad_config *cfg,
		struct v4l2_subdev_format *format)
{
	struct v4l2_mbus_framefmt *mf = &format->format;
	struct i2c_client *client = v4l2_get_subdevdata(sd);
	struct ak881x *ak881x = to_ak881x(client);

	if (format->pad)
		return -EINVAL;

	v4l_bound_align_image(&mf->width, 0, 720, 2,
			      &mf->height, 0, ak881x->lines, 1, 0);
	mf->field	= V4L2_FIELD_INTERLACED;
	mf->code	= MEDIA_BUS_FMT_YUYV8_2X8;
	mf->colorspace	= V4L2_COLORSPACE_SMPTE170M;

	return 0;
}

static int ak881x_enum_mbus_code(struct v4l2_subdev *sd,
		struct v4l2_subdev_pad_config *cfg,
		struct v4l2_subdev_mbus_code_enum *code)
{
	if (code->pad || code->index)
		return -EINVAL;

	code->code = MEDIA_BUS_FMT_YUYV8_2X8;
	return 0;
}

static int ak881x_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
{
	struct i2c_client *client = v4l2_get_subdevdata(sd);
	struct ak881x *ak881x = to_ak881x(client);

	a->bounds.left			= 0;
	a->bounds.top			= 0;
	a->bounds.width			= 720;
	a->bounds.height		= ak881x->lines;
	a->defrect			= a->bounds;
	a->type				= V4L2_BUF_TYPE_VIDEO_OUTPUT;
	a->pixelaspect.numerator	= 1;
	a->pixelaspect.denominator	= 1;

	return 0;
}

static int ak881x_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std)
{
	struct i2c_client *client = v4l2_get_subdevdata(sd);
	struct ak881x *ak881x = to_ak881x(client);
	u8 vp1;

	if (std == V4L2_STD_NTSC_443) {
		vp1 = 3;
		ak881x->lines = 480;
	} else if (std == V4L2_STD_PAL_M) {
		vp1 = 5;
		ak881x->lines = 480;
	} else if (std == V4L2_STD_PAL_60) {
		vp1 = 7;
		ak881x->lines = 480;
	} else if (std && !(std & ~V4L2_STD_PAL)) {
		vp1 = 0xf;
		ak881x->lines = 576;
	} else if (std && !(std & ~V4L2_STD_NTSC)) {
		vp1 = 0;
		ak881x->lines = 480;
	} else {
		/* No SECAM or PAL_N/Nc supported */
		return -EINVAL;
	}

	reg_set(client, AK881X_VIDEO_PROCESS1, vp1, 0xf);

	return 0;
}

static int ak881x_s_stream(struct v4l2_subdev *sd, int enable)
{
	struct i2c_client *client = v4l2_get_subdevdata(sd);
	struct ak881x *ak881x = to_ak881x(client);

	if (enable) {
		u8 dac;
		/* For colour-bar testing set bit 6 of AK881X_VIDEO_PROCESS1 */
		/* Default: composite output */
		if (ak881x->pdata->flags & AK881X_COMPONENT)
			dac = 3;
		else
			dac = 4;
		/* Turn on the DAC(s) */
		reg_write(client, AK881X_DAC_MODE, dac);
		dev_dbg(&client->dev, "chip status 0x%x\n",
			reg_read(client, AK881X_STATUS));
	} else {
		/* ...and clear bit 6 of AK881X_VIDEO_PROCESS1 here */
		reg_write(client, AK881X_DAC_MODE, 0);
		dev_dbg(&client->dev, "chip status 0x%x\n",
			reg_read(client, AK881X_STATUS));
	}

	return 0;
}

static struct v4l2_subdev_core_ops ak881x_subdev_core_ops = {
#ifdef CPTCFG_VIDEO_ADV_DEBUG
	.g_register	= ak881x_g_register,
	.s_register	= ak881x_s_register,
#endif
};

static struct v4l2_subdev_video_ops ak881x_subdev_video_ops = {
	.cropcap	= ak881x_cropcap,
	.s_std_output	= ak881x_s_std_output,
	.s_stream	= ak881x_s_stream,
};

static const struct v4l2_subdev_pad_ops ak881x_subdev_pad_ops = {
	.enum_mbus_code = ak881x_enum_mbus_code,
	.set_fmt	= ak881x_fill_fmt,
	.get_fmt	= ak881x_fill_fmt,
};

static struct v4l2_subdev_ops ak881x_subdev_ops = {
	.core	= &ak881x_subdev_core_ops,
	.video	= &ak881x_subdev_video_ops,
	.pad	= &ak881x_subdev_pad_ops,
};

static int ak881x_probe(struct i2c_client *client,
			const struct i2c_device_id *did)
{
	struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
	struct ak881x *ak881x;
	u8 ifmode, data;

	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
		dev_warn(&adapter->dev,
			 "I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n");
		return -EIO;
	}

	ak881x = devm_kzalloc(&client->dev, sizeof(*ak881x), GFP_KERNEL);
	if (!ak881x)
		return -ENOMEM;

	v4l2_i2c_subdev_init(&ak881x->subdev, client, &ak881x_subdev_ops);

	data = reg_read(client, AK881X_DEVICE_ID);

	switch (data) {
	case 0x13:
	case 0x14:
		break;
	default:
		dev_err(&client->dev,
			"No ak881x chip detected, register read %x\n", data);
		return -ENODEV;
	}

	ak881x->revision = reg_read(client, AK881X_DEVICE_REVISION);
	ak881x->pdata = client->dev.platform_data;

	if (ak881x->pdata) {
		if (ak881x->pdata->flags & AK881X_FIELD)
			ifmode = 4;
		else
			ifmode = 0;

		switch (ak881x->pdata->flags & AK881X_IF_MODE_MASK) {
		case AK881X_IF_MODE_BT656:
			ifmode |= 1;
			break;
		case AK881X_IF_MODE_MASTER:
			ifmode |= 2;
			break;
		case AK881X_IF_MODE_SLAVE:
		default:
			break;
		}

		dev_dbg(&client->dev, "IF mode %x\n", ifmode);

		/*
		 * "Line Blanking No." seems to be the same as the number of
		 * "black" lines on, e.g., SuperH VOU, whose default value of 20
		 * "incidentally" matches ak881x' default
		 */
		reg_write(client, AK881X_INTERFACE_MODE, ifmode | (20 << 3));
	}

	/* Hardware default: NTSC-M */
	ak881x->lines = 480;

	dev_info(&client->dev, "Detected an ak881x chip ID %x, revision %x\n",
		 data, ak881x->revision);

	return 0;
}

static int ak881x_remove(struct i2c_client *client)
{
	struct ak881x *ak881x = to_ak881x(client);

	v4l2_device_unregister_subdev(&ak881x->subdev);

	return 0;
}

static const struct i2c_device_id ak881x_id[] = {
	{ "ak8813", 0 },
	{ "ak8814", 0 },
	{ }
};
MODULE_DEVICE_TABLE(i2c, ak881x_id);

static struct i2c_driver ak881x_i2c_driver = {
	.driver = {
		.name = "ak881x",
	},
	.probe		= ak881x_probe,
	.remove		= ak881x_remove,
	.id_table	= ak881x_id,
};

module_i2c_driver(ak881x_i2c_driver);

MODULE_DESCRIPTION("TV-output driver for ak8813/ak8814");
MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");
MODULE_LICENSE("GPL v2");
