diff options
author | Len Sorensen <lsorense@csclub.uwaterloo.ca> | 2011-03-21 12:59:36 -0400 |
---|---|---|
committer | Jean Delvare <khali@endymion.delvare> | 2011-03-21 12:59:36 -0400 |
commit | 05e82fe40faee8499b4e3ba12fddaaf013d84203 (patch) | |
tree | b206f59c3bbc166e8743653806334d94b37fe6c3 /drivers/hwmon/lm75.c | |
parent | 96b4b9bfea28e38c38d26ca47e82ac0fbe2f28b6 (diff) |
hwmon: (lm75) Add detection of the National Semiconductor LM75A
Add support for detection of the National Semiconductor LM75A using the ID
register value.
Signed-off-by: Len Sorensen <lsorense@csclub.uwaterloo.ca>
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Diffstat (limited to 'drivers/hwmon/lm75.c')
-rw-r--r-- | drivers/hwmon/lm75.c | 56 |
1 files changed, 41 insertions, 15 deletions
diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c index f36eb80d227f..638dd0586e3f 100644 --- a/drivers/hwmon/lm75.c +++ b/drivers/hwmon/lm75.c | |||
@@ -232,6 +232,8 @@ static const struct i2c_device_id lm75_ids[] = { | |||
232 | }; | 232 | }; |
233 | MODULE_DEVICE_TABLE(i2c, lm75_ids); | 233 | MODULE_DEVICE_TABLE(i2c, lm75_ids); |
234 | 234 | ||
235 | #define LM75A_ID 0xA1 | ||
236 | |||
235 | /* Return 0 if detection is successful, -ENODEV otherwise */ | 237 | /* Return 0 if detection is successful, -ENODEV otherwise */ |
236 | static int lm75_detect(struct i2c_client *new_client, | 238 | static int lm75_detect(struct i2c_client *new_client, |
237 | struct i2c_board_info *info) | 239 | struct i2c_board_info *info) |
@@ -239,6 +241,7 @@ static int lm75_detect(struct i2c_client *new_client, | |||
239 | struct i2c_adapter *adapter = new_client->adapter; | 241 | struct i2c_adapter *adapter = new_client->adapter; |
240 | int i; | 242 | int i; |
241 | int cur, conf, hyst, os; | 243 | int cur, conf, hyst, os; |
244 | bool is_lm75a = 0; | ||
242 | 245 | ||
243 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | | 246 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | |
244 | I2C_FUNC_SMBUS_WORD_DATA)) | 247 | I2C_FUNC_SMBUS_WORD_DATA)) |
@@ -250,23 +253,43 @@ static int lm75_detect(struct i2c_client *new_client, | |||
250 | addresses 0x04-0x07 returning the last read value. | 253 | addresses 0x04-0x07 returning the last read value. |
251 | The cycling+unused addresses combination is not tested, | 254 | The cycling+unused addresses combination is not tested, |
252 | since it would significantly slow the detection down and would | 255 | since it would significantly slow the detection down and would |
253 | hardly add any value. */ | 256 | hardly add any value. |
257 | |||
258 | The National Semiconductor LM75A is different than earlier | ||
259 | LM75s. It has an ID byte of 0xaX (where X is the chip | ||
260 | revision, with 1 being the only revision in existence) in | ||
261 | register 7, and unused registers return 0xff rather than the | ||
262 | last read value. */ | ||
254 | 263 | ||
255 | /* Unused addresses */ | ||
256 | cur = i2c_smbus_read_word_data(new_client, 0); | 264 | cur = i2c_smbus_read_word_data(new_client, 0); |
257 | conf = i2c_smbus_read_byte_data(new_client, 1); | 265 | conf = i2c_smbus_read_byte_data(new_client, 1); |
258 | hyst = i2c_smbus_read_word_data(new_client, 2); | 266 | |
259 | if (i2c_smbus_read_word_data(new_client, 4) != hyst | 267 | /* First check for LM75A */ |
260 | || i2c_smbus_read_word_data(new_client, 5) != hyst | 268 | if (i2c_smbus_read_byte_data(new_client, 7) == LM75A_ID) { |
261 | || i2c_smbus_read_word_data(new_client, 6) != hyst | 269 | /* LM75A returns 0xff on unused registers so |
262 | || i2c_smbus_read_word_data(new_client, 7) != hyst) | 270 | just to be sure we check for that too. */ |
263 | return -ENODEV; | 271 | if (i2c_smbus_read_byte_data(new_client, 4) != 0xff |
264 | os = i2c_smbus_read_word_data(new_client, 3); | 272 | || i2c_smbus_read_byte_data(new_client, 5) != 0xff |
265 | if (i2c_smbus_read_word_data(new_client, 4) != os | 273 | || i2c_smbus_read_byte_data(new_client, 6) != 0xff) |
266 | || i2c_smbus_read_word_data(new_client, 5) != os | 274 | return -ENODEV; |
267 | || i2c_smbus_read_word_data(new_client, 6) != os | 275 | is_lm75a = 1; |
268 | || i2c_smbus_read_word_data(new_client, 7) != os) | 276 | hyst = i2c_smbus_read_word_data(new_client, 2); |
269 | return -ENODEV; | 277 | os = i2c_smbus_read_word_data(new_client, 3); |
278 | } else { /* Traditional style LM75 detection */ | ||
279 | /* Unused addresses */ | ||
280 | hyst = i2c_smbus_read_word_data(new_client, 2); | ||
281 | if (i2c_smbus_read_word_data(new_client, 4) != hyst | ||
282 | || i2c_smbus_read_word_data(new_client, 5) != hyst | ||
283 | || i2c_smbus_read_word_data(new_client, 6) != hyst | ||
284 | || i2c_smbus_read_word_data(new_client, 7) != hyst) | ||
285 | return -ENODEV; | ||
286 | os = i2c_smbus_read_word_data(new_client, 3); | ||
287 | if (i2c_smbus_read_word_data(new_client, 4) != os | ||
288 | || i2c_smbus_read_word_data(new_client, 5) != os | ||
289 | || i2c_smbus_read_word_data(new_client, 6) != os | ||
290 | || i2c_smbus_read_word_data(new_client, 7) != os) | ||
291 | return -ENODEV; | ||
292 | } | ||
270 | 293 | ||
271 | /* Unused bits */ | 294 | /* Unused bits */ |
272 | if (conf & 0xe0) | 295 | if (conf & 0xe0) |
@@ -278,9 +301,12 @@ static int lm75_detect(struct i2c_client *new_client, | |||
278 | || i2c_smbus_read_word_data(new_client, i + 2) != hyst | 301 | || i2c_smbus_read_word_data(new_client, i + 2) != hyst |
279 | || i2c_smbus_read_word_data(new_client, i + 3) != os) | 302 | || i2c_smbus_read_word_data(new_client, i + 3) != os) |
280 | return -ENODEV; | 303 | return -ENODEV; |
304 | if (is_lm75a && i2c_smbus_read_byte_data(new_client, i + 7) | ||
305 | != LM75A_ID) | ||
306 | return -ENODEV; | ||
281 | } | 307 | } |
282 | 308 | ||
283 | strlcpy(info->type, "lm75", I2C_NAME_SIZE); | 309 | strlcpy(info->type, is_lm75a ? "lm75a" : "lm75", I2C_NAME_SIZE); |
284 | 310 | ||
285 | return 0; | 311 | return 0; |
286 | } | 312 | } |