162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0+
262306a36Sopenharmony_ci//
362306a36Sopenharmony_ci// em28xx-i2c.c - driver for Empia EM2800/EM2820/2840 USB video capture devices
462306a36Sopenharmony_ci//
562306a36Sopenharmony_ci// Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it>
662306a36Sopenharmony_ci//		      Markus Rechberger <mrechberger@gmail.com>
762306a36Sopenharmony_ci//		      Mauro Carvalho Chehab <mchehab@kernel.org>
862306a36Sopenharmony_ci//		      Sascha Sommer <saschasommer@freenet.de>
962306a36Sopenharmony_ci// Copyright (C) 2013 Frank Schäfer <fschaefer.oss@googlemail.com>
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#include "em28xx.h"
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci#include <linux/module.h>
1462306a36Sopenharmony_ci#include <linux/kernel.h>
1562306a36Sopenharmony_ci#include <linux/usb.h>
1662306a36Sopenharmony_ci#include <linux/i2c.h>
1762306a36Sopenharmony_ci#include <linux/jiffies.h>
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci#include "xc2028.h"
2062306a36Sopenharmony_ci#include <media/v4l2-common.h>
2162306a36Sopenharmony_ci#include <media/tuner.h>
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ci/* ----------------------------------------------------------- */
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_cistatic unsigned int i2c_scan;
2662306a36Sopenharmony_cimodule_param(i2c_scan, int, 0444);
2762306a36Sopenharmony_ciMODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time");
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_cistatic unsigned int i2c_debug;
3062306a36Sopenharmony_cimodule_param(i2c_debug, int, 0644);
3162306a36Sopenharmony_ciMODULE_PARM_DESC(i2c_debug, "i2c debug message level (1: normal debug, 2: show I2C transfers)");
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ci#define dprintk(level, fmt, arg...) do {				\
3462306a36Sopenharmony_ci	if (i2c_debug > level)						\
3562306a36Sopenharmony_ci		dev_printk(KERN_DEBUG, &dev->intf->dev,			\
3662306a36Sopenharmony_ci			   "i2c: %s: " fmt, __func__, ## arg);		\
3762306a36Sopenharmony_ci} while (0)
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci/*
4062306a36Sopenharmony_ci * Time in msecs to wait for i2c xfers to finish.
4162306a36Sopenharmony_ci * 35ms is the maximum time a SMBUS device could wait when
4262306a36Sopenharmony_ci * clock stretching is used. As the transfer itself will take
4362306a36Sopenharmony_ci * some time to happen, set it to 35 ms.
4462306a36Sopenharmony_ci *
4562306a36Sopenharmony_ci * Ok, I2C doesn't specify any limit. So, eventually, we may need
4662306a36Sopenharmony_ci * to increase this timeout.
4762306a36Sopenharmony_ci */
4862306a36Sopenharmony_ci#define EM28XX_I2C_XFER_TIMEOUT         35 /* ms */
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_cistatic int em28xx_i2c_timeout(struct em28xx *dev)
5162306a36Sopenharmony_ci{
5262306a36Sopenharmony_ci	int time = EM28XX_I2C_XFER_TIMEOUT;
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_ci	switch (dev->i2c_speed & 0x03) {
5562306a36Sopenharmony_ci	case EM28XX_I2C_FREQ_25_KHZ:
5662306a36Sopenharmony_ci		time += 4;		/* Assume 4 ms for transfers */
5762306a36Sopenharmony_ci		break;
5862306a36Sopenharmony_ci	case EM28XX_I2C_FREQ_100_KHZ:
5962306a36Sopenharmony_ci	case EM28XX_I2C_FREQ_400_KHZ:
6062306a36Sopenharmony_ci		time += 1;		/* Assume 1 ms for transfers */
6162306a36Sopenharmony_ci		break;
6262306a36Sopenharmony_ci	default: /* EM28XX_I2C_FREQ_1_5_MHZ */
6362306a36Sopenharmony_ci		break;
6462306a36Sopenharmony_ci	}
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_ci	return msecs_to_jiffies(time);
6762306a36Sopenharmony_ci}
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_ci/*
7062306a36Sopenharmony_ci * em2800_i2c_send_bytes()
7162306a36Sopenharmony_ci * send up to 4 bytes to the em2800 i2c device
7262306a36Sopenharmony_ci */
7362306a36Sopenharmony_cistatic int em2800_i2c_send_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len)
7462306a36Sopenharmony_ci{
7562306a36Sopenharmony_ci	unsigned long timeout = jiffies + em28xx_i2c_timeout(dev);
7662306a36Sopenharmony_ci	int ret;
7762306a36Sopenharmony_ci	u8 b2[6];
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_ci	if (len < 1 || len > 4)
8062306a36Sopenharmony_ci		return -EOPNOTSUPP;
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_ci	b2[5] = 0x80 + len - 1;
8362306a36Sopenharmony_ci	b2[4] = addr;
8462306a36Sopenharmony_ci	b2[3] = buf[0];
8562306a36Sopenharmony_ci	if (len > 1)
8662306a36Sopenharmony_ci		b2[2] = buf[1];
8762306a36Sopenharmony_ci	if (len > 2)
8862306a36Sopenharmony_ci		b2[1] = buf[2];
8962306a36Sopenharmony_ci	if (len > 3)
9062306a36Sopenharmony_ci		b2[0] = buf[3];
9162306a36Sopenharmony_ci
9262306a36Sopenharmony_ci	/* trigger write */
9362306a36Sopenharmony_ci	ret = dev->em28xx_write_regs(dev, 4 - len, &b2[4 - len], 2 + len);
9462306a36Sopenharmony_ci	if (ret != 2 + len) {
9562306a36Sopenharmony_ci		dev_warn(&dev->intf->dev,
9662306a36Sopenharmony_ci			 "failed to trigger write to i2c address 0x%x (error=%i)\n",
9762306a36Sopenharmony_ci			    addr, ret);
9862306a36Sopenharmony_ci		return (ret < 0) ? ret : -EIO;
9962306a36Sopenharmony_ci	}
10062306a36Sopenharmony_ci	/* wait for completion */
10162306a36Sopenharmony_ci	while (time_is_after_jiffies(timeout)) {
10262306a36Sopenharmony_ci		ret = dev->em28xx_read_reg(dev, 0x05);
10362306a36Sopenharmony_ci		if (ret == 0x80 + len - 1)
10462306a36Sopenharmony_ci			return len;
10562306a36Sopenharmony_ci		if (ret == 0x94 + len - 1) {
10662306a36Sopenharmony_ci			dprintk(1, "R05 returned 0x%02x: I2C ACK error\n", ret);
10762306a36Sopenharmony_ci			return -ENXIO;
10862306a36Sopenharmony_ci		}
10962306a36Sopenharmony_ci		if (ret < 0) {
11062306a36Sopenharmony_ci			dev_warn(&dev->intf->dev,
11162306a36Sopenharmony_ci				 "failed to get i2c transfer status from bridge register (error=%i)\n",
11262306a36Sopenharmony_ci				ret);
11362306a36Sopenharmony_ci			return ret;
11462306a36Sopenharmony_ci		}
11562306a36Sopenharmony_ci		usleep_range(5000, 6000);
11662306a36Sopenharmony_ci	}
11762306a36Sopenharmony_ci	dprintk(0, "write to i2c device at 0x%x timed out\n", addr);
11862306a36Sopenharmony_ci	return -ETIMEDOUT;
11962306a36Sopenharmony_ci}
12062306a36Sopenharmony_ci
12162306a36Sopenharmony_ci/*
12262306a36Sopenharmony_ci * em2800_i2c_recv_bytes()
12362306a36Sopenharmony_ci * read up to 4 bytes from the em2800 i2c device
12462306a36Sopenharmony_ci */
12562306a36Sopenharmony_cistatic int em2800_i2c_recv_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len)
12662306a36Sopenharmony_ci{
12762306a36Sopenharmony_ci	unsigned long timeout = jiffies + em28xx_i2c_timeout(dev);
12862306a36Sopenharmony_ci	u8 buf2[4];
12962306a36Sopenharmony_ci	int ret;
13062306a36Sopenharmony_ci	int i;
13162306a36Sopenharmony_ci
13262306a36Sopenharmony_ci	if (len < 1 || len > 4)
13362306a36Sopenharmony_ci		return -EOPNOTSUPP;
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_ci	/* trigger read */
13662306a36Sopenharmony_ci	buf2[1] = 0x84 + len - 1;
13762306a36Sopenharmony_ci	buf2[0] = addr;
13862306a36Sopenharmony_ci	ret = dev->em28xx_write_regs(dev, 0x04, buf2, 2);
13962306a36Sopenharmony_ci	if (ret != 2) {
14062306a36Sopenharmony_ci		dev_warn(&dev->intf->dev,
14162306a36Sopenharmony_ci			 "failed to trigger read from i2c address 0x%x (error=%i)\n",
14262306a36Sopenharmony_ci			 addr, ret);
14362306a36Sopenharmony_ci		return (ret < 0) ? ret : -EIO;
14462306a36Sopenharmony_ci	}
14562306a36Sopenharmony_ci
14662306a36Sopenharmony_ci	/* wait for completion */
14762306a36Sopenharmony_ci	while (time_is_after_jiffies(timeout)) {
14862306a36Sopenharmony_ci		ret = dev->em28xx_read_reg(dev, 0x05);
14962306a36Sopenharmony_ci		if (ret == 0x84 + len - 1)
15062306a36Sopenharmony_ci			break;
15162306a36Sopenharmony_ci		if (ret == 0x94 + len - 1) {
15262306a36Sopenharmony_ci			dprintk(1, "R05 returned 0x%02x: I2C ACK error\n",
15362306a36Sopenharmony_ci				ret);
15462306a36Sopenharmony_ci			return -ENXIO;
15562306a36Sopenharmony_ci		}
15662306a36Sopenharmony_ci		if (ret < 0) {
15762306a36Sopenharmony_ci			dev_warn(&dev->intf->dev,
15862306a36Sopenharmony_ci				 "failed to get i2c transfer status from bridge register (error=%i)\n",
15962306a36Sopenharmony_ci				 ret);
16062306a36Sopenharmony_ci			return ret;
16162306a36Sopenharmony_ci		}
16262306a36Sopenharmony_ci		usleep_range(5000, 6000);
16362306a36Sopenharmony_ci	}
16462306a36Sopenharmony_ci	if (ret != 0x84 + len - 1)
16562306a36Sopenharmony_ci		dprintk(0, "read from i2c device at 0x%x timed out\n", addr);
16662306a36Sopenharmony_ci
16762306a36Sopenharmony_ci	/* get the received message */
16862306a36Sopenharmony_ci	ret = dev->em28xx_read_reg_req_len(dev, 0x00, 4 - len, buf2, len);
16962306a36Sopenharmony_ci	if (ret != len) {
17062306a36Sopenharmony_ci		dev_warn(&dev->intf->dev,
17162306a36Sopenharmony_ci			 "reading from i2c device at 0x%x failed: couldn't get the received message from the bridge (error=%i)\n",
17262306a36Sopenharmony_ci			 addr, ret);
17362306a36Sopenharmony_ci		return (ret < 0) ? ret : -EIO;
17462306a36Sopenharmony_ci	}
17562306a36Sopenharmony_ci	for (i = 0; i < len; i++)
17662306a36Sopenharmony_ci		buf[i] = buf2[len - 1 - i];
17762306a36Sopenharmony_ci
17862306a36Sopenharmony_ci	return ret;
17962306a36Sopenharmony_ci}
18062306a36Sopenharmony_ci
18162306a36Sopenharmony_ci/*
18262306a36Sopenharmony_ci * em2800_i2c_check_for_device()
18362306a36Sopenharmony_ci * check if there is an i2c device at the supplied address
18462306a36Sopenharmony_ci */
18562306a36Sopenharmony_cistatic int em2800_i2c_check_for_device(struct em28xx *dev, u8 addr)
18662306a36Sopenharmony_ci{
18762306a36Sopenharmony_ci	u8 buf;
18862306a36Sopenharmony_ci	int ret;
18962306a36Sopenharmony_ci
19062306a36Sopenharmony_ci	ret = em2800_i2c_recv_bytes(dev, addr, &buf, 1);
19162306a36Sopenharmony_ci	if (ret == 1)
19262306a36Sopenharmony_ci		return 0;
19362306a36Sopenharmony_ci	return (ret < 0) ? ret : -EIO;
19462306a36Sopenharmony_ci}
19562306a36Sopenharmony_ci
19662306a36Sopenharmony_ci/*
19762306a36Sopenharmony_ci * em28xx_i2c_send_bytes()
19862306a36Sopenharmony_ci */
19962306a36Sopenharmony_cistatic int em28xx_i2c_send_bytes(struct em28xx *dev, u16 addr, u8 *buf,
20062306a36Sopenharmony_ci				 u16 len, int stop)
20162306a36Sopenharmony_ci{
20262306a36Sopenharmony_ci	unsigned long timeout = jiffies + em28xx_i2c_timeout(dev);
20362306a36Sopenharmony_ci	int ret;
20462306a36Sopenharmony_ci
20562306a36Sopenharmony_ci	if (len < 1 || len > 64)
20662306a36Sopenharmony_ci		return -EOPNOTSUPP;
20762306a36Sopenharmony_ci	/*
20862306a36Sopenharmony_ci	 * NOTE: limited by the USB ctrl message constraints
20962306a36Sopenharmony_ci	 * Zero length reads always succeed, even if no device is connected
21062306a36Sopenharmony_ci	 */
21162306a36Sopenharmony_ci
21262306a36Sopenharmony_ci	/* Write to i2c device */
21362306a36Sopenharmony_ci	ret = dev->em28xx_write_regs_req(dev, stop ? 2 : 3, addr, buf, len);
21462306a36Sopenharmony_ci	if (ret != len) {
21562306a36Sopenharmony_ci		if (ret < 0) {
21662306a36Sopenharmony_ci			dev_warn(&dev->intf->dev,
21762306a36Sopenharmony_ci				 "writing to i2c device at 0x%x failed (error=%i)\n",
21862306a36Sopenharmony_ci				 addr, ret);
21962306a36Sopenharmony_ci			return ret;
22062306a36Sopenharmony_ci		}
22162306a36Sopenharmony_ci		dev_warn(&dev->intf->dev,
22262306a36Sopenharmony_ci			 "%i bytes write to i2c device at 0x%x requested, but %i bytes written\n",
22362306a36Sopenharmony_ci				len, addr, ret);
22462306a36Sopenharmony_ci		return -EIO;
22562306a36Sopenharmony_ci	}
22662306a36Sopenharmony_ci
22762306a36Sopenharmony_ci	/* wait for completion */
22862306a36Sopenharmony_ci	while (time_is_after_jiffies(timeout)) {
22962306a36Sopenharmony_ci		ret = dev->em28xx_read_reg(dev, 0x05);
23062306a36Sopenharmony_ci		if (ret == 0) /* success */
23162306a36Sopenharmony_ci			return len;
23262306a36Sopenharmony_ci		if (ret == 0x10) {
23362306a36Sopenharmony_ci			dprintk(1, "I2C ACK error on writing to addr 0x%02x\n",
23462306a36Sopenharmony_ci				addr);
23562306a36Sopenharmony_ci			return -ENXIO;
23662306a36Sopenharmony_ci		}
23762306a36Sopenharmony_ci		if (ret < 0) {
23862306a36Sopenharmony_ci			dev_warn(&dev->intf->dev,
23962306a36Sopenharmony_ci				 "failed to get i2c transfer status from bridge register (error=%i)\n",
24062306a36Sopenharmony_ci				 ret);
24162306a36Sopenharmony_ci			return ret;
24262306a36Sopenharmony_ci		}
24362306a36Sopenharmony_ci		usleep_range(5000, 6000);
24462306a36Sopenharmony_ci		/*
24562306a36Sopenharmony_ci		 * NOTE: do we really have to wait for success ?
24662306a36Sopenharmony_ci		 * Never seen anything else than 0x00 or 0x10
24762306a36Sopenharmony_ci		 * (even with high payload) ...
24862306a36Sopenharmony_ci		 */
24962306a36Sopenharmony_ci	}
25062306a36Sopenharmony_ci
25162306a36Sopenharmony_ci	if (ret == 0x02 || ret == 0x04) {
25262306a36Sopenharmony_ci		/* NOTE: these errors seem to be related to clock stretching */
25362306a36Sopenharmony_ci		dprintk(0,
25462306a36Sopenharmony_ci			"write to i2c device at 0x%x timed out (status=%i)\n",
25562306a36Sopenharmony_ci			addr, ret);
25662306a36Sopenharmony_ci		return -ETIMEDOUT;
25762306a36Sopenharmony_ci	}
25862306a36Sopenharmony_ci
25962306a36Sopenharmony_ci	dev_warn(&dev->intf->dev,
26062306a36Sopenharmony_ci		 "write to i2c device at 0x%x failed with unknown error (status=%i)\n",
26162306a36Sopenharmony_ci		 addr, ret);
26262306a36Sopenharmony_ci	return -EIO;
26362306a36Sopenharmony_ci}
26462306a36Sopenharmony_ci
26562306a36Sopenharmony_ci/*
26662306a36Sopenharmony_ci * em28xx_i2c_recv_bytes()
26762306a36Sopenharmony_ci * read a byte from the i2c device
26862306a36Sopenharmony_ci */
26962306a36Sopenharmony_cistatic int em28xx_i2c_recv_bytes(struct em28xx *dev, u16 addr, u8 *buf, u16 len)
27062306a36Sopenharmony_ci{
27162306a36Sopenharmony_ci	int ret;
27262306a36Sopenharmony_ci
27362306a36Sopenharmony_ci	if (len < 1 || len > 64)
27462306a36Sopenharmony_ci		return -EOPNOTSUPP;
27562306a36Sopenharmony_ci	/*
27662306a36Sopenharmony_ci	 * NOTE: limited by the USB ctrl message constraints
27762306a36Sopenharmony_ci	 * Zero length reads always succeed, even if no device is connected
27862306a36Sopenharmony_ci	 */
27962306a36Sopenharmony_ci
28062306a36Sopenharmony_ci	/* Read data from i2c device */
28162306a36Sopenharmony_ci	ret = dev->em28xx_read_reg_req_len(dev, 2, addr, buf, len);
28262306a36Sopenharmony_ci	if (ret < 0) {
28362306a36Sopenharmony_ci		dev_warn(&dev->intf->dev,
28462306a36Sopenharmony_ci			 "reading from i2c device at 0x%x failed (error=%i)\n",
28562306a36Sopenharmony_ci			 addr, ret);
28662306a36Sopenharmony_ci		return ret;
28762306a36Sopenharmony_ci	} else if (ret != len) {
28862306a36Sopenharmony_ci		dev_dbg(&dev->intf->dev,
28962306a36Sopenharmony_ci			"%i bytes read from i2c device at 0x%x requested, but %i bytes written\n",
29062306a36Sopenharmony_ci				ret, addr, len);
29162306a36Sopenharmony_ci	}
29262306a36Sopenharmony_ci	/*
29362306a36Sopenharmony_ci	 * NOTE: some devices with two i2c buses have the bad habit to return 0
29462306a36Sopenharmony_ci	 * bytes if we are on bus B AND there was no write attempt to the
29562306a36Sopenharmony_ci	 * specified slave address before AND no device is present at the
29662306a36Sopenharmony_ci	 * requested slave address.
29762306a36Sopenharmony_ci	 * Anyway, the next check will fail with -ENXIO in this case, so avoid
29862306a36Sopenharmony_ci	 * spamming the system log on device probing and do nothing here.
29962306a36Sopenharmony_ci	 */
30062306a36Sopenharmony_ci
30162306a36Sopenharmony_ci	/* Check success of the i2c operation */
30262306a36Sopenharmony_ci	ret = dev->em28xx_read_reg(dev, 0x05);
30362306a36Sopenharmony_ci	if (ret == 0) /* success */
30462306a36Sopenharmony_ci		return len;
30562306a36Sopenharmony_ci	if (ret < 0) {
30662306a36Sopenharmony_ci		dev_warn(&dev->intf->dev,
30762306a36Sopenharmony_ci			 "failed to get i2c transfer status from bridge register (error=%i)\n",
30862306a36Sopenharmony_ci			 ret);
30962306a36Sopenharmony_ci		return ret;
31062306a36Sopenharmony_ci	}
31162306a36Sopenharmony_ci	if (ret == 0x10) {
31262306a36Sopenharmony_ci		dprintk(1, "I2C ACK error on writing to addr 0x%02x\n",
31362306a36Sopenharmony_ci			addr);
31462306a36Sopenharmony_ci		return -ENXIO;
31562306a36Sopenharmony_ci	}
31662306a36Sopenharmony_ci
31762306a36Sopenharmony_ci	if (ret == 0x02 || ret == 0x04) {
31862306a36Sopenharmony_ci		/* NOTE: these errors seem to be related to clock stretching */
31962306a36Sopenharmony_ci		dprintk(0,
32062306a36Sopenharmony_ci			"write to i2c device at 0x%x timed out (status=%i)\n",
32162306a36Sopenharmony_ci			addr, ret);
32262306a36Sopenharmony_ci		return -ETIMEDOUT;
32362306a36Sopenharmony_ci	}
32462306a36Sopenharmony_ci
32562306a36Sopenharmony_ci	dev_warn(&dev->intf->dev,
32662306a36Sopenharmony_ci		 "read from i2c device at 0x%x failed with unknown error (status=%i)\n",
32762306a36Sopenharmony_ci		 addr, ret);
32862306a36Sopenharmony_ci	return -EIO;
32962306a36Sopenharmony_ci}
33062306a36Sopenharmony_ci
33162306a36Sopenharmony_ci/*
33262306a36Sopenharmony_ci * em28xx_i2c_check_for_device()
33362306a36Sopenharmony_ci * check if there is a i2c_device at the supplied address
33462306a36Sopenharmony_ci */
33562306a36Sopenharmony_cistatic int em28xx_i2c_check_for_device(struct em28xx *dev, u16 addr)
33662306a36Sopenharmony_ci{
33762306a36Sopenharmony_ci	int ret;
33862306a36Sopenharmony_ci	u8 buf;
33962306a36Sopenharmony_ci
34062306a36Sopenharmony_ci	ret = em28xx_i2c_recv_bytes(dev, addr, &buf, 1);
34162306a36Sopenharmony_ci	if (ret == 1)
34262306a36Sopenharmony_ci		return 0;
34362306a36Sopenharmony_ci	return (ret < 0) ? ret : -EIO;
34462306a36Sopenharmony_ci}
34562306a36Sopenharmony_ci
34662306a36Sopenharmony_ci/*
34762306a36Sopenharmony_ci * em25xx_bus_B_send_bytes
34862306a36Sopenharmony_ci * write bytes to the i2c device
34962306a36Sopenharmony_ci */
35062306a36Sopenharmony_cistatic int em25xx_bus_B_send_bytes(struct em28xx *dev, u16 addr, u8 *buf,
35162306a36Sopenharmony_ci				   u16 len)
35262306a36Sopenharmony_ci{
35362306a36Sopenharmony_ci	int ret;
35462306a36Sopenharmony_ci
35562306a36Sopenharmony_ci	if (len < 1 || len > 64)
35662306a36Sopenharmony_ci		return -EOPNOTSUPP;
35762306a36Sopenharmony_ci	/*
35862306a36Sopenharmony_ci	 * NOTE: limited by the USB ctrl message constraints
35962306a36Sopenharmony_ci	 * Zero length reads always succeed, even if no device is connected
36062306a36Sopenharmony_ci	 */
36162306a36Sopenharmony_ci
36262306a36Sopenharmony_ci	/* Set register and write value */
36362306a36Sopenharmony_ci	ret = dev->em28xx_write_regs_req(dev, 0x06, addr, buf, len);
36462306a36Sopenharmony_ci	if (ret != len) {
36562306a36Sopenharmony_ci		if (ret < 0) {
36662306a36Sopenharmony_ci			dev_warn(&dev->intf->dev,
36762306a36Sopenharmony_ci				 "writing to i2c device at 0x%x failed (error=%i)\n",
36862306a36Sopenharmony_ci				 addr, ret);
36962306a36Sopenharmony_ci			return ret;
37062306a36Sopenharmony_ci		}
37162306a36Sopenharmony_ci
37262306a36Sopenharmony_ci		dev_warn(&dev->intf->dev,
37362306a36Sopenharmony_ci			 "%i bytes write to i2c device at 0x%x requested, but %i bytes written\n",
37462306a36Sopenharmony_ci			 len, addr, ret);
37562306a36Sopenharmony_ci		return -EIO;
37662306a36Sopenharmony_ci	}
37762306a36Sopenharmony_ci	/* Check success */
37862306a36Sopenharmony_ci	ret = dev->em28xx_read_reg_req(dev, 0x08, 0x0000);
37962306a36Sopenharmony_ci	/*
38062306a36Sopenharmony_ci	 * NOTE: the only error we've seen so far is
38162306a36Sopenharmony_ci	 * 0x01 when the slave device is not present
38262306a36Sopenharmony_ci	 */
38362306a36Sopenharmony_ci	if (!ret)
38462306a36Sopenharmony_ci		return len;
38562306a36Sopenharmony_ci
38662306a36Sopenharmony_ci	if (ret > 0) {
38762306a36Sopenharmony_ci		dprintk(1, "Bus B R08 returned 0x%02x: I2C ACK error\n", ret);
38862306a36Sopenharmony_ci		return -ENXIO;
38962306a36Sopenharmony_ci	}
39062306a36Sopenharmony_ci
39162306a36Sopenharmony_ci	return ret;
39262306a36Sopenharmony_ci	/*
39362306a36Sopenharmony_ci	 * NOTE: With chip types (other chip IDs) which actually don't support
39462306a36Sopenharmony_ci	 * this operation, it seems to succeed ALWAYS ! (even if there is no
39562306a36Sopenharmony_ci	 * slave device or even no second i2c bus provided)
39662306a36Sopenharmony_ci	 */
39762306a36Sopenharmony_ci}
39862306a36Sopenharmony_ci
39962306a36Sopenharmony_ci/*
40062306a36Sopenharmony_ci * em25xx_bus_B_recv_bytes
40162306a36Sopenharmony_ci * read bytes from the i2c device
40262306a36Sopenharmony_ci */
40362306a36Sopenharmony_cistatic int em25xx_bus_B_recv_bytes(struct em28xx *dev, u16 addr, u8 *buf,
40462306a36Sopenharmony_ci				   u16 len)
40562306a36Sopenharmony_ci{
40662306a36Sopenharmony_ci	int ret;
40762306a36Sopenharmony_ci
40862306a36Sopenharmony_ci	if (len < 1 || len > 64)
40962306a36Sopenharmony_ci		return -EOPNOTSUPP;
41062306a36Sopenharmony_ci	/*
41162306a36Sopenharmony_ci	 * NOTE: limited by the USB ctrl message constraints
41262306a36Sopenharmony_ci	 * Zero length reads always succeed, even if no device is connected
41362306a36Sopenharmony_ci	 */
41462306a36Sopenharmony_ci
41562306a36Sopenharmony_ci	/* Read value */
41662306a36Sopenharmony_ci	ret = dev->em28xx_read_reg_req_len(dev, 0x06, addr, buf, len);
41762306a36Sopenharmony_ci	if (ret < 0) {
41862306a36Sopenharmony_ci		dev_warn(&dev->intf->dev,
41962306a36Sopenharmony_ci			 "reading from i2c device at 0x%x failed (error=%i)\n",
42062306a36Sopenharmony_ci			 addr, ret);
42162306a36Sopenharmony_ci		return ret;
42262306a36Sopenharmony_ci	}
42362306a36Sopenharmony_ci	/*
42462306a36Sopenharmony_ci	 * NOTE: some devices with two i2c buses have the bad habit to return 0
42562306a36Sopenharmony_ci	 * bytes if we are on bus B AND there was no write attempt to the
42662306a36Sopenharmony_ci	 * specified slave address before AND no device is present at the
42762306a36Sopenharmony_ci	 * requested slave address.
42862306a36Sopenharmony_ci	 * Anyway, the next check will fail with -ENXIO in this case, so avoid
42962306a36Sopenharmony_ci	 * spamming the system log on device probing and do nothing here.
43062306a36Sopenharmony_ci	 */
43162306a36Sopenharmony_ci
43262306a36Sopenharmony_ci	/* Check success */
43362306a36Sopenharmony_ci	ret = dev->em28xx_read_reg_req(dev, 0x08, 0x0000);
43462306a36Sopenharmony_ci	/*
43562306a36Sopenharmony_ci	 * NOTE: the only error we've seen so far is
43662306a36Sopenharmony_ci	 * 0x01 when the slave device is not present
43762306a36Sopenharmony_ci	 */
43862306a36Sopenharmony_ci	if (!ret)
43962306a36Sopenharmony_ci		return len;
44062306a36Sopenharmony_ci
44162306a36Sopenharmony_ci	if (ret > 0) {
44262306a36Sopenharmony_ci		dprintk(1, "Bus B R08 returned 0x%02x: I2C ACK error\n", ret);
44362306a36Sopenharmony_ci		return -ENXIO;
44462306a36Sopenharmony_ci	}
44562306a36Sopenharmony_ci
44662306a36Sopenharmony_ci	return ret;
44762306a36Sopenharmony_ci	/*
44862306a36Sopenharmony_ci	 * NOTE: With chip types (other chip IDs) which actually don't support
44962306a36Sopenharmony_ci	 * this operation, it seems to succeed ALWAYS ! (even if there is no
45062306a36Sopenharmony_ci	 * slave device or even no second i2c bus provided)
45162306a36Sopenharmony_ci	 */
45262306a36Sopenharmony_ci}
45362306a36Sopenharmony_ci
45462306a36Sopenharmony_ci/*
45562306a36Sopenharmony_ci * em25xx_bus_B_check_for_device()
45662306a36Sopenharmony_ci * check if there is a i2c device at the supplied address
45762306a36Sopenharmony_ci */
45862306a36Sopenharmony_cistatic int em25xx_bus_B_check_for_device(struct em28xx *dev, u16 addr)
45962306a36Sopenharmony_ci{
46062306a36Sopenharmony_ci	u8 buf;
46162306a36Sopenharmony_ci	int ret;
46262306a36Sopenharmony_ci
46362306a36Sopenharmony_ci	ret = em25xx_bus_B_recv_bytes(dev, addr, &buf, 1);
46462306a36Sopenharmony_ci	if (ret < 0)
46562306a36Sopenharmony_ci		return ret;
46662306a36Sopenharmony_ci
46762306a36Sopenharmony_ci	return 0;
46862306a36Sopenharmony_ci	/*
46962306a36Sopenharmony_ci	 * NOTE: With chips which do not support this operation,
47062306a36Sopenharmony_ci	 * it seems to succeed ALWAYS ! (even if no device connected)
47162306a36Sopenharmony_ci	 */
47262306a36Sopenharmony_ci}
47362306a36Sopenharmony_ci
47462306a36Sopenharmony_cistatic inline int i2c_check_for_device(struct em28xx_i2c_bus *i2c_bus, u16 addr)
47562306a36Sopenharmony_ci{
47662306a36Sopenharmony_ci	struct em28xx *dev = i2c_bus->dev;
47762306a36Sopenharmony_ci	int rc = -EOPNOTSUPP;
47862306a36Sopenharmony_ci
47962306a36Sopenharmony_ci	if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM28XX)
48062306a36Sopenharmony_ci		rc = em28xx_i2c_check_for_device(dev, addr);
48162306a36Sopenharmony_ci	else if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM2800)
48262306a36Sopenharmony_ci		rc = em2800_i2c_check_for_device(dev, addr);
48362306a36Sopenharmony_ci	else if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM25XX_BUS_B)
48462306a36Sopenharmony_ci		rc = em25xx_bus_B_check_for_device(dev, addr);
48562306a36Sopenharmony_ci	return rc;
48662306a36Sopenharmony_ci}
48762306a36Sopenharmony_ci
48862306a36Sopenharmony_cistatic inline int i2c_recv_bytes(struct em28xx_i2c_bus *i2c_bus,
48962306a36Sopenharmony_ci				 struct i2c_msg msg)
49062306a36Sopenharmony_ci{
49162306a36Sopenharmony_ci	struct em28xx *dev = i2c_bus->dev;
49262306a36Sopenharmony_ci	u16 addr = msg.addr << 1;
49362306a36Sopenharmony_ci	int rc = -EOPNOTSUPP;
49462306a36Sopenharmony_ci
49562306a36Sopenharmony_ci	if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM28XX)
49662306a36Sopenharmony_ci		rc = em28xx_i2c_recv_bytes(dev, addr, msg.buf, msg.len);
49762306a36Sopenharmony_ci	else if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM2800)
49862306a36Sopenharmony_ci		rc = em2800_i2c_recv_bytes(dev, addr, msg.buf, msg.len);
49962306a36Sopenharmony_ci	else if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM25XX_BUS_B)
50062306a36Sopenharmony_ci		rc = em25xx_bus_B_recv_bytes(dev, addr, msg.buf, msg.len);
50162306a36Sopenharmony_ci	return rc;
50262306a36Sopenharmony_ci}
50362306a36Sopenharmony_ci
50462306a36Sopenharmony_cistatic inline int i2c_send_bytes(struct em28xx_i2c_bus *i2c_bus,
50562306a36Sopenharmony_ci				 struct i2c_msg msg, int stop)
50662306a36Sopenharmony_ci{
50762306a36Sopenharmony_ci	struct em28xx *dev = i2c_bus->dev;
50862306a36Sopenharmony_ci	u16 addr = msg.addr << 1;
50962306a36Sopenharmony_ci	int rc = -EOPNOTSUPP;
51062306a36Sopenharmony_ci
51162306a36Sopenharmony_ci	if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM28XX)
51262306a36Sopenharmony_ci		rc = em28xx_i2c_send_bytes(dev, addr, msg.buf, msg.len, stop);
51362306a36Sopenharmony_ci	else if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM2800)
51462306a36Sopenharmony_ci		rc = em2800_i2c_send_bytes(dev, addr, msg.buf, msg.len);
51562306a36Sopenharmony_ci	else if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM25XX_BUS_B)
51662306a36Sopenharmony_ci		rc = em25xx_bus_B_send_bytes(dev, addr, msg.buf, msg.len);
51762306a36Sopenharmony_ci	return rc;
51862306a36Sopenharmony_ci}
51962306a36Sopenharmony_ci
52062306a36Sopenharmony_ci/*
52162306a36Sopenharmony_ci * em28xx_i2c_xfer()
52262306a36Sopenharmony_ci * the main i2c transfer function
52362306a36Sopenharmony_ci */
52462306a36Sopenharmony_cistatic int em28xx_i2c_xfer(struct i2c_adapter *i2c_adap,
52562306a36Sopenharmony_ci			   struct i2c_msg msgs[], int num)
52662306a36Sopenharmony_ci{
52762306a36Sopenharmony_ci	struct em28xx_i2c_bus *i2c_bus = i2c_adap->algo_data;
52862306a36Sopenharmony_ci	struct em28xx *dev = i2c_bus->dev;
52962306a36Sopenharmony_ci	unsigned int bus = i2c_bus->bus;
53062306a36Sopenharmony_ci	int addr, rc, i;
53162306a36Sopenharmony_ci	u8 reg;
53262306a36Sopenharmony_ci
53362306a36Sopenharmony_ci	/*
53462306a36Sopenharmony_ci	 * prevent i2c xfer attempts after device is disconnected
53562306a36Sopenharmony_ci	 * some fe's try to do i2c writes/reads from their release
53662306a36Sopenharmony_ci	 * interfaces when called in disconnect path
53762306a36Sopenharmony_ci	 */
53862306a36Sopenharmony_ci	if (dev->disconnected)
53962306a36Sopenharmony_ci		return -ENODEV;
54062306a36Sopenharmony_ci
54162306a36Sopenharmony_ci	if (!rt_mutex_trylock(&dev->i2c_bus_lock))
54262306a36Sopenharmony_ci		return -EAGAIN;
54362306a36Sopenharmony_ci
54462306a36Sopenharmony_ci	/* Switch I2C bus if needed */
54562306a36Sopenharmony_ci	if (bus != dev->cur_i2c_bus &&
54662306a36Sopenharmony_ci	    i2c_bus->algo_type == EM28XX_I2C_ALGO_EM28XX) {
54762306a36Sopenharmony_ci		if (bus == 1)
54862306a36Sopenharmony_ci			reg = EM2874_I2C_SECONDARY_BUS_SELECT;
54962306a36Sopenharmony_ci		else
55062306a36Sopenharmony_ci			reg = 0;
55162306a36Sopenharmony_ci		em28xx_write_reg_bits(dev, EM28XX_R06_I2C_CLK, reg,
55262306a36Sopenharmony_ci				      EM2874_I2C_SECONDARY_BUS_SELECT);
55362306a36Sopenharmony_ci		dev->cur_i2c_bus = bus;
55462306a36Sopenharmony_ci	}
55562306a36Sopenharmony_ci
55662306a36Sopenharmony_ci	for (i = 0; i < num; i++) {
55762306a36Sopenharmony_ci		addr = msgs[i].addr << 1;
55862306a36Sopenharmony_ci		if (!msgs[i].len) {
55962306a36Sopenharmony_ci			/*
56062306a36Sopenharmony_ci			 * no len: check only for device presence
56162306a36Sopenharmony_ci			 * This code is only called during device probe.
56262306a36Sopenharmony_ci			 */
56362306a36Sopenharmony_ci			rc = i2c_check_for_device(i2c_bus, addr);
56462306a36Sopenharmony_ci
56562306a36Sopenharmony_ci			if (rc == -ENXIO)
56662306a36Sopenharmony_ci				rc = -ENODEV;
56762306a36Sopenharmony_ci		} else if (msgs[i].flags & I2C_M_RD) {
56862306a36Sopenharmony_ci			/* read bytes */
56962306a36Sopenharmony_ci			rc = i2c_recv_bytes(i2c_bus, msgs[i]);
57062306a36Sopenharmony_ci		} else {
57162306a36Sopenharmony_ci			/* write bytes */
57262306a36Sopenharmony_ci			rc = i2c_send_bytes(i2c_bus, msgs[i], i == num - 1);
57362306a36Sopenharmony_ci		}
57462306a36Sopenharmony_ci
57562306a36Sopenharmony_ci		if (rc < 0)
57662306a36Sopenharmony_ci			goto error;
57762306a36Sopenharmony_ci
57862306a36Sopenharmony_ci		dprintk(2, "%s %s addr=%02x len=%d: %*ph\n",
57962306a36Sopenharmony_ci			(msgs[i].flags & I2C_M_RD) ? "read" : "write",
58062306a36Sopenharmony_ci			i == num - 1 ? "stop" : "nonstop",
58162306a36Sopenharmony_ci			addr, msgs[i].len,
58262306a36Sopenharmony_ci			msgs[i].len, msgs[i].buf);
58362306a36Sopenharmony_ci	}
58462306a36Sopenharmony_ci
58562306a36Sopenharmony_ci	rt_mutex_unlock(&dev->i2c_bus_lock);
58662306a36Sopenharmony_ci	return num;
58762306a36Sopenharmony_ci
58862306a36Sopenharmony_cierror:
58962306a36Sopenharmony_ci	dprintk(2, "%s %s addr=%02x len=%d: %sERROR: %i\n",
59062306a36Sopenharmony_ci		(msgs[i].flags & I2C_M_RD) ? "read" : "write",
59162306a36Sopenharmony_ci		i == num - 1 ? "stop" : "nonstop",
59262306a36Sopenharmony_ci		addr, msgs[i].len,
59362306a36Sopenharmony_ci		(rc == -ENODEV) ? "no device " : "",
59462306a36Sopenharmony_ci		rc);
59562306a36Sopenharmony_ci
59662306a36Sopenharmony_ci	rt_mutex_unlock(&dev->i2c_bus_lock);
59762306a36Sopenharmony_ci	return rc;
59862306a36Sopenharmony_ci}
59962306a36Sopenharmony_ci
60062306a36Sopenharmony_ci/*
60162306a36Sopenharmony_ci * based on linux/sunrpc/svcauth.h and linux/hash.h
60262306a36Sopenharmony_ci * The original hash function returns a different value, if arch is x86_64
60362306a36Sopenharmony_ci * or i386.
60462306a36Sopenharmony_ci */
60562306a36Sopenharmony_cistatic inline unsigned long em28xx_hash_mem(char *buf, int length, int bits)
60662306a36Sopenharmony_ci{
60762306a36Sopenharmony_ci	unsigned long hash = 0;
60862306a36Sopenharmony_ci	unsigned long l = 0;
60962306a36Sopenharmony_ci	int len = 0;
61062306a36Sopenharmony_ci	unsigned char c;
61162306a36Sopenharmony_ci
61262306a36Sopenharmony_ci	do {
61362306a36Sopenharmony_ci		if (len == length) {
61462306a36Sopenharmony_ci			c = (char)len;
61562306a36Sopenharmony_ci			len = -1;
61662306a36Sopenharmony_ci		} else {
61762306a36Sopenharmony_ci			c = *buf++;
61862306a36Sopenharmony_ci		}
61962306a36Sopenharmony_ci		l = (l << 8) | c;
62062306a36Sopenharmony_ci		len++;
62162306a36Sopenharmony_ci		if ((len & (32 / 8 - 1)) == 0)
62262306a36Sopenharmony_ci			hash = ((hash ^ l) * 0x9e370001UL);
62362306a36Sopenharmony_ci	} while (len);
62462306a36Sopenharmony_ci
62562306a36Sopenharmony_ci	return (hash >> (32 - bits)) & 0xffffffffUL;
62662306a36Sopenharmony_ci}
62762306a36Sopenharmony_ci
62862306a36Sopenharmony_ci/*
62962306a36Sopenharmony_ci * Helper function to read data blocks from i2c clients with 8 or 16 bit
63062306a36Sopenharmony_ci * address width, 8 bit register width and auto incrementation been activated
63162306a36Sopenharmony_ci */
63262306a36Sopenharmony_cistatic int em28xx_i2c_read_block(struct em28xx *dev, unsigned int bus, u16 addr,
63362306a36Sopenharmony_ci				 bool addr_w16, u16 len, u8 *data)
63462306a36Sopenharmony_ci{
63562306a36Sopenharmony_ci	int remain = len, rsize, rsize_max, ret;
63662306a36Sopenharmony_ci	u8 buf[2];
63762306a36Sopenharmony_ci
63862306a36Sopenharmony_ci	/* Sanity check */
63962306a36Sopenharmony_ci	if (addr + remain > (addr_w16 * 0xff00 + 0xff + 1))
64062306a36Sopenharmony_ci		return -EINVAL;
64162306a36Sopenharmony_ci	/* Select address */
64262306a36Sopenharmony_ci	buf[0] = addr >> 8;
64362306a36Sopenharmony_ci	buf[1] = addr & 0xff;
64462306a36Sopenharmony_ci	ret = i2c_master_send(&dev->i2c_client[bus],
64562306a36Sopenharmony_ci			      buf + !addr_w16, 1 + addr_w16);
64662306a36Sopenharmony_ci	if (ret < 0)
64762306a36Sopenharmony_ci		return ret;
64862306a36Sopenharmony_ci	/* Read data */
64962306a36Sopenharmony_ci	if (dev->board.is_em2800)
65062306a36Sopenharmony_ci		rsize_max = 4;
65162306a36Sopenharmony_ci	else
65262306a36Sopenharmony_ci		rsize_max = 64;
65362306a36Sopenharmony_ci	while (remain > 0) {
65462306a36Sopenharmony_ci		if (remain > rsize_max)
65562306a36Sopenharmony_ci			rsize = rsize_max;
65662306a36Sopenharmony_ci		else
65762306a36Sopenharmony_ci			rsize = remain;
65862306a36Sopenharmony_ci
65962306a36Sopenharmony_ci		ret = i2c_master_recv(&dev->i2c_client[bus], data, rsize);
66062306a36Sopenharmony_ci		if (ret < 0)
66162306a36Sopenharmony_ci			return ret;
66262306a36Sopenharmony_ci
66362306a36Sopenharmony_ci		remain -= rsize;
66462306a36Sopenharmony_ci		data += rsize;
66562306a36Sopenharmony_ci	}
66662306a36Sopenharmony_ci
66762306a36Sopenharmony_ci	return len;
66862306a36Sopenharmony_ci}
66962306a36Sopenharmony_ci
67062306a36Sopenharmony_cistatic int em28xx_i2c_eeprom(struct em28xx *dev, unsigned int bus,
67162306a36Sopenharmony_ci			     u8 **eedata, u16 *eedata_len)
67262306a36Sopenharmony_ci{
67362306a36Sopenharmony_ci	const u16 len = 256;
67462306a36Sopenharmony_ci	/*
67562306a36Sopenharmony_ci	 * FIXME common length/size for bytes to read, to display, hash
67662306a36Sopenharmony_ci	 * calculation and returned device dataset. Simplifies the code a lot,
67762306a36Sopenharmony_ci	 * but we might have to deal with multiple sizes in the future !
67862306a36Sopenharmony_ci	 */
67962306a36Sopenharmony_ci	int err;
68062306a36Sopenharmony_ci	struct em28xx_eeprom *dev_config;
68162306a36Sopenharmony_ci	u8 buf, *data;
68262306a36Sopenharmony_ci
68362306a36Sopenharmony_ci	*eedata = NULL;
68462306a36Sopenharmony_ci	*eedata_len = 0;
68562306a36Sopenharmony_ci
68662306a36Sopenharmony_ci	/* EEPROM is always on i2c bus 0 on all known devices. */
68762306a36Sopenharmony_ci
68862306a36Sopenharmony_ci	dev->i2c_client[bus].addr = 0xa0 >> 1;
68962306a36Sopenharmony_ci
69062306a36Sopenharmony_ci	/* Check if board has eeprom */
69162306a36Sopenharmony_ci	err = i2c_master_recv(&dev->i2c_client[bus], &buf, 0);
69262306a36Sopenharmony_ci	if (err < 0) {
69362306a36Sopenharmony_ci		dev_info(&dev->intf->dev, "board has no eeprom\n");
69462306a36Sopenharmony_ci		return -ENODEV;
69562306a36Sopenharmony_ci	}
69662306a36Sopenharmony_ci
69762306a36Sopenharmony_ci	data = kzalloc(len, GFP_KERNEL);
69862306a36Sopenharmony_ci	if (!data)
69962306a36Sopenharmony_ci		return -ENOMEM;
70062306a36Sopenharmony_ci
70162306a36Sopenharmony_ci	/* Read EEPROM content */
70262306a36Sopenharmony_ci	err = em28xx_i2c_read_block(dev, bus, 0x0000,
70362306a36Sopenharmony_ci				    dev->eeprom_addrwidth_16bit,
70462306a36Sopenharmony_ci				    len, data);
70562306a36Sopenharmony_ci	if (err != len) {
70662306a36Sopenharmony_ci		dev_err(&dev->intf->dev,
70762306a36Sopenharmony_ci			"failed to read eeprom (err=%d)\n", err);
70862306a36Sopenharmony_ci		goto error;
70962306a36Sopenharmony_ci	}
71062306a36Sopenharmony_ci
71162306a36Sopenharmony_ci	if (i2c_debug) {
71262306a36Sopenharmony_ci		/* Display eeprom content */
71362306a36Sopenharmony_ci		print_hex_dump(KERN_DEBUG, "em28xx eeprom ", DUMP_PREFIX_OFFSET,
71462306a36Sopenharmony_ci			       16, 1, data, len, true);
71562306a36Sopenharmony_ci
71662306a36Sopenharmony_ci		if (dev->eeprom_addrwidth_16bit)
71762306a36Sopenharmony_ci			dev_info(&dev->intf->dev,
71862306a36Sopenharmony_ci				 "eeprom %06x: ... (skipped)\n", 256);
71962306a36Sopenharmony_ci	}
72062306a36Sopenharmony_ci
72162306a36Sopenharmony_ci	if (dev->eeprom_addrwidth_16bit &&
72262306a36Sopenharmony_ci	    data[0] == 0x26 && data[3] == 0x00) {
72362306a36Sopenharmony_ci		/* new eeprom format; size 4-64kb */
72462306a36Sopenharmony_ci		u16 mc_start;
72562306a36Sopenharmony_ci		u16 hwconf_offset;
72662306a36Sopenharmony_ci
72762306a36Sopenharmony_ci		dev->hash = em28xx_hash_mem(data, len, 32);
72862306a36Sopenharmony_ci		mc_start = (data[1] << 8) + 4;	/* usually 0x0004 */
72962306a36Sopenharmony_ci
73062306a36Sopenharmony_ci		dev_info(&dev->intf->dev,
73162306a36Sopenharmony_ci			 "EEPROM ID = %4ph, EEPROM hash = 0x%08lx\n",
73262306a36Sopenharmony_ci			 data, dev->hash);
73362306a36Sopenharmony_ci		dev_info(&dev->intf->dev,
73462306a36Sopenharmony_ci			 "EEPROM info:\n");
73562306a36Sopenharmony_ci		dev_info(&dev->intf->dev,
73662306a36Sopenharmony_ci			 "\tmicrocode start address = 0x%04x, boot configuration = 0x%02x\n",
73762306a36Sopenharmony_ci			 mc_start, data[2]);
73862306a36Sopenharmony_ci		/*
73962306a36Sopenharmony_ci		 * boot configuration (address 0x0002):
74062306a36Sopenharmony_ci		 * [0]   microcode download speed: 1 = 400 kHz; 0 = 100 kHz
74162306a36Sopenharmony_ci		 * [1]   always selects 12 kb RAM
74262306a36Sopenharmony_ci		 * [2]   USB device speed: 1 = force Full Speed; 0 = auto detect
74362306a36Sopenharmony_ci		 * [4]   1 = force fast mode and no suspend for device testing
74462306a36Sopenharmony_ci		 * [5:7] USB PHY tuning registers; determined by device
74562306a36Sopenharmony_ci		 *       characterization
74662306a36Sopenharmony_ci		 */
74762306a36Sopenharmony_ci
74862306a36Sopenharmony_ci		/*
74962306a36Sopenharmony_ci		 * Read hardware config dataset offset from address
75062306a36Sopenharmony_ci		 * (microcode start + 46)
75162306a36Sopenharmony_ci		 */
75262306a36Sopenharmony_ci		err = em28xx_i2c_read_block(dev, bus, mc_start + 46, 1, 2,
75362306a36Sopenharmony_ci					    data);
75462306a36Sopenharmony_ci		if (err != 2) {
75562306a36Sopenharmony_ci			dev_err(&dev->intf->dev,
75662306a36Sopenharmony_ci				"failed to read hardware configuration data from eeprom (err=%d)\n",
75762306a36Sopenharmony_ci				err);
75862306a36Sopenharmony_ci			goto error;
75962306a36Sopenharmony_ci		}
76062306a36Sopenharmony_ci
76162306a36Sopenharmony_ci		/* Calculate hardware config dataset start address */
76262306a36Sopenharmony_ci		hwconf_offset = mc_start + data[0] + (data[1] << 8);
76362306a36Sopenharmony_ci
76462306a36Sopenharmony_ci		/* Read hardware config dataset */
76562306a36Sopenharmony_ci		/*
76662306a36Sopenharmony_ci		 * NOTE: the microcode copy can be multiple pages long, but
76762306a36Sopenharmony_ci		 * we assume the hardware config dataset is the same as in
76862306a36Sopenharmony_ci		 * the old eeprom and not longer than 256 bytes.
76962306a36Sopenharmony_ci		 * tveeprom is currently also limited to 256 bytes.
77062306a36Sopenharmony_ci		 */
77162306a36Sopenharmony_ci		err = em28xx_i2c_read_block(dev, bus, hwconf_offset, 1, len,
77262306a36Sopenharmony_ci					    data);
77362306a36Sopenharmony_ci		if (err != len) {
77462306a36Sopenharmony_ci			dev_err(&dev->intf->dev,
77562306a36Sopenharmony_ci				"failed to read hardware configuration data from eeprom (err=%d)\n",
77662306a36Sopenharmony_ci				err);
77762306a36Sopenharmony_ci			goto error;
77862306a36Sopenharmony_ci		}
77962306a36Sopenharmony_ci
78062306a36Sopenharmony_ci		/* Verify hardware config dataset */
78162306a36Sopenharmony_ci		/* NOTE: not all devices provide this type of dataset */
78262306a36Sopenharmony_ci		if (data[0] != 0x1a || data[1] != 0xeb ||
78362306a36Sopenharmony_ci		    data[2] != 0x67 || data[3] != 0x95) {
78462306a36Sopenharmony_ci			dev_info(&dev->intf->dev,
78562306a36Sopenharmony_ci				 "\tno hardware configuration dataset found in eeprom\n");
78662306a36Sopenharmony_ci			kfree(data);
78762306a36Sopenharmony_ci			return 0;
78862306a36Sopenharmony_ci		}
78962306a36Sopenharmony_ci
79062306a36Sopenharmony_ci		/*
79162306a36Sopenharmony_ci		 * TODO: decrypt eeprom data for camera bridges
79262306a36Sopenharmony_ci		 * (em25xx, em276x+)
79362306a36Sopenharmony_ci		 */
79462306a36Sopenharmony_ci
79562306a36Sopenharmony_ci	} else if (!dev->eeprom_addrwidth_16bit &&
79662306a36Sopenharmony_ci		   data[0] == 0x1a && data[1] == 0xeb &&
79762306a36Sopenharmony_ci		   data[2] == 0x67 && data[3] == 0x95) {
79862306a36Sopenharmony_ci		dev->hash = em28xx_hash_mem(data, len, 32);
79962306a36Sopenharmony_ci		dev_info(&dev->intf->dev,
80062306a36Sopenharmony_ci			 "EEPROM ID = %4ph, EEPROM hash = 0x%08lx\n",
80162306a36Sopenharmony_ci			 data, dev->hash);
80262306a36Sopenharmony_ci		dev_info(&dev->intf->dev,
80362306a36Sopenharmony_ci			 "EEPROM info:\n");
80462306a36Sopenharmony_ci	} else {
80562306a36Sopenharmony_ci		dev_info(&dev->intf->dev,
80662306a36Sopenharmony_ci			 "unknown eeprom format or eeprom corrupted !\n");
80762306a36Sopenharmony_ci		err = -ENODEV;
80862306a36Sopenharmony_ci		goto error;
80962306a36Sopenharmony_ci	}
81062306a36Sopenharmony_ci
81162306a36Sopenharmony_ci	*eedata = data;
81262306a36Sopenharmony_ci	*eedata_len = len;
81362306a36Sopenharmony_ci	dev_config = (void *)*eedata;
81462306a36Sopenharmony_ci
81562306a36Sopenharmony_ci	switch (le16_to_cpu(dev_config->chip_conf) >> 4 & 0x3) {
81662306a36Sopenharmony_ci	case 0:
81762306a36Sopenharmony_ci		dev_info(&dev->intf->dev, "\tNo audio on board.\n");
81862306a36Sopenharmony_ci		break;
81962306a36Sopenharmony_ci	case 1:
82062306a36Sopenharmony_ci		dev_info(&dev->intf->dev, "\tAC97 audio (5 sample rates)\n");
82162306a36Sopenharmony_ci		break;
82262306a36Sopenharmony_ci	case 2:
82362306a36Sopenharmony_ci		if (dev->chip_id < CHIP_ID_EM2860)
82462306a36Sopenharmony_ci			dev_info(&dev->intf->dev,
82562306a36Sopenharmony_ci				 "\tI2S audio, sample rate=32k\n");
82662306a36Sopenharmony_ci		else
82762306a36Sopenharmony_ci			dev_info(&dev->intf->dev,
82862306a36Sopenharmony_ci				 "\tI2S audio, 3 sample rates\n");
82962306a36Sopenharmony_ci		break;
83062306a36Sopenharmony_ci	case 3:
83162306a36Sopenharmony_ci		if (dev->chip_id < CHIP_ID_EM2860)
83262306a36Sopenharmony_ci			dev_info(&dev->intf->dev,
83362306a36Sopenharmony_ci				 "\tI2S audio, 3 sample rates\n");
83462306a36Sopenharmony_ci		else
83562306a36Sopenharmony_ci			dev_info(&dev->intf->dev,
83662306a36Sopenharmony_ci				 "\tI2S audio, 5 sample rates\n");
83762306a36Sopenharmony_ci		break;
83862306a36Sopenharmony_ci	}
83962306a36Sopenharmony_ci
84062306a36Sopenharmony_ci	if (le16_to_cpu(dev_config->chip_conf) & 1 << 3)
84162306a36Sopenharmony_ci		dev_info(&dev->intf->dev, "\tUSB Remote wakeup capable\n");
84262306a36Sopenharmony_ci
84362306a36Sopenharmony_ci	if (le16_to_cpu(dev_config->chip_conf) & 1 << 2)
84462306a36Sopenharmony_ci		dev_info(&dev->intf->dev, "\tUSB Self power capable\n");
84562306a36Sopenharmony_ci
84662306a36Sopenharmony_ci	switch (le16_to_cpu(dev_config->chip_conf) & 0x3) {
84762306a36Sopenharmony_ci	case 0:
84862306a36Sopenharmony_ci		dev_info(&dev->intf->dev, "\t500mA max power\n");
84962306a36Sopenharmony_ci		break;
85062306a36Sopenharmony_ci	case 1:
85162306a36Sopenharmony_ci		dev_info(&dev->intf->dev, "\t400mA max power\n");
85262306a36Sopenharmony_ci		break;
85362306a36Sopenharmony_ci	case 2:
85462306a36Sopenharmony_ci		dev_info(&dev->intf->dev, "\t300mA max power\n");
85562306a36Sopenharmony_ci		break;
85662306a36Sopenharmony_ci	case 3:
85762306a36Sopenharmony_ci		dev_info(&dev->intf->dev, "\t200mA max power\n");
85862306a36Sopenharmony_ci		break;
85962306a36Sopenharmony_ci	}
86062306a36Sopenharmony_ci	dev_info(&dev->intf->dev,
86162306a36Sopenharmony_ci		 "\tTable at offset 0x%02x, strings=0x%04x, 0x%04x, 0x%04x\n",
86262306a36Sopenharmony_ci		 dev_config->string_idx_table,
86362306a36Sopenharmony_ci		 le16_to_cpu(dev_config->string1),
86462306a36Sopenharmony_ci		 le16_to_cpu(dev_config->string2),
86562306a36Sopenharmony_ci		 le16_to_cpu(dev_config->string3));
86662306a36Sopenharmony_ci
86762306a36Sopenharmony_ci	return 0;
86862306a36Sopenharmony_ci
86962306a36Sopenharmony_cierror:
87062306a36Sopenharmony_ci	kfree(data);
87162306a36Sopenharmony_ci	return err;
87262306a36Sopenharmony_ci}
87362306a36Sopenharmony_ci
87462306a36Sopenharmony_ci/* ----------------------------------------------------------- */
87562306a36Sopenharmony_ci
87662306a36Sopenharmony_ci/*
87762306a36Sopenharmony_ci * functionality()
87862306a36Sopenharmony_ci */
87962306a36Sopenharmony_cistatic u32 functionality(struct i2c_adapter *i2c_adap)
88062306a36Sopenharmony_ci{
88162306a36Sopenharmony_ci	struct em28xx_i2c_bus *i2c_bus = i2c_adap->algo_data;
88262306a36Sopenharmony_ci
88362306a36Sopenharmony_ci	if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM28XX ||
88462306a36Sopenharmony_ci	    i2c_bus->algo_type == EM28XX_I2C_ALGO_EM25XX_BUS_B) {
88562306a36Sopenharmony_ci		return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
88662306a36Sopenharmony_ci	} else if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM2800)  {
88762306a36Sopenharmony_ci		return (I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL) &
88862306a36Sopenharmony_ci			~I2C_FUNC_SMBUS_WRITE_BLOCK_DATA;
88962306a36Sopenharmony_ci	}
89062306a36Sopenharmony_ci
89162306a36Sopenharmony_ci	WARN(1, "Unknown i2c bus algorithm.\n");
89262306a36Sopenharmony_ci	return 0;
89362306a36Sopenharmony_ci}
89462306a36Sopenharmony_ci
89562306a36Sopenharmony_cistatic const struct i2c_algorithm em28xx_algo = {
89662306a36Sopenharmony_ci	.master_xfer   = em28xx_i2c_xfer,
89762306a36Sopenharmony_ci	.functionality = functionality,
89862306a36Sopenharmony_ci};
89962306a36Sopenharmony_ci
90062306a36Sopenharmony_cistatic const struct i2c_adapter em28xx_adap_template = {
90162306a36Sopenharmony_ci	.owner = THIS_MODULE,
90262306a36Sopenharmony_ci	.name = "em28xx",
90362306a36Sopenharmony_ci	.algo = &em28xx_algo,
90462306a36Sopenharmony_ci};
90562306a36Sopenharmony_ci
90662306a36Sopenharmony_cistatic const struct i2c_client em28xx_client_template = {
90762306a36Sopenharmony_ci	.name = "em28xx internal",
90862306a36Sopenharmony_ci};
90962306a36Sopenharmony_ci
91062306a36Sopenharmony_ci/* ----------------------------------------------------------- */
91162306a36Sopenharmony_ci
91262306a36Sopenharmony_ci/*
91362306a36Sopenharmony_ci * i2c_devs
91462306a36Sopenharmony_ci * incomplete list of known devices
91562306a36Sopenharmony_ci */
91662306a36Sopenharmony_cistatic char *i2c_devs[128] = {
91762306a36Sopenharmony_ci	[0x1c >> 1] = "lgdt330x",
91862306a36Sopenharmony_ci	[0x3e >> 1] = "remote IR sensor",
91962306a36Sopenharmony_ci	[0x4a >> 1] = "saa7113h",
92062306a36Sopenharmony_ci	[0x52 >> 1] = "drxk",
92162306a36Sopenharmony_ci	[0x60 >> 1] = "remote IR sensor",
92262306a36Sopenharmony_ci	[0x8e >> 1] = "remote IR sensor",
92362306a36Sopenharmony_ci	[0x86 >> 1] = "tda9887",
92462306a36Sopenharmony_ci	[0x80 >> 1] = "msp34xx",
92562306a36Sopenharmony_ci	[0x88 >> 1] = "msp34xx",
92662306a36Sopenharmony_ci	[0xa0 >> 1] = "eeprom",
92762306a36Sopenharmony_ci	[0xb0 >> 1] = "tda9874",
92862306a36Sopenharmony_ci	[0xb8 >> 1] = "tvp5150a",
92962306a36Sopenharmony_ci	[0xba >> 1] = "webcam sensor or tvp5150a",
93062306a36Sopenharmony_ci	[0xc0 >> 1] = "tuner (analog)",
93162306a36Sopenharmony_ci	[0xc2 >> 1] = "tuner (analog)",
93262306a36Sopenharmony_ci	[0xc4 >> 1] = "tuner (analog)",
93362306a36Sopenharmony_ci	[0xc6 >> 1] = "tuner (analog)",
93462306a36Sopenharmony_ci};
93562306a36Sopenharmony_ci
93662306a36Sopenharmony_ci/*
93762306a36Sopenharmony_ci * do_i2c_scan()
93862306a36Sopenharmony_ci * check i2c address range for devices
93962306a36Sopenharmony_ci */
94062306a36Sopenharmony_civoid em28xx_do_i2c_scan(struct em28xx *dev, unsigned int bus)
94162306a36Sopenharmony_ci{
94262306a36Sopenharmony_ci	u8 i2c_devicelist[128];
94362306a36Sopenharmony_ci	unsigned char buf;
94462306a36Sopenharmony_ci	int i, rc;
94562306a36Sopenharmony_ci
94662306a36Sopenharmony_ci	memset(i2c_devicelist, 0, sizeof(i2c_devicelist));
94762306a36Sopenharmony_ci
94862306a36Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(i2c_devs); i++) {
94962306a36Sopenharmony_ci		dev->i2c_client[bus].addr = i;
95062306a36Sopenharmony_ci		rc = i2c_master_recv(&dev->i2c_client[bus], &buf, 0);
95162306a36Sopenharmony_ci		if (rc < 0)
95262306a36Sopenharmony_ci			continue;
95362306a36Sopenharmony_ci		i2c_devicelist[i] = i;
95462306a36Sopenharmony_ci		dev_info(&dev->intf->dev,
95562306a36Sopenharmony_ci			 "found i2c device @ 0x%x on bus %d [%s]\n",
95662306a36Sopenharmony_ci			 i << 1, bus, i2c_devs[i] ? i2c_devs[i] : "???");
95762306a36Sopenharmony_ci	}
95862306a36Sopenharmony_ci
95962306a36Sopenharmony_ci	if (bus == dev->def_i2c_bus)
96062306a36Sopenharmony_ci		dev->i2c_hash = em28xx_hash_mem(i2c_devicelist,
96162306a36Sopenharmony_ci						sizeof(i2c_devicelist), 32);
96262306a36Sopenharmony_ci}
96362306a36Sopenharmony_ci
96462306a36Sopenharmony_ci/*
96562306a36Sopenharmony_ci * em28xx_i2c_register()
96662306a36Sopenharmony_ci * register i2c bus
96762306a36Sopenharmony_ci */
96862306a36Sopenharmony_ciint em28xx_i2c_register(struct em28xx *dev, unsigned int bus,
96962306a36Sopenharmony_ci			enum em28xx_i2c_algo_type algo_type)
97062306a36Sopenharmony_ci{
97162306a36Sopenharmony_ci	int retval;
97262306a36Sopenharmony_ci
97362306a36Sopenharmony_ci	if (WARN_ON(!dev->em28xx_write_regs || !dev->em28xx_read_reg ||
97462306a36Sopenharmony_ci		    !dev->em28xx_write_regs_req || !dev->em28xx_read_reg_req))
97562306a36Sopenharmony_ci		return -ENODEV;
97662306a36Sopenharmony_ci
97762306a36Sopenharmony_ci	if (bus >= NUM_I2C_BUSES)
97862306a36Sopenharmony_ci		return -ENODEV;
97962306a36Sopenharmony_ci
98062306a36Sopenharmony_ci	dev->i2c_adap[bus] = em28xx_adap_template;
98162306a36Sopenharmony_ci	dev->i2c_adap[bus].dev.parent = &dev->intf->dev;
98262306a36Sopenharmony_ci	strscpy(dev->i2c_adap[bus].name, dev_name(&dev->intf->dev),
98362306a36Sopenharmony_ci		sizeof(dev->i2c_adap[bus].name));
98462306a36Sopenharmony_ci
98562306a36Sopenharmony_ci	dev->i2c_bus[bus].bus = bus;
98662306a36Sopenharmony_ci	dev->i2c_bus[bus].algo_type = algo_type;
98762306a36Sopenharmony_ci	dev->i2c_bus[bus].dev = dev;
98862306a36Sopenharmony_ci	dev->i2c_adap[bus].algo_data = &dev->i2c_bus[bus];
98962306a36Sopenharmony_ci
99062306a36Sopenharmony_ci	retval = i2c_add_adapter(&dev->i2c_adap[bus]);
99162306a36Sopenharmony_ci	if (retval < 0) {
99262306a36Sopenharmony_ci		dev_err(&dev->intf->dev,
99362306a36Sopenharmony_ci			"%s: i2c_add_adapter failed! retval [%d]\n",
99462306a36Sopenharmony_ci			__func__, retval);
99562306a36Sopenharmony_ci		return retval;
99662306a36Sopenharmony_ci	}
99762306a36Sopenharmony_ci
99862306a36Sopenharmony_ci	dev->i2c_client[bus] = em28xx_client_template;
99962306a36Sopenharmony_ci	dev->i2c_client[bus].adapter = &dev->i2c_adap[bus];
100062306a36Sopenharmony_ci
100162306a36Sopenharmony_ci	/* Up to now, all eeproms are at bus 0 */
100262306a36Sopenharmony_ci	if (!bus) {
100362306a36Sopenharmony_ci		retval = em28xx_i2c_eeprom(dev, bus,
100462306a36Sopenharmony_ci					   &dev->eedata, &dev->eedata_len);
100562306a36Sopenharmony_ci		if (retval < 0 && retval != -ENODEV) {
100662306a36Sopenharmony_ci			dev_err(&dev->intf->dev,
100762306a36Sopenharmony_ci				"%s: em28xx_i2_eeprom failed! retval [%d]\n",
100862306a36Sopenharmony_ci				__func__, retval);
100962306a36Sopenharmony_ci		}
101062306a36Sopenharmony_ci	}
101162306a36Sopenharmony_ci
101262306a36Sopenharmony_ci	if (i2c_scan)
101362306a36Sopenharmony_ci		em28xx_do_i2c_scan(dev, bus);
101462306a36Sopenharmony_ci
101562306a36Sopenharmony_ci	return 0;
101662306a36Sopenharmony_ci}
101762306a36Sopenharmony_ci
101862306a36Sopenharmony_ci/*
101962306a36Sopenharmony_ci * em28xx_i2c_unregister()
102062306a36Sopenharmony_ci * unregister i2c_bus
102162306a36Sopenharmony_ci */
102262306a36Sopenharmony_ciint em28xx_i2c_unregister(struct em28xx *dev, unsigned int bus)
102362306a36Sopenharmony_ci{
102462306a36Sopenharmony_ci	if (bus >= NUM_I2C_BUSES)
102562306a36Sopenharmony_ci		return -ENODEV;
102662306a36Sopenharmony_ci
102762306a36Sopenharmony_ci	i2c_del_adapter(&dev->i2c_adap[bus]);
102862306a36Sopenharmony_ci	return 0;
102962306a36Sopenharmony_ci}
1030