Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 20dead8d authored by Dmitri Belimov's avatar Dmitri Belimov Committed by Mauro Carvalho Chehab
Browse files

V4L/DVB: tm6000: fix i2c read



Set correct limit for I2C packet.
Use different method for the tm5600/tm6000 and tm6010 to read word.

[mchehab@redhat.com: Fix CodingStyle]
Signed-off-by: default avatarBeholder Intl. Ltd. Dmitry Belimov <d.belimov@gmail.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent a8567531
Loading
Loading
Loading
Loading
+77 −4
Original line number Diff line number Diff line
@@ -47,8 +47,38 @@ MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]");
static int tm6000_i2c_send_regs(struct tm6000_core *dev, unsigned char addr,
				__u8 reg, char *buf, int len)
{
	return tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
		REQ_16_SET_GET_I2C_WR1_RDN, addr | reg << 8, 0, buf, len);
	int rc;
	unsigned int tsleep;
	unsigned int i2c_packet_limit = 16;

	if (dev->dev_type == TM6010)
		i2c_packet_limit = 64;

	if (!buf)
		return -1;

	if (len < 1 || len > i2c_packet_limit) {
		printk(KERN_ERR "Incorrect length of i2c packet = %d, limit set to %d\n",
			len, i2c_packet_limit);
		return -1;
	}

	/* capture mutex */
	rc = tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR |
		USB_RECIP_DEVICE, REQ_16_SET_GET_I2C_WR1_RDN,
		addr | reg << 8, 0, buf, len);

	if (rc < 0) {
		/* release mutex */
		return rc;
	}

	/* Calculate delay time, 14000us for 64 bytes */
	tsleep = ((len * 200) + 200 + 1000) / 1000;
	msleep(tsleep);

	/* release mutex */
	return rc;
}

/* Generic read - doesn't work fine with 16bit registers */
@@ -57,7 +87,21 @@ static int tm6000_i2c_recv_regs(struct tm6000_core *dev, unsigned char addr,
{
	int rc;
	u8 b[2];
	unsigned int i2c_packet_limit = 16;

	if (dev->dev_type == TM6010)
		i2c_packet_limit = 64;

	if (!buf)
		return -1;

	if (len < 1 || len > i2c_packet_limit) {
		printk(KERN_ERR "Incorrect length of i2c packet = %d, limit set to %d\n",
			len, i2c_packet_limit);
		return -1;
	}

	/* capture mutex */
	if ((dev->caps.has_zl10353) && (dev->demod_addr << 1 == addr) && (reg % 2 == 0)) {
		/*
		 * Workaround an I2C bug when reading from zl10353
@@ -74,6 +118,7 @@ static int tm6000_i2c_recv_regs(struct tm6000_core *dev, unsigned char addr,
			REQ_16_SET_GET_I2C_WR1_RDN, addr | reg << 8, 0, buf, len);
	}

	/* release mutex */
	return rc;
}

@@ -84,8 +129,36 @@ static int tm6000_i2c_recv_regs(struct tm6000_core *dev, unsigned char addr,
static int tm6000_i2c_recv_regs16(struct tm6000_core *dev, unsigned char addr,
				  __u16 reg, char *buf, int len)
{
	return tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
		REQ_14_SET_GET_I2C_WR2_RDN, addr, reg, buf, len);
	int rc;
	unsigned char ureg;

	if (!buf || len != 2)
		return -1;

	/* capture mutex */
	if (dev->dev_type == TM6010) {
		ureg = reg & 0xFF;
		rc = tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR |
			USB_RECIP_DEVICE, REQ_16_SET_GET_I2C_WR1_RDN,
			addr | (reg & 0xFF00), 0, &ureg, 1);

		if (rc < 0) {
			/* release mutex */
			return rc;
		}

		msleep(1400 / 1000);
		rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR |
			USB_RECIP_DEVICE, REQ_35_AFTEK_TUNER_READ,
			reg, 0, buf, len);
	} else {
		rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR |
			USB_RECIP_DEVICE, REQ_14_SET_GET_I2C_WR2_RDN,
			addr, reg, buf, len);
	}

	/* release mutex */
	return rc;
}

static int tm6000_i2c_xfer(struct i2c_adapter *i2c_adap,