aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuenter Roeck <linux@roeck-us.net>2012-05-20 22:29:48 -0400
committerGuenter Roeck <linux@roeck-us.net>2013-04-08 00:16:38 -0400
commit9de2e2e84e7d52e4c2a9e1a1e21ab6ac686233c0 (patch)
treeeb61db97b5f21d7dd6e2ead5828c928da72cb479
parent24f9c539b9b7ef8fcc97741027a31f40ef399741 (diff)
hwmon: Driver for Nuvoton NCT6775F, NCT6776F, and NCT6779D
This driver will replace the w83627ehf driver for NCT6775F and NCT6776F, and provides support for NCT6779D. This patch provides support for voltage monitor attributes. Signed-off-by: Guenter Roeck <linux@roeck-us.net>
-rw-r--r--Documentation/hwmon/nct677581
-rw-r--r--drivers/hwmon/Kconfig13
-rw-r--r--drivers/hwmon/Makefile1
-rw-r--r--drivers/hwmon/nct6775.c1021
4 files changed, 1116 insertions, 0 deletions
diff --git a/Documentation/hwmon/nct6775 b/Documentation/hwmon/nct6775
new file mode 100644
index 000000000000..ccfd5cc21006
--- /dev/null
+++ b/Documentation/hwmon/nct6775
@@ -0,0 +1,81 @@
1Note
2====
3
4This driver supersedes the NCT6775F and NCT6776F support in the W83627EHF
5driver.
6
7Kernel driver NCT6775
8=====================
9
10Supported chips:
11 * Nuvoton NCT6775F/W83667HG-I
12 Prefix: 'nct6775'
13 Addresses scanned: ISA address retrieved from Super I/O registers
14 Datasheet: Available from Nuvoton upon request
15 * Nuvoton NCT6776F
16 Prefix: 'nct6776'
17 Addresses scanned: ISA address retrieved from Super I/O registers
18 Datasheet: Available from Nuvoton upon request
19 * Nuvoton NCT6779D
20 Prefix: 'nct6779'
21 Addresses scanned: ISA address retrieved from Super I/O registers
22 Datasheet: Available from Nuvoton upon request
23
24Authors:
25 Guenter Roeck <linux@roeck-us.net>
26
27Description
28-----------
29
30This driver implements support for the Nuvoton NCT6775F, NCT6776F, and NCT6779D
31super I/O chips.
32
33The chips support up to 25 temperature monitoring sources. Up to 6 of those are
34direct temperature sensor inputs, the others are special sources such as PECI,
35PCH, and SMBUS. Depending on the chip type, 2 to 6 of the temperature sources
36can be monitored and compared against minimum, maximum, and critical
37temperatures. The driver reports up to 10 of the temperatures to the user.
38There are 4 to 5 fan rotation speed sensors, 8 to 15 analog voltage sensors,
39one VID, alarms with beep warnings (control unimplemented), and some automatic
40fan regulation strategies (plus manual fan control mode).
41
42The temperature sensor sources on all chips are configurable. The configured
43source for each of the temperature sensors is provided in tempX_label.
44
45Temperatures are measured in degrees Celsius and measurement resolution is
46either 1 degC or 0.5 degC, depending on the temperature source and
47configuration. An alarm is triggered when the temperature gets higher than
48the high limit; it stays on until the temperature falls below the hysteresis
49value. Alarms are only supported for temp1 to temp6, depending on the chip type.
50
51Fan rotation speeds are reported in RPM (rotations per minute). An alarm is
52triggered if the rotation speed has dropped below a programmable limit. On
53NCT6775F, fan readings can be divided by a programmable divider (1, 2, 4, 8,
5416, 32, 64 or 128) to give the readings more range or accuracy; the other chips
55do not have a fan speed divider. The driver sets the most suitable fan divisor
56itself; specifically, it doubles the divider value each time a fan speed reading
57returns an invalid value. Some fans might not be present because they share pins
58with other functions.
59
60Voltage sensors (also known as IN sensors) report their values in millivolts.
61An alarm is triggered if the voltage has crossed a programmable minimum
62or maximum limit.
63
64The driver supports automatic fan control mode known as Thermal Cruise.
65In this mode, the chip attempts to keep the measured temperature in a
66predefined temperature range. If the temperature goes out of range, fan
67is driven slower/faster to reach the predefined range again.
68
69The mode works for fan1-fan5.
70
71Usage Notes
72-----------
73
74On various ASUS boards with NCT6776F, it appears that CPUTIN is not really
75connected to anything and floats, or that it is connected to some non-standard
76temperature measurement device. As a result, the temperature reported on CPUTIN
77will not reflect a usable value. It often reports unreasonably high
78temperatures, and in some cases the reported temperature declines if the actual
79temperature increases (similar to the raw PECI temperature value - see PECI
80specification for details). CPUTIN should therefore be be ignored on ASUS
81boards. The CPU temperature on ASUS boards is reported from PECI 0.
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 47d2176957a0..a0f1d6a406eb 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -897,6 +897,19 @@ config SENSORS_MCP3021
897 This driver can also be built as a module. If so, the module 897 This driver can also be built as a module. If so, the module
898 will be called mcp3021. 898 will be called mcp3021.
899 899
900config SENSORS_NCT6775
901 tristate "Nuvoton NCT6775F, NCT6776F, NCT6779D"
902 depends on !PPC
903 select HWMON_VID
904 help
905 If you say yes here you get support for the hardware monitoring
906 functionality of the Nuvoton NCT6775F, NCT6776F, and NCT6779D
907 Super-I/O chips. This driver replaces the w83627ehf driver for
908 NCT6775F and NCT6776F.
909
910 This driver can also be built as a module. If so, the module
911 will be called nct6775.
912
900config SENSORS_NTC_THERMISTOR 913config SENSORS_NTC_THERMISTOR
901 tristate "NTC thermistor support" 914 tristate "NTC thermistor support"
902 depends on (!OF && !IIO) || (OF && IIO) 915 depends on (!OF && !IIO) || (OF && IIO)
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 5d36a57c055b..82975724d3af 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -105,6 +105,7 @@ obj-$(CONFIG_SENSORS_MAX6650) += max6650.o
105obj-$(CONFIG_SENSORS_MAX6697) += max6697.o 105obj-$(CONFIG_SENSORS_MAX6697) += max6697.o
106obj-$(CONFIG_SENSORS_MC13783_ADC)+= mc13783-adc.o 106obj-$(CONFIG_SENSORS_MC13783_ADC)+= mc13783-adc.o
107obj-$(CONFIG_SENSORS_MCP3021) += mcp3021.o 107obj-$(CONFIG_SENSORS_MCP3021) += mcp3021.o
108obj-$(CONFIG_SENSORS_NCT6775) += nct6775.o
108obj-$(CONFIG_SENSORS_NTC_THERMISTOR) += ntc_thermistor.o 109obj-$(CONFIG_SENSORS_NTC_THERMISTOR) += ntc_thermistor.o
109obj-$(CONFIG_SENSORS_PC87360) += pc87360.o 110obj-$(CONFIG_SENSORS_PC87360) += pc87360.o
110obj-$(CONFIG_SENSORS_PC87427) += pc87427.o 111obj-$(CONFIG_SENSORS_PC87427) += pc87427.o
diff --git a/drivers/hwmon/nct6775.c b/drivers/hwmon/nct6775.c
new file mode 100644
index 000000000000..f75cd8231534
--- /dev/null
+++ b/drivers/hwmon/nct6775.c
@@ -0,0 +1,1021 @@
1/*
2 * nct6775 - Driver for the hardware monitoring functionality of
3 * Nuvoton NCT677x Super-I/O chips
4 *
5 * Copyright (C) 2012 Guenter Roeck <linux@roeck-us.net>
6 *
7 * Derived from w83627ehf driver
8 * Copyright (C) 2005-2012 Jean Delvare <khali@linux-fr.org>
9 * Copyright (C) 2006 Yuan Mu (Winbond),
10 * Rudolf Marek <r.marek@assembler.cz>
11 * David Hubbard <david.c.hubbard@gmail.com>
12 * Daniel J Blueman <daniel.blueman@gmail.com>
13 * Copyright (C) 2010 Sheng-Yuan Huang (Nuvoton) (PS00)
14 *
15 * Shamelessly ripped from the w83627hf driver
16 * Copyright (C) 2003 Mark Studebaker
17 *
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 2 of the License, or
21 * (at your option) any later version.
22 *
23 * This program is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
27 *
28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, write to the Free Software
30 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
31 *
32 *
33 * Supports the following chips:
34 *
35 * Chip #vin #fan #pwm #temp chip IDs man ID
36 * nct6775f 9 4 3 6+3 0xb470 0xc1 0x5ca3
37 * nct6776f 9 5 3 6+3 0xc330 0xc1 0x5ca3
38 * nct6779d 15 5 5 2+6 0xc560 0xc1 0x5ca3
39 *
40 * #temp lists the number of monitored temperature sources (first value) plus
41 * the number of directly connectable temperature sensors (second value).
42 */
43
44#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
45
46#include <linux/module.h>
47#include <linux/init.h>
48#include <linux/slab.h>
49#include <linux/jiffies.h>
50#include <linux/platform_device.h>
51#include <linux/hwmon.h>
52#include <linux/hwmon-sysfs.h>
53#include <linux/hwmon-vid.h>
54#include <linux/err.h>
55#include <linux/mutex.h>
56#include <linux/acpi.h>
57#include <linux/io.h>
58#include "lm75.h"
59
60enum kinds { nct6775, nct6776, nct6779 };
61
62/* used to set data->name = nct6775_device_names[data->sio_kind] */
63static const char * const nct6775_device_names[] = {
64 "nct6775",
65 "nct6776",
66 "nct6779",
67};
68
69static unsigned short force_id;
70module_param(force_id, ushort, 0);
71MODULE_PARM_DESC(force_id, "Override the detected device ID");
72
73#define DRVNAME "nct6775"
74
75/*
76 * Super-I/O constants and functions
77 */
78
79#define NCT6775_LD_HWM 0x0b
80#define NCT6775_LD_VID 0x0d
81
82#define SIO_REG_LDSEL 0x07 /* Logical device select */
83#define SIO_REG_DEVID 0x20 /* Device ID (2 bytes) */
84#define SIO_REG_ENABLE 0x30 /* Logical device enable */
85#define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */
86
87#define SIO_NCT6775_ID 0xb470
88#define SIO_NCT6776_ID 0xc330
89#define SIO_NCT6779_ID 0xc560
90#define SIO_ID_MASK 0xFFF0
91
92static inline void
93superio_outb(int ioreg, int reg, int val)
94{
95 outb(reg, ioreg);
96 outb(val, ioreg + 1);
97}
98
99static inline int
100superio_inb(int ioreg, int reg)
101{
102 outb(reg, ioreg);
103 return inb(ioreg + 1);
104}
105
106static inline void
107superio_select(int ioreg, int ld)
108{
109 outb(SIO_REG_LDSEL, ioreg);
110 outb(ld, ioreg + 1);
111}
112
113static inline int
114superio_enter(int ioreg)
115{
116 /*
117 * Try to reserve <ioreg> and <ioreg + 1> for exclusive access.
118 */
119 if (!request_muxed_region(ioreg, 2, DRVNAME))
120 return -EBUSY;
121
122 outb(0x87, ioreg);
123 outb(0x87, ioreg);
124
125 return 0;
126}
127
128static inline void
129superio_exit(int ioreg)
130{
131 outb(0xaa, ioreg);
132 outb(0x02, ioreg);
133 outb(0x02, ioreg + 1);
134 release_region(ioreg, 2);
135}
136
137/*
138 * ISA constants
139 */
140
141#define IOREGION_ALIGNMENT (~7)
142#define IOREGION_OFFSET 5
143#define IOREGION_LENGTH 2
144#define ADDR_REG_OFFSET 0
145#define DATA_REG_OFFSET 1
146
147#define NCT6775_REG_BANK 0x4E
148#define NCT6775_REG_CONFIG 0x40
149
150/*
151 * Not currently used:
152 * REG_MAN_ID has the value 0x5ca3 for all supported chips.
153 * REG_CHIP_ID == 0x88/0xa1/0xc1 depending on chip model.
154 * REG_MAN_ID is at port 0x4f
155 * REG_CHIP_ID is at port 0x58
156 */
157
158#define NUM_REG_ALARM 4 /* Max number of alarm registers */
159
160/* Common and NCT6775 specific data */
161
162/* Voltage min/max registers for nr=7..14 are in bank 5 */
163
164static const u16 NCT6775_REG_IN_MAX[] = {
165 0x2b, 0x2d, 0x2f, 0x31, 0x33, 0x35, 0x37, 0x554, 0x556, 0x558, 0x55a,
166 0x55c, 0x55e, 0x560, 0x562 };
167static const u16 NCT6775_REG_IN_MIN[] = {
168 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x555, 0x557, 0x559, 0x55b,
169 0x55d, 0x55f, 0x561, 0x563 };
170static const u16 NCT6775_REG_IN[] = {
171 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x550, 0x551, 0x552
172};
173
174#define NCT6775_REG_VBAT 0x5D
175
176static const u16 NCT6775_REG_ALARM[NUM_REG_ALARM] = { 0x459, 0x45A, 0x45B };
177
178/* 0..15 voltages, 16..23 fans, 24..31 temperatures */
179
180static const s8 NCT6775_ALARM_BITS[] = {
181 0, 1, 2, 3, 8, 21, 20, 16, /* in0.. in7 */
182 17, -1, -1, -1, -1, -1, -1, /* in8..in14 */
183 -1, /* unused */
184 6, 7, 11, 10, 23, /* fan1..fan5 */
185 -1, -1, -1, /* unused */
186 4, 5, 13, -1, -1, -1, /* temp1..temp6 */
187 12, -1 }; /* intrusion0, intrusion1 */
188
189/* NCT6776 specific data */
190
191static const s8 NCT6776_ALARM_BITS[] = {
192 0, 1, 2, 3, 8, 21, 20, 16, /* in0.. in7 */
193 17, -1, -1, -1, -1, -1, -1, /* in8..in14 */
194 -1, /* unused */
195 6, 7, 11, 10, 23, /* fan1..fan5 */
196 -1, -1, -1, /* unused */
197 4, 5, 13, -1, -1, -1, /* temp1..temp6 */
198 12, 9 }; /* intrusion0, intrusion1 */
199
200/* NCT6779 specific data */
201
202static const u16 NCT6779_REG_IN[] = {
203 0x480, 0x481, 0x482, 0x483, 0x484, 0x485, 0x486, 0x487,
204 0x488, 0x489, 0x48a, 0x48b, 0x48c, 0x48d, 0x48e };
205
206static const u16 NCT6779_REG_ALARM[NUM_REG_ALARM] = {
207 0x459, 0x45A, 0x45B, 0x568 };
208
209static const s8 NCT6779_ALARM_BITS[] = {
210 0, 1, 2, 3, 8, 21, 20, 16, /* in0.. in7 */
211 17, 24, 25, 26, 27, 28, 29, /* in8..in14 */
212 -1, /* unused */
213 6, 7, 11, 10, 23, /* fan1..fan5 */
214 -1, -1, -1, /* unused */
215 4, 5, 13, -1, -1, -1, /* temp1..temp6 */
216 12, 9 }; /* intrusion0, intrusion1 */
217
218/*
219 * Conversions
220 */
221
222/*
223 * Some of the voltage inputs have internal scaling, the tables below
224 * contain 8 (the ADC LSB in mV) * scaling factor * 100
225 */
226static const u16 scale_in[15] = {
227 800, 800, 1600, 1600, 800, 800, 800, 1600, 1600, 800, 800, 800, 800,
228 800, 800
229};
230
231static inline long in_from_reg(u8 reg, u8 nr)
232{
233 return DIV_ROUND_CLOSEST(reg * scale_in[nr], 100);
234}
235
236static inline u8 in_to_reg(u32 val, u8 nr)
237{
238 return clamp_val(DIV_ROUND_CLOSEST(val * 100, scale_in[nr]), 0, 255);
239}
240
241/*
242 * Data structures and manipulation thereof
243 */
244
245struct nct6775_data {
246 int addr; /* IO base of hw monitor block */
247 enum kinds kind;
248 const char *name;
249
250 struct device *hwmon_dev;
251 struct mutex lock;
252
253 u16 REG_CONFIG;
254 u16 REG_VBAT;
255
256 const s8 *ALARM_BITS;
257
258 const u16 *REG_VIN;
259 const u16 *REG_IN_MINMAX[2];
260
261 const u16 *REG_ALARM;
262
263 struct mutex update_lock;
264 bool valid; /* true if following fields are valid */
265 unsigned long last_updated; /* In jiffies */
266
267 /* Register values */
268 u8 bank; /* current register bank */
269 u8 in_num; /* number of in inputs we have */
270 u8 in[15][3]; /* [0]=in, [1]=in_max, [2]=in_min */
271
272 u64 alarms;
273
274 u8 vid;
275 u8 vrm;
276
277 u16 have_in;
278};
279
280struct nct6775_sio_data {
281 int sioreg;
282 enum kinds kind;
283};
284
285static bool is_word_sized(struct nct6775_data *data, u16 reg)
286{
287 switch (data->kind) {
288 case nct6775:
289 return (((reg & 0xff00) == 0x100 ||
290 (reg & 0xff00) == 0x200) &&
291 ((reg & 0x00ff) == 0x50 ||
292 (reg & 0x00ff) == 0x53 ||
293 (reg & 0x00ff) == 0x55)) ||
294 (reg & 0xfff0) == 0x630 ||
295 reg == 0x640 || reg == 0x642 ||
296 reg == 0x662 ||
297 ((reg & 0xfff0) == 0x650 && (reg & 0x000f) >= 0x06) ||
298 reg == 0x73 || reg == 0x75 || reg == 0x77;
299 case nct6776:
300 return (((reg & 0xff00) == 0x100 ||
301 (reg & 0xff00) == 0x200) &&
302 ((reg & 0x00ff) == 0x50 ||
303 (reg & 0x00ff) == 0x53 ||
304 (reg & 0x00ff) == 0x55)) ||
305 (reg & 0xfff0) == 0x630 ||
306 reg == 0x402 ||
307 reg == 0x640 || reg == 0x642 ||
308 ((reg & 0xfff0) == 0x650 && (reg & 0x000f) >= 0x06) ||
309 reg == 0x73 || reg == 0x75 || reg == 0x77;
310 case nct6779:
311 return reg == 0x150 || reg == 0x153 || reg == 0x155 ||
312 ((reg & 0xfff0) == 0x4b0 && (reg & 0x000f) < 0x09) ||
313 reg == 0x402 ||
314 reg == 0x63a || reg == 0x63c || reg == 0x63e ||
315 reg == 0x640 || reg == 0x642 ||
316 reg == 0x73 || reg == 0x75 || reg == 0x77 || reg == 0x79 ||
317 reg == 0x7b;
318 }
319 return false;
320}
321
322/*
323 * On older chips, only registers 0x50-0x5f are banked.
324 * On more recent chips, all registers are banked.
325 * Assume that is the case and set the bank number for each access.
326 * Cache the bank number so it only needs to be set if it changes.
327 */
328static inline void nct6775_set_bank(struct nct6775_data *data, u16 reg)
329{
330 u8 bank = reg >> 8;
331 if (data->bank != bank) {
332 outb_p(NCT6775_REG_BANK, data->addr + ADDR_REG_OFFSET);
333 outb_p(bank, data->addr + DATA_REG_OFFSET);
334 data->bank = bank;
335 }
336}
337
338static u16 nct6775_read_value(struct nct6775_data *data, u16 reg)
339{
340 int res, word_sized = is_word_sized(data, reg);
341
342 mutex_lock(&data->lock);
343
344 nct6775_set_bank(data, reg);
345 outb_p(reg & 0xff, data->addr + ADDR_REG_OFFSET);
346 res = inb_p(data->addr + DATA_REG_OFFSET);
347 if (word_sized) {
348 outb_p((reg & 0xff) + 1,
349 data->addr + ADDR_REG_OFFSET);
350 res = (res << 8) + inb_p(data->addr + DATA_REG_OFFSET);
351 }
352
353 mutex_unlock(&data->lock);
354 return res;
355}
356
357static int nct6775_write_value(struct nct6775_data *data, u16 reg, u16 value)
358{
359 int word_sized = is_word_sized(data, reg);
360
361 mutex_lock(&data->lock);
362
363 nct6775_set_bank(data, reg);
364 outb_p(reg & 0xff, data->addr + ADDR_REG_OFFSET);
365 if (word_sized) {
366 outb_p(value >> 8, data->addr + DATA_REG_OFFSET);
367 outb_p((reg & 0xff) + 1,
368 data->addr + ADDR_REG_OFFSET);
369 }
370 outb_p(value & 0xff, data->addr + DATA_REG_OFFSET);
371
372 mutex_unlock(&data->lock);
373 return 0;
374}
375
376static struct nct6775_data *nct6775_update_device(struct device *dev)
377{
378 struct nct6775_data *data = dev_get_drvdata(dev);
379 int i;
380
381 mutex_lock(&data->update_lock);
382
383 if (time_after(jiffies, data->last_updated + HZ + HZ/2)
384 || !data->valid) {
385 /* Measured voltages and limits */
386 for (i = 0; i < data->in_num; i++) {
387 if (!(data->have_in & (1 << i)))
388 continue;
389
390 data->in[i][0] = nct6775_read_value(data,
391 data->REG_VIN[i]);
392 data->in[i][1] = nct6775_read_value(data,
393 data->REG_IN_MINMAX[0][i]);
394 data->in[i][2] = nct6775_read_value(data,
395 data->REG_IN_MINMAX[1][i]);
396 }
397
398 data->alarms = 0;
399 for (i = 0; i < NUM_REG_ALARM; i++) {
400 u8 alarm;
401 if (!data->REG_ALARM[i])
402 continue;
403 alarm = nct6775_read_value(data, data->REG_ALARM[i]);
404 data->alarms |= ((u64)alarm) << (i << 3);
405 }
406
407 data->last_updated = jiffies;
408 data->valid = true;
409 }
410
411 mutex_unlock(&data->update_lock);
412 return data;
413}
414
415/*
416 * Sysfs callback functions
417 */
418static ssize_t
419show_in_reg(struct device *dev, struct device_attribute *attr, char *buf)
420{
421 struct nct6775_data *data = nct6775_update_device(dev);
422 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
423 int nr = sattr->nr;
424 int index = sattr->index;
425 return sprintf(buf, "%ld\n", in_from_reg(data->in[nr][index], nr));
426}
427
428static ssize_t
429store_in_reg(struct device *dev, struct device_attribute *attr, const char *buf,
430 size_t count)
431{
432 struct nct6775_data *data = dev_get_drvdata(dev);
433 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
434 int nr = sattr->nr;
435 int index = sattr->index;
436 unsigned long val;
437 int err = kstrtoul(buf, 10, &val);
438 if (err < 0)
439 return err;
440 mutex_lock(&data->update_lock);
441 data->in[nr][index] = in_to_reg(val, nr);
442 nct6775_write_value(data, data->REG_IN_MINMAX[index-1][nr],
443 data->in[nr][index]);
444 mutex_unlock(&data->update_lock);
445 return count;
446}
447
448static ssize_t
449show_alarm(struct device *dev, struct device_attribute *attr, char *buf)
450{
451 struct nct6775_data *data = nct6775_update_device(dev);
452 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
453 int nr = data->ALARM_BITS[sattr->index];
454 return sprintf(buf, "%u\n",
455 (unsigned int)((data->alarms >> nr) & 0x01));
456}
457
458static SENSOR_DEVICE_ATTR_2(in0_input, S_IRUGO, show_in_reg, NULL, 0, 0);
459static SENSOR_DEVICE_ATTR_2(in1_input, S_IRUGO, show_in_reg, NULL, 1, 0);
460static SENSOR_DEVICE_ATTR_2(in2_input, S_IRUGO, show_in_reg, NULL, 2, 0);
461static SENSOR_DEVICE_ATTR_2(in3_input, S_IRUGO, show_in_reg, NULL, 3, 0);
462static SENSOR_DEVICE_ATTR_2(in4_input, S_IRUGO, show_in_reg, NULL, 4, 0);
463static SENSOR_DEVICE_ATTR_2(in5_input, S_IRUGO, show_in_reg, NULL, 5, 0);
464static SENSOR_DEVICE_ATTR_2(in6_input, S_IRUGO, show_in_reg, NULL, 6, 0);
465static SENSOR_DEVICE_ATTR_2(in7_input, S_IRUGO, show_in_reg, NULL, 7, 0);
466static SENSOR_DEVICE_ATTR_2(in8_input, S_IRUGO, show_in_reg, NULL, 8, 0);
467static SENSOR_DEVICE_ATTR_2(in9_input, S_IRUGO, show_in_reg, NULL, 9, 0);
468static SENSOR_DEVICE_ATTR_2(in10_input, S_IRUGO, show_in_reg, NULL, 10, 0);
469static SENSOR_DEVICE_ATTR_2(in11_input, S_IRUGO, show_in_reg, NULL, 11, 0);
470static SENSOR_DEVICE_ATTR_2(in12_input, S_IRUGO, show_in_reg, NULL, 12, 0);
471static SENSOR_DEVICE_ATTR_2(in13_input, S_IRUGO, show_in_reg, NULL, 13, 0);
472static SENSOR_DEVICE_ATTR_2(in14_input, S_IRUGO, show_in_reg, NULL, 14, 0);
473
474static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0);
475static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1);
476static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 2);
477static SENSOR_DEVICE_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, 3);
478static SENSOR_DEVICE_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, 4);
479static SENSOR_DEVICE_ATTR(in5_alarm, S_IRUGO, show_alarm, NULL, 5);
480static SENSOR_DEVICE_ATTR(in6_alarm, S_IRUGO, show_alarm, NULL, 6);
481static SENSOR_DEVICE_ATTR(in7_alarm, S_IRUGO, show_alarm, NULL, 7);
482static SENSOR_DEVICE_ATTR(in8_alarm, S_IRUGO, show_alarm, NULL, 8);
483static SENSOR_DEVICE_ATTR(in9_alarm, S_IRUGO, show_alarm, NULL, 9);
484static SENSOR_DEVICE_ATTR(in10_alarm, S_IRUGO, show_alarm, NULL, 10);
485static SENSOR_DEVICE_ATTR(in11_alarm, S_IRUGO, show_alarm, NULL, 11);
486static SENSOR_DEVICE_ATTR(in12_alarm, S_IRUGO, show_alarm, NULL, 12);
487static SENSOR_DEVICE_ATTR(in13_alarm, S_IRUGO, show_alarm, NULL, 13);
488static SENSOR_DEVICE_ATTR(in14_alarm, S_IRUGO, show_alarm, NULL, 14);
489
490static SENSOR_DEVICE_ATTR_2(in0_min, S_IWUSR | S_IRUGO, show_in_reg,
491 store_in_reg, 0, 1);
492static SENSOR_DEVICE_ATTR_2(in1_min, S_IWUSR | S_IRUGO, show_in_reg,
493 store_in_reg, 1, 1);
494static SENSOR_DEVICE_ATTR_2(in2_min, S_IWUSR | S_IRUGO, show_in_reg,
495 store_in_reg, 2, 1);
496static SENSOR_DEVICE_ATTR_2(in3_min, S_IWUSR | S_IRUGO, show_in_reg,
497 store_in_reg, 3, 1);
498static SENSOR_DEVICE_ATTR_2(in4_min, S_IWUSR | S_IRUGO, show_in_reg,
499 store_in_reg, 4, 1);
500static SENSOR_DEVICE_ATTR_2(in5_min, S_IWUSR | S_IRUGO, show_in_reg,
501 store_in_reg, 5, 1);
502static SENSOR_DEVICE_ATTR_2(in6_min, S_IWUSR | S_IRUGO, show_in_reg,
503 store_in_reg, 6, 1);
504static SENSOR_DEVICE_ATTR_2(in7_min, S_IWUSR | S_IRUGO, show_in_reg,
505 store_in_reg, 7, 1);
506static SENSOR_DEVICE_ATTR_2(in8_min, S_IWUSR | S_IRUGO, show_in_reg,
507 store_in_reg, 8, 1);
508static SENSOR_DEVICE_ATTR_2(in9_min, S_IWUSR | S_IRUGO, show_in_reg,
509 store_in_reg, 9, 1);
510static SENSOR_DEVICE_ATTR_2(in10_min, S_IWUSR | S_IRUGO, show_in_reg,
511 store_in_reg, 10, 1);
512static SENSOR_DEVICE_ATTR_2(in11_min, S_IWUSR | S_IRUGO, show_in_reg,
513 store_in_reg, 11, 1);
514static SENSOR_DEVICE_ATTR_2(in12_min, S_IWUSR | S_IRUGO, show_in_reg,
515 store_in_reg, 12, 1);
516static SENSOR_DEVICE_ATTR_2(in13_min, S_IWUSR | S_IRUGO, show_in_reg,
517 store_in_reg, 13, 1);
518static SENSOR_DEVICE_ATTR_2(in14_min, S_IWUSR | S_IRUGO, show_in_reg,
519 store_in_reg, 14, 1);
520
521static SENSOR_DEVICE_ATTR_2(in0_max, S_IWUSR | S_IRUGO, show_in_reg,
522 store_in_reg, 0, 2);
523static SENSOR_DEVICE_ATTR_2(in1_max, S_IWUSR | S_IRUGO, show_in_reg,
524 store_in_reg, 1, 2);
525static SENSOR_DEVICE_ATTR_2(in2_max, S_IWUSR | S_IRUGO, show_in_reg,
526 store_in_reg, 2, 2);
527static SENSOR_DEVICE_ATTR_2(in3_max, S_IWUSR | S_IRUGO, show_in_reg,
528 store_in_reg, 3, 2);
529static SENSOR_DEVICE_ATTR_2(in4_max, S_IWUSR | S_IRUGO, show_in_reg,
530 store_in_reg, 4, 2);
531static SENSOR_DEVICE_ATTR_2(in5_max, S_IWUSR | S_IRUGO, show_in_reg,
532 store_in_reg, 5, 2);
533static SENSOR_DEVICE_ATTR_2(in6_max, S_IWUSR | S_IRUGO, show_in_reg,
534 store_in_reg, 6, 2);
535static SENSOR_DEVICE_ATTR_2(in7_max, S_IWUSR | S_IRUGO, show_in_reg,
536 store_in_reg, 7, 2);
537static SENSOR_DEVICE_ATTR_2(in8_max, S_IWUSR | S_IRUGO, show_in_reg,
538 store_in_reg, 8, 2);
539static SENSOR_DEVICE_ATTR_2(in9_max, S_IWUSR | S_IRUGO, show_in_reg,
540 store_in_reg, 9, 2);
541static SENSOR_DEVICE_ATTR_2(in10_max, S_IWUSR | S_IRUGO, show_in_reg,
542 store_in_reg, 10, 2);
543static SENSOR_DEVICE_ATTR_2(in11_max, S_IWUSR | S_IRUGO, show_in_reg,
544 store_in_reg, 11, 2);
545static SENSOR_DEVICE_ATTR_2(in12_max, S_IWUSR | S_IRUGO, show_in_reg,
546 store_in_reg, 12, 2);
547static SENSOR_DEVICE_ATTR_2(in13_max, S_IWUSR | S_IRUGO, show_in_reg,
548 store_in_reg, 13, 2);
549static SENSOR_DEVICE_ATTR_2(in14_max, S_IWUSR | S_IRUGO, show_in_reg,
550 store_in_reg, 14, 2);
551
552static struct attribute *nct6775_attributes_in[15][5] = {
553 {
554 &sensor_dev_attr_in0_input.dev_attr.attr,
555 &sensor_dev_attr_in0_min.dev_attr.attr,
556 &sensor_dev_attr_in0_max.dev_attr.attr,
557 &sensor_dev_attr_in0_alarm.dev_attr.attr,
558 NULL
559 },
560 {
561 &sensor_dev_attr_in1_input.dev_attr.attr,
562 &sensor_dev_attr_in1_min.dev_attr.attr,
563 &sensor_dev_attr_in1_max.dev_attr.attr,
564 &sensor_dev_attr_in1_alarm.dev_attr.attr,
565 NULL
566 },
567 {
568 &sensor_dev_attr_in2_input.dev_attr.attr,
569 &sensor_dev_attr_in2_min.dev_attr.attr,
570 &sensor_dev_attr_in2_max.dev_attr.attr,
571 &sensor_dev_attr_in2_alarm.dev_attr.attr,
572 NULL
573 },
574 {
575 &sensor_dev_attr_in3_input.dev_attr.attr,
576 &sensor_dev_attr_in3_min.dev_attr.attr,
577 &sensor_dev_attr_in3_max.dev_attr.attr,
578 &sensor_dev_attr_in3_alarm.dev_attr.attr,
579 NULL
580 },
581 {
582 &sensor_dev_attr_in4_input.dev_attr.attr,
583 &sensor_dev_attr_in4_min.dev_attr.attr,
584 &sensor_dev_attr_in4_max.dev_attr.attr,
585 &sensor_dev_attr_in4_alarm.dev_attr.attr,
586 NULL
587 },
588 {
589 &sensor_dev_attr_in5_input.dev_attr.attr,
590 &sensor_dev_attr_in5_min.dev_attr.attr,
591 &sensor_dev_attr_in5_max.dev_attr.attr,
592 &sensor_dev_attr_in5_alarm.dev_attr.attr,
593 NULL
594 },
595 {
596 &sensor_dev_attr_in6_input.dev_attr.attr,
597 &sensor_dev_attr_in6_min.dev_attr.attr,
598 &sensor_dev_attr_in6_max.dev_attr.attr,
599 &sensor_dev_attr_in6_alarm.dev_attr.attr,
600 NULL
601 },
602 {
603 &sensor_dev_attr_in7_input.dev_attr.attr,
604 &sensor_dev_attr_in7_min.dev_attr.attr,
605 &sensor_dev_attr_in7_max.dev_attr.attr,
606 &sensor_dev_attr_in7_alarm.dev_attr.attr,
607 NULL
608 },
609 {
610 &sensor_dev_attr_in8_input.dev_attr.attr,
611 &sensor_dev_attr_in8_min.dev_attr.attr,
612 &sensor_dev_attr_in8_max.dev_attr.attr,
613 &sensor_dev_attr_in8_alarm.dev_attr.attr,
614 NULL
615 },
616 {
617 &sensor_dev_attr_in9_input.dev_attr.attr,
618 &sensor_dev_attr_in9_min.dev_attr.attr,
619 &sensor_dev_attr_in9_max.dev_attr.attr,
620 &sensor_dev_attr_in9_alarm.dev_attr.attr,
621 NULL
622 },
623 {
624 &sensor_dev_attr_in10_input.dev_attr.attr,
625 &sensor_dev_attr_in10_min.dev_attr.attr,
626 &sensor_dev_attr_in10_max.dev_attr.attr,
627 &sensor_dev_attr_in10_alarm.dev_attr.attr,
628 NULL
629 },
630 {
631 &sensor_dev_attr_in11_input.dev_attr.attr,
632 &sensor_dev_attr_in11_min.dev_attr.attr,
633 &sensor_dev_attr_in11_max.dev_attr.attr,
634 &sensor_dev_attr_in11_alarm.dev_attr.attr,
635 NULL
636 },
637 {
638 &sensor_dev_attr_in12_input.dev_attr.attr,
639 &sensor_dev_attr_in12_min.dev_attr.attr,
640 &sensor_dev_attr_in12_max.dev_attr.attr,
641 &sensor_dev_attr_in12_alarm.dev_attr.attr,
642 NULL
643 },
644 {
645 &sensor_dev_attr_in13_input.dev_attr.attr,
646 &sensor_dev_attr_in13_min.dev_attr.attr,
647 &sensor_dev_attr_in13_max.dev_attr.attr,
648 &sensor_dev_attr_in13_alarm.dev_attr.attr,
649 NULL
650 },
651 {
652 &sensor_dev_attr_in14_input.dev_attr.attr,
653 &sensor_dev_attr_in14_min.dev_attr.attr,
654 &sensor_dev_attr_in14_max.dev_attr.attr,
655 &sensor_dev_attr_in14_alarm.dev_attr.attr,
656 NULL
657 },
658};
659
660static const struct attribute_group nct6775_group_in[15] = {
661 { .attrs = nct6775_attributes_in[0] },
662 { .attrs = nct6775_attributes_in[1] },
663 { .attrs = nct6775_attributes_in[2] },
664 { .attrs = nct6775_attributes_in[3] },
665 { .attrs = nct6775_attributes_in[4] },
666 { .attrs = nct6775_attributes_in[5] },
667 { .attrs = nct6775_attributes_in[6] },
668 { .attrs = nct6775_attributes_in[7] },
669 { .attrs = nct6775_attributes_in[8] },
670 { .attrs = nct6775_attributes_in[9] },
671 { .attrs = nct6775_attributes_in[10] },
672 { .attrs = nct6775_attributes_in[11] },
673 { .attrs = nct6775_attributes_in[12] },
674 { .attrs = nct6775_attributes_in[13] },
675 { .attrs = nct6775_attributes_in[14] },
676};
677
678static ssize_t
679show_name(struct device *dev, struct device_attribute *attr, char *buf)
680{
681 struct nct6775_data *data = dev_get_drvdata(dev);
682
683 return sprintf(buf, "%s\n", data->name);
684}
685
686static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
687
688static ssize_t
689show_vid(struct device *dev, struct device_attribute *attr, char *buf)
690{
691 struct nct6775_data *data = dev_get_drvdata(dev);
692 return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm));
693}
694
695static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL);
696
697/*
698 * Driver and device management
699 */
700
701static void nct6775_device_remove_files(struct device *dev)
702{
703 /*
704 * some entries in the following arrays may not have been used in
705 * device_create_file(), but device_remove_file() will ignore them
706 */
707 int i;
708 struct nct6775_data *data = dev_get_drvdata(dev);
709
710 for (i = 0; i < data->in_num; i++)
711 sysfs_remove_group(&dev->kobj, &nct6775_group_in[i]);
712
713 device_remove_file(dev, &dev_attr_name);
714 device_remove_file(dev, &dev_attr_cpu0_vid);
715}
716
717/* Get the monitoring functions started */
718static inline void nct6775_init_device(struct nct6775_data *data)
719{
720 u8 tmp;
721
722 /* Start monitoring if needed */
723 if (data->REG_CONFIG) {
724 tmp = nct6775_read_value(data, data->REG_CONFIG);
725 if (!(tmp & 0x01))
726 nct6775_write_value(data, data->REG_CONFIG, tmp | 0x01);
727 }
728
729 /* Enable VBAT monitoring if needed */
730 tmp = nct6775_read_value(data, data->REG_VBAT);
731 if (!(tmp & 0x01))
732 nct6775_write_value(data, data->REG_VBAT, tmp | 0x01);
733}
734
735static int nct6775_probe(struct platform_device *pdev)
736{
737 struct device *dev = &pdev->dev;
738 struct nct6775_sio_data *sio_data = dev->platform_data;
739 struct nct6775_data *data;
740 struct resource *res;
741 int i, err = 0;
742
743 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
744 if (!devm_request_region(&pdev->dev, res->start, IOREGION_LENGTH,
745 DRVNAME))
746 return -EBUSY;
747
748 data = devm_kzalloc(&pdev->dev, sizeof(struct nct6775_data),
749 GFP_KERNEL);
750 if (!data)
751 return -ENOMEM;
752
753 data->kind = sio_data->kind;
754 data->addr = res->start;
755 mutex_init(&data->lock);
756 mutex_init(&data->update_lock);
757 data->name = nct6775_device_names[data->kind];
758 data->bank = 0xff; /* Force initial bank selection */
759 platform_set_drvdata(pdev, data);
760
761 switch (data->kind) {
762 case nct6775:
763 data->in_num = 9;
764
765 data->ALARM_BITS = NCT6775_ALARM_BITS;
766
767 data->REG_CONFIG = NCT6775_REG_CONFIG;
768 data->REG_VBAT = NCT6775_REG_VBAT;
769 data->REG_VIN = NCT6775_REG_IN;
770 data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN;
771 data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX;
772 data->REG_ALARM = NCT6775_REG_ALARM;
773 break;
774 case nct6776:
775 data->in_num = 9;
776
777 data->ALARM_BITS = NCT6776_ALARM_BITS;
778
779 data->REG_CONFIG = NCT6775_REG_CONFIG;
780 data->REG_VBAT = NCT6775_REG_VBAT;
781 data->REG_VIN = NCT6775_REG_IN;
782 data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN;
783 data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX;
784 data->REG_ALARM = NCT6775_REG_ALARM;
785 break;
786 case nct6779:
787 data->in_num = 15;
788
789 data->ALARM_BITS = NCT6779_ALARM_BITS;
790
791 data->REG_CONFIG = NCT6775_REG_CONFIG;
792 data->REG_VBAT = NCT6775_REG_VBAT;
793 data->REG_VIN = NCT6779_REG_IN;
794 data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN;
795 data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX;
796 data->REG_ALARM = NCT6779_REG_ALARM;
797 break;
798 default:
799 return -ENODEV;
800 }
801 data->have_in = (1 << data->in_num) - 1;
802
803 /* Initialize the chip */
804 nct6775_init_device(data);
805
806 data->vrm = vid_which_vrm();
807 err = superio_enter(sio_data->sioreg);
808 if (err)
809 return err;
810
811 /*
812 * Read VID value
813 * We can get the VID input values directly at logical device D 0xe3.
814 */
815 superio_select(sio_data->sioreg, NCT6775_LD_VID);
816 data->vid = superio_inb(sio_data->sioreg, 0xe3);
817 superio_exit(sio_data->sioreg);
818
819 err = device_create_file(dev, &dev_attr_cpu0_vid);
820 if (err)
821 return err;
822
823 for (i = 0; i < data->in_num; i++) {
824 if (!(data->have_in & (1 << i)))
825 continue;
826 err = sysfs_create_group(&dev->kobj, &nct6775_group_in[i]);
827 if (err)
828 goto exit_remove;
829 }
830
831 err = device_create_file(dev, &dev_attr_name);
832 if (err)
833 goto exit_remove;
834
835 data->hwmon_dev = hwmon_device_register(dev);
836 if (IS_ERR(data->hwmon_dev)) {
837 err = PTR_ERR(data->hwmon_dev);
838 goto exit_remove;
839 }
840
841 return 0;
842
843exit_remove:
844 nct6775_device_remove_files(dev);
845 return err;
846}
847
848static int nct6775_remove(struct platform_device *pdev)
849{
850 struct nct6775_data *data = platform_get_drvdata(pdev);
851
852 hwmon_device_unregister(data->hwmon_dev);
853 nct6775_device_remove_files(&pdev->dev);
854
855 return 0;
856}
857
858static struct platform_driver nct6775_driver = {
859 .driver = {
860 .owner = THIS_MODULE,
861 .name = DRVNAME,
862 },
863 .probe = nct6775_probe,
864 .remove = nct6775_remove,
865};
866
867/* nct6775_find() looks for a '627 in the Super-I/O config space */
868static int __init nct6775_find(int sioaddr, unsigned short *addr,
869 struct nct6775_sio_data *sio_data)
870{
871 static const char sio_name_NCT6775[] __initconst = "NCT6775F";
872 static const char sio_name_NCT6776[] __initconst = "NCT6776F";
873 static const char sio_name_NCT6779[] __initconst = "NCT6779D";
874
875 u16 val;
876 const char *sio_name;
877 int err;
878
879 err = superio_enter(sioaddr);
880 if (err)
881 return err;
882
883 if (force_id)
884 val = force_id;
885 else
886 val = (superio_inb(sioaddr, SIO_REG_DEVID) << 8)
887 | superio_inb(sioaddr, SIO_REG_DEVID + 1);
888 switch (val & SIO_ID_MASK) {
889 case SIO_NCT6775_ID:
890 sio_data->kind = nct6775;
891 sio_name = sio_name_NCT6775;
892 break;
893 case SIO_NCT6776_ID:
894 sio_data->kind = nct6776;
895 sio_name = sio_name_NCT6776;
896 break;
897 case SIO_NCT6779_ID:
898 sio_data->kind = nct6779;
899 sio_name = sio_name_NCT6779;
900 break;
901 default:
902 if (val != 0xffff)
903 pr_debug("unsupported chip ID: 0x%04x\n", val);
904 superio_exit(sioaddr);
905 return -ENODEV;
906 }
907
908 /* We have a known chip, find the HWM I/O address */
909 superio_select(sioaddr, NCT6775_LD_HWM);
910 val = (superio_inb(sioaddr, SIO_REG_ADDR) << 8)
911 | superio_inb(sioaddr, SIO_REG_ADDR + 1);
912 *addr = val & IOREGION_ALIGNMENT;
913 if (*addr == 0) {
914 pr_err("Refusing to enable a Super-I/O device with a base I/O port 0\n");
915 superio_exit(sioaddr);
916 return -ENODEV;
917 }
918
919 /* Activate logical device if needed */
920 val = superio_inb(sioaddr, SIO_REG_ENABLE);
921 if (!(val & 0x01)) {
922 pr_warn("Forcibly enabling Super-I/O. Sensor is probably unusable.\n");
923 superio_outb(sioaddr, SIO_REG_ENABLE, val | 0x01);
924 }
925
926 superio_exit(sioaddr);
927 pr_info("Found %s chip at %#x\n", sio_name, *addr);
928 sio_data->sioreg = sioaddr;
929
930 return 0;
931}
932
933/*
934 * when Super-I/O functions move to a separate file, the Super-I/O
935 * bus will manage the lifetime of the device and this module will only keep
936 * track of the nct6775 driver. But since we platform_device_alloc(), we
937 * must keep track of the device
938 */
939static struct platform_device *pdev;
940
941static int __init sensors_nct6775_init(void)
942{
943 int err;
944 unsigned short address;
945 struct resource res;
946 struct nct6775_sio_data sio_data;
947
948 /*
949 * initialize sio_data->kind and sio_data->sioreg.
950 *
951 * when Super-I/O functions move to a separate file, the Super-I/O
952 * driver will probe 0x2e and 0x4e and auto-detect the presence of a
953 * nct6775 hardware monitor, and call probe()
954 */
955 if (nct6775_find(0x2e, &address, &sio_data) &&
956 nct6775_find(0x4e, &address, &sio_data))
957 return -ENODEV;
958
959 err = platform_driver_register(&nct6775_driver);
960 if (err)
961 goto exit;
962
963 pdev = platform_device_alloc(DRVNAME, address);
964 if (!pdev) {
965 err = -ENOMEM;
966 pr_err("Device allocation failed\n");
967 goto exit_unregister;
968 }
969
970 err = platform_device_add_data(pdev, &sio_data,
971 sizeof(struct nct6775_sio_data));
972 if (err) {
973 pr_err("Platform data allocation failed\n");
974 goto exit_device_put;
975 }
976
977 memset(&res, 0, sizeof(res));
978 res.name = DRVNAME;
979 res.start = address + IOREGION_OFFSET;
980 res.end = address + IOREGION_OFFSET + IOREGION_LENGTH - 1;
981 res.flags = IORESOURCE_IO;
982
983 err = acpi_check_resource_conflict(&res);
984 if (err)
985 goto exit_device_put;
986
987 err = platform_device_add_resources(pdev, &res, 1);
988 if (err) {
989 pr_err("Device resource addition failed (%d)\n", err);
990 goto exit_device_put;
991 }
992
993 /* platform_device_add calls probe() */
994 err = platform_device_add(pdev);
995 if (err) {
996 pr_err("Device addition failed (%d)\n", err);
997 goto exit_device_put;
998 }
999
1000 return 0;
1001
1002exit_device_put:
1003 platform_device_put(pdev);
1004exit_unregister:
1005 platform_driver_unregister(&nct6775_driver);
1006exit:
1007 return err;
1008}
1009
1010static void __exit sensors_nct6775_exit(void)
1011{
1012 platform_device_unregister(pdev);
1013 platform_driver_unregister(&nct6775_driver);
1014}
1015
1016MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>");
1017MODULE_DESCRIPTION("NCT6775F/NCT6776F/NCT6779D driver");
1018MODULE_LICENSE("GPL");
1019
1020module_init(sensors_nct6775_init);
1021module_exit(sensors_nct6775_exit);