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