// SPDX-License-Identifier: GPL-2.0+
//
// em28xx-i2c.c - driver for Empia EM2800/EM2820/2840 USB video capture devices
//
// Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it>
//		      Markus Rechberger <mrechberger@gmail.com>
//		      Mauro Carvalho Chehab <mchehab@kernel.org>
//		      Sascha Sommer <saschasommer@freenet.de>
// Copyright (C) 2013 Frank Schäfer <fschaefer.oss@googlemail.com>
//
// 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 "em28xx.h"

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

#include "tuner-xc2028.h"
#include <media/v4l2-common.h>
#include <media/tuner.h>

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

static unsigned int i2c_scan;
module_param(i2c_scan, int, 0444);
MODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time");

static unsigned int i2c_debug;
module_param(i2c_debug, int, 0644);
MODULE_PARM_DESC(i2c_debug, "i2c debug message level (1: normal debug, 2: show I2C transfers)");

#define dprintk(level, fmt, arg...) do {				\
	if (i2c_debug > level)						\
		dev_printk(KERN_DEBUG, &dev->intf->dev,			\
			   "i2c: %s: " fmt, __func__, ## arg);		\
} while (0)

/*
 * Time in msecs to wait for i2c xfers to finish.
 * 35ms is the maximum time a SMBUS device could wait when
 * clock stretching is used. As the transfer itself will take
 * some time to happen, set it to 35 ms.
 *
 * Ok, I2C doesn't specify any limit. So, eventually, we may need
 * to increase this timeout.
 */
#define EM28XX_I2C_XFER_TIMEOUT         35 /* ms */

static int em28xx_i2c_timeout(struct em28xx *dev)
{
	int time = EM28XX_I2C_XFER_TIMEOUT;

	switch (dev->i2c_speed & 0x03) {
	case EM28XX_I2C_FREQ_25_KHZ:
		time += 4;		/* Assume 4 ms for transfers */
		break;
	case EM28XX_I2C_FREQ_100_KHZ:
	case EM28XX_I2C_FREQ_400_KHZ:
		time += 1;		/* Assume 1 ms for transfers */
		break;
	default: /* EM28XX_I2C_FREQ_1_5_MHZ */
		break;
	}

	return msecs_to_jiffies(time);
}

/*
 * em2800_i2c_send_bytes()
 * send up to 4 bytes to the em2800 i2c device
 */
static int em2800_i2c_send_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len)
{
	unsigned long timeout = jiffies + em28xx_i2c_timeout(dev);
	int ret;
	u8 b2[6];

	if (len < 1 || len > 4)
		return -EOPNOTSUPP;

	b2[5] = 0x80 + len - 1;
	b2[4] = addr;
	b2[3] = buf[0];
	if (len > 1)
		b2[2] = buf[1];
	if (len > 2)
		b2[1] = buf[2];
	if (len > 3)
		b2[0] = buf[3];

	/* trigger write */
	ret = dev->em28xx_write_regs(dev, 4 - len, &b2[4 - len], 2 + len);
	if (ret != 2 + len) {
		dev_warn(&dev->intf->dev,
			 "failed to trigger write to i2c address 0x%x (error=%i)\n",
			    addr, ret);
		return (ret < 0) ? ret : -EIO;
	}
	/* wait for completion */
	while (time_is_after_jiffies(timeout)) {
		ret = dev->em28xx_read_reg(dev, 0x05);
		if (ret == 0x80 + len - 1)
			return len;
		if (ret == 0x94 + len - 1) {
			dprintk(1, "R05 returned 0x%02x: I2C ACK error\n", ret);
			return -ENXIO;
		}
		if (ret < 0) {
			dev_warn(&dev->intf->dev,
				 "failed to get i2c transfer status from bridge register (error=%i)\n",
				ret);
			return ret;
		}
		usleep_range(5000, 6000);
	}
	dprintk(0, "write to i2c device at 0x%x timed out\n", addr);
	return -ETIMEDOUT;
}

/*
 * em2800_i2c_recv_bytes()
 * read up to 4 bytes from the em2800 i2c device
 */
