/*
 * STK1160 driver
 *
 * Copyright (C) 2012 Ezequiel Garcia
 * <elezegarcia--a.t--gmail.com>
 *
 * Based on Easycap driver by R.M. Thomas
 *	Copyright (C) 2010 R.M. Thomas
 *	<rmthomas--a.t--sciolus.org>
 *
 * 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.
 *
 */

#include <linux/module.h>
#include <linux/usb.h>
#include <linux/i2c.h>

#include "stk1160.h"
#include "stk1160-reg.h"

static unsigned int i2c_debug;
module_param(i2c_debug, int, 0644);
MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]");

#define dprintk_i2c(fmt, args...)				\
do {								\
	if (i2c_debug)						\
		printk(KERN_DEBUG fmt, ##args);			\
} while (0)

static int stk1160_i2c_busy_wait(struct stk1160 *dev, u8 wait_bit_mask)
{
	unsigned long end;
	u8 flag;

	/* Wait until read/write finish bit is set */
	end = jiffies + msecs_to_jiffies(STK1160_I2C_TIMEOUT);
	while (time_is_after_jiffies(end)) {

		stk1160_read_reg(dev, STK1160_SICTL+1, &flag);
		/* read/write done? */
		if (flag & wait_bit_mask)
			goto done;

		usleep_range(10 * USEC_PER_MSEC, 20 * USEC_PER_MSEC);
	}

	return -ETIMEDOUT;

done:
	return 0;
}

static int stk1160_i2c_write_reg(struct stk1160 *dev, u8 addr,
		u8 reg, u8 value)
{
	int rc;

	/* Set serial device address */
	rc = stk1160_write_reg(dev, STK1160_SICTL_SDA, addr);
	if (rc < 0)
		return rc;

	/* Set i2c device register sub-address */
	rc = stk1160_write_reg(dev, STK1160_SBUSW_WA, reg);
	if (rc < 0)
		return rc;

	/* Set i2c device register value */
	rc = stk1160_write_reg(dev, STK1160_SBUSW_WD, value);
	if (rc < 0)
		return rc;

	/* Start write now */
	rc = stk1160_write_reg(dev, STK1160_SICTL, 0x01);
	if (rc < 0)
		return rc;

	rc = stk1160_i2c_busy_wait(dev, 0x04);
	if (rc < 0)
		return rc;

	return 0;
}

static int stk1160_i2c_read_reg(struct stk1160 *dev, u8 addr,
		u8 reg, u8 *value)
{
	int rc;

	/* Set serial device address */
	rc = stk1160_write_reg(dev, STK1160_SICTL_SDA, addr);
	if (rc < 0)
		return rc;

	/* Set i2c device register sub-address */
	rc = stk1160_write_reg(dev, STK1160_SBUSR_RA, reg);
	if (rc < 0)
		return rc;

	/* Start read now */
	rc = stk1160_write_reg(dev, STK1160_SICTL, 0x20);
	if (rc < 0)
		return rc;

	rc = stk1160_i2c_busy_wait(dev, 0x01);
	if (rc < 0)
		return rc;

	rc = stk1160_read_reg(dev, STK1160_SBUSR_RD, value);
	if (rc < 0)
		return rc;

	return 0;
}

/*
 * stk1160_i2c_check_for_device()
 * check if there is a i2c_device at the supplied address
 */
static int stk1160_i2c_check_for_device(struct stk1160 *dev,
		unsigned char addr)
{
	int rc;

	/* Set serial device address */
	rc = stk1160_write_reg(dev, STK1160_SICTL_SDA, addr);
	if (rc < 0)
		return rc;

	/* Set device sub-address, we'll chip version reg */
	rc = stk1160_write_reg(dev, STK1160_SBUSR_RA, 0x00);
	if (rc < 0)
		return rc;

	/* Start read now */
	rc = stk1160_write_reg(dev, STK1160_SICTL, 0x20);
	if (rc < 0)
		return rc;

	rc = stk1160_i2c_busy_wait(dev, 0x01);
	if (rc < 0)
		return -ENODEV;

	return 0;
}

/*
 * stk1160_i2c_xfer()
 * the main i2c transfer function
 */
static int stk1160_i2c_xfer(struct i2c_adapter *i2c_adap,
			   struct i2c_msg msgs[], int num)
{
	struct stk1160 *dev = i2c_adap->algo_data;
	int addr, rc, i;

	for (i = 0; i < num; i++) {
		addr = msgs[i].addr << 1;
		dprintk_i2c("%s: addr=%x", __func__, addr);

		if (!msgs[i].len) {
			/* no len: check only for device presence */
			rc = stk1160_i2c_check_for_device(dev, addr);
			if (rc < 0) {
				dprintk_i2c(" no device\n");
				return rc;
			}

		} else if (msgs[i].flags & I2C_M_RD) {
			/* read request without preceding register selection */
			dprintk_i2c(" subaddr not selected");
			rc = -EOPNOTSUPP;
			goto err;

		} else if (i + 1 < num && msgs[i].len <= 2 &&
			   (msgs[i + 1].flags & I2C_M_RD) &&
			   msgs[i].addr == msgs[i + 1].addr) {

			if (msgs[i].len != 1 || msgs[i + 1].len != 1) {
				dprintk_i2c(" len not supported");
				rc = -EOPNOTSUPP;
				goto err;
			}

			dprintk_i2c(" subaddr=%x", msgs[i].buf[0]);

			rc = stk1160_i2c_read_reg(dev, addr, msgs[i].buf[0],
				msgs[i + 1].buf);

			dprintk_i2c(" read=%x", *msgs[i + 1].buf);

			/* consumed two msgs, so we skip one of them */
			i++;

		} else {
			if (msgs[i].len != 2) {
				dprintk_i2c(" len not supported");
				rc = -EOPNOTSUPP;
				goto err;
			}

			dprintk_i2c(" subaddr=%x write=%x",
				msgs[i].buf[0],  msgs[i].buf[1]);

			rc = stk1160_i2c_write_reg(dev, addr, msgs[i].buf[0],
				msgs[i].buf[1]);
		}

		if (rc < 0)
			goto err;
		dprintk_i2c(" OK\n");
	}

	return num;
err:
	dprintk_i2c(" ERROR: %d\n", rc);
	return num;
}

/*
 * functionality(), what da heck is this?
 */
static u32 functionality(struct i2c_adapter *adap)
{
	return I2C_FUNC_SMBUS_EMUL;
}

static struct i2c_algorithm algo = {
	.master_xfer   = stk1160_i2c_xfer,
	.functionality = functionality,
};

static struct i2c_adapter adap_template = {
	.owner = THIS_MODULE,
	.name = "stk1160",
	.algo = &algo,
};

static struct i2c_client client_template = {
	.name = "stk1160 internal",
};

/*
 * stk1160_i2c_register()
 * register i2c bus
 */
int stk1160_i2c_register(struct stk1160 *dev)
{
	int rc;

	dev->i2c_adap = adap_template;
	dev->i2c_adap.dev.parent = dev->dev;
	strcpy(dev->i2c_adap.name, "stk1160");
	dev->i2c_adap.algo_data = dev;

	i2c_set_adapdata(&dev->i2c_adap, &dev->v4l2_dev);

	rc = i2c_add_adapter(&dev->i2c_adap);
	if (rc < 0) {
		stk1160_err("cannot add i2c adapter (%d)\n", rc);
		return rc;
	}

	dev->i2c_client = client_template;
	dev->i2c_client.adapter = &dev->i2c_adap;

	/* Set i2c clock divider device address */
	stk1160_write_reg(dev, STK1160_SICTL_CD,  0x0f);

	/* ??? */
	stk1160_write_reg(dev, STK1160_ASIC + 3,  0x00);

	return 0;
}

/*
 * stk1160_i2c_unregister()
 * unregister i2c_bus
 */
int stk1160_i2c_unregister(struct stk1160 *dev)
{
	i2c_del_adapter(&dev->i2c_adap);
	return 0;
}
