Skip to content

Commit 6948708

Browse files
Guenter RoeckJean Delvare
authored andcommitted
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>
1 parent 13c8495 commit 6948708

File tree

2 files changed

+64
-10
lines changed

2 files changed

+64
-10
lines changed

Documentation/hwmon/lm90

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -101,10 +101,11 @@ well as the temperature of up to one external diode. It is compatible
101101
with many other devices, many of which are supported by this driver.
102102

103103
Note that there is no easy way to differentiate between the MAX6657,
104-
MAX6658 and MAX6659 variants. The extra address and features of the
105-
MAX6659 are not supported by this driver. The MAX6680 and MAX6681 only
106-
differ in their pinout, therefore they obviously can't (and don't need to)
107-
be distinguished.
104+
MAX6658 and MAX6659 variants. The extra features of the MAX6659 are only
105+
supported by this driver if the chip is located at address 0x4d or 0x4e,
106+
or if the chip type is explicitly selected as max6659.
107+
The MAX6680 and MAX6681 only differ in their pinout, therefore they obviously
108+
can't (and don't need to) be distinguished.
108109

109110
The specificity of this family of chipsets over the ADM1021/LM84
110111
family is that it features critical limits with hysteresis, and an

drivers/hwmon/lm90.c

Lines changed: 59 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,11 @@
2828
* This driver also supports the MAX6657, MAX6658 and MAX6659 sensor
2929
* chips made by Maxim. These chips are similar to the LM86.
3030
* Note that there is no easy way to differentiate between the three
31-
* variants. The extra address and features of the MAX6659 are not
32-
* supported by this driver. These chips lack the remote temperature
33-
* offset feature.
31+
* variants. We use the device address to detect MAX6659, which will result
32+
* in a detection as max6657 if it is on address 0x4c. The extra address
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.
3436
*
3537
* This driver also supports the MAX6646, MAX6647, MAX6648, MAX6649 and
3638
* 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,
138140
/* MAX6646/6647/6649/6657/6658/6659 registers */
139141

140142
#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
141147

142148
/*
143149
* Device flags
@@ -147,6 +153,7 @@ enum chips { lm90, adm1032, lm99, lm86, max6657, max6659, adt7461, max6680,
147153
#define LM90_HAVE_OFFSET (1 << 1) /* temperature offset register */
148154
#define LM90_HAVE_LOCAL_EXT (1 << 2) /* extended local temperature */
149155
#define LM90_HAVE_REM_LIMIT_EXT (1 << 3) /* extended remote limit */
156+
#define LM90_HAVE_EMERGENCY (1 << 4) /* 3rd upper (emergency) limit */
150157

151158
/*
152159
* Functions declaration
@@ -213,10 +220,12 @@ struct lm90_data {
213220
u8 alert_alarms; /* Which alarm bits trigger ALERT# */
214221

215222
/* registers values */
216-
s8 temp8[4]; /* 0: local low limit
223+
s8 temp8[6]; /* 0: local low limit
217224
1: local high limit
218225
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) */
220229
s16 temp11[5]; /* 0: remote input
221230
1: remote low limit
222231
2: remote high limit
@@ -381,11 +390,13 @@ static ssize_t show_temp8(struct device *dev, struct device_attribute *devattr,
381390
static ssize_t set_temp8(struct device *dev, struct device_attribute *devattr,
382391
const char *buf, size_t count)
383392
{
384-
static const u8 reg[4] = {
393+
static const u8 reg[6] = {
385394
LM90_REG_W_LOCAL_LOW,
386395
LM90_REG_W_LOCAL_HIGH,
387396
LM90_REG_W_LOCAL_CRIT,
388397
LM90_REG_W_REMOTE_CRIT,
398+
MAX6659_REG_W_LOCAL_EMERG,
399+
MAX6659_REG_W_REMOTE_EMERG,
389400
};
390401

391402
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
@@ -608,6 +619,30 @@ static const struct attribute_group lm90_group = {
608619
.attrs = lm90_attributes,
609620
};
610621

622+
/*
623+
* Additional attributes for devices with emergency sensors
624+
*/
625+
static SENSOR_DEVICE_ATTR(temp1_emergency, S_IWUSR | S_IRUGO, show_temp8,
626+
set_temp8, 4);
627+
static SENSOR_DEVICE_ATTR(temp2_emergency, S_IWUSR | S_IRUGO, show_temp8,
628+
set_temp8, 5);
629+
static SENSOR_DEVICE_ATTR(temp1_emergency_hyst, S_IRUGO, show_temphyst,
630+
NULL, 4);
631+
static SENSOR_DEVICE_ATTR(temp2_emergency_hyst, S_IRUGO, show_temphyst,
632+
NULL, 5);
633+
634+
static 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+
642+
static const struct attribute_group lm90_emergency_group = {
643+
.attrs = lm90_emergency_attributes,
644+
};
645+
611646
/* pec used for ADM1032 only */
612647
static ssize_t show_pec(struct device *dev, struct device_attribute *dummy,
613648
char *buf)
@@ -826,6 +861,9 @@ static int lm90_detect(struct i2c_client *new_client,
826861

827862
static void lm90_remove_files(struct i2c_client *client, struct lm90_data *data)
828863
{
864+
if (data->flags & LM90_HAVE_EMERGENCY)
865+
sysfs_remove_group(&client->dev.kobj,
866+
&lm90_emergency_group);
829867
if (data->flags & LM90_HAVE_OFFSET)
830868
device_remove_file(&client->dev,
831869
&sensor_dev_attr_temp2_offset.dev_attr);
@@ -881,6 +919,9 @@ static int lm90_probe(struct i2c_client *new_client,
881919
&& data->kind != max6646 && data->kind != max6680)
882920
data->flags |= LM90_HAVE_REM_LIMIT_EXT;
883921

922+
if (data->kind == max6659)
923+
data->flags |= LM90_HAVE_EMERGENCY;
924+
884925
/* Initialize the LM90 chip */
885926
lm90_init_client(new_client);
886927

@@ -899,6 +940,12 @@ static int lm90_probe(struct i2c_client *new_client,
899940
if (err)
900941
goto exit_remove_files;
901942
}
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+
}
902949

903950
data->hwmon_dev = hwmon_device_register(&new_client->dev);
904951
if (IS_ERR(data->hwmon_dev)) {
@@ -1082,6 +1129,12 @@ static struct lm90_data *lm90_update_device(struct device *dev)
10821129
&l) == 0)
10831130
data->temp11[3] = (h << 8) | l;
10841131
}
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+
}
10851138
lm90_read_reg(client, LM90_REG_R_STATUS, &data->alarms);
10861139

10871140
/* Re-enable ALERT# output if it was originally enabled and

0 commit comments

Comments
 (0)