static int em2800_i2c_recv_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len)
{
	unsigned long timeout = jiffies + em28xx_i2c_timeout(dev);
	u8 buf2[4];
	int ret;
	int i;

	if (len < 1 || len > 4)
		return -EOPNOTSUPP;

	/* trigger read */
	buf2[1] = 0x84 + len - 1;
	buf2[0] = addr;
	ret = dev->em28xx_write_regs(dev, 0x04, buf2, 2);
	if (ret != 2) {
		dev_warn(&dev->intf->dev,
			 "failed to trigger read from i2c address 0x%x (error=%i)\n",
			 addr, ret);
		return (ret < 0) ? ret : -EIO;
	}

	/* wait for completion */
	while (time_is_after_jiffies(timeout)) {
		ret = dev->em28xx_read_reg(dev, 0x05);
		if (ret == 0x84 + len - 1)
			break;
		if (ret == 0x94 + len - 1) {
			dprintk(1, "R05 returned 0x%02x: I2C ACK error\n",
				ret);
			return -ENXIO;
		}
		if (ret < 0) {
			dev_warn(&dev->intf->dev,
				 "failed to get i2c transfer status from bridge register (error=%i)\n",
				 ret);
			return ret;
		}
		usleep_range(5000, 6000);
	}
	if (ret != 0x84 + len - 1)
		dprintk(0, "read from i2c device at 0x%x timed out\n", addr);

	/* get the received message */
	ret = dev->em28xx_read_reg_req_len(dev, 0x00, 4 - len, buf2, len);
	if (ret != len) {
		dev_warn(&dev->intf->dev,
			 "reading from i2c device at 0x%x failed: couldn't get the received message from the bridge (error=%i)\n",
			 addr, ret);
		return (ret < 0) ? ret : -EIO;
	}
	for (i = 0; i < len; i++)
		buf[i] = buf2[len - 1 - i];

	return ret;
}

/*
 * em2800_i2c_check_for_device()
 * check if there is an i2c device at the supplied address
 */
static int em2800_i2c_check_for_device(struct em28xx *dev, u8 addr)
{
	u8 buf;
	int ret;

	ret = em2800_i2c_recv_bytes(dev, addr, &buf, 1);
	if (ret == 1)
		return 0;
	return (ret < 0) ? ret : -EIO;
}

/*
 * em28xx_i2c_send_bytes()
 */
static int em28xx_i2c_send_bytes(struct em28xx *dev, u16 addr, u8 *buf,
				 u16 len, int stop)
{
	unsigned long timeout = jiffies + em28xx_i2c_timeout(dev);
	int ret;

	if (len < 1 || len > 64)
		return -EOPNOTSUPP;
	/*
	 * NOTE: limited by the USB ctrl message constraints
	 * Zero length reads always succeed, even if no device is connected
	 */

	/* Write to i2c device */
	ret = dev->em28xx_write_regs_req(dev, stop ? 2 : 3, addr, buf, len);
	if (ret != len) {
		if (ret < 0) {
			dev_warn(&dev->intf->dev,
				 "writing to i2c device at 0x%x failed (error=%i)\n",
				 addr, ret);
			return ret;
		}
		dev_warn(&dev->intf->dev,
			 "%i bytes write to i2c device at 0x%x requested, but %i bytes written\n",
				len, addr, ret);
		return -EIO;
	}

	/* wait for completion */
	while (time_is_after_jiffies(timeout)) {
		ret = dev->em28xx_read_reg(dev, 0x05);
		if (ret == 0) /* success */
			return len;
		if (ret == 0x10) {
			dprintk(1, "I2C ACK error on writing to addr 0x%02x\n",
				addr);
			return -ENXIO;
		}
		if (ret < 0) {
			dev_warn(&dev->intf->dev,
				 "failed to get i2c transfer status from bridge register (error=%i)\n",
				 ret);
			return ret;
		}
		usleep_range(5000, 6000);
		/*
		 * NOTE: do we really have to wait for success ?
		 * Never seen anything else than 0x00 or 0x10
		 * (even with high payload) ...
		 */
	}

	if (ret == 0x02 || ret == 0x04) {
		/* NOTE: these errors seem to be related to clock stretching */
		dprintk(0,
			"write to i2c device at 0x%x timed out (status=%i)\n",
			addr, ret);
		return -ETIMEDOUT;
	}

	dev_warn(&dev->intf->dev,
		 "write to i2c device at 0x%x failed with unknown error (status=%i)\n",
		 addr, ret);
	return -EIO;
}

