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