aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean Delvare <khali@linux-fr.org>2007-05-01 17:26:31 -0400
committerJean Delvare <khali@hyperion.delvare>2007-05-01 17:26:31 -0400
commit12b5053ac58709c7d475888bc18d1f61958afc4e (patch)
tree13a6afc6ad6d3f22568045ba71277c1331fd4283
parent0f3b48385213355a2d4408bec1b481ffcf0e8638 (diff)
i2c: Add i2c_new_probed_device()
Add a new helper function to instantiate an i2c device. It is meant as a replacement for i2c_new_device() when you don't know for sure at which address your I2C/SMBus device lives. This happens frequently on TV adapters for example, you know there is a tuner chip on the bus, but depending on the exact board model and revision, it can live at different addresses. So, the new i2c_new_probed_device() function will probe the bus according to a list of addresses, and as soon as one of these addresses responds, it will call i2c_new_device() on that one address. This function will make it possible to port the old i2c drivers to the new model quickly. Signed-off-by: Jean Delvare <khali@linux-fr.org>
-rw-r--r--drivers/i2c/i2c-core.c63
-rw-r--r--include/linux/i2c.h9
2 files changed, 72 insertions, 0 deletions
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 18124398b464..0fd4acbffb78 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -1092,6 +1092,69 @@ int i2c_probe(struct i2c_adapter *adapter,
1092} 1092}
1093EXPORT_SYMBOL(i2c_probe); 1093EXPORT_SYMBOL(i2c_probe);
1094 1094
1095struct i2c_client *
1096i2c_new_probed_device(struct i2c_adapter *adap,
1097 struct i2c_board_info *info,
1098 unsigned short const *addr_list)
1099{
1100 int i;
1101
1102 /* Stop here if the bus doesn't support probing */
1103 if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_READ_BYTE)) {
1104 dev_err(&adap->dev, "Probing not supported\n");
1105 return NULL;
1106 }
1107
1108 mutex_lock(&adap->clist_lock);
1109 for (i = 0; addr_list[i] != I2C_CLIENT_END; i++) {
1110 /* Check address validity */
1111 if (addr_list[i] < 0x03 || addr_list[i] > 0x77) {
1112 dev_warn(&adap->dev, "Invalid 7-bit address "
1113 "0x%02x\n", addr_list[i]);
1114 continue;
1115 }
1116
1117 /* Check address availability */
1118 if (__i2c_check_addr(adap, addr_list[i])) {
1119 dev_dbg(&adap->dev, "Address 0x%02x already in "
1120 "use, not probing\n", addr_list[i]);
1121 continue;
1122 }
1123
1124 /* Test address responsiveness
1125 The default probe method is a quick write, but it is known
1126 to corrupt the 24RF08 EEPROMs due to a state machine bug,
1127 and could also irreversibly write-protect some EEPROMs, so
1128 for address ranges 0x30-0x37 and 0x50-0x5f, we use a byte
1129 read instead. Also, some bus drivers don't implement
1130 quick write, so we fallback to a byte read it that case
1131 too. */
1132 if ((addr_list[i] & ~0x07) == 0x30
1133 || (addr_list[i] & ~0x0f) == 0x50
1134 || !i2c_check_functionality(adap, I2C_FUNC_SMBUS_QUICK)) {
1135 if (i2c_smbus_xfer(adap, addr_list[i], 0,
1136 I2C_SMBUS_READ, 0,
1137 I2C_SMBUS_BYTE, NULL) >= 0)
1138 break;
1139 } else {
1140 if (i2c_smbus_xfer(adap, addr_list[i], 0,
1141 I2C_SMBUS_WRITE, 0,
1142 I2C_SMBUS_QUICK, NULL) >= 0)
1143 break;
1144 }
1145 }
1146 mutex_unlock(&adap->clist_lock);
1147
1148 if (addr_list[i] == I2C_CLIENT_END) {
1149 dev_dbg(&adap->dev, "Probing failed, no device found\n");
1150 return NULL;
1151 }
1152
1153 info->addr = addr_list[i];
1154 return i2c_new_device(adap, info);
1155}
1156EXPORT_SYMBOL_GPL(i2c_new_probed_device);
1157
1095struct i2c_adapter* i2c_get_adapter(int id) 1158struct i2c_adapter* i2c_get_adapter(int id)
1096{ 1159{
1097 struct i2c_adapter *adapter; 1160 struct i2c_adapter *adapter;
diff --git a/include/linux/i2c.h b/include/linux/i2c.h
index 36d6814a6df4..da95ce79d075 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -245,6 +245,15 @@ struct i2c_board_info {
245extern struct i2c_client * 245extern struct i2c_client *
246i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info); 246i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info);
247 247
248/* If you don't know the exact address of an I2C device, use this variant
249 * instead, which can probe for device presence in a list of possible
250 * addresses.
251 */
252extern struct i2c_client *
253i2c_new_probed_device(struct i2c_adapter *adap,
254 struct i2c_board_info *info,
255 unsigned short const *addr_list);
256
248extern void i2c_unregister_device(struct i2c_client *); 257extern void i2c_unregister_device(struct i2c_client *);
249 258
250/* Mainboard arch_initcall() code should register all its I2C devices. 259/* Mainboard arch_initcall() code should register all its I2C devices.