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