/*
 * em28xx_i2c_recv_bytes()
 * read a byte from the i2c device
 */
static int em28xx_i2c_recv_bytes(struct em28xx *dev, u16 addr, u8 *buf, u16 len)
{
	int ret;

	if (len < 1 || len > 64)
		return -EOPNOTSUPP;
	/*
	 * NOTE: limited by the USB ctrl message constraints
	 * Zero length reads always succeed, even if no device is connected
	 */

	/* Read data from i2c device */
	ret = dev->em28xx_read_reg_req_len(dev, 2, addr, buf, len);
	if (ret < 0) {
		dev_warn(&dev->intf->dev,
			 "reading from i2c device at 0x%x failed (error=%i)\n",
			 addr, ret);
		return ret;
	}
	/*
	 * NOTE: some devices with two i2c busses have the bad habit to return 0
	 * bytes if we are on bus B AND there was no write attempt to the
	 * specified slave address before AND no device is present at the
	 * requested slave address.
	 * Anyway, the next check will fail with -ENXIO in this case, so avoid
	 * spamming the system log on device probing and do nothing here.
	 */

	/* Check success of the i2c operation */
	ret = dev->em28xx_read_reg(dev, 0x05);
	if (ret == 0) /* success */
		return len;
	if (ret < 0) {
		dev_warn(&dev->intf->dev,
			 "failed to get i2c transfer status from bridge register (error=%i)\n",
			 ret);
		return ret;
	}
	if (ret == 0x10) {
		dprintk(1, "I2C ACK error on writing to addr 0x%02x\n",
			addr);
		return -ENXIO;
	}

	if (ret == 0x02 || ret == 0x04) {
		/* NOTE: these errors seem to be related to clock stretching */
		dprintk(0,
			"write to i2c device at 0x%x timed out (status=%i)\n",
			addr, ret);
		return -ETIMEDOUT;
	}

	dev_warn(&dev->intf->dev,
		 "write to i2c device at 0x%x failed with unknown error (status=%i)\n",
		 addr, ret);
	return -EIO;
}

/*
 * em28xx_i2c_check_for_device()
 * check if there is a i2c_device at the supplied address
 */
static int em28xx_i2c_check_for_device(struct em28xx *dev, u16 addr)
{
	int ret;
	u8 buf;

	ret = em28xx_i2c_recv_bytes(dev, addr, &buf, 1);
	if (ret == 1)
		return 0;
	return (ret < 0) ? ret : -EIO;
}

/*
 * em25xx_bus_B_send_bytes
 * write bytes to the i2c device
 */
static int em25xx_bus_B_send_bytes(struct em28xx *dev, u16 addr, u8 *buf,
				   u16 len)
{
	int ret;

	if (len < 1 || len > 64)
		return -EOPNOTSUPP;
	/*
	 * NOTE: limited by the USB ctrl message constraints
	 * Zero length reads always succeed, even if no device is connected
	 */

	/* Set register and write value */
	ret = dev->em28xx_write_regs_req(dev, 0x06, addr, buf, len);
	if (ret != len) {
		if (ret < 0) {
			dev_warn(&dev->intf->dev,
				 "writing to i2c device at 0x%x failed (error=%i)\n",
				 addr, ret);
			return ret;
		}

		dev_warn(&dev->intf->dev,
			 "%i bytes write to i2c device at 0x%x requested, but %i bytes written\n",
			 len, addr, ret);
		return -EIO;
	}
	/* Check success */
	ret = dev->em28xx_read_reg_req(dev, 0x08, 0x0000);
	/*
	 * NOTE: the only error we've seen so far is
	 * 0x01 when the slave device is not present
	 */
	if (!ret)
		return len;

	if (ret > 0) {
		dprintk(1, "Bus B R08 returned 0x%02x: I2C ACK error\n", ret);
		return -ENXIO;
	}

	return ret;
	/*
	 * NOTE: With chip types (other chip IDs) which actually don't support
	 * this operation, it seems to succeed ALWAYS ! (even if there is no
	 * slave device or even no second i2c bus provided)
	 */
}

/*
 * em25xx_bus_B_recv_bytes
 * read bytes from the i2c device
 */
