aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/lm90.c
diff options
context:
space:
mode:
authorGuenter Roeck <guenter.roeck@ericsson.com>2010-10-28 14:31:43 -0400
committerJean Delvare <khali@endymion.delvare>2010-10-28 14:31:43 -0400
commit6948708dd07573c578aa99f80915cd1867334abe (patch)
treeff218b1febbe70410d98589ae058cbad3784c0aa /drivers/hwmon/lm90.c
parent13c84951a3d75ba820adf47eb2a3b1c5ab1fa635 (diff)
hwmon: (lm90) Add support for extra features of max6659
Signed-off-by: Guenter Roeck <guenter.roeck@ericsson.com> Signed-off-by: Jean Delvare <khali@linux-fr.org>
Diffstat (limited to 'drivers/hwmon/lm90.c')
-rw-r--r--drivers/hwmon/lm90.c65
1 files changed, 59 insertions, 6 deletions
diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c
index 68ee8f78843e..de544817d673 100644
--- a/drivers/hwmon/lm90.c
+++ b/drivers/hwmon/lm90.c
@@ -28,9 +28,11 @@
28 * This driver also supports the MAX6657, MAX6658 and MAX6659 sensor 28 * This driver also supports the MAX6657, MAX6658 and MAX6659 sensor
29 * chips made by Maxim. These chips are similar to the LM86. 29 * chips made by Maxim. These chips are similar to the LM86.
30 * Note that there is no easy way to differentiate between the three 30 * Note that there is no easy way to differentiate between the three
31 * variants. The extra address and features of the MAX6659 are not 31 * variants. We use the device address to detect MAX6659, which will result
32 * supported by this driver. These chips lack the remote temperature 32 * in a detection as max6657 if it is on address 0x4c. The extra address
33 * offset feature. 33 * and features of the MAX6659 are only supported if the chip is configured
34 * explicitly as max6659, or if its address is not 0x4c.
35 * These chips lack the remote temperature offset feature.
34 * 36 *
35 * This driver also supports the MAX6646, MAX6647, MAX6648, MAX6649 and 37 * This driver also supports the MAX6646, MAX6647, MAX6648, MAX6649 and
36 * MAX6692 chips made by Maxim. These are again similar to the LM86, 38 * MAX6692 chips made by Maxim. These are again similar to the LM86,
@@ -138,6 +140,10 @@ enum chips { lm90, adm1032, lm99, lm86, max6657, max6659, adt7461, max6680,
138/* MAX6646/6647/6649/6657/6658/6659 registers */ 140/* MAX6646/6647/6649/6657/6658/6659 registers */
139 141
140#define MAX6657_REG_R_LOCAL_TEMPL 0x11 142#define MAX6657_REG_R_LOCAL_TEMPL 0x11
143#define MAX6659_REG_R_REMOTE_EMERG 0x16
144#define MAX6659_REG_W_REMOTE_EMERG 0x16
145#define MAX6659_REG_R_LOCAL_EMERG 0x17
146#define MAX6659_REG_W_LOCAL_EMERG 0x17
141 147
142/* 148/*
143 * Device flags 149 * Device flags
@@ -147,6 +153,7 @@ enum chips { lm90, adm1032, lm99, lm86, max6657, max6659, adt7461, max6680,
147#define LM90_HAVE_OFFSET (1 << 1) /* temperature offset register */ 153#define LM90_HAVE_OFFSET (1 << 1) /* temperature offset register */
148#define LM90_HAVE_LOCAL_EXT (1 << 2) /* extended local temperature */ 154#define LM90_HAVE_LOCAL_EXT (1 << 2) /* extended local temperature */
149#define LM90_HAVE_REM_LIMIT_EXT (1 << 3) /* extended remote limit */ 155#define LM90_HAVE_REM_LIMIT_EXT (1 << 3) /* extended remote limit */
156#define LM90_HAVE_EMERGENCY (1 << 4) /* 3rd upper (emergency) limit */
150 157
151/* 158/*
152 * Functions declaration 159 * Functions declaration
@@ -213,10 +220,12 @@ struct lm90_data {
213 u8 alert_alarms; /* Which alarm bits trigger ALERT# */ 220 u8 alert_alarms; /* Which alarm bits trigger ALERT# */
214 221
215 /* registers values */ 222 /* registers values */
216 s8 temp8[4]; /* 0: local low limit 223 s8 temp8[6]; /* 0: local low limit
217 1: local high limit 224 1: local high limit
218 2: local critical limit 225 2: local critical limit
219 3: remote critical limit */ 226 3: remote critical limit
227 4: local emergency limit (max6659 only)
228 5: remote emergency limit (max6659 only) */
220 s16 temp11[5]; /* 0: remote input 229 s16 temp11[5]; /* 0: remote input
221 1: remote low limit 230 1: remote low limit
222 2: remote high limit 231 2: remote high limit
@@ -381,11 +390,13 @@ static ssize_t show_temp8(struct device *dev, struct device_attribute *devattr,
381static ssize_t set_temp8(struct device *dev, struct device_attribute *devattr, 390static ssize_t set_temp8(struct device *dev, struct device_attribute *devattr,
382 const char *buf, size_t count) 391 const char *buf, size_t count)
383{ 392{
384 static const u8 reg[4] = { 393 static const u8 reg[6] = {
385 LM90_REG_W_LOCAL_LOW, 394 LM90_REG_W_LOCAL_LOW,
386 LM90_REG_W_LOCAL_HIGH, 395 LM90_REG_W_LOCAL_HIGH,
387 LM90_REG_W_LOCAL_CRIT, 396 LM90_REG_W_LOCAL_CRIT,
388 LM90_REG_W_REMOTE_CRIT, 397 LM90_REG_W_REMOTE_CRIT,
398 MAX6659_REG_W_LOCAL_EMERG,
399 MAX6659_REG_W_REMOTE_EMERG,
389 }; 400 };
390 401
391 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 402 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
@@ -608,6 +619,30 @@ static const struct attribute_group lm90_group = {
608 .attrs = lm90_attributes, 619 .attrs = lm90_attributes,
609}; 620};
610 621
622/*
623 * Additional attributes for devices with emergency sensors
624 */
625static SENSOR_DEVICE_ATTR(temp1_emergency, S_IWUSR | S_IRUGO, show_temp8,
626 set_temp8, 4);
627static SENSOR_DEVICE_ATTR(temp2_emergency, S_IWUSR | S_IRUGO, show_temp8,
628 set_temp8, 5);
629static SENSOR_DEVICE_ATTR(temp1_emergency_hyst, S_IRUGO, show_temphyst,
630 NULL, 4);
631static SENSOR_DEVICE_ATTR(temp2_emergency_hyst, S_IRUGO, show_temphyst,
632 NULL, 5);
633
634static struct attribute *lm90_emergency_attributes[] = {
635 &sensor_dev_attr_temp1_emergency.dev_attr.attr,
636 &sensor_dev_attr_temp2_emergency.dev_attr.attr,
637 &sensor_dev_attr_temp1_emergency_hyst.dev_attr.attr,
638 &sensor_dev_attr_temp2_emergency_hyst.dev_attr.attr,
639 NULL
640};
641
642static const struct attribute_group lm90_emergency_group = {
643 .attrs = lm90_emergency_attributes,
644};
645
611/* pec used for ADM1032 only */ 646/* pec used for ADM1032 only */
612static ssize_t show_pec(struct device *dev, struct device_attribute *dummy, 647static ssize_t show_pec(struct device *dev, struct device_attribute *dummy,
613 char *buf) 648 char *buf)
@@ -826,6 +861,9 @@ static int lm90_detect(struct i2c_client *new_client,
826 861
827static void lm90_remove_files(struct i2c_client *client, struct lm90_data *data) 862static void lm90_remove_files(struct i2c_client *client, struct lm90_data *data)
828{ 863{
864 if (data->flags & LM90_HAVE_EMERGENCY)
865 sysfs_remove_group(&client->dev.kobj,
866 &lm90_emergency_group);
829 if (data->flags & LM90_HAVE_OFFSET) 867 if (data->flags & LM90_HAVE_OFFSET)
830 device_remove_file(&client->dev, 868 device_remove_file(&client->dev,
831 &sensor_dev_attr_temp2_offset.dev_attr); 869 &sensor_dev_attr_temp2_offset.dev_attr);
@@ -881,6 +919,9 @@ static int lm90_probe(struct i2c_client *new_client,
881 && data->kind != max6646 && data->kind != max6680) 919 && data->kind != max6646 && data->kind != max6680)
882 data->flags |= LM90_HAVE_REM_LIMIT_EXT; 920 data->flags |= LM90_HAVE_REM_LIMIT_EXT;
883 921
922 if (data->kind == max6659)
923 data->flags |= LM90_HAVE_EMERGENCY;
924
884 /* Initialize the LM90 chip */ 925 /* Initialize the LM90 chip */
885 lm90_init_client(new_client); 926 lm90_init_client(new_client);
886 927
@@ -899,6 +940,12 @@ static int lm90_probe(struct i2c_client *new_client,
899 if (err) 940 if (err)
900 goto exit_remove_files; 941 goto exit_remove_files;
901 } 942 }
943 if (data->flags & LM90_HAVE_EMERGENCY) {
944 err = sysfs_create_group(&new_client->dev.kobj,
945 &lm90_emergency_group);
946 if (err)
947 goto exit_remove_files;
948 }
902 949
903 data->hwmon_dev = hwmon_device_register(&new_client->dev); 950 data->hwmon_dev = hwmon_device_register(&new_client->dev);
904 if (IS_ERR(data->hwmon_dev)) { 951 if (IS_ERR(data->hwmon_dev)) {
@@ -1082,6 +1129,12 @@ static struct lm90_data *lm90_update_device(struct device *dev)
1082 &l) == 0) 1129 &l) == 0)
1083 data->temp11[3] = (h << 8) | l; 1130 data->temp11[3] = (h << 8) | l;
1084 } 1131 }
1132 if (data->flags & LM90_HAVE_EMERGENCY) {
1133 lm90_read_reg(client, MAX6659_REG_R_LOCAL_EMERG,
1134 &data->temp8[4]);
1135 lm90_read_reg(client, MAX6659_REG_R_REMOTE_EMERG,
1136 &data->temp8[5]);
1137 }
1085 lm90_read_reg(client, LM90_REG_R_STATUS, &data->alarms); 1138 lm90_read_reg(client, LM90_REG_R_STATUS, &data->alarms);
1086 1139
1087 /* Re-enable ALERT# output if it was originally enabled and 1140 /* Re-enable ALERT# output if it was originally enabled and