aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/i2c/max6697.txt64
-rw-r--r--Documentation/hwmon/max669758
-rw-r--r--drivers/hwmon/Kconfig11
-rw-r--r--drivers/hwmon/Makefile1
-rw-r--r--drivers/hwmon/max6697.c726
-rw-r--r--include/linux/platform_data/max6697.h36
6 files changed, 896 insertions, 0 deletions
diff --git a/Documentation/devicetree/bindings/i2c/max6697.txt b/Documentation/devicetree/bindings/i2c/max6697.txt
new file mode 100644
index 000000000000..5f793998e4a4
--- /dev/null
+++ b/Documentation/devicetree/bindings/i2c/max6697.txt
@@ -0,0 +1,64 @@
1max6697 properties
2
3Required properties:
4- compatible:
5 Should be one of
6 maxim,max6581
7 maxim,max6602
8 maxim,max6622
9 maxim,max6636
10 maxim,max6689
11 maxim,max6693
12 maxim,max6694
13 maxim,max6697
14 maxim,max6698
15 maxim,max6699
16- reg: I2C address
17
18Optional properties:
19
20- smbus-timeout-disable
21 Set to disable SMBus timeout. If not specified, SMBus timeout will be
22 enabled.
23- extended-range-enable
24 Only valid for MAX6581. Set to enable extended temperature range.
25 Extended temperature will be disabled if not specified.
26- beta-compensation-enable
27 Only valid for MAX6693 and MX6694. Set to enable beta compensation on
28 remote temperature channel 1.
29 Beta compensation will be disabled if not specified.
30- alert-mask
31 Alert bit mask. Alert disabled for bits set.
32 Select bit 0 for local temperature, bit 1..7 for remote temperatures.
33 If not specified, alert will be enabled for all channels.
34- over-temperature-mask
35 Over-temperature bit mask. Over-temperature reporting disabled for
36 bits set.
37 Select bit 0 for local temperature, bit 1..7 for remote temperatures.
38 If not specified, over-temperature reporting will be enabled for all
39 channels.
40- resistance-cancellation
41 Boolean for all chips other than MAX6581. Set to enable resistance
42 cancellation on remote temperature channel 1.
43 For MAX6581, resistance cancellation enabled for all channels if
44 specified as boolean, otherwise as per bit mask specified.
45 Only supported for remote temperatures (bit 1..7).
46 If not specified, resistance cancellation will be disabled for all
47 channels.
48- transistor-ideality
49 For MAX6581 only. Two values; first is bit mask, second is ideality
50 select value as per MAX6581 data sheet. Select bit 1..7 for remote
51 channels.
52 Transistor ideality will be initialized to default (1.008) if not
53 specified.
54
55Example:
56
57temp-sensor@1a {
58 compatible = "maxim,max6697";
59 reg = <0x1a>;
60 smbus-timeout-disable;
61 resistance-cancellation;
62 alert-mask = <0x72>;
63 over-temperature-mask = <0x7f>;
64};
diff --git a/Documentation/hwmon/max6697 b/Documentation/hwmon/max6697
new file mode 100644
index 000000000000..6594177ededa
--- /dev/null
+++ b/Documentation/hwmon/max6697
@@ -0,0 +1,58 @@
1Kernel driver max6697
2=====================
3
4Supported chips:
5 * Maxim MAX6581
6 Prefix: 'max6581'
7 Datasheet: http://datasheets.maximintegrated.com/en/ds/MAX6581.pdf
8 * Maxim MAX6602
9 Prefix: 'max6602'
10 Datasheet: http://datasheets.maximintegrated.com/en/ds/MAX6602.pdf
11 * Maxim MAX6622
12 Prefix: 'max6622'
13 Datasheet: http://datasheets.maximintegrated.com/en/ds/MAX6622.pdf
14 * Maxim MAX6636
15 Prefix: 'max6636'
16 Datasheet: http://datasheets.maximintegrated.com/en/ds/MAX6636.pdf
17 * Maxim MAX6689
18 Prefix: 'max6689'
19 Datasheet: http://datasheets.maximintegrated.com/en/ds/MAX6689.pdf
20 * Maxim MAX6693
21 Prefix: 'max6693'
22 Datasheet: http://datasheets.maximintegrated.com/en/ds/MAX6693.pdf
23 * Maxim MAX6694
24 Prefix: 'max6694'
25 Datasheet: http://datasheets.maximintegrated.com/en/ds/MAX6694.pdf
26 * Maxim MAX6697
27 Prefix: 'max6697'
28 Datasheet: http://datasheets.maximintegrated.com/en/ds/MAX6697.pdf
29 * Maxim MAX6698
30 Prefix: 'max6698'
31 Datasheet: http://datasheets.maximintegrated.com/en/ds/MAX6698.pdf
32 * Maxim MAX6699
33 Prefix: 'max6699'
34 Datasheet: http://datasheets.maximintegrated.com/en/ds/MAX6699.pdf
35
36Author:
37 Guenter Roeck <linux@roeck-us.net>
38
39Description
40-----------
41
42This driver implements support for several MAX6697 compatible temperature sensor
43chips. The chips support one local temperature sensor plus four, six, or seven
44remote temperature sensors. Remote temperature sensors are diode-connected
45thermal transitors, except for MAX6698 which supports three diode-connected
46thermal transistors plus three thermistors in addition to the local temperature
47sensor.
48
49The driver provides the following sysfs attributes. temp1 is the local (chip)
50temperature, temp[2..n] are remote temperatures. The actually supported
51per-channel attributes are chip type and channel dependent.
52
53tempX_input RO temperature
54tempX_max RW temperature maximum threshold
55tempX_max_alarm RO temperature maximum threshold alarm
56tempX_crit RW temperature critical threshold
57tempX_crit_alarm RO temperature critical threshold alarm
58tempX_fault RO temperature diode fault (remote sensors only)
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 32f238f3caea..ef5757265f78 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -854,6 +854,17 @@ config SENSORS_MAX6650
854 This driver can also be built as a module. If so, the module 854 This driver can also be built as a module. If so, the module
855 will be called max6650. 855 will be called max6650.
856 856
857config SENSORS_MAX6697
858 tristate "Maxim MAX6697 and compatibles"
859 depends on I2C
860 help
861 If you say yes here you get support for MAX6581, MAX6602, MAX6622,
862 MAX6636, MAX6689, MAX6693, MAX6694, MAX6697, MAX6698, and MAX6699
863 temperature sensor chips.
864
865 This driver can also be built as a module. If so, the module
866 will be called max6697.
867
857config SENSORS_MCP3021 868config SENSORS_MCP3021
858 tristate "Microchip MCP3021 and compatibles" 869 tristate "Microchip MCP3021 and compatibles"
859 depends on I2C 870 depends on I2C
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 5da287443f6c..a37a82c64da2 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -99,6 +99,7 @@ obj-$(CONFIG_SENSORS_MAX197) += max197.o
99obj-$(CONFIG_SENSORS_MAX6639) += max6639.o 99obj-$(CONFIG_SENSORS_MAX6639) += max6639.o
100obj-$(CONFIG_SENSORS_MAX6642) += max6642.o 100obj-$(CONFIG_SENSORS_MAX6642) += max6642.o
101obj-$(CONFIG_SENSORS_MAX6650) += max6650.o 101obj-$(CONFIG_SENSORS_MAX6650) += max6650.o
102obj-$(CONFIG_SENSORS_MAX6697) += max6697.o
102obj-$(CONFIG_SENSORS_MC13783_ADC)+= mc13783-adc.o 103obj-$(CONFIG_SENSORS_MC13783_ADC)+= mc13783-adc.o
103obj-$(CONFIG_SENSORS_MCP3021) += mcp3021.o 104obj-$(CONFIG_SENSORS_MCP3021) += mcp3021.o
104obj-$(CONFIG_SENSORS_NTC_THERMISTOR) += ntc_thermistor.o 105obj-$(CONFIG_SENSORS_NTC_THERMISTOR) += ntc_thermistor.o
diff --git a/drivers/hwmon/max6697.c b/drivers/hwmon/max6697.c
new file mode 100644
index 000000000000..bf4aa3777fc1
--- /dev/null
+++ b/drivers/hwmon/max6697.c
@@ -0,0 +1,726 @@
1/*
2 * Copyright (c) 2012 Guenter Roeck <linux@roeck-us.net>
3 *
4 * based on max1668.c
5 * Copyright (c) 2011 David George <david.george@ska.ac.za>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17
18#include <linux/module.h>
19#include <linux/init.h>
20#include <linux/slab.h>
21#include <linux/jiffies.h>
22#include <linux/i2c.h>
23#include <linux/hwmon.h>
24#include <linux/hwmon-sysfs.h>
25#include <linux/err.h>
26#include <linux/mutex.h>
27#include <linux/of.h>
28
29#include <linux/platform_data/max6697.h>
30
31enum chips { max6581, max6602, max6622, max6636, max6689, max6693, max6694,
32 max6697, max6698, max6699 };
33
34/* Report local sensor as temp1 */
35
36static const u8 MAX6697_REG_TEMP[] = {
37 0x07, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x08 };
38static const u8 MAX6697_REG_TEMP_EXT[] = {
39 0x57, 0x09, 0x52, 0x53, 0x54, 0x55, 0x56, 0 };
40static const u8 MAX6697_REG_MAX[] = {
41 0x17, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x18 };
42static const u8 MAX6697_REG_CRIT[] = {
43 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27 };
44
45/*
46 * Map device tree / platform data register bit map to chip bit map.
47 * Applies to alert register and over-temperature register.
48 */
49#define MAX6697_MAP_BITS(reg) ((((reg) & 0x7e) >> 1) | \
50 (((reg) & 0x01) << 6) | ((reg) & 0x80))
51
52#define MAX6697_REG_STAT(n) (0x44 + (n))
53
54#define MAX6697_REG_CONFIG 0x41
55#define MAX6581_CONF_EXTENDED (1 << 1)
56#define MAX6693_CONF_BETA (1 << 2)
57#define MAX6697_CONF_RESISTANCE (1 << 3)
58#define MAX6697_CONF_TIMEOUT (1 << 5)
59#define MAX6697_REG_ALERT_MASK 0x42
60#define MAX6697_REG_OVERT_MASK 0x43
61
62#define MAX6581_REG_RESISTANCE 0x4a
63#define MAX6581_REG_IDEALITY 0x4b
64#define MAX6581_REG_IDEALITY_SELECT 0x4c
65#define MAX6581_REG_OFFSET 0x4d
66#define MAX6581_REG_OFFSET_SELECT 0x4e
67
68#define MAX6697_CONV_TIME 156 /* ms per channel, worst case */
69
70struct max6697_chip_data {
71 int channels;
72 u32 have_ext;
73 u32 have_crit;
74 u32 have_fault;
75 u8 valid_conf;
76 const u8 *alarm_map;
77};
78
79struct max6697_data {
80 struct device *hwmon_dev;
81
82 enum chips type;
83 const struct max6697_chip_data *chip;
84
85 int update_interval; /* in milli-seconds */
86 int temp_offset; /* in degrees C */
87
88 struct mutex update_lock;
89 unsigned long last_updated; /* In jiffies */
90 bool valid; /* true if following fields are valid */
91
92 /* 1x local and up to 7x remote */
93 u8 temp[8][4]; /* [nr][0]=temp [1]=ext [2]=max [3]=crit */
94#define MAX6697_TEMP_INPUT 0
95#define MAX6697_TEMP_EXT 1
96#define MAX6697_TEMP_MAX 2
97#define MAX6697_TEMP_CRIT 3
98 u32 alarms;
99};
100
101/* Diode fault status bits on MAX6581 are right shifted by one bit */
102static const u8 max6581_alarm_map[] = {
103 0, 0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15,
104 16, 17, 18, 19, 20, 21, 22, 23 };
105
106static const struct max6697_chip_data max6697_chip_data[] = {
107 [max6581] = {
108 .channels = 8,
109 .have_crit = 0xff,
110 .have_ext = 0x7f,
111 .have_fault = 0xfe,
112 .valid_conf = MAX6581_CONF_EXTENDED | MAX6697_CONF_TIMEOUT,
113 .alarm_map = max6581_alarm_map,
114 },
115 [max6602] = {
116 .channels = 5,
117 .have_crit = 0x12,
118 .have_ext = 0x02,
119 .have_fault = 0x1e,
120 .valid_conf = MAX6697_CONF_RESISTANCE | MAX6697_CONF_TIMEOUT,
121 },
122 [max6622] = {
123 .channels = 5,
124 .have_crit = 0x12,
125 .have_ext = 0x02,
126 .have_fault = 0x1e,
127 .valid_conf = MAX6697_CONF_RESISTANCE | MAX6697_CONF_TIMEOUT,
128 },
129 [max6636] = {
130 .channels = 7,
131 .have_crit = 0x72,
132 .have_ext = 0x02,
133 .have_fault = 0x7e,
134 .valid_conf = MAX6697_CONF_RESISTANCE | MAX6697_CONF_TIMEOUT,
135 },
136 [max6689] = {
137 .channels = 7,
138 .have_crit = 0x72,
139 .have_ext = 0x02,
140 .have_fault = 0x7e,
141 .valid_conf = MAX6697_CONF_RESISTANCE | MAX6697_CONF_TIMEOUT,
142 },
143 [max6693] = {
144 .channels = 7,
145 .have_crit = 0x72,
146 .have_ext = 0x02,
147 .have_fault = 0x7e,
148 .valid_conf = MAX6697_CONF_RESISTANCE | MAX6693_CONF_BETA |
149 MAX6697_CONF_TIMEOUT,
150 },
151 [max6694] = {
152 .channels = 5,
153 .have_crit = 0x12,
154 .have_ext = 0x02,
155 .have_fault = 0x1e,
156 .valid_conf = MAX6697_CONF_RESISTANCE | MAX6693_CONF_BETA |
157 MAX6697_CONF_TIMEOUT,
158 },
159 [max6697] = {
160 .channels = 7,
161 .have_crit = 0x72,
162 .have_ext = 0x02,
163 .have_fault = 0x7e,
164 .valid_conf = MAX6697_CONF_RESISTANCE | MAX6697_CONF_TIMEOUT,
165 },
166 [max6698] = {
167 .channels = 7,
168 .have_crit = 0x72,
169 .have_ext = 0x02,
170 .have_fault = 0x0e,
171 .valid_conf = MAX6697_CONF_RESISTANCE | MAX6697_CONF_TIMEOUT,
172 },
173 [max6699] = {
174 .channels = 5,
175 .have_crit = 0x12,
176 .have_ext = 0x02,
177 .have_fault = 0x1e,
178 .valid_conf = MAX6697_CONF_RESISTANCE | MAX6697_CONF_TIMEOUT,
179 },
180};
181
182static struct max6697_data *max6697_update_device(struct device *dev)
183{
184 struct i2c_client *client = to_i2c_client(dev);
185 struct max6697_data *data = i2c_get_clientdata(client);
186 struct max6697_data *ret = data;
187 int val;
188 int i;
189 u32 alarms;
190
191 mutex_lock(&data->update_lock);
192
193 if (data->valid &&
194 !time_after(jiffies, data->last_updated
195 + msecs_to_jiffies(data->update_interval)))
196 goto abort;
197
198 for (i = 0; i < data->chip->channels; i++) {
199 if (data->chip->have_ext & (1 << i)) {
200 val = i2c_smbus_read_byte_data(client,
201 MAX6697_REG_TEMP_EXT[i]);
202 if (unlikely(val < 0)) {
203 ret = ERR_PTR(val);
204 goto abort;
205 }
206 data->temp[i][MAX6697_TEMP_EXT] = val;
207 }
208
209 val = i2c_smbus_read_byte_data(client, MAX6697_REG_TEMP[i]);
210 if (unlikely(val < 0)) {
211 ret = ERR_PTR(val);
212 goto abort;
213 }
214 data->temp[i][MAX6697_TEMP_INPUT] = val;
215
216 val = i2c_smbus_read_byte_data(client, MAX6697_REG_MAX[i]);
217 if (unlikely(val < 0)) {
218 ret = ERR_PTR(val);
219 goto abort;
220 }
221 data->temp[i][MAX6697_TEMP_MAX] = val;
222
223 if (data->chip->have_crit & (1 << i)) {
224 val = i2c_smbus_read_byte_data(client,
225 MAX6697_REG_CRIT[i]);
226 if (unlikely(val < 0)) {
227 ret = ERR_PTR(val);
228 goto abort;
229 }
230 data->temp[i][MAX6697_TEMP_CRIT] = val;
231 }
232 }
233
234 alarms = 0;
235 for (i = 0; i < 3; i++) {
236 val = i2c_smbus_read_byte_data(client, MAX6697_REG_STAT(i));
237 if (unlikely(val < 0)) {
238 ret = ERR_PTR(val);
239 goto abort;
240 }
241 alarms = (alarms << 8) | val;
242 }
243 data->alarms = alarms;
244 data->last_updated = jiffies;
245 data->valid = true;
246abort:
247 mutex_unlock(&data->update_lock);
248
249 return ret;
250}
251
252static ssize_t show_temp_input(struct device *dev,
253 struct device_attribute *devattr, char *buf)
254{
255 int index = to_sensor_dev_attr(devattr)->index;
256 struct max6697_data *data = max6697_update_device(dev);
257 int temp;
258
259 if (IS_ERR(data))
260 return PTR_ERR(data);
261
262 temp = (data->temp[index][MAX6697_TEMP_INPUT] - data->temp_offset) << 3;
263 temp |= data->temp[index][MAX6697_TEMP_EXT] >> 5;
264
265 return sprintf(buf, "%d\n", temp * 125);
266}
267
268static ssize_t show_temp(struct device *dev,
269 struct device_attribute *devattr, char *buf)
270{
271 int nr = to_sensor_dev_attr_2(devattr)->nr;
272 int index = to_sensor_dev_attr_2(devattr)->index;
273 struct max6697_data *data = max6697_update_device(dev);
274 int temp;
275
276 if (IS_ERR(data))
277 return PTR_ERR(data);
278
279 temp = data->temp[nr][index];
280 temp -= data->temp_offset;
281
282 return sprintf(buf, "%d\n", temp * 1000);
283}
284
285static ssize_t show_alarm(struct device *dev, struct device_attribute *attr,
286 char *buf)
287{
288 int index = to_sensor_dev_attr(attr)->index;
289 struct max6697_data *data = max6697_update_device(dev);
290
291 if (IS_ERR(data))
292 return PTR_ERR(data);
293
294 if (data->chip->alarm_map)
295 index = data->chip->alarm_map[index];
296
297 return sprintf(buf, "%u\n", (data->alarms >> index) & 0x1);
298}
299
300static ssize_t set_temp(struct device *dev,
301 struct device_attribute *devattr,
302 const char *buf, size_t count)
303{
304 int nr = to_sensor_dev_attr_2(devattr)->nr;
305 int index = to_sensor_dev_attr_2(devattr)->index;
306 struct i2c_client *client = to_i2c_client(dev);
307 struct max6697_data *data = i2c_get_clientdata(client);
308 long temp;
309 int ret;
310
311 ret = kstrtol(buf, 10, &temp);
312 if (ret < 0)
313 return ret;
314
315 mutex_lock(&data->update_lock);
316 temp = DIV_ROUND_CLOSEST(temp, 1000) + data->temp_offset;
317 temp = clamp_val(temp, 0, data->type == max6581 ? 255 : 127);
318 data->temp[nr][index] = temp;
319 ret = i2c_smbus_write_byte_data(client,
320 index == 2 ? MAX6697_REG_MAX[nr]
321 : MAX6697_REG_CRIT[nr],
322 temp);
323 mutex_unlock(&data->update_lock);
324
325 return ret < 0 ? ret : count;
326}
327
328static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_input, NULL, 0);
329static SENSOR_DEVICE_ATTR_2(temp1_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
330 0, MAX6697_TEMP_MAX);
331static SENSOR_DEVICE_ATTR_2(temp1_crit, S_IRUGO | S_IWUSR, show_temp, set_temp,
332 0, MAX6697_TEMP_CRIT);
333
334static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp_input, NULL, 1);
335static SENSOR_DEVICE_ATTR_2(temp2_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
336 1, MAX6697_TEMP_MAX);
337static SENSOR_DEVICE_ATTR_2(temp2_crit, S_IRUGO | S_IWUSR, show_temp, set_temp,
338 1, MAX6697_TEMP_CRIT);
339
340static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp_input, NULL, 2);
341static SENSOR_DEVICE_ATTR_2(temp3_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
342 2, MAX6697_TEMP_MAX);
343static SENSOR_DEVICE_ATTR_2(temp3_crit, S_IRUGO | S_IWUSR, show_temp, set_temp,
344 2, MAX6697_TEMP_CRIT);
345
346static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_temp_input, NULL, 3);
347static SENSOR_DEVICE_ATTR_2(temp4_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
348 3, MAX6697_TEMP_MAX);
349static SENSOR_DEVICE_ATTR_2(temp4_crit, S_IRUGO | S_IWUSR, show_temp, set_temp,
350 3, MAX6697_TEMP_CRIT);
351
352static SENSOR_DEVICE_ATTR(temp5_input, S_IRUGO, show_temp_input, NULL, 4);
353static SENSOR_DEVICE_ATTR_2(temp5_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
354 4, MAX6697_TEMP_MAX);
355static SENSOR_DEVICE_ATTR_2(temp5_crit, S_IRUGO | S_IWUSR, show_temp, set_temp,
356 4, MAX6697_TEMP_CRIT);
357
358static SENSOR_DEVICE_ATTR(temp6_input, S_IRUGO, show_temp_input, NULL, 5);
359static SENSOR_DEVICE_ATTR_2(temp6_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
360 5, MAX6697_TEMP_MAX);
361static SENSOR_DEVICE_ATTR_2(temp6_crit, S_IRUGO | S_IWUSR, show_temp, set_temp,
362 5, MAX6697_TEMP_CRIT);
363
364static SENSOR_DEVICE_ATTR(temp7_input, S_IRUGO, show_temp_input, NULL, 6);
365static SENSOR_DEVICE_ATTR_2(temp7_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
366 6, MAX6697_TEMP_MAX);
367static SENSOR_DEVICE_ATTR_2(temp7_crit, S_IRUGO | S_IWUSR, show_temp, set_temp,
368 6, MAX6697_TEMP_CRIT);
369
370static SENSOR_DEVICE_ATTR(temp8_input, S_IRUGO, show_temp_input, NULL, 7);
371static SENSOR_DEVICE_ATTR_2(temp8_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
372 7, MAX6697_TEMP_MAX);
373static SENSOR_DEVICE_ATTR_2(temp8_crit, S_IRUGO | S_IWUSR, show_temp, set_temp,
374 7, MAX6697_TEMP_CRIT);
375
376static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 22);
377static SENSOR_DEVICE_ATTR(temp2_max_alarm, S_IRUGO, show_alarm, NULL, 16);
378static SENSOR_DEVICE_ATTR(temp3_max_alarm, S_IRUGO, show_alarm, NULL, 17);
379static SENSOR_DEVICE_ATTR(temp4_max_alarm, S_IRUGO, show_alarm, NULL, 18);
380static SENSOR_DEVICE_ATTR(temp5_max_alarm, S_IRUGO, show_alarm, NULL, 19);
381static SENSOR_DEVICE_ATTR(temp6_max_alarm, S_IRUGO, show_alarm, NULL, 20);
382static SENSOR_DEVICE_ATTR(temp7_max_alarm, S_IRUGO, show_alarm, NULL, 21);
383static SENSOR_DEVICE_ATTR(temp8_max_alarm, S_IRUGO, show_alarm, NULL, 23);
384
385static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, 14);
386static SENSOR_DEVICE_ATTR(temp2_crit_alarm, S_IRUGO, show_alarm, NULL, 8);
387static SENSOR_DEVICE_ATTR(temp3_crit_alarm, S_IRUGO, show_alarm, NULL, 9);
388static SENSOR_DEVICE_ATTR(temp4_crit_alarm, S_IRUGO, show_alarm, NULL, 10);
389static SENSOR_DEVICE_ATTR(temp5_crit_alarm, S_IRUGO, show_alarm, NULL, 11);
390static SENSOR_DEVICE_ATTR(temp6_crit_alarm, S_IRUGO, show_alarm, NULL, 12);
391static SENSOR_DEVICE_ATTR(temp7_crit_alarm, S_IRUGO, show_alarm, NULL, 13);
392static SENSOR_DEVICE_ATTR(temp8_crit_alarm, S_IRUGO, show_alarm, NULL, 15);
393
394static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_alarm, NULL, 1);
395static SENSOR_DEVICE_ATTR(temp3_fault, S_IRUGO, show_alarm, NULL, 2);
396static SENSOR_DEVICE_ATTR(temp4_fault, S_IRUGO, show_alarm, NULL, 3);
397static SENSOR_DEVICE_ATTR(temp5_fault, S_IRUGO, show_alarm, NULL, 4);
398static SENSOR_DEVICE_ATTR(temp6_fault, S_IRUGO, show_alarm, NULL, 5);
399static SENSOR_DEVICE_ATTR(temp7_fault, S_IRUGO, show_alarm, NULL, 6);
400static SENSOR_DEVICE_ATTR(temp8_fault, S_IRUGO, show_alarm, NULL, 7);
401
402static struct attribute *max6697_attributes[8][7] = {
403 {
404 &sensor_dev_attr_temp1_input.dev_attr.attr,
405 &sensor_dev_attr_temp1_max.dev_attr.attr,
406 &sensor_dev_attr_temp1_max_alarm.dev_attr.attr,
407 &sensor_dev_attr_temp1_crit.dev_attr.attr,
408 &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr,
409 NULL
410 }, {
411 &sensor_dev_attr_temp2_input.dev_attr.attr,
412 &sensor_dev_attr_temp2_max.dev_attr.attr,
413 &sensor_dev_attr_temp2_max_alarm.dev_attr.attr,
414 &sensor_dev_attr_temp2_crit.dev_attr.attr,
415 &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr,
416 &sensor_dev_attr_temp2_fault.dev_attr.attr,
417 NULL
418 }, {
419 &sensor_dev_attr_temp3_input.dev_attr.attr,
420 &sensor_dev_attr_temp3_max.dev_attr.attr,
421 &sensor_dev_attr_temp3_max_alarm.dev_attr.attr,
422 &sensor_dev_attr_temp3_crit.dev_attr.attr,
423 &sensor_dev_attr_temp3_crit_alarm.dev_attr.attr,
424 &sensor_dev_attr_temp3_fault.dev_attr.attr,
425 NULL
426 }, {
427 &sensor_dev_attr_temp4_input.dev_attr.attr,
428 &sensor_dev_attr_temp4_max.dev_attr.attr,
429 &sensor_dev_attr_temp4_max_alarm.dev_attr.attr,
430 &sensor_dev_attr_temp4_crit.dev_attr.attr,
431 &sensor_dev_attr_temp4_crit_alarm.dev_attr.attr,
432 &sensor_dev_attr_temp4_fault.dev_attr.attr,
433 NULL
434 }, {
435 &sensor_dev_attr_temp5_input.dev_attr.attr,
436 &sensor_dev_attr_temp5_max.dev_attr.attr,
437 &sensor_dev_attr_temp5_max_alarm.dev_attr.attr,
438 &sensor_dev_attr_temp5_crit.dev_attr.attr,
439 &sensor_dev_attr_temp5_crit_alarm.dev_attr.attr,
440 &sensor_dev_attr_temp5_fault.dev_attr.attr,
441 NULL
442 }, {
443 &sensor_dev_attr_temp6_input.dev_attr.attr,
444 &sensor_dev_attr_temp6_max.dev_attr.attr,
445 &sensor_dev_attr_temp6_max_alarm.dev_attr.attr,
446 &sensor_dev_attr_temp6_crit.dev_attr.attr,
447 &sensor_dev_attr_temp6_crit_alarm.dev_attr.attr,
448 &sensor_dev_attr_temp6_fault.dev_attr.attr,
449 NULL
450 }, {
451 &sensor_dev_attr_temp7_input.dev_attr.attr,
452 &sensor_dev_attr_temp7_max.dev_attr.attr,
453 &sensor_dev_attr_temp7_max_alarm.dev_attr.attr,
454 &sensor_dev_attr_temp7_crit.dev_attr.attr,
455 &sensor_dev_attr_temp7_crit_alarm.dev_attr.attr,
456 &sensor_dev_attr_temp7_fault.dev_attr.attr,
457 NULL
458 }, {
459 &sensor_dev_attr_temp8_input.dev_attr.attr,
460 &sensor_dev_attr_temp8_max.dev_attr.attr,
461 &sensor_dev_attr_temp8_max_alarm.dev_attr.attr,
462 &sensor_dev_attr_temp8_crit.dev_attr.attr,
463 &sensor_dev_attr_temp8_crit_alarm.dev_attr.attr,
464 &sensor_dev_attr_temp8_fault.dev_attr.attr,
465 NULL
466 }
467};
468
469static const struct attribute_group max6697_group[8] = {
470 { .attrs = max6697_attributes[0] },
471 { .attrs = max6697_attributes[1] },
472 { .attrs = max6697_attributes[2] },
473 { .attrs = max6697_attributes[3] },
474 { .attrs = max6697_attributes[4] },
475 { .attrs = max6697_attributes[5] },
476 { .attrs = max6697_attributes[6] },
477 { .attrs = max6697_attributes[7] },
478};
479
480static void max6697_get_config_of(struct device_node *node,
481 struct max6697_platform_data *pdata)
482{
483 int len;
484 const __be32 *prop;
485
486 prop = of_get_property(node, "smbus-timeout-disable", &len);
487 if (prop)
488 pdata->smbus_timeout_disable = true;
489 prop = of_get_property(node, "extended-range-enable", &len);
490 if (prop)
491 pdata->extended_range_enable = true;
492 prop = of_get_property(node, "beta-compensation-enable", &len);
493 if (prop)
494 pdata->beta_compensation = true;
495 prop = of_get_property(node, "alert-mask", &len);
496 if (prop && len == sizeof(u32))
497 pdata->alert_mask = be32_to_cpu(prop[0]);
498 prop = of_get_property(node, "over-temperature-mask", &len);
499 if (prop && len == sizeof(u32))
500 pdata->over_temperature_mask = be32_to_cpu(prop[0]);
501 prop = of_get_property(node, "resistance-cancellation", &len);
502 if (prop) {
503 if (len == sizeof(u32))
504 pdata->resistance_cancellation = be32_to_cpu(prop[0]);
505 else
506 pdata->resistance_cancellation = 0xfe;
507 }
508 prop = of_get_property(node, "transistor-ideality", &len);
509 if (prop && len == 2 * sizeof(u32)) {
510 pdata->ideality_mask = be32_to_cpu(prop[0]);
511 pdata->ideality_value = be32_to_cpu(prop[1]);
512 }
513}
514
515static int max6697_init_chip(struct i2c_client *client)
516{
517 struct max6697_data *data = i2c_get_clientdata(client);
518 struct max6697_platform_data *pdata = dev_get_platdata(&client->dev);
519 struct max6697_platform_data p;
520 const struct max6697_chip_data *chip = data->chip;
521 int factor = chip->channels;
522 int ret, reg;
523
524 /*
525 * Don't touch configuration if neither platform data nor OF
526 * configuration was specified. If that is the case, use the
527 * current chip configuration.
528 */
529 if (!pdata && !client->dev.of_node) {
530 reg = i2c_smbus_read_byte_data(client, MAX6697_REG_CONFIG);
531 if (reg < 0)
532 return reg;
533 if (data->type == max6581) {
534 if (reg & MAX6581_CONF_EXTENDED)
535 data->temp_offset = 64;
536 reg = i2c_smbus_read_byte_data(client,
537 MAX6581_REG_RESISTANCE);
538 if (reg < 0)
539 return reg;
540 factor += hweight8(reg);
541 } else {
542 if (reg & MAX6697_CONF_RESISTANCE)
543 factor++;
544 }
545 goto done;
546 }
547
548 if (client->dev.of_node) {
549 memset(&p, 0, sizeof(p));
550 max6697_get_config_of(client->dev.of_node, &p);
551 pdata = &p;
552 }
553
554 reg = 0;
555 if (pdata->smbus_timeout_disable &&
556 (chip->valid_conf & MAX6697_CONF_TIMEOUT)) {
557 reg |= MAX6697_CONF_TIMEOUT;
558 }
559 if (pdata->extended_range_enable &&
560 (chip->valid_conf & MAX6581_CONF_EXTENDED)) {
561 reg |= MAX6581_CONF_EXTENDED;
562 data->temp_offset = 64;
563 }
564 if (pdata->resistance_cancellation &&
565 (chip->valid_conf & MAX6697_CONF_RESISTANCE)) {
566 reg |= MAX6697_CONF_RESISTANCE;
567 factor++;
568 }
569 if (pdata->beta_compensation &&
570 (chip->valid_conf & MAX6693_CONF_BETA)) {
571 reg |= MAX6693_CONF_BETA;
572 }
573
574 ret = i2c_smbus_write_byte_data(client, MAX6697_REG_CONFIG, reg);
575 if (ret < 0)
576 return ret;
577
578 ret = i2c_smbus_write_byte_data(client, MAX6697_REG_ALERT_MASK,
579 MAX6697_MAP_BITS(pdata->alert_mask));
580 if (ret < 0)
581 return ret;
582
583 ret = i2c_smbus_write_byte_data(client, MAX6697_REG_OVERT_MASK,
584 MAX6697_MAP_BITS(pdata->over_temperature_mask));
585 if (ret < 0)
586 return ret;
587
588 if (data->type == max6581) {
589 factor += hweight8(pdata->resistance_cancellation >> 1);
590 ret = i2c_smbus_write_byte_data(client, MAX6581_REG_RESISTANCE,
591 pdata->resistance_cancellation >> 1);
592 if (ret < 0)
593 return ret;
594 ret = i2c_smbus_write_byte_data(client, MAX6581_REG_IDEALITY,
595 pdata->ideality_mask >> 1);
596 if (ret < 0)
597 return ret;
598 ret = i2c_smbus_write_byte_data(client,
599 MAX6581_REG_IDEALITY_SELECT,
600 pdata->ideality_value);
601 if (ret < 0)
602 return ret;
603 }
604done:
605 data->update_interval = factor * MAX6697_CONV_TIME;
606 return 0;
607}
608
609static void max6697_remove_files(struct i2c_client *client)
610{
611 int i;
612
613 for (i = 0; i < ARRAY_SIZE(max6697_group); i++)
614 sysfs_remove_group(&client->dev.kobj, &max6697_group[i]);
615}
616
617static int max6697_probe(struct i2c_client *client,
618 const struct i2c_device_id *id)
619{
620 struct i2c_adapter *adapter = client->adapter;
621 struct device *dev = &client->dev;
622 struct max6697_data *data;
623 int i, err;
624
625 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
626 return -ENODEV;
627
628 data = devm_kzalloc(dev, sizeof(struct max6697_data), GFP_KERNEL);
629 if (!data)
630 return -ENOMEM;
631
632 data->type = id->driver_data;
633 data->chip = &max6697_chip_data[data->type];
634
635 i2c_set_clientdata(client, data);
636 mutex_init(&data->update_lock);
637
638 err = max6697_init_chip(client);
639 if (err)
640 return err;
641
642 for (i = 0; i < data->chip->channels; i++) {
643 err = sysfs_create_file(&dev->kobj,
644 max6697_attributes[i][0]);
645 if (err)
646 goto error;
647 err = sysfs_create_file(&dev->kobj,
648 max6697_attributes[i][1]);
649 if (err)
650 goto error;
651 err = sysfs_create_file(&dev->kobj,
652 max6697_attributes[i][2]);
653 if (err)
654 goto error;
655
656 if (data->chip->have_crit & (1 << i)) {
657 err = sysfs_create_file(&dev->kobj,
658 max6697_attributes[i][3]);
659 if (err)
660 goto error;
661 err = sysfs_create_file(&dev->kobj,
662 max6697_attributes[i][4]);
663 if (err)
664 goto error;
665 }
666 if (data->chip->have_fault & (1 << i)) {
667 err = sysfs_create_file(&dev->kobj,
668 max6697_attributes[i][5]);
669 if (err)
670 goto error;
671 }
672 }
673
674 data->hwmon_dev = hwmon_device_register(dev);
675 if (IS_ERR(data->hwmon_dev)) {
676 err = PTR_ERR(data->hwmon_dev);
677 goto error;
678 }
679
680 return 0;
681
682error:
683 max6697_remove_files(client);
684 return err;
685}
686
687static int max6697_remove(struct i2c_client *client)
688{
689 struct max6697_data *data = i2c_get_clientdata(client);
690
691 hwmon_device_unregister(data->hwmon_dev);
692 max6697_remove_files(client);
693
694 return 0;
695}
696
697static const struct i2c_device_id max6697_id[] = {
698 { "max6581", max6581 },
699 { "max6602", max6602 },
700 { "max6622", max6622 },
701 { "max6636", max6636 },
702 { "max6689", max6689 },
703 { "max6693", max6693 },
704 { "max6694", max6694 },
705 { "max6697", max6697 },
706 { "max6698", max6698 },
707 { "max6699", max6699 },
708 { }
709};
710MODULE_DEVICE_TABLE(i2c, max6697_id);
711
712static struct i2c_driver max6697_driver = {
713 .class = I2C_CLASS_HWMON,
714 .driver = {
715 .name = "max6697",
716 },
717 .probe = max6697_probe,
718 .remove = max6697_remove,
719 .id_table = max6697_id,
720};
721
722module_i2c_driver(max6697_driver);
723
724MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>");
725MODULE_DESCRIPTION("MAX6697 temperature sensor driver");
726MODULE_LICENSE("GPL");
diff --git a/include/linux/platform_data/max6697.h b/include/linux/platform_data/max6697.h
new file mode 100644
index 000000000000..ed9d3b3daf02
--- /dev/null
+++ b/include/linux/platform_data/max6697.h
@@ -0,0 +1,36 @@
1/*
2 * max6697.h
3 * Copyright (c) 2012 Guenter Roeck <linux@roeck-us.net>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 */
9
10#ifndef MAX6697_H
11#define MAX6697_H
12
13#include <linux/types.h>
14
15/*
16 * For all bit masks:
17 * bit 0: local temperature
18 * bit 1..7: remote temperatures
19 */
20struct max6697_platform_data {
21 bool smbus_timeout_disable; /* set to disable SMBus timeouts */
22 bool extended_range_enable; /* set to enable extended temp range */
23 bool beta_compensation; /* set to enable beta compensation */
24 u8 alert_mask; /* set bit to 1 to disable alert */
25 u8 over_temperature_mask; /* set bit to 1 to disable */
26 u8 resistance_cancellation; /* set bit to 0 to disable
27 * bit mask for MAX6581,
28 * boolean for other chips
29 */
30 u8 ideality_mask; /* set bit to 0 to disable */
31 u8 ideality_value; /* transistor ideality as per
32 * MAX6581 datasheet
33 */
34};
35
36#endif /* MAX6697_H */