static int em25xx_bus_B_recv_bytes(struct em28xx *dev, u16 addr, u8 *buf,
				   u16 len)
{
	int ret;

	if (len < 1 || len > 64)
		return -EOPNOTSUPP;
	/*
	 * NOTE: limited by the USB ctrl message constraints
	 * Zero length reads always succeed, even if no device is connected
	 */

	/* Read value */
	ret = dev->em28xx_read_reg_req_len(dev, 0x06, addr, buf, len);
	if (ret < 0) {
		dev_warn(&dev->intf->dev,
			 "reading from i2c device at 0x%x failed (error=%i)\n",
			 addr, ret);
		return ret;
	}
	/*
	 * NOTE: some devices with two i2c busses have the bad habit to return 0
	 * bytes if we are on bus B AND there was no write attempt to the
	 * specified slave address before AND no device is present at the
	 * requested slave address.
	 * Anyway, the next check will fail with -ENXIO in this case, so avoid
	 * spamming the system log on device probing and do nothing here.
	 */

	/* Check success */
	ret = dev->em28xx_read_reg_req(dev, 0x08, 0x0000);
	/*
	 * NOTE: the only error we've seen so far is
	 * 0x01 when the slave device is not present
	 */
	if (!ret)
		return len;

	if (ret > 0) {
		dprintk(1, "Bus B R08 returned 0x%02x: I2C ACK error\n", ret);
		return -ENXIO;
	}

	return ret;
	/*
	 * NOTE: With chip types (other chip IDs) which actually don't support
	 * this operation, it seems to succeed ALWAYS ! (even if there is no
	 * slave device or even no second i2c bus provided)
	 */
}

/*
 * em25xx_bus_B_check_for_device()
 * check if there is a i2c device at the supplied address
 */
static int em25xx_bus_B_check_for_device(struct em28xx *dev, u16 addr)
{
	u8 buf;
	int ret;

	ret = em25xx_bus_B_recv_bytes(dev, addr, &buf, 1);
	if (ret < 0)
		return ret;

	return 0;
	/*
	 * NOTE: With chips which do not support this operation,
	 * it seems to succeed ALWAYS ! (even if no device connected)
	 */
}

static inline int i2c_check_for_device(struct em28xx_i2c_bus *i2c_bus, u16 addr)
{
	struct em28xx *dev = i2c_bus->dev;
	int rc = -EOPNOTSUPP;

	if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM28XX)
		rc = em28xx_i2c_check_for_device(dev, addr);
	else if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM2800)
		rc = em2800_i2c_check_for_device(dev, addr);
	else if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM25XX_BUS_B)
		rc = em25xx_bus_B_check_for_device(dev, addr);
	return rc;
}

static inline int i2c_recv_bytes(struct em28xx_i2c_bus *i2c_bus,
				 struct i2c_msg msg)
{
	struct em28xx *dev = i2c_bus->dev;
	u16 addr = msg.addr << 1;
	int rc = -EOPNOTSUPP;

	if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM28XX)
		rc = em28xx_i2c_recv_bytes(dev, addr, msg.buf, msg.len);
	else if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM2800)
		rc = em2800_i2c_recv_bytes(dev, addr, msg.buf, msg.len);
	else if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM25XX_BUS_B)
		rc = em25xx_bus_B_recv_bytes(dev, addr, msg.buf, msg.len);
	return rc;
}

static inline int i2c_send_bytes(struct em28xx_i2c_bus *i2c_bus,
				 struct i2c_msg msg, int stop)
{
	struct em28xx *dev = i2c_bus->dev;
	u16 addr = msg.addr << 1;
	int rc = -EOPNOTSUPP;

	if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM28XX)
		rc = em28xx_i2c_send_bytes(dev, addr, msg.buf, msg.len, stop);
	else if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM2800)
		rc = em2800_i2c_send_bytes(dev, addr, msg.buf, msg.len);
	else if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM25XX_BUS_B)
		rc = em25xx_bus_B_send_bytes(dev, addr, msg.buf, msg.len);
	return rc;
}

/*
 * em28xx_i2c_xfer()
 * the main i2c transfer function
 */
