Merge tag 'boards-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm...
[deliverable/linux.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;
f73cf632
GR
728 struct attribute_group *group_in;
729 struct attribute_group *group_fan;
730 struct attribute_group *group_temp;
731 struct attribute_group *group_pwm;
9de2e2e8 732
b7a61353
GR
733 u16 reg_temp[5][NUM_TEMP]; /* 0=temp, 1=temp_over, 2=temp_hyst,
734 * 3=temp_crit, 4=temp_lcrit
aa136e5d
GR
735 */
736 u8 temp_src[NUM_TEMP];
737 u16 reg_temp_config[NUM_TEMP];
738 const char * const *temp_label;
739 int temp_label_num;
740
9de2e2e8
GR
741 u16 REG_CONFIG;
742 u16 REG_VBAT;
aa136e5d 743 u16 REG_DIODE;
6c009501 744 u8 DIODE_MASK;
9de2e2e8
GR
745
746 const s8 *ALARM_BITS;
30846993 747 const s8 *BEEP_BITS;
9de2e2e8
GR
748
749 const u16 *REG_VIN;
750 const u16 *REG_IN_MINMAX[2];
751
cdcaeceb 752 const u16 *REG_TARGET;
1c65dc36 753 const u16 *REG_FAN;
77eb5b37 754 const u16 *REG_FAN_MODE;
1c65dc36 755 const u16 *REG_FAN_MIN;
5c25d954 756 const u16 *REG_FAN_PULSES;
6c009501 757 const u16 *FAN_PULSE_SHIFT;
cdcaeceb
GR
758 const u16 *REG_FAN_TIME[3];
759
760 const u16 *REG_TOLERANCE_H;
aa136e5d 761
77eb5b37
GR
762 const u8 *REG_PWM_MODE;
763 const u8 *PWM_MODE_MASK;
764
bbd8decd
GR
765 const u16 *REG_PWM[7]; /* [0]=pwm, [1]=pwm_start, [2]=pwm_floor,
766 * [3]=pwm_max, [4]=pwm_step,
767 * [5]=weight_duty_step, [6]=weight_duty_base
cdcaeceb 768 */
77eb5b37
GR
769 const u16 *REG_PWM_READ;
770
6c009501
GR
771 const u16 *REG_CRITICAL_PWM_ENABLE;
772 u8 CRITICAL_PWM_ENABLE_MASK;
773 const u16 *REG_CRITICAL_PWM;
774
cdcaeceb
GR
775 const u16 *REG_AUTO_TEMP;
776 const u16 *REG_AUTO_PWM;
777
778 const u16 *REG_CRITICAL_TEMP;
779 const u16 *REG_CRITICAL_TEMP_TOLERANCE;
780
1c65dc36 781 const u16 *REG_TEMP_SOURCE; /* temp register sources */
cdcaeceb 782 const u16 *REG_TEMP_SEL;
bbd8decd
GR
783 const u16 *REG_WEIGHT_TEMP_SEL;
784 const u16 *REG_WEIGHT_TEMP[3]; /* 0=base, 1=tolerance, 2=step */
785
aa136e5d
GR
786 const u16 *REG_TEMP_OFFSET;
787
9de2e2e8 788 const u16 *REG_ALARM;
30846993 789 const u16 *REG_BEEP;
9de2e2e8 790
1c65dc36
GR
791 unsigned int (*fan_from_reg)(u16 reg, unsigned int divreg);
792 unsigned int (*fan_from_reg_min)(u16 reg, unsigned int divreg);
793
9de2e2e8
GR
794 struct mutex update_lock;
795 bool valid; /* true if following fields are valid */
796 unsigned long last_updated; /* In jiffies */
797
798 /* Register values */
799 u8 bank; /* current register bank */
800 u8 in_num; /* number of in inputs we have */
801 u8 in[15][3]; /* [0]=in, [1]=in_max, [2]=in_min */
578ab5f0
DB
802 unsigned int rpm[NUM_FAN];
803 u16 fan_min[NUM_FAN];
804 u8 fan_pulses[NUM_FAN];
805 u8 fan_div[NUM_FAN];
77eb5b37 806 u8 has_pwm;
1c65dc36
GR
807 u8 has_fan; /* some fan inputs can be disabled */
808 u8 has_fan_min; /* some fans don't have min register */
809 bool has_fan_div;
9de2e2e8 810
6c009501 811 u8 num_temp_alarms; /* 2, 3, or 6 */
30846993 812 u8 num_temp_beeps; /* 2, 3, or 6 */
aa136e5d
GR
813 u8 temp_fixed_num; /* 3 or 6 */
814 u8 temp_type[NUM_TEMP_FIXED];
815 s8 temp_offset[NUM_TEMP_FIXED];
f58876ac
DC
816 s16 temp[5][NUM_TEMP]; /* 0=temp, 1=temp_over, 2=temp_hyst,
817 * 3=temp_crit, 4=temp_lcrit */
9de2e2e8 818 u64 alarms;
30846993 819 u64 beeps;
9de2e2e8 820
77eb5b37 821 u8 pwm_num; /* number of pwm */
578ab5f0
DB
822 u8 pwm_mode[NUM_FAN]; /* 1->DC variable voltage,
823 * 0->PWM variable duty cycle
824 */
825 enum pwm_enable pwm_enable[NUM_FAN];
77eb5b37
GR
826 /* 0->off
827 * 1->manual
828 * 2->thermal cruise mode (also called SmartFan I)
829 * 3->fan speed cruise mode
830 * 4->SmartFan III
831 * 5->enhanced variable thermal cruise (SmartFan IV)
832 */
578ab5f0
DB
833 u8 pwm[7][NUM_FAN]; /* [0]=pwm, [1]=pwm_start, [2]=pwm_floor,
834 * [3]=pwm_max, [4]=pwm_step,
835 * [5]=weight_duty_step, [6]=weight_duty_base
836 */
cdcaeceb 837
578ab5f0 838 u8 target_temp[NUM_FAN];
cdcaeceb 839 u8 target_temp_mask;
578ab5f0
DB
840 u32 target_speed[NUM_FAN];
841 u32 target_speed_tolerance[NUM_FAN];
cdcaeceb
GR
842 u8 speed_tolerance_limit;
843
578ab5f0 844 u8 temp_tolerance[2][NUM_FAN];
cdcaeceb
GR
845 u8 tolerance_mask;
846
578ab5f0 847 u8 fan_time[3][NUM_FAN]; /* 0 = stop_time, 1 = step_up, 2 = step_down */
cdcaeceb
GR
848
849 /* Automatic fan speed control registers */
850 int auto_pwm_num;
578ab5f0
DB
851 u8 auto_pwm[NUM_FAN][7];
852 u8 auto_temp[NUM_FAN][7];
853 u8 pwm_temp_sel[NUM_FAN];
854 u8 pwm_weight_temp_sel[NUM_FAN];
855 u8 weight_temp[3][NUM_FAN]; /* 0->temp_step, 1->temp_step_tol,
856 * 2->temp_base
857 */
77eb5b37 858
9de2e2e8
GR
859 u8 vid;
860 u8 vrm;
861
f73cf632
GR
862 bool have_vid;
863
aa136e5d
GR
864 u16 have_temp;
865 u16 have_temp_fixed;
9de2e2e8 866 u16 have_in;
84d19d92
GR
867#ifdef CONFIG_PM
868 /* Remember extra register values over suspend/resume */
869 u8 vbat;
870 u8 fandiv1;
871 u8 fandiv2;
872#endif
9de2e2e8
GR
873};
874
875struct nct6775_sio_data {
876 int sioreg;
877 enum kinds kind;
878};
879
f73cf632
GR
880struct sensor_device_template {
881 struct device_attribute dev_attr;
882 union {
883 struct {
884 u8 nr;
885 u8 index;
886 } s;
887 int index;
888 } u;
889 bool s2; /* true if both index and nr are used */
890};
891
892struct sensor_device_attr_u {
893 union {
894 struct sensor_device_attribute a1;
895 struct sensor_device_attribute_2 a2;
896 } u;
897 char name[32];
898};
899
900#define __TEMPLATE_ATTR(_template, _mode, _show, _store) { \
901 .attr = {.name = _template, .mode = _mode }, \
902 .show = _show, \
903 .store = _store, \
904}
905
906#define SENSOR_DEVICE_TEMPLATE(_template, _mode, _show, _store, _index) \
907 { .dev_attr = __TEMPLATE_ATTR(_template, _mode, _show, _store), \
908 .u.index = _index, \
909 .s2 = false }
910
911#define SENSOR_DEVICE_TEMPLATE_2(_template, _mode, _show, _store, \
912 _nr, _index) \
913 { .dev_attr = __TEMPLATE_ATTR(_template, _mode, _show, _store), \
914 .u.s.index = _index, \
915 .u.s.nr = _nr, \
916 .s2 = true }
917
918#define SENSOR_TEMPLATE(_name, _template, _mode, _show, _store, _index) \
919static struct sensor_device_template sensor_dev_template_##_name \
920 = SENSOR_DEVICE_TEMPLATE(_template, _mode, _show, _store, \
921 _index)
922
923#define SENSOR_TEMPLATE_2(_name, _template, _mode, _show, _store, \
924 _nr, _index) \
925static struct sensor_device_template sensor_dev_template_##_name \
926 = SENSOR_DEVICE_TEMPLATE_2(_template, _mode, _show, _store, \
927 _nr, _index)
928
929struct sensor_template_group {
930 struct sensor_device_template **templates;
931 umode_t (*is_visible)(struct kobject *, struct attribute *, int);
932 int base;
933};
934
935static struct attribute_group *
936nct6775_create_attr_group(struct device *dev, struct sensor_template_group *tg,
937 int repeat)
938{
939 struct attribute_group *group;
940 struct sensor_device_attr_u *su;
941 struct sensor_device_attribute *a;
942 struct sensor_device_attribute_2 *a2;
943 struct attribute **attrs;
944 struct sensor_device_template **t;
945 int err, i, j, count;
946
947 if (repeat <= 0)
948 return ERR_PTR(-EINVAL);
949
950 t = tg->templates;
951 for (count = 0; *t; t++, count++)
952 ;
953
954 if (count == 0)
955 return ERR_PTR(-EINVAL);
956
957 group = devm_kzalloc(dev, sizeof(*group), GFP_KERNEL);
958 if (group == NULL)
959 return ERR_PTR(-ENOMEM);
960
961 attrs = devm_kzalloc(dev, sizeof(*attrs) * (repeat * count + 1),
962 GFP_KERNEL);
963 if (attrs == NULL)
964 return ERR_PTR(-ENOMEM);
965
966 su = devm_kzalloc(dev, sizeof(*su) * repeat * count,
967 GFP_KERNEL);
968 if (su == NULL)
969 return ERR_PTR(-ENOMEM);
970
971 group->attrs = attrs;
972 group->is_visible = tg->is_visible;
973
974 for (i = 0; i < repeat; i++) {
975 t = tg->templates;
976 for (j = 0; *t != NULL; j++) {
977 snprintf(su->name, sizeof(su->name),
978 (*t)->dev_attr.attr.name, tg->base + i);
979 if ((*t)->s2) {
980 a2 = &su->u.a2;
981 a2->dev_attr.attr.name = su->name;
982 a2->nr = (*t)->u.s.nr + i;
983 a2->index = (*t)->u.s.index;
984 a2->dev_attr.attr.mode =
985 (*t)->dev_attr.attr.mode;
986 a2->dev_attr.show = (*t)->dev_attr.show;
987 a2->dev_attr.store = (*t)->dev_attr.store;
988 *attrs = &a2->dev_attr.attr;
989 } else {
990 a = &su->u.a1;
991 a->dev_attr.attr.name = su->name;
992 a->index = (*t)->u.index + i;
993 a->dev_attr.attr.mode =
994 (*t)->dev_attr.attr.mode;
995 a->dev_attr.show = (*t)->dev_attr.show;
996 a->dev_attr.store = (*t)->dev_attr.store;
997 *attrs = &a->dev_attr.attr;
998 }
999 attrs++;
1000 su++;
1001 t++;
1002 }
1003 }
1004
1005 err = sysfs_create_group(&dev->kobj, group);
1006 if (err)
1007 return ERR_PTR(-ENOMEM);
1008
1009 return group;
1010}
1011
9de2e2e8
GR
1012static bool is_word_sized(struct nct6775_data *data, u16 reg)
1013{
1014 switch (data->kind) {
6c009501
GR
1015 case nct6106:
1016 return reg == 0x20 || reg == 0x22 || reg == 0x24 ||
1017 reg == 0xe0 || reg == 0xe2 || reg == 0xe4 ||
1018 reg == 0x111 || reg == 0x121 || reg == 0x131;
9de2e2e8
GR
1019 case nct6775:
1020 return (((reg & 0xff00) == 0x100 ||
1021 (reg & 0xff00) == 0x200) &&
1022 ((reg & 0x00ff) == 0x50 ||
1023 (reg & 0x00ff) == 0x53 ||
1024 (reg & 0x00ff) == 0x55)) ||
1025 (reg & 0xfff0) == 0x630 ||
1026 reg == 0x640 || reg == 0x642 ||
1027 reg == 0x662 ||
1028 ((reg & 0xfff0) == 0x650 && (reg & 0x000f) >= 0x06) ||
1029 reg == 0x73 || reg == 0x75 || reg == 0x77;
1030 case nct6776:
1031 return (((reg & 0xff00) == 0x100 ||
1032 (reg & 0xff00) == 0x200) &&
1033 ((reg & 0x00ff) == 0x50 ||
1034 (reg & 0x00ff) == 0x53 ||
1035 (reg & 0x00ff) == 0x55)) ||
1036 (reg & 0xfff0) == 0x630 ||
1037 reg == 0x402 ||
1038 reg == 0x640 || reg == 0x642 ||
1039 ((reg & 0xfff0) == 0x650 && (reg & 0x000f) >= 0x06) ||
1040 reg == 0x73 || reg == 0x75 || reg == 0x77;
1041 case nct6779:
578ab5f0 1042 case nct6791:
9de2e2e8 1043 return reg == 0x150 || reg == 0x153 || reg == 0x155 ||
578ab5f0 1044 ((reg & 0xfff0) == 0x4b0 && (reg & 0x000f) < 0x0b) ||
9de2e2e8
GR
1045 reg == 0x402 ||
1046 reg == 0x63a || reg == 0x63c || reg == 0x63e ||
1047 reg == 0x640 || reg == 0x642 ||
1048 reg == 0x73 || reg == 0x75 || reg == 0x77 || reg == 0x79 ||
1049 reg == 0x7b;
1050 }
1051 return false;
1052}
1053
1054/*
1055 * On older chips, only registers 0x50-0x5f are banked.
1056 * On more recent chips, all registers are banked.
1057 * Assume that is the case and set the bank number for each access.
1058 * Cache the bank number so it only needs to be set if it changes.
1059 */
1060static inline void nct6775_set_bank(struct nct6775_data *data, u16 reg)
1061{
1062 u8 bank = reg >> 8;
1063 if (data->bank != bank) {
1064 outb_p(NCT6775_REG_BANK, data->addr + ADDR_REG_OFFSET);
1065 outb_p(bank, data->addr + DATA_REG_OFFSET);
1066 data->bank = bank;
1067 }
1068}
1069
1070static u16 nct6775_read_value(struct nct6775_data *data, u16 reg)
1071{
1072 int res, word_sized = is_word_sized(data, reg);
1073
9de2e2e8
GR
1074 nct6775_set_bank(data, reg);
1075 outb_p(reg & 0xff, data->addr + ADDR_REG_OFFSET);
1076 res = inb_p(data->addr + DATA_REG_OFFSET);
1077 if (word_sized) {
1078 outb_p((reg & 0xff) + 1,
1079 data->addr + ADDR_REG_OFFSET);
1080 res = (res << 8) + inb_p(data->addr + DATA_REG_OFFSET);
1081 }
9de2e2e8
GR
1082 return res;
1083}
1084
1085static int nct6775_write_value(struct nct6775_data *data, u16 reg, u16 value)
1086{
1087 int word_sized = is_word_sized(data, reg);
1088
9de2e2e8
GR
1089 nct6775_set_bank(data, reg);
1090 outb_p(reg & 0xff, data->addr + ADDR_REG_OFFSET);
1091 if (word_sized) {
1092 outb_p(value >> 8, data->addr + DATA_REG_OFFSET);
1093 outb_p((reg & 0xff) + 1,
1094 data->addr + ADDR_REG_OFFSET);
1095 }
1096 outb_p(value & 0xff, data->addr + DATA_REG_OFFSET);
9de2e2e8
GR
1097 return 0;
1098}
1099
aa136e5d
GR
1100/* We left-align 8-bit temperature values to make the code simpler */
1101static u16 nct6775_read_temp(struct nct6775_data *data, u16 reg)
1102{
1103 u16 res;
1104
1105 res = nct6775_read_value(data, reg);
1106 if (!is_word_sized(data, reg))
1107 res <<= 8;
1108
1109 return res;
1110}
1111
1112static int nct6775_write_temp(struct nct6775_data *data, u16 reg, u16 value)
1113{
1114 if (!is_word_sized(data, reg))
1115 value >>= 8;
1116 return nct6775_write_value(data, reg, value);
1117}
1118
1c65dc36
GR
1119/* This function assumes that the caller holds data->update_lock */
1120static void nct6775_write_fan_div(struct nct6775_data *data, int nr)
1121{
1122 u8 reg;
1123
1124 switch (nr) {
1125 case 0:
1126 reg = (nct6775_read_value(data, NCT6775_REG_FANDIV1) & 0x70)
1127 | (data->fan_div[0] & 0x7);
1128 nct6775_write_value(data, NCT6775_REG_FANDIV1, reg);
1129 break;
1130 case 1:
1131 reg = (nct6775_read_value(data, NCT6775_REG_FANDIV1) & 0x7)
1132 | ((data->fan_div[1] << 4) & 0x70);
1133 nct6775_write_value(data, NCT6775_REG_FANDIV1, reg);
1134 break;
1135 case 2:
1136 reg = (nct6775_read_value(data, NCT6775_REG_FANDIV2) & 0x70)
1137 | (data->fan_div[2] & 0x7);
1138 nct6775_write_value(data, NCT6775_REG_FANDIV2, reg);
1139 break;
1140 case 3:
1141 reg = (nct6775_read_value(data, NCT6775_REG_FANDIV2) & 0x7)
1142 | ((data->fan_div[3] << 4) & 0x70);
1143 nct6775_write_value(data, NCT6775_REG_FANDIV2, reg);
1144 break;
1145 }
1146}
1147
1148static void nct6775_write_fan_div_common(struct nct6775_data *data, int nr)
1149{
1150 if (data->kind == nct6775)
1151 nct6775_write_fan_div(data, nr);
1152}
1153
1154static void nct6775_update_fan_div(struct nct6775_data *data)
1155{
1156 u8 i;
1157
1158 i = nct6775_read_value(data, NCT6775_REG_FANDIV1);
1159 data->fan_div[0] = i & 0x7;
1160 data->fan_div[1] = (i & 0x70) >> 4;
1161 i = nct6775_read_value(data, NCT6775_REG_FANDIV2);
1162 data->fan_div[2] = i & 0x7;
6445e660 1163 if (data->has_fan & (1 << 3))
1c65dc36
GR
1164 data->fan_div[3] = (i & 0x70) >> 4;
1165}
1166
1167static void nct6775_update_fan_div_common(struct nct6775_data *data)
1168{
1169 if (data->kind == nct6775)
1170 nct6775_update_fan_div(data);
1171}
1172
1173static void nct6775_init_fan_div(struct nct6775_data *data)
1174{
1175 int i;
1176
1177 nct6775_update_fan_div_common(data);
1178 /*
1179 * For all fans, start with highest divider value if the divider
1180 * register is not initialized. This ensures that we get a
1181 * reading from the fan count register, even if it is not optimal.
1182 * We'll compute a better divider later on.
1183 */
c409fd43 1184 for (i = 0; i < ARRAY_SIZE(data->fan_div); i++) {
1c65dc36
GR
1185 if (!(data->has_fan & (1 << i)))
1186 continue;
1187 if (data->fan_div[i] == 0) {
1188 data->fan_div[i] = 7;
1189 nct6775_write_fan_div_common(data, i);
1190 }
1191 }
1192}
1193
1194static void nct6775_init_fan_common(struct device *dev,
1195 struct nct6775_data *data)
1196{
1197 int i;
1198 u8 reg;
1199
1200 if (data->has_fan_div)
1201 nct6775_init_fan_div(data);
1202
1203 /*
1204 * If fan_min is not set (0), set it to 0xff to disable it. This
1205 * prevents the unnecessary warning when fanX_min is reported as 0.
1206 */
c409fd43 1207 for (i = 0; i < ARRAY_SIZE(data->fan_min); i++) {
1c65dc36
GR
1208 if (data->has_fan_min & (1 << i)) {
1209 reg = nct6775_read_value(data, data->REG_FAN_MIN[i]);
1210 if (!reg)
1211 nct6775_write_value(data, data->REG_FAN_MIN[i],
1212 data->has_fan_div ? 0xff
1213 : 0xff1f);
1214 }
1215 }
1216}
1217
1218static void nct6775_select_fan_div(struct device *dev,
1219 struct nct6775_data *data, int nr, u16 reg)
1220{
1221 u8 fan_div = data->fan_div[nr];
1222 u16 fan_min;
1223
1224 if (!data->has_fan_div)
1225 return;
1226
1227 /*
1228 * If we failed to measure the fan speed, or the reported value is not
1229 * in the optimal range, and the clock divider can be modified,
1230 * let's try that for next time.
1231 */
1232 if (reg == 0x00 && fan_div < 0x07)
1233 fan_div++;
1234 else if (reg != 0x00 && reg < 0x30 && fan_div > 0)
1235 fan_div--;
1236
1237 if (fan_div != data->fan_div[nr]) {
1238 dev_dbg(dev, "Modifying fan%d clock divider from %u to %u\n",
1239 nr + 1, div_from_reg(data->fan_div[nr]),
1240 div_from_reg(fan_div));
1241
1242 /* Preserve min limit if possible */
1243 if (data->has_fan_min & (1 << nr)) {
1244 fan_min = data->fan_min[nr];
1245 if (fan_div > data->fan_div[nr]) {
1246 if (fan_min != 255 && fan_min > 1)
1247 fan_min >>= 1;
1248 } else {
1249 if (fan_min != 255) {
1250 fan_min <<= 1;
1251 if (fan_min > 254)
1252 fan_min = 254;
1253 }
1254 }
1255 if (fan_min != data->fan_min[nr]) {
1256 data->fan_min[nr] = fan_min;
1257 nct6775_write_value(data, data->REG_FAN_MIN[nr],
1258 fan_min);
1259 }
1260 }
1261 data->fan_div[nr] = fan_div;
1262 nct6775_write_fan_div_common(data, nr);
1263 }
1264}
1265
77eb5b37
GR
1266static void nct6775_update_pwm(struct device *dev)
1267{
1268 struct nct6775_data *data = dev_get_drvdata(dev);
1269 int i, j;
cdcaeceb 1270 int fanmodecfg, reg;
77eb5b37
GR
1271 bool duty_is_dc;
1272
1273 for (i = 0; i < data->pwm_num; i++) {
1274 if (!(data->has_pwm & (1 << i)))
1275 continue;
1276
1277 duty_is_dc = data->REG_PWM_MODE[i] &&
1278 (nct6775_read_value(data, data->REG_PWM_MODE[i])
1279 & data->PWM_MODE_MASK[i]);
1280 data->pwm_mode[i] = duty_is_dc;
1281
1282 fanmodecfg = nct6775_read_value(data, data->REG_FAN_MODE[i]);
1283 for (j = 0; j < ARRAY_SIZE(data->REG_PWM); j++) {
1284 if (data->REG_PWM[j] && data->REG_PWM[j][i]) {
1285 data->pwm[j][i]
1286 = nct6775_read_value(data,
1287 data->REG_PWM[j][i]);
1288 }
1289 }
1290
1291 data->pwm_enable[i] = reg_to_pwm_enable(data->pwm[0][i],
1292 (fanmodecfg >> 4) & 7);
cdcaeceb
GR
1293
1294 if (!data->temp_tolerance[0][i] ||
1295 data->pwm_enable[i] != speed_cruise)
1296 data->temp_tolerance[0][i] = fanmodecfg & 0x0f;
1297 if (!data->target_speed_tolerance[i] ||
1298 data->pwm_enable[i] == speed_cruise) {
1299 u8 t = fanmodecfg & 0x0f;
1300 if (data->REG_TOLERANCE_H) {
1301 t |= (nct6775_read_value(data,
1302 data->REG_TOLERANCE_H[i]) & 0x70) >> 1;
1303 }
1304 data->target_speed_tolerance[i] = t;
1305 }
1306
1307 data->temp_tolerance[1][i] =
1308 nct6775_read_value(data,
1309 data->REG_CRITICAL_TEMP_TOLERANCE[i]);
1310
1311 reg = nct6775_read_value(data, data->REG_TEMP_SEL[i]);
1312 data->pwm_temp_sel[i] = reg & 0x1f;
1313 /* If fan can stop, report floor as 0 */
1314 if (reg & 0x80)
1315 data->pwm[2][i] = 0;
bbd8decd
GR
1316
1317 reg = nct6775_read_value(data, data->REG_WEIGHT_TEMP_SEL[i]);
1318 data->pwm_weight_temp_sel[i] = reg & 0x1f;
1319 /* If weight is disabled, report weight source as 0 */
1320 if (j == 1 && !(reg & 0x80))
1321 data->pwm_weight_temp_sel[i] = 0;
1322
1323 /* Weight temp data */
c409fd43 1324 for (j = 0; j < ARRAY_SIZE(data->weight_temp); j++) {
bbd8decd
GR
1325 data->weight_temp[j][i]
1326 = nct6775_read_value(data,
1327 data->REG_WEIGHT_TEMP[j][i]);
1328 }
cdcaeceb
GR
1329 }
1330}
1331
1332static void nct6775_update_pwm_limits(struct device *dev)
1333{
1334 struct nct6775_data *data = dev_get_drvdata(dev);
1335 int i, j;
1336 u8 reg;
1337 u16 reg_t;
1338
1339 for (i = 0; i < data->pwm_num; i++) {
1340 if (!(data->has_pwm & (1 << i)))
1341 continue;
1342
c409fd43 1343 for (j = 0; j < ARRAY_SIZE(data->fan_time); j++) {
cdcaeceb
GR
1344 data->fan_time[j][i] =
1345 nct6775_read_value(data, data->REG_FAN_TIME[j][i]);
1346 }
1347
1348 reg_t = nct6775_read_value(data, data->REG_TARGET[i]);
1349 /* Update only in matching mode or if never updated */
1350 if (!data->target_temp[i] ||
1351 data->pwm_enable[i] == thermal_cruise)
1352 data->target_temp[i] = reg_t & data->target_temp_mask;
1353 if (!data->target_speed[i] ||
1354 data->pwm_enable[i] == speed_cruise) {
1355 if (data->REG_TOLERANCE_H) {
1356 reg_t |= (nct6775_read_value(data,
1357 data->REG_TOLERANCE_H[i]) & 0x0f) << 8;
1358 }
1359 data->target_speed[i] = reg_t;
1360 }
1361
1362 for (j = 0; j < data->auto_pwm_num; j++) {
1363 data->auto_pwm[i][j] =
1364 nct6775_read_value(data,
1365 NCT6775_AUTO_PWM(data, i, j));
1366 data->auto_temp[i][j] =
1367 nct6775_read_value(data,
1368 NCT6775_AUTO_TEMP(data, i, j));
1369 }
1370
1371 /* critical auto_pwm temperature data */
1372 data->auto_temp[i][data->auto_pwm_num] =
1373 nct6775_read_value(data, data->REG_CRITICAL_TEMP[i]);
1374
1375 switch (data->kind) {
1376 case nct6775:
1377 reg = nct6775_read_value(data,
1378 NCT6775_REG_CRITICAL_ENAB[i]);
1379 data->auto_pwm[i][data->auto_pwm_num] =
1380 (reg & 0x02) ? 0xff : 0x00;
1381 break;
1382 case nct6776:
1383 data->auto_pwm[i][data->auto_pwm_num] = 0xff;
1384 break;
6c009501 1385 case nct6106:
cdcaeceb 1386 case nct6779:
578ab5f0 1387 case nct6791:
cdcaeceb 1388 reg = nct6775_read_value(data,
6c009501
GR
1389 data->REG_CRITICAL_PWM_ENABLE[i]);
1390 if (reg & data->CRITICAL_PWM_ENABLE_MASK)
1391 reg = nct6775_read_value(data,
1392 data->REG_CRITICAL_PWM[i]);
cdcaeceb 1393 else
6c009501
GR
1394 reg = 0xff;
1395 data->auto_pwm[i][data->auto_pwm_num] = reg;
cdcaeceb
GR
1396 break;
1397 }
77eb5b37
GR
1398 }
1399}
1400
9de2e2e8
GR
1401static struct nct6775_data *nct6775_update_device(struct device *dev)
1402{
1403 struct nct6775_data *data = dev_get_drvdata(dev);
aa136e5d 1404 int i, j;
9de2e2e8
GR
1405
1406 mutex_lock(&data->update_lock);
1407
6445e660 1408 if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
9de2e2e8 1409 || !data->valid) {
1c65dc36
GR
1410 /* Fan clock dividers */
1411 nct6775_update_fan_div_common(data);
1412
9de2e2e8
GR
1413 /* Measured voltages and limits */
1414 for (i = 0; i < data->in_num; i++) {
1415 if (!(data->have_in & (1 << i)))
1416 continue;
1417
1418 data->in[i][0] = nct6775_read_value(data,
1419 data->REG_VIN[i]);
1420 data->in[i][1] = nct6775_read_value(data,
1421 data->REG_IN_MINMAX[0][i]);
1422 data->in[i][2] = nct6775_read_value(data,
1423 data->REG_IN_MINMAX[1][i]);
1424 }
1425
1c65dc36 1426 /* Measured fan speeds and limits */
c409fd43 1427 for (i = 0; i < ARRAY_SIZE(data->rpm); i++) {
1c65dc36
GR
1428 u16 reg;
1429
1430 if (!(data->has_fan & (1 << i)))
1431 continue;
1432
1433 reg = nct6775_read_value(data, data->REG_FAN[i]);
1434 data->rpm[i] = data->fan_from_reg(reg,
1435 data->fan_div[i]);
1436
1437 if (data->has_fan_min & (1 << i))
1438 data->fan_min[i] = nct6775_read_value(data,
1439 data->REG_FAN_MIN[i]);
5c25d954 1440 data->fan_pulses[i] =
6c009501
GR
1441 (nct6775_read_value(data, data->REG_FAN_PULSES[i])
1442 >> data->FAN_PULSE_SHIFT[i]) & 0x03;
1c65dc36
GR
1443
1444 nct6775_select_fan_div(dev, data, i, reg);
1445 }
1446
77eb5b37 1447 nct6775_update_pwm(dev);
cdcaeceb 1448 nct6775_update_pwm_limits(dev);
77eb5b37 1449
aa136e5d
GR
1450 /* Measured temperatures and limits */
1451 for (i = 0; i < NUM_TEMP; i++) {
1452 if (!(data->have_temp & (1 << i)))
1453 continue;
c409fd43 1454 for (j = 0; j < ARRAY_SIZE(data->reg_temp); j++) {
aa136e5d
GR
1455 if (data->reg_temp[j][i])
1456 data->temp[j][i]
1457 = nct6775_read_temp(data,
1458 data->reg_temp[j][i]);
1459 }
1460 if (!(data->have_temp_fixed & (1 << i)))
1461 continue;
1462 data->temp_offset[i]
1463 = nct6775_read_value(data, data->REG_TEMP_OFFSET[i]);
1464 }
1465
9de2e2e8
GR
1466 data->alarms = 0;
1467 for (i = 0; i < NUM_REG_ALARM; i++) {
1468 u8 alarm;
1469 if (!data->REG_ALARM[i])
1470 continue;
1471 alarm = nct6775_read_value(data, data->REG_ALARM[i]);
1472 data->alarms |= ((u64)alarm) << (i << 3);
1473 }
1474
30846993
GR
1475 data->beeps = 0;
1476 for (i = 0; i < NUM_REG_BEEP; i++) {
1477 u8 beep;
1478 if (!data->REG_BEEP[i])
1479 continue;
1480 beep = nct6775_read_value(data, data->REG_BEEP[i]);
1481 data->beeps |= ((u64)beep) << (i << 3);
1482 }
1483
9de2e2e8
GR
1484 data->last_updated = jiffies;
1485 data->valid = true;
1486 }
1487
1488 mutex_unlock(&data->update_lock);
1489 return data;
1490}
1491
1492/*
1493 * Sysfs callback functions
1494 */
1495static ssize_t
1496show_in_reg(struct device *dev, struct device_attribute *attr, char *buf)
1497{
1498 struct nct6775_data *data = nct6775_update_device(dev);
1499 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
1500 int nr = sattr->nr;
1501 int index = sattr->index;
1502 return sprintf(buf, "%ld\n", in_from_reg(data->in[nr][index], nr));
1503}
1504
1505static ssize_t
1506store_in_reg(struct device *dev, struct device_attribute *attr, const char *buf,
1507 size_t count)
1508{
1509 struct nct6775_data *data = dev_get_drvdata(dev);
1510 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
1511 int nr = sattr->nr;
1512 int index = sattr->index;
1513 unsigned long val;
1514 int err = kstrtoul(buf, 10, &val);
1515 if (err < 0)
1516 return err;
1517 mutex_lock(&data->update_lock);
1518 data->in[nr][index] = in_to_reg(val, nr);
6445e660 1519 nct6775_write_value(data, data->REG_IN_MINMAX[index - 1][nr],
9de2e2e8
GR
1520 data->in[nr][index]);
1521 mutex_unlock(&data->update_lock);
1522 return count;
1523}
1524
1525static ssize_t
1526show_alarm(struct device *dev, struct device_attribute *attr, char *buf)
1527{
1528 struct nct6775_data *data = nct6775_update_device(dev);
1529 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1530 int nr = data->ALARM_BITS[sattr->index];
1531 return sprintf(buf, "%u\n",
1532 (unsigned int)((data->alarms >> nr) & 0x01));
1533}
1534
b1d2bff6
GR
1535static int find_temp_source(struct nct6775_data *data, int index, int count)
1536{
1537 int source = data->temp_src[index];
1538 int nr;
1539
1540 for (nr = 0; nr < count; nr++) {
1541 int src;
1542
1543 src = nct6775_read_value(data,
1544 data->REG_TEMP_SOURCE[nr]) & 0x1f;
1545 if (src == source)
1546 return nr;
1547 }
1548 return -1;
1549}
1550
1551static ssize_t
1552show_temp_alarm(struct device *dev, struct device_attribute *attr, char *buf)
1553{
1554 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1555 struct nct6775_data *data = nct6775_update_device(dev);
1556 unsigned int alarm = 0;
1557 int nr;
1558
1559 /*
1560 * For temperatures, there is no fixed mapping from registers to alarm
1561 * bits. Alarm bits are determined by the temperature source mapping.
1562 */
1563 nr = find_temp_source(data, sattr->index, data->num_temp_alarms);
1564 if (nr >= 0) {
1565 int bit = data->ALARM_BITS[nr + TEMP_ALARM_BASE];
1566 alarm = (data->alarms >> bit) & 0x01;
1567 }
1568 return sprintf(buf, "%u\n", alarm);
1569}
1570
30846993
GR
1571static ssize_t
1572show_beep(struct device *dev, struct device_attribute *attr, char *buf)
1573{
1574 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1575 struct nct6775_data *data = nct6775_update_device(dev);
1576 int nr = data->BEEP_BITS[sattr->index];
1577
1578 return sprintf(buf, "%u\n",
1579 (unsigned int)((data->beeps >> nr) & 0x01));
1580}
1581
1582static ssize_t
1583store_beep(struct device *dev, struct device_attribute *attr, const char *buf,
1584 size_t count)
1585{
1586 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
1587 struct nct6775_data *data = dev_get_drvdata(dev);
1588 int nr = data->BEEP_BITS[sattr->index];
1589 int regindex = nr >> 3;
1590 unsigned long val;
1591
1592 int err = kstrtoul(buf, 10, &val);
1593 if (err < 0)
1594 return err;
1595 if (val > 1)
1596 return -EINVAL;
1597
1598 mutex_lock(&data->update_lock);
1599 if (val)
1600 data->beeps |= (1ULL << nr);
1601 else
1602 data->beeps &= ~(1ULL << nr);
1603 nct6775_write_value(data, data->REG_BEEP[regindex],
1604 (data->beeps >> (regindex << 3)) & 0xff);
1605 mutex_unlock(&data->update_lock);
1606 return count;
1607}
1608
1609static ssize_t
1610show_temp_beep(struct device *dev, struct device_attribute *attr, char *buf)
1611{
1612 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1613 struct nct6775_data *data = nct6775_update_device(dev);
1614 unsigned int beep = 0;
1615 int nr;
1616
1617 /*
1618 * For temperatures, there is no fixed mapping from registers to beep
1619 * enable bits. Beep enable bits are determined by the temperature
1620 * source mapping.
1621 */
1622 nr = find_temp_source(data, sattr->index, data->num_temp_beeps);
1623 if (nr >= 0) {
1624 int bit = data->BEEP_BITS[nr + TEMP_ALARM_BASE];
1625 beep = (data->beeps >> bit) & 0x01;
1626 }
1627 return sprintf(buf, "%u\n", beep);
1628}
1629
1630static ssize_t
1631store_temp_beep(struct device *dev, struct device_attribute *attr,
1632 const char *buf, size_t count)
1633{
1634 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
1635 struct nct6775_data *data = dev_get_drvdata(dev);
1636 int nr, bit, regindex;
1637 unsigned long val;
1638
1639 int err = kstrtoul(buf, 10, &val);
1640 if (err < 0)
1641 return err;
1642 if (val > 1)
1643 return -EINVAL;
1644
1645 nr = find_temp_source(data, sattr->index, data->num_temp_beeps);
1646 if (nr < 0)
1647 return -ENODEV;
1648
1649 bit = data->BEEP_BITS[nr + TEMP_ALARM_BASE];
1650 regindex = bit >> 3;
1651
1652 mutex_lock(&data->update_lock);
1653 if (val)
1654 data->beeps |= (1ULL << bit);
1655 else
1656 data->beeps &= ~(1ULL << bit);
1657 nct6775_write_value(data, data->REG_BEEP[regindex],
1658 (data->beeps >> (regindex << 3)) & 0xff);
1659 mutex_unlock(&data->update_lock);
1660
1661 return count;
1662}
1663
f73cf632
GR
1664static umode_t nct6775_in_is_visible(struct kobject *kobj,
1665 struct attribute *attr, int index)
1666{
1667 struct device *dev = container_of(kobj, struct device, kobj);
1668 struct nct6775_data *data = dev_get_drvdata(dev);
30846993 1669 int in = index / 5; /* voltage index */
f73cf632
GR
1670
1671 if (!(data->have_in & (1 << in)))
1672 return 0;
1673
1674 return attr->mode;
1675}
1676
1677SENSOR_TEMPLATE_2(in_input, "in%d_input", S_IRUGO, show_in_reg, NULL, 0, 0);
1678SENSOR_TEMPLATE(in_alarm, "in%d_alarm", S_IRUGO, show_alarm, NULL, 0);
30846993
GR
1679SENSOR_TEMPLATE(in_beep, "in%d_beep", S_IWUSR | S_IRUGO, show_beep, store_beep,
1680 0);
f73cf632
GR
1681SENSOR_TEMPLATE_2(in_min, "in%d_min", S_IWUSR | S_IRUGO, show_in_reg,
1682 store_in_reg, 0, 1);
1683SENSOR_TEMPLATE_2(in_max, "in%d_max", S_IWUSR | S_IRUGO, show_in_reg,
1684 store_in_reg, 0, 2);
1685
1686/*
1687 * nct6775_in_is_visible uses the index into the following array
1688 * to determine if attributes should be created or not.
1689 * Any change in order or content must be matched.
1690 */
1691static struct sensor_device_template *nct6775_attributes_in_template[] = {
1692 &sensor_dev_template_in_input,
1693 &sensor_dev_template_in_alarm,
30846993 1694 &sensor_dev_template_in_beep,
f73cf632
GR
1695 &sensor_dev_template_in_min,
1696 &sensor_dev_template_in_max,
1697 NULL
9de2e2e8
GR
1698};
1699
f73cf632
GR
1700static struct sensor_template_group nct6775_in_template_group = {
1701 .templates = nct6775_attributes_in_template,
1702 .is_visible = nct6775_in_is_visible,
9de2e2e8
GR
1703};
1704
1c65dc36
GR
1705static ssize_t
1706show_fan(struct device *dev, struct device_attribute *attr, char *buf)
1707{
1708 struct nct6775_data *data = nct6775_update_device(dev);
1709 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1710 int nr = sattr->index;
1711 return sprintf(buf, "%d\n", data->rpm[nr]);
1712}
1713
1714static ssize_t
1715show_fan_min(struct device *dev, struct device_attribute *attr, char *buf)
1716{
1717 struct nct6775_data *data = nct6775_update_device(dev);
1718 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1719 int nr = sattr->index;
1720 return sprintf(buf, "%d\n",
1721 data->fan_from_reg_min(data->fan_min[nr],
1722 data->fan_div[nr]));
1723}
1724
1725static ssize_t
1726show_fan_div(struct device *dev, struct device_attribute *attr, char *buf)
1727{
1728 struct nct6775_data *data = nct6775_update_device(dev);
1729 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1730 int nr = sattr->index;
1731 return sprintf(buf, "%u\n", div_from_reg(data->fan_div[nr]));
1732}
1733
1734static ssize_t
1735store_fan_min(struct device *dev, struct device_attribute *attr,
1736 const char *buf, size_t count)
1737{
1738 struct nct6775_data *data = dev_get_drvdata(dev);
1739 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1740 int nr = sattr->index;
1741 unsigned long val;
1742 int err;
1743 unsigned int reg;
1744 u8 new_div;
1745
1746 err = kstrtoul(buf, 10, &val);
1747 if (err < 0)
1748 return err;
1749
1750 mutex_lock(&data->update_lock);
1751 if (!data->has_fan_div) {
1752 /* NCT6776F or NCT6779D; we know this is a 13 bit register */
1753 if (!val) {
1754 val = 0xff1f;
1755 } else {
1756 if (val > 1350000U)
1757 val = 135000U;
1758 val = 1350000U / val;
1759 val = (val & 0x1f) | ((val << 3) & 0xff00);
1760 }
1761 data->fan_min[nr] = val;
1762 goto write_min; /* Leave fan divider alone */
1763 }
1764 if (!val) {
1765 /* No min limit, alarm disabled */
1766 data->fan_min[nr] = 255;
1767 new_div = data->fan_div[nr]; /* No change */
1768 dev_info(dev, "fan%u low limit and alarm disabled\n", nr + 1);
1769 goto write_div;
1770 }
1771 reg = 1350000U / val;
1772 if (reg >= 128 * 255) {
1773 /*
1774 * Speed below this value cannot possibly be represented,
1775 * even with the highest divider (128)
1776 */
1777 data->fan_min[nr] = 254;
1778 new_div = 7; /* 128 == (1 << 7) */
1779 dev_warn(dev,
1780 "fan%u low limit %lu below minimum %u, set to minimum\n",
1781 nr + 1, val, data->fan_from_reg_min(254, 7));
1782 } else if (!reg) {
1783 /*
1784 * Speed above this value cannot possibly be represented,
1785 * even with the lowest divider (1)
1786 */
1787 data->fan_min[nr] = 1;
1788 new_div = 0; /* 1 == (1 << 0) */
1789 dev_warn(dev,
1790 "fan%u low limit %lu above maximum %u, set to maximum\n",
1791 nr + 1, val, data->fan_from_reg_min(1, 0));
1792 } else {
1793 /*
1794 * Automatically pick the best divider, i.e. the one such
1795 * that the min limit will correspond to a register value
1796 * in the 96..192 range
1797 */
1798 new_div = 0;
1799 while (reg > 192 && new_div < 7) {
1800 reg >>= 1;
1801 new_div++;
1802 }
1803 data->fan_min[nr] = reg;
1804 }
1805
1806write_div:
1807 /*
1808 * Write both the fan clock divider (if it changed) and the new
1809 * fan min (unconditionally)
1810 */
1811 if (new_div != data->fan_div[nr]) {
1812 dev_dbg(dev, "fan%u clock divider changed from %u to %u\n",
1813 nr + 1, div_from_reg(data->fan_div[nr]),
1814 div_from_reg(new_div));
1815 data->fan_div[nr] = new_div;
1816 nct6775_write_fan_div_common(data, nr);
1817 /* Give the chip time to sample a new speed value */
1818 data->last_updated = jiffies;
1819 }
1820
1821write_min:
1822 nct6775_write_value(data, data->REG_FAN_MIN[nr], data->fan_min[nr]);
1823 mutex_unlock(&data->update_lock);
1824
1825 return count;
1826}
1827
5c25d954
GR
1828static ssize_t
1829show_fan_pulses(struct device *dev, struct device_attribute *attr, char *buf)
1830{
1831 struct nct6775_data *data = nct6775_update_device(dev);
1832 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1833 int p = data->fan_pulses[sattr->index];
1834
1835 return sprintf(buf, "%d\n", p ? : 4);
1836}
1837
1838static ssize_t
1839store_fan_pulses(struct device *dev, struct device_attribute *attr,
1840 const char *buf, size_t count)
1841{
1842 struct nct6775_data *data = dev_get_drvdata(dev);
1843 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1844 int nr = sattr->index;
1845 unsigned long val;
1846 int err;
6c009501 1847 u8 reg;
5c25d954
GR
1848
1849 err = kstrtoul(buf, 10, &val);
1850 if (err < 0)
1851 return err;
1852
1853 if (val > 4)
1854 return -EINVAL;
1855
1856 mutex_lock(&data->update_lock);
1857 data->fan_pulses[nr] = val & 3;
6c009501
GR
1858 reg = nct6775_read_value(data, data->REG_FAN_PULSES[nr]);
1859 reg &= ~(0x03 << data->FAN_PULSE_SHIFT[nr]);
1860 reg |= (val & 3) << data->FAN_PULSE_SHIFT[nr];
1861 nct6775_write_value(data, data->REG_FAN_PULSES[nr], reg);
5c25d954
GR
1862 mutex_unlock(&data->update_lock);
1863
1864 return count;
1865}
1866
f73cf632
GR
1867static umode_t nct6775_fan_is_visible(struct kobject *kobj,
1868 struct attribute *attr, int index)
1869{
1870 struct device *dev = container_of(kobj, struct device, kobj);
1871 struct nct6775_data *data = dev_get_drvdata(dev);
30846993
GR
1872 int fan = index / 6; /* fan index */
1873 int nr = index % 6; /* attribute index */
1c65dc36 1874
f73cf632
GR
1875 if (!(data->has_fan & (1 << fan)))
1876 return 0;
1c65dc36 1877
f73cf632
GR
1878 if (nr == 1 && data->ALARM_BITS[FAN_ALARM_BASE + fan] == -1)
1879 return 0;
30846993 1880 if (nr == 2 && data->BEEP_BITS[FAN_ALARM_BASE + fan] == -1)
f73cf632 1881 return 0;
30846993
GR
1882 if (nr == 4 && !(data->has_fan_min & (1 << fan)))
1883 return 0;
1884 if (nr == 5 && data->kind != nct6775)
f73cf632
GR
1885 return 0;
1886
1887 return attr->mode;
1888}
1c65dc36 1889
f73cf632
GR
1890SENSOR_TEMPLATE(fan_input, "fan%d_input", S_IRUGO, show_fan, NULL, 0);
1891SENSOR_TEMPLATE(fan_alarm, "fan%d_alarm", S_IRUGO, show_alarm, NULL,
1892 FAN_ALARM_BASE);
30846993
GR
1893SENSOR_TEMPLATE(fan_beep, "fan%d_beep", S_IWUSR | S_IRUGO, show_beep,
1894 store_beep, FAN_ALARM_BASE);
f73cf632
GR
1895SENSOR_TEMPLATE(fan_pulses, "fan%d_pulses", S_IWUSR | S_IRUGO, show_fan_pulses,
1896 store_fan_pulses, 0);
1897SENSOR_TEMPLATE(fan_min, "fan%d_min", S_IWUSR | S_IRUGO, show_fan_min,
1898 store_fan_min, 0);
1899SENSOR_TEMPLATE(fan_div, "fan%d_div", S_IRUGO, show_fan_div, NULL, 0);
1900
1901/*
1902 * nct6775_fan_is_visible uses the index into the following array
1903 * to determine if attributes should be created or not.
1904 * Any change in order or content must be matched.
1905 */
1906static struct sensor_device_template *nct6775_attributes_fan_template[] = {
1907 &sensor_dev_template_fan_input,
1908 &sensor_dev_template_fan_alarm, /* 1 */
30846993 1909 &sensor_dev_template_fan_beep, /* 2 */
f73cf632 1910 &sensor_dev_template_fan_pulses,
30846993
GR
1911 &sensor_dev_template_fan_min, /* 4 */
1912 &sensor_dev_template_fan_div, /* 5 */
f73cf632 1913 NULL
5c25d954
GR
1914};
1915
f73cf632
GR
1916static struct sensor_template_group nct6775_fan_template_group = {
1917 .templates = nct6775_attributes_fan_template,
1918 .is_visible = nct6775_fan_is_visible,
1919 .base = 1,
1c65dc36
GR
1920};
1921
aa136e5d
GR
1922static ssize_t
1923show_temp_label(struct device *dev, struct device_attribute *attr, char *buf)
1924{
1925 struct nct6775_data *data = nct6775_update_device(dev);
1926 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1927 int nr = sattr->index;
1928 return sprintf(buf, "%s\n", data->temp_label[data->temp_src[nr]]);
1929}
1930
1931static ssize_t
1932show_temp(struct device *dev, struct device_attribute *attr, char *buf)
1933{
1934 struct nct6775_data *data = nct6775_update_device(dev);
1935 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
1936 int nr = sattr->nr;
1937 int index = sattr->index;
1938
1939 return sprintf(buf, "%d\n", LM75_TEMP_FROM_REG(data->temp[index][nr]));
1940}
1941
1942static ssize_t
1943store_temp(struct device *dev, struct device_attribute *attr, const char *buf,
1944 size_t count)
1945{
1946 struct nct6775_data *data = dev_get_drvdata(dev);
1947 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
1948 int nr = sattr->nr;
1949 int index = sattr->index;
1950 int err;
1951 long val;
1952
1953 err = kstrtol(buf, 10, &val);
1954 if (err < 0)
1955 return err;
1956
1957 mutex_lock(&data->update_lock);
1958 data->temp[index][nr] = LM75_TEMP_TO_REG(val);
1959 nct6775_write_temp(data, data->reg_temp[index][nr],
1960 data->temp[index][nr]);
1961 mutex_unlock(&data->update_lock);
1962 return count;
1963}
1964
1965static ssize_t
1966show_temp_offset(struct device *dev, struct device_attribute *attr, char *buf)
1967{
1968 struct nct6775_data *data = nct6775_update_device(dev);
1969 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1970
1971 return sprintf(buf, "%d\n", data->temp_offset[sattr->index] * 1000);
1972}
1973
1974static ssize_t
1975store_temp_offset(struct device *dev, struct device_attribute *attr,
1976 const char *buf, size_t count)
1977{
1978 struct nct6775_data *data = dev_get_drvdata(dev);
1979 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1980 int nr = sattr->index;
1981 long val;
1982 int err;
1983
1984 err = kstrtol(buf, 10, &val);
1985 if (err < 0)
1986 return err;
1987
1988 val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), -128, 127);
1989
1990 mutex_lock(&data->update_lock);
1991 data->temp_offset[nr] = val;
1992 nct6775_write_value(data, data->REG_TEMP_OFFSET[nr], val);
1993 mutex_unlock(&data->update_lock);
1994
1995 return count;
1996}
1997
1998static ssize_t
1999show_temp_type(struct device *dev, struct device_attribute *attr, char *buf)
2000{
2001 struct nct6775_data *data = nct6775_update_device(dev);
2002 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2003 int nr = sattr->index;
2004 return sprintf(buf, "%d\n", (int)data->temp_type[nr]);
2005}
2006
2007static ssize_t
2008store_temp_type(struct device *dev, struct device_attribute *attr,
2009 const char *buf, size_t count)
2010{
2011 struct nct6775_data *data = nct6775_update_device(dev);
2012 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2013 int nr = sattr->index;
2014 unsigned long val;
2015 int err;
6c009501 2016 u8 vbat, diode, vbit, dbit;
aa136e5d
GR
2017
2018 err = kstrtoul(buf, 10, &val);
2019 if (err < 0)
2020 return err;
2021
2022 if (val != 1 && val != 3 && val != 4)
2023 return -EINVAL;
2024
2025 mutex_lock(&data->update_lock);
2026
2027 data->temp_type[nr] = val;
6c009501
GR
2028 vbit = 0x02 << nr;
2029 dbit = data->DIODE_MASK << nr;
2030 vbat = nct6775_read_value(data, data->REG_VBAT) & ~vbit;
2031 diode = nct6775_read_value(data, data->REG_DIODE) & ~dbit;
aa136e5d
GR
2032 switch (val) {
2033 case 1: /* CPU diode (diode, current mode) */
6c009501
GR
2034 vbat |= vbit;
2035 diode |= dbit;
aa136e5d
GR
2036 break;
2037 case 3: /* diode, voltage mode */
6c009501 2038 vbat |= dbit;
aa136e5d
GR
2039 break;
2040 case 4: /* thermistor */
2041 break;
2042 }
2043 nct6775_write_value(data, data->REG_VBAT, vbat);
2044 nct6775_write_value(data, data->REG_DIODE, diode);
2045
2046 mutex_unlock(&data->update_lock);
2047 return count;
2048}
2049
f73cf632
GR
2050static umode_t nct6775_temp_is_visible(struct kobject *kobj,
2051 struct attribute *attr, int index)
2052{
2053 struct device *dev = container_of(kobj, struct device, kobj);
2054 struct nct6775_data *data = dev_get_drvdata(dev);
30846993
GR
2055 int temp = index / 10; /* temp index */
2056 int nr = index % 10; /* attribute index */
aa136e5d 2057
f73cf632
GR
2058 if (!(data->have_temp & (1 << temp)))
2059 return 0;
aa136e5d 2060
f73cf632
GR
2061 if (nr == 2 && find_temp_source(data, temp, data->num_temp_alarms) < 0)
2062 return 0; /* alarm */
aa136e5d 2063
30846993
GR
2064 if (nr == 3 && find_temp_source(data, temp, data->num_temp_beeps) < 0)
2065 return 0; /* beep */
2066
2067 if (nr == 4 && !data->reg_temp[1][temp]) /* max */
f73cf632 2068 return 0;
aa136e5d 2069
30846993 2070 if (nr == 5 && !data->reg_temp[2][temp]) /* max_hyst */
f73cf632 2071 return 0;
aa136e5d 2072
30846993 2073 if (nr == 6 && !data->reg_temp[3][temp]) /* crit */
f73cf632
GR
2074 return 0;
2075
30846993 2076 if (nr == 7 && !data->reg_temp[4][temp]) /* lcrit */
b7a61353
GR
2077 return 0;
2078
2079 /* offset and type only apply to fixed sensors */
30846993 2080 if (nr > 7 && !(data->have_temp_fixed & (1 << temp)))
f73cf632 2081 return 0;
aa136e5d 2082
f73cf632
GR
2083 return attr->mode;
2084}
2085
2086SENSOR_TEMPLATE_2(temp_input, "temp%d_input", S_IRUGO, show_temp, NULL, 0, 0);
2087SENSOR_TEMPLATE(temp_label, "temp%d_label", S_IRUGO, show_temp_label, NULL, 0);
2088SENSOR_TEMPLATE_2(temp_max, "temp%d_max", S_IRUGO | S_IWUSR, show_temp,
2089 store_temp, 0, 1);
2090SENSOR_TEMPLATE_2(temp_max_hyst, "temp%d_max_hyst", S_IRUGO | S_IWUSR,
2091 show_temp, store_temp, 0, 2);
2092SENSOR_TEMPLATE_2(temp_crit, "temp%d_crit", S_IRUGO | S_IWUSR, show_temp,
2093 store_temp, 0, 3);
b7a61353
GR
2094SENSOR_TEMPLATE_2(temp_lcrit, "temp%d_lcrit", S_IRUGO | S_IWUSR, show_temp,
2095 store_temp, 0, 4);
f73cf632
GR
2096SENSOR_TEMPLATE(temp_offset, "temp%d_offset", S_IRUGO | S_IWUSR,
2097 show_temp_offset, store_temp_offset, 0);
2098SENSOR_TEMPLATE(temp_type, "temp%d_type", S_IRUGO | S_IWUSR, show_temp_type,
2099 store_temp_type, 0);
2100SENSOR_TEMPLATE(temp_alarm, "temp%d_alarm", S_IRUGO, show_temp_alarm, NULL, 0);
30846993
GR
2101SENSOR_TEMPLATE(temp_beep, "temp%d_beep", S_IRUGO | S_IWUSR, show_temp_beep,
2102 store_temp_beep, 0);
f73cf632
GR
2103
2104/*
2105 * nct6775_temp_is_visible uses the index into the following array
2106 * to determine if attributes should be created or not.
2107 * Any change in order or content must be matched.
2108 */
2109static struct sensor_device_template *nct6775_attributes_temp_template[] = {
2110 &sensor_dev_template_temp_input,
2111 &sensor_dev_template_temp_label,
2112 &sensor_dev_template_temp_alarm, /* 2 */
30846993
GR
2113 &sensor_dev_template_temp_beep, /* 3 */
2114 &sensor_dev_template_temp_max, /* 4 */
2115 &sensor_dev_template_temp_max_hyst, /* 5 */
2116 &sensor_dev_template_temp_crit, /* 6 */
2117 &sensor_dev_template_temp_lcrit, /* 7 */
2118 &sensor_dev_template_temp_offset, /* 8 */
2119 &sensor_dev_template_temp_type, /* 9 */
f73cf632 2120 NULL
aa136e5d
GR
2121};
2122
f73cf632
GR
2123static struct sensor_template_group nct6775_temp_template_group = {
2124 .templates = nct6775_attributes_temp_template,
2125 .is_visible = nct6775_temp_is_visible,
2126 .base = 1,
aa136e5d
GR
2127};
2128
77eb5b37
GR
2129static ssize_t
2130show_pwm_mode(struct device *dev, struct device_attribute *attr, char *buf)
2131{
2132 struct nct6775_data *data = nct6775_update_device(dev);
2133 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2134
2135 return sprintf(buf, "%d\n", !data->pwm_mode[sattr->index]);
2136}
2137
2138static ssize_t
2139store_pwm_mode(struct device *dev, struct device_attribute *attr,
2140 const char *buf, size_t count)
2141{
2142 struct nct6775_data *data = dev_get_drvdata(dev);
2143 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2144 int nr = sattr->index;
2145 unsigned long val;
2146 int err;
2147 u8 reg;
2148
2149 err = kstrtoul(buf, 10, &val);
2150 if (err < 0)
2151 return err;
2152
2153 if (val > 1)
2154 return -EINVAL;
2155
2156 /* Setting DC mode is not supported for all chips/channels */
2157 if (data->REG_PWM_MODE[nr] == 0) {
2158 if (val)
2159 return -EINVAL;
2160 return count;
2161 }
2162
2163 mutex_lock(&data->update_lock);
2164 data->pwm_mode[nr] = val;
2165 reg = nct6775_read_value(data, data->REG_PWM_MODE[nr]);
2166 reg &= ~data->PWM_MODE_MASK[nr];
2167 if (val)
2168 reg |= data->PWM_MODE_MASK[nr];
2169 nct6775_write_value(data, data->REG_PWM_MODE[nr], reg);
2170 mutex_unlock(&data->update_lock);
2171 return count;
2172}
2173
2174static ssize_t
2175show_pwm(struct device *dev, struct device_attribute *attr, char *buf)
2176{
2177 struct nct6775_data *data = nct6775_update_device(dev);
2178 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2179 int nr = sattr->nr;
2180 int index = sattr->index;
2181 int pwm;
2182
2183 /*
2184 * For automatic fan control modes, show current pwm readings.
2185 * Otherwise, show the configured value.
2186 */
2187 if (index == 0 && data->pwm_enable[nr] > manual)
2188 pwm = nct6775_read_value(data, data->REG_PWM_READ[nr]);
2189 else
2190 pwm = data->pwm[index][nr];
2191
2192 return sprintf(buf, "%d\n", pwm);
2193}
2194
2195static ssize_t
2196store_pwm(struct device *dev, struct device_attribute *attr, const char *buf,
2197 size_t count)
2198{
2199 struct nct6775_data *data = dev_get_drvdata(dev);
2200 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2201 int nr = sattr->nr;
2202 int index = sattr->index;
2203 unsigned long val;
bbd8decd
GR
2204 int minval[7] = { 0, 1, 1, data->pwm[2][nr], 0, 0, 0 };
2205 int maxval[7]
2206 = { 255, 255, data->pwm[3][nr] ? : 255, 255, 255, 255, 255 };
77eb5b37 2207 int err;
cdcaeceb 2208 u8 reg;
77eb5b37
GR
2209
2210 err = kstrtoul(buf, 10, &val);
2211 if (err < 0)
2212 return err;
cdcaeceb 2213 val = clamp_val(val, minval[index], maxval[index]);
77eb5b37
GR
2214
2215 mutex_lock(&data->update_lock);
2216 data->pwm[index][nr] = val;
2217 nct6775_write_value(data, data->REG_PWM[index][nr], val);
cdcaeceb
GR
2218 if (index == 2) { /* floor: disable if val == 0 */
2219 reg = nct6775_read_value(data, data->REG_TEMP_SEL[nr]);
2220 reg &= 0x7f;
2221 if (val)
2222 reg |= 0x80;
2223 nct6775_write_value(data, data->REG_TEMP_SEL[nr], reg);
2224 }
77eb5b37
GR
2225 mutex_unlock(&data->update_lock);
2226 return count;
2227}
2228
cdcaeceb
GR
2229/* Returns 0 if OK, -EINVAL otherwise */
2230static int check_trip_points(struct nct6775_data *data, int nr)
2231{
2232 int i;
2233
2234 for (i = 0; i < data->auto_pwm_num - 1; i++) {
2235 if (data->auto_temp[nr][i] > data->auto_temp[nr][i + 1])
2236 return -EINVAL;
2237 }
2238 for (i = 0; i < data->auto_pwm_num - 1; i++) {
2239 if (data->auto_pwm[nr][i] > data->auto_pwm[nr][i + 1])
2240 return -EINVAL;
2241 }
2242 /* validate critical temperature and pwm if enabled (pwm > 0) */
2243 if (data->auto_pwm[nr][data->auto_pwm_num]) {
2244 if (data->auto_temp[nr][data->auto_pwm_num - 1] >
2245 data->auto_temp[nr][data->auto_pwm_num] ||
2246 data->auto_pwm[nr][data->auto_pwm_num - 1] >
2247 data->auto_pwm[nr][data->auto_pwm_num])
2248 return -EINVAL;
2249 }
2250 return 0;
2251}
2252
2253static void pwm_update_registers(struct nct6775_data *data, int nr)
2254{
2255 u8 reg;
2256
2257 switch (data->pwm_enable[nr]) {
2258 case off:
2259 case manual:
2260 break;
2261 case speed_cruise:
2262 reg = nct6775_read_value(data, data->REG_FAN_MODE[nr]);
2263 reg = (reg & ~data->tolerance_mask) |
2264 (data->target_speed_tolerance[nr] & data->tolerance_mask);
2265 nct6775_write_value(data, data->REG_FAN_MODE[nr], reg);
2266 nct6775_write_value(data, data->REG_TARGET[nr],
2267 data->target_speed[nr] & 0xff);
2268 if (data->REG_TOLERANCE_H) {
2269 reg = (data->target_speed[nr] >> 8) & 0x0f;
2270 reg |= (data->target_speed_tolerance[nr] & 0x38) << 1;
2271 nct6775_write_value(data,
2272 data->REG_TOLERANCE_H[nr],
2273 reg);
2274 }
2275 break;
2276 case thermal_cruise:
2277 nct6775_write_value(data, data->REG_TARGET[nr],
2278 data->target_temp[nr]);
2279 /* intentional */
2280 default:
2281 reg = nct6775_read_value(data, data->REG_FAN_MODE[nr]);
2282 reg = (reg & ~data->tolerance_mask) |
2283 data->temp_tolerance[0][nr];
2284 nct6775_write_value(data, data->REG_FAN_MODE[nr], reg);
2285 break;
2286 }
2287}
2288
77eb5b37
GR
2289static ssize_t
2290show_pwm_enable(struct device *dev, struct device_attribute *attr, char *buf)
2291{
2292 struct nct6775_data *data = nct6775_update_device(dev);
2293 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2294
2295 return sprintf(buf, "%d\n", data->pwm_enable[sattr->index]);
2296}
2297
2298static ssize_t
2299store_pwm_enable(struct device *dev, struct device_attribute *attr,
2300 const char *buf, size_t count)
2301{
2302 struct nct6775_data *data = dev_get_drvdata(dev);
2303 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2304 int nr = sattr->index;
2305 unsigned long val;
2306 int err;
2307 u16 reg;
2308
2309 err = kstrtoul(buf, 10, &val);
2310 if (err < 0)
2311 return err;
2312
2313 if (val > sf4)
2314 return -EINVAL;
2315
2316 if (val == sf3 && data->kind != nct6775)
2317 return -EINVAL;
2318
cdcaeceb
GR
2319 if (val == sf4 && check_trip_points(data, nr)) {
2320 dev_err(dev, "Inconsistent trip points, not switching to SmartFan IV mode\n");
2321 dev_err(dev, "Adjust trip points and try again\n");
2322 return -EINVAL;
2323 }
2324
77eb5b37
GR
2325 mutex_lock(&data->update_lock);
2326 data->pwm_enable[nr] = val;
2327 if (val == off) {
2328 /*
2329 * turn off pwm control: select manual mode, set pwm to maximum
2330 */
2331 data->pwm[0][nr] = 255;
2332 nct6775_write_value(data, data->REG_PWM[0][nr], 255);
2333 }
cdcaeceb 2334 pwm_update_registers(data, nr);
77eb5b37
GR
2335 reg = nct6775_read_value(data, data->REG_FAN_MODE[nr]);
2336 reg &= 0x0f;
2337 reg |= pwm_enable_to_reg(val) << 4;
2338 nct6775_write_value(data, data->REG_FAN_MODE[nr], reg);
2339 mutex_unlock(&data->update_lock);
2340 return count;
2341}
2342
cdcaeceb 2343static ssize_t
bbd8decd 2344show_pwm_temp_sel_common(struct nct6775_data *data, char *buf, int src)
cdcaeceb 2345{
bbd8decd 2346 int i, sel = 0;
cdcaeceb
GR
2347
2348 for (i = 0; i < NUM_TEMP; i++) {
2349 if (!(data->have_temp & (1 << i)))
2350 continue;
2351 if (src == data->temp_src[i]) {
2352 sel = i + 1;
2353 break;
2354 }
2355 }
2356
2357 return sprintf(buf, "%d\n", sel);
2358}
2359
bbd8decd
GR
2360static ssize_t
2361show_pwm_temp_sel(struct device *dev, struct device_attribute *attr, char *buf)
2362{
2363 struct nct6775_data *data = nct6775_update_device(dev);
2364 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2365 int index = sattr->index;
2366
2367 return show_pwm_temp_sel_common(data, buf, data->pwm_temp_sel[index]);
2368}
2369
cdcaeceb
GR
2370static ssize_t
2371store_pwm_temp_sel(struct device *dev, struct device_attribute *attr,
2372 const char *buf, size_t count)
2373{
2374 struct nct6775_data *data = nct6775_update_device(dev);
2375 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2376 int nr = sattr->index;
2377 unsigned long val;
2378 int err, reg, src;
2379
2380 err = kstrtoul(buf, 10, &val);
2381 if (err < 0)
2382 return err;
2383 if (val == 0 || val > NUM_TEMP)
2384 return -EINVAL;
2385 if (!(data->have_temp & (1 << (val - 1))) || !data->temp_src[val - 1])
2386 return -EINVAL;
2387
2388 mutex_lock(&data->update_lock);
2389 src = data->temp_src[val - 1];
2390 data->pwm_temp_sel[nr] = src;
2391 reg = nct6775_read_value(data, data->REG_TEMP_SEL[nr]);
2392 reg &= 0xe0;
2393 reg |= src;
2394 nct6775_write_value(data, data->REG_TEMP_SEL[nr], reg);
2395 mutex_unlock(&data->update_lock);
2396
2397 return count;
2398}
2399
bbd8decd
GR
2400static ssize_t
2401show_pwm_weight_temp_sel(struct device *dev, struct device_attribute *attr,
2402 char *buf)
2403{
2404 struct nct6775_data *data = nct6775_update_device(dev);
2405 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2406 int index = sattr->index;
2407
2408 return show_pwm_temp_sel_common(data, buf,
2409 data->pwm_weight_temp_sel[index]);
2410}
2411
2412static ssize_t
2413store_pwm_weight_temp_sel(struct device *dev, struct device_attribute *attr,
2414 const char *buf, size_t count)
2415{
2416 struct nct6775_data *data = nct6775_update_device(dev);
2417 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2418 int nr = sattr->index;
2419 unsigned long val;
2420 int err, reg, src;
2421
2422 err = kstrtoul(buf, 10, &val);
2423 if (err < 0)
2424 return err;
2425 if (val > NUM_TEMP)
2426 return -EINVAL;
2427 if (val && (!(data->have_temp & (1 << (val - 1))) ||
2428 !data->temp_src[val - 1]))
2429 return -EINVAL;
2430
2431 mutex_lock(&data->update_lock);
2432 if (val) {
2433 src = data->temp_src[val - 1];
2434 data->pwm_weight_temp_sel[nr] = src;
2435 reg = nct6775_read_value(data, data->REG_WEIGHT_TEMP_SEL[nr]);
2436 reg &= 0xe0;
2437 reg |= (src | 0x80);
2438 nct6775_write_value(data, data->REG_WEIGHT_TEMP_SEL[nr], reg);
2439 } else {
2440 data->pwm_weight_temp_sel[nr] = 0;
2441 reg = nct6775_read_value(data, data->REG_WEIGHT_TEMP_SEL[nr]);
2442 reg &= 0x7f;
2443 nct6775_write_value(data, data->REG_WEIGHT_TEMP_SEL[nr], reg);
2444 }
2445 mutex_unlock(&data->update_lock);
2446
2447 return count;
2448}
2449
cdcaeceb
GR
2450static ssize_t
2451show_target_temp(struct device *dev, struct device_attribute *attr, char *buf)
2452{
2453 struct nct6775_data *data = nct6775_update_device(dev);
2454 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2455
2456 return sprintf(buf, "%d\n", data->target_temp[sattr->index] * 1000);
2457}
2458
2459static ssize_t
2460store_target_temp(struct device *dev, struct device_attribute *attr,
2461 const char *buf, size_t count)
2462{
2463 struct nct6775_data *data = dev_get_drvdata(dev);
2464 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2465 int nr = sattr->index;
2466 unsigned long val;
2467 int err;
2468
2469 err = kstrtoul(buf, 10, &val);
2470 if (err < 0)
2471 return err;
2472
2473 val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0,
2474 data->target_temp_mask);
2475
2476 mutex_lock(&data->update_lock);
2477 data->target_temp[nr] = val;
2478 pwm_update_registers(data, nr);
2479 mutex_unlock(&data->update_lock);
2480 return count;
2481}
2482
2483static ssize_t
2484show_target_speed(struct device *dev, struct device_attribute *attr, char *buf)
2485{
2486 struct nct6775_data *data = nct6775_update_device(dev);
2487 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2488 int nr = sattr->index;
2489
2490 return sprintf(buf, "%d\n",
2491 fan_from_reg16(data->target_speed[nr],
2492 data->fan_div[nr]));
2493}
2494
2495static ssize_t
2496store_target_speed(struct device *dev, struct device_attribute *attr,
2497 const char *buf, size_t count)
2498{
2499 struct nct6775_data *data = dev_get_drvdata(dev);
2500 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2501 int nr = sattr->index;
2502 unsigned long val;
2503 int err;
2504 u16 speed;
2505
2506 err = kstrtoul(buf, 10, &val);
2507 if (err < 0)
2508 return err;
2509
2510 val = clamp_val(val, 0, 1350000U);
2511 speed = fan_to_reg(val, data->fan_div[nr]);
2512
2513 mutex_lock(&data->update_lock);
2514 data->target_speed[nr] = speed;
2515 pwm_update_registers(data, nr);
2516 mutex_unlock(&data->update_lock);
2517 return count;
2518}
2519
2520static ssize_t
2521show_temp_tolerance(struct device *dev, struct device_attribute *attr,
2522 char *buf)
2523{
2524 struct nct6775_data *data = nct6775_update_device(dev);
2525 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2526 int nr = sattr->nr;
2527 int index = sattr->index;
2528
2529 return sprintf(buf, "%d\n", data->temp_tolerance[index][nr] * 1000);
2530}
2531
2532static ssize_t
2533store_temp_tolerance(struct device *dev, struct device_attribute *attr,
2534 const char *buf, size_t count)
2535{
2536 struct nct6775_data *data = dev_get_drvdata(dev);
2537 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2538 int nr = sattr->nr;
2539 int index = sattr->index;
2540 unsigned long val;
2541 int err;
2542
2543 err = kstrtoul(buf, 10, &val);
2544 if (err < 0)
2545 return err;
2546
2547 /* Limit tolerance as needed */
2548 val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0, data->tolerance_mask);
2549
2550 mutex_lock(&data->update_lock);
2551 data->temp_tolerance[index][nr] = val;
2552 if (index)
2553 pwm_update_registers(data, nr);
2554 else
2555 nct6775_write_value(data,
2556 data->REG_CRITICAL_TEMP_TOLERANCE[nr],
2557 val);
2558 mutex_unlock(&data->update_lock);
2559 return count;
2560}
2561
2562/*
2563 * Fan speed tolerance is a tricky beast, since the associated register is
2564 * a tick counter, but the value is reported and configured as rpm.
2565 * Compute resulting low and high rpm values and report the difference.
2566 */
2567static ssize_t
2568show_speed_tolerance(struct device *dev, struct device_attribute *attr,
2569 char *buf)
2570{
2571 struct nct6775_data *data = nct6775_update_device(dev);
2572 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2573 int nr = sattr->index;
2574 int low = data->target_speed[nr] - data->target_speed_tolerance[nr];
2575 int high = data->target_speed[nr] + data->target_speed_tolerance[nr];
2576 int tolerance;
2577
2578 if (low <= 0)
2579 low = 1;
2580 if (high > 0xffff)
2581 high = 0xffff;
2582 if (high < low)
2583 high = low;
2584
2585 tolerance = (fan_from_reg16(low, data->fan_div[nr])
2586 - fan_from_reg16(high, data->fan_div[nr])) / 2;
2587
2588 return sprintf(buf, "%d\n", tolerance);
2589}
2590
2591static ssize_t
2592store_speed_tolerance(struct device *dev, struct device_attribute *attr,
2593 const char *buf, size_t count)
2594{
2595 struct nct6775_data *data = dev_get_drvdata(dev);
2596 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2597 int nr = sattr->index;
2598 unsigned long val;
2599 int err;
2600 int low, high;
2601
2602 err = kstrtoul(buf, 10, &val);
2603 if (err < 0)
2604 return err;
2605
2606 high = fan_from_reg16(data->target_speed[nr],
2607 data->fan_div[nr]) + val;
2608 low = fan_from_reg16(data->target_speed[nr],
2609 data->fan_div[nr]) - val;
2610 if (low <= 0)
2611 low = 1;
2612 if (high < low)
2613 high = low;
2614
2615 val = (fan_to_reg(low, data->fan_div[nr]) -
2616 fan_to_reg(high, data->fan_div[nr])) / 2;
2617
2618 /* Limit tolerance as needed */
2619 val = clamp_val(val, 0, data->speed_tolerance_limit);
2620
2621 mutex_lock(&data->update_lock);
2622 data->target_speed_tolerance[nr] = val;
2623 pwm_update_registers(data, nr);
2624 mutex_unlock(&data->update_lock);
2625 return count;
2626}
2627
f73cf632
GR
2628SENSOR_TEMPLATE_2(pwm, "pwm%d", S_IWUSR | S_IRUGO, show_pwm, store_pwm, 0, 0);
2629SENSOR_TEMPLATE(pwm_mode, "pwm%d_mode", S_IWUSR | S_IRUGO, show_pwm_mode,
2630 store_pwm_mode, 0);
2631SENSOR_TEMPLATE(pwm_enable, "pwm%d_enable", S_IWUSR | S_IRUGO, show_pwm_enable,
2632 store_pwm_enable, 0);
2633SENSOR_TEMPLATE(pwm_temp_sel, "pwm%d_temp_sel", S_IWUSR | S_IRUGO,
2634 show_pwm_temp_sel, store_pwm_temp_sel, 0);
2635SENSOR_TEMPLATE(pwm_target_temp, "pwm%d_target_temp", S_IWUSR | S_IRUGO,
2636 show_target_temp, store_target_temp, 0);
2637SENSOR_TEMPLATE(fan_target, "fan%d_target", S_IWUSR | S_IRUGO,
2638 show_target_speed, store_target_speed, 0);
2639SENSOR_TEMPLATE(fan_tolerance, "fan%d_tolerance", S_IWUSR | S_IRUGO,
2640 show_speed_tolerance, store_speed_tolerance, 0);
cdcaeceb
GR
2641
2642/* Smart Fan registers */
2643
bbd8decd
GR
2644static ssize_t
2645show_weight_temp(struct device *dev, struct device_attribute *attr, char *buf)
2646{
2647 struct nct6775_data *data = nct6775_update_device(dev);
2648 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2649 int nr = sattr->nr;
2650 int index = sattr->index;
2651
2652 return sprintf(buf, "%d\n", data->weight_temp[index][nr] * 1000);
2653}
2654
2655static ssize_t
2656store_weight_temp(struct device *dev, struct device_attribute *attr,
2657 const char *buf, size_t count)
2658{
2659 struct nct6775_data *data = dev_get_drvdata(dev);
2660 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2661 int nr = sattr->nr;
2662 int index = sattr->index;
2663 unsigned long val;
2664 int err;
2665
2666 err = kstrtoul(buf, 10, &val);
2667 if (err < 0)
2668 return err;
2669
2670 val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0, 255);
2671
2672 mutex_lock(&data->update_lock);
2673 data->weight_temp[index][nr] = val;
2674 nct6775_write_value(data, data->REG_WEIGHT_TEMP[index][nr], val);
2675 mutex_unlock(&data->update_lock);
2676 return count;
2677}
2678
f73cf632
GR
2679SENSOR_TEMPLATE(pwm_weight_temp_sel, "pwm%d_weight_temp_sel", S_IWUSR | S_IRUGO,
2680 show_pwm_weight_temp_sel, store_pwm_weight_temp_sel, 0);
2681SENSOR_TEMPLATE_2(pwm_weight_temp_step, "pwm%d_weight_temp_step",
2682 S_IWUSR | S_IRUGO, show_weight_temp, store_weight_temp, 0, 0);
2683SENSOR_TEMPLATE_2(pwm_weight_temp_step_tol, "pwm%d_weight_temp_step_tol",
2684 S_IWUSR | S_IRUGO, show_weight_temp, store_weight_temp, 0, 1);
2685SENSOR_TEMPLATE_2(pwm_weight_temp_step_base, "pwm%d_weight_temp_step_base",
2686 S_IWUSR | S_IRUGO, show_weight_temp, store_weight_temp, 0, 2);
2687SENSOR_TEMPLATE_2(pwm_weight_duty_step, "pwm%d_weight_duty_step",
2688 S_IWUSR | S_IRUGO, show_pwm, store_pwm, 0, 5);
2689SENSOR_TEMPLATE_2(pwm_weight_duty_base, "pwm%d_weight_duty_base",
2690 S_IWUSR | S_IRUGO, show_pwm, store_pwm, 0, 6);
bbd8decd 2691
cdcaeceb
GR
2692static ssize_t
2693show_fan_time(struct device *dev, struct device_attribute *attr, char *buf)
2694{
2695 struct nct6775_data *data = nct6775_update_device(dev);
2696 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2697 int nr = sattr->nr;
2698 int index = sattr->index;
2699
2700 return sprintf(buf, "%d\n",
2701 step_time_from_reg(data->fan_time[index][nr],
2702 data->pwm_mode[nr]));
2703}
2704
2705static ssize_t
2706store_fan_time(struct device *dev, struct device_attribute *attr,
2707 const char *buf, size_t count)
2708{
2709 struct nct6775_data *data = dev_get_drvdata(dev);
2710 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2711 int nr = sattr->nr;
2712 int index = sattr->index;
2713 unsigned long val;
2714 int err;
2715
2716 err = kstrtoul(buf, 10, &val);
2717 if (err < 0)
2718 return err;
2719
2720 val = step_time_to_reg(val, data->pwm_mode[nr]);
2721 mutex_lock(&data->update_lock);
2722 data->fan_time[index][nr] = val;
2723 nct6775_write_value(data, data->REG_FAN_TIME[index][nr], val);
2724 mutex_unlock(&data->update_lock);
2725 return count;
2726}
2727
9de2e2e8
GR
2728static ssize_t
2729show_name(struct device *dev, struct device_attribute *attr, char *buf)
2730{
2731 struct nct6775_data *data = dev_get_drvdata(dev);
2732
2733 return sprintf(buf, "%s\n", data->name);
2734}
2735
2736static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
2737
cdcaeceb
GR
2738static ssize_t
2739show_auto_pwm(struct device *dev, struct device_attribute *attr, char *buf)
2740{
2741 struct nct6775_data *data = nct6775_update_device(dev);
2742 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2743
2744 return sprintf(buf, "%d\n", data->auto_pwm[sattr->nr][sattr->index]);
2745}
2746
2747static ssize_t
2748store_auto_pwm(struct device *dev, struct device_attribute *attr,
2749 const char *buf, size_t count)
2750{
2751 struct nct6775_data *data = dev_get_drvdata(dev);
2752 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2753 int nr = sattr->nr;
2754 int point = sattr->index;
2755 unsigned long val;
2756 int err;
2757 u8 reg;
2758
2759 err = kstrtoul(buf, 10, &val);
2760 if (err < 0)
2761 return err;
2762 if (val > 255)
2763 return -EINVAL;
2764
2765 if (point == data->auto_pwm_num) {
2766 if (data->kind != nct6775 && !val)
2767 return -EINVAL;
2768 if (data->kind != nct6779 && val)
2769 val = 0xff;
2770 }
2771
2772 mutex_lock(&data->update_lock);
2773 data->auto_pwm[nr][point] = val;
2774 if (point < data->auto_pwm_num) {
2775 nct6775_write_value(data,
2776 NCT6775_AUTO_PWM(data, nr, point),
2777 data->auto_pwm[nr][point]);
2778 } else {
2779 switch (data->kind) {
2780 case nct6775:
2781 /* disable if needed (pwm == 0) */
2782 reg = nct6775_read_value(data,
2783 NCT6775_REG_CRITICAL_ENAB[nr]);
2784 if (val)
2785 reg |= 0x02;
2786 else
2787 reg &= ~0x02;
2788 nct6775_write_value(data, NCT6775_REG_CRITICAL_ENAB[nr],
2789 reg);
2790 break;
2791 case nct6776:
2792 break; /* always enabled, nothing to do */
6c009501 2793 case nct6106:
cdcaeceb 2794 case nct6779:
578ab5f0 2795 case nct6791:
6c009501 2796 nct6775_write_value(data, data->REG_CRITICAL_PWM[nr],
cdcaeceb
GR
2797 val);
2798 reg = nct6775_read_value(data,
6c009501 2799 data->REG_CRITICAL_PWM_ENABLE[nr]);
cdcaeceb 2800 if (val == 255)
6c009501 2801 reg &= ~data->CRITICAL_PWM_ENABLE_MASK;
cdcaeceb 2802 else
6c009501 2803 reg |= data->CRITICAL_PWM_ENABLE_MASK;
cdcaeceb 2804 nct6775_write_value(data,
6c009501 2805 data->REG_CRITICAL_PWM_ENABLE[nr],
cdcaeceb
GR
2806 reg);
2807 break;
2808 }
2809 }
2810 mutex_unlock(&data->update_lock);
2811 return count;
2812}
2813
2814static ssize_t
2815show_auto_temp(struct device *dev, struct device_attribute *attr, char *buf)
2816{
2817 struct nct6775_data *data = nct6775_update_device(dev);
2818 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2819 int nr = sattr->nr;
2820 int point = sattr->index;
2821
2822 /*
2823 * We don't know for sure if the temperature is signed or unsigned.
2824 * Assume it is unsigned.
2825 */
2826 return sprintf(buf, "%d\n", data->auto_temp[nr][point] * 1000);
2827}
2828
2829static ssize_t
2830store_auto_temp(struct device *dev, struct device_attribute *attr,
2831 const char *buf, size_t count)
2832{
2833 struct nct6775_data *data = dev_get_drvdata(dev);
2834 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2835 int nr = sattr->nr;
2836 int point = sattr->index;
2837 unsigned long val;
2838 int err;
2839
2840 err = kstrtoul(buf, 10, &val);
2841 if (err)
2842 return err;
2843 if (val > 255000)
2844 return -EINVAL;
2845
2846 mutex_lock(&data->update_lock);
2847 data->auto_temp[nr][point] = DIV_ROUND_CLOSEST(val, 1000);
2848 if (point < data->auto_pwm_num) {
2849 nct6775_write_value(data,
2850 NCT6775_AUTO_TEMP(data, nr, point),
2851 data->auto_temp[nr][point]);
2852 } else {
2853 nct6775_write_value(data, data->REG_CRITICAL_TEMP[nr],
2854 data->auto_temp[nr][point]);
2855 }
2856 mutex_unlock(&data->update_lock);
2857 return count;
2858}
2859
f73cf632
GR
2860static umode_t nct6775_pwm_is_visible(struct kobject *kobj,
2861 struct attribute *attr, int index)
2862{
2863 struct device *dev = container_of(kobj, struct device, kobj);
2864 struct nct6775_data *data = dev_get_drvdata(dev);
2865 int pwm = index / 36; /* pwm index */
2866 int nr = index % 36; /* attribute index */
2867
2868 if (!(data->has_pwm & (1 << pwm)))
2869 return 0;
2870
2871 if (nr == 19 && data->REG_PWM[3] == NULL) /* pwm_max */
2872 return 0;
2873 if (nr == 20 && data->REG_PWM[4] == NULL) /* pwm_step */
2874 return 0;
2875 if (nr == 21 && data->REG_PWM[6] == NULL) /* weight_duty_base */
2876 return 0;
2877
2878 if (nr >= 22 && nr <= 35) { /* auto point */
2879 int api = (nr - 22) / 2; /* auto point index */
2880
2881 if (api > data->auto_pwm_num)
2882 return 0;
2883 }
2884 return attr->mode;
2885}
2886
2887SENSOR_TEMPLATE_2(pwm_stop_time, "pwm%d_stop_time", S_IWUSR | S_IRUGO,
2888 show_fan_time, store_fan_time, 0, 0);
2889SENSOR_TEMPLATE_2(pwm_step_up_time, "pwm%d_step_up_time", S_IWUSR | S_IRUGO,
2890 show_fan_time, store_fan_time, 0, 1);
2891SENSOR_TEMPLATE_2(pwm_step_down_time, "pwm%d_step_down_time", S_IWUSR | S_IRUGO,
2892 show_fan_time, store_fan_time, 0, 2);
2893SENSOR_TEMPLATE_2(pwm_start, "pwm%d_start", S_IWUSR | S_IRUGO, show_pwm,
2894 store_pwm, 0, 1);
2895SENSOR_TEMPLATE_2(pwm_floor, "pwm%d_floor", S_IWUSR | S_IRUGO, show_pwm,
2896 store_pwm, 0, 2);
2897SENSOR_TEMPLATE_2(pwm_temp_tolerance, "pwm%d_temp_tolerance", S_IWUSR | S_IRUGO,
2898 show_temp_tolerance, store_temp_tolerance, 0, 0);
2899SENSOR_TEMPLATE_2(pwm_crit_temp_tolerance, "pwm%d_crit_temp_tolerance",
2900 S_IWUSR | S_IRUGO, show_temp_tolerance, store_temp_tolerance,
2901 0, 1);
2902
2903SENSOR_TEMPLATE_2(pwm_max, "pwm%d_max", S_IWUSR | S_IRUGO, show_pwm, store_pwm,
2904 0, 3);
2905
2906SENSOR_TEMPLATE_2(pwm_step, "pwm%d_step", S_IWUSR | S_IRUGO, show_pwm,
2907 store_pwm, 0, 4);
2908
2909SENSOR_TEMPLATE_2(pwm_auto_point1_pwm, "pwm%d_auto_point1_pwm",
2910 S_IWUSR | S_IRUGO, show_auto_pwm, store_auto_pwm, 0, 0);
2911SENSOR_TEMPLATE_2(pwm_auto_point1_temp, "pwm%d_auto_point1_temp",
2912 S_IWUSR | S_IRUGO, show_auto_temp, store_auto_temp, 0, 0);
2913
2914SENSOR_TEMPLATE_2(pwm_auto_point2_pwm, "pwm%d_auto_point2_pwm",
2915 S_IWUSR | S_IRUGO, show_auto_pwm, store_auto_pwm, 0, 1);
2916SENSOR_TEMPLATE_2(pwm_auto_point2_temp, "pwm%d_auto_point2_temp",
2917 S_IWUSR | S_IRUGO, show_auto_temp, store_auto_temp, 0, 1);
2918
2919SENSOR_TEMPLATE_2(pwm_auto_point3_pwm, "pwm%d_auto_point3_pwm",
2920 S_IWUSR | S_IRUGO, show_auto_pwm, store_auto_pwm, 0, 2);
2921SENSOR_TEMPLATE_2(pwm_auto_point3_temp, "pwm%d_auto_point3_temp",
2922 S_IWUSR | S_IRUGO, show_auto_temp, store_auto_temp, 0, 2);
2923
2924SENSOR_TEMPLATE_2(pwm_auto_point4_pwm, "pwm%d_auto_point4_pwm",
2925 S_IWUSR | S_IRUGO, show_auto_pwm, store_auto_pwm, 0, 3);
2926SENSOR_TEMPLATE_2(pwm_auto_point4_temp, "pwm%d_auto_point4_temp",
2927 S_IWUSR | S_IRUGO, show_auto_temp, store_auto_temp, 0, 3);
2928
2929SENSOR_TEMPLATE_2(pwm_auto_point5_pwm, "pwm%d_auto_point5_pwm",
2930 S_IWUSR | S_IRUGO, show_auto_pwm, store_auto_pwm, 0, 4);
2931SENSOR_TEMPLATE_2(pwm_auto_point5_temp, "pwm%d_auto_point5_temp",
2932 S_IWUSR | S_IRUGO, show_auto_temp, store_auto_temp, 0, 4);
2933
2934SENSOR_TEMPLATE_2(pwm_auto_point6_pwm, "pwm%d_auto_point6_pwm",
2935 S_IWUSR | S_IRUGO, show_auto_pwm, store_auto_pwm, 0, 5);
2936SENSOR_TEMPLATE_2(pwm_auto_point6_temp, "pwm%d_auto_point6_temp",
2937 S_IWUSR | S_IRUGO, show_auto_temp, store_auto_temp, 0, 5);
2938
2939SENSOR_TEMPLATE_2(pwm_auto_point7_pwm, "pwm%d_auto_point7_pwm",
2940 S_IWUSR | S_IRUGO, show_auto_pwm, store_auto_pwm, 0, 6);
2941SENSOR_TEMPLATE_2(pwm_auto_point7_temp, "pwm%d_auto_point7_temp",
2942 S_IWUSR | S_IRUGO, show_auto_temp, store_auto_temp, 0, 6);
2943
cdcaeceb 2944/*
f73cf632
GR
2945 * nct6775_pwm_is_visible uses the index into the following array
2946 * to determine if attributes should be created or not.
2947 * Any change in order or content must be matched.
cdcaeceb 2948 */
f73cf632
GR
2949static struct sensor_device_template *nct6775_attributes_pwm_template[] = {
2950 &sensor_dev_template_pwm,
2951 &sensor_dev_template_pwm_mode,
2952 &sensor_dev_template_pwm_enable,
2953 &sensor_dev_template_pwm_temp_sel,
2954 &sensor_dev_template_pwm_temp_tolerance,
2955 &sensor_dev_template_pwm_crit_temp_tolerance,
2956 &sensor_dev_template_pwm_target_temp,
2957 &sensor_dev_template_fan_target,
2958 &sensor_dev_template_fan_tolerance,
2959 &sensor_dev_template_pwm_stop_time,
2960 &sensor_dev_template_pwm_step_up_time,
2961 &sensor_dev_template_pwm_step_down_time,
2962 &sensor_dev_template_pwm_start,
2963 &sensor_dev_template_pwm_floor,
2964 &sensor_dev_template_pwm_weight_temp_sel,
2965 &sensor_dev_template_pwm_weight_temp_step,
2966 &sensor_dev_template_pwm_weight_temp_step_tol,
2967 &sensor_dev_template_pwm_weight_temp_step_base,
2968 &sensor_dev_template_pwm_weight_duty_step,
2969 &sensor_dev_template_pwm_max, /* 19 */
2970 &sensor_dev_template_pwm_step, /* 20 */
2971 &sensor_dev_template_pwm_weight_duty_base, /* 21 */
2972 &sensor_dev_template_pwm_auto_point1_pwm, /* 22 */
2973 &sensor_dev_template_pwm_auto_point1_temp,
2974 &sensor_dev_template_pwm_auto_point2_pwm,
2975 &sensor_dev_template_pwm_auto_point2_temp,
2976 &sensor_dev_template_pwm_auto_point3_pwm,
2977 &sensor_dev_template_pwm_auto_point3_temp,
2978 &sensor_dev_template_pwm_auto_point4_pwm,
2979 &sensor_dev_template_pwm_auto_point4_temp,
2980 &sensor_dev_template_pwm_auto_point5_pwm,
2981 &sensor_dev_template_pwm_auto_point5_temp,
2982 &sensor_dev_template_pwm_auto_point6_pwm,
2983 &sensor_dev_template_pwm_auto_point6_temp,
2984 &sensor_dev_template_pwm_auto_point7_pwm,
2985 &sensor_dev_template_pwm_auto_point7_temp, /* 35 */
2986
2987 NULL
2988};
2989
2990static struct sensor_template_group nct6775_pwm_template_group = {
2991 .templates = nct6775_attributes_pwm_template,
2992 .is_visible = nct6775_pwm_is_visible,
2993 .base = 1,
cdcaeceb
GR
2994};
2995
9de2e2e8
GR
2996static ssize_t
2997show_vid(struct device *dev, struct device_attribute *attr, char *buf)
2998{
2999 struct nct6775_data *data = dev_get_drvdata(dev);
3000 return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm));
3001}
3002
3003static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL);
3004
a6bd5878
GR
3005/* Case open detection */
3006
3007static ssize_t
3008clear_caseopen(struct device *dev, struct device_attribute *attr,
3009 const char *buf, size_t count)
3010{
3011 struct nct6775_data *data = dev_get_drvdata(dev);
a6bd5878
GR
3012 int nr = to_sensor_dev_attr(attr)->index - INTRUSION_ALARM_BASE;
3013 unsigned long val;
3014 u8 reg;
3015 int ret;
3016
3017 if (kstrtoul(buf, 10, &val) || val != 0)
3018 return -EINVAL;
3019
3020 mutex_lock(&data->update_lock);
3021
3022 /*
3023 * Use CR registers to clear caseopen status.
3024 * The CR registers are the same for all chips, and not all chips
3025 * support clearing the caseopen status through "regular" registers.
3026 */
df612d5f 3027 ret = superio_enter(data->sioreg);
a6bd5878
GR
3028 if (ret) {
3029 count = ret;
3030 goto error;
3031 }
3032
df612d5f
GR
3033 superio_select(data->sioreg, NCT6775_LD_ACPI);
3034 reg = superio_inb(data->sioreg, NCT6775_REG_CR_CASEOPEN_CLR[nr]);
a6bd5878 3035 reg |= NCT6775_CR_CASEOPEN_CLR_MASK[nr];
df612d5f 3036 superio_outb(data->sioreg, NCT6775_REG_CR_CASEOPEN_CLR[nr], reg);
a6bd5878 3037 reg &= ~NCT6775_CR_CASEOPEN_CLR_MASK[nr];
df612d5f
GR
3038 superio_outb(data->sioreg, NCT6775_REG_CR_CASEOPEN_CLR[nr], reg);
3039 superio_exit(data->sioreg);
a6bd5878
GR
3040
3041 data->valid = false; /* Force cache refresh */
3042error:
3043 mutex_unlock(&data->update_lock);
3044 return count;
3045}
3046
f73cf632
GR
3047static SENSOR_DEVICE_ATTR(intrusion0_alarm, S_IWUSR | S_IRUGO, show_alarm,
3048 clear_caseopen, INTRUSION_ALARM_BASE);
3049static SENSOR_DEVICE_ATTR(intrusion1_alarm, S_IWUSR | S_IRUGO, show_alarm,
3050 clear_caseopen, INTRUSION_ALARM_BASE + 1);
30846993
GR
3051static SENSOR_DEVICE_ATTR(intrusion0_beep, S_IWUSR | S_IRUGO, show_beep,
3052 store_beep, INTRUSION_ALARM_BASE);
3053static SENSOR_DEVICE_ATTR(intrusion1_beep, S_IWUSR | S_IRUGO, show_beep,
3054 store_beep, INTRUSION_ALARM_BASE + 1);
3055static SENSOR_DEVICE_ATTR(beep_enable, S_IWUSR | S_IRUGO, show_beep,
3056 store_beep, BEEP_ENABLE_BASE);
9de2e2e8 3057
f73cf632
GR
3058static umode_t nct6775_other_is_visible(struct kobject *kobj,
3059 struct attribute *attr, int index)
9de2e2e8 3060{
f73cf632 3061 struct device *dev = container_of(kobj, struct device, kobj);
9de2e2e8
GR
3062 struct nct6775_data *data = dev_get_drvdata(dev);
3063
f73cf632
GR
3064 if (index == 1 && !data->have_vid)
3065 return 0;
77eb5b37 3066
f73cf632
GR
3067 if (index == 2 || index == 3) {
3068 if (data->ALARM_BITS[INTRUSION_ALARM_BASE + index - 2] < 0)
3069 return 0;
3070 }
cdcaeceb 3071
30846993
GR
3072 if (index == 4 || index == 5) {
3073 if (data->BEEP_BITS[INTRUSION_ALARM_BASE + index - 4] < 0)
3074 return 0;
3075 }
3076
f73cf632
GR
3077 return attr->mode;
3078}
cdcaeceb 3079
f73cf632
GR
3080/*
3081 * nct6775_other_is_visible uses the index into the following array
3082 * to determine if attributes should be created or not.
3083 * Any change in order or content must be matched.
3084 */
3085static struct attribute *nct6775_attributes_other[] = {
3086 &dev_attr_name.attr,
3087 &dev_attr_cpu0_vid.attr, /* 1 */
3088 &sensor_dev_attr_intrusion0_alarm.dev_attr.attr, /* 2 */
3089 &sensor_dev_attr_intrusion1_alarm.dev_attr.attr, /* 3 */
30846993
GR
3090 &sensor_dev_attr_intrusion0_beep.dev_attr.attr, /* 4 */
3091 &sensor_dev_attr_intrusion1_beep.dev_attr.attr, /* 5 */
3092 &sensor_dev_attr_beep_enable.dev_attr.attr, /* 6 */
bbd8decd 3093
f73cf632
GR
3094 NULL
3095};
cdcaeceb 3096
f73cf632
GR
3097static const struct attribute_group nct6775_group_other = {
3098 .attrs = nct6775_attributes_other,
3099 .is_visible = nct6775_other_is_visible,
3100};
9de2e2e8 3101
f73cf632
GR
3102/*
3103 * Driver and device management
3104 */
3105
3106static void nct6775_device_remove_files(struct device *dev)
3107{
3108 struct nct6775_data *data = dev_get_drvdata(dev);
aa136e5d 3109
f73cf632
GR
3110 if (data->group_pwm)
3111 sysfs_remove_group(&dev->kobj, data->group_pwm);
3112 if (data->group_in)
3113 sysfs_remove_group(&dev->kobj, data->group_in);
3114 if (data->group_fan)
3115 sysfs_remove_group(&dev->kobj, data->group_fan);
3116 if (data->group_temp)
3117 sysfs_remove_group(&dev->kobj, data->group_temp);
a6bd5878 3118
f73cf632 3119 sysfs_remove_group(&dev->kobj, &nct6775_group_other);
9de2e2e8
GR
3120}
3121
3122/* Get the monitoring functions started */
3123static inline void nct6775_init_device(struct nct6775_data *data)
3124{
aa136e5d
GR
3125 int i;
3126 u8 tmp, diode;
9de2e2e8
GR
3127
3128 /* Start monitoring if needed */
3129 if (data->REG_CONFIG) {
3130 tmp = nct6775_read_value(data, data->REG_CONFIG);
3131 if (!(tmp & 0x01))
3132 nct6775_write_value(data, data->REG_CONFIG, tmp | 0x01);
3133 }
3134
aa136e5d
GR
3135 /* Enable temperature sensors if needed */
3136 for (i = 0; i < NUM_TEMP; i++) {
3137 if (!(data->have_temp & (1 << i)))
3138 continue;
3139 if (!data->reg_temp_config[i])
3140 continue;
3141 tmp = nct6775_read_value(data, data->reg_temp_config[i]);
3142 if (tmp & 0x01)
3143 nct6775_write_value(data, data->reg_temp_config[i],
3144 tmp & 0xfe);
3145 }
3146
9de2e2e8
GR
3147 /* Enable VBAT monitoring if needed */
3148 tmp = nct6775_read_value(data, data->REG_VBAT);
3149 if (!(tmp & 0x01))
3150 nct6775_write_value(data, data->REG_VBAT, tmp | 0x01);
aa136e5d
GR
3151
3152 diode = nct6775_read_value(data, data->REG_DIODE);
3153
3154 for (i = 0; i < data->temp_fixed_num; i++) {
3155 if (!(data->have_temp_fixed & (1 << i)))
3156 continue;
6c009501
GR
3157 if ((tmp & (data->DIODE_MASK << i))) /* diode */
3158 data->temp_type[i]
3159 = 3 - ((diode >> i) & data->DIODE_MASK);
aa136e5d
GR
3160 else /* thermistor */
3161 data->temp_type[i] = 4;
3162 }
9de2e2e8
GR
3163}
3164
f73cf632 3165static void
df612d5f 3166nct6775_check_fan_inputs(struct nct6775_data *data)
1c65dc36 3167{
578ab5f0
DB
3168 bool fan3pin, fan4pin, fan4min, fan5pin, fan6pin;
3169 bool pwm3pin, pwm4pin, pwm5pin, pwm6pin;
df612d5f
GR
3170 int sioreg = data->sioreg;
3171 int regval;
1c65dc36
GR
3172
3173 /* fan4 and fan5 share some pins with the GPIO and serial flash */
3174 if (data->kind == nct6775) {
df612d5f 3175 regval = superio_inb(sioreg, 0x2c);
1c65dc36
GR
3176
3177 fan3pin = regval & (1 << 6);
77eb5b37 3178 pwm3pin = regval & (1 << 7);
1c65dc36
GR
3179
3180 /* On NCT6775, fan4 shares pins with the fdc interface */
df612d5f 3181 fan4pin = !(superio_inb(sioreg, 0x2A) & 0x80);
578ab5f0
DB
3182 fan4min = false;
3183 fan5pin = false;
3184 fan6pin = false;
3185 pwm4pin = false;
3186 pwm5pin = false;
3187 pwm6pin = false;
1c65dc36 3188 } else if (data->kind == nct6776) {
df612d5f 3189 bool gpok = superio_inb(sioreg, 0x27) & 0x80;
1c65dc36 3190
df612d5f
GR
3191 superio_select(sioreg, NCT6775_LD_HWM);
3192 regval = superio_inb(sioreg, SIO_REG_ENABLE);
1c65dc36
GR
3193
3194 if (regval & 0x80)
3195 fan3pin = gpok;
3196 else
df612d5f 3197 fan3pin = !(superio_inb(sioreg, 0x24) & 0x40);
1c65dc36
GR
3198
3199 if (regval & 0x40)
3200 fan4pin = gpok;
3201 else
df612d5f 3202 fan4pin = superio_inb(sioreg, 0x1C) & 0x01;
1c65dc36
GR
3203
3204 if (regval & 0x20)
3205 fan5pin = gpok;
3206 else
df612d5f 3207 fan5pin = superio_inb(sioreg, 0x1C) & 0x02;
1c65dc36
GR
3208
3209 fan4min = fan4pin;
578ab5f0 3210 fan6pin = false;
77eb5b37 3211 pwm3pin = fan3pin;
578ab5f0
DB
3212 pwm4pin = false;
3213 pwm5pin = false;
3214 pwm6pin = false;
6c009501 3215 } else if (data->kind == nct6106) {
df612d5f 3216 regval = superio_inb(sioreg, 0x24);
6c009501
GR
3217 fan3pin = !(regval & 0x80);
3218 pwm3pin = regval & 0x08;
6c009501
GR
3219
3220 fan4pin = false;
3221 fan4min = false;
3222 fan5pin = false;
578ab5f0 3223 fan6pin = false;
6c009501
GR
3224 pwm4pin = false;
3225 pwm5pin = false;
578ab5f0
DB
3226 pwm6pin = false;
3227 } else { /* NCT6779D or NCT6791D */
df612d5f 3228 regval = superio_inb(sioreg, 0x1c);
1c65dc36
GR
3229
3230 fan3pin = !(regval & (1 << 5));
3231 fan4pin = !(regval & (1 << 6));
3232 fan5pin = !(regval & (1 << 7));
3233
77eb5b37
GR
3234 pwm3pin = !(regval & (1 << 0));
3235 pwm4pin = !(regval & (1 << 1));
3236 pwm5pin = !(regval & (1 << 2));
3237
1c65dc36 3238 fan4min = fan4pin;
1c65dc36 3239
578ab5f0 3240 if (data->kind == nct6791) {
df612d5f 3241 regval = superio_inb(sioreg, 0x2d);
578ab5f0
DB
3242 fan6pin = (regval & (1 << 1));
3243 pwm6pin = (regval & (1 << 0));
3244 } else { /* NCT6779D */
3245 fan6pin = false;
3246 pwm6pin = false;
3247 }
3248 }
1c65dc36 3249
578ab5f0
DB
3250 /* fan 1 and 2 (0x03) are always present */
3251 data->has_fan = 0x03 | (fan3pin << 2) | (fan4pin << 3) |
3252 (fan5pin << 4) | (fan6pin << 5);
3253 data->has_fan_min = 0x03 | (fan3pin << 2) | (fan4min << 3) |
3254 (fan5pin << 4);
3255 data->has_pwm = 0x03 | (pwm3pin << 2) | (pwm4pin << 3) |
3256 (pwm5pin << 4) | (pwm6pin << 5);
1c65dc36
GR
3257}
3258
8e9285b0
GR
3259static void add_temp_sensors(struct nct6775_data *data, const u16 *regp,
3260 int *available, int *mask)
3261{
3262 int i;
3263 u8 src;
3264
3265 for (i = 0; i < data->pwm_num && *available; i++) {
3266 int index;
3267
3268 if (!regp[i])
3269 continue;
3270 src = nct6775_read_value(data, regp[i]);
3271 src &= 0x1f;
3272 if (!src || (*mask & (1 << src)))
3273 continue;
3274 if (src >= data->temp_label_num ||
3275 !strlen(data->temp_label[src]))
3276 continue;
3277
3278 index = __ffs(*available);
3279 nct6775_write_value(data, data->REG_TEMP_SOURCE[index], src);
3280 *available &= ~(1 << index);
3281 *mask |= 1 << src;
3282 }
3283}
3284
9de2e2e8
GR
3285static int nct6775_probe(struct platform_device *pdev)
3286{
3287 struct device *dev = &pdev->dev;
a8b3a3a5 3288 struct nct6775_sio_data *sio_data = dev_get_platdata(dev);
9de2e2e8
GR
3289 struct nct6775_data *data;
3290 struct resource *res;
aa136e5d
GR
3291 int i, s, err = 0;
3292 int src, mask, available;
3293 const u16 *reg_temp, *reg_temp_over, *reg_temp_hyst, *reg_temp_config;
3294 const u16 *reg_temp_alternate, *reg_temp_crit;
b7a61353 3295 const u16 *reg_temp_crit_l = NULL, *reg_temp_crit_h = NULL;
aa136e5d 3296 int num_reg_temp;
0fc1f8fc 3297 u8 cr2a;
f73cf632 3298 struct attribute_group *group;
9de2e2e8
GR
3299
3300 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
3301 if (!devm_request_region(&pdev->dev, res->start, IOREGION_LENGTH,
3302 DRVNAME))
3303 return -EBUSY;
3304
3305 data = devm_kzalloc(&pdev->dev, sizeof(struct nct6775_data),
3306 GFP_KERNEL);
3307 if (!data)
3308 return -ENOMEM;
3309
3310 data->kind = sio_data->kind;
df612d5f 3311 data->sioreg = sio_data->sioreg;
9de2e2e8 3312 data->addr = res->start;
9de2e2e8
GR
3313 mutex_init(&data->update_lock);
3314 data->name = nct6775_device_names[data->kind];
3315 data->bank = 0xff; /* Force initial bank selection */
3316 platform_set_drvdata(pdev, data);
3317
3318 switch (data->kind) {
6c009501
GR
3319 case nct6106:
3320 data->in_num = 9;
3321 data->pwm_num = 3;
3322 data->auto_pwm_num = 4;
3323 data->temp_fixed_num = 3;
3324 data->num_temp_alarms = 6;
30846993 3325 data->num_temp_beeps = 6;
6c009501
GR
3326
3327 data->fan_from_reg = fan_from_reg13;
3328 data->fan_from_reg_min = fan_from_reg13;
3329
3330 data->temp_label = nct6776_temp_label;
3331 data->temp_label_num = ARRAY_SIZE(nct6776_temp_label);
3332
3333 data->REG_VBAT = NCT6106_REG_VBAT;
3334 data->REG_DIODE = NCT6106_REG_DIODE;
3335 data->DIODE_MASK = NCT6106_DIODE_MASK;
3336 data->REG_VIN = NCT6106_REG_IN;
3337 data->REG_IN_MINMAX[0] = NCT6106_REG_IN_MIN;
3338 data->REG_IN_MINMAX[1] = NCT6106_REG_IN_MAX;
3339 data->REG_TARGET = NCT6106_REG_TARGET;
3340 data->REG_FAN = NCT6106_REG_FAN;
3341 data->REG_FAN_MODE = NCT6106_REG_FAN_MODE;
3342 data->REG_FAN_MIN = NCT6106_REG_FAN_MIN;
3343 data->REG_FAN_PULSES = NCT6106_REG_FAN_PULSES;
3344 data->FAN_PULSE_SHIFT = NCT6106_FAN_PULSE_SHIFT;
3345 data->REG_FAN_TIME[0] = NCT6106_REG_FAN_STOP_TIME;
3346 data->REG_FAN_TIME[1] = NCT6106_REG_FAN_STEP_UP_TIME;
3347 data->REG_FAN_TIME[2] = NCT6106_REG_FAN_STEP_DOWN_TIME;
3348 data->REG_PWM[0] = NCT6106_REG_PWM;
3349 data->REG_PWM[1] = NCT6106_REG_FAN_START_OUTPUT;
3350 data->REG_PWM[2] = NCT6106_REG_FAN_STOP_OUTPUT;
3351 data->REG_PWM[5] = NCT6106_REG_WEIGHT_DUTY_STEP;
3352 data->REG_PWM[6] = NCT6106_REG_WEIGHT_DUTY_BASE;
3353 data->REG_PWM_READ = NCT6106_REG_PWM_READ;
3354 data->REG_PWM_MODE = NCT6106_REG_PWM_MODE;
3355 data->PWM_MODE_MASK = NCT6106_PWM_MODE_MASK;
3356 data->REG_AUTO_TEMP = NCT6106_REG_AUTO_TEMP;
3357 data->REG_AUTO_PWM = NCT6106_REG_AUTO_PWM;
3358 data->REG_CRITICAL_TEMP = NCT6106_REG_CRITICAL_TEMP;
3359 data->REG_CRITICAL_TEMP_TOLERANCE
3360 = NCT6106_REG_CRITICAL_TEMP_TOLERANCE;
3361 data->REG_CRITICAL_PWM_ENABLE = NCT6106_REG_CRITICAL_PWM_ENABLE;
3362 data->CRITICAL_PWM_ENABLE_MASK
3363 = NCT6106_CRITICAL_PWM_ENABLE_MASK;
3364 data->REG_CRITICAL_PWM = NCT6106_REG_CRITICAL_PWM;
3365 data->REG_TEMP_OFFSET = NCT6106_REG_TEMP_OFFSET;
3366 data->REG_TEMP_SOURCE = NCT6106_REG_TEMP_SOURCE;
3367 data->REG_TEMP_SEL = NCT6106_REG_TEMP_SEL;
3368 data->REG_WEIGHT_TEMP_SEL = NCT6106_REG_WEIGHT_TEMP_SEL;
3369 data->REG_WEIGHT_TEMP[0] = NCT6106_REG_WEIGHT_TEMP_STEP;
3370 data->REG_WEIGHT_TEMP[1] = NCT6106_REG_WEIGHT_TEMP_STEP_TOL;
3371 data->REG_WEIGHT_TEMP[2] = NCT6106_REG_WEIGHT_TEMP_BASE;
3372 data->REG_ALARM = NCT6106_REG_ALARM;
3373 data->ALARM_BITS = NCT6106_ALARM_BITS;
30846993
GR
3374 data->REG_BEEP = NCT6106_REG_BEEP;
3375 data->BEEP_BITS = NCT6106_BEEP_BITS;
6c009501
GR
3376
3377 reg_temp = NCT6106_REG_TEMP;
3378 num_reg_temp = ARRAY_SIZE(NCT6106_REG_TEMP);
3379 reg_temp_over = NCT6106_REG_TEMP_OVER;
3380 reg_temp_hyst = NCT6106_REG_TEMP_HYST;
3381 reg_temp_config = NCT6106_REG_TEMP_CONFIG;
3382 reg_temp_alternate = NCT6106_REG_TEMP_ALTERNATE;
3383 reg_temp_crit = NCT6106_REG_TEMP_CRIT;
b7a61353
GR
3384 reg_temp_crit_l = NCT6106_REG_TEMP_CRIT_L;
3385 reg_temp_crit_h = NCT6106_REG_TEMP_CRIT_H;
6c009501
GR
3386
3387 break;
9de2e2e8
GR
3388 case nct6775:
3389 data->in_num = 9;
77eb5b37 3390 data->pwm_num = 3;
cdcaeceb 3391 data->auto_pwm_num = 6;
1c65dc36 3392 data->has_fan_div = true;
aa136e5d 3393 data->temp_fixed_num = 3;
b1d2bff6 3394 data->num_temp_alarms = 3;
30846993 3395 data->num_temp_beeps = 3;
9de2e2e8
GR
3396
3397 data->ALARM_BITS = NCT6775_ALARM_BITS;
30846993 3398 data->BEEP_BITS = NCT6775_BEEP_BITS;
9de2e2e8 3399
1c65dc36
GR
3400 data->fan_from_reg = fan_from_reg16;
3401 data->fan_from_reg_min = fan_from_reg8;
cdcaeceb
GR
3402 data->target_temp_mask = 0x7f;
3403 data->tolerance_mask = 0x0f;
3404 data->speed_tolerance_limit = 15;
1c65dc36 3405
aa136e5d
GR
3406 data->temp_label = nct6775_temp_label;
3407 data->temp_label_num = ARRAY_SIZE(nct6775_temp_label);
3408
9de2e2e8
GR
3409 data->REG_CONFIG = NCT6775_REG_CONFIG;
3410 data->REG_VBAT = NCT6775_REG_VBAT;
aa136e5d 3411 data->REG_DIODE = NCT6775_REG_DIODE;
6c009501 3412 data->DIODE_MASK = NCT6775_DIODE_MASK;
9de2e2e8
GR
3413 data->REG_VIN = NCT6775_REG_IN;
3414 data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN;
3415 data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX;
cdcaeceb 3416 data->REG_TARGET = NCT6775_REG_TARGET;
1c65dc36 3417 data->REG_FAN = NCT6775_REG_FAN;
77eb5b37 3418 data->REG_FAN_MODE = NCT6775_REG_FAN_MODE;
1c65dc36 3419 data->REG_FAN_MIN = NCT6775_REG_FAN_MIN;
5c25d954 3420 data->REG_FAN_PULSES = NCT6775_REG_FAN_PULSES;
6c009501 3421 data->FAN_PULSE_SHIFT = NCT6775_FAN_PULSE_SHIFT;
cdcaeceb
GR
3422 data->REG_FAN_TIME[0] = NCT6775_REG_FAN_STOP_TIME;
3423 data->REG_FAN_TIME[1] = NCT6775_REG_FAN_STEP_UP_TIME;
3424 data->REG_FAN_TIME[2] = NCT6775_REG_FAN_STEP_DOWN_TIME;
77eb5b37 3425 data->REG_PWM[0] = NCT6775_REG_PWM;
cdcaeceb
GR
3426 data->REG_PWM[1] = NCT6775_REG_FAN_START_OUTPUT;
3427 data->REG_PWM[2] = NCT6775_REG_FAN_STOP_OUTPUT;
3428 data->REG_PWM[3] = NCT6775_REG_FAN_MAX_OUTPUT;
3429 data->REG_PWM[4] = NCT6775_REG_FAN_STEP_OUTPUT;
bbd8decd 3430 data->REG_PWM[5] = NCT6775_REG_WEIGHT_DUTY_STEP;
77eb5b37
GR
3431 data->REG_PWM_READ = NCT6775_REG_PWM_READ;
3432 data->REG_PWM_MODE = NCT6775_REG_PWM_MODE;
3433 data->PWM_MODE_MASK = NCT6775_PWM_MODE_MASK;
cdcaeceb
GR
3434 data->REG_AUTO_TEMP = NCT6775_REG_AUTO_TEMP;
3435 data->REG_AUTO_PWM = NCT6775_REG_AUTO_PWM;
3436 data->REG_CRITICAL_TEMP = NCT6775_REG_CRITICAL_TEMP;
3437 data->REG_CRITICAL_TEMP_TOLERANCE
3438 = NCT6775_REG_CRITICAL_TEMP_TOLERANCE;
aa136e5d
GR
3439 data->REG_TEMP_OFFSET = NCT6775_REG_TEMP_OFFSET;
3440 data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE;
cdcaeceb 3441 data->REG_TEMP_SEL = NCT6775_REG_TEMP_SEL;
bbd8decd
GR
3442 data->REG_WEIGHT_TEMP_SEL = NCT6775_REG_WEIGHT_TEMP_SEL;
3443 data->REG_WEIGHT_TEMP[0] = NCT6775_REG_WEIGHT_TEMP_STEP;
3444 data->REG_WEIGHT_TEMP[1] = NCT6775_REG_WEIGHT_TEMP_STEP_TOL;
3445 data->REG_WEIGHT_TEMP[2] = NCT6775_REG_WEIGHT_TEMP_BASE;
9de2e2e8 3446 data->REG_ALARM = NCT6775_REG_ALARM;
30846993 3447 data->REG_BEEP = NCT6775_REG_BEEP;
aa136e5d
GR
3448
3449 reg_temp = NCT6775_REG_TEMP;
3450 num_reg_temp = ARRAY_SIZE(NCT6775_REG_TEMP);
3451 reg_temp_over = NCT6775_REG_TEMP_OVER;
3452 reg_temp_hyst = NCT6775_REG_TEMP_HYST;
3453 reg_temp_config = NCT6775_REG_TEMP_CONFIG;
3454 reg_temp_alternate = NCT6775_REG_TEMP_ALTERNATE;
3455 reg_temp_crit = NCT6775_REG_TEMP_CRIT;
3456
9de2e2e8
GR
3457 break;
3458 case nct6776:
3459 data->in_num = 9;
77eb5b37 3460 data->pwm_num = 3;
cdcaeceb 3461 data->auto_pwm_num = 4;
1c65dc36 3462 data->has_fan_div = false;
aa136e5d 3463 data->temp_fixed_num = 3;
b1d2bff6 3464 data->num_temp_alarms = 3;
30846993 3465 data->num_temp_beeps = 6;
9de2e2e8
GR
3466
3467 data->ALARM_BITS = NCT6776_ALARM_BITS;
30846993 3468 data->BEEP_BITS = NCT6776_BEEP_BITS;
9de2e2e8 3469
1c65dc36
GR
3470 data->fan_from_reg = fan_from_reg13;
3471 data->fan_from_reg_min = fan_from_reg13;
cdcaeceb
GR
3472 data->target_temp_mask = 0xff;
3473 data->tolerance_mask = 0x07;
3474 data->speed_tolerance_limit = 63;
1c65dc36 3475
aa136e5d
GR
3476 data->temp_label = nct6776_temp_label;
3477 data->temp_label_num = ARRAY_SIZE(nct6776_temp_label);
3478
9de2e2e8
GR
3479 data->REG_CONFIG = NCT6775_REG_CONFIG;
3480 data->REG_VBAT = NCT6775_REG_VBAT;
aa136e5d 3481 data->REG_DIODE = NCT6775_REG_DIODE;
6c009501 3482 data->DIODE_MASK = NCT6775_DIODE_MASK;
9de2e2e8
GR
3483 data->REG_VIN = NCT6775_REG_IN;
3484 data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN;
3485 data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX;
cdcaeceb 3486 data->REG_TARGET = NCT6775_REG_TARGET;
1c65dc36 3487 data->REG_FAN = NCT6775_REG_FAN;
77eb5b37 3488 data->REG_FAN_MODE = NCT6775_REG_FAN_MODE;
1c65dc36 3489 data->REG_FAN_MIN = NCT6776_REG_FAN_MIN;
5c25d954 3490 data->REG_FAN_PULSES = NCT6776_REG_FAN_PULSES;
6c009501 3491 data->FAN_PULSE_SHIFT = NCT6775_FAN_PULSE_SHIFT;
cdcaeceb
GR
3492 data->REG_FAN_TIME[0] = NCT6775_REG_FAN_STOP_TIME;
3493 data->REG_FAN_TIME[1] = NCT6775_REG_FAN_STEP_UP_TIME;
3494 data->REG_FAN_TIME[2] = NCT6775_REG_FAN_STEP_DOWN_TIME;
3495 data->REG_TOLERANCE_H = NCT6776_REG_TOLERANCE_H;
77eb5b37 3496 data->REG_PWM[0] = NCT6775_REG_PWM;
cdcaeceb
GR
3497 data->REG_PWM[1] = NCT6775_REG_FAN_START_OUTPUT;
3498 data->REG_PWM[2] = NCT6775_REG_FAN_STOP_OUTPUT;
bbd8decd
GR
3499 data->REG_PWM[5] = NCT6775_REG_WEIGHT_DUTY_STEP;
3500 data->REG_PWM[6] = NCT6776_REG_WEIGHT_DUTY_BASE;
77eb5b37
GR
3501 data->REG_PWM_READ = NCT6775_REG_PWM_READ;
3502 data->REG_PWM_MODE = NCT6776_REG_PWM_MODE;
3503 data->PWM_MODE_MASK = NCT6776_PWM_MODE_MASK;
cdcaeceb
GR
3504 data->REG_AUTO_TEMP = NCT6775_REG_AUTO_TEMP;
3505 data->REG_AUTO_PWM = NCT6775_REG_AUTO_PWM;
3506 data->REG_CRITICAL_TEMP = NCT6775_REG_CRITICAL_TEMP;
3507 data->REG_CRITICAL_TEMP_TOLERANCE
3508 = NCT6775_REG_CRITICAL_TEMP_TOLERANCE;
aa136e5d
GR
3509 data->REG_TEMP_OFFSET = NCT6775_REG_TEMP_OFFSET;
3510 data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE;
cdcaeceb 3511 data->REG_TEMP_SEL = NCT6775_REG_TEMP_SEL;
bbd8decd
GR
3512 data->REG_WEIGHT_TEMP_SEL = NCT6775_REG_WEIGHT_TEMP_SEL;
3513 data->REG_WEIGHT_TEMP[0] = NCT6775_REG_WEIGHT_TEMP_STEP;
3514 data->REG_WEIGHT_TEMP[1] = NCT6775_REG_WEIGHT_TEMP_STEP_TOL;
3515 data->REG_WEIGHT_TEMP[2] = NCT6775_REG_WEIGHT_TEMP_BASE;
9de2e2e8 3516 data->REG_ALARM = NCT6775_REG_ALARM;
30846993 3517 data->REG_BEEP = NCT6776_REG_BEEP;
aa136e5d
GR
3518
3519 reg_temp = NCT6775_REG_TEMP;
3520 num_reg_temp = ARRAY_SIZE(NCT6775_REG_TEMP);
3521 reg_temp_over = NCT6775_REG_TEMP_OVER;
3522 reg_temp_hyst = NCT6775_REG_TEMP_HYST;
3523 reg_temp_config = NCT6776_REG_TEMP_CONFIG;
3524 reg_temp_alternate = NCT6776_REG_TEMP_ALTERNATE;
3525 reg_temp_crit = NCT6776_REG_TEMP_CRIT;
3526
9de2e2e8
GR
3527 break;
3528 case nct6779:
3529 data->in_num = 15;
77eb5b37 3530 data->pwm_num = 5;
cdcaeceb 3531 data->auto_pwm_num = 4;
1c65dc36 3532 data->has_fan_div = false;
aa136e5d 3533 data->temp_fixed_num = 6;
b1d2bff6 3534 data->num_temp_alarms = 2;
30846993 3535 data->num_temp_beeps = 2;
9de2e2e8
GR
3536
3537 data->ALARM_BITS = NCT6779_ALARM_BITS;
30846993 3538 data->BEEP_BITS = NCT6779_BEEP_BITS;
9de2e2e8 3539
1c65dc36
GR
3540 data->fan_from_reg = fan_from_reg13;
3541 data->fan_from_reg_min = fan_from_reg13;
cdcaeceb
GR
3542 data->target_temp_mask = 0xff;
3543 data->tolerance_mask = 0x07;
3544 data->speed_tolerance_limit = 63;
1c65dc36 3545
aa136e5d
GR
3546 data->temp_label = nct6779_temp_label;
3547 data->temp_label_num = ARRAY_SIZE(nct6779_temp_label);
3548
9de2e2e8
GR
3549 data->REG_CONFIG = NCT6775_REG_CONFIG;
3550 data->REG_VBAT = NCT6775_REG_VBAT;
aa136e5d 3551 data->REG_DIODE = NCT6775_REG_DIODE;
6c009501 3552 data->DIODE_MASK = NCT6775_DIODE_MASK;
9de2e2e8
GR
3553 data->REG_VIN = NCT6779_REG_IN;
3554 data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN;
3555 data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX;
cdcaeceb 3556 data->REG_TARGET = NCT6775_REG_TARGET;
1c65dc36 3557 data->REG_FAN = NCT6779_REG_FAN;
77eb5b37 3558 data->REG_FAN_MODE = NCT6775_REG_FAN_MODE;
1c65dc36 3559 data->REG_FAN_MIN = NCT6776_REG_FAN_MIN;
5c25d954 3560 data->REG_FAN_PULSES = NCT6779_REG_FAN_PULSES;
6c009501 3561 data->FAN_PULSE_SHIFT = NCT6775_FAN_PULSE_SHIFT;
cdcaeceb
GR
3562 data->REG_FAN_TIME[0] = NCT6775_REG_FAN_STOP_TIME;
3563 data->REG_FAN_TIME[1] = NCT6775_REG_FAN_STEP_UP_TIME;
3564 data->REG_FAN_TIME[2] = NCT6775_REG_FAN_STEP_DOWN_TIME;
3565 data->REG_TOLERANCE_H = NCT6776_REG_TOLERANCE_H;
77eb5b37 3566 data->REG_PWM[0] = NCT6775_REG_PWM;
cdcaeceb
GR
3567 data->REG_PWM[1] = NCT6775_REG_FAN_START_OUTPUT;
3568 data->REG_PWM[2] = NCT6775_REG_FAN_STOP_OUTPUT;
bbd8decd
GR
3569 data->REG_PWM[5] = NCT6775_REG_WEIGHT_DUTY_STEP;
3570 data->REG_PWM[6] = NCT6776_REG_WEIGHT_DUTY_BASE;
77eb5b37
GR
3571 data->REG_PWM_READ = NCT6775_REG_PWM_READ;
3572 data->REG_PWM_MODE = NCT6776_REG_PWM_MODE;
3573 data->PWM_MODE_MASK = NCT6776_PWM_MODE_MASK;
cdcaeceb
GR
3574 data->REG_AUTO_TEMP = NCT6775_REG_AUTO_TEMP;
3575 data->REG_AUTO_PWM = NCT6775_REG_AUTO_PWM;
3576 data->REG_CRITICAL_TEMP = NCT6775_REG_CRITICAL_TEMP;
3577 data->REG_CRITICAL_TEMP_TOLERANCE
3578 = NCT6775_REG_CRITICAL_TEMP_TOLERANCE;
6c009501
GR
3579 data->REG_CRITICAL_PWM_ENABLE = NCT6779_REG_CRITICAL_PWM_ENABLE;
3580 data->CRITICAL_PWM_ENABLE_MASK
3581 = NCT6779_CRITICAL_PWM_ENABLE_MASK;
3582 data->REG_CRITICAL_PWM = NCT6779_REG_CRITICAL_PWM;
aa136e5d
GR
3583 data->REG_TEMP_OFFSET = NCT6779_REG_TEMP_OFFSET;
3584 data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE;
cdcaeceb 3585 data->REG_TEMP_SEL = NCT6775_REG_TEMP_SEL;
bbd8decd
GR
3586 data->REG_WEIGHT_TEMP_SEL = NCT6775_REG_WEIGHT_TEMP_SEL;
3587 data->REG_WEIGHT_TEMP[0] = NCT6775_REG_WEIGHT_TEMP_STEP;
3588 data->REG_WEIGHT_TEMP[1] = NCT6775_REG_WEIGHT_TEMP_STEP_TOL;
3589 data->REG_WEIGHT_TEMP[2] = NCT6775_REG_WEIGHT_TEMP_BASE;
9de2e2e8 3590 data->REG_ALARM = NCT6779_REG_ALARM;
30846993 3591 data->REG_BEEP = NCT6776_REG_BEEP;
aa136e5d
GR
3592
3593 reg_temp = NCT6779_REG_TEMP;
3594 num_reg_temp = ARRAY_SIZE(NCT6779_REG_TEMP);
3595 reg_temp_over = NCT6779_REG_TEMP_OVER;
3596 reg_temp_hyst = NCT6779_REG_TEMP_HYST;
3597 reg_temp_config = NCT6779_REG_TEMP_CONFIG;
3598 reg_temp_alternate = NCT6779_REG_TEMP_ALTERNATE;
3599 reg_temp_crit = NCT6779_REG_TEMP_CRIT;
3600
578ab5f0
DB
3601 break;
3602 case nct6791:
3603 data->in_num = 15;
3604 data->pwm_num = 6;
3605 data->auto_pwm_num = 4;
3606 data->has_fan_div = false;
3607 data->temp_fixed_num = 6;
3608 data->num_temp_alarms = 2;
3609 data->num_temp_beeps = 2;
3610
3611 data->ALARM_BITS = NCT6791_ALARM_BITS;
3612 data->BEEP_BITS = NCT6779_BEEP_BITS;
3613
3614 data->fan_from_reg = fan_from_reg13;
3615 data->fan_from_reg_min = fan_from_reg13;
3616 data->target_temp_mask = 0xff;
3617 data->tolerance_mask = 0x07;
3618 data->speed_tolerance_limit = 63;
3619
3620 data->temp_label = nct6779_temp_label;
3621 data->temp_label_num = ARRAY_SIZE(nct6779_temp_label);
3622
3623 data->REG_CONFIG = NCT6775_REG_CONFIG;
3624 data->REG_VBAT = NCT6775_REG_VBAT;
3625 data->REG_DIODE = NCT6775_REG_DIODE;
3626 data->DIODE_MASK = NCT6775_DIODE_MASK;
3627 data->REG_VIN = NCT6779_REG_IN;
3628 data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN;
3629 data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX;
3630 data->REG_TARGET = NCT6775_REG_TARGET;
3631 data->REG_FAN = NCT6779_REG_FAN;
3632 data->REG_FAN_MODE = NCT6775_REG_FAN_MODE;
3633 data->REG_FAN_MIN = NCT6776_REG_FAN_MIN;
3634 data->REG_FAN_PULSES = NCT6779_REG_FAN_PULSES;
3635 data->FAN_PULSE_SHIFT = NCT6775_FAN_PULSE_SHIFT;
3636 data->REG_FAN_TIME[0] = NCT6775_REG_FAN_STOP_TIME;
3637 data->REG_FAN_TIME[1] = NCT6775_REG_FAN_STEP_UP_TIME;
3638 data->REG_FAN_TIME[2] = NCT6775_REG_FAN_STEP_DOWN_TIME;
3639 data->REG_TOLERANCE_H = NCT6776_REG_TOLERANCE_H;
3640 data->REG_PWM[0] = NCT6775_REG_PWM;
3641 data->REG_PWM[1] = NCT6775_REG_FAN_START_OUTPUT;
3642 data->REG_PWM[2] = NCT6775_REG_FAN_STOP_OUTPUT;
3643 data->REG_PWM[5] = NCT6775_REG_WEIGHT_DUTY_STEP;
3644 data->REG_PWM[6] = NCT6776_REG_WEIGHT_DUTY_BASE;
3645 data->REG_PWM_READ = NCT6775_REG_PWM_READ;
3646 data->REG_PWM_MODE = NCT6776_REG_PWM_MODE;
3647 data->PWM_MODE_MASK = NCT6776_PWM_MODE_MASK;
3648 data->REG_AUTO_TEMP = NCT6775_REG_AUTO_TEMP;
3649 data->REG_AUTO_PWM = NCT6775_REG_AUTO_PWM;
3650 data->REG_CRITICAL_TEMP = NCT6775_REG_CRITICAL_TEMP;
3651 data->REG_CRITICAL_TEMP_TOLERANCE
3652 = NCT6775_REG_CRITICAL_TEMP_TOLERANCE;
3653 data->REG_CRITICAL_PWM_ENABLE = NCT6779_REG_CRITICAL_PWM_ENABLE;
3654 data->CRITICAL_PWM_ENABLE_MASK
3655 = NCT6779_CRITICAL_PWM_ENABLE_MASK;
3656 data->REG_CRITICAL_PWM = NCT6779_REG_CRITICAL_PWM;
3657 data->REG_TEMP_OFFSET = NCT6779_REG_TEMP_OFFSET;
3658 data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE;
3659 data->REG_TEMP_SEL = NCT6775_REG_TEMP_SEL;
3660 data->REG_WEIGHT_TEMP_SEL = NCT6775_REG_WEIGHT_TEMP_SEL;
3661 data->REG_WEIGHT_TEMP[0] = NCT6775_REG_WEIGHT_TEMP_STEP;
3662 data->REG_WEIGHT_TEMP[1] = NCT6775_REG_WEIGHT_TEMP_STEP_TOL;
3663 data->REG_WEIGHT_TEMP[2] = NCT6775_REG_WEIGHT_TEMP_BASE;
3664 data->REG_ALARM = NCT6791_REG_ALARM;
3665 data->REG_BEEP = NCT6776_REG_BEEP;
3666
3667 reg_temp = NCT6779_REG_TEMP;
3668 num_reg_temp = ARRAY_SIZE(NCT6779_REG_TEMP);
3669 reg_temp_over = NCT6779_REG_TEMP_OVER;
3670 reg_temp_hyst = NCT6779_REG_TEMP_HYST;
3671 reg_temp_config = NCT6779_REG_TEMP_CONFIG;
3672 reg_temp_alternate = NCT6779_REG_TEMP_ALTERNATE;
3673 reg_temp_crit = NCT6779_REG_TEMP_CRIT;
3674
9de2e2e8
GR
3675 break;
3676 default:
3677 return -ENODEV;
3678 }
3679 data->have_in = (1 << data->in_num) - 1;
aa136e5d
GR
3680 data->have_temp = 0;
3681
3682 /*
3683 * On some boards, not all available temperature sources are monitored,
3684 * even though some of the monitoring registers are unused.
3685 * Get list of unused monitoring registers, then detect if any fan
3686 * controls are configured to use unmonitored temperature sources.
3687 * If so, assign the unmonitored temperature sources to available
3688 * monitoring registers.
3689 */
3690 mask = 0;
3691 available = 0;
3692 for (i = 0; i < num_reg_temp; i++) {
3693 if (reg_temp[i] == 0)
3694 continue;
3695
3696 src = nct6775_read_value(data, data->REG_TEMP_SOURCE[i]) & 0x1f;
3697 if (!src || (mask & (1 << src)))
3698 available |= 1 << i;
3699
3700 mask |= 1 << src;
3701 }
3702
8e9285b0
GR
3703 /*
3704 * Now find unmonitored temperature registers and enable monitoring
3705 * if additional monitoring registers are available.
3706 */
3707 add_temp_sensors(data, data->REG_TEMP_SEL, &available, &mask);
3708 add_temp_sensors(data, data->REG_WEIGHT_TEMP_SEL, &available, &mask);
3709
aa136e5d
GR
3710 mask = 0;
3711 s = NUM_TEMP_FIXED; /* First dynamic temperature attribute */
3712 for (i = 0; i < num_reg_temp; i++) {
3713 if (reg_temp[i] == 0)
3714 continue;
3715
3716 src = nct6775_read_value(data, data->REG_TEMP_SOURCE[i]) & 0x1f;
3717 if (!src || (mask & (1 << src)))
3718 continue;
3719
3720 if (src >= data->temp_label_num ||
3721 !strlen(data->temp_label[src])) {
3722 dev_info(dev,
3723 "Invalid temperature source %d at index %d, source register 0x%x, temp register 0x%x\n",
3724 src, i, data->REG_TEMP_SOURCE[i], reg_temp[i]);
3725 continue;
3726 }
3727
3728 mask |= 1 << src;
3729
3730 /* Use fixed index for SYSTIN(1), CPUTIN(2), AUXTIN(3) */
3731 if (src <= data->temp_fixed_num) {
3732 data->have_temp |= 1 << (src - 1);
3733 data->have_temp_fixed |= 1 << (src - 1);
3734 data->reg_temp[0][src - 1] = reg_temp[i];
3735 data->reg_temp[1][src - 1] = reg_temp_over[i];
3736 data->reg_temp[2][src - 1] = reg_temp_hyst[i];
b7a61353
GR
3737 if (reg_temp_crit_h && reg_temp_crit_h[i])
3738 data->reg_temp[3][src - 1] = reg_temp_crit_h[i];
3739 else if (reg_temp_crit[src - 1])
3740 data->reg_temp[3][src - 1]
3741 = reg_temp_crit[src - 1];
3742 if (reg_temp_crit_l && reg_temp_crit_l[i])
3743 data->reg_temp[4][src - 1] = reg_temp_crit_l[i];
aa136e5d
GR
3744 data->reg_temp_config[src - 1] = reg_temp_config[i];
3745 data->temp_src[src - 1] = src;
3746 continue;
3747 }
3748
3749 if (s >= NUM_TEMP)
3750 continue;
3751
3752 /* Use dynamic index for other sources */
3753 data->have_temp |= 1 << s;
3754 data->reg_temp[0][s] = reg_temp[i];
3755 data->reg_temp[1][s] = reg_temp_over[i];
3756 data->reg_temp[2][s] = reg_temp_hyst[i];
3757 data->reg_temp_config[s] = reg_temp_config[i];
b7a61353
GR
3758 if (reg_temp_crit_h && reg_temp_crit_h[i])
3759 data->reg_temp[3][s] = reg_temp_crit_h[i];
3760 else if (reg_temp_crit[src - 1])
aa136e5d 3761 data->reg_temp[3][s] = reg_temp_crit[src - 1];
b7a61353
GR
3762 if (reg_temp_crit_l && reg_temp_crit_l[i])
3763 data->reg_temp[4][s] = reg_temp_crit_l[i];
aa136e5d
GR
3764
3765 data->temp_src[s] = src;
3766 s++;
3767 }
3768
3769#ifdef USE_ALTERNATE
3770 /*
3771 * Go through the list of alternate temp registers and enable
3772 * if possible.
3773 * The temperature is already monitored if the respective bit in <mask>
3774 * is set.
3775 */
3776 for (i = 0; i < data->temp_label_num - 1; i++) {
3777 if (!reg_temp_alternate[i])
3778 continue;
3779 if (mask & (1 << (i + 1)))
3780 continue;
3781 if (i < data->temp_fixed_num) {
3782 if (data->have_temp & (1 << i))
3783 continue;
3784 data->have_temp |= 1 << i;
3785 data->have_temp_fixed |= 1 << i;
3786 data->reg_temp[0][i] = reg_temp_alternate[i];
169c05cd
GR
3787 if (i < num_reg_temp) {
3788 data->reg_temp[1][i] = reg_temp_over[i];
3789 data->reg_temp[2][i] = reg_temp_hyst[i];
3790 }
aa136e5d
GR
3791 data->temp_src[i] = i + 1;
3792 continue;
3793 }
3794
3795 if (s >= NUM_TEMP) /* Abort if no more space */
3796 break;
3797
3798 data->have_temp |= 1 << s;
3799 data->reg_temp[0][s] = reg_temp_alternate[i];
3800 data->temp_src[s] = i + 1;
3801 s++;
3802 }
3803#endif /* USE_ALTERNATE */
3804
9de2e2e8
GR
3805 /* Initialize the chip */
3806 nct6775_init_device(data);
3807
9de2e2e8
GR
3808 err = superio_enter(sio_data->sioreg);
3809 if (err)
3810 return err;
3811
0fc1f8fc
GR
3812 cr2a = superio_inb(sio_data->sioreg, 0x2a);
3813 switch (data->kind) {
3814 case nct6775:
f73cf632 3815 data->have_vid = (cr2a & 0x40);
0fc1f8fc
GR
3816 break;
3817 case nct6776:
f73cf632 3818 data->have_vid = (cr2a & 0x60) == 0x40;
0fc1f8fc 3819 break;
6c009501 3820 case nct6106:
0fc1f8fc 3821 case nct6779:
578ab5f0 3822 case nct6791:
0fc1f8fc
GR
3823 break;
3824 }
3825
9de2e2e8
GR
3826 /*
3827 * Read VID value
3828 * We can get the VID input values directly at logical device D 0xe3.
3829 */
f73cf632 3830 if (data->have_vid) {
0fc1f8fc
GR
3831 superio_select(sio_data->sioreg, NCT6775_LD_VID);
3832 data->vid = superio_inb(sio_data->sioreg, 0xe3);
3833 data->vrm = vid_which_vrm();
3834 }
47ece964
GR
3835
3836 if (fan_debounce) {
3837 u8 tmp;
3838
3839 superio_select(sio_data->sioreg, NCT6775_LD_HWM);
3840 tmp = superio_inb(sio_data->sioreg,
3841 NCT6775_REG_CR_FAN_DEBOUNCE);
3842 switch (data->kind) {
6c009501
GR
3843 case nct6106:
3844 tmp |= 0xe0;
3845 break;
47ece964
GR
3846 case nct6775:
3847 tmp |= 0x1e;
3848 break;
3849 case nct6776:
3850 case nct6779:
3851 tmp |= 0x3e;
3852 break;
578ab5f0
DB
3853 case nct6791:
3854 tmp |= 0x7e;
3855 break;
47ece964
GR
3856 }
3857 superio_outb(sio_data->sioreg, NCT6775_REG_CR_FAN_DEBOUNCE,
3858 tmp);
3859 dev_info(&pdev->dev, "Enabled fan debounce for chip %s\n",
3860 data->name);
3861 }
3862
df612d5f 3863 nct6775_check_fan_inputs(data);
9de2e2e8 3864
f73cf632 3865 superio_exit(sio_data->sioreg);
1c65dc36
GR
3866
3867 /* Read fan clock dividers immediately */
3868 nct6775_init_fan_common(dev, data);
3869
77eb5b37 3870 /* Register sysfs hooks */
f73cf632
GR
3871 group = nct6775_create_attr_group(dev, &nct6775_pwm_template_group,
3872 data->pwm_num);
3873 if (IS_ERR(group)) {
3874 err = PTR_ERR(group);
3875 goto exit_remove;
9de2e2e8 3876 }
f73cf632 3877 data->group_pwm = group;
9de2e2e8 3878
f73cf632
GR
3879 group = nct6775_create_attr_group(dev, &nct6775_in_template_group,
3880 fls(data->have_in));
3881 if (IS_ERR(group)) {
3882 err = PTR_ERR(group);
3883 goto exit_remove;
1c65dc36 3884 }
f73cf632 3885 data->group_in = group;
1c65dc36 3886
f73cf632
GR
3887 group = nct6775_create_attr_group(dev, &nct6775_fan_template_group,
3888 fls(data->has_fan));
3889 if (IS_ERR(group)) {
3890 err = PTR_ERR(group);
3891 goto exit_remove;
aa136e5d 3892 }
f73cf632 3893 data->group_fan = group;
aa136e5d 3894
f73cf632
GR
3895 group = nct6775_create_attr_group(dev, &nct6775_temp_template_group,
3896 fls(data->have_temp));
3897 if (IS_ERR(group)) {
3898 err = PTR_ERR(group);
3899 goto exit_remove;
a6bd5878 3900 }
f73cf632 3901 data->group_temp = group;
a6bd5878 3902
f73cf632 3903 err = sysfs_create_group(&dev->kobj, &nct6775_group_other);
9de2e2e8
GR
3904 if (err)
3905 goto exit_remove;
3906
3907 data->hwmon_dev = hwmon_device_register(dev);
3908 if (IS_ERR(data->hwmon_dev)) {
3909 err = PTR_ERR(data->hwmon_dev);
3910 goto exit_remove;
3911 }
3912
3913 return 0;
3914
3915exit_remove:
3916 nct6775_device_remove_files(dev);
3917 return err;
3918}
3919
3920static int nct6775_remove(struct platform_device *pdev)
3921{
3922 struct nct6775_data *data = platform_get_drvdata(pdev);
3923
3924 hwmon_device_unregister(data->hwmon_dev);
3925 nct6775_device_remove_files(&pdev->dev);
3926
3927 return 0;
3928}
3929
84d19d92
GR
3930#ifdef CONFIG_PM
3931static int nct6775_suspend(struct device *dev)
3932{
3933 struct nct6775_data *data = nct6775_update_device(dev);
84d19d92
GR
3934
3935 mutex_lock(&data->update_lock);
3936 data->vbat = nct6775_read_value(data, data->REG_VBAT);
df612d5f 3937 if (data->kind == nct6775) {
84d19d92
GR
3938 data->fandiv1 = nct6775_read_value(data, NCT6775_REG_FANDIV1);
3939 data->fandiv2 = nct6775_read_value(data, NCT6775_REG_FANDIV2);
3940 }
3941 mutex_unlock(&data->update_lock);
3942
3943 return 0;
3944}
3945
3946static int nct6775_resume(struct device *dev)
3947{
3948 struct nct6775_data *data = dev_get_drvdata(dev);
84d19d92
GR
3949 int i, j;
3950
3951 mutex_lock(&data->update_lock);
3952 data->bank = 0xff; /* Force initial bank selection */
3953
3954 /* Restore limits */
3955 for (i = 0; i < data->in_num; i++) {
3956 if (!(data->have_in & (1 << i)))
3957 continue;
3958
3959 nct6775_write_value(data, data->REG_IN_MINMAX[0][i],
3960 data->in[i][1]);
3961 nct6775_write_value(data, data->REG_IN_MINMAX[1][i],
3962 data->in[i][2]);
3963 }
3964
c409fd43 3965 for (i = 0; i < ARRAY_SIZE(data->fan_min); i++) {
84d19d92
GR
3966 if (!(data->has_fan_min & (1 << i)))
3967 continue;
3968
3969 nct6775_write_value(data, data->REG_FAN_MIN[i],
3970 data->fan_min[i]);
3971 }
3972
3973 for (i = 0; i < NUM_TEMP; i++) {
3974 if (!(data->have_temp & (1 << i)))
3975 continue;
3976
c409fd43 3977 for (j = 1; j < ARRAY_SIZE(data->reg_temp); j++)
84d19d92
GR
3978 if (data->reg_temp[j][i])
3979 nct6775_write_temp(data, data->reg_temp[j][i],
3980 data->temp[j][i]);
3981 }
3982
3983 /* Restore other settings */
3984 nct6775_write_value(data, data->REG_VBAT, data->vbat);
df612d5f 3985 if (data->kind == nct6775) {
84d19d92
GR
3986 nct6775_write_value(data, NCT6775_REG_FANDIV1, data->fandiv1);
3987 nct6775_write_value(data, NCT6775_REG_FANDIV2, data->fandiv2);
3988 }
3989
3990 /* Force re-reading all values */
3991 data->valid = false;
3992 mutex_unlock(&data->update_lock);
3993
3994 return 0;
3995}
3996
3997static const struct dev_pm_ops nct6775_dev_pm_ops = {
3998 .suspend = nct6775_suspend,
3999 .resume = nct6775_resume,
374d1f98
HJ
4000 .freeze = nct6775_suspend,
4001 .restore = nct6775_resume,
84d19d92
GR
4002};
4003
4004#define NCT6775_DEV_PM_OPS (&nct6775_dev_pm_ops)
4005#else
4006#define NCT6775_DEV_PM_OPS NULL
4007#endif /* CONFIG_PM */
4008
9de2e2e8
GR
4009static struct platform_driver nct6775_driver = {
4010 .driver = {
4011 .owner = THIS_MODULE,
4012 .name = DRVNAME,
84d19d92 4013 .pm = NCT6775_DEV_PM_OPS,
9de2e2e8
GR
4014 },
4015 .probe = nct6775_probe,
4016 .remove = nct6775_remove,
4017};
4018
6d4b3621 4019static const char * const nct6775_sio_names[] __initconst = {
6c009501 4020 "NCT6106D",
2c7fd30d
GR
4021 "NCT6775F",
4022 "NCT6776D/F",
4023 "NCT6779D",
578ab5f0 4024 "NCT6791D",
2c7fd30d
GR
4025};
4026
9de2e2e8 4027/* nct6775_find() looks for a '627 in the Super-I/O config space */
698a7c24 4028static int __init nct6775_find(int sioaddr, struct nct6775_sio_data *sio_data)
9de2e2e8 4029{
9de2e2e8 4030 u16 val;
9de2e2e8 4031 int err;
698a7c24 4032 int addr;
9de2e2e8
GR
4033
4034 err = superio_enter(sioaddr);
4035 if (err)
4036 return err;
4037
4038 if (force_id)
4039 val = force_id;
4040 else
4041 val = (superio_inb(sioaddr, SIO_REG_DEVID) << 8)
4042 | superio_inb(sioaddr, SIO_REG_DEVID + 1);
4043 switch (val & SIO_ID_MASK) {
6c009501
GR
4044 case SIO_NCT6106_ID:
4045 sio_data->kind = nct6106;
4046 break;
9de2e2e8
GR
4047 case SIO_NCT6775_ID:
4048 sio_data->kind = nct6775;
9de2e2e8
GR
4049 break;
4050 case SIO_NCT6776_ID:
4051 sio_data->kind = nct6776;
9de2e2e8
GR
4052 break;
4053 case SIO_NCT6779_ID:
4054 sio_data->kind = nct6779;
9de2e2e8 4055 break;
578ab5f0
DB
4056 case SIO_NCT6791_ID:
4057 sio_data->kind = nct6791;
4058 break;
9de2e2e8
GR
4059 default:
4060 if (val != 0xffff)
4061 pr_debug("unsupported chip ID: 0x%04x\n", val);
4062 superio_exit(sioaddr);
4063 return -ENODEV;
4064 }
4065
4066 /* We have a known chip, find the HWM I/O address */
4067 superio_select(sioaddr, NCT6775_LD_HWM);
4068 val = (superio_inb(sioaddr, SIO_REG_ADDR) << 8)
4069 | superio_inb(sioaddr, SIO_REG_ADDR + 1);
698a7c24
GR
4070 addr = val & IOREGION_ALIGNMENT;
4071 if (addr == 0) {
9de2e2e8
GR
4072 pr_err("Refusing to enable a Super-I/O device with a base I/O port 0\n");
4073 superio_exit(sioaddr);
4074 return -ENODEV;
4075 }
4076
4077 /* Activate logical device if needed */
4078 val = superio_inb(sioaddr, SIO_REG_ENABLE);
4079 if (!(val & 0x01)) {
4080 pr_warn("Forcibly enabling Super-I/O. Sensor is probably unusable.\n");
4081 superio_outb(sioaddr, SIO_REG_ENABLE, val | 0x01);
4082 }
578ab5f0
DB
4083 if (sio_data->kind == nct6791) {
4084 val = superio_inb(sioaddr, NCT6791_REG_HM_IO_SPACE_LOCK_ENABLE);
4085 if (val & 0x10) {
4086 pr_info("Enabling hardware monitor logical device mappings.\n");
4087 superio_outb(sioaddr,
4088 NCT6791_REG_HM_IO_SPACE_LOCK_ENABLE,
4089 val & ~0x10);
4090 }
4091 }
9de2e2e8
GR
4092
4093 superio_exit(sioaddr);
698a7c24
GR
4094 pr_info("Found %s or compatible chip at %#x:%#x\n",
4095 nct6775_sio_names[sio_data->kind], sioaddr, addr);
9de2e2e8
GR
4096 sio_data->sioreg = sioaddr;
4097
698a7c24 4098 return addr;
9de2e2e8
GR
4099}
4100
4101/*
4102 * when Super-I/O functions move to a separate file, the Super-I/O
4103 * bus will manage the lifetime of the device and this module will only keep
4104 * track of the nct6775 driver. But since we platform_device_alloc(), we
4105 * must keep track of the device
4106 */
698a7c24 4107static struct platform_device *pdev[2];
9de2e2e8
GR
4108
4109static int __init sensors_nct6775_init(void)
4110{
698a7c24
GR
4111 int i, err;
4112 bool found = false;
4113 int address;
9de2e2e8
GR
4114 struct resource res;
4115 struct nct6775_sio_data sio_data;
698a7c24
GR
4116 int sioaddr[2] = { 0x2e, 0x4e };
4117
4118 err = platform_driver_register(&nct6775_driver);
4119 if (err)
4120 return err;
9de2e2e8
GR
4121
4122 /*
4123 * initialize sio_data->kind and sio_data->sioreg.
4124 *
4125 * when Super-I/O functions move to a separate file, the Super-I/O
4126 * driver will probe 0x2e and 0x4e and auto-detect the presence of a
4127 * nct6775 hardware monitor, and call probe()
4128 */
698a7c24
GR
4129 for (i = 0; i < ARRAY_SIZE(pdev); i++) {
4130 address = nct6775_find(sioaddr[i], &sio_data);
4131 if (address <= 0)
4132 continue;
9de2e2e8 4133
698a7c24 4134 found = true;
9de2e2e8 4135
698a7c24
GR
4136 pdev[i] = platform_device_alloc(DRVNAME, address);
4137 if (!pdev[i]) {
4138 err = -ENOMEM;
4139 goto exit_device_put;
4140 }
9de2e2e8 4141
698a7c24
GR
4142 err = platform_device_add_data(pdev[i], &sio_data,
4143 sizeof(struct nct6775_sio_data));
4144 if (err)
4145 goto exit_device_put;
4146
4147 memset(&res, 0, sizeof(res));
4148 res.name = DRVNAME;
4149 res.start = address + IOREGION_OFFSET;
4150 res.end = address + IOREGION_OFFSET + IOREGION_LENGTH - 1;
4151 res.flags = IORESOURCE_IO;
4152
4153 err = acpi_check_resource_conflict(&res);
4154 if (err) {
4155 platform_device_put(pdev[i]);
4156 pdev[i] = NULL;
4157 continue;
4158 }
9de2e2e8 4159
698a7c24
GR
4160 err = platform_device_add_resources(pdev[i], &res, 1);
4161 if (err)
4162 goto exit_device_put;
9de2e2e8 4163
698a7c24
GR
4164 /* platform_device_add calls probe() */
4165 err = platform_device_add(pdev[i]);
4166 if (err)
4167 goto exit_device_put;
9de2e2e8 4168 }
698a7c24
GR
4169 if (!found) {
4170 err = -ENODEV;
4171 goto exit_unregister;
9de2e2e8
GR
4172 }
4173
4174 return 0;
4175
4176exit_device_put:
698a7c24
GR
4177 for (i = 0; i < ARRAY_SIZE(pdev); i++) {
4178 if (pdev[i])
4179 platform_device_put(pdev[i]);
4180 }
9de2e2e8
GR
4181exit_unregister:
4182 platform_driver_unregister(&nct6775_driver);
9de2e2e8
GR
4183 return err;
4184}
4185
4186static void __exit sensors_nct6775_exit(void)
4187{
698a7c24
GR
4188 int i;
4189
4190 for (i = 0; i < ARRAY_SIZE(pdev); i++) {
4191 if (pdev[i])
4192 platform_device_unregister(pdev[i]);
4193 }
9de2e2e8
GR
4194 platform_driver_unregister(&nct6775_driver);
4195}
4196
4197MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>");
4198MODULE_DESCRIPTION("NCT6775F/NCT6776F/NCT6779D driver");
4199MODULE_LICENSE("GPL");
4200
4201module_init(sensors_nct6775_init);
4202module_exit(sensors_nct6775_exit);
This page took 0.399857 seconds and 5 git commands to generate.