aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/lm90.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwmon/lm90.c')
-rw-r--r--drivers/hwmon/lm90.c89
1 files changed, 84 insertions, 5 deletions
diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c
index 7c9bdc167426..7cc2708871ab 100644
--- a/drivers/hwmon/lm90.c
+++ b/drivers/hwmon/lm90.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * lm90.c - Part of lm_sensors, Linux kernel modules for hardware 2 * lm90.c - Part of lm_sensors, Linux kernel modules for hardware
3 * monitoring 3 * monitoring
4 * Copyright (C) 2003-2009 Jean Delvare <khali@linux-fr.org> 4 * Copyright (C) 2003-2010 Jean Delvare <khali@linux-fr.org>
5 * 5 *
6 * Based on the lm83 driver. The LM90 is a sensor chip made by National 6 * Based on the lm83 driver. The LM90 is a sensor chip made by National
7 * Semiconductor. It reports up to two temperatures (its own plus up to 7 * Semiconductor. It reports up to two temperatures (its own plus up to
@@ -93,7 +93,8 @@
93static const unsigned short normal_i2c[] = { 93static const unsigned short normal_i2c[] = {
94 0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b, 0x4c, 0x4d, 0x4e, I2C_CLIENT_END }; 94 0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b, 0x4c, 0x4d, 0x4e, I2C_CLIENT_END };
95 95
96enum chips { lm90, adm1032, lm99, lm86, max6657, adt7461, max6680, max6646 }; 96enum chips { lm90, adm1032, lm99, lm86, max6657, adt7461, max6680, max6646,
97 w83l771 };
97 98
98/* 99/*
99 * The LM90 registers 100 * The LM90 registers
@@ -151,6 +152,7 @@ static int lm90_detect(struct i2c_client *client, struct i2c_board_info *info);
151static int lm90_probe(struct i2c_client *client, 152static int lm90_probe(struct i2c_client *client,
152 const struct i2c_device_id *id); 153 const struct i2c_device_id *id);
153static void lm90_init_client(struct i2c_client *client); 154static void lm90_init_client(struct i2c_client *client);
155static void lm90_alert(struct i2c_client *client, unsigned int flag);
154static int lm90_remove(struct i2c_client *client); 156static int lm90_remove(struct i2c_client *client);
155static struct lm90_data *lm90_update_device(struct device *dev); 157static struct lm90_data *lm90_update_device(struct device *dev);
156 158
@@ -173,6 +175,7 @@ static const struct i2c_device_id lm90_id[] = {
173 { "max6659", max6657 }, 175 { "max6659", max6657 },
174 { "max6680", max6680 }, 176 { "max6680", max6680 },
175 { "max6681", max6680 }, 177 { "max6681", max6680 },
178 { "w83l771", w83l771 },
176 { } 179 { }
177}; 180};
178MODULE_DEVICE_TABLE(i2c, lm90_id); 181MODULE_DEVICE_TABLE(i2c, lm90_id);
@@ -184,6 +187,7 @@ static struct i2c_driver lm90_driver = {
184 }, 187 },
185 .probe = lm90_probe, 188 .probe = lm90_probe,
186 .remove = lm90_remove, 189 .remove = lm90_remove,
190 .alert = lm90_alert,
187 .id_table = lm90_id, 191 .id_table = lm90_id,
188 .detect = lm90_detect, 192 .detect = lm90_detect,
189 .address_list = normal_i2c, 193 .address_list = normal_i2c,
@@ -201,6 +205,9 @@ struct lm90_data {
201 int kind; 205 int kind;
202 int flags; 206 int flags;
203 207
208 u8 config_orig; /* Original configuration register value */
209 u8 alert_alarms; /* Which alarm bits trigger ALERT# */
210
204 /* registers values */ 211 /* registers values */
205 s8 temp8[4]; /* 0: local low limit 212 s8 temp8[4]; /* 0: local low limit
206 1: local high limit 213 1: local high limit
@@ -758,6 +765,14 @@ static int lm90_detect(struct i2c_client *new_client,
758 && reg_convrate <= 0x07) { 765 && reg_convrate <= 0x07) {
759 name = "max6646"; 766 name = "max6646";
760 } 767 }
768 } else
769 if (address == 0x4C
770 && man_id == 0x5C) { /* Winbond/Nuvoton */
771 if ((chip_id & 0xFE) == 0x10 /* W83L771AWG/ASG */
772 && (reg_config1 & 0x2A) == 0x00
773 && reg_convrate <= 0x08) {
774 name = "w83l771";
775 }
761 } 776 }
762 777
763 if (!name) { /* identification failed */ 778 if (!name) { /* identification failed */
@@ -794,6 +809,19 @@ static int lm90_probe(struct i2c_client *new_client,
794 new_client->flags &= ~I2C_CLIENT_PEC; 809 new_client->flags &= ~I2C_CLIENT_PEC;
795 } 810 }
796 811
812 /* Different devices have different alarm bits triggering the
813 * ALERT# output */
814 switch (data->kind) {
815 case lm90:
816 case lm99:
817 case lm86:
818 data->alert_alarms = 0x7b;
819 break;
820 default:
821 data->alert_alarms = 0x7c;
822 break;
823 }
824
797 /* Initialize the LM90 chip */ 825 /* Initialize the LM90 chip */
798 lm90_init_client(new_client); 826 lm90_init_client(new_client);
799 827
@@ -830,7 +858,7 @@ exit:
830 858
831static void lm90_init_client(struct i2c_client *client) 859static void lm90_init_client(struct i2c_client *client)
832{ 860{
833 u8 config, config_orig; 861 u8 config;
834 struct lm90_data *data = i2c_get_clientdata(client); 862 struct lm90_data *data = i2c_get_clientdata(client);
835 863
836 /* 864 /*
@@ -842,7 +870,7 @@ static void lm90_init_client(struct i2c_client *client)
842 dev_warn(&client->dev, "Initialization failed!\n"); 870 dev_warn(&client->dev, "Initialization failed!\n");
843 return; 871 return;
844 } 872 }
845 config_orig = config; 873 data->config_orig = config;
846 874
847 /* Check Temperature Range Select */ 875 /* Check Temperature Range Select */
848 if (data->kind == adt7461) { 876 if (data->kind == adt7461) {
@@ -860,7 +888,7 @@ static void lm90_init_client(struct i2c_client *client)
860 } 888 }
861 889
862 config &= 0xBF; /* run */ 890 config &= 0xBF; /* run */
863 if (config != config_orig) /* Only write if changed */ 891 if (config != data->config_orig) /* Only write if changed */
864 i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1, config); 892 i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1, config);
865} 893}
866 894
@@ -875,10 +903,46 @@ static int lm90_remove(struct i2c_client *client)
875 device_remove_file(&client->dev, 903 device_remove_file(&client->dev,
876 &sensor_dev_attr_temp2_offset.dev_attr); 904 &sensor_dev_attr_temp2_offset.dev_attr);
877 905
906 /* Restore initial configuration */
907 i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1,
908 data->config_orig);
909
878 kfree(data); 910 kfree(data);
879 return 0; 911 return 0;
880} 912}
881 913
914static void lm90_alert(struct i2c_client *client, unsigned int flag)
915{
916 struct lm90_data *data = i2c_get_clientdata(client);
917 u8 config, alarms;
918
919 lm90_read_reg(client, LM90_REG_R_STATUS, &alarms);
920 if ((alarms & 0x7f) == 0) {
921 dev_info(&client->dev, "Everything OK\n");
922 } else {
923 if (alarms & 0x61)
924 dev_warn(&client->dev,
925 "temp%d out of range, please check!\n", 1);
926 if (alarms & 0x1a)
927 dev_warn(&client->dev,
928 "temp%d out of range, please check!\n", 2);
929 if (alarms & 0x04)
930 dev_warn(&client->dev,
931 "temp%d diode open, please check!\n", 2);
932
933 /* Disable ALERT# output, because these chips don't implement
934 SMBus alert correctly; they should only hold the alert line
935 low briefly. */
936 if ((data->kind == adm1032 || data->kind == adt7461)
937 && (alarms & data->alert_alarms)) {
938 dev_dbg(&client->dev, "Disabling ALERT#\n");
939 lm90_read_reg(client, LM90_REG_R_CONFIG1, &config);
940 i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1,
941 config | 0x80);
942 }
943 }
944}
945
882static int lm90_read16(struct i2c_client *client, u8 regh, u8 regl, u16 *value) 946static int lm90_read16(struct i2c_client *client, u8 regh, u8 regl, u16 *value)
883{ 947{
884 int err; 948 int err;
@@ -966,6 +1030,21 @@ static struct lm90_data *lm90_update_device(struct device *dev)
966 } 1030 }
967 lm90_read_reg(client, LM90_REG_R_STATUS, &data->alarms); 1031 lm90_read_reg(client, LM90_REG_R_STATUS, &data->alarms);
968 1032
1033 /* Re-enable ALERT# output if it was originally enabled and
1034 * relevant alarms are all clear */
1035 if ((data->config_orig & 0x80) == 0
1036 && (data->alarms & data->alert_alarms) == 0) {
1037 u8 config;
1038
1039 lm90_read_reg(client, LM90_REG_R_CONFIG1, &config);
1040 if (config & 0x80) {
1041 dev_dbg(&client->dev, "Re-enabling ALERT#\n");
1042 i2c_smbus_write_byte_data(client,
1043 LM90_REG_W_CONFIG1,
1044 config & ~0x80);
1045 }
1046 }
1047
969 data->last_updated = jiffies; 1048 data->last_updated = jiffies;
970 data->valid = 1; 1049 data->valid = 1;
971 } 1050 }