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