static int em28xx_i2c_xfer(struct i2c_adapter *i2c_adap,
			   struct i2c_msg msgs[], int num)
{
	struct em28xx_i2c_bus *i2c_bus = i2c_adap->algo_data;
	struct em28xx *dev = i2c_bus->dev;
	unsigned int bus = i2c_bus->bus;
	int addr, rc, i;
	u8 reg;

	/*
	 * prevent i2c xfer attempts after device is disconnected
	 * some fe's try to do i2c writes/reads from their release
	 * interfaces when called in disconnect path
	 */
	if (dev->disconnected)
		return -ENODEV;

	if (!rt_mutex_trylock(&dev->i2c_bus_lock))
		return -EAGAIN;

	/* Switch I2C bus if needed */
	if (bus != dev->cur_i2c_bus &&
	    i2c_bus->algo_type == EM28XX_I2C_ALGO_EM28XX) {
		if (bus == 1)
			reg = EM2874_I2C_SECONDARY_BUS_SELECT;
		else
			reg = 0;
		em28xx_write_reg_bits(dev, EM28XX_R06_I2C_CLK, reg,
				      EM2874_I2C_SECONDARY_BUS_SELECT);
		dev->cur_i2c_bus = bus;
	}

	for (i = 0; i < num; i++) {
		addr = msgs[i].addr << 1;
		if (!msgs[i].len) {
			/*
			 * no len: check only for device presence
			 * This code is only called during device probe.
			 */
			rc = i2c_check_for_device(i2c_bus, addr);

			if (rc == -ENXIO)
				rc = -ENODEV;
		} else if (msgs[i].flags & I2C_M_RD) {
			/* read bytes */
			rc = i2c_recv_bytes(i2c_bus, msgs[i]);
		} else {
			/* write bytes */
			rc = i2c_send_bytes(i2c_bus, msgs[i], i == num - 1);
		}

		if (rc < 0)
			goto error;

		dprintk(2, "%s %s addr=%02x len=%d: %*ph\n",
			(msgs[i].flags & I2C_M_RD) ? "read" : "write",
			i == num - 1 ? "stop" : "nonstop",
			addr, msgs[i].len,
			msgs[i].len, msgs[i].buf);
	}

	rt_mutex_unlock(&dev->i2c_bus_lock);
	return num;

error:
	dprintk(2, "%s %s addr=%02x len=%d: %sERROR: %i\n",
		(msgs[i].flags & I2C_M_RD) ? "read" : "write",
		i == num - 1 ? "stop" : "nonstop",
		addr, msgs[i].len,
		(rc == -ENODEV) ? "no device " : "",
		rc);

	rt_mutex_unlock(&dev->i2c_bus_lock);
	return rc;
}

/*
 * based on linux/sunrpc/svcauth.h and linux/hash.h
 * The original hash function returns a different value, if arch is x86_64
 * or i386.
 */
static inline unsigned long em28xx_hash_mem(char *buf, int length, int bits)
{
	unsigned long hash = 0;
	unsigned long l = 0;
	int len = 0;
	unsigned char c;

	do {
		if (len == length) {
			c = (char)len;
			len = -1;
		} else {
			c = *buf++;
		}
		l = (l << 8) | c;
		len++;
		if ((len & (32 / 8 - 1)) == 0)
			hash = ((hash ^ l) * 0x9e370001UL);
	} while (len);

	return (hash >> (32 - bits)) & 0xffffffffUL;
}

/*
 * Helper function to read data blocks from i2c clients with 8 or 16 bit
 * address width, 8 bit register width and auto incrementation been activated
 */
static int em28xx_i2c_read_block(struct em28xx *dev, unsigned int bus, u16 addr,
				 bool addr_w16, u16 len, u8 *data)
{
	int remain = len, rsize, rsize_max, ret;
	u8 buf[2];

	/* Sanity check */
	if (addr + remain > (addr_w16 * 0xff00 + 0xff + 1))
		return -EINVAL;
	/* Select address */
	buf[0] = addr >> 8;
	buf[1] = addr & 0xff;
	ret = i2c_master_send(&dev->i2c_client[bus],
			      buf + !addr_w16, 1 + addr_w16);
	if (ret < 0)
		return ret;
	/* Read data */
	if (dev->board.is_em2800)
		rsize_max = 4;
	else
		rsize_max = 64;
	while (remain > 0) {
		if (remain > rsize_max)
			rsize = rsize_max;
		else
			rsize = remain;

		ret = i2c_master_recv(&dev->i2c_client[bus], data, rsize);
		if (ret < 0)
			return ret;

		remain -= rsize;
		data += rsize;
	}

	return len;
}

