/*
 * usbvision_i2c.c
 *  i2c algorithm for USB-I2C Bridges
 *
 * Copyright (c) 1999-2007 Joerg Heckenbach <joerg@heckenbach-aw.de>
 *                         Dwaine Garden <dwainegarden@rogers.com>
 *
 * This module is part of usbvision driver project.
 * Updates to driver completed by Dwaine P. Garden
 *
 * 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/kernel.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <asm/uaccess.h>
#include <linux/ioport.h>
#include <linux/errno.h>
#include <linux/usb.h>
#include <linux/i2c.h>
#include "usbvision.h"

#define DBG_I2C		1<<0

static int i2c_debug;

module_param (i2c_debug, int, 0644);			// debug_i2c_usb mode of the device driver
MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]");

#define PDEBUG(level, fmt, args...) { \
		if (i2c_debug & (level)) \
			printk(KERN_INFO KBUILD_MODNAME ":[%s:%d] " fmt, \
				__func__, __LINE__ , ## args); \
	}

static int usbvision_i2c_write(struct usb_usbvision *usbvision, unsigned char addr, char *buf,
			    short len);
static int usbvision_i2c_read(struct usb_usbvision *usbvision, unsigned char addr, char *buf,
			   short len);

static inline int try_write_address(struct i2c_adapter *i2c_adap,
				    unsigned char addr, int retries)
{
	struct usb_usbvision *usbvision;
	int i, ret = -1;
	char buf[4];

	usbvision = (struct usb_usbvision *)i2c_get_adapdata(i2c_adap);
	buf[0] = 0x00;
	for (i = 0; i <= retries; i++) {
		ret = (usbvision_i2c_write(usbvision, addr, buf, 1));
		if (ret == 1)
			break;	/* success! */
		udelay(5);
		if (i == retries)	/* no success */
			break;
		udelay(10);
	}
	if (i) {
		PDEBUG(DBG_I2C,"Needed %d retries for address %#2x", i, addr);
		PDEBUG(DBG_I2C,"Maybe there's no device at this address");
	}
	return ret;
}

static inline int try_read_address(struct i2c_adapter *i2c_adap,
				   unsigned char addr, int retries)
{
	struct usb_usbvision *usbvision;
	int i, ret = -1;
	char buf[4];

	usbvision = (struct usb_usbvision *)i2c_get_adapdata(i2c_adap);
	for (i = 0; i <= retries; i++) {
		ret = (usbvision_i2c_read(usbvision, addr, buf, 1));
		if (ret == 1)
			break;	/* success! */
		udelay(5);
		if (i == retries)	/* no success */
			break;
		udelay(10);
	}
	if (i) {
		PDEBUG(DBG_I2C,"Needed %d retries for address %#2x", i, addr);
		PDEBUG(DBG_I2C,"Maybe there's no device at this address");
	}
	return ret;
}

static inline int usb_find_address(struct i2c_adapter *i2c_adap,
				   struct i2c_msg *msg, int retries,
				   unsigned char *add)
{
	unsigned short flags = msg->flags;

	unsigned char addr;
	int ret;
	if ((flags & I2C_M_TEN)) {
		/* a ten bit address */
		addr = 0xf0 | ((msg->addr >> 7) & 0x03);
		/* try extended address code... */
		ret = try_write_address(i2c_adap, addr, retries);
		if (ret != 1) {
			dev_err(&i2c_adap->dev,
				"died at extended address code,	while writing\n");
			return -EREMOTEIO;
		}
		add[0] = addr;
		if (flags & I2C_M_RD) {
			/* okay, now switch into reading mode */
			addr |= 0x01;
			ret = try_read_address(i2c_adap, addr, retries);
			if (ret != 1) {
				dev_err(&i2c_adap->dev,
					"died at extended address code, while reading\n");
				return -EREMOTEIO;
			}
		}

	} else {		/* normal 7bit address  */
		addr = (msg->addr << 1);
		if (flags & I2C_M_RD)
			addr |= 1;

		add[0] = addr;
		if (flags & I2C_M_RD)
			ret = try_read_address(i2c_adap, addr, retries);
		else
			ret = try_write_address(i2c_adap, addr, retries);

		if (ret != 1) {
			return -EREMOTEIO;
		}
	}
	return 0;
}

static int
usbvision_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num)
{
	struct i2c_msg *pmsg;
	struct usb_usbvision *usbvision;
	int i, ret;
	unsigned char addr = 0;

	usbvision = (struct usb_usbvision *)i2c_get_adapdata(i2c_adap);

	for (i = 0; i < num; i++) {
		pmsg = &msgs[i];
		ret = usb_find_address(i2c_adap, pmsg, i2c_adap->retries, &addr);
		if (ret != 0) {
			PDEBUG(DBG_I2C,"got NAK from device, message #%d", i);
			return (ret < 0) ? ret : -EREMOTEIO;
		}

		if (pmsg->flags & I2C_M_RD) {
			/* read bytes into buffer */
			ret = (usbvision_i2c_read(usbvision, addr, pmsg->buf, pmsg->len));
			if (ret < pmsg->len) {
				return (ret < 0) ? ret : -EREMOTEIO;
			}
		} else {
			/* write bytes from buffer */
			ret = (usbvision_i2c_write(usbvision, addr, pmsg->buf, pmsg->len));
			if (ret < pmsg->len) {
				return (ret < 0) ? ret : -EREMOTEIO;
			}
		}
	}
	return num;
}

