diff options
| -rw-r--r-- | drivers/hwmon/adm1021.c | 58 |
1 files changed, 50 insertions, 8 deletions
diff --git a/drivers/hwmon/adm1021.c b/drivers/hwmon/adm1021.c index 7e76922a4ba9..f920619cd6da 100644 --- a/drivers/hwmon/adm1021.c +++ b/drivers/hwmon/adm1021.c | |||
| @@ -331,26 +331,68 @@ static int adm1021_detect(struct i2c_client *client, | |||
| 331 | man_id = i2c_smbus_read_byte_data(client, ADM1021_REG_MAN_ID); | 331 | man_id = i2c_smbus_read_byte_data(client, ADM1021_REG_MAN_ID); |
| 332 | dev_id = i2c_smbus_read_byte_data(client, ADM1021_REG_DEV_ID); | 332 | dev_id = i2c_smbus_read_byte_data(client, ADM1021_REG_DEV_ID); |
| 333 | 333 | ||
| 334 | if (man_id < 0 || dev_id < 0) | ||
| 335 | return -ENODEV; | ||
| 336 | |||
| 334 | if (man_id == 0x4d && dev_id == 0x01) | 337 | if (man_id == 0x4d && dev_id == 0x01) |
| 335 | type_name = "max1617a"; | 338 | type_name = "max1617a"; |
| 336 | else if (man_id == 0x41) { | 339 | else if (man_id == 0x41) { |
| 337 | if ((dev_id & 0xF0) == 0x30) | 340 | if ((dev_id & 0xF0) == 0x30) |
| 338 | type_name = "adm1023"; | 341 | type_name = "adm1023"; |
| 339 | else | 342 | else if ((dev_id & 0xF0) == 0x00) |
| 340 | type_name = "adm1021"; | 343 | type_name = "adm1021"; |
| 344 | else | ||
| 345 | return -ENODEV; | ||
| 341 | } else if (man_id == 0x49) | 346 | } else if (man_id == 0x49) |
| 342 | type_name = "thmc10"; | 347 | type_name = "thmc10"; |
| 343 | else if (man_id == 0x23) | 348 | else if (man_id == 0x23) |
| 344 | type_name = "gl523sm"; | 349 | type_name = "gl523sm"; |
| 345 | else if (man_id == 0x54) | 350 | else if (man_id == 0x54) |
| 346 | type_name = "mc1066"; | 351 | type_name = "mc1066"; |
| 347 | /* LM84 Mfr ID in a different place, and it has more unused bits */ | 352 | else { |
| 348 | else if (conv_rate == 0x00 | 353 | int lte, rte, lhi, rhi, llo, rlo; |
| 349 | && (config & 0x7F) == 0x00 | 354 | |
| 350 | && (status & 0xAB) == 0x00) | 355 | /* extra checks for LM84 and MAX1617 to avoid misdetections */ |
| 351 | type_name = "lm84"; | 356 | |
| 352 | else | 357 | llo = i2c_smbus_read_byte_data(client, ADM1021_REG_THYST_R(0)); |
| 353 | type_name = "max1617"; | 358 | rlo = i2c_smbus_read_byte_data(client, ADM1021_REG_THYST_R(1)); |
| 359 | |||
| 360 | /* fail if any of the additional register reads failed */ | ||
| 361 | if (llo < 0 || rlo < 0) | ||
| 362 | return -ENODEV; | ||
| 363 | |||
| 364 | lte = i2c_smbus_read_byte_data(client, ADM1021_REG_TEMP(0)); | ||
| 365 | rte = i2c_smbus_read_byte_data(client, ADM1021_REG_TEMP(1)); | ||
| 366 | lhi = i2c_smbus_read_byte_data(client, ADM1021_REG_TOS_R(0)); | ||
| 367 | rhi = i2c_smbus_read_byte_data(client, ADM1021_REG_TOS_R(1)); | ||
| 368 | |||
| 369 | /* | ||
| 370 | * Fail for negative temperatures and negative high limits. | ||
| 371 | * This check also catches read errors on the tested registers. | ||
| 372 | */ | ||
| 373 | if ((s8)lte < 0 || (s8)rte < 0 || (s8)lhi < 0 || (s8)rhi < 0) | ||
| 374 | return -ENODEV; | ||
| 375 | |||
| 376 | /* fail if all registers hold the same value */ | ||
| 377 | if (lte == rte && lte == lhi && lte == rhi && lte == llo | ||
| 378 | && lte == rlo) | ||
| 379 | return -ENODEV; | ||
| 380 | |||
| 381 | /* | ||
| 382 | * LM84 Mfr ID is in a different place, | ||
| 383 | * and it has more unused bits. | ||
| 384 | */ | ||
| 385 | if (conv_rate == 0x00 | ||
| 386 | && (config & 0x7F) == 0x00 | ||
| 387 | && (status & 0xAB) == 0x00) { | ||
| 388 | type_name = "lm84"; | ||
| 389 | } else { | ||
| 390 | /* fail if low limits are larger than high limits */ | ||
| 391 | if ((s8)llo > lhi || (s8)rlo > rhi) | ||
| 392 | return -ENODEV; | ||
| 393 | type_name = "max1617"; | ||
| 394 | } | ||
| 395 | } | ||
| 354 | 396 | ||
| 355 | pr_debug("Detected chip %s at adapter %d, address 0x%02x.\n", | 397 | pr_debug("Detected chip %s at adapter %d, address 0x%02x.\n", |
| 356 | type_name, i2c_adapter_id(adapter), client->addr); | 398 | type_name, i2c_adapter_id(adapter), client->addr); |