static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned int bus,
			     u8 **eedata, u16 *eedata_len)
{
	const u16 len = 256;
	/*
	 * FIXME common length/size for bytes to read, to display, hash
	 * calculation and returned device dataset. Simplifies the code a lot,
	 * but we might have to deal with multiple sizes in the future !
	 */
	int err;
	struct em28xx_eeprom *dev_config;
	u8 buf, *data;

	*eedata = NULL;
	*eedata_len = 0;

	/* EEPROM is always on i2c bus 0 on all known devices. */

	dev->i2c_client[bus].addr = 0xa0 >> 1;

	/* Check if board has eeprom */
	err = i2c_master_recv(&dev->i2c_client[bus], &buf, 0);
	if (err < 0) {
		dev_info(&dev->intf->dev, "board has no eeprom\n");
		return -ENODEV;
	}

	data = kzalloc(len, GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	/* Read EEPROM content */
	err = em28xx_i2c_read_block(dev, bus, 0x0000,
				    dev->eeprom_addrwidth_16bit,
				    len, data);
	if (err != len) {
		dev_err(&dev->intf->dev,
			"failed to read eeprom (err=%d)\n", err);
		goto error;
	}

	if (i2c_debug) {
		/* Display eeprom content */
		print_hex_dump(KERN_DEBUG, "em28xx eeprom ", DUMP_PREFIX_OFFSET,
			       16, 1, data, len, true);

		if (dev->eeprom_addrwidth_16bit)
			dev_info(&dev->intf->dev,
				 "eeprom %06x: ... (skipped)\n", 256);
	}

	if (dev->eeprom_addrwidth_16bit &&
	    data[0] == 0x26 && data[3] == 0x00) {
		/* new eeprom format; size 4-64kb */
		u16 mc_start;
		u16 hwconf_offset;

		dev->hash = em28xx_hash_mem(data, len, 32);
		mc_start = (data[1] << 8) + 4;	/* usually 0x0004 */

		dev_info(&dev->intf->dev,
			 "EEPROM ID = %4ph, EEPROM hash = 0x%08lx\n",
			 data, dev->hash);
		dev_info(&dev->intf->dev,
			 "EEPROM info:\n");
		dev_info(&dev->intf->dev,
			 "\tmicrocode start address = 0x%04x, boot configuration = 0x%02x\n",
			 mc_start, data[2]);
		/*
		 * boot configuration (address 0x0002):
		 * [0]   microcode download speed: 1 = 400 kHz; 0 = 100 kHz
		 * [1]   always selects 12 kb RAM
		 * [2]   USB device speed: 1 = force Full Speed; 0 = auto detect
		 * [4]   1 = force fast mode and no suspend for device testing
		 * [5:7] USB PHY tuning registers; determined by device
		 *       characterization
		 */

		/*
		 * Read hardware config dataset offset from address
		 * (microcode start + 46)
		 */
		err = em28xx_i2c_read_block(dev, bus, mc_start + 46, 1, 2,
					    data);
		if (err != 2) {
			dev_err(&dev->intf->dev,
				"failed to read hardware configuration data from eeprom (err=%d)\n",
				err);
			goto error;
		}

		/* Calculate hardware config dataset start address */
		hwconf_offset = mc_start + data[0] + (data[1] << 8);

		/* Read hardware config dataset */
		/*
		 * NOTE: the microcode copy can be multiple pages long, but
		 * we assume the hardware config dataset is the same as in
		 * the old eeprom and not longer than 256 bytes.
		 * tveeprom is currently also limited to 256 bytes.
		 */
		err = em28xx_i2c_read_block(dev, bus, hwconf_offset, 1, len,
					    data);
		if (err != len) {
			dev_err(&dev->intf->dev,
				"failed to read hardware configuration data from eeprom (err=%d)\n",
				err);
			goto error;
		}

		/* Verify hardware config dataset */
		/* NOTE: not all devices provide this type of dataset */
		if (data[0] != 0x1a || data[1] != 0xeb ||
		    data[2] != 0x67 || data[3] != 0x95) {
			dev_info(&dev->intf->dev,
				 "\tno hardware configuration dataset found in eeprom\n");
			kfree(data);
			return 0;
		}

		/*
		 * TODO: decrypt eeprom data for camera bridges
		 * (em25xx, em276x+)
		 */

	} else if (!dev->eeprom_addrwidth_16bit &&
		   data[0] == 0x1a && data[1] == 0xeb &&
		   data[2] == 0x67 && data[3] == 0x95) {
		dev->hash = em28xx_hash_mem(data, len, 32);
		dev_info(&dev->intf->dev,
			 "EEPROM ID = %4ph, EEPROM hash = 0x%08lx\n",
			 data, dev->hash);
		dev_info(&dev->intf->dev,
			 "EEPROM info:\n");
	} else {
		dev_info(&dev->intf->dev,
			 "unknown eeprom format or eeprom corrupted !\n");
		err = -ENODEV;
		goto error;
	}

	*eedata = data;
	*eedata_len = len;
	dev_config = (void *)*eedata;

	switch (le16_to_cpu(dev_config->chip_conf) >> 4 & 0x3) {
	case 0:
		dev_info(&dev->intf->dev, "\tNo audio on board.\n");
		break;
	case 1:
		dev_info(&dev->intf->dev, "\tAC97 audio (5 sample rates)\n");
		break;
	case 2:
		if (dev->chip_id < CHIP_ID_EM2860)
			dev_info(&dev->intf->dev,
				 "\tI2S audio, sample rate=32k\n");
		else
			dev_info(&dev->intf->dev,
				 "\tI2S audio, 3 sample rates\n");
		break;
	case 3:
		if (dev->chip_id < CHIP_ID_EM2860)
			dev_info(&dev->intf->dev,
				 "\tI2S audio, 3 sample rates\n");
		else
			dev_info(&dev->intf->dev,
				 "\tI2S audio, 5 sample rates\n");
		break;
	}

	if (le16_to_cpu(dev_config->chip_conf) & 1 << 3)
		dev_info(&dev->intf->dev, "\tUSB Remote wakeup capable\n");

	if (le16_to_cpu(dev_config->chip_conf) & 1 << 2)
		dev_info(&dev->intf->dev, "\tUSB Self power capable\n");

	switch (le16_to_cpu(dev_config->chip_conf) & 0x3) {
	case 0:
		dev_info(&dev->intf->dev, "\t500mA max power\n");
		break;
	case 1:
		dev_info(&dev->intf->dev, "\t400mA max power\n");
		break;
	case 2:
		dev_info(&dev->intf->dev, "\t300mA max power\n");
		break;
	case 3:
		dev_info(&dev->intf->dev, "\t200mA max power\n");
		break;
	}
	dev_info(&dev->intf->dev,
		 "\tTable at offset 0x%02x, strings=0x%04x, 0x%04x, 0x%04x\n",
		 dev_config->string_idx_table,
		 le16_to_cpu(dev_config->string1),
		 le16_to_cpu(dev_config->string2),
		 le16_to_cpu(dev_config->string3));

	return 0;

error:
	kfree(data);
	return err;
}

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

/*
 * functionality()
 */
static u32 functionality(struct i2c_adapter *i2c_adap)
{
	struct em28xx_i2c_bus *i2c_bus = i2c_adap->algo_data;

	if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM28XX ||
	    i2c_bus->algo_type == EM28XX_I2C_ALGO_EM25XX_BUS_B) {
		return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
	} else if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM2800)  {
		return (I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL) &
			~I2C_FUNC_SMBUS_WRITE_BLOCK_DATA;
	}

	WARN(1, "Unknown i2c bus algorithm.\n");
	return 0;
}

