Home Home > GIT Browse
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean Delvare <khali@linux-fr.org>2010-05-26 10:05:11 -0300
committerGreg Kroah-Hartman <gregkh@suse.de>2010-08-02 10:21:26 -0700
commite9594751e4454139901cb1d68dd05ad7f48bdb59 (patch)
treec91df25ce6ec849dd2dfc0400c2c66b15b884ba2
parent65019a1c668d1dbcc4c6bdcdb7bb66d8ea714752 (diff)
V4L/DVB: FusionHDTV: Use quick reads for I2C IR device probing
commit 806b07c29b711aaf90c81d2a19711607769f8246 upstream. IR support on FusionHDTV cards is broken since kernel 2.6.31. One side effect of the switch to the standard binding model for IR I2C devices was to let i2c-core do the probing instead of the ir-kbd-i2c driver. There is a slight difference between the two probe methods: i2c-core uses 0-byte writes, while the ir-kbd-i2c was using 0-byte reads. As some IR I2C devices only support reads, the new probe method fails to detect them. For now, revert to letting the driver do the probe, using 0-byte reads. In the future, i2c-core will be extended to let callers of i2c_new_probed_device() provide a custom probing function. Signed-off-by: Jean Delvare <khali@linux-fr.org> Tested-by: "Timothy D. Lenz" <tlenz@vorgon.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/media/video/cx23885/cx23885-i2c.c12
-rw-r--r--drivers/media/video/cx88/cx88-i2c.c16
2 files changed, 26 insertions, 2 deletions
diff --git a/drivers/media/video/cx23885/cx23885-i2c.c b/drivers/media/video/cx23885/cx23885-i2c.c
index 4172cb387420..d4746e064516 100644
--- a/drivers/media/video/cx23885/cx23885-i2c.c
+++ b/drivers/media/video/cx23885/cx23885-i2c.c
@@ -365,7 +365,17 @@ int cx23885_i2c_register(struct cx23885_i2c *bus)
memset(&info, 0, sizeof(struct i2c_board_info));
strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
- i2c_new_probed_device(&bus->i2c_adap, &info, addr_list);
+ /*
+ * We can't call i2c_new_probed_device() because it uses
+ * quick writes for probing and the IR receiver device only
+ * replies to reads.
+ */
+ if (i2c_smbus_xfer(&bus->i2c_adap, addr_list[0], 0,
+ I2C_SMBUS_READ, 0, I2C_SMBUS_QUICK,
+ NULL) >= 0) {
+ info.addr = addr_list[0];
+ i2c_new_device(&bus->i2c_adap, &info);
+ }
}
return bus->i2c_rc;
diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c
index ee1ca39db06a..fb39f1184558 100644
--- a/drivers/media/video/cx88/cx88-i2c.c
+++ b/drivers/media/video/cx88/cx88-i2c.c
@@ -188,10 +188,24 @@ int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci)
0x18, 0x6b, 0x71,
I2C_CLIENT_END
};
+ const unsigned short *addrp;
memset(&info, 0, sizeof(struct i2c_board_info));
strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
- i2c_new_probed_device(&core->i2c_adap, &info, addr_list);
+ /*
+ * We can't call i2c_new_probed_device() because it uses
+ * quick writes for probing and at least some R receiver
+ * devices only reply to reads.
+ */
+ for (addrp = addr_list; *addrp != I2C_CLIENT_END; addrp++) {
+ if (i2c_smbus_xfer(&core->i2c_adap, *addrp, 0,
+ I2C_SMBUS_READ, 0,
+ I2C_SMBUS_QUICK, NULL) >= 0) {
+ info.addr = *addrp;
+ i2c_new_device(&core->i2c_adap, &info);
+ break;
+ }
+ }
}
return core->i2c_rc;
}