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