static const struct i2c_algorithm em28xx_algo = {
	.master_xfer   = em28xx_i2c_xfer,
	.functionality = functionality,
};

static const struct i2c_adapter em28xx_adap_template = {
	.owner = THIS_MODULE,
	.name = "em28xx",
	.algo = &em28xx_algo,
};

static const struct i2c_client em28xx_client_template = {
	.name = "em28xx internal",
};

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

/*
 * i2c_devs
 * incomplete list of known devices
 */
static char *i2c_devs[128] = {
	[0x1c >> 1] = "lgdt330x",
	[0x3e >> 1] = "remote IR sensor",
	[0x4a >> 1] = "saa7113h",
	[0x52 >> 1] = "drxk",
	[0x60 >> 1] = "remote IR sensor",
	[0x8e >> 1] = "remote IR sensor",
	[0x86 >> 1] = "tda9887",
	[0x80 >> 1] = "msp34xx",
	[0x88 >> 1] = "msp34xx",
	[0xa0 >> 1] = "eeprom",
	[0xb0 >> 1] = "tda9874",
	[0xb8 >> 1] = "tvp5150a",
	[0xba >> 1] = "webcam sensor or tvp5150a",
	[0xc0 >> 1] = "tuner (analog)",
	[0xc2 >> 1] = "tuner (analog)",
	[0xc4 >> 1] = "tuner (analog)",
	[0xc6 >> 1] = "tuner (analog)",
};