static u32 functionality(struct i2c_adapter *adap)
{
	return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR;
}

/* -----exported algorithm data: -------------------------------------	*/

static struct i2c_algorithm usbvision_algo = {
	.master_xfer   = usbvision_i2c_xfer,
	.smbus_xfer    = NULL,
	.functionality = functionality,
};


/* ----------------------------------------------------------------------- */
/* usbvision specific I2C functions                                        */
/* ----------------------------------------------------------------------- */
static struct i2c_adapter i2c_adap_template;

int usbvision_i2c_register(struct usb_usbvision *usbvision)
{
	static unsigned short saa711x_addrs[] = {
		0x4a >> 1, 0x48 >> 1,	/* SAA7111, SAA7111A and SAA7113 */
		0x42 >> 1, 0x40 >> 1,	/* SAA7114, SAA7115 and SAA7118 */
		I2C_CLIENT_END };

	memcpy(&usbvision->i2c_adap, &i2c_adap_template,
	       sizeof(struct i2c_adapter));

	sprintf(usbvision->i2c_adap.name + strlen(usbvision->i2c_adap.name),
		" #%d", usbvision->vdev->num);
	PDEBUG(DBG_I2C,"Adaptername: %s", usbvision->i2c_adap.name);
	usbvision->i2c_adap.dev.parent = &usbvision->dev->dev;

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

	if (usbvision_write_reg(usbvision, USBVISION_SER_MODE, USBVISION_IIC_LRNACK) < 0) {
		printk(KERN_ERR "usbvision_register: can't write reg\n");
		return -EBUSY;
	}

	PDEBUG(DBG_I2C, "I2C   debugging is enabled [i2c]");
	PDEBUG(DBG_I2C, "ALGO   debugging is enabled [i2c]");

	/* register new adapter to i2c module... */

	usbvision->i2c_adap.algo = &usbvision_algo;

	usbvision->i2c_adap.timeout = 100;	/* default values, should       */
	usbvision->i2c_adap.retries = 3;	/* be replaced by defines       */

	i2c_add_adapter(&usbvision->i2c_adap);

	PDEBUG(DBG_I2C, "i2c bus for %s registered", usbvision->i2c_adap.name);

	/* Request the load of the i2c modules we need */
	switch (usbvision_device_data[usbvision->DevModel].Codec) {
	case CODEC_SAA7113:
	case CODEC_SAA7111:
		v4l2_i2c_new_subdev(&usbvision->v4l2_dev,
				&usbvision->i2c_adap, "saa7115",
				"saa7115_auto", 0, saa711x_addrs);
		break;
	}
	if (usbvision_device_data[usbvision->DevModel].Tuner == 1) {
		struct v4l2_subdev *sd;
		enum v4l2_i2c_tuner_type type;
		struct tuner_setup tun_setup;

		sd = v4l2_i2c_new_subdev(&usbvision->v4l2_dev,
				&usbvision->i2c_adap, "tuner",
				"tuner", 0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
		/* depending on whether we found a demod or not, select
		   the tuner type. */
		type = sd ? ADDRS_TV_WITH_DEMOD : ADDRS_TV;

		sd = v4l2_i2c_new_subdev(&usbvision->v4l2_dev,
				&usbvision->i2c_adap, "tuner",
				"tuner", 0, v4l2_i2c_tuner_addrs(type));

		if (usbvision->tuner_type != -1) {
			tun_setup.mode_mask = T_ANALOG_TV | T_RADIO;
			tun_setup.type = usbvision->tuner_type;
			tun_setup.addr = v4l2_i2c_subdev_addr(sd);
			call_all(usbvision, tuner, s_type_addr, &tun_setup);
		}
	}

	return 0;
}

int usbvision_i2c_unregister(struct usb_usbvision *usbvision)
{

	i2c_del_adapter(&(usbvision->i2c_adap));

	PDEBUG(DBG_I2C,"i2c bus for %s unregistered", usbvision->i2c_adap.name);

	return 0;
}

static int
usbvision_i2c_read_max4(struct usb_usbvision *usbvision, unsigned char addr,
		     char *buf, short len)
{
	int rc, retries;

	for (retries = 5;;) {
		rc = usbvision_write_reg(usbvision, USBVISION_SER_ADRS, addr);
		if (rc < 0)
			return rc;

		/* Initiate byte read cycle                    */
		/* USBVISION_SER_CONT <- d0-d2 n. of bytes to r/w */
		/*                    d3 0=Wr 1=Rd             */
		rc = usbvision_write_reg(usbvision, USBVISION_SER_CONT,
				      (len & 0x07) | 0x18);
		if (rc < 0)
			return rc;

		/* Test for Busy and ACK */
		do {
			/* USBVISION_SER_CONT -> d4 == 0 busy */
			rc = usbvision_read_reg(usbvision, USBVISION_SER_CONT);
		} while (rc > 0 && ((rc & 0x10) != 0));	/* Retry while busy */
		if (rc < 0)
			return rc;

		/* USBVISION_SER_CONT -> d5 == 1 Not ack */
		if ((rc & 0x20) == 0)	/* Ack? */
			break;

		/* I2C abort */
		rc = usbvision_write_reg(usbvision, USBVISION_SER_CONT, 0x00);
		if (rc < 0)
			return rc;

		if (--retries < 0)
			return -1;
	}

	switch (len) {
	case 4:
		buf[3] = usbvision_read_reg(usbvision, USBVISION_SER_DAT4);
	case 3:
		buf[2] = usbvision_read_reg(usbvision, USBVISION_SER_DAT3);
	case 2:
		buf[1] = usbvision_read_reg(usbvision, USBVISION_SER_DAT2);
	case 1:
		buf[0] = usbvision_read_reg(usbvision, USBVISION_SER_DAT1);
		break;
	default:
		printk(KERN_ERR
		       "usbvision_i2c_read_max4: buffer length > 4\n");
	}

	if (i2c_debug & DBG_I2C) {
		int idx;
		for (idx = 0; idx < len; idx++) {
			PDEBUG(DBG_I2C,"read %x from address %x", (unsigned char)buf[idx], addr);
		}
	}
	return len;
}


static int usbvision_i2c_write_max4(struct usb_usbvision *usbvision,
				 unsigned char addr, const char *buf,
				 short len)
{
	int rc, retries;
	int i;
	unsigned char value[6];
	unsigned char ser_cont;

	ser_cont = (len & 0x07) | 0x10;

	value[0] = addr;
	value[1] = ser_cont;
	for (i = 0; i < len; i++)
		value[i + 2] = buf[i];

	for (retries = 5;;) {
		rc = usb_control_msg(usbvision->dev,
				     usb_sndctrlpipe(usbvision->dev, 1),
				     USBVISION_OP_CODE,
				     USB_DIR_OUT | USB_TYPE_VENDOR |
				     USB_RECIP_ENDPOINT, 0,
				     (__u16) USBVISION_SER_ADRS, value,
				     len + 2, HZ);

		if (rc < 0)
			return rc;

		rc = usbvision_write_reg(usbvision, USBVISION_SER_CONT,
				      (len & 0x07) | 0x10);
		if (rc < 0)
			return rc;

		/* Test for Busy and ACK */
		do {
			rc = usbvision_read_reg(usbvision, USBVISION_SER_CONT);
		} while (rc > 0 && ((rc & 0x10) != 0));	/* Retry while busy */
		if (rc < 0)
			return rc;

		if ((rc & 0x20) == 0)	/* Ack? */
			break;

		/* I2C abort */
		usbvision_write_reg(usbvision, USBVISION_SER_CONT, 0x00);

		if (--retries < 0)
			return -1;

	}

	if (i2c_debug & DBG_I2C) {
		int idx;
		for (idx = 0; idx < len; idx++) {
			PDEBUG(DBG_I2C,"wrote %x at address %x", (unsigned char)buf[idx], addr);
		}
	}
	return len;
}

static int usbvision_i2c_write(struct usb_usbvision *usbvision, unsigned char addr, char *buf,
			    short len)
{
	char *bufPtr = buf;
	int retval;
	int wrcount = 0;
	int count;
	int maxLen = 4;

	while (len > 0) {
		count = (len > maxLen) ? maxLen : len;
		retval = usbvision_i2c_write_max4(usbvision, addr, bufPtr, count);
		if (retval > 0) {
			len -= count;
			bufPtr += count;
			wrcount += count;
		} else
			return (retval < 0) ? retval : -EFAULT;
	}
	return wrcount;
}

static int usbvision_i2c_read(struct usb_usbvision *usbvision, unsigned char addr, char *buf,
			   short len)
{
	char temp[4];
	int retval, i;
	int rdcount = 0;
	int count;

	while (len > 0) {
		count = (len > 3) ? 4 : len;
		retval = usbvision_i2c_read_max4(usbvision, addr, temp, count);
		if (retval > 0) {
			for (i = 0; i < len; i++)
				buf[rdcount + i] = temp[i];
			len -= count;
			rdcount += count;
		} else
			return (retval < 0) ? retval : -EFAULT;
	}
	return rdcount;
}

static struct i2c_adapter i2c_adap_template = {
	.owner = THIS_MODULE,
	.name              = "usbvision",
};

/*
 * Overrides for Emacs so that we follow Linus's tabbing style.
 * ---------------------------------------------------------------------------
 * Local variables:
 * c-basic-offset: 8
 * End:
 */
