diff options
Diffstat (limited to 'drivers/hwmon/lm90.c')
-rw-r--r-- | drivers/hwmon/lm90.c | 181 |
1 files changed, 116 insertions, 65 deletions
diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c index 14de05fcd431..83cf2e1b09f5 100644 --- a/drivers/hwmon/lm90.c +++ b/drivers/hwmon/lm90.c | |||
@@ -31,7 +31,7 @@ | |||
31 | * Devices. That chip is similar to the LM90, with a few differences | 31 | * Devices. That chip is similar to the LM90, with a few differences |
32 | * that are not handled by this driver. Complete datasheet can be | 32 | * that are not handled by this driver. Complete datasheet can be |
33 | * obtained from Analog's website at: | 33 | * obtained from Analog's website at: |
34 | * http://products.analog.com/products/info.asp?product=ADM1032 | 34 | * http://www.analog.com/en/prod/0,2877,ADM1032,00.html |
35 | * Among others, it has a higher accuracy than the LM90, much like the | 35 | * Among others, it has a higher accuracy than the LM90, much like the |
36 | * LM86 does. | 36 | * LM86 does. |
37 | * | 37 | * |
@@ -49,7 +49,7 @@ | |||
49 | * register values are decoded differently) it is ignored by this | 49 | * register values are decoded differently) it is ignored by this |
50 | * driver. Complete datasheet can be obtained from Analog's website | 50 | * driver. Complete datasheet can be obtained from Analog's website |
51 | * at: | 51 | * at: |
52 | * http://products.analog.com/products/info.asp?product=ADT7461 | 52 | * http://www.analog.com/en/prod/0,2877,ADT7461,00.html |
53 | * | 53 | * |
54 | * Since the LM90 was the first chipset supported by this driver, most | 54 | * Since the LM90 was the first chipset supported by this driver, most |
55 | * comments will refer to this chipset, but are actually general and | 55 | * comments will refer to this chipset, but are actually general and |
@@ -83,10 +83,10 @@ | |||
83 | * Addresses to scan | 83 | * Addresses to scan |
84 | * Address is fully defined internally and cannot be changed except for | 84 | * Address is fully defined internally and cannot be changed except for |
85 | * MAX6659. | 85 | * MAX6659. |
86 | * LM86, LM89, LM90, LM99, ADM1032, MAX6657 and MAX6658 have address 0x4c. | 86 | * LM86, LM89, LM90, LM99, ADM1032, ADM1032-1, ADT7461, MAX6657 and MAX6658 |
87 | * LM89-1, and LM99-1 have address 0x4d. | 87 | * have address 0x4c. |
88 | * ADM1032-2, ADT7461-2, LM89-1, and LM99-1 have address 0x4d. | ||
88 | * MAX6659 can have address 0x4c, 0x4d or 0x4e (unsupported). | 89 | * MAX6659 can have address 0x4c, 0x4d or 0x4e (unsupported). |
89 | * ADT7461 always has address 0x4c. | ||
90 | */ | 90 | */ |
91 | 91 | ||
92 | static unsigned short normal_i2c[] = { 0x4c, 0x4d, I2C_CLIENT_END }; | 92 | static unsigned short normal_i2c[] = { 0x4c, 0x4d, I2C_CLIENT_END }; |
@@ -345,10 +345,74 @@ static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IWUSR | S_IRUGO, show_temphyst, | |||
345 | static SENSOR_DEVICE_ATTR(temp2_crit_hyst, S_IRUGO, show_temphyst, NULL, 4); | 345 | static SENSOR_DEVICE_ATTR(temp2_crit_hyst, S_IRUGO, show_temphyst, NULL, 4); |
346 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); | 346 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); |
347 | 347 | ||
348 | /* pec used for ADM1032 only */ | ||
349 | static ssize_t show_pec(struct device *dev, struct device_attribute *dummy, | ||
350 | char *buf) | ||
351 | { | ||
352 | struct i2c_client *client = to_i2c_client(dev); | ||
353 | return sprintf(buf, "%d\n", !!(client->flags & I2C_CLIENT_PEC)); | ||
354 | } | ||
355 | |||
356 | static ssize_t set_pec(struct device *dev, struct device_attribute *dummy, | ||
357 | const char *buf, size_t count) | ||
358 | { | ||
359 | struct i2c_client *client = to_i2c_client(dev); | ||
360 | long val = simple_strtol(buf, NULL, 10); | ||
361 | |||
362 | switch (val) { | ||
363 | case 0: | ||
364 | client->flags &= ~I2C_CLIENT_PEC; | ||
365 | break; | ||
366 | case 1: | ||
367 | client->flags |= I2C_CLIENT_PEC; | ||
368 | break; | ||
369 | default: | ||
370 | return -EINVAL; | ||
371 | } | ||
372 | |||
373 | return count; | ||
374 | } | ||
375 | |||
376 | static DEVICE_ATTR(pec, S_IWUSR | S_IRUGO, show_pec, set_pec); | ||
377 | |||
348 | /* | 378 | /* |
349 | * Real code | 379 | * Real code |
350 | */ | 380 | */ |
351 | 381 | ||
382 | /* The ADM1032 supports PEC but not on write byte transactions, so we need | ||
383 | to explicitely ask for a transaction without PEC. */ | ||
384 | static inline s32 adm1032_write_byte(struct i2c_client *client, u8 value) | ||
385 | { | ||
386 | return i2c_smbus_xfer(client->adapter, client->addr, | ||
387 | client->flags & ~I2C_CLIENT_PEC, | ||
388 | I2C_SMBUS_WRITE, value, I2C_SMBUS_BYTE, NULL); | ||
389 | } | ||
390 | |||
391 | /* It is assumed that client->update_lock is held (unless we are in | ||
392 | detection or initialization steps). This matters when PEC is enabled, | ||
393 | because we don't want the address pointer to change between the write | ||
394 | byte and the read byte transactions. */ | ||
395 | static int lm90_read_reg(struct i2c_client* client, u8 reg, u8 *value) | ||
396 | { | ||
397 | int err; | ||
398 | |||
399 | if (client->flags & I2C_CLIENT_PEC) { | ||
400 | err = adm1032_write_byte(client, reg); | ||
401 | if (err >= 0) | ||
402 | err = i2c_smbus_read_byte(client); | ||
403 | } else | ||
404 | err = i2c_smbus_read_byte_data(client, reg); | ||
405 | |||
406 | if (err < 0) { | ||
407 | dev_warn(&client->dev, "Register %#02x read failed (%d)\n", | ||
408 | reg, err); | ||
409 | return err; | ||
410 | } | ||
411 | *value = err; | ||
412 | |||
413 | return 0; | ||
414 | } | ||
415 | |||
352 | static int lm90_attach_adapter(struct i2c_adapter *adapter) | 416 | static int lm90_attach_adapter(struct i2c_adapter *adapter) |
353 | { | 417 | { |
354 | if (!(adapter->class & I2C_CLASS_HWMON)) | 418 | if (!(adapter->class & I2C_CLASS_HWMON)) |
@@ -370,11 +434,10 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind) | |||
370 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | 434 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) |
371 | goto exit; | 435 | goto exit; |
372 | 436 | ||
373 | if (!(data = kmalloc(sizeof(struct lm90_data), GFP_KERNEL))) { | 437 | if (!(data = kzalloc(sizeof(struct lm90_data), GFP_KERNEL))) { |
374 | err = -ENOMEM; | 438 | err = -ENOMEM; |
375 | goto exit; | 439 | goto exit; |
376 | } | 440 | } |
377 | memset(data, 0, sizeof(struct lm90_data)); | ||
378 | 441 | ||
379 | /* The common I2C client data is placed right before the | 442 | /* The common I2C client data is placed right before the |
380 | LM90-specific data. */ | 443 | LM90-specific data. */ |
@@ -403,20 +466,22 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind) | |||
403 | if (kind < 0) { /* detection and identification */ | 466 | if (kind < 0) { /* detection and identification */ |
404 | u8 man_id, chip_id, reg_config1, reg_convrate; | 467 | u8 man_id, chip_id, reg_config1, reg_convrate; |
405 | 468 | ||
406 | man_id = i2c_smbus_read_byte_data(new_client, | 469 | if (lm90_read_reg(new_client, LM90_REG_R_MAN_ID, |
407 | LM90_REG_R_MAN_ID); | 470 | &man_id) < 0 |
408 | chip_id = i2c_smbus_read_byte_data(new_client, | 471 | || lm90_read_reg(new_client, LM90_REG_R_CHIP_ID, |
409 | LM90_REG_R_CHIP_ID); | 472 | &chip_id) < 0 |
410 | reg_config1 = i2c_smbus_read_byte_data(new_client, | 473 | || lm90_read_reg(new_client, LM90_REG_R_CONFIG1, |
411 | LM90_REG_R_CONFIG1); | 474 | ®_config1) < 0 |
412 | reg_convrate = i2c_smbus_read_byte_data(new_client, | 475 | || lm90_read_reg(new_client, LM90_REG_R_CONVRATE, |
413 | LM90_REG_R_CONVRATE); | 476 | ®_convrate) < 0) |
477 | goto exit_free; | ||
414 | 478 | ||
415 | if (man_id == 0x01) { /* National Semiconductor */ | 479 | if (man_id == 0x01) { /* National Semiconductor */ |
416 | u8 reg_config2; | 480 | u8 reg_config2; |
417 | 481 | ||
418 | reg_config2 = i2c_smbus_read_byte_data(new_client, | 482 | if (lm90_read_reg(new_client, LM90_REG_R_CONFIG2, |
419 | LM90_REG_R_CONFIG2); | 483 | ®_config2) < 0) |
484 | goto exit_free; | ||
420 | 485 | ||
421 | if ((reg_config1 & 0x2A) == 0x00 | 486 | if ((reg_config1 & 0x2A) == 0x00 |
422 | && (reg_config2 & 0xF8) == 0x00 | 487 | && (reg_config2 & 0xF8) == 0x00 |
@@ -435,14 +500,12 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind) | |||
435 | } | 500 | } |
436 | } else | 501 | } else |
437 | if (man_id == 0x41) { /* Analog Devices */ | 502 | if (man_id == 0x41) { /* Analog Devices */ |
438 | if (address == 0x4C | 503 | if ((chip_id & 0xF0) == 0x40 /* ADM1032 */ |
439 | && (chip_id & 0xF0) == 0x40 /* ADM1032 */ | ||
440 | && (reg_config1 & 0x3F) == 0x00 | 504 | && (reg_config1 & 0x3F) == 0x00 |
441 | && reg_convrate <= 0x0A) { | 505 | && reg_convrate <= 0x0A) { |
442 | kind = adm1032; | 506 | kind = adm1032; |
443 | } else | 507 | } else |
444 | if (address == 0x4c | 508 | if (chip_id == 0x51 /* ADT7461 */ |
445 | && chip_id == 0x51 /* ADT7461 */ | ||
446 | && (reg_config1 & 0x1F) == 0x00 /* check compat mode */ | 509 | && (reg_config1 & 0x1F) == 0x00 /* check compat mode */ |
447 | && reg_convrate <= 0x0A) { | 510 | && reg_convrate <= 0x0A) { |
448 | kind = adt7461; | 511 | kind = adt7461; |
@@ -477,6 +540,10 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind) | |||
477 | name = "lm90"; | 540 | name = "lm90"; |
478 | } else if (kind == adm1032) { | 541 | } else if (kind == adm1032) { |
479 | name = "adm1032"; | 542 | name = "adm1032"; |
543 | /* The ADM1032 supports PEC, but only if combined | ||
544 | transactions are not used. */ | ||
545 | if (i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) | ||
546 | new_client->flags |= I2C_CLIENT_PEC; | ||
480 | } else if (kind == lm99) { | 547 | } else if (kind == lm99) { |
481 | name = "lm99"; | 548 | name = "lm99"; |
482 | } else if (kind == lm86) { | 549 | } else if (kind == lm86) { |
@@ -529,6 +596,9 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind) | |||
529 | &sensor_dev_attr_temp2_crit_hyst.dev_attr); | 596 | &sensor_dev_attr_temp2_crit_hyst.dev_attr); |
530 | device_create_file(&new_client->dev, &dev_attr_alarms); | 597 | device_create_file(&new_client->dev, &dev_attr_alarms); |
531 | 598 | ||
599 | if (new_client->flags & I2C_CLIENT_PEC) | ||
600 | device_create_file(&new_client->dev, &dev_attr_pec); | ||
601 | |||
532 | return 0; | 602 | return 0; |
533 | 603 | ||
534 | exit_detach: | 604 | exit_detach: |
@@ -548,7 +618,10 @@ static void lm90_init_client(struct i2c_client *client) | |||
548 | */ | 618 | */ |
549 | i2c_smbus_write_byte_data(client, LM90_REG_W_CONVRATE, | 619 | i2c_smbus_write_byte_data(client, LM90_REG_W_CONVRATE, |
550 | 5); /* 2 Hz */ | 620 | 5); /* 2 Hz */ |
551 | config = i2c_smbus_read_byte_data(client, LM90_REG_R_CONFIG1); | 621 | if (lm90_read_reg(client, LM90_REG_R_CONFIG1, &config) < 0) { |
622 | dev_warn(&client->dev, "Initialization failed!\n"); | ||
623 | return; | ||
624 | } | ||
552 | if (config & 0x40) | 625 | if (config & 0x40) |
553 | i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1, | 626 | i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1, |
554 | config & 0xBF); /* run */ | 627 | config & 0xBF); /* run */ |
@@ -576,21 +649,15 @@ static struct lm90_data *lm90_update_device(struct device *dev) | |||
576 | down(&data->update_lock); | 649 | down(&data->update_lock); |
577 | 650 | ||
578 | if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) { | 651 | if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) { |
579 | u8 oldh, newh; | 652 | u8 oldh, newh, l; |
580 | 653 | ||
581 | dev_dbg(&client->dev, "Updating lm90 data.\n"); | 654 | dev_dbg(&client->dev, "Updating lm90 data.\n"); |
582 | data->temp8[0] = i2c_smbus_read_byte_data(client, | 655 | lm90_read_reg(client, LM90_REG_R_LOCAL_TEMP, &data->temp8[0]); |
583 | LM90_REG_R_LOCAL_TEMP); | 656 | lm90_read_reg(client, LM90_REG_R_LOCAL_LOW, &data->temp8[1]); |
584 | data->temp8[1] = i2c_smbus_read_byte_data(client, | 657 | lm90_read_reg(client, LM90_REG_R_LOCAL_HIGH, &data->temp8[2]); |
585 | LM90_REG_R_LOCAL_LOW); | 658 | lm90_read_reg(client, LM90_REG_R_LOCAL_CRIT, &data->temp8[3]); |
586 | data->temp8[2] = i2c_smbus_read_byte_data(client, | 659 | lm90_read_reg(client, LM90_REG_R_REMOTE_CRIT, &data->temp8[4]); |
587 | LM90_REG_R_LOCAL_HIGH); | 660 | lm90_read_reg(client, LM90_REG_R_TCRIT_HYST, &data->temp_hyst); |
588 | data->temp8[3] = i2c_smbus_read_byte_data(client, | ||
589 | LM90_REG_R_LOCAL_CRIT); | ||
590 | data->temp8[4] = i2c_smbus_read_byte_data(client, | ||
591 | LM90_REG_R_REMOTE_CRIT); | ||
592 | data->temp_hyst = i2c_smbus_read_byte_data(client, | ||
593 | LM90_REG_R_TCRIT_HYST); | ||
594 | 661 | ||
595 | /* | 662 | /* |
596 | * There is a trick here. We have to read two registers to | 663 | * There is a trick here. We have to read two registers to |
@@ -606,36 +673,20 @@ static struct lm90_data *lm90_update_device(struct device *dev) | |||
606 | * then we have a valid reading. Else we have to read the low | 673 | * then we have a valid reading. Else we have to read the low |
607 | * byte again, and now we believe we have a correct reading. | 674 | * byte again, and now we believe we have a correct reading. |
608 | */ | 675 | */ |
609 | oldh = i2c_smbus_read_byte_data(client, | 676 | if (lm90_read_reg(client, LM90_REG_R_REMOTE_TEMPH, &oldh) == 0 |
610 | LM90_REG_R_REMOTE_TEMPH); | 677 | && lm90_read_reg(client, LM90_REG_R_REMOTE_TEMPL, &l) == 0 |
611 | data->temp11[0] = i2c_smbus_read_byte_data(client, | 678 | && lm90_read_reg(client, LM90_REG_R_REMOTE_TEMPH, &newh) == 0 |
612 | LM90_REG_R_REMOTE_TEMPL); | 679 | && (newh == oldh |
613 | newh = i2c_smbus_read_byte_data(client, | 680 | || lm90_read_reg(client, LM90_REG_R_REMOTE_TEMPL, &l) == 0)) |
614 | LM90_REG_R_REMOTE_TEMPH); | 681 | data->temp11[0] = (newh << 8) | l; |
615 | if (newh != oldh) { | 682 | |
616 | data->temp11[0] = i2c_smbus_read_byte_data(client, | 683 | if (lm90_read_reg(client, LM90_REG_R_REMOTE_LOWH, &newh) == 0 |
617 | LM90_REG_R_REMOTE_TEMPL); | 684 | && lm90_read_reg(client, LM90_REG_R_REMOTE_LOWL, &l) == 0) |
618 | #ifdef DEBUG | 685 | data->temp11[1] = (newh << 8) | l; |
619 | oldh = i2c_smbus_read_byte_data(client, | 686 | if (lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHH, &newh) == 0 |
620 | LM90_REG_R_REMOTE_TEMPH); | 687 | && lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHL, &l) == 0) |
621 | /* oldh is actually newer */ | 688 | data->temp11[2] = (newh << 8) | l; |
622 | if (newh != oldh) | 689 | lm90_read_reg(client, LM90_REG_R_STATUS, &data->alarms); |
623 | dev_warn(&client->dev, "Remote temperature may be " | ||
624 | "wrong.\n"); | ||
625 | #endif | ||
626 | } | ||
627 | data->temp11[0] |= (newh << 8); | ||
628 | |||
629 | data->temp11[1] = (i2c_smbus_read_byte_data(client, | ||
630 | LM90_REG_R_REMOTE_LOWH) << 8) + | ||
631 | i2c_smbus_read_byte_data(client, | ||
632 | LM90_REG_R_REMOTE_LOWL); | ||
633 | data->temp11[2] = (i2c_smbus_read_byte_data(client, | ||
634 | LM90_REG_R_REMOTE_HIGHH) << 8) + | ||
635 | i2c_smbus_read_byte_data(client, | ||
636 | LM90_REG_R_REMOTE_HIGHL); | ||
637 | data->alarms = i2c_smbus_read_byte_data(client, | ||
638 | LM90_REG_R_STATUS); | ||
639 | 690 | ||
640 | data->last_updated = jiffies; | 691 | data->last_updated = jiffies; |
641 | data->valid = 1; | 692 | data->valid = 1; |