/*
 * do_i2c_scan()
 * check i2c address range for devices
 */
void em28xx_do_i2c_scan(struct em28xx *dev, unsigned int bus)
{
	u8 i2c_devicelist[128];
	unsigned char buf;
	int i, rc;

	memset(i2c_devicelist, 0, ARRAY_SIZE(i2c_devicelist));

	for (i = 0; i < ARRAY_SIZE(i2c_devs); i++) {
		dev->i2c_client[bus].addr = i;
		rc = i2c_master_recv(&dev->i2c_client[bus], &buf, 0);
		if (rc < 0)
			continue;
		i2c_devicelist[i] = i;
		dev_info(&dev->intf->dev,
			 "found i2c device @ 0x%x on bus %d [%s]\n",
			 i << 1, bus, i2c_devs[i] ? i2c_devs[i] : "???");
	}

	if (bus == dev->def_i2c_bus)
		dev->i2c_hash = em28xx_hash_mem(i2c_devicelist,
						ARRAY_SIZE(i2c_devicelist), 32);
}

/*
 * em28xx_i2c_register()
 * register i2c bus
 */
int em28xx_i2c_register(struct em28xx *dev, unsigned int bus,
			enum em28xx_i2c_algo_type algo_type)
{
	int retval;

	if (WARN_ON(!dev->em28xx_write_regs || !dev->em28xx_read_reg ||
		    !dev->em28xx_write_regs_req || !dev->em28xx_read_reg_req))
		return -ENODEV;

	if (bus >= NUM_I2C_BUSES)
		return -ENODEV;

	dev->i2c_adap[bus] = em28xx_adap_template;
	dev->i2c_adap[bus].dev.parent = &dev->intf->dev;
	strcpy(dev->i2c_adap[bus].name, dev_name(&dev->intf->dev));

	dev->i2c_bus[bus].bus = bus;
	dev->i2c_bus[bus].algo_type = algo_type;
	dev->i2c_bus[bus].dev = dev;
	dev->i2c_adap[bus].algo_data = &dev->i2c_bus[bus];

	retval = i2c_add_adapter(&dev->i2c_adap[bus]);
	if (retval < 0) {
		dev_err(&dev->intf->dev,
			"%s: i2c_add_adapter failed! retval [%d]\n",
			__func__, retval);
		return retval;
	}

	dev->i2c_client[bus] = em28xx_client_template;
	dev->i2c_client[bus].adapter = &dev->i2c_adap[bus];

	/* Up to now, all eeproms are at bus 0 */
	if (!bus) {
		retval = em28xx_i2c_eeprom(dev, bus,
					   &dev->eedata, &dev->eedata_len);
		if (retval < 0 && retval != -ENODEV) {
			dev_err(&dev->intf->dev,
				"%s: em28xx_i2_eeprom failed! retval [%d]\n",
				__func__, retval);
		}
	}

	if (i2c_scan)
		em28xx_do_i2c_scan(dev, bus);

	return 0;
}

/*
 * em28xx_i2c_unregister()
 * unregister i2c_bus
 */
int em28xx_i2c_unregister(struct em28xx *dev, unsigned int bus)
{
	if (bus >= NUM_I2C_BUSES)
		return -ENODEV;

	i2c_del_adapter(&dev->i2c_adap[bus]);
	return 0;
}
