diff options
-rw-r--r-- | drivers/i2c/i2c-core.c | 80 |
1 files changed, 40 insertions, 40 deletions
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index e0f833cca3f1..f744f73e3ff5 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c | |||
@@ -1277,6 +1277,41 @@ EXPORT_SYMBOL(i2c_master_recv); | |||
1277 | * ---------------------------------------------------- | 1277 | * ---------------------------------------------------- |
1278 | */ | 1278 | */ |
1279 | 1279 | ||
1280 | /* | ||
1281 | * Legacy default probe function, mostly relevant for SMBus. The default | ||
1282 | * probe method is a quick write, but it is known to corrupt the 24RF08 | ||
1283 | * EEPROMs due to a state machine bug, and could also irreversibly | ||
1284 | * write-protect some EEPROMs, so for address ranges 0x30-0x37 and 0x50-0x5f, | ||
1285 | * we use a short byte read instead. Also, some bus drivers don't implement | ||
1286 | * quick write, so we fallback to a byte read in that case too. | ||
1287 | * On x86, there is another special case for FSC hardware monitoring chips, | ||
1288 | * which want regular byte reads (address 0x73.) Fortunately, these are the | ||
1289 | * only known chips using this I2C address on PC hardware. | ||
1290 | * Returns 1 if probe succeeded, 0 if not. | ||
1291 | */ | ||
1292 | static int i2c_default_probe(struct i2c_adapter *adap, unsigned short addr) | ||
1293 | { | ||
1294 | int err; | ||
1295 | union i2c_smbus_data dummy; | ||
1296 | |||
1297 | #ifdef CONFIG_X86 | ||
1298 | if (addr == 0x73 && (adap->class & I2C_CLASS_HWMON) | ||
1299 | && i2c_check_functionality(adap, I2C_FUNC_SMBUS_READ_BYTE_DATA)) | ||
1300 | err = i2c_smbus_xfer(adap, addr, 0, I2C_SMBUS_READ, 0, | ||
1301 | I2C_SMBUS_BYTE_DATA, &dummy); | ||
1302 | else | ||
1303 | #endif | ||
1304 | if ((addr & ~0x07) == 0x30 || (addr & ~0x0f) == 0x50 | ||
1305 | || !i2c_check_functionality(adap, I2C_FUNC_SMBUS_QUICK)) | ||
1306 | err = i2c_smbus_xfer(adap, addr, 0, I2C_SMBUS_READ, 0, | ||
1307 | I2C_SMBUS_BYTE, &dummy); | ||
1308 | else | ||
1309 | err = i2c_smbus_xfer(adap, addr, 0, I2C_SMBUS_WRITE, 0, | ||
1310 | I2C_SMBUS_QUICK, NULL); | ||
1311 | |||
1312 | return err >= 0; | ||
1313 | } | ||
1314 | |||
1280 | static int i2c_detect_address(struct i2c_client *temp_client, | 1315 | static int i2c_detect_address(struct i2c_client *temp_client, |
1281 | struct i2c_driver *driver) | 1316 | struct i2c_driver *driver) |
1282 | { | 1317 | { |
@@ -1297,23 +1332,8 @@ static int i2c_detect_address(struct i2c_client *temp_client, | |||
1297 | return 0; | 1332 | return 0; |
1298 | 1333 | ||
1299 | /* Make sure there is something at this address */ | 1334 | /* Make sure there is something at this address */ |
1300 | if (addr == 0x73 && (adapter->class & I2C_CLASS_HWMON)) { | 1335 | if (!i2c_default_probe(adapter, addr)) |
1301 | /* Special probe for FSC hwmon chips */ | 1336 | return 0; |
1302 | union i2c_smbus_data dummy; | ||
1303 | |||
1304 | if (i2c_smbus_xfer(adapter, addr, 0, I2C_SMBUS_READ, 0, | ||
1305 | I2C_SMBUS_BYTE_DATA, &dummy) < 0) | ||
1306 | return 0; | ||
1307 | } else { | ||
1308 | if (i2c_smbus_xfer(adapter, addr, 0, I2C_SMBUS_WRITE, 0, | ||
1309 | I2C_SMBUS_QUICK, NULL) < 0) | ||
1310 | return 0; | ||
1311 | |||
1312 | /* Prevent 24RF08 corruption */ | ||
1313 | if ((addr & ~0x0f) == 0x50) | ||
1314 | i2c_smbus_xfer(adapter, addr, 0, I2C_SMBUS_WRITE, 0, | ||
1315 | I2C_SMBUS_QUICK, NULL); | ||
1316 | } | ||
1317 | 1337 | ||
1318 | /* Finally call the custom detection function */ | 1338 | /* Finally call the custom detection function */ |
1319 | memset(&info, 0, sizeof(struct i2c_board_info)); | 1339 | memset(&info, 0, sizeof(struct i2c_board_info)); |
@@ -1420,29 +1440,9 @@ i2c_new_probed_device(struct i2c_adapter *adap, | |||
1420 | continue; | 1440 | continue; |
1421 | } | 1441 | } |
1422 | 1442 | ||
1423 | /* Test address responsiveness | 1443 | /* Test address responsiveness */ |
1424 | The default probe method is a quick write, but it is known | 1444 | if (i2c_default_probe(adap, addr_list[i])) |
1425 | to corrupt the 24RF08 EEPROMs due to a state machine bug, | 1445 | break; |
1426 | and could also irreversibly write-protect some EEPROMs, so | ||
1427 | for address ranges 0x30-0x37 and 0x50-0x5f, we use a byte | ||
1428 | read instead. Also, some bus drivers don't implement | ||
1429 | quick write, so we fallback to a byte read it that case | ||
1430 | too. */ | ||
1431 | if ((addr_list[i] & ~0x07) == 0x30 | ||
1432 | || (addr_list[i] & ~0x0f) == 0x50 | ||
1433 | || !i2c_check_functionality(adap, I2C_FUNC_SMBUS_QUICK)) { | ||
1434 | union i2c_smbus_data data; | ||
1435 | |||
1436 | if (i2c_smbus_xfer(adap, addr_list[i], 0, | ||
1437 | I2C_SMBUS_READ, 0, | ||
1438 | I2C_SMBUS_BYTE, &data) >= 0) | ||
1439 | break; | ||
1440 | } else { | ||
1441 | if (i2c_smbus_xfer(adap, addr_list[i], 0, | ||
1442 | I2C_SMBUS_WRITE, 0, | ||
1443 | I2C_SMBUS_QUICK, NULL) >= 0) | ||
1444 | break; | ||
1445 | } | ||
1446 | } | 1446 | } |
1447 | 1447 | ||
1448 | if (addr_list[i] == I2C_CLIENT_END) { | 1448 | if (addr_list[i] == I2C_CLIENT_END) { |