diff options
author | Guenter Roeck <linux@roeck-us.net> | 2014-04-22 12:34:14 -0400 |
---|---|---|
committer | Guenter Roeck <linux@roeck-us.net> | 2014-12-02 09:11:53 -0500 |
commit | dfcd4c53be1da9e297bba340ec46f3269cbc239e (patch) | |
tree | f409d8b31a0705fc7a9ba74b813fca51de458a51 /drivers/hwmon/lm95234.c | |
parent | 162a8dfe73df95e59265e350b2f247b8b35490d1 (diff) |
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>
Diffstat (limited to 'drivers/hwmon/lm95234.c')
-rw-r--r-- | drivers/hwmon/lm95234.c | 91 |
1 files changed, 65 insertions, 26 deletions
diff --git a/drivers/hwmon/lm95234.c b/drivers/hwmon/lm95234.c index 411202bdaf6b..8796de39ff9b 100644 --- a/drivers/hwmon/lm95234.c +++ b/drivers/hwmon/lm95234.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Driver for Texas Instruments / National Semiconductor LM95234 | 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 | * Derived from lm95241.c | 6 | * Derived from lm95241.c |
7 | * Copyright (C) 2008, 2010 Davide Rizzo <elpa.rizzo@gmail.com> | 7 | * Copyright (C) 2008, 2010 Davide Rizzo <elpa.rizzo@gmail.com> |
@@ -30,7 +30,10 @@ | |||
30 | 30 | ||
31 | #define DRVNAME "lm95234" | 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 | /* LM95234 registers */ | 38 | /* LM95234 registers */ |
36 | #define LM95234_REG_MAN_ID 0xFE | 39 | #define LM95234_REG_MAN_ID 0xFE |
@@ -53,11 +56,13 @@ static const unsigned short normal_i2c[] = { 0x18, 0x4d, 0x4e, I2C_CLIENT_END }; | |||
53 | #define LM95234_REG_TCRIT_HYST 0x5a | 56 | #define LM95234_REG_TCRIT_HYST 0x5a |
54 | 57 | ||
55 | #define NATSEMI_MAN_ID 0x01 | 58 | #define NATSEMI_MAN_ID 0x01 |
59 | #define LM95233_CHIP_ID 0x89 | ||
56 | #define LM95234_CHIP_ID 0x79 | 60 | #define LM95234_CHIP_ID 0x79 |
57 | 61 | ||
58 | /* Client data (each client gets its own) */ | 62 | /* Client data (each client gets its own) */ |
59 | struct lm95234_data { | 63 | struct lm95234_data { |
60 | struct i2c_client *client; | 64 | struct i2c_client *client; |
65 | const struct attribute_group *groups[3]; | ||
61 | struct mutex update_lock; | 66 | struct mutex update_lock; |
62 | unsigned long last_updated, interval; /* in jiffies */ | 67 | unsigned long last_updated, interval; /* in jiffies */ |
63 | bool valid; /* false until following fields are valid */ | 68 | bool valid; /* false until following fields are valid */ |
@@ -564,35 +569,23 @@ static SENSOR_DEVICE_ATTR(temp5_offset, S_IWUSR | S_IRUGO, show_offset, | |||
564 | static DEVICE_ATTR(update_interval, S_IWUSR | S_IRUGO, show_interval, | 569 | static DEVICE_ATTR(update_interval, S_IWUSR | S_IRUGO, show_interval, |
565 | set_interval); | 570 | set_interval); |
566 | 571 | ||
567 | static struct attribute *lm95234_attrs[] = { | 572 | static struct attribute *lm95234_common_attrs[] = { |
568 | &sensor_dev_attr_temp1_input.dev_attr.attr, | 573 | &sensor_dev_attr_temp1_input.dev_attr.attr, |
569 | &sensor_dev_attr_temp2_input.dev_attr.attr, | 574 | &sensor_dev_attr_temp2_input.dev_attr.attr, |
570 | &sensor_dev_attr_temp3_input.dev_attr.attr, | 575 | &sensor_dev_attr_temp3_input.dev_attr.attr, |
571 | &sensor_dev_attr_temp4_input.dev_attr.attr, | ||
572 | &sensor_dev_attr_temp5_input.dev_attr.attr, | ||
573 | &sensor_dev_attr_temp2_fault.dev_attr.attr, | 576 | &sensor_dev_attr_temp2_fault.dev_attr.attr, |
574 | &sensor_dev_attr_temp3_fault.dev_attr.attr, | 577 | &sensor_dev_attr_temp3_fault.dev_attr.attr, |
575 | &sensor_dev_attr_temp4_fault.dev_attr.attr, | ||
576 | &sensor_dev_attr_temp5_fault.dev_attr.attr, | ||
577 | &sensor_dev_attr_temp2_type.dev_attr.attr, | 578 | &sensor_dev_attr_temp2_type.dev_attr.attr, |
578 | &sensor_dev_attr_temp3_type.dev_attr.attr, | 579 | &sensor_dev_attr_temp3_type.dev_attr.attr, |
579 | &sensor_dev_attr_temp4_type.dev_attr.attr, | ||
580 | &sensor_dev_attr_temp5_type.dev_attr.attr, | ||
581 | &sensor_dev_attr_temp1_max.dev_attr.attr, | 580 | &sensor_dev_attr_temp1_max.dev_attr.attr, |
582 | &sensor_dev_attr_temp2_max.dev_attr.attr, | 581 | &sensor_dev_attr_temp2_max.dev_attr.attr, |
583 | &sensor_dev_attr_temp3_max.dev_attr.attr, | 582 | &sensor_dev_attr_temp3_max.dev_attr.attr, |
584 | &sensor_dev_attr_temp4_max.dev_attr.attr, | ||
585 | &sensor_dev_attr_temp5_max.dev_attr.attr, | ||
586 | &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, | 583 | &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, |
587 | &sensor_dev_attr_temp2_max_hyst.dev_attr.attr, | 584 | &sensor_dev_attr_temp2_max_hyst.dev_attr.attr, |
588 | &sensor_dev_attr_temp3_max_hyst.dev_attr.attr, | 585 | &sensor_dev_attr_temp3_max_hyst.dev_attr.attr, |
589 | &sensor_dev_attr_temp4_max_hyst.dev_attr.attr, | ||
590 | &sensor_dev_attr_temp5_max_hyst.dev_attr.attr, | ||
591 | &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, | 586 | &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, |
592 | &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, | 587 | &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, |
593 | &sensor_dev_attr_temp3_max_alarm.dev_attr.attr, | 588 | &sensor_dev_attr_temp3_max_alarm.dev_attr.attr, |
594 | &sensor_dev_attr_temp4_max_alarm.dev_attr.attr, | ||
595 | &sensor_dev_attr_temp5_max_alarm.dev_attr.attr, | ||
596 | &sensor_dev_attr_temp2_crit.dev_attr.attr, | 589 | &sensor_dev_attr_temp2_crit.dev_attr.attr, |
597 | &sensor_dev_attr_temp3_crit.dev_attr.attr, | 590 | &sensor_dev_attr_temp3_crit.dev_attr.attr, |
598 | &sensor_dev_attr_temp2_crit_hyst.dev_attr.attr, | 591 | &sensor_dev_attr_temp2_crit_hyst.dev_attr.attr, |
@@ -601,18 +594,44 @@ static struct attribute *lm95234_attrs[] = { | |||
601 | &sensor_dev_attr_temp3_crit_alarm.dev_attr.attr, | 594 | &sensor_dev_attr_temp3_crit_alarm.dev_attr.attr, |
602 | &sensor_dev_attr_temp2_offset.dev_attr.attr, | 595 | &sensor_dev_attr_temp2_offset.dev_attr.attr, |
603 | &sensor_dev_attr_temp3_offset.dev_attr.attr, | 596 | &sensor_dev_attr_temp3_offset.dev_attr.attr, |
597 | &dev_attr_update_interval.attr, | ||
598 | NULL | ||
599 | }; | ||
600 | |||
601 | static const struct attribute_group lm95234_common_group = { | ||
602 | .attrs = lm95234_common_attrs, | ||
603 | }; | ||
604 | |||
605 | static struct attribute *lm95234_attrs[] = { | ||
606 | &sensor_dev_attr_temp4_input.dev_attr.attr, | ||
607 | &sensor_dev_attr_temp5_input.dev_attr.attr, | ||
608 | &sensor_dev_attr_temp4_fault.dev_attr.attr, | ||
609 | &sensor_dev_attr_temp5_fault.dev_attr.attr, | ||
610 | &sensor_dev_attr_temp4_type.dev_attr.attr, | ||
611 | &sensor_dev_attr_temp5_type.dev_attr.attr, | ||
612 | &sensor_dev_attr_temp4_max.dev_attr.attr, | ||
613 | &sensor_dev_attr_temp5_max.dev_attr.attr, | ||
614 | &sensor_dev_attr_temp4_max_hyst.dev_attr.attr, | ||
615 | &sensor_dev_attr_temp5_max_hyst.dev_attr.attr, | ||
616 | &sensor_dev_attr_temp4_max_alarm.dev_attr.attr, | ||
617 | &sensor_dev_attr_temp5_max_alarm.dev_attr.attr, | ||
604 | &sensor_dev_attr_temp4_offset.dev_attr.attr, | 618 | &sensor_dev_attr_temp4_offset.dev_attr.attr, |
605 | &sensor_dev_attr_temp5_offset.dev_attr.attr, | 619 | &sensor_dev_attr_temp5_offset.dev_attr.attr, |
606 | &dev_attr_update_interval.attr, | ||
607 | NULL | 620 | NULL |
608 | }; | 621 | }; |
609 | ATTRIBUTE_GROUPS(lm95234); | 622 | |
623 | static const struct attribute_group lm95234_group = { | ||
624 | .attrs = lm95234_attrs, | ||
625 | }; | ||
610 | 626 | ||
611 | static int lm95234_detect(struct i2c_client *client, | 627 | static int lm95234_detect(struct i2c_client *client, |
612 | struct i2c_board_info *info) | 628 | struct i2c_board_info *info) |
613 | { | 629 | { |
614 | struct i2c_adapter *adapter = client->adapter; | 630 | struct i2c_adapter *adapter = client->adapter; |
631 | int address = client->addr; | ||
632 | u8 config_mask, model_mask; | ||
615 | int mfg_id, chip_id, val; | 633 | int mfg_id, chip_id, val; |
634 | const char *name; | ||
616 | 635 | ||
617 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | 636 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) |
618 | return -ENODEV; | 637 | return -ENODEV; |
@@ -622,15 +641,31 @@ static int lm95234_detect(struct i2c_client *client, | |||
622 | return -ENODEV; | 641 | return -ENODEV; |
623 | 642 | ||
624 | chip_id = i2c_smbus_read_byte_data(client, LM95234_REG_CHIP_ID); | 643 | chip_id = i2c_smbus_read_byte_data(client, LM95234_REG_CHIP_ID); |
625 | if (chip_id != LM95234_CHIP_ID) | 644 | switch (chip_id) { |
645 | case LM95233_CHIP_ID: | ||
646 | if (address != 0x18 && address != 0x2a && address != 0x2b) | ||
647 | return -ENODEV; | ||
648 | config_mask = 0xbf; | ||
649 | model_mask = 0xf9; | ||
650 | name = "lm95233"; | ||
651 | break; | ||
652 | case LM95234_CHIP_ID: | ||
653 | if (address != 0x18 && address != 0x4d && address != 0x4e) | ||
654 | return -ENODEV; | ||
655 | config_mask = 0xbc; | ||
656 | model_mask = 0xe1; | ||
657 | name = "lm95234"; | ||
658 | break; | ||
659 | default: | ||
626 | return -ENODEV; | 660 | return -ENODEV; |
661 | } | ||
627 | 662 | ||
628 | val = i2c_smbus_read_byte_data(client, LM95234_REG_STATUS); | 663 | val = i2c_smbus_read_byte_data(client, LM95234_REG_STATUS); |
629 | if (val & 0x30) | 664 | if (val & 0x30) |
630 | return -ENODEV; | 665 | return -ENODEV; |
631 | 666 | ||
632 | val = i2c_smbus_read_byte_data(client, LM95234_REG_CONFIG); | 667 | val = i2c_smbus_read_byte_data(client, LM95234_REG_CONFIG); |
633 | if (val & 0xbc) | 668 | if (val & config_mask) |
634 | return -ENODEV; | 669 | return -ENODEV; |
635 | 670 | ||
636 | val = i2c_smbus_read_byte_data(client, LM95234_REG_CONVRATE); | 671 | val = i2c_smbus_read_byte_data(client, LM95234_REG_CONVRATE); |
@@ -638,14 +673,14 @@ static int lm95234_detect(struct i2c_client *client, | |||
638 | return -ENODEV; | 673 | return -ENODEV; |
639 | 674 | ||
640 | val = i2c_smbus_read_byte_data(client, LM95234_REG_REM_MODEL); | 675 | val = i2c_smbus_read_byte_data(client, LM95234_REG_REM_MODEL); |
641 | if (val & 0xe1) | 676 | if (val & model_mask) |
642 | return -ENODEV; | 677 | return -ENODEV; |
643 | 678 | ||
644 | val = i2c_smbus_read_byte_data(client, LM95234_REG_REM_MODEL_STS); | 679 | val = i2c_smbus_read_byte_data(client, LM95234_REG_REM_MODEL_STS); |
645 | if (val & 0xe1) | 680 | if (val & model_mask) |
646 | return -ENODEV; | 681 | return -ENODEV; |
647 | 682 | ||
648 | strlcpy(info->type, "lm95234", I2C_NAME_SIZE); | 683 | strlcpy(info->type, name, I2C_NAME_SIZE); |
649 | return 0; | 684 | return 0; |
650 | } | 685 | } |
651 | 686 | ||
@@ -698,15 +733,19 @@ static int lm95234_probe(struct i2c_client *client, | |||
698 | if (err < 0) | 733 | if (err < 0) |
699 | return err; | 734 | return err; |
700 | 735 | ||
736 | data->groups[0] = &lm95234_common_group; | ||
737 | if (id->driver_data == lm95234) | ||
738 | data->groups[1] = &lm95234_group; | ||
739 | |||
701 | hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, | 740 | hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, |
702 | data, | 741 | data, data->groups); |
703 | lm95234_groups); | ||
704 | return PTR_ERR_OR_ZERO(hwmon_dev); | 742 | return PTR_ERR_OR_ZERO(hwmon_dev); |
705 | } | 743 | } |
706 | 744 | ||
707 | /* Driver data (common to all clients) */ | 745 | /* Driver data (common to all clients) */ |
708 | static const struct i2c_device_id lm95234_id[] = { | 746 | static const struct i2c_device_id lm95234_id[] = { |
709 | { "lm95234", 0 }, | 747 | { "lm95233", lm95233 }, |
748 | { "lm95234", lm95234 }, | ||
710 | { } | 749 | { } |
711 | }; | 750 | }; |
712 | MODULE_DEVICE_TABLE(i2c, lm95234_id); | 751 | MODULE_DEVICE_TABLE(i2c, lm95234_id); |
@@ -725,5 +764,5 @@ static struct i2c_driver lm95234_driver = { | |||
725 | module_i2c_driver(lm95234_driver); | 764 | module_i2c_driver(lm95234_driver); |
726 | 765 | ||
727 | MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>"); | 766 | MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>"); |
728 | MODULE_DESCRIPTION("LM95234 sensor driver"); | 767 | MODULE_DESCRIPTION("LM95233/LM95234 sensor driver"); |
729 | MODULE_LICENSE("GPL"); | 768 | MODULE_LICENSE("GPL"); |