aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean Delvare <khali@linux-fr.org>2011-05-25 14:43:33 -0400
committerJean Delvare <khali@endymion.delvare>2011-05-25 14:43:33 -0400
commitb0b349a85d3df00a40a8bd398e4a151fd8e91bbe (patch)
tree79d2e5d15bb13e349af23cd3602090c9ef92f793
parentec693fe5287e1791f4d206e81ebdfdc7d1f8f6b9 (diff)
hwmon: New driver for the SMSC EMC6W201
This is a new driver for the SMSC EMC6W201 hardware monitoring device. The device is functionally close to the EMC6D100 series, but is register-incompatible. Signed-off-by: Jean Delvare <khali@linux-fr.org> Tested-by: Harry G McGavran Jr <w5pny@arrl.net> Tested-by: Jeff Rickman <jrickman@myamigos.us> Acked-by: Guenter Roeck <guenter.roeck@ericsson.com>
-rw-r--r--Documentation/hwmon/emc6w20142
-rw-r--r--drivers/hwmon/Kconfig10
-rw-r--r--drivers/hwmon/Makefile1
-rw-r--r--drivers/hwmon/emc6w201.c539
4 files changed, 592 insertions, 0 deletions
diff --git a/Documentation/hwmon/emc6w201 b/Documentation/hwmon/emc6w201
new file mode 100644
index 000000000000..32f355aaf56b
--- /dev/null
+++ b/Documentation/hwmon/emc6w201
@@ -0,0 +1,42 @@
1Kernel driver emc6w201
2======================
3
4Supported chips:
5 * SMSC EMC6W201
6 Prefix: 'emc6w201'
7 Addresses scanned: I2C 0x2c, 0x2d, 0x2e
8 Datasheet: Not public
9
10Author: Jean Delvare <khali@linux-fr.org>
11
12
13Description
14-----------
15
16From the datasheet:
17
18"The EMC6W201 is an environmental monitoring device with automatic fan
19control capability and enhanced system acoustics for noise suppression.
20This ACPI compliant device provides hardware monitoring for up to six
21voltages (including its own VCC) and five external thermal sensors,
22measures the speed of up to five fans, and controls the speed of
23multiple DC fans using three Pulse Width Modulator (PWM) outputs. Note
24that it is possible to control more than three fans by connecting two
25fans to one PWM output. The EMC6W201 will be available in a 36-pin
26QFN package."
27
28The device is functionally close to the EMC6D100 series, but is
29register-incompatible.
30
31The driver currently only supports the monitoring of the voltages,
32temperatures and fan speeds. Limits can be changed. Alarms are not
33supported, and neither is fan speed control.
34
35
36Known Systems With EMC6W201
37---------------------------
38
39The EMC6W201 is a rare device, only found on a few systems, made in
402005 and 2006. Known systems with this device:
41* Dell Precision 670 workstation
42* Gigabyte 2CEWH mainboard
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 900409615ae9..16db83c83c8b 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -988,6 +988,16 @@ config SENSORS_EMC2103
988 This driver can also be built as a module. If so, the module 988 This driver can also be built as a module. If so, the module
989 will be called emc2103. 989 will be called emc2103.
990 990
991config SENSORS_EMC6W201
992 tristate "SMSC EMC6W201"
993 depends on I2C
994 help
995 If you say yes here you get support for the SMSC EMC6W201
996 hardware monitoring chip.
997
998 This driver can also be built as a module. If so, the module
999 will be called emc6w201.
1000
991config SENSORS_SMSC47M1 1001config SENSORS_SMSC47M1
992 tristate "SMSC LPC47M10x and compatibles" 1002 tristate "SMSC LPC47M10x and compatibles"
993 help 1003 help
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 8a57eca7a764..28061cfa0cdb 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -46,6 +46,7 @@ obj-$(CONFIG_SENSORS_DS620) += ds620.o
46obj-$(CONFIG_SENSORS_DS1621) += ds1621.o 46obj-$(CONFIG_SENSORS_DS1621) += ds1621.o
47obj-$(CONFIG_SENSORS_EMC1403) += emc1403.o 47obj-$(CONFIG_SENSORS_EMC1403) += emc1403.o
48obj-$(CONFIG_SENSORS_EMC2103) += emc2103.o 48obj-$(CONFIG_SENSORS_EMC2103) += emc2103.o
49obj-$(CONFIG_SENSORS_EMC6W201) += emc6w201.o
49obj-$(CONFIG_SENSORS_F71805F) += f71805f.o 50obj-$(CONFIG_SENSORS_F71805F) += f71805f.o
50obj-$(CONFIG_SENSORS_F71882FG) += f71882fg.o 51obj-$(CONFIG_SENSORS_F71882FG) += f71882fg.o
51obj-$(CONFIG_SENSORS_F75375S) += f75375s.o 52obj-$(CONFIG_SENSORS_F75375S) += f75375s.o
diff --git a/drivers/hwmon/emc6w201.c b/drivers/hwmon/emc6w201.c
new file mode 100644
index 000000000000..e0ef32378ac6
--- /dev/null
+++ b/drivers/hwmon/emc6w201.c
@@ -0,0 +1,539 @@
1/*
2 * emc6w201.c - Hardware monitoring driver for the SMSC EMC6W201
3 * Copyright (C) 2011 Jean Delvare <khali@linux-fr.org>
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 as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20#include <linux/module.h>
21#include <linux/delay.h>
22#include <linux/init.h>
23#include <linux/slab.h>
24#include <linux/jiffies.h>
25#include <linux/i2c.h>
26#include <linux/hwmon.h>
27#include <linux/hwmon-sysfs.h>
28#include <linux/err.h>
29#include <linux/mutex.h>
30
31/*
32 * Addresses to scan
33 */
34
35static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
36
37/*
38 * The EMC6W201 registers
39 */
40
41#define EMC6W201_REG_IN(nr) (0x20 + (nr))
42#define EMC6W201_REG_TEMP(nr) (0x26 + (nr))
43#define EMC6W201_REG_FAN(nr) (0x2C + (nr) * 2)
44#define EMC6W201_REG_COMPANY 0x3E
45#define EMC6W201_REG_VERSTEP 0x3F
46#define EMC6W201_REG_CONFIG 0x40
47#define EMC6W201_REG_IN_LOW(nr) (0x4A + (nr) * 2)
48#define EMC6W201_REG_IN_HIGH(nr) (0x4B + (nr) * 2)
49#define EMC6W201_REG_TEMP_LOW(nr) (0x56 + (nr) * 2)
50#define EMC6W201_REG_TEMP_HIGH(nr) (0x57 + (nr) * 2)
51#define EMC6W201_REG_FAN_MIN(nr) (0x62 + (nr) * 2)
52
53enum { input, min, max } subfeature;
54
55/*
56 * Per-device data
57 */
58
59struct emc6w201_data {
60 struct device *hwmon_dev;
61 struct mutex update_lock;
62 char valid; /* zero until following fields are valid */
63 unsigned long last_updated; /* in jiffies */
64
65 /* registers values */
66 u8 in[3][6];
67 s8 temp[3][6];
68 u16 fan[2][5];
69};
70
71/*
72 * Combine LSB and MSB registers in a single value
73 * Locking: must be called with data->update_lock held
74 */
75static u16 emc6w201_read16(struct i2c_client *client, u8 reg)
76{
77 int lsb, msb;
78
79 lsb = i2c_smbus_read_byte_data(client, reg);
80 msb = i2c_smbus_read_byte_data(client, reg + 1);
81 if (lsb < 0 || msb < 0) {
82 dev_err(&client->dev, "16-bit read failed at 0x%02x\n", reg);
83 return 0xFFFF; /* Arbitrary value */
84 }
85
86 return (msb << 8) | lsb;
87}
88
89/*
90 * Write 16-bit value to LSB and MSB registers
91 * Locking: must be called with data->update_lock held
92 */
93static int emc6w201_write16(struct i2c_client *client, u8 reg, u16 val)
94{
95 int err;
96
97 err = i2c_smbus_write_byte_data(client, reg, val & 0xff);
98 if (!err)
99 err = i2c_smbus_write_byte_data(client, reg + 1, val >> 8);
100 if (err < 0)
101 dev_err(&client->dev, "16-bit write failed at 0x%02x\n", reg);
102
103 return err;
104}
105
106static struct emc6w201_data *emc6w201_update_device(struct device *dev)
107{
108 struct i2c_client *client = to_i2c_client(dev);
109 struct emc6w201_data *data = i2c_get_clientdata(client);
110 int nr;
111
112 mutex_lock(&data->update_lock);
113
114 if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
115 for (nr = 0; nr < 6; nr++) {
116 data->in[input][nr] =
117 i2c_smbus_read_byte_data(client,
118 EMC6W201_REG_IN(nr));
119 data->in[min][nr] =
120 i2c_smbus_read_byte_data(client,
121 EMC6W201_REG_IN_LOW(nr));
122 data->in[max][nr] =
123 i2c_smbus_read_byte_data(client,
124 EMC6W201_REG_IN_HIGH(nr));
125 }
126
127 for (nr = 0; nr < 6; nr++) {
128 data->temp[input][nr] =
129 i2c_smbus_read_byte_data(client,
130 EMC6W201_REG_TEMP(nr));
131 data->temp[min][nr] =
132 i2c_smbus_read_byte_data(client,
133 EMC6W201_REG_TEMP_LOW(nr));
134 data->temp[max][nr] =
135 i2c_smbus_read_byte_data(client,
136 EMC6W201_REG_TEMP_HIGH(nr));
137 }
138
139 for (nr = 0; nr < 5; nr++) {
140 data->fan[input][nr] =
141 emc6w201_read16(client,
142 EMC6W201_REG_FAN(nr));
143 data->fan[min][nr] =
144 emc6w201_read16(client,
145 EMC6W201_REG_FAN_MIN(nr));
146 }
147
148 data->last_updated = jiffies;
149 data->valid = 1;
150 }
151
152 mutex_unlock(&data->update_lock);
153
154 return data;
155}
156
157/*
158 * Sysfs callback functions
159 */
160
161static const u16 nominal_mv[6] = { 2500, 1500, 3300, 5000, 1500, 1500 };
162
163static ssize_t show_in(struct device *dev, struct device_attribute *devattr,
164 char *buf)
165{
166 struct emc6w201_data *data = emc6w201_update_device(dev);
167 int sf = to_sensor_dev_attr_2(devattr)->index;
168 int nr = to_sensor_dev_attr_2(devattr)->nr;
169
170 return sprintf(buf, "%u\n",
171 (unsigned)data->in[sf][nr] * nominal_mv[nr] / 0xC0);
172}
173
174static ssize_t set_in(struct device *dev, struct device_attribute *devattr,
175 const char *buf, size_t count)
176{
177 struct i2c_client *client = to_i2c_client(dev);
178 struct emc6w201_data *data = i2c_get_clientdata(client);
179 int sf = to_sensor_dev_attr_2(devattr)->index;
180 int nr = to_sensor_dev_attr_2(devattr)->nr;
181 int err;
182 long val;
183 u8 reg;
184
185 err = strict_strtol(buf, 10, &val);
186 if (err < 0)
187 return err;
188
189 val = DIV_ROUND_CLOSEST(val * 0xC0, nominal_mv[nr]);
190 reg = (sf == min) ? EMC6W201_REG_IN_LOW(nr)
191 : EMC6W201_REG_IN_HIGH(nr);
192
193 mutex_lock(&data->update_lock);
194 data->in[sf][nr] = SENSORS_LIMIT(val, 0, 255);
195 err = i2c_smbus_write_byte_data(client, reg, data->in[sf][nr]);
196 mutex_unlock(&data->update_lock);
197
198 return err < 0 ? err : count;
199}
200
201static ssize_t show_temp(struct device *dev, struct device_attribute *devattr,
202 char *buf)
203{
204 struct emc6w201_data *data = emc6w201_update_device(dev);
205 int sf = to_sensor_dev_attr_2(devattr)->index;
206 int nr = to_sensor_dev_attr_2(devattr)->nr;
207
208 return sprintf(buf, "%d\n", (int)data->temp[sf][nr] * 1000);
209}
210
211static ssize_t set_temp(struct device *dev, struct device_attribute *devattr,
212 const char *buf, size_t count)
213{
214 struct i2c_client *client = to_i2c_client(dev);
215 struct emc6w201_data *data = i2c_get_clientdata(client);
216 int sf = to_sensor_dev_attr_2(devattr)->index;
217 int nr = to_sensor_dev_attr_2(devattr)->nr;
218 int err;
219 long val;
220 u8 reg;
221
222 err = strict_strtol(buf, 10, &val);
223 if (err < 0)
224 return err;
225
226 val /= 1000;
227 reg = (sf == min) ? EMC6W201_REG_TEMP_LOW(nr)
228 : EMC6W201_REG_TEMP_HIGH(nr);
229
230 mutex_lock(&data->update_lock);
231 data->temp[sf][nr] = SENSORS_LIMIT(val, -127, 128);
232 err = i2c_smbus_write_byte_data(client, reg, data->temp[sf][nr]);
233 mutex_unlock(&data->update_lock);
234
235 return err < 0 ? err : count;
236}
237
238static ssize_t show_fan(struct device *dev, struct device_attribute *devattr,
239 char *buf)
240{
241 struct emc6w201_data *data = emc6w201_update_device(dev);
242 int sf = to_sensor_dev_attr_2(devattr)->index;
243 int nr = to_sensor_dev_attr_2(devattr)->nr;
244 unsigned rpm;
245
246 if (data->fan[sf][nr] == 0 || data->fan[sf][nr] == 0xFFFF)
247 rpm = 0;
248 else
249 rpm = 5400000U / data->fan[sf][nr];
250
251 return sprintf(buf, "%u\n", rpm);
252}
253
254static ssize_t set_fan(struct device *dev, struct device_attribute *devattr,
255 const char *buf, size_t count)
256{
257 struct i2c_client *client = to_i2c_client(dev);
258 struct emc6w201_data *data = i2c_get_clientdata(client);
259 int sf = to_sensor_dev_attr_2(devattr)->index;
260 int nr = to_sensor_dev_attr_2(devattr)->nr;
261 int err;
262 unsigned long val;
263
264 err = strict_strtoul(buf, 10, &val);
265 if (err < 0)
266 return err;
267
268 if (val == 0) {
269 val = 0xFFFF;
270 } else {
271 val = DIV_ROUND_CLOSEST(5400000U, val);
272 val = SENSORS_LIMIT(val, 0, 0xFFFE);
273 }
274
275 mutex_lock(&data->update_lock);
276 data->fan[sf][nr] = val;
277 err = emc6w201_write16(client, EMC6W201_REG_FAN_MIN(nr),
278 data->fan[sf][nr]);
279 mutex_unlock(&data->update_lock);
280
281 return err < 0 ? err : count;
282}
283
284static SENSOR_DEVICE_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, input);
285static SENSOR_DEVICE_ATTR_2(in0_min, S_IRUGO | S_IWUSR, show_in, set_in,
286 0, min);
287static SENSOR_DEVICE_ATTR_2(in0_max, S_IRUGO | S_IWUSR, show_in, set_in,
288 0, max);
289static SENSOR_DEVICE_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 1, input);
290static SENSOR_DEVICE_ATTR_2(in1_min, S_IRUGO | S_IWUSR, show_in, set_in,
291 1, min);
292static SENSOR_DEVICE_ATTR_2(in1_max, S_IRUGO | S_IWUSR, show_in, set_in,
293 1, max);
294static SENSOR_DEVICE_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 2, input);
295static SENSOR_DEVICE_ATTR_2(in2_min, S_IRUGO | S_IWUSR, show_in, set_in,
296 2, min);
297static SENSOR_DEVICE_ATTR_2(in2_max, S_IRUGO | S_IWUSR, show_in, set_in,
298 2, max);
299static SENSOR_DEVICE_ATTR_2(in3_input, S_IRUGO, show_in, NULL, 3, input);
300static SENSOR_DEVICE_ATTR_2(in3_min, S_IRUGO | S_IWUSR, show_in, set_in,
301 3, min);
302static SENSOR_DEVICE_ATTR_2(in3_max, S_IRUGO | S_IWUSR, show_in, set_in,
303 3, max);
304static SENSOR_DEVICE_ATTR_2(in4_input, S_IRUGO, show_in, NULL, 4, input);
305static SENSOR_DEVICE_ATTR_2(in4_min, S_IRUGO | S_IWUSR, show_in, set_in,
306 4, min);
307static SENSOR_DEVICE_ATTR_2(in4_max, S_IRUGO | S_IWUSR, show_in, set_in,
308 4, max);
309static SENSOR_DEVICE_ATTR_2(in5_input, S_IRUGO, show_in, NULL, 5, input);
310static SENSOR_DEVICE_ATTR_2(in5_min, S_IRUGO | S_IWUSR, show_in, set_in,
311 5, min);
312static SENSOR_DEVICE_ATTR_2(in5_max, S_IRUGO | S_IWUSR, show_in, set_in,
313 5, max);
314
315static SENSOR_DEVICE_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, input);
316static SENSOR_DEVICE_ATTR_2(temp1_min, S_IRUGO | S_IWUSR, show_temp, set_temp,
317 0, min);
318static SENSOR_DEVICE_ATTR_2(temp1_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
319 0, max);
320static SENSOR_DEVICE_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 1, input);
321static SENSOR_DEVICE_ATTR_2(temp2_min, S_IRUGO | S_IWUSR, show_temp, set_temp,
322 1, min);
323static SENSOR_DEVICE_ATTR_2(temp2_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
324 1, max);
325static SENSOR_DEVICE_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 2, input);
326static SENSOR_DEVICE_ATTR_2(temp3_min, S_IRUGO | S_IWUSR, show_temp, set_temp,
327 2, min);
328static SENSOR_DEVICE_ATTR_2(temp3_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
329 2, max);
330static SENSOR_DEVICE_ATTR_2(temp4_input, S_IRUGO, show_temp, NULL, 3, input);
331static SENSOR_DEVICE_ATTR_2(temp4_min, S_IRUGO | S_IWUSR, show_temp, set_temp,
332 3, min);
333static SENSOR_DEVICE_ATTR_2(temp4_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
334 3, max);
335static SENSOR_DEVICE_ATTR_2(temp5_input, S_IRUGO, show_temp, NULL, 4, input);
336static SENSOR_DEVICE_ATTR_2(temp5_min, S_IRUGO | S_IWUSR, show_temp, set_temp,
337 4, min);
338static SENSOR_DEVICE_ATTR_2(temp5_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
339 4, max);
340static SENSOR_DEVICE_ATTR_2(temp6_input, S_IRUGO, show_temp, NULL, 5, input);
341static SENSOR_DEVICE_ATTR_2(temp6_min, S_IRUGO | S_IWUSR, show_temp, set_temp,
342 5, min);
343static SENSOR_DEVICE_ATTR_2(temp6_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
344 5, max);
345
346static SENSOR_DEVICE_ATTR_2(fan1_input, S_IRUGO, show_fan, NULL, 0, input);
347static SENSOR_DEVICE_ATTR_2(fan1_min, S_IRUGO | S_IWUSR, show_fan, set_fan,
348 0, min);
349static SENSOR_DEVICE_ATTR_2(fan2_input, S_IRUGO, show_fan, NULL, 1, input);
350static SENSOR_DEVICE_ATTR_2(fan2_min, S_IRUGO | S_IWUSR, show_fan, set_fan,
351 1, min);
352static SENSOR_DEVICE_ATTR_2(fan3_input, S_IRUGO, show_fan, NULL, 2, input);
353static SENSOR_DEVICE_ATTR_2(fan3_min, S_IRUGO | S_IWUSR, show_fan, set_fan,
354 2, min);
355static SENSOR_DEVICE_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 3, input);
356static SENSOR_DEVICE_ATTR_2(fan4_min, S_IRUGO | S_IWUSR, show_fan, set_fan,
357 3, min);
358static SENSOR_DEVICE_ATTR_2(fan5_input, S_IRUGO, show_fan, NULL, 4, input);
359static SENSOR_DEVICE_ATTR_2(fan5_min, S_IRUGO | S_IWUSR, show_fan, set_fan,
360 4, min);
361
362static struct attribute *emc6w201_attributes[] = {
363 &sensor_dev_attr_in0_input.dev_attr.attr,
364 &sensor_dev_attr_in0_min.dev_attr.attr,
365 &sensor_dev_attr_in0_max.dev_attr.attr,
366 &sensor_dev_attr_in1_input.dev_attr.attr,
367 &sensor_dev_attr_in1_min.dev_attr.attr,
368 &sensor_dev_attr_in1_max.dev_attr.attr,
369 &sensor_dev_attr_in2_input.dev_attr.attr,
370 &sensor_dev_attr_in2_min.dev_attr.attr,
371 &sensor_dev_attr_in2_max.dev_attr.attr,
372 &sensor_dev_attr_in3_input.dev_attr.attr,
373 &sensor_dev_attr_in3_min.dev_attr.attr,
374 &sensor_dev_attr_in3_max.dev_attr.attr,
375 &sensor_dev_attr_in4_input.dev_attr.attr,
376 &sensor_dev_attr_in4_min.dev_attr.attr,
377 &sensor_dev_attr_in4_max.dev_attr.attr,
378 &sensor_dev_attr_in5_input.dev_attr.attr,
379 &sensor_dev_attr_in5_min.dev_attr.attr,
380 &sensor_dev_attr_in5_max.dev_attr.attr,
381
382 &sensor_dev_attr_temp1_input.dev_attr.attr,
383 &sensor_dev_attr_temp1_min.dev_attr.attr,
384 &sensor_dev_attr_temp1_max.dev_attr.attr,
385 &sensor_dev_attr_temp2_input.dev_attr.attr,
386 &sensor_dev_attr_temp2_min.dev_attr.attr,
387 &sensor_dev_attr_temp2_max.dev_attr.attr,
388 &sensor_dev_attr_temp3_input.dev_attr.attr,
389 &sensor_dev_attr_temp3_min.dev_attr.attr,
390 &sensor_dev_attr_temp3_max.dev_attr.attr,
391 &sensor_dev_attr_temp4_input.dev_attr.attr,
392 &sensor_dev_attr_temp4_min.dev_attr.attr,
393 &sensor_dev_attr_temp4_max.dev_attr.attr,
394 &sensor_dev_attr_temp5_input.dev_attr.attr,
395 &sensor_dev_attr_temp5_min.dev_attr.attr,
396 &sensor_dev_attr_temp5_max.dev_attr.attr,
397 &sensor_dev_attr_temp6_input.dev_attr.attr,
398 &sensor_dev_attr_temp6_min.dev_attr.attr,
399 &sensor_dev_attr_temp6_max.dev_attr.attr,
400
401 &sensor_dev_attr_fan1_input.dev_attr.attr,
402 &sensor_dev_attr_fan1_min.dev_attr.attr,
403 &sensor_dev_attr_fan2_input.dev_attr.attr,
404 &sensor_dev_attr_fan2_min.dev_attr.attr,
405 &sensor_dev_attr_fan3_input.dev_attr.attr,
406 &sensor_dev_attr_fan3_min.dev_attr.attr,
407 &sensor_dev_attr_fan4_input.dev_attr.attr,
408 &sensor_dev_attr_fan4_min.dev_attr.attr,
409 &sensor_dev_attr_fan5_input.dev_attr.attr,
410 &sensor_dev_attr_fan5_min.dev_attr.attr,
411 NULL
412};
413
414static const struct attribute_group emc6w201_group = {
415 .attrs = emc6w201_attributes,
416};
417
418/*
419 * Driver interface
420 */
421
422/* Return 0 if detection is successful, -ENODEV otherwise */
423static int emc6w201_detect(struct i2c_client *client,
424 struct i2c_board_info *info)
425{
426 struct i2c_adapter *adapter = client->adapter;
427 int company, verstep, config;
428
429 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
430 return -ENODEV;
431
432 /* Identification */
433 company = i2c_smbus_read_byte_data(client, EMC6W201_REG_COMPANY);
434 if (company != 0x5C)
435 return -ENODEV;
436 verstep = i2c_smbus_read_byte_data(client, EMC6W201_REG_VERSTEP);
437 if (verstep < 0 || (verstep & 0xF0) != 0xB0)
438 return -ENODEV;
439 if ((verstep & 0x0F) > 2) {
440 dev_dbg(&client->dev, "Unknwown EMC6W201 stepping %d\n",
441 verstep & 0x0F);
442 return -ENODEV;
443 }
444
445 /* Check configuration */
446 config = i2c_smbus_read_byte_data(client, EMC6W201_REG_CONFIG);
447 if ((config & 0xF4) != 0x04)
448 return -ENODEV;
449 if (!(config & 0x01)) {
450 dev_err(&client->dev, "Monitoring not enabled\n");
451 return -ENODEV;
452 }
453
454 strlcpy(info->type, "emc6w201", I2C_NAME_SIZE);
455
456 return 0;
457}
458
459static int emc6w201_probe(struct i2c_client *client,
460 const struct i2c_device_id *id)
461{
462 struct emc6w201_data *data;
463 int err;
464
465 data = kzalloc(sizeof(struct emc6w201_data), GFP_KERNEL);
466 if (!data) {
467 err = -ENOMEM;
468 goto exit;
469 }
470
471 i2c_set_clientdata(client, data);
472 mutex_init(&data->update_lock);
473
474 /* Create sysfs attribute */
475 err = sysfs_create_group(&client->dev.kobj, &emc6w201_group);
476 if (err)
477 goto exit_free;
478
479 /* Expose as a hwmon device */
480 data->hwmon_dev = hwmon_device_register(&client->dev);
481 if (IS_ERR(data->hwmon_dev)) {
482 err = PTR_ERR(data->hwmon_dev);
483 goto exit_remove;
484 }
485
486 return 0;
487
488 exit_remove:
489 sysfs_remove_group(&client->dev.kobj, &emc6w201_group);
490 exit_free:
491 kfree(data);
492 exit:
493 return err;
494}
495
496static int emc6w201_remove(struct i2c_client *client)
497{
498 struct emc6w201_data *data = i2c_get_clientdata(client);
499
500 hwmon_device_unregister(data->hwmon_dev);
501 sysfs_remove_group(&client->dev.kobj, &emc6w201_group);
502 kfree(data);
503
504 return 0;
505}
506
507static const struct i2c_device_id emc6w201_id[] = {
508 { "emc6w201", 0 },
509 { }
510};
511MODULE_DEVICE_TABLE(i2c, emc6w201_id);
512
513static struct i2c_driver emc6w201_driver = {
514 .class = I2C_CLASS_HWMON,
515 .driver = {
516 .name = "emc6w201",
517 },
518 .probe = emc6w201_probe,
519 .remove = emc6w201_remove,
520 .id_table = emc6w201_id,
521 .detect = emc6w201_detect,
522 .address_list = normal_i2c,
523};
524
525static int __init sensors_emc6w201_init(void)
526{
527 return i2c_add_driver(&emc6w201_driver);
528}
529module_init(sensors_emc6w201_init);
530
531static void __exit sensors_emc6w201_exit(void)
532{
533 i2c_del_driver(&emc6w201_driver);
534}
535module_exit(sensors_emc6w201_exit);
536
537MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
538MODULE_DESCRIPTION("SMSC EMC6W201 hardware monitoring driver");
539MODULE_LICENSE("GPL");