// 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;
	}

	if (num <= 0) {
		rt_mutex_unlock(&dev->i2c_bus_lock);
		return 0;
	}
	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;
}
