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