hwmon: Provide managed hwmon registration
[linux-block.git] / drivers / hwmon / nct6775.c
CommitLineData
9de2e2e8
GR
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
6c009501 36 * nct6106d 9 3 3 6+3 0xc450 0xc1 0x5ca3
9de2e2e8
GR
37 * nct6775f 9 4 3 6+3 0xb470 0xc1 0x5ca3
38 * nct6776f 9 5 3 6+3 0xc330 0xc1 0x5ca3
39 * nct6779d 15 5 5 2+6 0xc560 0xc1 0x5ca3
578ab5f0 40 * nct6791d 15 6 6 2+6 0xc800 0xc1 0x5ca3
9de2e2e8
GR
41 *
42 * #temp lists the number of monitored temperature sources (first value) plus
43 * the number of directly connectable temperature sensors (second value).
44 */
45
46#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
47
48#include <linux/module.h>
49#include <linux/init.h>
50#include <linux/slab.h>
51#include <linux/jiffies.h>
52#include <linux/platform_device.h>
53#include <linux/hwmon.h>
54#include <linux/hwmon-sysfs.h>
55#include <linux/hwmon-vid.h>
56#include <linux/err.h>
57#include <linux/mutex.h>
58#include <linux/acpi.h>
59#include <linux/io.h>
60#include "lm75.h"
61
aa136e5d
GR
62#define USE_ALTERNATE
63
578ab5f0 64enum kinds { nct6106, nct6775, nct6776, nct6779, nct6791 };
9de2e2e8
GR
65
66/* used to set data->name = nct6775_device_names[data->sio_kind] */
67static const char * const nct6775_device_names[] = {
6c009501 68 "nct6106",
9de2e2e8
GR
69 "nct6775",
70 "nct6776",
71 "nct6779",
578ab5f0 72 "nct6791",
9de2e2e8
GR
73};
74
75static unsigned short force_id;
76module_param(force_id, ushort, 0);
77MODULE_PARM_DESC(force_id, "Override the detected device ID");
78
47ece964
GR
79static unsigned short fan_debounce;
80module_param(fan_debounce, ushort, 0);
81MODULE_PARM_DESC(fan_debounce, "Enable debouncing for fan RPM signal");
82
9de2e2e8
GR
83#define DRVNAME "nct6775"
84
85/*
86 * Super-I/O constants and functions
87 */
88
a6bd5878 89#define NCT6775_LD_ACPI 0x0a
9de2e2e8
GR
90#define NCT6775_LD_HWM 0x0b
91#define NCT6775_LD_VID 0x0d
92
93#define SIO_REG_LDSEL 0x07 /* Logical device select */
94#define SIO_REG_DEVID 0x20 /* Device ID (2 bytes) */
95#define SIO_REG_ENABLE 0x30 /* Logical device enable */
96#define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */
97
6c009501 98#define SIO_NCT6106_ID 0xc450
9de2e2e8
GR
99#define SIO_NCT6775_ID 0xb470
100#define SIO_NCT6776_ID 0xc330
101#define SIO_NCT6779_ID 0xc560
578ab5f0 102#define SIO_NCT6791_ID 0xc800
9de2e2e8
GR
103#define SIO_ID_MASK 0xFFF0
104
77eb5b37
GR
105enum pwm_enable { off, manual, thermal_cruise, speed_cruise, sf3, sf4 };
106
9de2e2e8
GR
107static inline void
108superio_outb(int ioreg, int reg, int val)
109{
110 outb(reg, ioreg);
111 outb(val, ioreg + 1);
112}
113
114static inline int
115superio_inb(int ioreg, int reg)
116{
117 outb(reg, ioreg);
118 return inb(ioreg + 1);
119}
120
121static inline void
122superio_select(int ioreg, int ld)
123{
124 outb(SIO_REG_LDSEL, ioreg);
125 outb(ld, ioreg + 1);
126}
127
128static inline int
129superio_enter(int ioreg)
130{
131 /*
132 * Try to reserve <ioreg> and <ioreg + 1> for exclusive access.
133 */
134 if (!request_muxed_region(ioreg, 2, DRVNAME))
135 return -EBUSY;
136
137 outb(0x87, ioreg);
138 outb(0x87, ioreg);
139
140 return 0;
141}
142
143static inline void
144superio_exit(int ioreg)
145{
146 outb(0xaa, ioreg);
147 outb(0x02, ioreg);
148 outb(0x02, ioreg + 1);
149 release_region(ioreg, 2);
150}
151
152/*
153 * ISA constants
154 */
155
156#define IOREGION_ALIGNMENT (~7)
157#define IOREGION_OFFSET 5
158#define IOREGION_LENGTH 2
159#define ADDR_REG_OFFSET 0
160#define DATA_REG_OFFSET 1
161
162#define NCT6775_REG_BANK 0x4E
163#define NCT6775_REG_CONFIG 0x40
164
165/*
166 * Not currently used:
167 * REG_MAN_ID has the value 0x5ca3 for all supported chips.
168 * REG_CHIP_ID == 0x88/0xa1/0xc1 depending on chip model.
169 * REG_MAN_ID is at port 0x4f
170 * REG_CHIP_ID is at port 0x58
171 */
172
aa136e5d
GR
173#define NUM_TEMP 10 /* Max number of temp attribute sets w/ limits*/
174#define NUM_TEMP_FIXED 6 /* Max number of fixed temp attribute sets */
175
6c009501 176#define NUM_REG_ALARM 7 /* Max number of alarm registers */
30846993 177#define NUM_REG_BEEP 5 /* Max number of beep registers */
9de2e2e8 178
578ab5f0
DB
179#define NUM_FAN 6
180
9de2e2e8
GR
181/* Common and NCT6775 specific data */
182
183/* Voltage min/max registers for nr=7..14 are in bank 5 */
184
185static const u16 NCT6775_REG_IN_MAX[] = {
186 0x2b, 0x2d, 0x2f, 0x31, 0x33, 0x35, 0x37, 0x554, 0x556, 0x558, 0x55a,
187 0x55c, 0x55e, 0x560, 0x562 };
188static const u16 NCT6775_REG_IN_MIN[] = {
189 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x555, 0x557, 0x559, 0x55b,
190 0x55d, 0x55f, 0x561, 0x563 };
191static const u16 NCT6775_REG_IN[] = {
192 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x550, 0x551, 0x552
193};
194
195#define NCT6775_REG_VBAT 0x5D
aa136e5d 196#define NCT6775_REG_DIODE 0x5E
6c009501 197#define NCT6775_DIODE_MASK 0x02
9de2e2e8 198
1c65dc36
GR
199#define NCT6775_REG_FANDIV1 0x506
200#define NCT6775_REG_FANDIV2 0x507
201
47ece964
GR
202#define NCT6775_REG_CR_FAN_DEBOUNCE 0xf0
203
9de2e2e8
GR
204static const u16 NCT6775_REG_ALARM[NUM_REG_ALARM] = { 0x459, 0x45A, 0x45B };
205
30846993 206/* 0..15 voltages, 16..23 fans, 24..29 temperatures, 30..31 intrusion */
9de2e2e8
GR
207
208static const s8 NCT6775_ALARM_BITS[] = {
209 0, 1, 2, 3, 8, 21, 20, 16, /* in0.. in7 */
210 17, -1, -1, -1, -1, -1, -1, /* in8..in14 */
211 -1, /* unused */
41fa9a94 212 6, 7, 11, -1, -1, /* fan1..fan5 */
9de2e2e8
GR
213 -1, -1, -1, /* unused */
214 4, 5, 13, -1, -1, -1, /* temp1..temp6 */
215 12, -1 }; /* intrusion0, intrusion1 */
216
1c65dc36 217#define FAN_ALARM_BASE 16
aa136e5d 218#define TEMP_ALARM_BASE 24
a6bd5878
GR
219#define INTRUSION_ALARM_BASE 30
220
30846993
GR
221static const u16 NCT6775_REG_BEEP[NUM_REG_BEEP] = { 0x56, 0x57, 0x453, 0x4e };
222
223/*
224 * 0..14 voltages, 15 global beep enable, 16..23 fans, 24..29 temperatures,
225 * 30..31 intrusion
226 */
227static const s8 NCT6775_BEEP_BITS[] = {
228 0, 1, 2, 3, 8, 9, 10, 16, /* in0.. in7 */
229 17, -1, -1, -1, -1, -1, -1, /* in8..in14 */
230 21, /* global beep enable */
231 6, 7, 11, 28, -1, /* fan1..fan5 */
232 -1, -1, -1, /* unused */
233 4, 5, 13, -1, -1, -1, /* temp1..temp6 */
234 12, -1 }; /* intrusion0, intrusion1 */
235
236#define BEEP_ENABLE_BASE 15
237
a6bd5878
GR
238static const u8 NCT6775_REG_CR_CASEOPEN_CLR[] = { 0xe6, 0xee };
239static const u8 NCT6775_CR_CASEOPEN_CLR_MASK[] = { 0x20, 0x01 };
240
77eb5b37
GR
241/* DC or PWM output fan configuration */
242static const u8 NCT6775_REG_PWM_MODE[] = { 0x04, 0x04, 0x12 };
243static const u8 NCT6775_PWM_MODE_MASK[] = { 0x01, 0x02, 0x01 };
244
cdcaeceb 245/* Advanced Fan control, some values are common for all fans */
77eb5b37 246
578ab5f0
DB
247static const u16 NCT6775_REG_TARGET[] = {
248 0x101, 0x201, 0x301, 0x801, 0x901, 0xa01 };
249static const u16 NCT6775_REG_FAN_MODE[] = {
250 0x102, 0x202, 0x302, 0x802, 0x902, 0xa02 };
cdcaeceb 251static const u16 NCT6775_REG_FAN_STEP_DOWN_TIME[] = {
578ab5f0 252 0x103, 0x203, 0x303, 0x803, 0x903, 0xa03 };
cdcaeceb 253static const u16 NCT6775_REG_FAN_STEP_UP_TIME[] = {
578ab5f0 254 0x104, 0x204, 0x304, 0x804, 0x904, 0xa04 };
cdcaeceb 255static const u16 NCT6775_REG_FAN_STOP_OUTPUT[] = {
578ab5f0
DB
256 0x105, 0x205, 0x305, 0x805, 0x905, 0xa05 };
257static const u16 NCT6775_REG_FAN_START_OUTPUT[] = {
258 0x106, 0x206, 0x306, 0x806, 0x906, 0xa06 };
cdcaeceb
GR
259static const u16 NCT6775_REG_FAN_MAX_OUTPUT[] = { 0x10a, 0x20a, 0x30a };
260static const u16 NCT6775_REG_FAN_STEP_OUTPUT[] = { 0x10b, 0x20b, 0x30b };
261
262static const u16 NCT6775_REG_FAN_STOP_TIME[] = {
578ab5f0
DB
263 0x107, 0x207, 0x307, 0x807, 0x907, 0xa07 };
264static const u16 NCT6775_REG_PWM[] = {
265 0x109, 0x209, 0x309, 0x809, 0x909, 0xa09 };
266static const u16 NCT6775_REG_PWM_READ[] = {
267 0x01, 0x03, 0x11, 0x13, 0x15, 0xa09 };
77eb5b37 268
1c65dc36
GR
269static const u16 NCT6775_REG_FAN[] = { 0x630, 0x632, 0x634, 0x636, 0x638 };
270static const u16 NCT6775_REG_FAN_MIN[] = { 0x3b, 0x3c, 0x3d };
5c25d954 271static const u16 NCT6775_REG_FAN_PULSES[] = { 0x641, 0x642, 0x643, 0x644, 0 };
578ab5f0 272static const u16 NCT6775_FAN_PULSE_SHIFT[] = { 0, 0, 0, 0, 0, 0 };
1c65dc36 273
aa136e5d
GR
274static const u16 NCT6775_REG_TEMP[] = {
275 0x27, 0x150, 0x250, 0x62b, 0x62c, 0x62d };
276
277static const u16 NCT6775_REG_TEMP_CONFIG[ARRAY_SIZE(NCT6775_REG_TEMP)] = {
278 0, 0x152, 0x252, 0x628, 0x629, 0x62A };
279static const u16 NCT6775_REG_TEMP_HYST[ARRAY_SIZE(NCT6775_REG_TEMP)] = {
280 0x3a, 0x153, 0x253, 0x673, 0x678, 0x67D };
281static const u16 NCT6775_REG_TEMP_OVER[ARRAY_SIZE(NCT6775_REG_TEMP)] = {
282 0x39, 0x155, 0x255, 0x672, 0x677, 0x67C };
283
284static const u16 NCT6775_REG_TEMP_SOURCE[ARRAY_SIZE(NCT6775_REG_TEMP)] = {
285 0x621, 0x622, 0x623, 0x624, 0x625, 0x626 };
286
cdcaeceb 287static const u16 NCT6775_REG_TEMP_SEL[] = {
578ab5f0 288 0x100, 0x200, 0x300, 0x800, 0x900, 0xa00 };
cdcaeceb 289
bbd8decd 290static const u16 NCT6775_REG_WEIGHT_TEMP_SEL[] = {
578ab5f0 291 0x139, 0x239, 0x339, 0x839, 0x939, 0xa39 };
bbd8decd 292static const u16 NCT6775_REG_WEIGHT_TEMP_STEP[] = {
578ab5f0 293 0x13a, 0x23a, 0x33a, 0x83a, 0x93a, 0xa3a };
bbd8decd 294static const u16 NCT6775_REG_WEIGHT_TEMP_STEP_TOL[] = {
578ab5f0 295 0x13b, 0x23b, 0x33b, 0x83b, 0x93b, 0xa3b };
bbd8decd 296static const u16 NCT6775_REG_WEIGHT_DUTY_STEP[] = {
578ab5f0 297 0x13c, 0x23c, 0x33c, 0x83c, 0x93c, 0xa3c };
bbd8decd 298static const u16 NCT6775_REG_WEIGHT_TEMP_BASE[] = {
578ab5f0 299 0x13d, 0x23d, 0x33d, 0x83d, 0x93d, 0xa3d };
bbd8decd 300
aa136e5d
GR
301static const u16 NCT6775_REG_TEMP_OFFSET[] = { 0x454, 0x455, 0x456 };
302
cdcaeceb 303static const u16 NCT6775_REG_AUTO_TEMP[] = {
578ab5f0 304 0x121, 0x221, 0x321, 0x821, 0x921, 0xa21 };
cdcaeceb 305static const u16 NCT6775_REG_AUTO_PWM[] = {
578ab5f0 306 0x127, 0x227, 0x327, 0x827, 0x927, 0xa27 };
cdcaeceb
GR
307
308#define NCT6775_AUTO_TEMP(data, nr, p) ((data)->REG_AUTO_TEMP[nr] + (p))
309#define NCT6775_AUTO_PWM(data, nr, p) ((data)->REG_AUTO_PWM[nr] + (p))
310
311static const u16 NCT6775_REG_CRITICAL_ENAB[] = { 0x134, 0x234, 0x334 };
312
313static const u16 NCT6775_REG_CRITICAL_TEMP[] = {
578ab5f0 314 0x135, 0x235, 0x335, 0x835, 0x935, 0xa35 };
cdcaeceb 315static const u16 NCT6775_REG_CRITICAL_TEMP_TOLERANCE[] = {
578ab5f0 316 0x138, 0x238, 0x338, 0x838, 0x938, 0xa38 };
cdcaeceb 317
aa136e5d
GR
318static const char *const nct6775_temp_label[] = {
319 "",
320 "SYSTIN",
321 "CPUTIN",
322 "AUXTIN",
323 "AMD SB-TSI",
324 "PECI Agent 0",
325 "PECI Agent 1",
326 "PECI Agent 2",
327 "PECI Agent 3",
328 "PECI Agent 4",
329 "PECI Agent 5",
330 "PECI Agent 6",
331 "PECI Agent 7",
332 "PCH_CHIP_CPU_MAX_TEMP",
333 "PCH_CHIP_TEMP",
334 "PCH_CPU_TEMP",
335 "PCH_MCH_TEMP",
336 "PCH_DIM0_TEMP",
337 "PCH_DIM1_TEMP",
338 "PCH_DIM2_TEMP",
339 "PCH_DIM3_TEMP"
340};
341
342static const u16 NCT6775_REG_TEMP_ALTERNATE[ARRAY_SIZE(nct6775_temp_label) - 1]
343 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x661, 0x662, 0x664 };
344
345static const u16 NCT6775_REG_TEMP_CRIT[ARRAY_SIZE(nct6775_temp_label) - 1]
346 = { 0, 0, 0, 0, 0xa00, 0xa01, 0xa02, 0xa03, 0xa04, 0xa05, 0xa06,
347 0xa07 };
348
9de2e2e8
GR
349/* NCT6776 specific data */
350
351static const s8 NCT6776_ALARM_BITS[] = {
352 0, 1, 2, 3, 8, 21, 20, 16, /* in0.. in7 */
353 17, -1, -1, -1, -1, -1, -1, /* in8..in14 */
354 -1, /* unused */
355 6, 7, 11, 10, 23, /* fan1..fan5 */
356 -1, -1, -1, /* unused */
357 4, 5, 13, -1, -1, -1, /* temp1..temp6 */
358 12, 9 }; /* intrusion0, intrusion1 */
359
30846993
GR
360static const u16 NCT6776_REG_BEEP[NUM_REG_BEEP] = { 0xb2, 0xb3, 0xb4, 0xb5 };
361
362static const s8 NCT6776_BEEP_BITS[] = {
363 0, 1, 2, 3, 4, 5, 6, 7, /* in0.. in7 */
364 8, -1, -1, -1, -1, -1, -1, /* in8..in14 */
365 24, /* global beep enable */
366 25, 26, 27, 28, 29, /* fan1..fan5 */
367 -1, -1, -1, /* unused */
368 16, 17, 18, 19, 20, 21, /* temp1..temp6 */
369 30, 31 }; /* intrusion0, intrusion1 */
370
cdcaeceb 371static const u16 NCT6776_REG_TOLERANCE_H[] = {
578ab5f0 372 0x10c, 0x20c, 0x30c, 0x80c, 0x90c, 0xa0c };
cdcaeceb 373
578ab5f0
DB
374static const u8 NCT6776_REG_PWM_MODE[] = { 0x04, 0, 0, 0, 0, 0 };
375static const u8 NCT6776_PWM_MODE_MASK[] = { 0x01, 0, 0, 0, 0, 0 };
77eb5b37 376
1c65dc36 377static const u16 NCT6776_REG_FAN_MIN[] = { 0x63a, 0x63c, 0x63e, 0x640, 0x642 };
5c25d954 378static const u16 NCT6776_REG_FAN_PULSES[] = { 0x644, 0x645, 0x646, 0, 0 };
1c65dc36 379
bbd8decd 380static const u16 NCT6776_REG_WEIGHT_DUTY_BASE[] = {
578ab5f0 381 0x13e, 0x23e, 0x33e, 0x83e, 0x93e, 0xa3e };
bbd8decd 382
aa136e5d
GR
383static const u16 NCT6776_REG_TEMP_CONFIG[ARRAY_SIZE(NCT6775_REG_TEMP)] = {
384 0x18, 0x152, 0x252, 0x628, 0x629, 0x62A };
385
386static const char *const nct6776_temp_label[] = {
387 "",
388 "SYSTIN",
389 "CPUTIN",
390 "AUXTIN",
391 "SMBUSMASTER 0",
392 "SMBUSMASTER 1",
393 "SMBUSMASTER 2",
394 "SMBUSMASTER 3",
395 "SMBUSMASTER 4",
396 "SMBUSMASTER 5",
397 "SMBUSMASTER 6",
398 "SMBUSMASTER 7",
399 "PECI Agent 0",
400 "PECI Agent 1",
401 "PCH_CHIP_CPU_MAX_TEMP",
402 "PCH_CHIP_TEMP",
403 "PCH_CPU_TEMP",
404 "PCH_MCH_TEMP",
405 "PCH_DIM0_TEMP",
406 "PCH_DIM1_TEMP",
407 "PCH_DIM2_TEMP",
408 "PCH_DIM3_TEMP",
409 "BYTE_TEMP"
410};
411
412static const u16 NCT6776_REG_TEMP_ALTERNATE[ARRAY_SIZE(nct6776_temp_label) - 1]
413 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x401, 0x402, 0x404 };
414
415static const u16 NCT6776_REG_TEMP_CRIT[ARRAY_SIZE(nct6776_temp_label) - 1]
416 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x709, 0x70a };
417
9de2e2e8
GR
418/* NCT6779 specific data */
419
420static const u16 NCT6779_REG_IN[] = {
421 0x480, 0x481, 0x482, 0x483, 0x484, 0x485, 0x486, 0x487,
422 0x488, 0x489, 0x48a, 0x48b, 0x48c, 0x48d, 0x48e };
423
424static const u16 NCT6779_REG_ALARM[NUM_REG_ALARM] = {
425 0x459, 0x45A, 0x45B, 0x568 };
426
427static const s8 NCT6779_ALARM_BITS[] = {
428 0, 1, 2, 3, 8, 21, 20, 16, /* in0.. in7 */
429 17, 24, 25, 26, 27, 28, 29, /* in8..in14 */
430 -1, /* unused */
431 6, 7, 11, 10, 23, /* fan1..fan5 */
432 -1, -1, -1, /* unused */
433 4, 5, 13, -1, -1, -1, /* temp1..temp6 */
434 12, 9 }; /* intrusion0, intrusion1 */
435
30846993
GR
436static const s8 NCT6779_BEEP_BITS[] = {
437 0, 1, 2, 3, 4, 5, 6, 7, /* in0.. in7 */
438 8, 9, 10, 11, 12, 13, 14, /* in8..in14 */
439 24, /* global beep enable */
440 25, 26, 27, 28, 29, /* fan1..fan5 */
441 -1, -1, -1, /* unused */
442 16, 17, -1, -1, -1, -1, /* temp1..temp6 */
443 30, 31 }; /* intrusion0, intrusion1 */
444
578ab5f0
DB
445static const u16 NCT6779_REG_FAN[] = {
446 0x4b0, 0x4b2, 0x4b4, 0x4b6, 0x4b8, 0x4ba };
5c25d954 447static const u16 NCT6779_REG_FAN_PULSES[] = {
578ab5f0 448 0x644, 0x645, 0x646, 0x647, 0x648, 0x649 };
1c65dc36 449
cdcaeceb 450static const u16 NCT6779_REG_CRITICAL_PWM_ENABLE[] = {
578ab5f0 451 0x136, 0x236, 0x336, 0x836, 0x936, 0xa36 };
6c009501 452#define NCT6779_CRITICAL_PWM_ENABLE_MASK 0x01
cdcaeceb 453static const u16 NCT6779_REG_CRITICAL_PWM[] = {
578ab5f0 454 0x137, 0x237, 0x337, 0x837, 0x937, 0xa37 };
cdcaeceb 455
aa136e5d
GR
456static const u16 NCT6779_REG_TEMP[] = { 0x27, 0x150 };
457static const u16 NCT6779_REG_TEMP_CONFIG[ARRAY_SIZE(NCT6779_REG_TEMP)] = {
458 0x18, 0x152 };
459static const u16 NCT6779_REG_TEMP_HYST[ARRAY_SIZE(NCT6779_REG_TEMP)] = {
460 0x3a, 0x153 };
461static const u16 NCT6779_REG_TEMP_OVER[ARRAY_SIZE(NCT6779_REG_TEMP)] = {
462 0x39, 0x155 };
463
464static const u16 NCT6779_REG_TEMP_OFFSET[] = {
465 0x454, 0x455, 0x456, 0x44a, 0x44b, 0x44c };
466
467static const char *const nct6779_temp_label[] = {
468 "",
469 "SYSTIN",
470 "CPUTIN",
471 "AUXTIN0",
472 "AUXTIN1",
473 "AUXTIN2",
474 "AUXTIN3",
475 "",
476 "SMBUSMASTER 0",
477 "SMBUSMASTER 1",
478 "SMBUSMASTER 2",
479 "SMBUSMASTER 3",
480 "SMBUSMASTER 4",
481 "SMBUSMASTER 5",
482 "SMBUSMASTER 6",
483 "SMBUSMASTER 7",
484 "PECI Agent 0",
485 "PECI Agent 1",
486 "PCH_CHIP_CPU_MAX_TEMP",
487 "PCH_CHIP_TEMP",
488 "PCH_CPU_TEMP",
489 "PCH_MCH_TEMP",
490 "PCH_DIM0_TEMP",
491 "PCH_DIM1_TEMP",
492 "PCH_DIM2_TEMP",
493 "PCH_DIM3_TEMP",
494 "BYTE_TEMP"
495};
496
497static const u16 NCT6779_REG_TEMP_ALTERNATE[ARRAY_SIZE(nct6779_temp_label) - 1]
498 = { 0x490, 0x491, 0x492, 0x493, 0x494, 0x495, 0, 0,
499 0, 0, 0, 0, 0, 0, 0, 0,
500 0, 0x400, 0x401, 0x402, 0x404, 0x405, 0x406, 0x407,
501 0x408, 0 };
502
503static const u16 NCT6779_REG_TEMP_CRIT[ARRAY_SIZE(nct6779_temp_label) - 1]
504 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x709, 0x70a };
505
578ab5f0
DB
506/* NCT6791 specific data */
507
508#define NCT6791_REG_HM_IO_SPACE_LOCK_ENABLE 0x28
509
510static const u16 NCT6791_REG_ALARM[NUM_REG_ALARM] = {
511 0x459, 0x45A, 0x45B, 0x568, 0x45D };
512
513static const s8 NCT6791_ALARM_BITS[] = {
514 0, 1, 2, 3, 8, 21, 20, 16, /* in0.. in7 */
515 17, 24, 25, 26, 27, 28, 29, /* in8..in14 */
516 -1, /* unused */
517 6, 7, 11, 10, 23, 33, /* fan1..fan6 */
518 -1, -1, /* unused */
519 4, 5, 13, -1, -1, -1, /* temp1..temp6 */
520 12, 9 }; /* intrusion0, intrusion1 */
521
522
6c009501
GR
523/* NCT6102D/NCT6106D specific data */
524
525#define NCT6106_REG_VBAT 0x318
526#define NCT6106_REG_DIODE 0x319
527#define NCT6106_DIODE_MASK 0x01
528
529static const u16 NCT6106_REG_IN_MAX[] = {
530 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9e, 0xa0, 0xa2 };
531static const u16 NCT6106_REG_IN_MIN[] = {
532 0x91, 0x93, 0x95, 0x97, 0x99, 0x9b, 0x9f, 0xa1, 0xa3 };
533static const u16 NCT6106_REG_IN[] = {
534 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x07, 0x08, 0x09 };
535
536static const u16 NCT6106_REG_TEMP[] = { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15 };
537static const u16 NCT6106_REG_TEMP_HYST[] = {
538 0xc3, 0xc7, 0xcb, 0xcf, 0xd3, 0xd7 };
539static const u16 NCT6106_REG_TEMP_OVER[] = {
b7a61353
GR
540 0xc2, 0xc6, 0xca, 0xce, 0xd2, 0xd6 };
541static const u16 NCT6106_REG_TEMP_CRIT_L[] = {
542 0xc0, 0xc4, 0xc8, 0xcc, 0xd0, 0xd4 };
543static const u16 NCT6106_REG_TEMP_CRIT_H[] = {
544 0xc1, 0xc5, 0xc9, 0xcf, 0xd1, 0xd5 };
6c009501
GR
545static const u16 NCT6106_REG_TEMP_OFFSET[] = { 0x311, 0x312, 0x313 };
546static const u16 NCT6106_REG_TEMP_CONFIG[] = {
547 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc };
548
549static const u16 NCT6106_REG_FAN[] = { 0x20, 0x22, 0x24 };
550static const u16 NCT6106_REG_FAN_MIN[] = { 0xe0, 0xe2, 0xe4 };
551static const u16 NCT6106_REG_FAN_PULSES[] = { 0xf6, 0xf6, 0xf6, 0, 0 };
552static const u16 NCT6106_FAN_PULSE_SHIFT[] = { 0, 2, 4, 0, 0 };
553
554static const u8 NCT6106_REG_PWM_MODE[] = { 0xf3, 0xf3, 0xf3 };
555static const u8 NCT6106_PWM_MODE_MASK[] = { 0x01, 0x02, 0x04 };
556static const u16 NCT6106_REG_PWM[] = { 0x119, 0x129, 0x139 };
557static const u16 NCT6106_REG_PWM_READ[] = { 0x4a, 0x4b, 0x4c };
558static const u16 NCT6106_REG_FAN_MODE[] = { 0x113, 0x123, 0x133 };
559static const u16 NCT6106_REG_TEMP_SEL[] = { 0x110, 0x120, 0x130 };
560static const u16 NCT6106_REG_TEMP_SOURCE[] = {
561 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5 };
562
563static const u16 NCT6106_REG_CRITICAL_TEMP[] = { 0x11a, 0x12a, 0x13a };
564static const u16 NCT6106_REG_CRITICAL_TEMP_TOLERANCE[] = {
565 0x11b, 0x12b, 0x13b };
566
567static const u16 NCT6106_REG_CRITICAL_PWM_ENABLE[] = { 0x11c, 0x12c, 0x13c };
568#define NCT6106_CRITICAL_PWM_ENABLE_MASK 0x10
569static const u16 NCT6106_REG_CRITICAL_PWM[] = { 0x11d, 0x12d, 0x13d };
570
571static const u16 NCT6106_REG_FAN_STEP_UP_TIME[] = { 0x114, 0x124, 0x134 };
572static const u16 NCT6106_REG_FAN_STEP_DOWN_TIME[] = { 0x115, 0x125, 0x135 };
573static const u16 NCT6106_REG_FAN_STOP_OUTPUT[] = { 0x116, 0x126, 0x136 };
574static const u16 NCT6106_REG_FAN_START_OUTPUT[] = { 0x117, 0x127, 0x137 };
575static const u16 NCT6106_REG_FAN_STOP_TIME[] = { 0x118, 0x128, 0x138 };
576static const u16 NCT6106_REG_TOLERANCE_H[] = { 0x112, 0x122, 0x132 };
577
578static const u16 NCT6106_REG_TARGET[] = { 0x111, 0x121, 0x131 };
579
580static const u16 NCT6106_REG_WEIGHT_TEMP_SEL[] = { 0x168, 0x178, 0x188 };
581static const u16 NCT6106_REG_WEIGHT_TEMP_STEP[] = { 0x169, 0x179, 0x189 };
582static const u16 NCT6106_REG_WEIGHT_TEMP_STEP_TOL[] = { 0x16a, 0x17a, 0x18a };
583static const u16 NCT6106_REG_WEIGHT_DUTY_STEP[] = { 0x16b, 0x17b, 0x17c };
584static const u16 NCT6106_REG_WEIGHT_TEMP_BASE[] = { 0x16c, 0x17c, 0x18c };
585static const u16 NCT6106_REG_WEIGHT_DUTY_BASE[] = { 0x16d, 0x17d, 0x18d };
586
587static const u16 NCT6106_REG_AUTO_TEMP[] = { 0x160, 0x170, 0x180 };
588static const u16 NCT6106_REG_AUTO_PWM[] = { 0x164, 0x174, 0x184 };
589
590static const u16 NCT6106_REG_ALARM[NUM_REG_ALARM] = {
591 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d };
592
593static const s8 NCT6106_ALARM_BITS[] = {
594 0, 1, 2, 3, 4, 5, 7, 8, /* in0.. in7 */
595 9, -1, -1, -1, -1, -1, -1, /* in8..in14 */
596 -1, /* unused */
597 32, 33, 34, -1, -1, /* fan1..fan5 */
598 -1, -1, -1, /* unused */
599 16, 17, 18, 19, 20, 21, /* temp1..temp6 */
600 48, -1 /* intrusion0, intrusion1 */
601};
602
30846993
GR
603static const u16 NCT6106_REG_BEEP[NUM_REG_BEEP] = {
604 0x3c0, 0x3c1, 0x3c2, 0x3c3, 0x3c4 };
605
606static const s8 NCT6106_BEEP_BITS[] = {
607 0, 1, 2, 3, 4, 5, 7, 8, /* in0.. in7 */
608 9, 10, 11, 12, -1, -1, -1, /* in8..in14 */
609 32, /* global beep enable */
610 24, 25, 26, 27, 28, /* fan1..fan5 */
611 -1, -1, -1, /* unused */
612 16, 17, 18, 19, 20, 21, /* temp1..temp6 */
613 34, -1 /* intrusion0, intrusion1 */
614};
615
6c009501
GR
616static const u16 NCT6106_REG_TEMP_ALTERNATE[ARRAY_SIZE(nct6776_temp_label) - 1]
617 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x51, 0x52, 0x54 };
618
619static const u16 NCT6106_REG_TEMP_CRIT[ARRAY_SIZE(nct6776_temp_label) - 1]
620 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x204, 0x205 };
621
77eb5b37
GR
622static enum pwm_enable reg_to_pwm_enable(int pwm, int mode)
623{
624 if (mode == 0 && pwm == 255)
625 return off;
626 return mode + 1;
627}
628
629static int pwm_enable_to_reg(enum pwm_enable mode)
630{
631 if (mode == off)
632 return 0;
633 return mode - 1;
634}
635
9de2e2e8
GR
636/*
637 * Conversions
638 */
639
cdcaeceb
GR
640/* 1 is DC mode, output in ms */
641static unsigned int step_time_from_reg(u8 reg, u8 mode)
642{
643 return mode ? 400 * reg : 100 * reg;
644}
645
646static u8 step_time_to_reg(unsigned int msec, u8 mode)
647{
648 return clamp_val((mode ? (msec + 200) / 400 :
649 (msec + 50) / 100), 1, 255);
650}
651
1c65dc36
GR
652static unsigned int fan_from_reg8(u16 reg, unsigned int divreg)
653{
654 if (reg == 0 || reg == 255)
655 return 0;
656 return 1350000U / (reg << divreg);
657}
658
659static unsigned int fan_from_reg13(u16 reg, unsigned int divreg)
660{
661 if ((reg & 0xff1f) == 0xff1f)
662 return 0;
663
664 reg = (reg & 0x1f) | ((reg & 0xff00) >> 3);
665
666 if (reg == 0)
667 return 0;
668
669 return 1350000U / reg;
670}
671
672static unsigned int fan_from_reg16(u16 reg, unsigned int divreg)
673{
674 if (reg == 0 || reg == 0xffff)
675 return 0;
676
677 /*
678 * Even though the registers are 16 bit wide, the fan divisor
679 * still applies.
680 */
681 return 1350000U / (reg << divreg);
682}
683
cdcaeceb
GR
684static u16 fan_to_reg(u32 fan, unsigned int divreg)
685{
686 if (!fan)
687 return 0;
688
689 return (1350000U / fan) >> divreg;
690}
691
1c65dc36
GR
692static inline unsigned int
693div_from_reg(u8 reg)
694{
695 return 1 << reg;
696}
697
9de2e2e8
GR
698/*
699 * Some of the voltage inputs have internal scaling, the tables below
700 * contain 8 (the ADC LSB in mV) * scaling factor * 100
701 */
702static const u16 scale_in[15] = {
703 800, 800, 1600, 1600, 800, 800, 800, 1600, 1600, 800, 800, 800, 800,
704 800, 800
705};
706
707static inline long in_from_reg(u8 reg, u8 nr)
708{
709 return DIV_ROUND_CLOSEST(reg * scale_in[nr], 100);
710}
711
712static inline u8 in_to_reg(u32 val, u8 nr)
713{
714 return clamp_val(DIV_ROUND_CLOSEST(val * 100, scale_in[nr]), 0, 255);
715}
716
717/*
718 * Data structures and manipulation thereof
719 */
720
721struct nct6775_data {
722 int addr; /* IO base of hw monitor block */
df612d5f 723 int sioreg; /* SIO register address */
9de2e2e8
GR
724 enum kinds kind;
725 const char *name;
726
727 struct device *hwmon_dev;
615fc8cb
GR
728
729 int num_attr_groups;
730 const struct attribute_group *groups[6];
9de2e2e8 731
b7a61353
GR
732 u16 reg_temp[5][NUM_TEMP]; /* 0=temp, 1=temp_over, 2=temp_hyst,
733 * 3=temp_crit, 4=temp_lcrit
aa136e5d
GR
734 */
735 u8 temp_src[NUM_TEMP];
736 u16 reg_temp_config[NUM_TEMP];
737 const char * const *temp_label;
738 int temp_label_num;
739
9de2e2e8
GR
740 u16 REG_CONFIG;
741 u16 REG_VBAT;
aa136e5d 742 u16 REG_DIODE;
6c009501 743 u8 DIODE_MASK;
9de2e2e8
GR
744
745 const s8 *ALARM_BITS;
30846993 746 const s8 *BEEP_BITS;
9de2e2e8
GR
747
748 const u16 *REG_VIN;
749 const u16 *REG_IN_MINMAX[2];
750
cdcaeceb 751 const u16 *REG_TARGET;
1c65dc36 752 const u16 *REG_FAN;
77eb5b37 753 const u16 *REG_FAN_MODE;
1c65dc36 754 const u16 *REG_FAN_MIN;
5c25d954 755 const u16 *REG_FAN_PULSES;
6c009501 756 const u16 *FAN_PULSE_SHIFT;
cdcaeceb
GR
757 const u16 *REG_FAN_TIME[3];
758
759 const u16 *REG_TOLERANCE_H;
aa136e5d 760
77eb5b37
GR
761 const u8 *REG_PWM_MODE;
762 const u8 *PWM_MODE_MASK;
763
bbd8decd
GR
764 const u16 *REG_PWM[7]; /* [0]=pwm, [1]=pwm_start, [2]=pwm_floor,
765 * [3]=pwm_max, [4]=pwm_step,
766 * [5]=weight_duty_step, [6]=weight_duty_base
cdcaeceb 767 */
77eb5b37
GR
768 const u16 *REG_PWM_READ;
769
6c009501
GR
770 const u16 *REG_CRITICAL_PWM_ENABLE;
771 u8 CRITICAL_PWM_ENABLE_MASK;
772 const u16 *REG_CRITICAL_PWM;
773
cdcaeceb
GR
774 const u16 *REG_AUTO_TEMP;
775 const u16 *REG_AUTO_PWM;
776
777 const u16 *REG_CRITICAL_TEMP;
778 const u16 *REG_CRITICAL_TEMP_TOLERANCE;
779
1c65dc36 780 const u16 *REG_TEMP_SOURCE; /* temp register sources */
cdcaeceb 781 const u16 *REG_TEMP_SEL;
bbd8decd
GR
782 const u16 *REG_WEIGHT_TEMP_SEL;
783 const u16 *REG_WEIGHT_TEMP[3]; /* 0=base, 1=tolerance, 2=step */
784
aa136e5d
GR
785 const u16 *REG_TEMP_OFFSET;
786
9de2e2e8 787 const u16 *REG_ALARM;
30846993 788 const u16 *REG_BEEP;
9de2e2e8 789
1c65dc36
GR
790 unsigned int (*fan_from_reg)(u16 reg, unsigned int divreg);
791 unsigned int (*fan_from_reg_min)(u16 reg, unsigned int divreg);
792
9de2e2e8
GR
793 struct mutex update_lock;
794 bool valid; /* true if following fields are valid */
795 unsigned long last_updated; /* In jiffies */
796
797 /* Register values */
798 u8 bank; /* current register bank */
799 u8 in_num; /* number of in inputs we have */
800 u8 in[15][3]; /* [0]=in, [1]=in_max, [2]=in_min */
578ab5f0
DB
801 unsigned int rpm[NUM_FAN];
802 u16 fan_min[NUM_FAN];
803 u8 fan_pulses[NUM_FAN];
804 u8 fan_div[NUM_FAN];
77eb5b37 805 u8 has_pwm;
1c65dc36
GR
806 u8 has_fan; /* some fan inputs can be disabled */
807 u8 has_fan_min; /* some fans don't have min register */
808 bool has_fan_div;
9de2e2e8 809
6c009501 810 u8 num_temp_alarms; /* 2, 3, or 6 */
30846993 811 u8 num_temp_beeps; /* 2, 3, or 6 */
aa136e5d
GR
812 u8 temp_fixed_num; /* 3 or 6 */
813 u8 temp_type[NUM_TEMP_FIXED];
814 s8 temp_offset[NUM_TEMP_FIXED];
f58876ac
DC
815 s16 temp[5][NUM_TEMP]; /* 0=temp, 1=temp_over, 2=temp_hyst,
816 * 3=temp_crit, 4=temp_lcrit */
9de2e2e8 817 u64 alarms;
30846993 818 u64 beeps;
9de2e2e8 819
77eb5b37 820 u8 pwm_num; /* number of pwm */
578ab5f0
DB
821 u8 pwm_mode[NUM_FAN]; /* 1->DC variable voltage,
822 * 0->PWM variable duty cycle
823 */
824 enum pwm_enable pwm_enable[NUM_FAN];
77eb5b37
GR
825 /* 0->off
826 * 1->manual
827 * 2->thermal cruise mode (also called SmartFan I)
828 * 3->fan speed cruise mode
829 * 4->SmartFan III
830 * 5->enhanced variable thermal cruise (SmartFan IV)
831 */
578ab5f0
DB
832 u8 pwm[7][NUM_FAN]; /* [0]=pwm, [1]=pwm_start, [2]=pwm_floor,
833 * [3]=pwm_max, [4]=pwm_step,
834 * [5]=weight_duty_step, [6]=weight_duty_base
835 */
cdcaeceb 836
578ab5f0 837 u8 target_temp[NUM_FAN];
cdcaeceb 838 u8 target_temp_mask;
578ab5f0
DB
839 u32 target_speed[NUM_FAN];
840 u32 target_speed_tolerance[NUM_FAN];
cdcaeceb
GR
841 u8 speed_tolerance_limit;
842
578ab5f0 843 u8 temp_tolerance[2][NUM_FAN];
cdcaeceb
GR
844 u8 tolerance_mask;
845
578ab5f0 846 u8 fan_time[3][NUM_FAN]; /* 0 = stop_time, 1 = step_up, 2 = step_down */
cdcaeceb
GR
847
848 /* Automatic fan speed control registers */
849 int auto_pwm_num;
578ab5f0
DB
850 u8 auto_pwm[NUM_FAN][7];
851 u8 auto_temp[NUM_FAN][7];
852 u8 pwm_temp_sel[NUM_FAN];
853 u8 pwm_weight_temp_sel[NUM_FAN];
854 u8 weight_temp[3][NUM_FAN]; /* 0->temp_step, 1->temp_step_tol,
855 * 2->temp_base
856 */
77eb5b37 857
9de2e2e8
GR
858 u8 vid;
859 u8 vrm;
860
f73cf632
GR
861 bool have_vid;
862
aa136e5d
GR
863 u16 have_temp;
864 u16 have_temp_fixed;
9de2e2e8 865 u16 have_in;
84d19d92
GR
866#ifdef CONFIG_PM
867 /* Remember extra register values over suspend/resume */
868 u8 vbat;
869 u8 fandiv1;
870 u8 fandiv2;
871#endif
9de2e2e8
GR
872};
873
874struct nct6775_sio_data {
875 int sioreg;
876 enum kinds kind;
877};
878
f73cf632
GR
879struct sensor_device_template {
880 struct device_attribute dev_attr;
881 union {
882 struct {
883 u8 nr;
884 u8 index;
885 } s;
886 int index;
887 } u;
888 bool s2; /* true if both index and nr are used */
889};
890
891struct sensor_device_attr_u {
892 union {
893 struct sensor_device_attribute a1;
894 struct sensor_device_attribute_2 a2;
895 } u;
896 char name[32];
897};
898
899#define __TEMPLATE_ATTR(_template, _mode, _show, _store) { \
900 .attr = {.name = _template, .mode = _mode }, \
901 .show = _show, \
902 .store = _store, \
903}
904
905#define SENSOR_DEVICE_TEMPLATE(_template, _mode, _show, _store, _index) \
906 { .dev_attr = __TEMPLATE_ATTR(_template, _mode, _show, _store), \
907 .u.index = _index, \
908 .s2 = false }
909
910#define SENSOR_DEVICE_TEMPLATE_2(_template, _mode, _show, _store, \
911 _nr, _index) \
912 { .dev_attr = __TEMPLATE_ATTR(_template, _mode, _show, _store), \
913 .u.s.index = _index, \
914 .u.s.nr = _nr, \
915 .s2 = true }
916
917#define SENSOR_TEMPLATE(_name, _template, _mode, _show, _store, _index) \
918static struct sensor_device_template sensor_dev_template_##_name \
919 = SENSOR_DEVICE_TEMPLATE(_template, _mode, _show, _store, \
920 _index)
921
922#define SENSOR_TEMPLATE_2(_name, _template, _mode, _show, _store, \
923 _nr, _index) \
924static struct sensor_device_template sensor_dev_template_##_name \
925 = SENSOR_DEVICE_TEMPLATE_2(_template, _mode, _show, _store, \
926 _nr, _index)
927
928struct sensor_template_group {
929 struct sensor_device_template **templates;
930 umode_t (*is_visible)(struct kobject *, struct attribute *, int);
931 int base;
932};
933
934static struct attribute_group *
935nct6775_create_attr_group(struct device *dev, struct sensor_template_group *tg,
936 int repeat)
937{
938 struct attribute_group *group;
939 struct sensor_device_attr_u *su;
940 struct sensor_device_attribute *a;
941 struct sensor_device_attribute_2 *a2;
942 struct attribute **attrs;
943 struct sensor_device_template **t;
615fc8cb 944 int i, j, count;
f73cf632
GR
945
946 if (repeat <= 0)
947 return ERR_PTR(-EINVAL);
948
949 t = tg->templates;
950 for (count = 0; *t; t++, count++)
951 ;
952
953 if (count == 0)
954 return ERR_PTR(-EINVAL);
955
956 group = devm_kzalloc(dev, sizeof(*group), GFP_KERNEL);
957 if (group == NULL)
958 return ERR_PTR(-ENOMEM);
959
960 attrs = devm_kzalloc(dev, sizeof(*attrs) * (repeat * count + 1),
961 GFP_KERNEL);
962 if (attrs == NULL)
963 return ERR_PTR(-ENOMEM);
964
965 su = devm_kzalloc(dev, sizeof(*su) * repeat * count,
966 GFP_KERNEL);
967 if (su == NULL)
968 return ERR_PTR(-ENOMEM);
969
970 group->attrs = attrs;
971 group->is_visible = tg->is_visible;
972
973 for (i = 0; i < repeat; i++) {
974 t = tg->templates;
975 for (j = 0; *t != NULL; j++) {
976 snprintf(su->name, sizeof(su->name),
977 (*t)->dev_attr.attr.name, tg->base + i);
978 if ((*t)->s2) {
979 a2 = &su->u.a2;
980 a2->dev_attr.attr.name = su->name;
981 a2->nr = (*t)->u.s.nr + i;
982 a2->index = (*t)->u.s.index;
983 a2->dev_attr.attr.mode =
984 (*t)->dev_attr.attr.mode;
985 a2->dev_attr.show = (*t)->dev_attr.show;
986 a2->dev_attr.store = (*t)->dev_attr.store;
987 *attrs = &a2->dev_attr.attr;
988 } else {
989 a = &su->u.a1;
990 a->dev_attr.attr.name = su->name;
991 a->index = (*t)->u.index + i;
992 a->dev_attr.attr.mode =
993 (*t)->dev_attr.attr.mode;
994 a->dev_attr.show = (*t)->dev_attr.show;
995 a->dev_attr.store = (*t)->dev_attr.store;
996 *attrs = &a->dev_attr.attr;
997 }
998 attrs++;
999 su++;
1000 t++;
1001 }
1002 }
1003
f73cf632
GR
1004 return group;
1005}
1006
9de2e2e8
GR
1007static bool is_word_sized(struct nct6775_data *data, u16 reg)
1008{
1009 switch (data->kind) {
6c009501
GR
1010 case nct6106:
1011 return reg == 0x20 || reg == 0x22 || reg == 0x24 ||
1012 reg == 0xe0 || reg == 0xe2 || reg == 0xe4 ||
1013 reg == 0x111 || reg == 0x121 || reg == 0x131;
9de2e2e8
GR
1014 case nct6775:
1015 return (((reg & 0xff00) == 0x100 ||
1016 (reg & 0xff00) == 0x200) &&
1017 ((reg & 0x00ff) == 0x50 ||
1018 (reg & 0x00ff) == 0x53 ||
1019 (reg & 0x00ff) == 0x55)) ||
1020 (reg & 0xfff0) == 0x630 ||
1021 reg == 0x640 || reg == 0x642 ||
1022 reg == 0x662 ||
1023 ((reg & 0xfff0) == 0x650 && (reg & 0x000f) >= 0x06) ||
1024 reg == 0x73 || reg == 0x75 || reg == 0x77;
1025 case nct6776:
1026 return (((reg & 0xff00) == 0x100 ||
1027 (reg & 0xff00) == 0x200) &&
1028 ((reg & 0x00ff) == 0x50 ||
1029 (reg & 0x00ff) == 0x53 ||
1030 (reg & 0x00ff) == 0x55)) ||
1031 (reg & 0xfff0) == 0x630 ||
1032 reg == 0x402 ||
1033 reg == 0x640 || reg == 0x642 ||
1034 ((reg & 0xfff0) == 0x650 && (reg & 0x000f) >= 0x06) ||
1035 reg == 0x73 || reg == 0x75 || reg == 0x77;
1036 case nct6779:
578ab5f0 1037 case nct6791:
9de2e2e8 1038 return reg == 0x150 || reg == 0x153 || reg == 0x155 ||
578ab5f0 1039 ((reg & 0xfff0) == 0x4b0 && (reg & 0x000f) < 0x0b) ||
9de2e2e8
GR
1040 reg == 0x402 ||
1041 reg == 0x63a || reg == 0x63c || reg == 0x63e ||
1042 reg == 0x640 || reg == 0x642 ||
1043 reg == 0x73 || reg == 0x75 || reg == 0x77 || reg == 0x79 ||
1044 reg == 0x7b;
1045 }
1046 return false;
1047}
1048
1049/*
1050 * On older chips, only registers 0x50-0x5f are banked.
1051 * On more recent chips, all registers are banked.
1052 * Assume that is the case and set the bank number for each access.
1053 * Cache the bank number so it only needs to be set if it changes.
1054 */
1055static inline void nct6775_set_bank(struct nct6775_data *data, u16 reg)
1056{
1057 u8 bank = reg >> 8;
1058 if (data->bank != bank) {
1059 outb_p(NCT6775_REG_BANK, data->addr + ADDR_REG_OFFSET);
1060 outb_p(bank, data->addr + DATA_REG_OFFSET);
1061 data->bank = bank;
1062 }
1063}
1064
1065static u16 nct6775_read_value(struct nct6775_data *data, u16 reg)
1066{
1067 int res, word_sized = is_word_sized(data, reg);
1068
9de2e2e8
GR
1069 nct6775_set_bank(data, reg);
1070 outb_p(reg & 0xff, data->addr + ADDR_REG_OFFSET);
1071 res = inb_p(data->addr + DATA_REG_OFFSET);
1072 if (word_sized) {
1073 outb_p((reg & 0xff) + 1,
1074 data->addr + ADDR_REG_OFFSET);
1075 res = (res << 8) + inb_p(data->addr + DATA_REG_OFFSET);
1076 }
9de2e2e8
GR
1077 return res;
1078}
1079
1080static int nct6775_write_value(struct nct6775_data *data, u16 reg, u16 value)
1081{
1082 int word_sized = is_word_sized(data, reg);
1083
9de2e2e8
GR
1084 nct6775_set_bank(data, reg);
1085 outb_p(reg & 0xff, data->addr + ADDR_REG_OFFSET);
1086 if (word_sized) {
1087 outb_p(value >> 8, data->addr + DATA_REG_OFFSET);
1088 outb_p((reg & 0xff) + 1,
1089 data->addr + ADDR_REG_OFFSET);
1090 }
1091 outb_p(value & 0xff, data->addr + DATA_REG_OFFSET);
9de2e2e8
GR
1092 return 0;
1093}
1094
aa136e5d
GR
1095/* We left-align 8-bit temperature values to make the code simpler */
1096static u16 nct6775_read_temp(struct nct6775_data *data, u16 reg)
1097{
1098 u16 res;
1099
1100 res = nct6775_read_value(data, reg);
1101 if (!is_word_sized(data, reg))
1102 res <<= 8;
1103
1104 return res;
1105}
1106
1107static int nct6775_write_temp(struct nct6775_data *data, u16 reg, u16 value)
1108{
1109 if (!is_word_sized(data, reg))
1110 value >>= 8;
1111 return nct6775_write_value(data, reg, value);
1112}
1113
1c65dc36
GR
1114/* This function assumes that the caller holds data->update_lock */
1115static void nct6775_write_fan_div(struct nct6775_data *data, int nr)
1116{
1117 u8 reg;
1118
1119 switch (nr) {
1120 case 0:
1121 reg = (nct6775_read_value(data, NCT6775_REG_FANDIV1) & 0x70)
1122 | (data->fan_div[0] & 0x7);
1123 nct6775_write_value(data, NCT6775_REG_FANDIV1, reg);
1124 break;
1125 case 1:
1126 reg = (nct6775_read_value(data, NCT6775_REG_FANDIV1) & 0x7)
1127 | ((data->fan_div[1] << 4) & 0x70);
1128 nct6775_write_value(data, NCT6775_REG_FANDIV1, reg);
1129 break;
1130 case 2:
1131 reg = (nct6775_read_value(data, NCT6775_REG_FANDIV2) & 0x70)
1132 | (data->fan_div[2] & 0x7);
1133 nct6775_write_value(data, NCT6775_REG_FANDIV2, reg);
1134 break;
1135 case 3:
1136 reg = (nct6775_read_value(data, NCT6775_REG_FANDIV2) & 0x7)
1137 | ((data->fan_div[3] << 4) & 0x70);
1138 nct6775_write_value(data, NCT6775_REG_FANDIV2, reg);
1139 break;
1140 }
1141}
1142
1143static void nct6775_write_fan_div_common(struct nct6775_data *data, int nr)
1144{
1145 if (data->kind == nct6775)
1146 nct6775_write_fan_div(data, nr);
1147}
1148
1149static void nct6775_update_fan_div(struct nct6775_data *data)
1150{
1151 u8 i;
1152
1153 i = nct6775_read_value(data, NCT6775_REG_FANDIV1);
1154 data->fan_div[0] = i & 0x7;
1155 data->fan_div[1] = (i & 0x70) >> 4;
1156 i = nct6775_read_value(data, NCT6775_REG_FANDIV2);
1157 data->fan_div[2] = i & 0x7;
6445e660 1158 if (data->has_fan & (1 << 3))
1c65dc36
GR
1159 data->fan_div[3] = (i & 0x70) >> 4;
1160}
1161
1162static void nct6775_update_fan_div_common(struct nct6775_data *data)
1163{
1164 if (data->kind == nct6775)
1165 nct6775_update_fan_div(data);
1166}
1167
1168static void nct6775_init_fan_div(struct nct6775_data *data)
1169{
1170 int i;
1171
1172 nct6775_update_fan_div_common(data);
1173 /*
1174 * For all fans, start with highest divider value if the divider
1175 * register is not initialized. This ensures that we get a
1176 * reading from the fan count register, even if it is not optimal.
1177 * We'll compute a better divider later on.
1178 */
c409fd43 1179 for (i = 0; i < ARRAY_SIZE(data->fan_div); i++) {
1c65dc36
GR
1180 if (!(data->has_fan & (1 << i)))
1181 continue;
1182 if (data->fan_div[i] == 0) {
1183 data->fan_div[i] = 7;
1184 nct6775_write_fan_div_common(data, i);
1185 }
1186 }
1187}
1188
1189static void nct6775_init_fan_common(struct device *dev,
1190 struct nct6775_data *data)
1191{
1192 int i;
1193 u8 reg;
1194
1195 if (data->has_fan_div)
1196 nct6775_init_fan_div(data);
1197
1198 /*
1199 * If fan_min is not set (0), set it to 0xff to disable it. This
1200 * prevents the unnecessary warning when fanX_min is reported as 0.
1201 */
c409fd43 1202 for (i = 0; i < ARRAY_SIZE(data->fan_min); i++) {
1c65dc36
GR
1203 if (data->has_fan_min & (1 << i)) {
1204 reg = nct6775_read_value(data, data->REG_FAN_MIN[i]);
1205 if (!reg)
1206 nct6775_write_value(data, data->REG_FAN_MIN[i],
1207 data->has_fan_div ? 0xff
1208 : 0xff1f);
1209 }
1210 }
1211}
1212
1213static void nct6775_select_fan_div(struct device *dev,
1214 struct nct6775_data *data, int nr, u16 reg)
1215{
1216 u8 fan_div = data->fan_div[nr];
1217 u16 fan_min;
1218
1219 if (!data->has_fan_div)
1220 return;
1221
1222 /*
1223 * If we failed to measure the fan speed, or the reported value is not
1224 * in the optimal range, and the clock divider can be modified,
1225 * let's try that for next time.
1226 */
1227 if (reg == 0x00 && fan_div < 0x07)
1228 fan_div++;
1229 else if (reg != 0x00 && reg < 0x30 && fan_div > 0)
1230 fan_div--;
1231
1232 if (fan_div != data->fan_div[nr]) {
1233 dev_dbg(dev, "Modifying fan%d clock divider from %u to %u\n",
1234 nr + 1, div_from_reg(data->fan_div[nr]),
1235 div_from_reg(fan_div));
1236
1237 /* Preserve min limit if possible */
1238 if (data->has_fan_min & (1 << nr)) {
1239 fan_min = data->fan_min[nr];
1240 if (fan_div > data->fan_div[nr]) {
1241 if (fan_min != 255 && fan_min > 1)
1242 fan_min >>= 1;
1243 } else {
1244 if (fan_min != 255) {
1245 fan_min <<= 1;
1246 if (fan_min > 254)
1247 fan_min = 254;
1248 }
1249 }
1250 if (fan_min != data->fan_min[nr]) {
1251 data->fan_min[nr] = fan_min;
1252 nct6775_write_value(data, data->REG_FAN_MIN[nr],
1253 fan_min);
1254 }
1255 }
1256 data->fan_div[nr] = fan_div;
1257 nct6775_write_fan_div_common(data, nr);
1258 }
1259}
1260
77eb5b37
GR
1261static void nct6775_update_pwm(struct device *dev)
1262{
1263 struct nct6775_data *data = dev_get_drvdata(dev);
1264 int i, j;
cdcaeceb 1265 int fanmodecfg, reg;
77eb5b37
GR
1266 bool duty_is_dc;
1267
1268 for (i = 0; i < data->pwm_num; i++) {
1269 if (!(data->has_pwm & (1 << i)))
1270 continue;
1271
1272 duty_is_dc = data->REG_PWM_MODE[i] &&
1273 (nct6775_read_value(data, data->REG_PWM_MODE[i])
1274 & data->PWM_MODE_MASK[i]);
1275 data->pwm_mode[i] = duty_is_dc;
1276
1277 fanmodecfg = nct6775_read_value(data, data->REG_FAN_MODE[i]);
1278 for (j = 0; j < ARRAY_SIZE(data->REG_PWM); j++) {
1279 if (data->REG_PWM[j] && data->REG_PWM[j][i]) {
1280 data->pwm[j][i]
1281 = nct6775_read_value(data,
1282 data->REG_PWM[j][i]);
1283 }
1284 }
1285
1286 data->pwm_enable[i] = reg_to_pwm_enable(data->pwm[0][i],
1287 (fanmodecfg >> 4) & 7);
cdcaeceb
GR
1288
1289 if (!data->temp_tolerance[0][i] ||
1290 data->pwm_enable[i] != speed_cruise)
1291 data->temp_tolerance[0][i] = fanmodecfg & 0x0f;
1292 if (!data->target_speed_tolerance[i] ||
1293 data->pwm_enable[i] == speed_cruise) {
1294 u8 t = fanmodecfg & 0x0f;
1295 if (data->REG_TOLERANCE_H) {
1296 t |= (nct6775_read_value(data,
1297 data->REG_TOLERANCE_H[i]) & 0x70) >> 1;
1298 }
1299 data->target_speed_tolerance[i] = t;
1300 }
1301
1302 data->temp_tolerance[1][i] =
1303 nct6775_read_value(data,
1304 data->REG_CRITICAL_TEMP_TOLERANCE[i]);
1305
1306 reg = nct6775_read_value(data, data->REG_TEMP_SEL[i]);
1307 data->pwm_temp_sel[i] = reg & 0x1f;
1308 /* If fan can stop, report floor as 0 */
1309 if (reg & 0x80)
1310 data->pwm[2][i] = 0;
bbd8decd
GR
1311
1312 reg = nct6775_read_value(data, data->REG_WEIGHT_TEMP_SEL[i]);
1313 data->pwm_weight_temp_sel[i] = reg & 0x1f;
1314 /* If weight is disabled, report weight source as 0 */
1315 if (j == 1 && !(reg & 0x80))
1316 data->pwm_weight_temp_sel[i] = 0;
1317
1318 /* Weight temp data */
c409fd43 1319 for (j = 0; j < ARRAY_SIZE(data->weight_temp); j++) {
bbd8decd
GR
1320 data->weight_temp[j][i]
1321 = nct6775_read_value(data,
1322 data->REG_WEIGHT_TEMP[j][i]);
1323 }
cdcaeceb
GR
1324 }
1325}
1326
1327static void nct6775_update_pwm_limits(struct device *dev)
1328{
1329 struct nct6775_data *data = dev_get_drvdata(dev);
1330 int i, j;
1331 u8 reg;
1332 u16 reg_t;
1333
1334 for (i = 0; i < data->pwm_num; i++) {
1335 if (!(data->has_pwm & (1 << i)))
1336 continue;
1337
c409fd43 1338 for (j = 0; j < ARRAY_SIZE(data->fan_time); j++) {
cdcaeceb
GR
1339 data->fan_time[j][i] =
1340 nct6775_read_value(data, data->REG_FAN_TIME[j][i]);
1341 }
1342
1343 reg_t = nct6775_read_value(data, data->REG_TARGET[i]);
1344 /* Update only in matching mode or if never updated */
1345 if (!data->target_temp[i] ||
1346 data->pwm_enable[i] == thermal_cruise)
1347 data->target_temp[i] = reg_t & data->target_temp_mask;
1348 if (!data->target_speed[i] ||
1349 data->pwm_enable[i] == speed_cruise) {
1350 if (data->REG_TOLERANCE_H) {
1351 reg_t |= (nct6775_read_value(data,
1352 data->REG_TOLERANCE_H[i]) & 0x0f) << 8;
1353 }
1354 data->target_speed[i] = reg_t;
1355 }
1356
1357 for (j = 0; j < data->auto_pwm_num; j++) {
1358 data->auto_pwm[i][j] =
1359 nct6775_read_value(data,
1360 NCT6775_AUTO_PWM(data, i, j));
1361 data->auto_temp[i][j] =
1362 nct6775_read_value(data,
1363 NCT6775_AUTO_TEMP(data, i, j));
1364 }
1365
1366 /* critical auto_pwm temperature data */
1367 data->auto_temp[i][data->auto_pwm_num] =
1368 nct6775_read_value(data, data->REG_CRITICAL_TEMP[i]);
1369
1370 switch (data->kind) {
1371 case nct6775:
1372 reg = nct6775_read_value(data,
1373 NCT6775_REG_CRITICAL_ENAB[i]);
1374 data->auto_pwm[i][data->auto_pwm_num] =
1375 (reg & 0x02) ? 0xff : 0x00;
1376 break;
1377 case nct6776:
1378 data->auto_pwm[i][data->auto_pwm_num] = 0xff;
1379 break;
6c009501 1380 case nct6106:
cdcaeceb 1381 case nct6779:
578ab5f0 1382 case nct6791:
cdcaeceb 1383 reg = nct6775_read_value(data,
6c009501
GR
1384 data->REG_CRITICAL_PWM_ENABLE[i]);
1385 if (reg & data->CRITICAL_PWM_ENABLE_MASK)
1386 reg = nct6775_read_value(data,
1387 data->REG_CRITICAL_PWM[i]);
cdcaeceb 1388 else
6c009501
GR
1389 reg = 0xff;
1390 data->auto_pwm[i][data->auto_pwm_num] = reg;
cdcaeceb
GR
1391 break;
1392 }
77eb5b37
GR
1393 }
1394}
1395
9de2e2e8
GR
1396static struct nct6775_data *nct6775_update_device(struct device *dev)
1397{
1398 struct nct6775_data *data = dev_get_drvdata(dev);
aa136e5d 1399 int i, j;
9de2e2e8
GR
1400
1401 mutex_lock(&data->update_lock);
1402
6445e660 1403 if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
9de2e2e8 1404 || !data->valid) {
1c65dc36
GR
1405 /* Fan clock dividers */
1406 nct6775_update_fan_div_common(data);
1407
9de2e2e8
GR
1408 /* Measured voltages and limits */
1409 for (i = 0; i < data->in_num; i++) {
1410 if (!(data->have_in & (1 << i)))
1411 continue;
1412
1413 data->in[i][0] = nct6775_read_value(data,
1414 data->REG_VIN[i]);
1415 data->in[i][1] = nct6775_read_value(data,
1416 data->REG_IN_MINMAX[0][i]);
1417 data->in[i][2] = nct6775_read_value(data,
1418 data->REG_IN_MINMAX[1][i]);
1419 }
1420
1c65dc36 1421 /* Measured fan speeds and limits */
c409fd43 1422 for (i = 0; i < ARRAY_SIZE(data->rpm); i++) {
1c65dc36
GR
1423 u16 reg;
1424
1425 if (!(data->has_fan & (1 << i)))
1426 continue;
1427
1428 reg = nct6775_read_value(data, data->REG_FAN[i]);
1429 data->rpm[i] = data->fan_from_reg(reg,
1430 data->fan_div[i]);
1431
1432 if (data->has_fan_min & (1 << i))
1433 data->fan_min[i] = nct6775_read_value(data,
1434 data->REG_FAN_MIN[i]);
5c25d954 1435 data->fan_pulses[i] =
6c009501
GR
1436 (nct6775_read_value(data, data->REG_FAN_PULSES[i])
1437 >> data->FAN_PULSE_SHIFT[i]) & 0x03;
1c65dc36
GR
1438
1439 nct6775_select_fan_div(dev, data, i, reg);
1440 }
1441
77eb5b37 1442 nct6775_update_pwm(dev);
cdcaeceb 1443 nct6775_update_pwm_limits(dev);
77eb5b37 1444
aa136e5d
GR
1445 /* Measured temperatures and limits */
1446 for (i = 0; i < NUM_TEMP; i++) {
1447 if (!(data->have_temp & (1 << i)))
1448 continue;
c409fd43 1449 for (j = 0; j < ARRAY_SIZE(data->reg_temp); j++) {
aa136e5d
GR
1450 if (data->reg_temp[j][i])
1451 data->temp[j][i]
1452 = nct6775_read_temp(data,
1453 data->reg_temp[j][i]);
1454 }
45a5b3a1
GR
1455 if (i >= NUM_TEMP_FIXED ||
1456 !(data->have_temp_fixed & (1 << i)))
aa136e5d
GR
1457 continue;
1458 data->temp_offset[i]
1459 = nct6775_read_value(data, data->REG_TEMP_OFFSET[i]);
1460 }
1461
9de2e2e8
GR
1462 data->alarms = 0;
1463 for (i = 0; i < NUM_REG_ALARM; i++) {
1464 u8 alarm;
1465 if (!data->REG_ALARM[i])
1466 continue;
1467 alarm = nct6775_read_value(data, data->REG_ALARM[i]);
1468 data->alarms |= ((u64)alarm) << (i << 3);
1469 }
1470
30846993
GR
1471 data->beeps = 0;
1472 for (i = 0; i < NUM_REG_BEEP; i++) {
1473 u8 beep;
1474 if (!data->REG_BEEP[i])
1475 continue;
1476 beep = nct6775_read_value(data, data->REG_BEEP[i]);
1477 data->beeps |= ((u64)beep) << (i << 3);
1478 }
1479
9de2e2e8
GR
1480 data->last_updated = jiffies;
1481 data->valid = true;
1482 }
1483
1484 mutex_unlock(&data->update_lock);
1485 return data;
1486}
1487
1488/*
1489 * Sysfs callback functions
1490 */
1491static ssize_t
1492show_in_reg(struct device *dev, struct device_attribute *attr, char *buf)
1493{
1494 struct nct6775_data *data = nct6775_update_device(dev);
1495 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
1496 int nr = sattr->nr;
1497 int index = sattr->index;
1498 return sprintf(buf, "%ld\n", in_from_reg(data->in[nr][index], nr));
1499}
1500
1501static ssize_t
1502store_in_reg(struct device *dev, struct device_attribute *attr, const char *buf,
1503 size_t count)
1504{
1505 struct nct6775_data *data = dev_get_drvdata(dev);
1506 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
1507 int nr = sattr->nr;
1508 int index = sattr->index;
1509 unsigned long val;
1510 int err = kstrtoul(buf, 10, &val);
1511 if (err < 0)
1512 return err;
1513 mutex_lock(&data->update_lock);
1514 data->in[nr][index] = in_to_reg(val, nr);
6445e660 1515 nct6775_write_value(data, data->REG_IN_MINMAX[index - 1][nr],
9de2e2e8
GR
1516 data->in[nr][index]);
1517 mutex_unlock(&data->update_lock);
1518 return count;
1519}
1520
1521static ssize_t
1522show_alarm(struct device *dev, struct device_attribute *attr, char *buf)
1523{
1524 struct nct6775_data *data = nct6775_update_device(dev);
1525 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1526 int nr = data->ALARM_BITS[sattr->index];
1527 return sprintf(buf, "%u\n",
1528 (unsigned int)((data->alarms >> nr) & 0x01));
1529}
1530
b1d2bff6
GR
1531static int find_temp_source(struct nct6775_data *data, int index, int count)
1532{
1533 int source = data->temp_src[index];
1534 int nr;
1535
1536 for (nr = 0; nr < count; nr++) {
1537 int src;
1538
1539 src = nct6775_read_value(data,
1540 data->REG_TEMP_SOURCE[nr]) & 0x1f;
1541 if (src == source)
1542 return nr;
1543 }
e8ab508c 1544 return -ENODEV;
b1d2bff6
GR
1545}
1546
1547static ssize_t
1548show_temp_alarm(struct device *dev, struct device_attribute *attr, char *buf)
1549{
1550 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1551 struct nct6775_data *data = nct6775_update_device(dev);
1552 unsigned int alarm = 0;
1553 int nr;
1554
1555 /*
1556 * For temperatures, there is no fixed mapping from registers to alarm
1557 * bits. Alarm bits are determined by the temperature source mapping.
1558 */
1559 nr = find_temp_source(data, sattr->index, data->num_temp_alarms);
1560 if (nr >= 0) {
1561 int bit = data->ALARM_BITS[nr + TEMP_ALARM_BASE];
1562 alarm = (data->alarms >> bit) & 0x01;
1563 }
1564 return sprintf(buf, "%u\n", alarm);
1565}
1566
30846993
GR
1567static ssize_t
1568show_beep(struct device *dev, struct device_attribute *attr, char *buf)
1569{
1570 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1571 struct nct6775_data *data = nct6775_update_device(dev);
1572 int nr = data->BEEP_BITS[sattr->index];
1573
1574 return sprintf(buf, "%u\n",
1575 (unsigned int)((data->beeps >> nr) & 0x01));
1576}
1577
1578static ssize_t
1579store_beep(struct device *dev, struct device_attribute *attr, const char *buf,
1580 size_t count)
1581{
1582 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
1583 struct nct6775_data *data = dev_get_drvdata(dev);
1584 int nr = data->BEEP_BITS[sattr->index];
1585 int regindex = nr >> 3;
1586 unsigned long val;
1587
1588 int err = kstrtoul(buf, 10, &val);
1589 if (err < 0)
1590 return err;
1591 if (val > 1)
1592 return -EINVAL;
1593
1594 mutex_lock(&data->update_lock);
1595 if (val)
1596 data->beeps |= (1ULL << nr);
1597 else
1598 data->beeps &= ~(1ULL << nr);
1599 nct6775_write_value(data, data->REG_BEEP[regindex],
1600 (data->beeps >> (regindex << 3)) & 0xff);
1601 mutex_unlock(&data->update_lock);
1602 return count;
1603}
1604
1605static ssize_t
1606show_temp_beep(struct device *dev, struct device_attribute *attr, char *buf)
1607{
1608 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1609 struct nct6775_data *data = nct6775_update_device(dev);
1610 unsigned int beep = 0;
1611 int nr;
1612
1613 /*
1614 * For temperatures, there is no fixed mapping from registers to beep
1615 * enable bits. Beep enable bits are determined by the temperature
1616 * source mapping.
1617 */
1618 nr = find_temp_source(data, sattr->index, data->num_temp_beeps);
1619 if (nr >= 0) {
1620 int bit = data->BEEP_BITS[nr + TEMP_ALARM_BASE];
1621 beep = (data->beeps >> bit) & 0x01;
1622 }
1623 return sprintf(buf, "%u\n", beep);
1624}
1625
1626static ssize_t
1627store_temp_beep(struct device *dev, struct device_attribute *attr,
1628 const char *buf, size_t count)
1629{
1630 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
1631 struct nct6775_data *data = dev_get_drvdata(dev);
1632 int nr, bit, regindex;
1633 unsigned long val;
1634
1635 int err = kstrtoul(buf, 10, &val);
1636 if (err < 0)
1637 return err;
1638 if (val > 1)
1639 return -EINVAL;
1640
1641 nr = find_temp_source(data, sattr->index, data->num_temp_beeps);
1642 if (nr < 0)
e8ab508c 1643 return nr;
30846993
GR
1644
1645 bit = data->BEEP_BITS[nr + TEMP_ALARM_BASE];
1646 regindex = bit >> 3;
1647
1648 mutex_lock(&data->update_lock);
1649 if (val)
1650 data->beeps |= (1ULL << bit);
1651 else
1652 data->beeps &= ~(1ULL << bit);
1653 nct6775_write_value(data, data->REG_BEEP[regindex],
1654 (data->beeps >> (regindex << 3)) & 0xff);
1655 mutex_unlock(&data->update_lock);
1656
1657 return count;
1658}
1659
f73cf632
GR
1660static umode_t nct6775_in_is_visible(struct kobject *kobj,
1661 struct attribute *attr, int index)
1662{
1663 struct device *dev = container_of(kobj, struct device, kobj);
1664 struct nct6775_data *data = dev_get_drvdata(dev);
30846993 1665 int in = index / 5; /* voltage index */
f73cf632
GR
1666
1667 if (!(data->have_in & (1 << in)))
1668 return 0;
1669
1670 return attr->mode;
1671}
1672
1673SENSOR_TEMPLATE_2(in_input, "in%d_input", S_IRUGO, show_in_reg, NULL, 0, 0);
1674SENSOR_TEMPLATE(in_alarm, "in%d_alarm", S_IRUGO, show_alarm, NULL, 0);
30846993
GR
1675SENSOR_TEMPLATE(in_beep, "in%d_beep", S_IWUSR | S_IRUGO, show_beep, store_beep,
1676 0);
f73cf632
GR
1677SENSOR_TEMPLATE_2(in_min, "in%d_min", S_IWUSR | S_IRUGO, show_in_reg,
1678 store_in_reg, 0, 1);
1679SENSOR_TEMPLATE_2(in_max, "in%d_max", S_IWUSR | S_IRUGO, show_in_reg,
1680 store_in_reg, 0, 2);
1681
1682/*
1683 * nct6775_in_is_visible uses the index into the following array
1684 * to determine if attributes should be created or not.
1685 * Any change in order or content must be matched.
1686 */
1687static struct sensor_device_template *nct6775_attributes_in_template[] = {
1688 &sensor_dev_template_in_input,
1689 &sensor_dev_template_in_alarm,
30846993 1690 &sensor_dev_template_in_beep,
f73cf632
GR
1691 &sensor_dev_template_in_min,
1692 &sensor_dev_template_in_max,
1693 NULL
9de2e2e8
GR
1694};
1695
f73cf632
GR
1696static struct sensor_template_group nct6775_in_template_group = {
1697 .templates = nct6775_attributes_in_template,
1698 .is_visible = nct6775_in_is_visible,
9de2e2e8
GR
1699};
1700
1c65dc36
GR
1701static ssize_t
1702show_fan(struct device *dev, struct device_attribute *attr, char *buf)
1703{
1704 struct nct6775_data *data = nct6775_update_device(dev);
1705 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1706 int nr = sattr->index;
1707 return sprintf(buf, "%d\n", data->rpm[nr]);
1708}
1709
1710static ssize_t
1711show_fan_min(struct device *dev, struct device_attribute *attr, char *buf)
1712{
1713 struct nct6775_data *data = nct6775_update_device(dev);
1714 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1715 int nr = sattr->index;
1716 return sprintf(buf, "%d\n",
1717 data->fan_from_reg_min(data->fan_min[nr],
1718 data->fan_div[nr]));
1719}
1720
1721static ssize_t
1722show_fan_div(struct device *dev, struct device_attribute *attr, char *buf)
1723{
1724 struct nct6775_data *data = nct6775_update_device(dev);
1725 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1726 int nr = sattr->index;
1727 return sprintf(buf, "%u\n", div_from_reg(data->fan_div[nr]));
1728}
1729
1730static ssize_t
1731store_fan_min(struct device *dev, struct device_attribute *attr,
1732 const char *buf, size_t count)
1733{
1734 struct nct6775_data *data = dev_get_drvdata(dev);
1735 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1736 int nr = sattr->index;
1737 unsigned long val;
1738 int err;
1739 unsigned int reg;
1740 u8 new_div;
1741
1742 err = kstrtoul(buf, 10, &val);
1743 if (err < 0)
1744 return err;
1745
1746 mutex_lock(&data->update_lock);
1747 if (!data->has_fan_div) {
1748 /* NCT6776F or NCT6779D; we know this is a 13 bit register */
1749 if (!val) {
1750 val = 0xff1f;
1751 } else {
1752 if (val > 1350000U)
1753 val = 135000U;
1754 val = 1350000U / val;
1755 val = (val & 0x1f) | ((val << 3) & 0xff00);
1756 }
1757 data->fan_min[nr] = val;
1758 goto write_min; /* Leave fan divider alone */
1759 }
1760 if (!val) {
1761 /* No min limit, alarm disabled */
1762 data->fan_min[nr] = 255;
1763 new_div = data->fan_div[nr]; /* No change */
1764 dev_info(dev, "fan%u low limit and alarm disabled\n", nr + 1);
1765 goto write_div;
1766 }
1767 reg = 1350000U / val;
1768 if (reg >= 128 * 255) {
1769 /*
1770 * Speed below this value cannot possibly be represented,
1771 * even with the highest divider (128)
1772 */
1773 data->fan_min[nr] = 254;
1774 new_div = 7; /* 128 == (1 << 7) */
1775 dev_warn(dev,
1776 "fan%u low limit %lu below minimum %u, set to minimum\n",
1777 nr + 1, val, data->fan_from_reg_min(254, 7));
1778 } else if (!reg) {
1779 /*
1780 * Speed above this value cannot possibly be represented,
1781 * even with the lowest divider (1)
1782 */
1783 data->fan_min[nr] = 1;
1784 new_div = 0; /* 1 == (1 << 0) */
1785 dev_warn(dev,
1786 "fan%u low limit %lu above maximum %u, set to maximum\n",
1787 nr + 1, val, data->fan_from_reg_min(1, 0));
1788 } else {
1789 /*
1790 * Automatically pick the best divider, i.e. the one such
1791 * that the min limit will correspond to a register value
1792 * in the 96..192 range
1793 */
1794 new_div = 0;
1795 while (reg > 192 && new_div < 7) {
1796 reg >>= 1;
1797 new_div++;
1798 }
1799 data->fan_min[nr] = reg;
1800 }
1801
1802write_div:
1803 /*
1804 * Write both the fan clock divider (if it changed) and the new
1805 * fan min (unconditionally)
1806 */
1807 if (new_div != data->fan_div[nr]) {
1808 dev_dbg(dev, "fan%u clock divider changed from %u to %u\n",
1809 nr + 1, div_from_reg(data->fan_div[nr]),
1810 div_from_reg(new_div));
1811 data->fan_div[nr] = new_div;
1812 nct6775_write_fan_div_common(data, nr);
1813 /* Give the chip time to sample a new speed value */
1814 data->last_updated = jiffies;
1815 }
1816
1817write_min:
1818 nct6775_write_value(data, data->REG_FAN_MIN[nr], data->fan_min[nr]);
1819 mutex_unlock(&data->update_lock);
1820
1821 return count;
1822}
1823
5c25d954
GR
1824static ssize_t
1825show_fan_pulses(struct device *dev, struct device_attribute *attr, char *buf)
1826{
1827 struct nct6775_data *data = nct6775_update_device(dev);
1828 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1829 int p = data->fan_pulses[sattr->index];
1830
1831 return sprintf(buf, "%d\n", p ? : 4);
1832}
1833
1834static ssize_t
1835store_fan_pulses(struct device *dev, struct device_attribute *attr,
1836 const char *buf, size_t count)
1837{
1838 struct nct6775_data *data = dev_get_drvdata(dev);
1839 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1840 int nr = sattr->index;
1841 unsigned long val;
1842 int err;
6c009501 1843 u8 reg;
5c25d954
GR
1844
1845 err = kstrtoul(buf, 10, &val);
1846 if (err < 0)
1847 return err;
1848
1849 if (val > 4)
1850 return -EINVAL;
1851
1852 mutex_lock(&data->update_lock);
1853 data->fan_pulses[nr] = val & 3;
6c009501
GR
1854 reg = nct6775_read_value(data, data->REG_FAN_PULSES[nr]);
1855 reg &= ~(0x03 << data->FAN_PULSE_SHIFT[nr]);
1856 reg |= (val & 3) << data->FAN_PULSE_SHIFT[nr];
1857 nct6775_write_value(data, data->REG_FAN_PULSES[nr], reg);
5c25d954
GR
1858 mutex_unlock(&data->update_lock);
1859
1860 return count;
1861}
1862
f73cf632
GR
1863static umode_t nct6775_fan_is_visible(struct kobject *kobj,
1864 struct attribute *attr, int index)
1865{
1866 struct device *dev = container_of(kobj, struct device, kobj);
1867 struct nct6775_data *data = dev_get_drvdata(dev);
30846993
GR
1868 int fan = index / 6; /* fan index */
1869 int nr = index % 6; /* attribute index */
1c65dc36 1870
f73cf632
GR
1871 if (!(data->has_fan & (1 << fan)))
1872 return 0;
1c65dc36 1873
f73cf632
GR
1874 if (nr == 1 && data->ALARM_BITS[FAN_ALARM_BASE + fan] == -1)
1875 return 0;
30846993 1876 if (nr == 2 && data->BEEP_BITS[FAN_ALARM_BASE + fan] == -1)
f73cf632 1877 return 0;
30846993
GR
1878 if (nr == 4 && !(data->has_fan_min & (1 << fan)))
1879 return 0;
1880 if (nr == 5 && data->kind != nct6775)
f73cf632
GR
1881 return 0;
1882
1883 return attr->mode;
1884}
1c65dc36 1885
f73cf632
GR
1886SENSOR_TEMPLATE(fan_input, "fan%d_input", S_IRUGO, show_fan, NULL, 0);
1887SENSOR_TEMPLATE(fan_alarm, "fan%d_alarm", S_IRUGO, show_alarm, NULL,
1888 FAN_ALARM_BASE);
30846993
GR
1889SENSOR_TEMPLATE(fan_beep, "fan%d_beep", S_IWUSR | S_IRUGO, show_beep,
1890 store_beep, FAN_ALARM_BASE);
f73cf632
GR
1891SENSOR_TEMPLATE(fan_pulses, "fan%d_pulses", S_IWUSR | S_IRUGO, show_fan_pulses,
1892 store_fan_pulses, 0);
1893SENSOR_TEMPLATE(fan_min, "fan%d_min", S_IWUSR | S_IRUGO, show_fan_min,
1894 store_fan_min, 0);
1895SENSOR_TEMPLATE(fan_div, "fan%d_div", S_IRUGO, show_fan_div, NULL, 0);
1896
1897/*
1898 * nct6775_fan_is_visible uses the index into the following array
1899 * to determine if attributes should be created or not.
1900 * Any change in order or content must be matched.
1901 */
1902static struct sensor_device_template *nct6775_attributes_fan_template[] = {
1903 &sensor_dev_template_fan_input,
1904 &sensor_dev_template_fan_alarm, /* 1 */
30846993 1905 &sensor_dev_template_fan_beep, /* 2 */
f73cf632 1906 &sensor_dev_template_fan_pulses,
30846993
GR
1907 &sensor_dev_template_fan_min, /* 4 */
1908 &sensor_dev_template_fan_div, /* 5 */
f73cf632 1909 NULL
5c25d954
GR
1910};
1911
f73cf632
GR
1912static struct sensor_template_group nct6775_fan_template_group = {
1913 .templates = nct6775_attributes_fan_template,
1914 .is_visible = nct6775_fan_is_visible,
1915 .base = 1,
1c65dc36
GR
1916};
1917
aa136e5d
GR
1918static ssize_t
1919show_temp_label(struct device *dev, struct device_attribute *attr, char *buf)
1920{
1921 struct nct6775_data *data = nct6775_update_device(dev);
1922 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1923 int nr = sattr->index;
1924 return sprintf(buf, "%s\n", data->temp_label[data->temp_src[nr]]);
1925}
1926
1927static ssize_t
1928show_temp(struct device *dev, struct device_attribute *attr, char *buf)
1929{
1930 struct nct6775_data *data = nct6775_update_device(dev);
1931 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
1932 int nr = sattr->nr;
1933 int index = sattr->index;
1934
1935 return sprintf(buf, "%d\n", LM75_TEMP_FROM_REG(data->temp[index][nr]));
1936}
1937
1938static ssize_t
1939store_temp(struct device *dev, struct device_attribute *attr, const char *buf,
1940 size_t count)
1941{
1942 struct nct6775_data *data = dev_get_drvdata(dev);
1943 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
1944 int nr = sattr->nr;
1945 int index = sattr->index;
1946 int err;
1947 long val;
1948
1949 err = kstrtol(buf, 10, &val);
1950 if (err < 0)
1951 return err;
1952
1953 mutex_lock(&data->update_lock);
1954 data->temp[index][nr] = LM75_TEMP_TO_REG(val);
1955 nct6775_write_temp(data, data->reg_temp[index][nr],
1956 data->temp[index][nr]);
1957 mutex_unlock(&data->update_lock);
1958 return count;
1959}
1960
1961static ssize_t
1962show_temp_offset(struct device *dev, struct device_attribute *attr, char *buf)
1963{
1964 struct nct6775_data *data = nct6775_update_device(dev);
1965 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1966
1967 return sprintf(buf, "%d\n", data->temp_offset[sattr->index] * 1000);
1968}
1969
1970static ssize_t
1971store_temp_offset(struct device *dev, struct device_attribute *attr,
1972 const char *buf, size_t count)
1973{
1974 struct nct6775_data *data = dev_get_drvdata(dev);
1975 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1976 int nr = sattr->index;
1977 long val;
1978 int err;
1979
1980 err = kstrtol(buf, 10, &val);
1981 if (err < 0)
1982 return err;
1983
1984 val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), -128, 127);
1985
1986 mutex_lock(&data->update_lock);
1987 data->temp_offset[nr] = val;
1988 nct6775_write_value(data, data->REG_TEMP_OFFSET[nr], val);
1989 mutex_unlock(&data->update_lock);
1990
1991 return count;
1992}
1993
1994static ssize_t
1995show_temp_type(struct device *dev, struct device_attribute *attr, char *buf)
1996{
1997 struct nct6775_data *data = nct6775_update_device(dev);
1998 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1999 int nr = sattr->index;
2000 return sprintf(buf, "%d\n", (int)data->temp_type[nr]);
2001}
2002
2003static ssize_t
2004store_temp_type(struct device *dev, struct device_attribute *attr,
2005 const char *buf, size_t count)
2006{
2007 struct nct6775_data *data = nct6775_update_device(dev);
2008 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2009 int nr = sattr->index;
2010 unsigned long val;
2011 int err;
6c009501 2012 u8 vbat, diode, vbit, dbit;
aa136e5d
GR
2013
2014 err = kstrtoul(buf, 10, &val);
2015 if (err < 0)
2016 return err;
2017
2018 if (val != 1 && val != 3 && val != 4)
2019 return -EINVAL;
2020
2021 mutex_lock(&data->update_lock);
2022
2023 data->temp_type[nr] = val;
6c009501
GR
2024 vbit = 0x02 << nr;
2025 dbit = data->DIODE_MASK << nr;
2026 vbat = nct6775_read_value(data, data->REG_VBAT) & ~vbit;
2027 diode = nct6775_read_value(data, data->REG_DIODE) & ~dbit;
aa136e5d
GR
2028 switch (val) {
2029 case 1: /* CPU diode (diode, current mode) */
6c009501
GR
2030 vbat |= vbit;
2031 diode |= dbit;
aa136e5d
GR
2032 break;
2033 case 3: /* diode, voltage mode */
6c009501 2034 vbat |= dbit;
aa136e5d
GR
2035 break;
2036 case 4: /* thermistor */
2037 break;
2038 }
2039 nct6775_write_value(data, data->REG_VBAT, vbat);
2040 nct6775_write_value(data, data->REG_DIODE, diode);
2041
2042 mutex_unlock(&data->update_lock);
2043 return count;
2044}
2045
f73cf632
GR
2046static umode_t nct6775_temp_is_visible(struct kobject *kobj,
2047 struct attribute *attr, int index)
2048{
2049 struct device *dev = container_of(kobj, struct device, kobj);
2050 struct nct6775_data *data = dev_get_drvdata(dev);
30846993
GR
2051 int temp = index / 10; /* temp index */
2052 int nr = index % 10; /* attribute index */
aa136e5d 2053
f73cf632
GR
2054 if (!(data->have_temp & (1 << temp)))
2055 return 0;
aa136e5d 2056
f73cf632
GR
2057 if (nr == 2 && find_temp_source(data, temp, data->num_temp_alarms) < 0)
2058 return 0; /* alarm */
aa136e5d 2059
30846993
GR
2060 if (nr == 3 && find_temp_source(data, temp, data->num_temp_beeps) < 0)
2061 return 0; /* beep */
2062
2063 if (nr == 4 && !data->reg_temp[1][temp]) /* max */
f73cf632 2064 return 0;
aa136e5d 2065
30846993 2066 if (nr == 5 && !data->reg_temp[2][temp]) /* max_hyst */
f73cf632 2067 return 0;
aa136e5d 2068
30846993 2069 if (nr == 6 && !data->reg_temp[3][temp]) /* crit */
f73cf632
GR
2070 return 0;
2071
30846993 2072 if (nr == 7 && !data->reg_temp[4][temp]) /* lcrit */
b7a61353
GR
2073 return 0;
2074
2075 /* offset and type only apply to fixed sensors */
30846993 2076 if (nr > 7 && !(data->have_temp_fixed & (1 << temp)))
f73cf632 2077 return 0;
aa136e5d 2078
f73cf632
GR
2079 return attr->mode;
2080}
2081
2082SENSOR_TEMPLATE_2(temp_input, "temp%d_input", S_IRUGO, show_temp, NULL, 0, 0);
2083SENSOR_TEMPLATE(temp_label, "temp%d_label", S_IRUGO, show_temp_label, NULL, 0);
2084SENSOR_TEMPLATE_2(temp_max, "temp%d_max", S_IRUGO | S_IWUSR, show_temp,
2085 store_temp, 0, 1);
2086SENSOR_TEMPLATE_2(temp_max_hyst, "temp%d_max_hyst", S_IRUGO | S_IWUSR,
2087 show_temp, store_temp, 0, 2);
2088SENSOR_TEMPLATE_2(temp_crit, "temp%d_crit", S_IRUGO | S_IWUSR, show_temp,
2089 store_temp, 0, 3);
b7a61353
GR
2090SENSOR_TEMPLATE_2(temp_lcrit, "temp%d_lcrit", S_IRUGO | S_IWUSR, show_temp,
2091 store_temp, 0, 4);
f73cf632
GR
2092SENSOR_TEMPLATE(temp_offset, "temp%d_offset", S_IRUGO | S_IWUSR,
2093 show_temp_offset, store_temp_offset, 0);
2094SENSOR_TEMPLATE(temp_type, "temp%d_type", S_IRUGO | S_IWUSR, show_temp_type,
2095 store_temp_type, 0);
2096SENSOR_TEMPLATE(temp_alarm, "temp%d_alarm", S_IRUGO, show_temp_alarm, NULL, 0);
30846993
GR
2097SENSOR_TEMPLATE(temp_beep, "temp%d_beep", S_IRUGO | S_IWUSR, show_temp_beep,
2098 store_temp_beep, 0);
f73cf632
GR
2099
2100/*
2101 * nct6775_temp_is_visible uses the index into the following array
2102 * to determine if attributes should be created or not.
2103 * Any change in order or content must be matched.
2104 */
2105static struct sensor_device_template *nct6775_attributes_temp_template[] = {
2106 &sensor_dev_template_temp_input,
2107 &sensor_dev_template_temp_label,
2108 &sensor_dev_template_temp_alarm, /* 2 */
30846993
GR
2109 &sensor_dev_template_temp_beep, /* 3 */
2110 &sensor_dev_template_temp_max, /* 4 */
2111 &sensor_dev_template_temp_max_hyst, /* 5 */
2112 &sensor_dev_template_temp_crit, /* 6 */
2113 &sensor_dev_template_temp_lcrit, /* 7 */
2114 &sensor_dev_template_temp_offset, /* 8 */
2115 &sensor_dev_template_temp_type, /* 9 */
f73cf632 2116 NULL
aa136e5d
GR
2117};
2118
f73cf632
GR
2119static struct sensor_template_group nct6775_temp_template_group = {
2120 .templates = nct6775_attributes_temp_template,
2121 .is_visible = nct6775_temp_is_visible,
2122 .base = 1,
aa136e5d
GR
2123};
2124
77eb5b37
GR
2125static ssize_t
2126show_pwm_mode(struct device *dev, struct device_attribute *attr, char *buf)
2127{
2128 struct nct6775_data *data = nct6775_update_device(dev);
2129 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2130
2131 return sprintf(buf, "%d\n", !data->pwm_mode[sattr->index]);
2132}
2133
2134static ssize_t
2135store_pwm_mode(struct device *dev, struct device_attribute *attr,
2136 const char *buf, size_t count)
2137{
2138 struct nct6775_data *data = dev_get_drvdata(dev);
2139 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2140 int nr = sattr->index;
2141 unsigned long val;
2142 int err;
2143 u8 reg;
2144
2145 err = kstrtoul(buf, 10, &val);
2146 if (err < 0)
2147 return err;
2148
2149 if (val > 1)
2150 return -EINVAL;
2151
2152 /* Setting DC mode is not supported for all chips/channels */
2153 if (data->REG_PWM_MODE[nr] == 0) {
2154 if (val)
2155 return -EINVAL;
2156 return count;
2157 }
2158
2159 mutex_lock(&data->update_lock);
2160 data->pwm_mode[nr] = val;
2161 reg = nct6775_read_value(data, data->REG_PWM_MODE[nr]);
2162 reg &= ~data->PWM_MODE_MASK[nr];
2163 if (val)
2164 reg |= data->PWM_MODE_MASK[nr];
2165 nct6775_write_value(data, data->REG_PWM_MODE[nr], reg);
2166 mutex_unlock(&data->update_lock);
2167 return count;
2168}
2169
2170static ssize_t
2171show_pwm(struct device *dev, struct device_attribute *attr, char *buf)
2172{
2173 struct nct6775_data *data = nct6775_update_device(dev);
2174 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2175 int nr = sattr->nr;
2176 int index = sattr->index;
2177 int pwm;
2178
2179 /*
2180 * For automatic fan control modes, show current pwm readings.
2181 * Otherwise, show the configured value.
2182 */
2183 if (index == 0 && data->pwm_enable[nr] > manual)
2184 pwm = nct6775_read_value(data, data->REG_PWM_READ[nr]);
2185 else
2186 pwm = data->pwm[index][nr];
2187
2188 return sprintf(buf, "%d\n", pwm);
2189}
2190
2191static ssize_t
2192store_pwm(struct device *dev, struct device_attribute *attr, const char *buf,
2193 size_t count)
2194{
2195 struct nct6775_data *data = dev_get_drvdata(dev);
2196 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2197 int nr = sattr->nr;
2198 int index = sattr->index;
2199 unsigned long val;
bbd8decd
GR
2200 int minval[7] = { 0, 1, 1, data->pwm[2][nr], 0, 0, 0 };
2201 int maxval[7]
2202 = { 255, 255, data->pwm[3][nr] ? : 255, 255, 255, 255, 255 };
77eb5b37 2203 int err;
cdcaeceb 2204 u8 reg;
77eb5b37
GR
2205
2206 err = kstrtoul(buf, 10, &val);
2207 if (err < 0)
2208 return err;
cdcaeceb 2209 val = clamp_val(val, minval[index], maxval[index]);
77eb5b37
GR
2210
2211 mutex_lock(&data->update_lock);
2212 data->pwm[index][nr] = val;
2213 nct6775_write_value(data, data->REG_PWM[index][nr], val);
cdcaeceb
GR
2214 if (index == 2) { /* floor: disable if val == 0 */
2215 reg = nct6775_read_value(data, data->REG_TEMP_SEL[nr]);
2216 reg &= 0x7f;
2217 if (val)
2218 reg |= 0x80;
2219 nct6775_write_value(data, data->REG_TEMP_SEL[nr], reg);
2220 }
77eb5b37
GR
2221 mutex_unlock(&data->update_lock);
2222 return count;
2223}
2224
cdcaeceb
GR
2225/* Returns 0 if OK, -EINVAL otherwise */
2226static int check_trip_points(struct nct6775_data *data, int nr)
2227{
2228 int i;
2229
2230 for (i = 0; i < data->auto_pwm_num - 1; i++) {
2231 if (data->auto_temp[nr][i] > data->auto_temp[nr][i + 1])
2232 return -EINVAL;
2233 }
2234 for (i = 0; i < data->auto_pwm_num - 1; i++) {
2235 if (data->auto_pwm[nr][i] > data->auto_pwm[nr][i + 1])
2236 return -EINVAL;
2237 }
2238 /* validate critical temperature and pwm if enabled (pwm > 0) */
2239 if (data->auto_pwm[nr][data->auto_pwm_num]) {
2240 if (data->auto_temp[nr][data->auto_pwm_num - 1] >
2241 data->auto_temp[nr][data->auto_pwm_num] ||
2242 data->auto_pwm[nr][data->auto_pwm_num - 1] >
2243 data->auto_pwm[nr][data->auto_pwm_num])
2244 return -EINVAL;
2245 }
2246 return 0;
2247}
2248
2249static void pwm_update_registers(struct nct6775_data *data, int nr)
2250{
2251 u8 reg;
2252
2253 switch (data->pwm_enable[nr]) {
2254 case off:
2255 case manual:
2256 break;
2257 case speed_cruise:
2258 reg = nct6775_read_value(data, data->REG_FAN_MODE[nr]);
2259 reg = (reg & ~data->tolerance_mask) |
2260 (data->target_speed_tolerance[nr] & data->tolerance_mask);
2261 nct6775_write_value(data, data->REG_FAN_MODE[nr], reg);
2262 nct6775_write_value(data, data->REG_TARGET[nr],
2263 data->target_speed[nr] & 0xff);
2264 if (data->REG_TOLERANCE_H) {
2265 reg = (data->target_speed[nr] >> 8) & 0x0f;
2266 reg |= (data->target_speed_tolerance[nr] & 0x38) << 1;
2267 nct6775_write_value(data,
2268 data->REG_TOLERANCE_H[nr],
2269 reg);
2270 }
2271 break;
2272 case thermal_cruise:
2273 nct6775_write_value(data, data->REG_TARGET[nr],
2274 data->target_temp[nr]);
2275 /* intentional */
2276 default:
2277 reg = nct6775_read_value(data, data->REG_FAN_MODE[nr]);
2278 reg = (reg & ~data->tolerance_mask) |
2279 data->temp_tolerance[0][nr];
2280 nct6775_write_value(data, data->REG_FAN_MODE[nr], reg);
2281 break;
2282 }
2283}
2284
77eb5b37
GR
2285static ssize_t
2286show_pwm_enable(struct device *dev, struct device_attribute *attr, char *buf)
2287{
2288 struct nct6775_data *data = nct6775_update_device(dev);
2289 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2290
2291 return sprintf(buf, "%d\n", data->pwm_enable[sattr->index]);
2292}
2293
2294static ssize_t
2295store_pwm_enable(struct device *dev, struct device_attribute *attr,
2296 const char *buf, size_t count)
2297{
2298 struct nct6775_data *data = dev_get_drvdata(dev);
2299 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2300 int nr = sattr->index;
2301 unsigned long val;
2302 int err;
2303 u16 reg;
2304
2305 err = kstrtoul(buf, 10, &val);
2306 if (err < 0)
2307 return err;
2308
2309 if (val > sf4)
2310 return -EINVAL;
2311
2312 if (val == sf3 && data->kind != nct6775)
2313 return -EINVAL;
2314
cdcaeceb
GR
2315 if (val == sf4 && check_trip_points(data, nr)) {
2316 dev_err(dev, "Inconsistent trip points, not switching to SmartFan IV mode\n");
2317 dev_err(dev, "Adjust trip points and try again\n");
2318 return -EINVAL;
2319 }
2320
77eb5b37
GR
2321 mutex_lock(&data->update_lock);
2322 data->pwm_enable[nr] = val;
2323 if (val == off) {
2324 /*
2325 * turn off pwm control: select manual mode, set pwm to maximum
2326 */
2327 data->pwm[0][nr] = 255;
2328 nct6775_write_value(data, data->REG_PWM[0][nr], 255);
2329 }
cdcaeceb 2330 pwm_update_registers(data, nr);
77eb5b37
GR
2331 reg = nct6775_read_value(data, data->REG_FAN_MODE[nr]);
2332 reg &= 0x0f;
2333 reg |= pwm_enable_to_reg(val) << 4;
2334 nct6775_write_value(data, data->REG_FAN_MODE[nr], reg);
2335 mutex_unlock(&data->update_lock);
2336 return count;
2337}
2338
cdcaeceb 2339static ssize_t
bbd8decd 2340show_pwm_temp_sel_common(struct nct6775_data *data, char *buf, int src)
cdcaeceb 2341{
bbd8decd 2342 int i, sel = 0;
cdcaeceb
GR
2343
2344 for (i = 0; i < NUM_TEMP; i++) {
2345 if (!(data->have_temp & (1 << i)))
2346 continue;
2347 if (src == data->temp_src[i]) {
2348 sel = i + 1;
2349 break;
2350 }
2351 }
2352
2353 return sprintf(buf, "%d\n", sel);
2354}
2355
bbd8decd
GR
2356static ssize_t
2357show_pwm_temp_sel(struct device *dev, struct device_attribute *attr, char *buf)
2358{
2359 struct nct6775_data *data = nct6775_update_device(dev);
2360 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2361 int index = sattr->index;
2362
2363 return show_pwm_temp_sel_common(data, buf, data->pwm_temp_sel[index]);
2364}
2365
cdcaeceb
GR
2366static ssize_t
2367store_pwm_temp_sel(struct device *dev, struct device_attribute *attr,
2368 const char *buf, size_t count)
2369{
2370 struct nct6775_data *data = nct6775_update_device(dev);
2371 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2372 int nr = sattr->index;
2373 unsigned long val;
2374 int err, reg, src;
2375
2376 err = kstrtoul(buf, 10, &val);
2377 if (err < 0)
2378 return err;
2379 if (val == 0 || val > NUM_TEMP)
2380 return -EINVAL;
2381 if (!(data->have_temp & (1 << (val - 1))) || !data->temp_src[val - 1])
2382 return -EINVAL;
2383
2384 mutex_lock(&data->update_lock);
2385 src = data->temp_src[val - 1];
2386 data->pwm_temp_sel[nr] = src;
2387 reg = nct6775_read_value(data, data->REG_TEMP_SEL[nr]);
2388 reg &= 0xe0;
2389 reg |= src;
2390 nct6775_write_value(data, data->REG_TEMP_SEL[nr], reg);
2391 mutex_unlock(&data->update_lock);
2392
2393 return count;
2394}
2395
bbd8decd
GR
2396static ssize_t
2397show_pwm_weight_temp_sel(struct device *dev, struct device_attribute *attr,
2398 char *buf)
2399{
2400 struct nct6775_data *data = nct6775_update_device(dev);
2401 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2402 int index = sattr->index;
2403
2404 return show_pwm_temp_sel_common(data, buf,
2405 data->pwm_weight_temp_sel[index]);
2406}
2407
2408static ssize_t
2409store_pwm_weight_temp_sel(struct device *dev, struct device_attribute *attr,
2410 const char *buf, size_t count)
2411{
2412 struct nct6775_data *data = nct6775_update_device(dev);
2413 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2414 int nr = sattr->index;
2415 unsigned long val;
2416 int err, reg, src;
2417
2418 err = kstrtoul(buf, 10, &val);
2419 if (err < 0)
2420 return err;
2421 if (val > NUM_TEMP)
2422 return -EINVAL;
2423 if (val && (!(data->have_temp & (1 << (val - 1))) ||
2424 !data->temp_src[val - 1]))
2425 return -EINVAL;
2426
2427 mutex_lock(&data->update_lock);
2428 if (val) {
2429 src = data->temp_src[val - 1];
2430 data->pwm_weight_temp_sel[nr] = src;
2431 reg = nct6775_read_value(data, data->REG_WEIGHT_TEMP_SEL[nr]);
2432 reg &= 0xe0;
2433 reg |= (src | 0x80);
2434 nct6775_write_value(data, data->REG_WEIGHT_TEMP_SEL[nr], reg);
2435 } else {
2436 data->pwm_weight_temp_sel[nr] = 0;
2437 reg = nct6775_read_value(data, data->REG_WEIGHT_TEMP_SEL[nr]);
2438 reg &= 0x7f;
2439 nct6775_write_value(data, data->REG_WEIGHT_TEMP_SEL[nr], reg);
2440 }
2441 mutex_unlock(&data->update_lock);
2442
2443 return count;
2444}
2445
cdcaeceb
GR
2446static ssize_t
2447show_target_temp(struct device *dev, struct device_attribute *attr, char *buf)
2448{
2449 struct nct6775_data *data = nct6775_update_device(dev);
2450 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2451
2452 return sprintf(buf, "%d\n", data->target_temp[sattr->index] * 1000);
2453}
2454
2455static ssize_t
2456store_target_temp(struct device *dev, struct device_attribute *attr,
2457 const char *buf, size_t count)
2458{
2459 struct nct6775_data *data = dev_get_drvdata(dev);
2460 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2461 int nr = sattr->index;
2462 unsigned long val;
2463 int err;
2464
2465 err = kstrtoul(buf, 10, &val);
2466 if (err < 0)
2467 return err;
2468
2469 val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0,
2470 data->target_temp_mask);
2471
2472 mutex_lock(&data->update_lock);
2473 data->target_temp[nr] = val;
2474 pwm_update_registers(data, nr);
2475 mutex_unlock(&data->update_lock);
2476 return count;
2477}
2478
2479static ssize_t
2480show_target_speed(struct device *dev, struct device_attribute *attr, char *buf)
2481{
2482 struct nct6775_data *data = nct6775_update_device(dev);
2483 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2484 int nr = sattr->index;
2485
2486 return sprintf(buf, "%d\n",
2487 fan_from_reg16(data->target_speed[nr],
2488 data->fan_div[nr]));
2489}
2490
2491static ssize_t
2492store_target_speed(struct device *dev, struct device_attribute *attr,
2493 const char *buf, size_t count)
2494{
2495 struct nct6775_data *data = dev_get_drvdata(dev);
2496 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2497 int nr = sattr->index;
2498 unsigned long val;
2499 int err;
2500 u16 speed;
2501
2502 err = kstrtoul(buf, 10, &val);
2503 if (err < 0)
2504 return err;
2505
2506 val = clamp_val(val, 0, 1350000U);
2507 speed = fan_to_reg(val, data->fan_div[nr]);
2508
2509 mutex_lock(&data->update_lock);
2510 data->target_speed[nr] = speed;
2511 pwm_update_registers(data, nr);
2512 mutex_unlock(&data->update_lock);
2513 return count;
2514}
2515
2516static ssize_t
2517show_temp_tolerance(struct device *dev, struct device_attribute *attr,
2518 char *buf)
2519{
2520 struct nct6775_data *data = nct6775_update_device(dev);
2521 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2522 int nr = sattr->nr;
2523 int index = sattr->index;
2524
2525 return sprintf(buf, "%d\n", data->temp_tolerance[index][nr] * 1000);
2526}
2527
2528static ssize_t
2529store_temp_tolerance(struct device *dev, struct device_attribute *attr,
2530 const char *buf, size_t count)
2531{
2532 struct nct6775_data *data = dev_get_drvdata(dev);
2533 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2534 int nr = sattr->nr;
2535 int index = sattr->index;
2536 unsigned long val;
2537 int err;
2538
2539 err = kstrtoul(buf, 10, &val);
2540 if (err < 0)
2541 return err;
2542
2543 /* Limit tolerance as needed */
2544 val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0, data->tolerance_mask);
2545
2546 mutex_lock(&data->update_lock);
2547 data->temp_tolerance[index][nr] = val;
2548 if (index)
2549 pwm_update_registers(data, nr);
2550 else
2551 nct6775_write_value(data,
2552 data->REG_CRITICAL_TEMP_TOLERANCE[nr],
2553 val);
2554 mutex_unlock(&data->update_lock);
2555 return count;
2556}
2557
2558/*
2559 * Fan speed tolerance is a tricky beast, since the associated register is
2560 * a tick counter, but the value is reported and configured as rpm.
2561 * Compute resulting low and high rpm values and report the difference.
2562 */
2563static ssize_t
2564show_speed_tolerance(struct device *dev, struct device_attribute *attr,
2565 char *buf)
2566{
2567 struct nct6775_data *data = nct6775_update_device(dev);
2568 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2569 int nr = sattr->index;
2570 int low = data->target_speed[nr] - data->target_speed_tolerance[nr];
2571 int high = data->target_speed[nr] + data->target_speed_tolerance[nr];
2572 int tolerance;
2573
2574 if (low <= 0)
2575 low = 1;
2576 if (high > 0xffff)
2577 high = 0xffff;
2578 if (high < low)
2579 high = low;
2580
2581 tolerance = (fan_from_reg16(low, data->fan_div[nr])
2582 - fan_from_reg16(high, data->fan_div[nr])) / 2;
2583
2584 return sprintf(buf, "%d\n", tolerance);
2585}
2586
2587static ssize_t
2588store_speed_tolerance(struct device *dev, struct device_attribute *attr,
2589 const char *buf, size_t count)
2590{
2591 struct nct6775_data *data = dev_get_drvdata(dev);
2592 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2593 int nr = sattr->index;
2594 unsigned long val;
2595 int err;
2596 int low, high;
2597
2598 err = kstrtoul(buf, 10, &val);
2599 if (err < 0)
2600 return err;
2601
2602 high = fan_from_reg16(data->target_speed[nr],
2603 data->fan_div[nr]) + val;
2604 low = fan_from_reg16(data->target_speed[nr],
2605 data->fan_div[nr]) - val;
2606 if (low <= 0)
2607 low = 1;
2608 if (high < low)
2609 high = low;
2610
2611 val = (fan_to_reg(low, data->fan_div[nr]) -
2612 fan_to_reg(high, data->fan_div[nr])) / 2;
2613
2614 /* Limit tolerance as needed */
2615 val = clamp_val(val, 0, data->speed_tolerance_limit);
2616
2617 mutex_lock(&data->update_lock);
2618 data->target_speed_tolerance[nr] = val;
2619 pwm_update_registers(data, nr);
2620 mutex_unlock(&data->update_lock);
2621 return count;
2622}
2623
f73cf632
GR
2624SENSOR_TEMPLATE_2(pwm, "pwm%d", S_IWUSR | S_IRUGO, show_pwm, store_pwm, 0, 0);
2625SENSOR_TEMPLATE(pwm_mode, "pwm%d_mode", S_IWUSR | S_IRUGO, show_pwm_mode,
2626 store_pwm_mode, 0);
2627SENSOR_TEMPLATE(pwm_enable, "pwm%d_enable", S_IWUSR | S_IRUGO, show_pwm_enable,
2628 store_pwm_enable, 0);
2629SENSOR_TEMPLATE(pwm_temp_sel, "pwm%d_temp_sel", S_IWUSR | S_IRUGO,
2630 show_pwm_temp_sel, store_pwm_temp_sel, 0);
2631SENSOR_TEMPLATE(pwm_target_temp, "pwm%d_target_temp", S_IWUSR | S_IRUGO,
2632 show_target_temp, store_target_temp, 0);
2633SENSOR_TEMPLATE(fan_target, "fan%d_target", S_IWUSR | S_IRUGO,
2634 show_target_speed, store_target_speed, 0);
2635SENSOR_TEMPLATE(fan_tolerance, "fan%d_tolerance", S_IWUSR | S_IRUGO,
2636 show_speed_tolerance, store_speed_tolerance, 0);
cdcaeceb
GR
2637
2638/* Smart Fan registers */
2639
bbd8decd
GR
2640static ssize_t
2641show_weight_temp(struct device *dev, struct device_attribute *attr, char *buf)
2642{
2643 struct nct6775_data *data = nct6775_update_device(dev);
2644 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2645 int nr = sattr->nr;
2646 int index = sattr->index;
2647
2648 return sprintf(buf, "%d\n", data->weight_temp[index][nr] * 1000);
2649}
2650
2651static ssize_t
2652store_weight_temp(struct device *dev, struct device_attribute *attr,
2653 const char *buf, size_t count)
2654{
2655 struct nct6775_data *data = dev_get_drvdata(dev);
2656 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2657 int nr = sattr->nr;
2658 int index = sattr->index;
2659 unsigned long val;
2660 int err;
2661
2662 err = kstrtoul(buf, 10, &val);
2663 if (err < 0)
2664 return err;
2665
2666 val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0, 255);
2667
2668 mutex_lock(&data->update_lock);
2669 data->weight_temp[index][nr] = val;
2670 nct6775_write_value(data, data->REG_WEIGHT_TEMP[index][nr], val);
2671 mutex_unlock(&data->update_lock);
2672 return count;
2673}
2674
f73cf632
GR
2675SENSOR_TEMPLATE(pwm_weight_temp_sel, "pwm%d_weight_temp_sel", S_IWUSR | S_IRUGO,
2676 show_pwm_weight_temp_sel, store_pwm_weight_temp_sel, 0);
2677SENSOR_TEMPLATE_2(pwm_weight_temp_step, "pwm%d_weight_temp_step",
2678 S_IWUSR | S_IRUGO, show_weight_temp, store_weight_temp, 0, 0);
2679SENSOR_TEMPLATE_2(pwm_weight_temp_step_tol, "pwm%d_weight_temp_step_tol",
2680 S_IWUSR | S_IRUGO, show_weight_temp, store_weight_temp, 0, 1);
2681SENSOR_TEMPLATE_2(pwm_weight_temp_step_base, "pwm%d_weight_temp_step_base",
2682 S_IWUSR | S_IRUGO, show_weight_temp, store_weight_temp, 0, 2);
2683SENSOR_TEMPLATE_2(pwm_weight_duty_step, "pwm%d_weight_duty_step",
2684 S_IWUSR | S_IRUGO, show_pwm, store_pwm, 0, 5);
2685SENSOR_TEMPLATE_2(pwm_weight_duty_base, "pwm%d_weight_duty_base",
2686 S_IWUSR | S_IRUGO, show_pwm, store_pwm, 0, 6);
bbd8decd 2687
cdcaeceb
GR
2688static ssize_t
2689show_fan_time(struct device *dev, struct device_attribute *attr, char *buf)
2690{
2691 struct nct6775_data *data = nct6775_update_device(dev);
2692 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2693 int nr = sattr->nr;
2694 int index = sattr->index;
2695
2696 return sprintf(buf, "%d\n",
2697 step_time_from_reg(data->fan_time[index][nr],
2698 data->pwm_mode[nr]));
2699}
2700
2701static ssize_t
2702store_fan_time(struct device *dev, struct device_attribute *attr,
2703 const char *buf, size_t count)
2704{
2705 struct nct6775_data *data = dev_get_drvdata(dev);
2706 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2707 int nr = sattr->nr;
2708 int index = sattr->index;
2709 unsigned long val;
2710 int err;
2711
2712 err = kstrtoul(buf, 10, &val);
2713 if (err < 0)
2714 return err;
2715
2716 val = step_time_to_reg(val, data->pwm_mode[nr]);
2717 mutex_lock(&data->update_lock);
2718 data->fan_time[index][nr] = val;
2719 nct6775_write_value(data, data->REG_FAN_TIME[index][nr], val);
2720 mutex_unlock(&data->update_lock);
2721 return count;
2722}
2723
cdcaeceb
GR
2724static ssize_t
2725show_auto_pwm(struct device *dev, struct device_attribute *attr, char *buf)
2726{
2727 struct nct6775_data *data = nct6775_update_device(dev);
2728 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2729
2730 return sprintf(buf, "%d\n", data->auto_pwm[sattr->nr][sattr->index]);
2731}
2732
2733static ssize_t
2734store_auto_pwm(struct device *dev, struct device_attribute *attr,
2735 const char *buf, size_t count)
2736{
2737 struct nct6775_data *data = dev_get_drvdata(dev);
2738 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2739 int nr = sattr->nr;
2740 int point = sattr->index;
2741 unsigned long val;
2742 int err;
2743 u8 reg;
2744
2745 err = kstrtoul(buf, 10, &val);
2746 if (err < 0)
2747 return err;
2748 if (val > 255)
2749 return -EINVAL;
2750
2751 if (point == data->auto_pwm_num) {
2752 if (data->kind != nct6775 && !val)
2753 return -EINVAL;
2754 if (data->kind != nct6779 && val)
2755 val = 0xff;
2756 }
2757
2758 mutex_lock(&data->update_lock);
2759 data->auto_pwm[nr][point] = val;
2760 if (point < data->auto_pwm_num) {
2761 nct6775_write_value(data,
2762 NCT6775_AUTO_PWM(data, nr, point),
2763 data->auto_pwm[nr][point]);
2764 } else {
2765 switch (data->kind) {
2766 case nct6775:
2767 /* disable if needed (pwm == 0) */
2768 reg = nct6775_read_value(data,
2769 NCT6775_REG_CRITICAL_ENAB[nr]);
2770 if (val)
2771 reg |= 0x02;
2772 else
2773 reg &= ~0x02;
2774 nct6775_write_value(data, NCT6775_REG_CRITICAL_ENAB[nr],
2775 reg);
2776 break;
2777 case nct6776:
2778 break; /* always enabled, nothing to do */
6c009501 2779 case nct6106:
cdcaeceb 2780 case nct6779:
578ab5f0 2781 case nct6791:
6c009501 2782 nct6775_write_value(data, data->REG_CRITICAL_PWM[nr],
cdcaeceb
GR
2783 val);
2784 reg = nct6775_read_value(data,
6c009501 2785 data->REG_CRITICAL_PWM_ENABLE[nr]);
cdcaeceb 2786 if (val == 255)
6c009501 2787 reg &= ~data->CRITICAL_PWM_ENABLE_MASK;
cdcaeceb 2788 else
6c009501 2789 reg |= data->CRITICAL_PWM_ENABLE_MASK;
cdcaeceb 2790 nct6775_write_value(data,
6c009501 2791 data->REG_CRITICAL_PWM_ENABLE[nr],
cdcaeceb
GR
2792 reg);
2793 break;
2794 }
2795 }
2796 mutex_unlock(&data->update_lock);
2797 return count;
2798}
2799
2800static ssize_t
2801show_auto_temp(struct device *dev, struct device_attribute *attr, char *buf)
2802{
2803 struct nct6775_data *data = nct6775_update_device(dev);
2804 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2805 int nr = sattr->nr;
2806 int point = sattr->index;
2807
2808 /*
2809 * We don't know for sure if the temperature is signed or unsigned.
2810 * Assume it is unsigned.
2811 */
2812 return sprintf(buf, "%d\n", data->auto_temp[nr][point] * 1000);
2813}
2814
2815static ssize_t
2816store_auto_temp(struct device *dev, struct device_attribute *attr,
2817 const char *buf, size_t count)
2818{
2819 struct nct6775_data *data = dev_get_drvdata(dev);
2820 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2821 int nr = sattr->nr;
2822 int point = sattr->index;
2823 unsigned long val;
2824 int err;
2825
2826 err = kstrtoul(buf, 10, &val);
2827 if (err)
2828 return err;
2829 if (val > 255000)
2830 return -EINVAL;
2831
2832 mutex_lock(&data->update_lock);
2833 data->auto_temp[nr][point] = DIV_ROUND_CLOSEST(val, 1000);
2834 if (point < data->auto_pwm_num) {
2835 nct6775_write_value(data,
2836 NCT6775_AUTO_TEMP(data, nr, point),
2837 data->auto_temp[nr][point]);
2838 } else {
2839 nct6775_write_value(data, data->REG_CRITICAL_TEMP[nr],
2840 data->auto_temp[nr][point]);
2841 }
2842 mutex_unlock(&data->update_lock);
2843 return count;
2844}
2845
f73cf632
GR
2846static umode_t nct6775_pwm_is_visible(struct kobject *kobj,
2847 struct attribute *attr, int index)
2848{
2849 struct device *dev = container_of(kobj, struct device, kobj);
2850 struct nct6775_data *data = dev_get_drvdata(dev);
2851 int pwm = index / 36; /* pwm index */
2852 int nr = index % 36; /* attribute index */
2853
2854 if (!(data->has_pwm & (1 << pwm)))
2855 return 0;
2856
2857 if (nr == 19 && data->REG_PWM[3] == NULL) /* pwm_max */
2858 return 0;
2859 if (nr == 20 && data->REG_PWM[4] == NULL) /* pwm_step */
2860 return 0;
2861 if (nr == 21 && data->REG_PWM[6] == NULL) /* weight_duty_base */
2862 return 0;
2863
2864 if (nr >= 22 && nr <= 35) { /* auto point */
2865 int api = (nr - 22) / 2; /* auto point index */
2866
2867 if (api > data->auto_pwm_num)
2868 return 0;
2869 }
2870 return attr->mode;
2871}
2872
2873SENSOR_TEMPLATE_2(pwm_stop_time, "pwm%d_stop_time", S_IWUSR | S_IRUGO,
2874 show_fan_time, store_fan_time, 0, 0);
2875SENSOR_TEMPLATE_2(pwm_step_up_time, "pwm%d_step_up_time", S_IWUSR | S_IRUGO,
2876 show_fan_time, store_fan_time, 0, 1);
2877SENSOR_TEMPLATE_2(pwm_step_down_time, "pwm%d_step_down_time", S_IWUSR | S_IRUGO,
2878 show_fan_time, store_fan_time, 0, 2);
2879SENSOR_TEMPLATE_2(pwm_start, "pwm%d_start", S_IWUSR | S_IRUGO, show_pwm,
2880 store_pwm, 0, 1);
2881SENSOR_TEMPLATE_2(pwm_floor, "pwm%d_floor", S_IWUSR | S_IRUGO, show_pwm,
2882 store_pwm, 0, 2);
2883SENSOR_TEMPLATE_2(pwm_temp_tolerance, "pwm%d_temp_tolerance", S_IWUSR | S_IRUGO,
2884 show_temp_tolerance, store_temp_tolerance, 0, 0);
2885SENSOR_TEMPLATE_2(pwm_crit_temp_tolerance, "pwm%d_crit_temp_tolerance",
2886 S_IWUSR | S_IRUGO, show_temp_tolerance, store_temp_tolerance,
2887 0, 1);
2888
2889SENSOR_TEMPLATE_2(pwm_max, "pwm%d_max", S_IWUSR | S_IRUGO, show_pwm, store_pwm,
2890 0, 3);
2891
2892SENSOR_TEMPLATE_2(pwm_step, "pwm%d_step", S_IWUSR | S_IRUGO, show_pwm,
2893 store_pwm, 0, 4);
2894
2895SENSOR_TEMPLATE_2(pwm_auto_point1_pwm, "pwm%d_auto_point1_pwm",
2896 S_IWUSR | S_IRUGO, show_auto_pwm, store_auto_pwm, 0, 0);
2897SENSOR_TEMPLATE_2(pwm_auto_point1_temp, "pwm%d_auto_point1_temp",
2898 S_IWUSR | S_IRUGO, show_auto_temp, store_auto_temp, 0, 0);
2899
2900SENSOR_TEMPLATE_2(pwm_auto_point2_pwm, "pwm%d_auto_point2_pwm",
2901 S_IWUSR | S_IRUGO, show_auto_pwm, store_auto_pwm, 0, 1);
2902SENSOR_TEMPLATE_2(pwm_auto_point2_temp, "pwm%d_auto_point2_temp",
2903 S_IWUSR | S_IRUGO, show_auto_temp, store_auto_temp, 0, 1);
2904
2905SENSOR_TEMPLATE_2(pwm_auto_point3_pwm, "pwm%d_auto_point3_pwm",
2906 S_IWUSR | S_IRUGO, show_auto_pwm, store_auto_pwm, 0, 2);
2907SENSOR_TEMPLATE_2(pwm_auto_point3_temp, "pwm%d_auto_point3_temp",
2908 S_IWUSR | S_IRUGO, show_auto_temp, store_auto_temp, 0, 2);
2909
2910SENSOR_TEMPLATE_2(pwm_auto_point4_pwm, "pwm%d_auto_point4_pwm",
2911 S_IWUSR | S_IRUGO, show_auto_pwm, store_auto_pwm, 0, 3);
2912SENSOR_TEMPLATE_2(pwm_auto_point4_temp, "pwm%d_auto_point4_temp",
2913 S_IWUSR | S_IRUGO, show_auto_temp, store_auto_temp, 0, 3);
2914
2915SENSOR_TEMPLATE_2(pwm_auto_point5_pwm, "pwm%d_auto_point5_pwm",
2916 S_IWUSR | S_IRUGO, show_auto_pwm, store_auto_pwm, 0, 4);
2917SENSOR_TEMPLATE_2(pwm_auto_point5_temp, "pwm%d_auto_point5_temp",
2918 S_IWUSR | S_IRUGO, show_auto_temp, store_auto_temp, 0, 4);
2919
2920SENSOR_TEMPLATE_2(pwm_auto_point6_pwm, "pwm%d_auto_point6_pwm",
2921 S_IWUSR | S_IRUGO, show_auto_pwm, store_auto_pwm, 0, 5);
2922SENSOR_TEMPLATE_2(pwm_auto_point6_temp, "pwm%d_auto_point6_temp",
2923 S_IWUSR | S_IRUGO, show_auto_temp, store_auto_temp, 0, 5);
2924
2925SENSOR_TEMPLATE_2(pwm_auto_point7_pwm, "pwm%d_auto_point7_pwm",
2926 S_IWUSR | S_IRUGO, show_auto_pwm, store_auto_pwm, 0, 6);
2927SENSOR_TEMPLATE_2(pwm_auto_point7_temp, "pwm%d_auto_point7_temp",
2928 S_IWUSR | S_IRUGO, show_auto_temp, store_auto_temp, 0, 6);
2929
cdcaeceb 2930/*
f73cf632
GR
2931 * nct6775_pwm_is_visible uses the index into the following array
2932 * to determine if attributes should be created or not.
2933 * Any change in order or content must be matched.
cdcaeceb 2934 */
f73cf632
GR
2935static struct sensor_device_template *nct6775_attributes_pwm_template[] = {
2936 &sensor_dev_template_pwm,
2937 &sensor_dev_template_pwm_mode,
2938 &sensor_dev_template_pwm_enable,
2939 &sensor_dev_template_pwm_temp_sel,
2940 &sensor_dev_template_pwm_temp_tolerance,
2941 &sensor_dev_template_pwm_crit_temp_tolerance,
2942 &sensor_dev_template_pwm_target_temp,
2943 &sensor_dev_template_fan_target,
2944 &sensor_dev_template_fan_tolerance,
2945 &sensor_dev_template_pwm_stop_time,
2946 &sensor_dev_template_pwm_step_up_time,
2947 &sensor_dev_template_pwm_step_down_time,
2948 &sensor_dev_template_pwm_start,
2949 &sensor_dev_template_pwm_floor,
2950 &sensor_dev_template_pwm_weight_temp_sel,
2951 &sensor_dev_template_pwm_weight_temp_step,
2952 &sensor_dev_template_pwm_weight_temp_step_tol,
2953 &sensor_dev_template_pwm_weight_temp_step_base,
2954 &sensor_dev_template_pwm_weight_duty_step,
2955 &sensor_dev_template_pwm_max, /* 19 */
2956 &sensor_dev_template_pwm_step, /* 20 */
2957 &sensor_dev_template_pwm_weight_duty_base, /* 21 */
2958 &sensor_dev_template_pwm_auto_point1_pwm, /* 22 */
2959 &sensor_dev_template_pwm_auto_point1_temp,
2960 &sensor_dev_template_pwm_auto_point2_pwm,
2961 &sensor_dev_template_pwm_auto_point2_temp,
2962 &sensor_dev_template_pwm_auto_point3_pwm,
2963 &sensor_dev_template_pwm_auto_point3_temp,
2964 &sensor_dev_template_pwm_auto_point4_pwm,
2965 &sensor_dev_template_pwm_auto_point4_temp,
2966 &sensor_dev_template_pwm_auto_point5_pwm,
2967 &sensor_dev_template_pwm_auto_point5_temp,
2968 &sensor_dev_template_pwm_auto_point6_pwm,
2969 &sensor_dev_template_pwm_auto_point6_temp,
2970 &sensor_dev_template_pwm_auto_point7_pwm,
2971 &sensor_dev_template_pwm_auto_point7_temp, /* 35 */
2972
2973 NULL
2974};
2975
2976static struct sensor_template_group nct6775_pwm_template_group = {
2977 .templates = nct6775_attributes_pwm_template,
2978 .is_visible = nct6775_pwm_is_visible,
2979 .base = 1,
cdcaeceb
GR
2980};
2981
9de2e2e8
GR
2982static ssize_t
2983show_vid(struct device *dev, struct device_attribute *attr, char *buf)
2984{
2985 struct nct6775_data *data = dev_get_drvdata(dev);
2986 return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm));
2987}
2988
2989static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL);
2990
a6bd5878
GR
2991/* Case open detection */
2992
2993static ssize_t
2994clear_caseopen(struct device *dev, struct device_attribute *attr,
2995 const char *buf, size_t count)
2996{
2997 struct nct6775_data *data = dev_get_drvdata(dev);
a6bd5878
GR
2998 int nr = to_sensor_dev_attr(attr)->index - INTRUSION_ALARM_BASE;
2999 unsigned long val;
3000 u8 reg;
3001 int ret;
3002
3003 if (kstrtoul(buf, 10, &val) || val != 0)
3004 return -EINVAL;
3005
3006 mutex_lock(&data->update_lock);
3007
3008 /*
3009 * Use CR registers to clear caseopen status.
3010 * The CR registers are the same for all chips, and not all chips
3011 * support clearing the caseopen status through "regular" registers.
3012 */
df612d5f 3013 ret = superio_enter(data->sioreg);
a6bd5878
GR
3014 if (ret) {
3015 count = ret;
3016 goto error;
3017 }
3018
df612d5f
GR
3019 superio_select(data->sioreg, NCT6775_LD_ACPI);
3020 reg = superio_inb(data->sioreg, NCT6775_REG_CR_CASEOPEN_CLR[nr]);
a6bd5878 3021 reg |= NCT6775_CR_CASEOPEN_CLR_MASK[nr];
df612d5f 3022 superio_outb(data->sioreg, NCT6775_REG_CR_CASEOPEN_CLR[nr], reg);
a6bd5878 3023 reg &= ~NCT6775_CR_CASEOPEN_CLR_MASK[nr];
df612d5f
GR
3024 superio_outb(data->sioreg, NCT6775_REG_CR_CASEOPEN_CLR[nr], reg);
3025 superio_exit(data->sioreg);
a6bd5878
GR
3026
3027 data->valid = false; /* Force cache refresh */
3028error:
3029 mutex_unlock(&data->update_lock);
3030 return count;
3031}
3032
f73cf632
GR
3033static SENSOR_DEVICE_ATTR(intrusion0_alarm, S_IWUSR | S_IRUGO, show_alarm,
3034 clear_caseopen, INTRUSION_ALARM_BASE);
3035static SENSOR_DEVICE_ATTR(intrusion1_alarm, S_IWUSR | S_IRUGO, show_alarm,
3036 clear_caseopen, INTRUSION_ALARM_BASE + 1);
30846993
GR
3037static SENSOR_DEVICE_ATTR(intrusion0_beep, S_IWUSR | S_IRUGO, show_beep,
3038 store_beep, INTRUSION_ALARM_BASE);
3039static SENSOR_DEVICE_ATTR(intrusion1_beep, S_IWUSR | S_IRUGO, show_beep,
3040 store_beep, INTRUSION_ALARM_BASE + 1);
3041static SENSOR_DEVICE_ATTR(beep_enable, S_IWUSR | S_IRUGO, show_beep,
3042 store_beep, BEEP_ENABLE_BASE);
9de2e2e8 3043
f73cf632
GR
3044static umode_t nct6775_other_is_visible(struct kobject *kobj,
3045 struct attribute *attr, int index)
9de2e2e8 3046{
f73cf632 3047 struct device *dev = container_of(kobj, struct device, kobj);
9de2e2e8
GR
3048 struct nct6775_data *data = dev_get_drvdata(dev);
3049
615fc8cb 3050 if (index == 0 && !data->have_vid)
f73cf632 3051 return 0;
77eb5b37 3052
615fc8cb
GR
3053 if (index == 1 || index == 2) {
3054 if (data->ALARM_BITS[INTRUSION_ALARM_BASE + index - 1] < 0)
f73cf632
GR
3055 return 0;
3056 }
cdcaeceb 3057
615fc8cb
GR
3058 if (index == 3 || index == 4) {
3059 if (data->BEEP_BITS[INTRUSION_ALARM_BASE + index - 3] < 0)
30846993
GR
3060 return 0;
3061 }
3062
f73cf632
GR
3063 return attr->mode;
3064}
cdcaeceb 3065
f73cf632
GR
3066/*
3067 * nct6775_other_is_visible uses the index into the following array
3068 * to determine if attributes should be created or not.
3069 * Any change in order or content must be matched.
3070 */
3071static struct attribute *nct6775_attributes_other[] = {
615fc8cb
GR
3072 &dev_attr_cpu0_vid.attr, /* 0 */
3073 &sensor_dev_attr_intrusion0_alarm.dev_attr.attr, /* 1 */
3074 &sensor_dev_attr_intrusion1_alarm.dev_attr.attr, /* 2 */
3075 &sensor_dev_attr_intrusion0_beep.dev_attr.attr, /* 3 */
3076 &sensor_dev_attr_intrusion1_beep.dev_attr.attr, /* 4 */
3077 &sensor_dev_attr_beep_enable.dev_attr.attr, /* 5 */
bbd8decd 3078
f73cf632
GR
3079 NULL
3080};
cdcaeceb 3081
f73cf632
GR
3082static const struct attribute_group nct6775_group_other = {
3083 .attrs = nct6775_attributes_other,
3084 .is_visible = nct6775_other_is_visible,
3085};
9de2e2e8 3086
9de2e2e8
GR
3087static inline void nct6775_init_device(struct nct6775_data *data)
3088{
aa136e5d
GR
3089 int i;
3090 u8 tmp, diode;
9de2e2e8
GR
3091
3092 /* Start monitoring if needed */
3093 if (data->REG_CONFIG) {
3094 tmp = nct6775_read_value(data, data->REG_CONFIG);
3095 if (!(tmp & 0x01))
3096 nct6775_write_value(data, data->REG_CONFIG, tmp | 0x01);
3097 }
3098
aa136e5d
GR
3099 /* Enable temperature sensors if needed */
3100 for (i = 0; i < NUM_TEMP; i++) {
3101 if (!(data->have_temp & (1 << i)))
3102 continue;
3103 if (!data->reg_temp_config[i])
3104 continue;
3105 tmp = nct6775_read_value(data, data->reg_temp_config[i]);
3106 if (tmp & 0x01)
3107 nct6775_write_value(data, data->reg_temp_config[i],
3108 tmp & 0xfe);
3109 }
3110
9de2e2e8
GR
3111 /* Enable VBAT monitoring if needed */
3112 tmp = nct6775_read_value(data, data->REG_VBAT);
3113 if (!(tmp & 0x01))
3114 nct6775_write_value(data, data->REG_VBAT, tmp | 0x01);
aa136e5d
GR
3115
3116 diode = nct6775_read_value(data, data->REG_DIODE);
3117
3118 for (i = 0; i < data->temp_fixed_num; i++) {
3119 if (!(data->have_temp_fixed & (1 << i)))
3120 continue;
6c009501
GR
3121 if ((tmp & (data->DIODE_MASK << i))) /* diode */
3122 data->temp_type[i]
3123 = 3 - ((diode >> i) & data->DIODE_MASK);
aa136e5d
GR
3124 else /* thermistor */
3125 data->temp_type[i] = 4;
3126 }
9de2e2e8
GR
3127}
3128
f73cf632 3129static void
df612d5f 3130nct6775_check_fan_inputs(struct nct6775_data *data)
1c65dc36 3131{
578ab5f0
DB
3132 bool fan3pin, fan4pin, fan4min, fan5pin, fan6pin;
3133 bool pwm3pin, pwm4pin, pwm5pin, pwm6pin;
df612d5f
GR
3134 int sioreg = data->sioreg;
3135 int regval;
1c65dc36
GR
3136
3137 /* fan4 and fan5 share some pins with the GPIO and serial flash */
3138 if (data->kind == nct6775) {
df612d5f 3139 regval = superio_inb(sioreg, 0x2c);
1c65dc36
GR
3140
3141 fan3pin = regval & (1 << 6);
77eb5b37 3142 pwm3pin = regval & (1 << 7);
1c65dc36
GR
3143
3144 /* On NCT6775, fan4 shares pins with the fdc interface */
df612d5f 3145 fan4pin = !(superio_inb(sioreg, 0x2A) & 0x80);
578ab5f0
DB
3146 fan4min = false;
3147 fan5pin = false;
3148 fan6pin = false;
3149 pwm4pin = false;
3150 pwm5pin = false;
3151 pwm6pin = false;
1c65dc36 3152 } else if (data->kind == nct6776) {
df612d5f 3153 bool gpok = superio_inb(sioreg, 0x27) & 0x80;
1c65dc36 3154
df612d5f
GR
3155 superio_select(sioreg, NCT6775_LD_HWM);
3156 regval = superio_inb(sioreg, SIO_REG_ENABLE);
1c65dc36
GR
3157
3158 if (regval & 0x80)
3159 fan3pin = gpok;
3160 else
df612d5f 3161 fan3pin = !(superio_inb(sioreg, 0x24) & 0x40);
1c65dc36
GR
3162
3163 if (regval & 0x40)
3164 fan4pin = gpok;
3165 else
df612d5f 3166 fan4pin = superio_inb(sioreg, 0x1C) & 0x01;
1c65dc36
GR
3167
3168 if (regval & 0x20)
3169 fan5pin = gpok;
3170 else
df612d5f 3171 fan5pin = superio_inb(sioreg, 0x1C) & 0x02;
1c65dc36
GR
3172
3173 fan4min = fan4pin;
578ab5f0 3174 fan6pin = false;
77eb5b37 3175 pwm3pin = fan3pin;
578ab5f0
DB
3176 pwm4pin = false;
3177 pwm5pin = false;
3178 pwm6pin = false;
6c009501 3179 } else if (data->kind == nct6106) {
df612d5f 3180 regval = superio_inb(sioreg, 0x24);
6c009501
GR
3181 fan3pin = !(regval & 0x80);
3182 pwm3pin = regval & 0x08;
6c009501
GR
3183
3184 fan4pin = false;
3185 fan4min = false;
3186 fan5pin = false;
578ab5f0 3187 fan6pin = false;
6c009501
GR
3188 pwm4pin = false;
3189 pwm5pin = false;
578ab5f0
DB
3190 pwm6pin = false;
3191 } else { /* NCT6779D or NCT6791D */
df612d5f 3192 regval = superio_inb(sioreg, 0x1c);
1c65dc36
GR
3193
3194 fan3pin = !(regval & (1 << 5));
3195 fan4pin = !(regval & (1 << 6));
3196 fan5pin = !(regval & (1 << 7));
3197
77eb5b37
GR
3198 pwm3pin = !(regval & (1 << 0));
3199 pwm4pin = !(regval & (1 << 1));
3200 pwm5pin = !(regval & (1 << 2));
3201
1c65dc36 3202 fan4min = fan4pin;
1c65dc36 3203
578ab5f0 3204 if (data->kind == nct6791) {
df612d5f 3205 regval = superio_inb(sioreg, 0x2d);
578ab5f0
DB
3206 fan6pin = (regval & (1 << 1));
3207 pwm6pin = (regval & (1 << 0));
3208 } else { /* NCT6779D */
3209 fan6pin = false;
3210 pwm6pin = false;
3211 }
3212 }
1c65dc36 3213
578ab5f0
DB
3214 /* fan 1 and 2 (0x03) are always present */
3215 data->has_fan = 0x03 | (fan3pin << 2) | (fan4pin << 3) |
3216 (fan5pin << 4) | (fan6pin << 5);
3217 data->has_fan_min = 0x03 | (fan3pin << 2) | (fan4min << 3) |
3218 (fan5pin << 4);
3219 data->has_pwm = 0x03 | (pwm3pin << 2) | (pwm4pin << 3) |
3220 (pwm5pin << 4) | (pwm6pin << 5);
1c65dc36
GR
3221}
3222
8e9285b0
GR
3223static void add_temp_sensors(struct nct6775_data *data, const u16 *regp,
3224 int *available, int *mask)
3225{
3226 int i;
3227 u8 src;
3228
3229 for (i = 0; i < data->pwm_num && *available; i++) {
3230 int index;
3231
3232 if (!regp[i])
3233 continue;
3234 src = nct6775_read_value(data, regp[i]);
3235 src &= 0x1f;
3236 if (!src || (*mask & (1 << src)))
3237 continue;
3238 if (src >= data->temp_label_num ||
3239 !strlen(data->temp_label[src]))
3240 continue;
3241
3242 index = __ffs(*available);
3243 nct6775_write_value(data, data->REG_TEMP_SOURCE[index], src);
3244 *available &= ~(1 << index);
3245 *mask |= 1 << src;
3246 }
3247}
3248
9de2e2e8
GR
3249static int nct6775_probe(struct platform_device *pdev)
3250{
3251 struct device *dev = &pdev->dev;
a8b3a3a5 3252 struct nct6775_sio_data *sio_data = dev_get_platdata(dev);
9de2e2e8
GR
3253 struct nct6775_data *data;
3254 struct resource *res;
aa136e5d
GR
3255 int i, s, err = 0;
3256 int src, mask, available;
3257 const u16 *reg_temp, *reg_temp_over, *reg_temp_hyst, *reg_temp_config;
3258 const u16 *reg_temp_alternate, *reg_temp_crit;
b7a61353 3259 const u16 *reg_temp_crit_l = NULL, *reg_temp_crit_h = NULL;
aa136e5d 3260 int num_reg_temp;
0fc1f8fc 3261 u8 cr2a;
f73cf632 3262 struct attribute_group *group;
9de2e2e8
GR
3263
3264 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
3265 if (!devm_request_region(&pdev->dev, res->start, IOREGION_LENGTH,
3266 DRVNAME))
3267 return -EBUSY;
3268
3269 data = devm_kzalloc(&pdev->dev, sizeof(struct nct6775_data),
3270 GFP_KERNEL);
3271 if (!data)
3272 return -ENOMEM;
3273
3274 data->kind = sio_data->kind;
df612d5f 3275 data->sioreg = sio_data->sioreg;
9de2e2e8 3276 data->addr = res->start;
9de2e2e8
GR
3277 mutex_init(&data->update_lock);
3278 data->name = nct6775_device_names[data->kind];
3279 data->bank = 0xff; /* Force initial bank selection */
3280 platform_set_drvdata(pdev, data);
3281
3282 switch (data->kind) {
6c009501
GR
3283 case nct6106:
3284 data->in_num = 9;
3285 data->pwm_num = 3;
3286 data->auto_pwm_num = 4;
3287 data->temp_fixed_num = 3;
3288 data->num_temp_alarms = 6;
30846993 3289 data->num_temp_beeps = 6;
6c009501
GR
3290
3291 data->fan_from_reg = fan_from_reg13;
3292 data->fan_from_reg_min = fan_from_reg13;
3293
3294 data->temp_label = nct6776_temp_label;
3295 data->temp_label_num = ARRAY_SIZE(nct6776_temp_label);
3296
3297 data->REG_VBAT = NCT6106_REG_VBAT;
3298 data->REG_DIODE = NCT6106_REG_DIODE;
3299 data->DIODE_MASK = NCT6106_DIODE_MASK;
3300 data->REG_VIN = NCT6106_REG_IN;
3301 data->REG_IN_MINMAX[0] = NCT6106_REG_IN_MIN;
3302 data->REG_IN_MINMAX[1] = NCT6106_REG_IN_MAX;
3303 data->REG_TARGET = NCT6106_REG_TARGET;
3304 data->REG_FAN = NCT6106_REG_FAN;
3305 data->REG_FAN_MODE = NCT6106_REG_FAN_MODE;
3306 data->REG_FAN_MIN = NCT6106_REG_FAN_MIN;
3307 data->REG_FAN_PULSES = NCT6106_REG_FAN_PULSES;
3308 data->FAN_PULSE_SHIFT = NCT6106_FAN_PULSE_SHIFT;
3309 data->REG_FAN_TIME[0] = NCT6106_REG_FAN_STOP_TIME;
3310 data->REG_FAN_TIME[1] = NCT6106_REG_FAN_STEP_UP_TIME;
3311 data->REG_FAN_TIME[2] = NCT6106_REG_FAN_STEP_DOWN_TIME;
3312 data->REG_PWM[0] = NCT6106_REG_PWM;
3313 data->REG_PWM[1] = NCT6106_REG_FAN_START_OUTPUT;
3314 data->REG_PWM[2] = NCT6106_REG_FAN_STOP_OUTPUT;
3315 data->REG_PWM[5] = NCT6106_REG_WEIGHT_DUTY_STEP;
3316 data->REG_PWM[6] = NCT6106_REG_WEIGHT_DUTY_BASE;
3317 data->REG_PWM_READ = NCT6106_REG_PWM_READ;
3318 data->REG_PWM_MODE = NCT6106_REG_PWM_MODE;
3319 data->PWM_MODE_MASK = NCT6106_PWM_MODE_MASK;
3320 data->REG_AUTO_TEMP = NCT6106_REG_AUTO_TEMP;
3321 data->REG_AUTO_PWM = NCT6106_REG_AUTO_PWM;
3322 data->REG_CRITICAL_TEMP = NCT6106_REG_CRITICAL_TEMP;
3323 data->REG_CRITICAL_TEMP_TOLERANCE
3324 = NCT6106_REG_CRITICAL_TEMP_TOLERANCE;
3325 data->REG_CRITICAL_PWM_ENABLE = NCT6106_REG_CRITICAL_PWM_ENABLE;
3326 data->CRITICAL_PWM_ENABLE_MASK
3327 = NCT6106_CRITICAL_PWM_ENABLE_MASK;
3328 data->REG_CRITICAL_PWM = NCT6106_REG_CRITICAL_PWM;
3329 data->REG_TEMP_OFFSET = NCT6106_REG_TEMP_OFFSET;
3330 data->REG_TEMP_SOURCE = NCT6106_REG_TEMP_SOURCE;
3331 data->REG_TEMP_SEL = NCT6106_REG_TEMP_SEL;
3332 data->REG_WEIGHT_TEMP_SEL = NCT6106_REG_WEIGHT_TEMP_SEL;
3333 data->REG_WEIGHT_TEMP[0] = NCT6106_REG_WEIGHT_TEMP_STEP;
3334 data->REG_WEIGHT_TEMP[1] = NCT6106_REG_WEIGHT_TEMP_STEP_TOL;
3335 data->REG_WEIGHT_TEMP[2] = NCT6106_REG_WEIGHT_TEMP_BASE;
3336 data->REG_ALARM = NCT6106_REG_ALARM;
3337 data->ALARM_BITS = NCT6106_ALARM_BITS;
30846993
GR
3338 data->REG_BEEP = NCT6106_REG_BEEP;
3339 data->BEEP_BITS = NCT6106_BEEP_BITS;
6c009501
GR
3340
3341 reg_temp = NCT6106_REG_TEMP;
3342 num_reg_temp = ARRAY_SIZE(NCT6106_REG_TEMP);
3343 reg_temp_over = NCT6106_REG_TEMP_OVER;
3344 reg_temp_hyst = NCT6106_REG_TEMP_HYST;
3345 reg_temp_config = NCT6106_REG_TEMP_CONFIG;
3346 reg_temp_alternate = NCT6106_REG_TEMP_ALTERNATE;
3347 reg_temp_crit = NCT6106_REG_TEMP_CRIT;
b7a61353
GR
3348 reg_temp_crit_l = NCT6106_REG_TEMP_CRIT_L;
3349 reg_temp_crit_h = NCT6106_REG_TEMP_CRIT_H;
6c009501
GR
3350
3351 break;
9de2e2e8
GR
3352 case nct6775:
3353 data->in_num = 9;
77eb5b37 3354 data->pwm_num = 3;
cdcaeceb 3355 data->auto_pwm_num = 6;
1c65dc36 3356 data->has_fan_div = true;
aa136e5d 3357 data->temp_fixed_num = 3;
b1d2bff6 3358 data->num_temp_alarms = 3;
30846993 3359 data->num_temp_beeps = 3;
9de2e2e8
GR
3360
3361 data->ALARM_BITS = NCT6775_ALARM_BITS;
30846993 3362 data->BEEP_BITS = NCT6775_BEEP_BITS;
9de2e2e8 3363
1c65dc36
GR
3364 data->fan_from_reg = fan_from_reg16;
3365 data->fan_from_reg_min = fan_from_reg8;
cdcaeceb
GR
3366 data->target_temp_mask = 0x7f;
3367 data->tolerance_mask = 0x0f;
3368 data->speed_tolerance_limit = 15;
1c65dc36 3369
aa136e5d
GR
3370 data->temp_label = nct6775_temp_label;
3371 data->temp_label_num = ARRAY_SIZE(nct6775_temp_label);
3372
9de2e2e8
GR
3373 data->REG_CONFIG = NCT6775_REG_CONFIG;
3374 data->REG_VBAT = NCT6775_REG_VBAT;
aa136e5d 3375 data->REG_DIODE = NCT6775_REG_DIODE;
6c009501 3376 data->DIODE_MASK = NCT6775_DIODE_MASK;
9de2e2e8
GR
3377 data->REG_VIN = NCT6775_REG_IN;
3378 data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN;
3379 data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX;
cdcaeceb 3380 data->REG_TARGET = NCT6775_REG_TARGET;
1c65dc36 3381 data->REG_FAN = NCT6775_REG_FAN;
77eb5b37 3382 data->REG_FAN_MODE = NCT6775_REG_FAN_MODE;
1c65dc36 3383 data->REG_FAN_MIN = NCT6775_REG_FAN_MIN;
5c25d954 3384 data->REG_FAN_PULSES = NCT6775_REG_FAN_PULSES;
6c009501 3385 data->FAN_PULSE_SHIFT = NCT6775_FAN_PULSE_SHIFT;
cdcaeceb
GR
3386 data->REG_FAN_TIME[0] = NCT6775_REG_FAN_STOP_TIME;
3387 data->REG_FAN_TIME[1] = NCT6775_REG_FAN_STEP_UP_TIME;
3388 data->REG_FAN_TIME[2] = NCT6775_REG_FAN_STEP_DOWN_TIME;
77eb5b37 3389 data->REG_PWM[0] = NCT6775_REG_PWM;
cdcaeceb
GR
3390 data->REG_PWM[1] = NCT6775_REG_FAN_START_OUTPUT;
3391 data->REG_PWM[2] = NCT6775_REG_FAN_STOP_OUTPUT;
3392 data->REG_PWM[3] = NCT6775_REG_FAN_MAX_OUTPUT;
3393 data->REG_PWM[4] = NCT6775_REG_FAN_STEP_OUTPUT;
bbd8decd 3394 data->REG_PWM[5] = NCT6775_REG_WEIGHT_DUTY_STEP;
77eb5b37
GR
3395 data->REG_PWM_READ = NCT6775_REG_PWM_READ;
3396 data->REG_PWM_MODE = NCT6775_REG_PWM_MODE;
3397 data->PWM_MODE_MASK = NCT6775_PWM_MODE_MASK;
cdcaeceb
GR
3398 data->REG_AUTO_TEMP = NCT6775_REG_AUTO_TEMP;
3399 data->REG_AUTO_PWM = NCT6775_REG_AUTO_PWM;
3400 data->REG_CRITICAL_TEMP = NCT6775_REG_CRITICAL_TEMP;
3401 data->REG_CRITICAL_TEMP_TOLERANCE
3402 = NCT6775_REG_CRITICAL_TEMP_TOLERANCE;
aa136e5d
GR
3403 data->REG_TEMP_OFFSET = NCT6775_REG_TEMP_OFFSET;
3404 data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE;
cdcaeceb 3405 data->REG_TEMP_SEL = NCT6775_REG_TEMP_SEL;
bbd8decd
GR
3406 data->REG_WEIGHT_TEMP_SEL = NCT6775_REG_WEIGHT_TEMP_SEL;
3407 data->REG_WEIGHT_TEMP[0] = NCT6775_REG_WEIGHT_TEMP_STEP;
3408 data->REG_WEIGHT_TEMP[1] = NCT6775_REG_WEIGHT_TEMP_STEP_TOL;
3409 data->REG_WEIGHT_TEMP[2] = NCT6775_REG_WEIGHT_TEMP_BASE;
9de2e2e8 3410 data->REG_ALARM = NCT6775_REG_ALARM;
30846993 3411 data->REG_BEEP = NCT6775_REG_BEEP;
aa136e5d
GR
3412
3413 reg_temp = NCT6775_REG_TEMP;
3414 num_reg_temp = ARRAY_SIZE(NCT6775_REG_TEMP);
3415 reg_temp_over = NCT6775_REG_TEMP_OVER;
3416 reg_temp_hyst = NCT6775_REG_TEMP_HYST;
3417 reg_temp_config = NCT6775_REG_TEMP_CONFIG;
3418 reg_temp_alternate = NCT6775_REG_TEMP_ALTERNATE;
3419 reg_temp_crit = NCT6775_REG_TEMP_CRIT;
3420
9de2e2e8
GR
3421 break;
3422 case nct6776:
3423 data->in_num = 9;
77eb5b37 3424 data->pwm_num = 3;
cdcaeceb 3425 data->auto_pwm_num = 4;
1c65dc36 3426 data->has_fan_div = false;
aa136e5d 3427 data->temp_fixed_num = 3;
b1d2bff6 3428 data->num_temp_alarms = 3;
30846993 3429 data->num_temp_beeps = 6;
9de2e2e8
GR
3430
3431 data->ALARM_BITS = NCT6776_ALARM_BITS;
30846993 3432 data->BEEP_BITS = NCT6776_BEEP_BITS;
9de2e2e8 3433
1c65dc36
GR
3434 data->fan_from_reg = fan_from_reg13;
3435 data->fan_from_reg_min = fan_from_reg13;
cdcaeceb
GR
3436 data->target_temp_mask = 0xff;
3437 data->tolerance_mask = 0x07;
3438 data->speed_tolerance_limit = 63;
1c65dc36 3439
aa136e5d
GR
3440 data->temp_label = nct6776_temp_label;
3441 data->temp_label_num = ARRAY_SIZE(nct6776_temp_label);
3442
9de2e2e8
GR
3443 data->REG_CONFIG = NCT6775_REG_CONFIG;
3444 data->REG_VBAT = NCT6775_REG_VBAT;
aa136e5d 3445 data->REG_DIODE = NCT6775_REG_DIODE;
6c009501 3446 data->DIODE_MASK = NCT6775_DIODE_MASK;
9de2e2e8
GR
3447 data->REG_VIN = NCT6775_REG_IN;
3448 data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN;
3449 data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX;
cdcaeceb 3450 data->REG_TARGET = NCT6775_REG_TARGET;
1c65dc36 3451 data->REG_FAN = NCT6775_REG_FAN;
77eb5b37 3452 data->REG_FAN_MODE = NCT6775_REG_FAN_MODE;
1c65dc36 3453 data->REG_FAN_MIN = NCT6776_REG_FAN_MIN;
5c25d954 3454 data->REG_FAN_PULSES = NCT6776_REG_FAN_PULSES;
6c009501 3455 data->FAN_PULSE_SHIFT = NCT6775_FAN_PULSE_SHIFT;
cdcaeceb
GR
3456 data->REG_FAN_TIME[0] = NCT6775_REG_FAN_STOP_TIME;
3457 data->REG_FAN_TIME[1] = NCT6775_REG_FAN_STEP_UP_TIME;
3458 data->REG_FAN_TIME[2] = NCT6775_REG_FAN_STEP_DOWN_TIME;
3459 data->REG_TOLERANCE_H = NCT6776_REG_TOLERANCE_H;
77eb5b37 3460 data->REG_PWM[0] = NCT6775_REG_PWM;
cdcaeceb
GR
3461 data->REG_PWM[1] = NCT6775_REG_FAN_START_OUTPUT;
3462 data->REG_PWM[2] = NCT6775_REG_FAN_STOP_OUTPUT;
bbd8decd
GR
3463 data->REG_PWM[5] = NCT6775_REG_WEIGHT_DUTY_STEP;
3464 data->REG_PWM[6] = NCT6776_REG_WEIGHT_DUTY_BASE;
77eb5b37
GR
3465 data->REG_PWM_READ = NCT6775_REG_PWM_READ;
3466 data->REG_PWM_MODE = NCT6776_REG_PWM_MODE;
3467 data->PWM_MODE_MASK = NCT6776_PWM_MODE_MASK;
cdcaeceb
GR
3468 data->REG_AUTO_TEMP = NCT6775_REG_AUTO_TEMP;
3469 data->REG_AUTO_PWM = NCT6775_REG_AUTO_PWM;
3470 data->REG_CRITICAL_TEMP = NCT6775_REG_CRITICAL_TEMP;
3471 data->REG_CRITICAL_TEMP_TOLERANCE
3472 = NCT6775_REG_CRITICAL_TEMP_TOLERANCE;
aa136e5d
GR
3473 data->REG_TEMP_OFFSET = NCT6775_REG_TEMP_OFFSET;
3474 data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE;
cdcaeceb 3475 data->REG_TEMP_SEL = NCT6775_REG_TEMP_SEL;
bbd8decd
GR
3476 data->REG_WEIGHT_TEMP_SEL = NCT6775_REG_WEIGHT_TEMP_SEL;
3477 data->REG_WEIGHT_TEMP[0] = NCT6775_REG_WEIGHT_TEMP_STEP;
3478 data->REG_WEIGHT_TEMP[1] = NCT6775_REG_WEIGHT_TEMP_STEP_TOL;
3479 data->REG_WEIGHT_TEMP[2] = NCT6775_REG_WEIGHT_TEMP_BASE;
9de2e2e8 3480 data->REG_ALARM = NCT6775_REG_ALARM;
30846993 3481 data->REG_BEEP = NCT6776_REG_BEEP;
aa136e5d
GR
3482
3483 reg_temp = NCT6775_REG_TEMP;
3484 num_reg_temp = ARRAY_SIZE(NCT6775_REG_TEMP);
3485 reg_temp_over = NCT6775_REG_TEMP_OVER;
3486 reg_temp_hyst = NCT6775_REG_TEMP_HYST;
3487 reg_temp_config = NCT6776_REG_TEMP_CONFIG;
3488 reg_temp_alternate = NCT6776_REG_TEMP_ALTERNATE;
3489 reg_temp_crit = NCT6776_REG_TEMP_CRIT;
3490
9de2e2e8
GR
3491 break;
3492 case nct6779:
3493 data->in_num = 15;
77eb5b37 3494 data->pwm_num = 5;
cdcaeceb 3495 data->auto_pwm_num = 4;
1c65dc36 3496 data->has_fan_div = false;
aa136e5d 3497 data->temp_fixed_num = 6;
b1d2bff6 3498 data->num_temp_alarms = 2;
30846993 3499 data->num_temp_beeps = 2;
9de2e2e8
GR
3500
3501 data->ALARM_BITS = NCT6779_ALARM_BITS;
30846993 3502 data->BEEP_BITS = NCT6779_BEEP_BITS;
9de2e2e8 3503
1c65dc36
GR
3504 data->fan_from_reg = fan_from_reg13;
3505 data->fan_from_reg_min = fan_from_reg13;
cdcaeceb
GR
3506 data->target_temp_mask = 0xff;
3507 data->tolerance_mask = 0x07;
3508 data->speed_tolerance_limit = 63;
1c65dc36 3509
aa136e5d
GR
3510 data->temp_label = nct6779_temp_label;
3511 data->temp_label_num = ARRAY_SIZE(nct6779_temp_label);
3512
9de2e2e8
GR
3513 data->REG_CONFIG = NCT6775_REG_CONFIG;
3514 data->REG_VBAT = NCT6775_REG_VBAT;
aa136e5d 3515 data->REG_DIODE = NCT6775_REG_DIODE;
6c009501 3516 data->DIODE_MASK = NCT6775_DIODE_MASK;
9de2e2e8
GR
3517 data->REG_VIN = NCT6779_REG_IN;
3518 data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN;
3519 data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX;
cdcaeceb 3520 data->REG_TARGET = NCT6775_REG_TARGET;
1c65dc36 3521 data->REG_FAN = NCT6779_REG_FAN;
77eb5b37 3522 data->REG_FAN_MODE = NCT6775_REG_FAN_MODE;
1c65dc36 3523 data->REG_FAN_MIN = NCT6776_REG_FAN_MIN;
5c25d954 3524 data->REG_FAN_PULSES = NCT6779_REG_FAN_PULSES;
6c009501 3525 data->FAN_PULSE_SHIFT = NCT6775_FAN_PULSE_SHIFT;
cdcaeceb
GR
3526 data->REG_FAN_TIME[0] = NCT6775_REG_FAN_STOP_TIME;
3527 data->REG_FAN_TIME[1] = NCT6775_REG_FAN_STEP_UP_TIME;
3528 data->REG_FAN_TIME[2] = NCT6775_REG_FAN_STEP_DOWN_TIME;
3529 data->REG_TOLERANCE_H = NCT6776_REG_TOLERANCE_H;
77eb5b37 3530 data->REG_PWM[0] = NCT6775_REG_PWM;
cdcaeceb
GR
3531 data->REG_PWM[1] = NCT6775_REG_FAN_START_OUTPUT;
3532 data->REG_PWM[2] = NCT6775_REG_FAN_STOP_OUTPUT;
bbd8decd
GR
3533 data->REG_PWM[5] = NCT6775_REG_WEIGHT_DUTY_STEP;
3534 data->REG_PWM[6] = NCT6776_REG_WEIGHT_DUTY_BASE;
77eb5b37
GR
3535 data->REG_PWM_READ = NCT6775_REG_PWM_READ;
3536 data->REG_PWM_MODE = NCT6776_REG_PWM_MODE;
3537 data->PWM_MODE_MASK = NCT6776_PWM_MODE_MASK;
cdcaeceb
GR
3538 data->REG_AUTO_TEMP = NCT6775_REG_AUTO_TEMP;
3539 data->REG_AUTO_PWM = NCT6775_REG_AUTO_PWM;
3540 data->REG_CRITICAL_TEMP = NCT6775_REG_CRITICAL_TEMP;
3541 data->REG_CRITICAL_TEMP_TOLERANCE
3542 = NCT6775_REG_CRITICAL_TEMP_TOLERANCE;
6c009501
GR
3543 data->REG_CRITICAL_PWM_ENABLE = NCT6779_REG_CRITICAL_PWM_ENABLE;
3544 data->CRITICAL_PWM_ENABLE_MASK
3545 = NCT6779_CRITICAL_PWM_ENABLE_MASK;
3546 data->REG_CRITICAL_PWM = NCT6779_REG_CRITICAL_PWM;
aa136e5d
GR
3547 data->REG_TEMP_OFFSET = NCT6779_REG_TEMP_OFFSET;
3548 data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE;
cdcaeceb 3549 data->REG_TEMP_SEL = NCT6775_REG_TEMP_SEL;
bbd8decd
GR
3550 data->REG_WEIGHT_TEMP_SEL = NCT6775_REG_WEIGHT_TEMP_SEL;
3551 data->REG_WEIGHT_TEMP[0] = NCT6775_REG_WEIGHT_TEMP_STEP;
3552 data->REG_WEIGHT_TEMP[1] = NCT6775_REG_WEIGHT_TEMP_STEP_TOL;
3553 data->REG_WEIGHT_TEMP[2] = NCT6775_REG_WEIGHT_TEMP_BASE;
9de2e2e8 3554 data->REG_ALARM = NCT6779_REG_ALARM;
30846993 3555 data->REG_BEEP = NCT6776_REG_BEEP;
aa136e5d
GR
3556
3557 reg_temp = NCT6779_REG_TEMP;
3558 num_reg_temp = ARRAY_SIZE(NCT6779_REG_TEMP);
3559 reg_temp_over = NCT6779_REG_TEMP_OVER;
3560 reg_temp_hyst = NCT6779_REG_TEMP_HYST;
3561 reg_temp_config = NCT6779_REG_TEMP_CONFIG;
3562 reg_temp_alternate = NCT6779_REG_TEMP_ALTERNATE;
3563 reg_temp_crit = NCT6779_REG_TEMP_CRIT;
3564
578ab5f0
DB
3565 break;
3566 case nct6791:
3567 data->in_num = 15;
3568 data->pwm_num = 6;
3569 data->auto_pwm_num = 4;
3570 data->has_fan_div = false;
3571 data->temp_fixed_num = 6;
3572 data->num_temp_alarms = 2;
3573 data->num_temp_beeps = 2;
3574
3575 data->ALARM_BITS = NCT6791_ALARM_BITS;
3576 data->BEEP_BITS = NCT6779_BEEP_BITS;
3577
3578 data->fan_from_reg = fan_from_reg13;
3579 data->fan_from_reg_min = fan_from_reg13;
3580 data->target_temp_mask = 0xff;
3581 data->tolerance_mask = 0x07;
3582 data->speed_tolerance_limit = 63;
3583
3584 data->temp_label = nct6779_temp_label;
3585 data->temp_label_num = ARRAY_SIZE(nct6779_temp_label);
3586
3587 data->REG_CONFIG = NCT6775_REG_CONFIG;
3588 data->REG_VBAT = NCT6775_REG_VBAT;
3589 data->REG_DIODE = NCT6775_REG_DIODE;
3590 data->DIODE_MASK = NCT6775_DIODE_MASK;
3591 data->REG_VIN = NCT6779_REG_IN;
3592 data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN;
3593 data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX;
3594 data->REG_TARGET = NCT6775_REG_TARGET;
3595 data->REG_FAN = NCT6779_REG_FAN;
3596 data->REG_FAN_MODE = NCT6775_REG_FAN_MODE;
3597 data->REG_FAN_MIN = NCT6776_REG_FAN_MIN;
3598 data->REG_FAN_PULSES = NCT6779_REG_FAN_PULSES;
3599 data->FAN_PULSE_SHIFT = NCT6775_FAN_PULSE_SHIFT;
3600 data->REG_FAN_TIME[0] = NCT6775_REG_FAN_STOP_TIME;
3601 data->REG_FAN_TIME[1] = NCT6775_REG_FAN_STEP_UP_TIME;
3602 data->REG_FAN_TIME[2] = NCT6775_REG_FAN_STEP_DOWN_TIME;
3603 data->REG_TOLERANCE_H = NCT6776_REG_TOLERANCE_H;
3604 data->REG_PWM[0] = NCT6775_REG_PWM;
3605 data->REG_PWM[1] = NCT6775_REG_FAN_START_OUTPUT;
3606 data->REG_PWM[2] = NCT6775_REG_FAN_STOP_OUTPUT;
3607 data->REG_PWM[5] = NCT6775_REG_WEIGHT_DUTY_STEP;
3608 data->REG_PWM[6] = NCT6776_REG_WEIGHT_DUTY_BASE;
3609 data->REG_PWM_READ = NCT6775_REG_PWM_READ;
3610 data->REG_PWM_MODE = NCT6776_REG_PWM_MODE;
3611 data->PWM_MODE_MASK = NCT6776_PWM_MODE_MASK;
3612 data->REG_AUTO_TEMP = NCT6775_REG_AUTO_TEMP;
3613 data->REG_AUTO_PWM = NCT6775_REG_AUTO_PWM;
3614 data->REG_CRITICAL_TEMP = NCT6775_REG_CRITICAL_TEMP;
3615 data->REG_CRITICAL_TEMP_TOLERANCE
3616 = NCT6775_REG_CRITICAL_TEMP_TOLERANCE;
3617 data->REG_CRITICAL_PWM_ENABLE = NCT6779_REG_CRITICAL_PWM_ENABLE;
3618 data->CRITICAL_PWM_ENABLE_MASK
3619 = NCT6779_CRITICAL_PWM_ENABLE_MASK;
3620 data->REG_CRITICAL_PWM = NCT6779_REG_CRITICAL_PWM;
3621 data->REG_TEMP_OFFSET = NCT6779_REG_TEMP_OFFSET;
3622 data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE;
3623 data->REG_TEMP_SEL = NCT6775_REG_TEMP_SEL;
3624 data->REG_WEIGHT_TEMP_SEL = NCT6775_REG_WEIGHT_TEMP_SEL;
3625 data->REG_WEIGHT_TEMP[0] = NCT6775_REG_WEIGHT_TEMP_STEP;
3626 data->REG_WEIGHT_TEMP[1] = NCT6775_REG_WEIGHT_TEMP_STEP_TOL;
3627 data->REG_WEIGHT_TEMP[2] = NCT6775_REG_WEIGHT_TEMP_BASE;
3628 data->REG_ALARM = NCT6791_REG_ALARM;
3629 data->REG_BEEP = NCT6776_REG_BEEP;
3630
3631 reg_temp = NCT6779_REG_TEMP;
3632 num_reg_temp = ARRAY_SIZE(NCT6779_REG_TEMP);
3633 reg_temp_over = NCT6779_REG_TEMP_OVER;
3634 reg_temp_hyst = NCT6779_REG_TEMP_HYST;
3635 reg_temp_config = NCT6779_REG_TEMP_CONFIG;
3636 reg_temp_alternate = NCT6779_REG_TEMP_ALTERNATE;
3637 reg_temp_crit = NCT6779_REG_TEMP_CRIT;
3638
9de2e2e8
GR
3639 break;
3640 default:
3641 return -ENODEV;
3642 }
3643 data->have_in = (1 << data->in_num) - 1;
aa136e5d
GR
3644 data->have_temp = 0;
3645
3646 /*
3647 * On some boards, not all available temperature sources are monitored,
3648 * even though some of the monitoring registers are unused.
3649 * Get list of unused monitoring registers, then detect if any fan
3650 * controls are configured to use unmonitored temperature sources.
3651 * If so, assign the unmonitored temperature sources to available
3652 * monitoring registers.
3653 */
3654 mask = 0;
3655 available = 0;
3656 for (i = 0; i < num_reg_temp; i++) {
3657 if (reg_temp[i] == 0)
3658 continue;
3659
3660 src = nct6775_read_value(data, data->REG_TEMP_SOURCE[i]) & 0x1f;
3661 if (!src || (mask & (1 << src)))
3662 available |= 1 << i;
3663
3664 mask |= 1 << src;
3665 }
3666
8e9285b0
GR
3667 /*
3668 * Now find unmonitored temperature registers and enable monitoring
3669 * if additional monitoring registers are available.
3670 */
3671 add_temp_sensors(data, data->REG_TEMP_SEL, &available, &mask);
3672 add_temp_sensors(data, data->REG_WEIGHT_TEMP_SEL, &available, &mask);
3673
aa136e5d
GR
3674 mask = 0;
3675 s = NUM_TEMP_FIXED; /* First dynamic temperature attribute */
3676 for (i = 0; i < num_reg_temp; i++) {
3677 if (reg_temp[i] == 0)
3678 continue;
3679
3680 src = nct6775_read_value(data, data->REG_TEMP_SOURCE[i]) & 0x1f;
3681 if (!src || (mask & (1 << src)))
3682 continue;
3683
3684 if (src >= data->temp_label_num ||
3685 !strlen(data->temp_label[src])) {
3686 dev_info(dev,
3687 "Invalid temperature source %d at index %d, source register 0x%x, temp register 0x%x\n",
3688 src, i, data->REG_TEMP_SOURCE[i], reg_temp[i]);
3689 continue;
3690 }
3691
3692 mask |= 1 << src;
3693
3694 /* Use fixed index for SYSTIN(1), CPUTIN(2), AUXTIN(3) */
3695 if (src <= data->temp_fixed_num) {
3696 data->have_temp |= 1 << (src - 1);
3697 data->have_temp_fixed |= 1 << (src - 1);
3698 data->reg_temp[0][src - 1] = reg_temp[i];
3699 data->reg_temp[1][src - 1] = reg_temp_over[i];
3700 data->reg_temp[2][src - 1] = reg_temp_hyst[i];
b7a61353
GR
3701 if (reg_temp_crit_h && reg_temp_crit_h[i])
3702 data->reg_temp[3][src - 1] = reg_temp_crit_h[i];
3703 else if (reg_temp_crit[src - 1])
3704 data->reg_temp[3][src - 1]
3705 = reg_temp_crit[src - 1];
3706 if (reg_temp_crit_l && reg_temp_crit_l[i])
3707 data->reg_temp[4][src - 1] = reg_temp_crit_l[i];
aa136e5d
GR
3708 data->reg_temp_config[src - 1] = reg_temp_config[i];
3709 data->temp_src[src - 1] = src;
3710 continue;
3711 }
3712
3713 if (s >= NUM_TEMP)
3714 continue;
3715
3716 /* Use dynamic index for other sources */
3717 data->have_temp |= 1 << s;
3718 data->reg_temp[0][s] = reg_temp[i];
3719 data->reg_temp[1][s] = reg_temp_over[i];
3720 data->reg_temp[2][s] = reg_temp_hyst[i];
3721 data->reg_temp_config[s] = reg_temp_config[i];
b7a61353
GR
3722 if (reg_temp_crit_h && reg_temp_crit_h[i])
3723 data->reg_temp[3][s] = reg_temp_crit_h[i];
3724 else if (reg_temp_crit[src - 1])
aa136e5d 3725 data->reg_temp[3][s] = reg_temp_crit[src - 1];
b7a61353
GR
3726 if (reg_temp_crit_l && reg_temp_crit_l[i])
3727 data->reg_temp[4][s] = reg_temp_crit_l[i];
aa136e5d
GR
3728
3729 data->temp_src[s] = src;
3730 s++;
3731 }
3732
3733#ifdef USE_ALTERNATE
3734 /*
3735 * Go through the list of alternate temp registers and enable
3736 * if possible.
3737 * The temperature is already monitored if the respective bit in <mask>
3738 * is set.
3739 */
3740 for (i = 0; i < data->temp_label_num - 1; i++) {
3741 if (!reg_temp_alternate[i])
3742 continue;
3743 if (mask & (1 << (i + 1)))
3744 continue;
3745 if (i < data->temp_fixed_num) {
3746 if (data->have_temp & (1 << i))
3747 continue;
3748 data->have_temp |= 1 << i;
3749 data->have_temp_fixed |= 1 << i;
3750 data->reg_temp[0][i] = reg_temp_alternate[i];
169c05cd
GR
3751 if (i < num_reg_temp) {
3752 data->reg_temp[1][i] = reg_temp_over[i];
3753 data->reg_temp[2][i] = reg_temp_hyst[i];
3754 }
aa136e5d
GR
3755 data->temp_src[i] = i + 1;
3756 continue;
3757 }
3758
3759 if (s >= NUM_TEMP) /* Abort if no more space */
3760 break;
3761
3762 data->have_temp |= 1 << s;
3763 data->reg_temp[0][s] = reg_temp_alternate[i];
3764 data->temp_src[s] = i + 1;
3765 s++;
3766 }
3767#endif /* USE_ALTERNATE */
3768
9de2e2e8
GR
3769 /* Initialize the chip */
3770 nct6775_init_device(data);
3771
9de2e2e8
GR
3772 err = superio_enter(sio_data->sioreg);
3773 if (err)
3774 return err;
3775
0fc1f8fc
GR
3776 cr2a = superio_inb(sio_data->sioreg, 0x2a);
3777 switch (data->kind) {
3778 case nct6775:
f73cf632 3779 data->have_vid = (cr2a & 0x40);
0fc1f8fc
GR
3780 break;
3781 case nct6776:
f73cf632 3782 data->have_vid = (cr2a & 0x60) == 0x40;
0fc1f8fc 3783 break;
6c009501 3784 case nct6106:
0fc1f8fc 3785 case nct6779:
578ab5f0 3786 case nct6791:
0fc1f8fc
GR
3787 break;
3788 }
3789
9de2e2e8
GR
3790 /*
3791 * Read VID value
3792 * We can get the VID input values directly at logical device D 0xe3.
3793 */
f73cf632 3794 if (data->have_vid) {
0fc1f8fc
GR
3795 superio_select(sio_data->sioreg, NCT6775_LD_VID);
3796 data->vid = superio_inb(sio_data->sioreg, 0xe3);
3797 data->vrm = vid_which_vrm();
3798 }
47ece964
GR
3799
3800 if (fan_debounce) {
3801 u8 tmp;
3802
3803 superio_select(sio_data->sioreg, NCT6775_LD_HWM);
3804 tmp = superio_inb(sio_data->sioreg,
3805 NCT6775_REG_CR_FAN_DEBOUNCE);
3806 switch (data->kind) {
6c009501
GR
3807 case nct6106:
3808 tmp |= 0xe0;
3809 break;
47ece964
GR
3810 case nct6775:
3811 tmp |= 0x1e;
3812 break;
3813 case nct6776:
3814 case nct6779:
3815 tmp |= 0x3e;
3816 break;
578ab5f0
DB
3817 case nct6791:
3818 tmp |= 0x7e;
3819 break;
47ece964
GR
3820 }
3821 superio_outb(sio_data->sioreg, NCT6775_REG_CR_FAN_DEBOUNCE,
3822 tmp);
3823 dev_info(&pdev->dev, "Enabled fan debounce for chip %s\n",
3824 data->name);
3825 }
3826
df612d5f 3827 nct6775_check_fan_inputs(data);
9de2e2e8 3828
f73cf632 3829 superio_exit(sio_data->sioreg);
1c65dc36
GR
3830
3831 /* Read fan clock dividers immediately */
3832 nct6775_init_fan_common(dev, data);
3833
77eb5b37 3834 /* Register sysfs hooks */
f73cf632
GR
3835 group = nct6775_create_attr_group(dev, &nct6775_pwm_template_group,
3836 data->pwm_num);
615fc8cb
GR
3837 if (IS_ERR(group))
3838 return PTR_ERR(group);
3839
3840 data->groups[data->num_attr_groups++] = group;
9de2e2e8 3841
f73cf632
GR
3842 group = nct6775_create_attr_group(dev, &nct6775_in_template_group,
3843 fls(data->have_in));
615fc8cb
GR
3844 if (IS_ERR(group))
3845 return PTR_ERR(group);
3846
3847 data->groups[data->num_attr_groups++] = group;
1c65dc36 3848
f73cf632
GR
3849 group = nct6775_create_attr_group(dev, &nct6775_fan_template_group,
3850 fls(data->has_fan));
615fc8cb
GR
3851 if (IS_ERR(group))
3852 return PTR_ERR(group);
3853
3854 data->groups[data->num_attr_groups++] = group;
aa136e5d 3855
f73cf632
GR
3856 group = nct6775_create_attr_group(dev, &nct6775_temp_template_group,
3857 fls(data->have_temp));
615fc8cb
GR
3858 if (IS_ERR(group))
3859 return PTR_ERR(group);
a6bd5878 3860
615fc8cb
GR
3861 data->groups[data->num_attr_groups++] = group;
3862 data->groups[data->num_attr_groups++] = &nct6775_group_other;
9de2e2e8 3863
615fc8cb
GR
3864 data->hwmon_dev = hwmon_device_register_with_groups(dev, data->name,
3865 data, data->groups);
3866 if (IS_ERR(data->hwmon_dev))
3867 return PTR_ERR(data->hwmon_dev);
9de2e2e8
GR
3868
3869 return 0;
9de2e2e8
GR
3870}
3871
3872static int nct6775_remove(struct platform_device *pdev)
3873{
3874 struct nct6775_data *data = platform_get_drvdata(pdev);
3875
3876 hwmon_device_unregister(data->hwmon_dev);
9de2e2e8
GR
3877
3878 return 0;
3879}
3880
84d19d92
GR
3881#ifdef CONFIG_PM
3882static int nct6775_suspend(struct device *dev)
3883{
3884 struct nct6775_data *data = nct6775_update_device(dev);
84d19d92
GR
3885
3886 mutex_lock(&data->update_lock);
3887 data->vbat = nct6775_read_value(data, data->REG_VBAT);
df612d5f 3888 if (data->kind == nct6775) {
84d19d92
GR
3889 data->fandiv1 = nct6775_read_value(data, NCT6775_REG_FANDIV1);
3890 data->fandiv2 = nct6775_read_value(data, NCT6775_REG_FANDIV2);
3891 }
3892 mutex_unlock(&data->update_lock);
3893
3894 return 0;
3895}
3896
3897static int nct6775_resume(struct device *dev)
3898{
3899 struct nct6775_data *data = dev_get_drvdata(dev);
84d19d92
GR
3900 int i, j;
3901
3902 mutex_lock(&data->update_lock);
3903 data->bank = 0xff; /* Force initial bank selection */
3904
3905 /* Restore limits */
3906 for (i = 0; i < data->in_num; i++) {
3907 if (!(data->have_in & (1 << i)))
3908 continue;
3909
3910 nct6775_write_value(data, data->REG_IN_MINMAX[0][i],
3911 data->in[i][1]);
3912 nct6775_write_value(data, data->REG_IN_MINMAX[1][i],
3913 data->in[i][2]);
3914 }
3915
c409fd43 3916 for (i = 0; i < ARRAY_SIZE(data->fan_min); i++) {
84d19d92
GR
3917 if (!(data->has_fan_min & (1 << i)))
3918 continue;
3919
3920 nct6775_write_value(data, data->REG_FAN_MIN[i],
3921 data->fan_min[i]);
3922 }
3923
3924 for (i = 0; i < NUM_TEMP; i++) {
3925 if (!(data->have_temp & (1 << i)))
3926 continue;
3927
c409fd43 3928 for (j = 1; j < ARRAY_SIZE(data->reg_temp); j++)
84d19d92
GR
3929 if (data->reg_temp[j][i])
3930 nct6775_write_temp(data, data->reg_temp[j][i],
3931 data->temp[j][i]);
3932 }
3933
3934 /* Restore other settings */
3935 nct6775_write_value(data, data->REG_VBAT, data->vbat);
df612d5f 3936 if (data->kind == nct6775) {
84d19d92
GR
3937 nct6775_write_value(data, NCT6775_REG_FANDIV1, data->fandiv1);
3938 nct6775_write_value(data, NCT6775_REG_FANDIV2, data->fandiv2);
3939 }
3940
3941 /* Force re-reading all values */
3942 data->valid = false;
3943 mutex_unlock(&data->update_lock);
3944
3945 return 0;
3946}
3947
3948static const struct dev_pm_ops nct6775_dev_pm_ops = {
3949 .suspend = nct6775_suspend,
3950 .resume = nct6775_resume,
374d1f98
HJ
3951 .freeze = nct6775_suspend,
3952 .restore = nct6775_resume,
84d19d92
GR
3953};
3954
3955#define NCT6775_DEV_PM_OPS (&nct6775_dev_pm_ops)
3956#else
3957#define NCT6775_DEV_PM_OPS NULL
3958#endif /* CONFIG_PM */
3959
9de2e2e8
GR
3960static struct platform_driver nct6775_driver = {
3961 .driver = {
3962 .owner = THIS_MODULE,
3963 .name = DRVNAME,
84d19d92 3964 .pm = NCT6775_DEV_PM_OPS,
9de2e2e8
GR
3965 },
3966 .probe = nct6775_probe,
3967 .remove = nct6775_remove,
3968};
3969
6d4b3621 3970static const char * const nct6775_sio_names[] __initconst = {
6c009501 3971 "NCT6106D",
2c7fd30d
GR
3972 "NCT6775F",
3973 "NCT6776D/F",
3974 "NCT6779D",
578ab5f0 3975 "NCT6791D",
2c7fd30d
GR
3976};
3977
9de2e2e8 3978/* nct6775_find() looks for a '627 in the Super-I/O config space */
698a7c24 3979static int __init nct6775_find(int sioaddr, struct nct6775_sio_data *sio_data)
9de2e2e8 3980{
9de2e2e8 3981 u16 val;
9de2e2e8 3982 int err;
698a7c24 3983 int addr;
9de2e2e8
GR
3984
3985 err = superio_enter(sioaddr);
3986 if (err)
3987 return err;
3988
3989 if (force_id)
3990 val = force_id;
3991 else
3992 val = (superio_inb(sioaddr, SIO_REG_DEVID) << 8)
3993 | superio_inb(sioaddr, SIO_REG_DEVID + 1);
3994 switch (val & SIO_ID_MASK) {
6c009501
GR
3995 case SIO_NCT6106_ID:
3996 sio_data->kind = nct6106;
3997 break;
9de2e2e8
GR
3998 case SIO_NCT6775_ID:
3999 sio_data->kind = nct6775;
9de2e2e8
GR
4000 break;
4001 case SIO_NCT6776_ID:
4002 sio_data->kind = nct6776;
9de2e2e8
GR
4003 break;
4004 case SIO_NCT6779_ID:
4005 sio_data->kind = nct6779;
9de2e2e8 4006 break;
578ab5f0
DB
4007 case SIO_NCT6791_ID:
4008 sio_data->kind = nct6791;
4009 break;
9de2e2e8
GR
4010 default:
4011 if (val != 0xffff)
4012 pr_debug("unsupported chip ID: 0x%04x\n", val);
4013 superio_exit(sioaddr);
4014 return -ENODEV;
4015 }
4016
4017 /* We have a known chip, find the HWM I/O address */
4018 superio_select(sioaddr, NCT6775_LD_HWM);
4019 val = (superio_inb(sioaddr, SIO_REG_ADDR) << 8)
4020 | superio_inb(sioaddr, SIO_REG_ADDR + 1);
698a7c24
GR
4021 addr = val & IOREGION_ALIGNMENT;
4022 if (addr == 0) {
9de2e2e8
GR
4023 pr_err("Refusing to enable a Super-I/O device with a base I/O port 0\n");
4024 superio_exit(sioaddr);
4025 return -ENODEV;
4026 }
4027
4028 /* Activate logical device if needed */
4029 val = superio_inb(sioaddr, SIO_REG_ENABLE);
4030 if (!(val & 0x01)) {
4031 pr_warn("Forcibly enabling Super-I/O. Sensor is probably unusable.\n");
4032 superio_outb(sioaddr, SIO_REG_ENABLE, val | 0x01);
4033 }
578ab5f0
DB
4034 if (sio_data->kind == nct6791) {
4035 val = superio_inb(sioaddr, NCT6791_REG_HM_IO_SPACE_LOCK_ENABLE);
4036 if (val & 0x10) {
4037 pr_info("Enabling hardware monitor logical device mappings.\n");
4038 superio_outb(sioaddr,
4039 NCT6791_REG_HM_IO_SPACE_LOCK_ENABLE,
4040 val & ~0x10);
4041 }
4042 }
9de2e2e8
GR
4043
4044 superio_exit(sioaddr);
698a7c24
GR
4045 pr_info("Found %s or compatible chip at %#x:%#x\n",
4046 nct6775_sio_names[sio_data->kind], sioaddr, addr);
9de2e2e8
GR
4047 sio_data->sioreg = sioaddr;
4048
698a7c24 4049 return addr;
9de2e2e8
GR
4050}
4051
4052/*
4053 * when Super-I/O functions move to a separate file, the Super-I/O
4054 * bus will manage the lifetime of the device and this module will only keep
615fc8cb 4055 * track of the nct6775 driver. But since we use platform_device_alloc(), we
9de2e2e8
GR
4056 * must keep track of the device
4057 */
698a7c24 4058static struct platform_device *pdev[2];
9de2e2e8
GR
4059
4060static int __init sensors_nct6775_init(void)
4061{
698a7c24
GR
4062 int i, err;
4063 bool found = false;
4064 int address;
9de2e2e8
GR
4065 struct resource res;
4066 struct nct6775_sio_data sio_data;
698a7c24
GR
4067 int sioaddr[2] = { 0x2e, 0x4e };
4068
4069 err = platform_driver_register(&nct6775_driver);
4070 if (err)
4071 return err;
9de2e2e8
GR
4072
4073 /*
4074 * initialize sio_data->kind and sio_data->sioreg.
4075 *
4076 * when Super-I/O functions move to a separate file, the Super-I/O
4077 * driver will probe 0x2e and 0x4e and auto-detect the presence of a
4078 * nct6775 hardware monitor, and call probe()
4079 */
698a7c24
GR
4080 for (i = 0; i < ARRAY_SIZE(pdev); i++) {
4081 address = nct6775_find(sioaddr[i], &sio_data);
4082 if (address <= 0)
4083 continue;
9de2e2e8 4084
698a7c24 4085 found = true;
9de2e2e8 4086
698a7c24
GR
4087 pdev[i] = platform_device_alloc(DRVNAME, address);
4088 if (!pdev[i]) {
4089 err = -ENOMEM;
4090 goto exit_device_put;
4091 }
9de2e2e8 4092
698a7c24
GR
4093 err = platform_device_add_data(pdev[i], &sio_data,
4094 sizeof(struct nct6775_sio_data));
4095 if (err)
4096 goto exit_device_put;
4097
4098 memset(&res, 0, sizeof(res));
4099 res.name = DRVNAME;
4100 res.start = address + IOREGION_OFFSET;
4101 res.end = address + IOREGION_OFFSET + IOREGION_LENGTH - 1;
4102 res.flags = IORESOURCE_IO;
4103
4104 err = acpi_check_resource_conflict(&res);
4105 if (err) {
4106 platform_device_put(pdev[i]);
4107 pdev[i] = NULL;
4108 continue;
4109 }
9de2e2e8 4110
698a7c24
GR
4111 err = platform_device_add_resources(pdev[i], &res, 1);
4112 if (err)
4113 goto exit_device_put;
9de2e2e8 4114
698a7c24
GR
4115 /* platform_device_add calls probe() */
4116 err = platform_device_add(pdev[i]);
4117 if (err)
4118 goto exit_device_put;
9de2e2e8 4119 }
698a7c24
GR
4120 if (!found) {
4121 err = -ENODEV;
4122 goto exit_unregister;
9de2e2e8
GR
4123 }
4124
4125 return 0;
4126
4127exit_device_put:
698a7c24
GR
4128 for (i = 0; i < ARRAY_SIZE(pdev); i++) {
4129 if (pdev[i])
4130 platform_device_put(pdev[i]);
4131 }
9de2e2e8
GR
4132exit_unregister:
4133 platform_driver_unregister(&nct6775_driver);
9de2e2e8
GR
4134 return err;
4135}
4136
4137static void __exit sensors_nct6775_exit(void)
4138{
698a7c24
GR
4139 int i;
4140
4141 for (i = 0; i < ARRAY_SIZE(pdev); i++) {
4142 if (pdev[i])
4143 platform_device_unregister(pdev[i]);
4144 }
9de2e2e8
GR
4145 platform_driver_unregister(&nct6775_driver);
4146}
4147
4148MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>");
4149MODULE_DESCRIPTION("NCT6775F/NCT6776F/NCT6779D driver");
4150MODULE_LICENSE("GPL");
4151
4152module_init(sensors_nct6775_init);
4153module_exit(sensors_nct6775_exit);