Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

hwmon: (lm95234) Add support for LM95233

LM95233 is similar to LM95234, but it only supports two
instead of four external temperature sensors.

Reviewed-by: Jean Delvare <jdelvare@suse.de>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>

+79 -35
+10 -5
Documentation/hwmon/lm95234
··· 2 2 ===================== 3 3 4 4 Supported chips: 5 + * National Semiconductor / Texas Instruments LM95233 6 + Addresses scanned: I2C 0x18, 0x2a, 0x2b 7 + Datasheet: Publicly available at the Texas Instruments website 8 + http://www.ti.com/product/lm95233 5 9 * National Semiconductor / Texas Instruments LM95234 6 10 Addresses scanned: I2C 0x18, 0x4d, 0x4e 7 11 Datasheet: Publicly available at the Texas Instruments website ··· 17 13 Description 18 14 ----------- 19 15 20 - LM95234 is an 11-bit digital temperature sensor with a 2-wire System Management 21 - Bus (SMBus) interface and TrueTherm technology that can very accurately monitor 22 - the temperature of four remote diodes as well as its own temperature. 23 - The four remote diodes can be external devices such as microprocessors, 24 - graphics processors or diode-connected 2N3904s. The LM95234's TruTherm 16 + LM95233 and LM95234 are 11-bit digital temperature sensors with a 2-wire 17 + System Management Bus (SMBus) interface and TrueTherm technology 18 + that can very accurately monitor the temperature of two (LM95233) 19 + or four (LM95234) remote diodes as well as its own temperature. 20 + The remote diodes can be external devices such as microprocessors, 21 + graphics processors or diode-connected 2N3904s. The chip's TruTherm 25 22 beta compensation technology allows sensing of 90 nm or 65 nm process 26 23 thermal diodes accurately. 27 24
+3 -3
drivers/hwmon/Kconfig
··· 1028 1028 will be called lm93. 1029 1029 1030 1030 config SENSORS_LM95234 1031 - tristate "National Semiconductor LM95234" 1031 + tristate "National Semiconductor LM95234 and compatibles" 1032 1032 depends on I2C 1033 1033 help 1034 - If you say yes here you get support for the LM95234 temperature 1035 - sensor. 1034 + If you say yes here you get support for the LM95233 and LM95234 1035 + temperature sensor chips. 1036 1036 1037 1037 This driver can also be built as a module. If so, the module 1038 1038 will be called lm95234.
+66 -27
drivers/hwmon/lm95234.c
··· 1 1 /* 2 2 * Driver for Texas Instruments / National Semiconductor LM95234 3 3 * 4 - * Copyright (c) 2013 Guenter Roeck <linux@roeck-us.net> 4 + * Copyright (c) 2013, 2014 Guenter Roeck <linux@roeck-us.net> 5 5 * 6 6 * Derived from lm95241.c 7 7 * Copyright (C) 2008, 2010 Davide Rizzo <elpa.rizzo@gmail.com> ··· 30 30 31 31 #define DRVNAME "lm95234" 32 32 33 - static const unsigned short normal_i2c[] = { 0x18, 0x4d, 0x4e, I2C_CLIENT_END }; 33 + enum chips { lm95233, lm95234 }; 34 + 35 + static const unsigned short normal_i2c[] = { 36 + 0x18, 0x2a, 0x2b, 0x4d, 0x4e, I2C_CLIENT_END }; 34 37 35 38 /* LM95234 registers */ 36 39 #define LM95234_REG_MAN_ID 0xFE ··· 56 53 #define LM95234_REG_TCRIT_HYST 0x5a 57 54 58 55 #define NATSEMI_MAN_ID 0x01 56 + #define LM95233_CHIP_ID 0x89 59 57 #define LM95234_CHIP_ID 0x79 60 58 61 59 /* Client data (each client gets its own) */ 62 60 struct lm95234_data { 63 61 struct i2c_client *client; 62 + const struct attribute_group *groups[3]; 64 63 struct mutex update_lock; 65 64 unsigned long last_updated, interval; /* in jiffies */ 66 65 bool valid; /* false until following fields are valid */ ··· 569 564 static DEVICE_ATTR(update_interval, S_IWUSR | S_IRUGO, show_interval, 570 565 set_interval); 571 566 572 - static struct attribute *lm95234_attrs[] = { 567 + static struct attribute *lm95234_common_attrs[] = { 573 568 &sensor_dev_attr_temp1_input.dev_attr.attr, 574 569 &sensor_dev_attr_temp2_input.dev_attr.attr, 575 570 &sensor_dev_attr_temp3_input.dev_attr.attr, 576 - &sensor_dev_attr_temp4_input.dev_attr.attr, 577 - &sensor_dev_attr_temp5_input.dev_attr.attr, 578 571 &sensor_dev_attr_temp2_fault.dev_attr.attr, 579 572 &sensor_dev_attr_temp3_fault.dev_attr.attr, 580 - &sensor_dev_attr_temp4_fault.dev_attr.attr, 581 - &sensor_dev_attr_temp5_fault.dev_attr.attr, 582 573 &sensor_dev_attr_temp2_type.dev_attr.attr, 583 574 &sensor_dev_attr_temp3_type.dev_attr.attr, 584 - &sensor_dev_attr_temp4_type.dev_attr.attr, 585 - &sensor_dev_attr_temp5_type.dev_attr.attr, 586 575 &sensor_dev_attr_temp1_max.dev_attr.attr, 587 576 &sensor_dev_attr_temp2_max.dev_attr.attr, 588 577 &sensor_dev_attr_temp3_max.dev_attr.attr, 589 - &sensor_dev_attr_temp4_max.dev_attr.attr, 590 - &sensor_dev_attr_temp5_max.dev_attr.attr, 591 578 &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, 592 579 &sensor_dev_attr_temp2_max_hyst.dev_attr.attr, 593 580 &sensor_dev_attr_temp3_max_hyst.dev_attr.attr, 594 - &sensor_dev_attr_temp4_max_hyst.dev_attr.attr, 595 - &sensor_dev_attr_temp5_max_hyst.dev_attr.attr, 596 581 &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, 597 582 &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, 598 583 &sensor_dev_attr_temp3_max_alarm.dev_attr.attr, 599 - &sensor_dev_attr_temp4_max_alarm.dev_attr.attr, 600 - &sensor_dev_attr_temp5_max_alarm.dev_attr.attr, 601 584 &sensor_dev_attr_temp2_crit.dev_attr.attr, 602 585 &sensor_dev_attr_temp3_crit.dev_attr.attr, 603 586 &sensor_dev_attr_temp2_crit_hyst.dev_attr.attr, ··· 594 601 &sensor_dev_attr_temp3_crit_alarm.dev_attr.attr, 595 602 &sensor_dev_attr_temp2_offset.dev_attr.attr, 596 603 &sensor_dev_attr_temp3_offset.dev_attr.attr, 597 - &sensor_dev_attr_temp4_offset.dev_attr.attr, 598 - &sensor_dev_attr_temp5_offset.dev_attr.attr, 599 604 &dev_attr_update_interval.attr, 600 605 NULL 601 606 }; 602 - ATTRIBUTE_GROUPS(lm95234); 607 + 608 + static const struct attribute_group lm95234_common_group = { 609 + .attrs = lm95234_common_attrs, 610 + }; 611 + 612 + static struct attribute *lm95234_attrs[] = { 613 + &sensor_dev_attr_temp4_input.dev_attr.attr, 614 + &sensor_dev_attr_temp5_input.dev_attr.attr, 615 + &sensor_dev_attr_temp4_fault.dev_attr.attr, 616 + &sensor_dev_attr_temp5_fault.dev_attr.attr, 617 + &sensor_dev_attr_temp4_type.dev_attr.attr, 618 + &sensor_dev_attr_temp5_type.dev_attr.attr, 619 + &sensor_dev_attr_temp4_max.dev_attr.attr, 620 + &sensor_dev_attr_temp5_max.dev_attr.attr, 621 + &sensor_dev_attr_temp4_max_hyst.dev_attr.attr, 622 + &sensor_dev_attr_temp5_max_hyst.dev_attr.attr, 623 + &sensor_dev_attr_temp4_max_alarm.dev_attr.attr, 624 + &sensor_dev_attr_temp5_max_alarm.dev_attr.attr, 625 + &sensor_dev_attr_temp4_offset.dev_attr.attr, 626 + &sensor_dev_attr_temp5_offset.dev_attr.attr, 627 + NULL 628 + }; 629 + 630 + static const struct attribute_group lm95234_group = { 631 + .attrs = lm95234_attrs, 632 + }; 603 633 604 634 static int lm95234_detect(struct i2c_client *client, 605 635 struct i2c_board_info *info) 606 636 { 607 637 struct i2c_adapter *adapter = client->adapter; 638 + int address = client->addr; 639 + u8 config_mask, model_mask; 608 640 int mfg_id, chip_id, val; 641 + const char *name; 609 642 610 643 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 611 644 return -ENODEV; ··· 641 622 return -ENODEV; 642 623 643 624 chip_id = i2c_smbus_read_byte_data(client, LM95234_REG_CHIP_ID); 644 - if (chip_id != LM95234_CHIP_ID) 625 + switch (chip_id) { 626 + case LM95233_CHIP_ID: 627 + if (address != 0x18 && address != 0x2a && address != 0x2b) 628 + return -ENODEV; 629 + config_mask = 0xbf; 630 + model_mask = 0xf9; 631 + name = "lm95233"; 632 + break; 633 + case LM95234_CHIP_ID: 634 + if (address != 0x18 && address != 0x4d && address != 0x4e) 635 + return -ENODEV; 636 + config_mask = 0xbc; 637 + model_mask = 0xe1; 638 + name = "lm95234"; 639 + break; 640 + default: 645 641 return -ENODEV; 642 + } 646 643 647 644 val = i2c_smbus_read_byte_data(client, LM95234_REG_STATUS); 648 645 if (val & 0x30) 649 646 return -ENODEV; 650 647 651 648 val = i2c_smbus_read_byte_data(client, LM95234_REG_CONFIG); 652 - if (val & 0xbc) 649 + if (val & config_mask) 653 650 return -ENODEV; 654 651 655 652 val = i2c_smbus_read_byte_data(client, LM95234_REG_CONVRATE); ··· 673 638 return -ENODEV; 674 639 675 640 val = i2c_smbus_read_byte_data(client, LM95234_REG_REM_MODEL); 676 - if (val & 0xe1) 641 + if (val & model_mask) 677 642 return -ENODEV; 678 643 679 644 val = i2c_smbus_read_byte_data(client, LM95234_REG_REM_MODEL_STS); 680 - if (val & 0xe1) 645 + if (val & model_mask) 681 646 return -ENODEV; 682 647 683 - strlcpy(info->type, "lm95234", I2C_NAME_SIZE); 648 + strlcpy(info->type, name, I2C_NAME_SIZE); 684 649 return 0; 685 650 } 686 651 ··· 733 698 if (err < 0) 734 699 return err; 735 700 701 + data->groups[0] = &lm95234_common_group; 702 + if (id->driver_data == lm95234) 703 + data->groups[1] = &lm95234_group; 704 + 736 705 hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, 737 - data, 738 - lm95234_groups); 706 + data, data->groups); 739 707 return PTR_ERR_OR_ZERO(hwmon_dev); 740 708 } 741 709 742 710 /* Driver data (common to all clients) */ 743 711 static const struct i2c_device_id lm95234_id[] = { 744 - { "lm95234", 0 }, 712 + { "lm95233", lm95233 }, 713 + { "lm95234", lm95234 }, 745 714 { } 746 715 }; 747 716 MODULE_DEVICE_TABLE(i2c, lm95234_id); ··· 764 725 module_i2c_driver(lm95234_driver); 765 726 766 727 MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>"); 767 - MODULE_DESCRIPTION("LM95234 sensor driver"); 728 + MODULE_DESCRIPTION("LM95233/LM95234 sensor driver"); 768 729 MODULE_LICENSE("GPL");