blob: 778772d6bddaaa2a9f4f54b550c53682f83c7fed [file] [log] [blame]
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07001/*
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
36 * nct6775f 9 4 3 6+3 0xb470 0xc1 0x5ca3
37 * nct6776f 9 5 3 6+3 0xc330 0xc1 0x5ca3
38 * nct6779d 15 5 5 2+6 0xc560 0xc1 0x5ca3
39 *
40 * #temp lists the number of monitored temperature sources (first value) plus
41 * the number of directly connectable temperature sensors (second value).
42 */
43
44#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
45
46#include <linux/module.h>
47#include <linux/init.h>
48#include <linux/slab.h>
49#include <linux/jiffies.h>
50#include <linux/platform_device.h>
51#include <linux/hwmon.h>
52#include <linux/hwmon-sysfs.h>
53#include <linux/hwmon-vid.h>
54#include <linux/err.h>
55#include <linux/mutex.h>
56#include <linux/acpi.h>
57#include <linux/io.h>
58#include "lm75.h"
59
Guenter Roeckaa136e52012-12-04 03:26:05 -080060#define USE_ALTERNATE
61
Guenter Roeck9de2e2e2012-05-20 19:29:48 -070062enum kinds { nct6775, nct6776, nct6779 };
63
64/* used to set data->name = nct6775_device_names[data->sio_kind] */
65static const char * const nct6775_device_names[] = {
66 "nct6775",
67 "nct6776",
68 "nct6779",
69};
70
71static unsigned short force_id;
72module_param(force_id, ushort, 0);
73MODULE_PARM_DESC(force_id, "Override the detected device ID");
74
Guenter Roeck47ece962012-12-04 07:59:32 -080075static unsigned short fan_debounce;
76module_param(fan_debounce, ushort, 0);
77MODULE_PARM_DESC(fan_debounce, "Enable debouncing for fan RPM signal");
78
Guenter Roeck9de2e2e2012-05-20 19:29:48 -070079#define DRVNAME "nct6775"
80
81/*
82 * Super-I/O constants and functions
83 */
84
Guenter Roecka6bd5872012-12-04 03:13:34 -080085#define NCT6775_LD_ACPI 0x0a
Guenter Roeck9de2e2e2012-05-20 19:29:48 -070086#define NCT6775_LD_HWM 0x0b
87#define NCT6775_LD_VID 0x0d
88
89#define SIO_REG_LDSEL 0x07 /* Logical device select */
90#define SIO_REG_DEVID 0x20 /* Device ID (2 bytes) */
91#define SIO_REG_ENABLE 0x30 /* Logical device enable */
92#define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */
93
94#define SIO_NCT6775_ID 0xb470
95#define SIO_NCT6776_ID 0xc330
96#define SIO_NCT6779_ID 0xc560
97#define SIO_ID_MASK 0xFFF0
98
Guenter Roeck77eb5b32012-12-04 08:30:54 -080099enum pwm_enable { off, manual, thermal_cruise, speed_cruise, sf3, sf4 };
100
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700101static inline void
102superio_outb(int ioreg, int reg, int val)
103{
104 outb(reg, ioreg);
105 outb(val, ioreg + 1);
106}
107
108static inline int
109superio_inb(int ioreg, int reg)
110{
111 outb(reg, ioreg);
112 return inb(ioreg + 1);
113}
114
115static inline void
116superio_select(int ioreg, int ld)
117{
118 outb(SIO_REG_LDSEL, ioreg);
119 outb(ld, ioreg + 1);
120}
121
122static inline int
123superio_enter(int ioreg)
124{
125 /*
126 * Try to reserve <ioreg> and <ioreg + 1> for exclusive access.
127 */
128 if (!request_muxed_region(ioreg, 2, DRVNAME))
129 return -EBUSY;
130
131 outb(0x87, ioreg);
132 outb(0x87, ioreg);
133
134 return 0;
135}
136
137static inline void
138superio_exit(int ioreg)
139{
140 outb(0xaa, ioreg);
141 outb(0x02, ioreg);
142 outb(0x02, ioreg + 1);
143 release_region(ioreg, 2);
144}
145
146/*
147 * ISA constants
148 */
149
150#define IOREGION_ALIGNMENT (~7)
151#define IOREGION_OFFSET 5
152#define IOREGION_LENGTH 2
153#define ADDR_REG_OFFSET 0
154#define DATA_REG_OFFSET 1
155
156#define NCT6775_REG_BANK 0x4E
157#define NCT6775_REG_CONFIG 0x40
158
159/*
160 * Not currently used:
161 * REG_MAN_ID has the value 0x5ca3 for all supported chips.
162 * REG_CHIP_ID == 0x88/0xa1/0xc1 depending on chip model.
163 * REG_MAN_ID is at port 0x4f
164 * REG_CHIP_ID is at port 0x58
165 */
166
Guenter Roeckaa136e52012-12-04 03:26:05 -0800167#define NUM_TEMP 10 /* Max number of temp attribute sets w/ limits*/
168#define NUM_TEMP_FIXED 6 /* Max number of fixed temp attribute sets */
169
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700170#define NUM_REG_ALARM 4 /* Max number of alarm registers */
171
172/* Common and NCT6775 specific data */
173
174/* Voltage min/max registers for nr=7..14 are in bank 5 */
175
176static const u16 NCT6775_REG_IN_MAX[] = {
177 0x2b, 0x2d, 0x2f, 0x31, 0x33, 0x35, 0x37, 0x554, 0x556, 0x558, 0x55a,
178 0x55c, 0x55e, 0x560, 0x562 };
179static const u16 NCT6775_REG_IN_MIN[] = {
180 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x555, 0x557, 0x559, 0x55b,
181 0x55d, 0x55f, 0x561, 0x563 };
182static const u16 NCT6775_REG_IN[] = {
183 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x550, 0x551, 0x552
184};
185
186#define NCT6775_REG_VBAT 0x5D
Guenter Roeckaa136e52012-12-04 03:26:05 -0800187#define NCT6775_REG_DIODE 0x5E
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700188
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800189#define NCT6775_REG_FANDIV1 0x506
190#define NCT6775_REG_FANDIV2 0x507
191
Guenter Roeck47ece962012-12-04 07:59:32 -0800192#define NCT6775_REG_CR_FAN_DEBOUNCE 0xf0
193
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700194static const u16 NCT6775_REG_ALARM[NUM_REG_ALARM] = { 0x459, 0x45A, 0x45B };
195
196/* 0..15 voltages, 16..23 fans, 24..31 temperatures */
197
198static const s8 NCT6775_ALARM_BITS[] = {
199 0, 1, 2, 3, 8, 21, 20, 16, /* in0.. in7 */
200 17, -1, -1, -1, -1, -1, -1, /* in8..in14 */
201 -1, /* unused */
Guenter Roeck41fa9a92013-06-23 13:04:04 -0700202 6, 7, 11, -1, -1, /* fan1..fan5 */
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700203 -1, -1, -1, /* unused */
204 4, 5, 13, -1, -1, -1, /* temp1..temp6 */
205 12, -1 }; /* intrusion0, intrusion1 */
206
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800207#define FAN_ALARM_BASE 16
Guenter Roeckaa136e52012-12-04 03:26:05 -0800208#define TEMP_ALARM_BASE 24
Guenter Roecka6bd5872012-12-04 03:13:34 -0800209#define INTRUSION_ALARM_BASE 30
210
211static const u8 NCT6775_REG_CR_CASEOPEN_CLR[] = { 0xe6, 0xee };
212static const u8 NCT6775_CR_CASEOPEN_CLR_MASK[] = { 0x20, 0x01 };
213
Guenter Roeck77eb5b32012-12-04 08:30:54 -0800214/* DC or PWM output fan configuration */
215static const u8 NCT6775_REG_PWM_MODE[] = { 0x04, 0x04, 0x12 };
216static const u8 NCT6775_PWM_MODE_MASK[] = { 0x01, 0x02, 0x01 };
217
Guenter Roeckcdcaece2012-12-04 09:04:52 -0800218/* Advanced Fan control, some values are common for all fans */
Guenter Roeck77eb5b32012-12-04 08:30:54 -0800219
Guenter Roeckcdcaece2012-12-04 09:04:52 -0800220static const u16 NCT6775_REG_TARGET[] = { 0x101, 0x201, 0x301, 0x801, 0x901 };
221static const u16 NCT6775_REG_FAN_MODE[] = { 0x102, 0x202, 0x302, 0x802, 0x902 };
222static const u16 NCT6775_REG_FAN_STEP_DOWN_TIME[] = {
223 0x103, 0x203, 0x303, 0x803, 0x903 };
224static const u16 NCT6775_REG_FAN_STEP_UP_TIME[] = {
225 0x104, 0x204, 0x304, 0x804, 0x904 };
226static const u16 NCT6775_REG_FAN_STOP_OUTPUT[] = {
227 0x105, 0x205, 0x305, 0x805, 0x905 };
228static const u16 NCT6775_REG_FAN_START_OUTPUT[]
229 = { 0x106, 0x206, 0x306, 0x806, 0x906 };
230static const u16 NCT6775_REG_FAN_MAX_OUTPUT[] = { 0x10a, 0x20a, 0x30a };
231static const u16 NCT6775_REG_FAN_STEP_OUTPUT[] = { 0x10b, 0x20b, 0x30b };
232
233static const u16 NCT6775_REG_FAN_STOP_TIME[] = {
234 0x107, 0x207, 0x307, 0x807, 0x907 };
Guenter Roeck77eb5b32012-12-04 08:30:54 -0800235static const u16 NCT6775_REG_PWM[] = { 0x109, 0x209, 0x309, 0x809, 0x909 };
236static const u16 NCT6775_REG_PWM_READ[] = { 0x01, 0x03, 0x11, 0x13, 0x15 };
237
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800238static const u16 NCT6775_REG_FAN[] = { 0x630, 0x632, 0x634, 0x636, 0x638 };
239static const u16 NCT6775_REG_FAN_MIN[] = { 0x3b, 0x3c, 0x3d };
Guenter Roeck5c25d952012-12-11 07:29:06 -0800240static const u16 NCT6775_REG_FAN_PULSES[] = { 0x641, 0x642, 0x643, 0x644, 0 };
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800241
Guenter Roeckaa136e52012-12-04 03:26:05 -0800242static const u16 NCT6775_REG_TEMP[] = {
243 0x27, 0x150, 0x250, 0x62b, 0x62c, 0x62d };
244
245static const u16 NCT6775_REG_TEMP_CONFIG[ARRAY_SIZE(NCT6775_REG_TEMP)] = {
246 0, 0x152, 0x252, 0x628, 0x629, 0x62A };
247static const u16 NCT6775_REG_TEMP_HYST[ARRAY_SIZE(NCT6775_REG_TEMP)] = {
248 0x3a, 0x153, 0x253, 0x673, 0x678, 0x67D };
249static const u16 NCT6775_REG_TEMP_OVER[ARRAY_SIZE(NCT6775_REG_TEMP)] = {
250 0x39, 0x155, 0x255, 0x672, 0x677, 0x67C };
251
252static const u16 NCT6775_REG_TEMP_SOURCE[ARRAY_SIZE(NCT6775_REG_TEMP)] = {
253 0x621, 0x622, 0x623, 0x624, 0x625, 0x626 };
254
Guenter Roeckcdcaece2012-12-04 09:04:52 -0800255static const u16 NCT6775_REG_TEMP_SEL[] = {
256 0x100, 0x200, 0x300, 0x800, 0x900 };
257
Guenter Roeckbbd8dec2012-12-04 09:08:29 -0800258static const u16 NCT6775_REG_WEIGHT_TEMP_SEL[] = {
259 0x139, 0x239, 0x339, 0x839, 0x939 };
260static const u16 NCT6775_REG_WEIGHT_TEMP_STEP[] = {
261 0x13a, 0x23a, 0x33a, 0x83a, 0x93a };
262static const u16 NCT6775_REG_WEIGHT_TEMP_STEP_TOL[] = {
263 0x13b, 0x23b, 0x33b, 0x83b, 0x93b };
264static const u16 NCT6775_REG_WEIGHT_DUTY_STEP[] = {
265 0x13c, 0x23c, 0x33c, 0x83c, 0x93c };
266static const u16 NCT6775_REG_WEIGHT_TEMP_BASE[] = {
267 0x13d, 0x23d, 0x33d, 0x83d, 0x93d };
268
Guenter Roeckaa136e52012-12-04 03:26:05 -0800269static const u16 NCT6775_REG_TEMP_OFFSET[] = { 0x454, 0x455, 0x456 };
270
Guenter Roeckcdcaece2012-12-04 09:04:52 -0800271static const u16 NCT6775_REG_AUTO_TEMP[] = {
272 0x121, 0x221, 0x321, 0x821, 0x921 };
273static const u16 NCT6775_REG_AUTO_PWM[] = {
274 0x127, 0x227, 0x327, 0x827, 0x927 };
275
276#define NCT6775_AUTO_TEMP(data, nr, p) ((data)->REG_AUTO_TEMP[nr] + (p))
277#define NCT6775_AUTO_PWM(data, nr, p) ((data)->REG_AUTO_PWM[nr] + (p))
278
279static const u16 NCT6775_REG_CRITICAL_ENAB[] = { 0x134, 0x234, 0x334 };
280
281static const u16 NCT6775_REG_CRITICAL_TEMP[] = {
282 0x135, 0x235, 0x335, 0x835, 0x935 };
283static const u16 NCT6775_REG_CRITICAL_TEMP_TOLERANCE[] = {
284 0x138, 0x238, 0x338, 0x838, 0x938 };
285
Guenter Roeckaa136e52012-12-04 03:26:05 -0800286static const char *const nct6775_temp_label[] = {
287 "",
288 "SYSTIN",
289 "CPUTIN",
290 "AUXTIN",
291 "AMD SB-TSI",
292 "PECI Agent 0",
293 "PECI Agent 1",
294 "PECI Agent 2",
295 "PECI Agent 3",
296 "PECI Agent 4",
297 "PECI Agent 5",
298 "PECI Agent 6",
299 "PECI Agent 7",
300 "PCH_CHIP_CPU_MAX_TEMP",
301 "PCH_CHIP_TEMP",
302 "PCH_CPU_TEMP",
303 "PCH_MCH_TEMP",
304 "PCH_DIM0_TEMP",
305 "PCH_DIM1_TEMP",
306 "PCH_DIM2_TEMP",
307 "PCH_DIM3_TEMP"
308};
309
310static const u16 NCT6775_REG_TEMP_ALTERNATE[ARRAY_SIZE(nct6775_temp_label) - 1]
311 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x661, 0x662, 0x664 };
312
313static const u16 NCT6775_REG_TEMP_CRIT[ARRAY_SIZE(nct6775_temp_label) - 1]
314 = { 0, 0, 0, 0, 0xa00, 0xa01, 0xa02, 0xa03, 0xa04, 0xa05, 0xa06,
315 0xa07 };
316
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700317/* NCT6776 specific data */
318
319static const s8 NCT6776_ALARM_BITS[] = {
320 0, 1, 2, 3, 8, 21, 20, 16, /* in0.. in7 */
321 17, -1, -1, -1, -1, -1, -1, /* in8..in14 */
322 -1, /* unused */
323 6, 7, 11, 10, 23, /* fan1..fan5 */
324 -1, -1, -1, /* unused */
325 4, 5, 13, -1, -1, -1, /* temp1..temp6 */
326 12, 9 }; /* intrusion0, intrusion1 */
327
Guenter Roeckcdcaece2012-12-04 09:04:52 -0800328static const u16 NCT6776_REG_TOLERANCE_H[] = {
329 0x10c, 0x20c, 0x30c, 0x80c, 0x90c };
330
Guenter Roeck77eb5b32012-12-04 08:30:54 -0800331static const u8 NCT6776_REG_PWM_MODE[] = { 0x04, 0, 0 };
332static const u8 NCT6776_PWM_MODE_MASK[] = { 0x01, 0, 0 };
333
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800334static const u16 NCT6776_REG_FAN_MIN[] = { 0x63a, 0x63c, 0x63e, 0x640, 0x642 };
Guenter Roeck5c25d952012-12-11 07:29:06 -0800335static const u16 NCT6776_REG_FAN_PULSES[] = { 0x644, 0x645, 0x646, 0, 0 };
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800336
Guenter Roeckbbd8dec2012-12-04 09:08:29 -0800337static const u16 NCT6776_REG_WEIGHT_DUTY_BASE[] = {
338 0x13e, 0x23e, 0x33e, 0x83e, 0x93e };
339
Guenter Roeckaa136e52012-12-04 03:26:05 -0800340static const u16 NCT6776_REG_TEMP_CONFIG[ARRAY_SIZE(NCT6775_REG_TEMP)] = {
341 0x18, 0x152, 0x252, 0x628, 0x629, 0x62A };
342
343static const char *const nct6776_temp_label[] = {
344 "",
345 "SYSTIN",
346 "CPUTIN",
347 "AUXTIN",
348 "SMBUSMASTER 0",
349 "SMBUSMASTER 1",
350 "SMBUSMASTER 2",
351 "SMBUSMASTER 3",
352 "SMBUSMASTER 4",
353 "SMBUSMASTER 5",
354 "SMBUSMASTER 6",
355 "SMBUSMASTER 7",
356 "PECI Agent 0",
357 "PECI Agent 1",
358 "PCH_CHIP_CPU_MAX_TEMP",
359 "PCH_CHIP_TEMP",
360 "PCH_CPU_TEMP",
361 "PCH_MCH_TEMP",
362 "PCH_DIM0_TEMP",
363 "PCH_DIM1_TEMP",
364 "PCH_DIM2_TEMP",
365 "PCH_DIM3_TEMP",
366 "BYTE_TEMP"
367};
368
369static const u16 NCT6776_REG_TEMP_ALTERNATE[ARRAY_SIZE(nct6776_temp_label) - 1]
370 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x401, 0x402, 0x404 };
371
372static const u16 NCT6776_REG_TEMP_CRIT[ARRAY_SIZE(nct6776_temp_label) - 1]
373 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x709, 0x70a };
374
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700375/* NCT6779 specific data */
376
377static const u16 NCT6779_REG_IN[] = {
378 0x480, 0x481, 0x482, 0x483, 0x484, 0x485, 0x486, 0x487,
379 0x488, 0x489, 0x48a, 0x48b, 0x48c, 0x48d, 0x48e };
380
381static const u16 NCT6779_REG_ALARM[NUM_REG_ALARM] = {
382 0x459, 0x45A, 0x45B, 0x568 };
383
384static const s8 NCT6779_ALARM_BITS[] = {
385 0, 1, 2, 3, 8, 21, 20, 16, /* in0.. in7 */
386 17, 24, 25, 26, 27, 28, 29, /* in8..in14 */
387 -1, /* unused */
388 6, 7, 11, 10, 23, /* fan1..fan5 */
389 -1, -1, -1, /* unused */
390 4, 5, 13, -1, -1, -1, /* temp1..temp6 */
391 12, 9 }; /* intrusion0, intrusion1 */
392
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800393static const u16 NCT6779_REG_FAN[] = { 0x4b0, 0x4b2, 0x4b4, 0x4b6, 0x4b8 };
Guenter Roeck5c25d952012-12-11 07:29:06 -0800394static const u16 NCT6779_REG_FAN_PULSES[] = {
395 0x644, 0x645, 0x646, 0x647, 0x648 };
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800396
Guenter Roeckcdcaece2012-12-04 09:04:52 -0800397static const u16 NCT6779_REG_CRITICAL_PWM_ENABLE[] = {
398 0x136, 0x236, 0x336, 0x836, 0x936 };
399static const u16 NCT6779_REG_CRITICAL_PWM[] = {
400 0x137, 0x237, 0x337, 0x837, 0x937 };
401
Guenter Roeckaa136e52012-12-04 03:26:05 -0800402static const u16 NCT6779_REG_TEMP[] = { 0x27, 0x150 };
403static const u16 NCT6779_REG_TEMP_CONFIG[ARRAY_SIZE(NCT6779_REG_TEMP)] = {
404 0x18, 0x152 };
405static const u16 NCT6779_REG_TEMP_HYST[ARRAY_SIZE(NCT6779_REG_TEMP)] = {
406 0x3a, 0x153 };
407static const u16 NCT6779_REG_TEMP_OVER[ARRAY_SIZE(NCT6779_REG_TEMP)] = {
408 0x39, 0x155 };
409
410static const u16 NCT6779_REG_TEMP_OFFSET[] = {
411 0x454, 0x455, 0x456, 0x44a, 0x44b, 0x44c };
412
413static const char *const nct6779_temp_label[] = {
414 "",
415 "SYSTIN",
416 "CPUTIN",
417 "AUXTIN0",
418 "AUXTIN1",
419 "AUXTIN2",
420 "AUXTIN3",
421 "",
422 "SMBUSMASTER 0",
423 "SMBUSMASTER 1",
424 "SMBUSMASTER 2",
425 "SMBUSMASTER 3",
426 "SMBUSMASTER 4",
427 "SMBUSMASTER 5",
428 "SMBUSMASTER 6",
429 "SMBUSMASTER 7",
430 "PECI Agent 0",
431 "PECI Agent 1",
432 "PCH_CHIP_CPU_MAX_TEMP",
433 "PCH_CHIP_TEMP",
434 "PCH_CPU_TEMP",
435 "PCH_MCH_TEMP",
436 "PCH_DIM0_TEMP",
437 "PCH_DIM1_TEMP",
438 "PCH_DIM2_TEMP",
439 "PCH_DIM3_TEMP",
440 "BYTE_TEMP"
441};
442
443static const u16 NCT6779_REG_TEMP_ALTERNATE[ARRAY_SIZE(nct6779_temp_label) - 1]
444 = { 0x490, 0x491, 0x492, 0x493, 0x494, 0x495, 0, 0,
445 0, 0, 0, 0, 0, 0, 0, 0,
446 0, 0x400, 0x401, 0x402, 0x404, 0x405, 0x406, 0x407,
447 0x408, 0 };
448
449static const u16 NCT6779_REG_TEMP_CRIT[ARRAY_SIZE(nct6779_temp_label) - 1]
450 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x709, 0x70a };
451
Guenter Roeck77eb5b32012-12-04 08:30:54 -0800452static enum pwm_enable reg_to_pwm_enable(int pwm, int mode)
453{
454 if (mode == 0 && pwm == 255)
455 return off;
456 return mode + 1;
457}
458
459static int pwm_enable_to_reg(enum pwm_enable mode)
460{
461 if (mode == off)
462 return 0;
463 return mode - 1;
464}
465
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700466/*
467 * Conversions
468 */
469
Guenter Roeckcdcaece2012-12-04 09:04:52 -0800470/* 1 is DC mode, output in ms */
471static unsigned int step_time_from_reg(u8 reg, u8 mode)
472{
473 return mode ? 400 * reg : 100 * reg;
474}
475
476static u8 step_time_to_reg(unsigned int msec, u8 mode)
477{
478 return clamp_val((mode ? (msec + 200) / 400 :
479 (msec + 50) / 100), 1, 255);
480}
481
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800482static unsigned int fan_from_reg8(u16 reg, unsigned int divreg)
483{
484 if (reg == 0 || reg == 255)
485 return 0;
486 return 1350000U / (reg << divreg);
487}
488
489static unsigned int fan_from_reg13(u16 reg, unsigned int divreg)
490{
491 if ((reg & 0xff1f) == 0xff1f)
492 return 0;
493
494 reg = (reg & 0x1f) | ((reg & 0xff00) >> 3);
495
496 if (reg == 0)
497 return 0;
498
499 return 1350000U / reg;
500}
501
502static unsigned int fan_from_reg16(u16 reg, unsigned int divreg)
503{
504 if (reg == 0 || reg == 0xffff)
505 return 0;
506
507 /*
508 * Even though the registers are 16 bit wide, the fan divisor
509 * still applies.
510 */
511 return 1350000U / (reg << divreg);
512}
513
Guenter Roeckcdcaece2012-12-04 09:04:52 -0800514static u16 fan_to_reg(u32 fan, unsigned int divreg)
515{
516 if (!fan)
517 return 0;
518
519 return (1350000U / fan) >> divreg;
520}
521
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800522static inline unsigned int
523div_from_reg(u8 reg)
524{
525 return 1 << reg;
526}
527
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700528/*
529 * Some of the voltage inputs have internal scaling, the tables below
530 * contain 8 (the ADC LSB in mV) * scaling factor * 100
531 */
532static const u16 scale_in[15] = {
533 800, 800, 1600, 1600, 800, 800, 800, 1600, 1600, 800, 800, 800, 800,
534 800, 800
535};
536
537static inline long in_from_reg(u8 reg, u8 nr)
538{
539 return DIV_ROUND_CLOSEST(reg * scale_in[nr], 100);
540}
541
542static inline u8 in_to_reg(u32 val, u8 nr)
543{
544 return clamp_val(DIV_ROUND_CLOSEST(val * 100, scale_in[nr]), 0, 255);
545}
546
547/*
548 * Data structures and manipulation thereof
549 */
550
551struct nct6775_data {
552 int addr; /* IO base of hw monitor block */
553 enum kinds kind;
554 const char *name;
555
556 struct device *hwmon_dev;
Guenter Roeckf73cf632013-03-18 09:22:50 -0700557 struct attribute_group *group_in;
558 struct attribute_group *group_fan;
559 struct attribute_group *group_temp;
560 struct attribute_group *group_pwm;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700561
Guenter Roeckaa136e52012-12-04 03:26:05 -0800562 u16 reg_temp[4][NUM_TEMP]; /* 0=temp, 1=temp_over, 2=temp_hyst,
563 * 3=temp_crit
564 */
565 u8 temp_src[NUM_TEMP];
566 u16 reg_temp_config[NUM_TEMP];
567 const char * const *temp_label;
568 int temp_label_num;
569
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700570 u16 REG_CONFIG;
571 u16 REG_VBAT;
Guenter Roeckaa136e52012-12-04 03:26:05 -0800572 u16 REG_DIODE;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700573
574 const s8 *ALARM_BITS;
575
576 const u16 *REG_VIN;
577 const u16 *REG_IN_MINMAX[2];
578
Guenter Roeckcdcaece2012-12-04 09:04:52 -0800579 const u16 *REG_TARGET;
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800580 const u16 *REG_FAN;
Guenter Roeck77eb5b32012-12-04 08:30:54 -0800581 const u16 *REG_FAN_MODE;
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800582 const u16 *REG_FAN_MIN;
Guenter Roeck5c25d952012-12-11 07:29:06 -0800583 const u16 *REG_FAN_PULSES;
Guenter Roeckcdcaece2012-12-04 09:04:52 -0800584 const u16 *REG_FAN_TIME[3];
585
586 const u16 *REG_TOLERANCE_H;
Guenter Roeckaa136e52012-12-04 03:26:05 -0800587
Guenter Roeck77eb5b32012-12-04 08:30:54 -0800588 const u8 *REG_PWM_MODE;
589 const u8 *PWM_MODE_MASK;
590
Guenter Roeckbbd8dec2012-12-04 09:08:29 -0800591 const u16 *REG_PWM[7]; /* [0]=pwm, [1]=pwm_start, [2]=pwm_floor,
592 * [3]=pwm_max, [4]=pwm_step,
593 * [5]=weight_duty_step, [6]=weight_duty_base
Guenter Roeckcdcaece2012-12-04 09:04:52 -0800594 */
Guenter Roeck77eb5b32012-12-04 08:30:54 -0800595 const u16 *REG_PWM_READ;
596
Guenter Roeckcdcaece2012-12-04 09:04:52 -0800597 const u16 *REG_AUTO_TEMP;
598 const u16 *REG_AUTO_PWM;
599
600 const u16 *REG_CRITICAL_TEMP;
601 const u16 *REG_CRITICAL_TEMP_TOLERANCE;
602
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800603 const u16 *REG_TEMP_SOURCE; /* temp register sources */
Guenter Roeckcdcaece2012-12-04 09:04:52 -0800604 const u16 *REG_TEMP_SEL;
Guenter Roeckbbd8dec2012-12-04 09:08:29 -0800605 const u16 *REG_WEIGHT_TEMP_SEL;
606 const u16 *REG_WEIGHT_TEMP[3]; /* 0=base, 1=tolerance, 2=step */
607
Guenter Roeckaa136e52012-12-04 03:26:05 -0800608 const u16 *REG_TEMP_OFFSET;
609
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700610 const u16 *REG_ALARM;
611
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800612 unsigned int (*fan_from_reg)(u16 reg, unsigned int divreg);
613 unsigned int (*fan_from_reg_min)(u16 reg, unsigned int divreg);
614
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700615 struct mutex update_lock;
616 bool valid; /* true if following fields are valid */
617 unsigned long last_updated; /* In jiffies */
618
619 /* Register values */
620 u8 bank; /* current register bank */
621 u8 in_num; /* number of in inputs we have */
622 u8 in[15][3]; /* [0]=in, [1]=in_max, [2]=in_min */
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800623 unsigned int rpm[5];
624 u16 fan_min[5];
Guenter Roeck5c25d952012-12-11 07:29:06 -0800625 u8 fan_pulses[5];
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800626 u8 fan_div[5];
Guenter Roeck77eb5b32012-12-04 08:30:54 -0800627 u8 has_pwm;
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800628 u8 has_fan; /* some fan inputs can be disabled */
629 u8 has_fan_min; /* some fans don't have min register */
630 bool has_fan_div;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700631
Guenter Roeckb1d2bff2013-06-22 16:15:31 -0700632 u8 num_temp_alarms; /* 2 or 3 */
Guenter Roeckaa136e52012-12-04 03:26:05 -0800633 u8 temp_fixed_num; /* 3 or 6 */
634 u8 temp_type[NUM_TEMP_FIXED];
635 s8 temp_offset[NUM_TEMP_FIXED];
636 s16 temp[4][NUM_TEMP]; /* 0=temp, 1=temp_over, 2=temp_hyst,
637 * 3=temp_crit */
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700638 u64 alarms;
639
Guenter Roeck77eb5b32012-12-04 08:30:54 -0800640 u8 pwm_num; /* number of pwm */
641 u8 pwm_mode[5]; /* 1->DC variable voltage, 0->PWM variable duty cycle */
642 enum pwm_enable pwm_enable[5];
643 /* 0->off
644 * 1->manual
645 * 2->thermal cruise mode (also called SmartFan I)
646 * 3->fan speed cruise mode
647 * 4->SmartFan III
648 * 5->enhanced variable thermal cruise (SmartFan IV)
649 */
Guenter Roeckbbd8dec2012-12-04 09:08:29 -0800650 u8 pwm[7][5]; /* [0]=pwm, [1]=pwm_start, [2]=pwm_floor,
651 * [3]=pwm_max, [4]=pwm_step,
652 * [5]=weight_duty_step, [6]=weight_duty_base
Guenter Roeckcdcaece2012-12-04 09:04:52 -0800653 */
654
655 u8 target_temp[5];
656 u8 target_temp_mask;
657 u32 target_speed[5];
658 u32 target_speed_tolerance[5];
659 u8 speed_tolerance_limit;
660
661 u8 temp_tolerance[2][5];
662 u8 tolerance_mask;
663
664 u8 fan_time[3][5]; /* 0 = stop_time, 1 = step_up, 2 = step_down */
665
666 /* Automatic fan speed control registers */
667 int auto_pwm_num;
668 u8 auto_pwm[5][7];
669 u8 auto_temp[5][7];
670 u8 pwm_temp_sel[5];
Guenter Roeckbbd8dec2012-12-04 09:08:29 -0800671 u8 pwm_weight_temp_sel[5];
672 u8 weight_temp[3][5]; /* 0->temp_step, 1->temp_step_tol,
673 * 2->temp_base
674 */
Guenter Roeck77eb5b32012-12-04 08:30:54 -0800675
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700676 u8 vid;
677 u8 vrm;
678
Guenter Roeckf73cf632013-03-18 09:22:50 -0700679 bool have_vid;
680
Guenter Roeckaa136e52012-12-04 03:26:05 -0800681 u16 have_temp;
682 u16 have_temp_fixed;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700683 u16 have_in;
Guenter Roeck84d19d92012-12-04 08:01:39 -0800684#ifdef CONFIG_PM
685 /* Remember extra register values over suspend/resume */
686 u8 vbat;
687 u8 fandiv1;
688 u8 fandiv2;
689#endif
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700690};
691
692struct nct6775_sio_data {
693 int sioreg;
694 enum kinds kind;
695};
696
Guenter Roeckf73cf632013-03-18 09:22:50 -0700697struct sensor_device_template {
698 struct device_attribute dev_attr;
699 union {
700 struct {
701 u8 nr;
702 u8 index;
703 } s;
704 int index;
705 } u;
706 bool s2; /* true if both index and nr are used */
707};
708
709struct sensor_device_attr_u {
710 union {
711 struct sensor_device_attribute a1;
712 struct sensor_device_attribute_2 a2;
713 } u;
714 char name[32];
715};
716
717#define __TEMPLATE_ATTR(_template, _mode, _show, _store) { \
718 .attr = {.name = _template, .mode = _mode }, \
719 .show = _show, \
720 .store = _store, \
721}
722
723#define SENSOR_DEVICE_TEMPLATE(_template, _mode, _show, _store, _index) \
724 { .dev_attr = __TEMPLATE_ATTR(_template, _mode, _show, _store), \
725 .u.index = _index, \
726 .s2 = false }
727
728#define SENSOR_DEVICE_TEMPLATE_2(_template, _mode, _show, _store, \
729 _nr, _index) \
730 { .dev_attr = __TEMPLATE_ATTR(_template, _mode, _show, _store), \
731 .u.s.index = _index, \
732 .u.s.nr = _nr, \
733 .s2 = true }
734
735#define SENSOR_TEMPLATE(_name, _template, _mode, _show, _store, _index) \
736static struct sensor_device_template sensor_dev_template_##_name \
737 = SENSOR_DEVICE_TEMPLATE(_template, _mode, _show, _store, \
738 _index)
739
740#define SENSOR_TEMPLATE_2(_name, _template, _mode, _show, _store, \
741 _nr, _index) \
742static struct sensor_device_template sensor_dev_template_##_name \
743 = SENSOR_DEVICE_TEMPLATE_2(_template, _mode, _show, _store, \
744 _nr, _index)
745
746struct sensor_template_group {
747 struct sensor_device_template **templates;
748 umode_t (*is_visible)(struct kobject *, struct attribute *, int);
749 int base;
750};
751
752static struct attribute_group *
753nct6775_create_attr_group(struct device *dev, struct sensor_template_group *tg,
754 int repeat)
755{
756 struct attribute_group *group;
757 struct sensor_device_attr_u *su;
758 struct sensor_device_attribute *a;
759 struct sensor_device_attribute_2 *a2;
760 struct attribute **attrs;
761 struct sensor_device_template **t;
762 int err, i, j, count;
763
764 if (repeat <= 0)
765 return ERR_PTR(-EINVAL);
766
767 t = tg->templates;
768 for (count = 0; *t; t++, count++)
769 ;
770
771 if (count == 0)
772 return ERR_PTR(-EINVAL);
773
774 group = devm_kzalloc(dev, sizeof(*group), GFP_KERNEL);
775 if (group == NULL)
776 return ERR_PTR(-ENOMEM);
777
778 attrs = devm_kzalloc(dev, sizeof(*attrs) * (repeat * count + 1),
779 GFP_KERNEL);
780 if (attrs == NULL)
781 return ERR_PTR(-ENOMEM);
782
783 su = devm_kzalloc(dev, sizeof(*su) * repeat * count,
784 GFP_KERNEL);
785 if (su == NULL)
786 return ERR_PTR(-ENOMEM);
787
788 group->attrs = attrs;
789 group->is_visible = tg->is_visible;
790
791 for (i = 0; i < repeat; i++) {
792 t = tg->templates;
793 for (j = 0; *t != NULL; j++) {
794 snprintf(su->name, sizeof(su->name),
795 (*t)->dev_attr.attr.name, tg->base + i);
796 if ((*t)->s2) {
797 a2 = &su->u.a2;
798 a2->dev_attr.attr.name = su->name;
799 a2->nr = (*t)->u.s.nr + i;
800 a2->index = (*t)->u.s.index;
801 a2->dev_attr.attr.mode =
802 (*t)->dev_attr.attr.mode;
803 a2->dev_attr.show = (*t)->dev_attr.show;
804 a2->dev_attr.store = (*t)->dev_attr.store;
805 *attrs = &a2->dev_attr.attr;
806 } else {
807 a = &su->u.a1;
808 a->dev_attr.attr.name = su->name;
809 a->index = (*t)->u.index + i;
810 a->dev_attr.attr.mode =
811 (*t)->dev_attr.attr.mode;
812 a->dev_attr.show = (*t)->dev_attr.show;
813 a->dev_attr.store = (*t)->dev_attr.store;
814 *attrs = &a->dev_attr.attr;
815 }
816 attrs++;
817 su++;
818 t++;
819 }
820 }
821
822 err = sysfs_create_group(&dev->kobj, group);
823 if (err)
824 return ERR_PTR(-ENOMEM);
825
826 return group;
827}
828
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700829static bool is_word_sized(struct nct6775_data *data, u16 reg)
830{
831 switch (data->kind) {
832 case nct6775:
833 return (((reg & 0xff00) == 0x100 ||
834 (reg & 0xff00) == 0x200) &&
835 ((reg & 0x00ff) == 0x50 ||
836 (reg & 0x00ff) == 0x53 ||
837 (reg & 0x00ff) == 0x55)) ||
838 (reg & 0xfff0) == 0x630 ||
839 reg == 0x640 || reg == 0x642 ||
840 reg == 0x662 ||
841 ((reg & 0xfff0) == 0x650 && (reg & 0x000f) >= 0x06) ||
842 reg == 0x73 || reg == 0x75 || reg == 0x77;
843 case nct6776:
844 return (((reg & 0xff00) == 0x100 ||
845 (reg & 0xff00) == 0x200) &&
846 ((reg & 0x00ff) == 0x50 ||
847 (reg & 0x00ff) == 0x53 ||
848 (reg & 0x00ff) == 0x55)) ||
849 (reg & 0xfff0) == 0x630 ||
850 reg == 0x402 ||
851 reg == 0x640 || reg == 0x642 ||
852 ((reg & 0xfff0) == 0x650 && (reg & 0x000f) >= 0x06) ||
853 reg == 0x73 || reg == 0x75 || reg == 0x77;
854 case nct6779:
855 return reg == 0x150 || reg == 0x153 || reg == 0x155 ||
856 ((reg & 0xfff0) == 0x4b0 && (reg & 0x000f) < 0x09) ||
857 reg == 0x402 ||
858 reg == 0x63a || reg == 0x63c || reg == 0x63e ||
859 reg == 0x640 || reg == 0x642 ||
860 reg == 0x73 || reg == 0x75 || reg == 0x77 || reg == 0x79 ||
861 reg == 0x7b;
862 }
863 return false;
864}
865
866/*
867 * On older chips, only registers 0x50-0x5f are banked.
868 * On more recent chips, all registers are banked.
869 * Assume that is the case and set the bank number for each access.
870 * Cache the bank number so it only needs to be set if it changes.
871 */
872static inline void nct6775_set_bank(struct nct6775_data *data, u16 reg)
873{
874 u8 bank = reg >> 8;
875 if (data->bank != bank) {
876 outb_p(NCT6775_REG_BANK, data->addr + ADDR_REG_OFFSET);
877 outb_p(bank, data->addr + DATA_REG_OFFSET);
878 data->bank = bank;
879 }
880}
881
882static u16 nct6775_read_value(struct nct6775_data *data, u16 reg)
883{
884 int res, word_sized = is_word_sized(data, reg);
885
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700886 nct6775_set_bank(data, reg);
887 outb_p(reg & 0xff, data->addr + ADDR_REG_OFFSET);
888 res = inb_p(data->addr + DATA_REG_OFFSET);
889 if (word_sized) {
890 outb_p((reg & 0xff) + 1,
891 data->addr + ADDR_REG_OFFSET);
892 res = (res << 8) + inb_p(data->addr + DATA_REG_OFFSET);
893 }
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700894 return res;
895}
896
897static int nct6775_write_value(struct nct6775_data *data, u16 reg, u16 value)
898{
899 int word_sized = is_word_sized(data, reg);
900
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700901 nct6775_set_bank(data, reg);
902 outb_p(reg & 0xff, data->addr + ADDR_REG_OFFSET);
903 if (word_sized) {
904 outb_p(value >> 8, data->addr + DATA_REG_OFFSET);
905 outb_p((reg & 0xff) + 1,
906 data->addr + ADDR_REG_OFFSET);
907 }
908 outb_p(value & 0xff, data->addr + DATA_REG_OFFSET);
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700909 return 0;
910}
911
Guenter Roeckaa136e52012-12-04 03:26:05 -0800912/* We left-align 8-bit temperature values to make the code simpler */
913static u16 nct6775_read_temp(struct nct6775_data *data, u16 reg)
914{
915 u16 res;
916
917 res = nct6775_read_value(data, reg);
918 if (!is_word_sized(data, reg))
919 res <<= 8;
920
921 return res;
922}
923
924static int nct6775_write_temp(struct nct6775_data *data, u16 reg, u16 value)
925{
926 if (!is_word_sized(data, reg))
927 value >>= 8;
928 return nct6775_write_value(data, reg, value);
929}
930
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800931/* This function assumes that the caller holds data->update_lock */
932static void nct6775_write_fan_div(struct nct6775_data *data, int nr)
933{
934 u8 reg;
935
936 switch (nr) {
937 case 0:
938 reg = (nct6775_read_value(data, NCT6775_REG_FANDIV1) & 0x70)
939 | (data->fan_div[0] & 0x7);
940 nct6775_write_value(data, NCT6775_REG_FANDIV1, reg);
941 break;
942 case 1:
943 reg = (nct6775_read_value(data, NCT6775_REG_FANDIV1) & 0x7)
944 | ((data->fan_div[1] << 4) & 0x70);
945 nct6775_write_value(data, NCT6775_REG_FANDIV1, reg);
946 break;
947 case 2:
948 reg = (nct6775_read_value(data, NCT6775_REG_FANDIV2) & 0x70)
949 | (data->fan_div[2] & 0x7);
950 nct6775_write_value(data, NCT6775_REG_FANDIV2, reg);
951 break;
952 case 3:
953 reg = (nct6775_read_value(data, NCT6775_REG_FANDIV2) & 0x7)
954 | ((data->fan_div[3] << 4) & 0x70);
955 nct6775_write_value(data, NCT6775_REG_FANDIV2, reg);
956 break;
957 }
958}
959
960static void nct6775_write_fan_div_common(struct nct6775_data *data, int nr)
961{
962 if (data->kind == nct6775)
963 nct6775_write_fan_div(data, nr);
964}
965
966static void nct6775_update_fan_div(struct nct6775_data *data)
967{
968 u8 i;
969
970 i = nct6775_read_value(data, NCT6775_REG_FANDIV1);
971 data->fan_div[0] = i & 0x7;
972 data->fan_div[1] = (i & 0x70) >> 4;
973 i = nct6775_read_value(data, NCT6775_REG_FANDIV2);
974 data->fan_div[2] = i & 0x7;
Guenter Roeck6445e662013-04-21 09:13:28 -0700975 if (data->has_fan & (1 << 3))
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800976 data->fan_div[3] = (i & 0x70) >> 4;
977}
978
979static void nct6775_update_fan_div_common(struct nct6775_data *data)
980{
981 if (data->kind == nct6775)
982 nct6775_update_fan_div(data);
983}
984
985static void nct6775_init_fan_div(struct nct6775_data *data)
986{
987 int i;
988
989 nct6775_update_fan_div_common(data);
990 /*
991 * For all fans, start with highest divider value if the divider
992 * register is not initialized. This ensures that we get a
993 * reading from the fan count register, even if it is not optimal.
994 * We'll compute a better divider later on.
995 */
Guenter Roeckc409fd42013-04-09 05:04:00 -0700996 for (i = 0; i < ARRAY_SIZE(data->fan_div); i++) {
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800997 if (!(data->has_fan & (1 << i)))
998 continue;
999 if (data->fan_div[i] == 0) {
1000 data->fan_div[i] = 7;
1001 nct6775_write_fan_div_common(data, i);
1002 }
1003 }
1004}
1005
1006static void nct6775_init_fan_common(struct device *dev,
1007 struct nct6775_data *data)
1008{
1009 int i;
1010 u8 reg;
1011
1012 if (data->has_fan_div)
1013 nct6775_init_fan_div(data);
1014
1015 /*
1016 * If fan_min is not set (0), set it to 0xff to disable it. This
1017 * prevents the unnecessary warning when fanX_min is reported as 0.
1018 */
Guenter Roeckc409fd42013-04-09 05:04:00 -07001019 for (i = 0; i < ARRAY_SIZE(data->fan_min); i++) {
Guenter Roeck1c65dc32012-12-04 07:56:24 -08001020 if (data->has_fan_min & (1 << i)) {
1021 reg = nct6775_read_value(data, data->REG_FAN_MIN[i]);
1022 if (!reg)
1023 nct6775_write_value(data, data->REG_FAN_MIN[i],
1024 data->has_fan_div ? 0xff
1025 : 0xff1f);
1026 }
1027 }
1028}
1029
1030static void nct6775_select_fan_div(struct device *dev,
1031 struct nct6775_data *data, int nr, u16 reg)
1032{
1033 u8 fan_div = data->fan_div[nr];
1034 u16 fan_min;
1035
1036 if (!data->has_fan_div)
1037 return;
1038
1039 /*
1040 * If we failed to measure the fan speed, or the reported value is not
1041 * in the optimal range, and the clock divider can be modified,
1042 * let's try that for next time.
1043 */
1044 if (reg == 0x00 && fan_div < 0x07)
1045 fan_div++;
1046 else if (reg != 0x00 && reg < 0x30 && fan_div > 0)
1047 fan_div--;
1048
1049 if (fan_div != data->fan_div[nr]) {
1050 dev_dbg(dev, "Modifying fan%d clock divider from %u to %u\n",
1051 nr + 1, div_from_reg(data->fan_div[nr]),
1052 div_from_reg(fan_div));
1053
1054 /* Preserve min limit if possible */
1055 if (data->has_fan_min & (1 << nr)) {
1056 fan_min = data->fan_min[nr];
1057 if (fan_div > data->fan_div[nr]) {
1058 if (fan_min != 255 && fan_min > 1)
1059 fan_min >>= 1;
1060 } else {
1061 if (fan_min != 255) {
1062 fan_min <<= 1;
1063 if (fan_min > 254)
1064 fan_min = 254;
1065 }
1066 }
1067 if (fan_min != data->fan_min[nr]) {
1068 data->fan_min[nr] = fan_min;
1069 nct6775_write_value(data, data->REG_FAN_MIN[nr],
1070 fan_min);
1071 }
1072 }
1073 data->fan_div[nr] = fan_div;
1074 nct6775_write_fan_div_common(data, nr);
1075 }
1076}
1077
Guenter Roeck77eb5b32012-12-04 08:30:54 -08001078static void nct6775_update_pwm(struct device *dev)
1079{
1080 struct nct6775_data *data = dev_get_drvdata(dev);
1081 int i, j;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08001082 int fanmodecfg, reg;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08001083 bool duty_is_dc;
1084
1085 for (i = 0; i < data->pwm_num; i++) {
1086 if (!(data->has_pwm & (1 << i)))
1087 continue;
1088
1089 duty_is_dc = data->REG_PWM_MODE[i] &&
1090 (nct6775_read_value(data, data->REG_PWM_MODE[i])
1091 & data->PWM_MODE_MASK[i]);
1092 data->pwm_mode[i] = duty_is_dc;
1093
1094 fanmodecfg = nct6775_read_value(data, data->REG_FAN_MODE[i]);
1095 for (j = 0; j < ARRAY_SIZE(data->REG_PWM); j++) {
1096 if (data->REG_PWM[j] && data->REG_PWM[j][i]) {
1097 data->pwm[j][i]
1098 = nct6775_read_value(data,
1099 data->REG_PWM[j][i]);
1100 }
1101 }
1102
1103 data->pwm_enable[i] = reg_to_pwm_enable(data->pwm[0][i],
1104 (fanmodecfg >> 4) & 7);
Guenter Roeckcdcaece2012-12-04 09:04:52 -08001105
1106 if (!data->temp_tolerance[0][i] ||
1107 data->pwm_enable[i] != speed_cruise)
1108 data->temp_tolerance[0][i] = fanmodecfg & 0x0f;
1109 if (!data->target_speed_tolerance[i] ||
1110 data->pwm_enable[i] == speed_cruise) {
1111 u8 t = fanmodecfg & 0x0f;
1112 if (data->REG_TOLERANCE_H) {
1113 t |= (nct6775_read_value(data,
1114 data->REG_TOLERANCE_H[i]) & 0x70) >> 1;
1115 }
1116 data->target_speed_tolerance[i] = t;
1117 }
1118
1119 data->temp_tolerance[1][i] =
1120 nct6775_read_value(data,
1121 data->REG_CRITICAL_TEMP_TOLERANCE[i]);
1122
1123 reg = nct6775_read_value(data, data->REG_TEMP_SEL[i]);
1124 data->pwm_temp_sel[i] = reg & 0x1f;
1125 /* If fan can stop, report floor as 0 */
1126 if (reg & 0x80)
1127 data->pwm[2][i] = 0;
Guenter Roeckbbd8dec2012-12-04 09:08:29 -08001128
1129 reg = nct6775_read_value(data, data->REG_WEIGHT_TEMP_SEL[i]);
1130 data->pwm_weight_temp_sel[i] = reg & 0x1f;
1131 /* If weight is disabled, report weight source as 0 */
1132 if (j == 1 && !(reg & 0x80))
1133 data->pwm_weight_temp_sel[i] = 0;
1134
1135 /* Weight temp data */
Guenter Roeckc409fd42013-04-09 05:04:00 -07001136 for (j = 0; j < ARRAY_SIZE(data->weight_temp); j++) {
Guenter Roeckbbd8dec2012-12-04 09:08:29 -08001137 data->weight_temp[j][i]
1138 = nct6775_read_value(data,
1139 data->REG_WEIGHT_TEMP[j][i]);
1140 }
Guenter Roeckcdcaece2012-12-04 09:04:52 -08001141 }
1142}
1143
1144static void nct6775_update_pwm_limits(struct device *dev)
1145{
1146 struct nct6775_data *data = dev_get_drvdata(dev);
1147 int i, j;
1148 u8 reg;
1149 u16 reg_t;
1150
1151 for (i = 0; i < data->pwm_num; i++) {
1152 if (!(data->has_pwm & (1 << i)))
1153 continue;
1154
Guenter Roeckc409fd42013-04-09 05:04:00 -07001155 for (j = 0; j < ARRAY_SIZE(data->fan_time); j++) {
Guenter Roeckcdcaece2012-12-04 09:04:52 -08001156 data->fan_time[j][i] =
1157 nct6775_read_value(data, data->REG_FAN_TIME[j][i]);
1158 }
1159
1160 reg_t = nct6775_read_value(data, data->REG_TARGET[i]);
1161 /* Update only in matching mode or if never updated */
1162 if (!data->target_temp[i] ||
1163 data->pwm_enable[i] == thermal_cruise)
1164 data->target_temp[i] = reg_t & data->target_temp_mask;
1165 if (!data->target_speed[i] ||
1166 data->pwm_enable[i] == speed_cruise) {
1167 if (data->REG_TOLERANCE_H) {
1168 reg_t |= (nct6775_read_value(data,
1169 data->REG_TOLERANCE_H[i]) & 0x0f) << 8;
1170 }
1171 data->target_speed[i] = reg_t;
1172 }
1173
1174 for (j = 0; j < data->auto_pwm_num; j++) {
1175 data->auto_pwm[i][j] =
1176 nct6775_read_value(data,
1177 NCT6775_AUTO_PWM(data, i, j));
1178 data->auto_temp[i][j] =
1179 nct6775_read_value(data,
1180 NCT6775_AUTO_TEMP(data, i, j));
1181 }
1182
1183 /* critical auto_pwm temperature data */
1184 data->auto_temp[i][data->auto_pwm_num] =
1185 nct6775_read_value(data, data->REG_CRITICAL_TEMP[i]);
1186
1187 switch (data->kind) {
1188 case nct6775:
1189 reg = nct6775_read_value(data,
1190 NCT6775_REG_CRITICAL_ENAB[i]);
1191 data->auto_pwm[i][data->auto_pwm_num] =
1192 (reg & 0x02) ? 0xff : 0x00;
1193 break;
1194 case nct6776:
1195 data->auto_pwm[i][data->auto_pwm_num] = 0xff;
1196 break;
1197 case nct6779:
1198 reg = nct6775_read_value(data,
1199 NCT6779_REG_CRITICAL_PWM_ENABLE[i]);
1200 if (reg & 1)
1201 data->auto_pwm[i][data->auto_pwm_num] =
1202 nct6775_read_value(data,
1203 NCT6779_REG_CRITICAL_PWM[i]);
1204 else
1205 data->auto_pwm[i][data->auto_pwm_num] = 0xff;
1206 break;
1207 }
Guenter Roeck77eb5b32012-12-04 08:30:54 -08001208 }
1209}
1210
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07001211static struct nct6775_data *nct6775_update_device(struct device *dev)
1212{
1213 struct nct6775_data *data = dev_get_drvdata(dev);
Guenter Roeckaa136e52012-12-04 03:26:05 -08001214 int i, j;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07001215
1216 mutex_lock(&data->update_lock);
1217
Guenter Roeck6445e662013-04-21 09:13:28 -07001218 if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07001219 || !data->valid) {
Guenter Roeck1c65dc32012-12-04 07:56:24 -08001220 /* Fan clock dividers */
1221 nct6775_update_fan_div_common(data);
1222
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07001223 /* Measured voltages and limits */
1224 for (i = 0; i < data->in_num; i++) {
1225 if (!(data->have_in & (1 << i)))
1226 continue;
1227
1228 data->in[i][0] = nct6775_read_value(data,
1229 data->REG_VIN[i]);
1230 data->in[i][1] = nct6775_read_value(data,
1231 data->REG_IN_MINMAX[0][i]);
1232 data->in[i][2] = nct6775_read_value(data,
1233 data->REG_IN_MINMAX[1][i]);
1234 }
1235
Guenter Roeck1c65dc32012-12-04 07:56:24 -08001236 /* Measured fan speeds and limits */
Guenter Roeckc409fd42013-04-09 05:04:00 -07001237 for (i = 0; i < ARRAY_SIZE(data->rpm); i++) {
Guenter Roeck1c65dc32012-12-04 07:56:24 -08001238 u16 reg;
1239
1240 if (!(data->has_fan & (1 << i)))
1241 continue;
1242
1243 reg = nct6775_read_value(data, data->REG_FAN[i]);
1244 data->rpm[i] = data->fan_from_reg(reg,
1245 data->fan_div[i]);
1246
1247 if (data->has_fan_min & (1 << i))
1248 data->fan_min[i] = nct6775_read_value(data,
1249 data->REG_FAN_MIN[i]);
Guenter Roeck5c25d952012-12-11 07:29:06 -08001250 data->fan_pulses[i] =
1251 nct6775_read_value(data, data->REG_FAN_PULSES[i]);
Guenter Roeck1c65dc32012-12-04 07:56:24 -08001252
1253 nct6775_select_fan_div(dev, data, i, reg);
1254 }
1255
Guenter Roeck77eb5b32012-12-04 08:30:54 -08001256 nct6775_update_pwm(dev);
Guenter Roeckcdcaece2012-12-04 09:04:52 -08001257 nct6775_update_pwm_limits(dev);
Guenter Roeck77eb5b32012-12-04 08:30:54 -08001258
Guenter Roeckaa136e52012-12-04 03:26:05 -08001259 /* Measured temperatures and limits */
1260 for (i = 0; i < NUM_TEMP; i++) {
1261 if (!(data->have_temp & (1 << i)))
1262 continue;
Guenter Roeckc409fd42013-04-09 05:04:00 -07001263 for (j = 0; j < ARRAY_SIZE(data->reg_temp); j++) {
Guenter Roeckaa136e52012-12-04 03:26:05 -08001264 if (data->reg_temp[j][i])
1265 data->temp[j][i]
1266 = nct6775_read_temp(data,
1267 data->reg_temp[j][i]);
1268 }
1269 if (!(data->have_temp_fixed & (1 << i)))
1270 continue;
1271 data->temp_offset[i]
1272 = nct6775_read_value(data, data->REG_TEMP_OFFSET[i]);
1273 }
1274
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07001275 data->alarms = 0;
1276 for (i = 0; i < NUM_REG_ALARM; i++) {
1277 u8 alarm;
1278 if (!data->REG_ALARM[i])
1279 continue;
1280 alarm = nct6775_read_value(data, data->REG_ALARM[i]);
1281 data->alarms |= ((u64)alarm) << (i << 3);
1282 }
1283
1284 data->last_updated = jiffies;
1285 data->valid = true;
1286 }
1287
1288 mutex_unlock(&data->update_lock);
1289 return data;
1290}
1291
1292/*
1293 * Sysfs callback functions
1294 */
1295static ssize_t
1296show_in_reg(struct device *dev, struct device_attribute *attr, char *buf)
1297{
1298 struct nct6775_data *data = nct6775_update_device(dev);
1299 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
1300 int nr = sattr->nr;
1301 int index = sattr->index;
1302 return sprintf(buf, "%ld\n", in_from_reg(data->in[nr][index], nr));
1303}
1304
1305static ssize_t
1306store_in_reg(struct device *dev, struct device_attribute *attr, const char *buf,
1307 size_t count)
1308{
1309 struct nct6775_data *data = dev_get_drvdata(dev);
1310 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
1311 int nr = sattr->nr;
1312 int index = sattr->index;
1313 unsigned long val;
1314 int err = kstrtoul(buf, 10, &val);
1315 if (err < 0)
1316 return err;
1317 mutex_lock(&data->update_lock);
1318 data->in[nr][index] = in_to_reg(val, nr);
Guenter Roeck6445e662013-04-21 09:13:28 -07001319 nct6775_write_value(data, data->REG_IN_MINMAX[index - 1][nr],
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07001320 data->in[nr][index]);
1321 mutex_unlock(&data->update_lock);
1322 return count;
1323}
1324
1325static ssize_t
1326show_alarm(struct device *dev, struct device_attribute *attr, char *buf)
1327{
1328 struct nct6775_data *data = nct6775_update_device(dev);
1329 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1330 int nr = data->ALARM_BITS[sattr->index];
1331 return sprintf(buf, "%u\n",
1332 (unsigned int)((data->alarms >> nr) & 0x01));
1333}
1334
Guenter Roeckb1d2bff2013-06-22 16:15:31 -07001335static int find_temp_source(struct nct6775_data *data, int index, int count)
1336{
1337 int source = data->temp_src[index];
1338 int nr;
1339
1340 for (nr = 0; nr < count; nr++) {
1341 int src;
1342
1343 src = nct6775_read_value(data,
1344 data->REG_TEMP_SOURCE[nr]) & 0x1f;
1345 if (src == source)
1346 return nr;
1347 }
1348 return -1;
1349}
1350
1351static ssize_t
1352show_temp_alarm(struct device *dev, struct device_attribute *attr, char *buf)
1353{
1354 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1355 struct nct6775_data *data = nct6775_update_device(dev);
1356 unsigned int alarm = 0;
1357 int nr;
1358
1359 /*
1360 * For temperatures, there is no fixed mapping from registers to alarm
1361 * bits. Alarm bits are determined by the temperature source mapping.
1362 */
1363 nr = find_temp_source(data, sattr->index, data->num_temp_alarms);
1364 if (nr >= 0) {
1365 int bit = data->ALARM_BITS[nr + TEMP_ALARM_BASE];
1366 alarm = (data->alarms >> bit) & 0x01;
1367 }
1368 return sprintf(buf, "%u\n", alarm);
1369}
1370
Guenter Roeckf73cf632013-03-18 09:22:50 -07001371static umode_t nct6775_in_is_visible(struct kobject *kobj,
1372 struct attribute *attr, int index)
1373{
1374 struct device *dev = container_of(kobj, struct device, kobj);
1375 struct nct6775_data *data = dev_get_drvdata(dev);
1376 int in = index / 4; /* voltage index */
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07001377
Guenter Roeckf73cf632013-03-18 09:22:50 -07001378 if (!(data->have_in & (1 << in)))
1379 return 0;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07001380
Guenter Roeckf73cf632013-03-18 09:22:50 -07001381 return attr->mode;
1382}
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07001383
Guenter Roeckf73cf632013-03-18 09:22:50 -07001384SENSOR_TEMPLATE_2(in_input, "in%d_input", S_IRUGO, show_in_reg, NULL, 0, 0);
1385SENSOR_TEMPLATE(in_alarm, "in%d_alarm", S_IRUGO, show_alarm, NULL, 0);
1386SENSOR_TEMPLATE_2(in_min, "in%d_min", S_IWUSR | S_IRUGO, show_in_reg,
1387 store_in_reg, 0, 1);
1388SENSOR_TEMPLATE_2(in_max, "in%d_max", S_IWUSR | S_IRUGO, show_in_reg,
1389 store_in_reg, 0, 2);
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07001390
Guenter Roeckf73cf632013-03-18 09:22:50 -07001391/*
1392 * nct6775_in_is_visible uses the index into the following array
1393 * to determine if attributes should be created or not.
1394 * Any change in order or content must be matched.
1395 */
1396static struct sensor_device_template *nct6775_attributes_in_template[] = {
1397 &sensor_dev_template_in_input,
1398 &sensor_dev_template_in_alarm,
1399 &sensor_dev_template_in_min,
1400 &sensor_dev_template_in_max,
1401 NULL
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07001402};
1403
Guenter Roeckf73cf632013-03-18 09:22:50 -07001404static struct sensor_template_group nct6775_in_template_group = {
1405 .templates = nct6775_attributes_in_template,
1406 .is_visible = nct6775_in_is_visible,
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07001407};
1408
1409static ssize_t
Guenter Roeck1c65dc32012-12-04 07:56:24 -08001410show_fan(struct device *dev, struct device_attribute *attr, char *buf)
1411{
1412 struct nct6775_data *data = nct6775_update_device(dev);
1413 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1414 int nr = sattr->index;
1415 return sprintf(buf, "%d\n", data->rpm[nr]);
1416}
1417
1418static ssize_t
1419show_fan_min(struct device *dev, struct device_attribute *attr, char *buf)
1420{
1421 struct nct6775_data *data = nct6775_update_device(dev);
1422 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1423 int nr = sattr->index;
1424 return sprintf(buf, "%d\n",
1425 data->fan_from_reg_min(data->fan_min[nr],
1426 data->fan_div[nr]));
1427}
1428
1429static ssize_t
1430show_fan_div(struct device *dev, struct device_attribute *attr, char *buf)
1431{
1432 struct nct6775_data *data = nct6775_update_device(dev);
1433 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1434 int nr = sattr->index;
1435 return sprintf(buf, "%u\n", div_from_reg(data->fan_div[nr]));
1436}
1437
1438static ssize_t
1439store_fan_min(struct device *dev, struct device_attribute *attr,
1440 const char *buf, size_t count)
1441{
1442 struct nct6775_data *data = dev_get_drvdata(dev);
1443 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1444 int nr = sattr->index;
1445 unsigned long val;
1446 int err;
1447 unsigned int reg;
1448 u8 new_div;
1449
1450 err = kstrtoul(buf, 10, &val);
1451 if (err < 0)
1452 return err;
1453
1454 mutex_lock(&data->update_lock);
1455 if (!data->has_fan_div) {
1456 /* NCT6776F or NCT6779D; we know this is a 13 bit register */
1457 if (!val) {
1458 val = 0xff1f;
1459 } else {
1460 if (val > 1350000U)
1461 val = 135000U;
1462 val = 1350000U / val;
1463 val = (val & 0x1f) | ((val << 3) & 0xff00);
1464 }
1465 data->fan_min[nr] = val;
1466 goto write_min; /* Leave fan divider alone */
1467 }
1468 if (!val) {
1469 /* No min limit, alarm disabled */
1470 data->fan_min[nr] = 255;
1471 new_div = data->fan_div[nr]; /* No change */
1472 dev_info(dev, "fan%u low limit and alarm disabled\n", nr + 1);
1473 goto write_div;
1474 }
1475 reg = 1350000U / val;
1476 if (reg >= 128 * 255) {
1477 /*
1478 * Speed below this value cannot possibly be represented,
1479 * even with the highest divider (128)
1480 */
1481 data->fan_min[nr] = 254;
1482 new_div = 7; /* 128 == (1 << 7) */
1483 dev_warn(dev,
1484 "fan%u low limit %lu below minimum %u, set to minimum\n",
1485 nr + 1, val, data->fan_from_reg_min(254, 7));
1486 } else if (!reg) {
1487 /*
1488 * Speed above this value cannot possibly be represented,
1489 * even with the lowest divider (1)
1490 */
1491 data->fan_min[nr] = 1;
1492 new_div = 0; /* 1 == (1 << 0) */
1493 dev_warn(dev,
1494 "fan%u low limit %lu above maximum %u, set to maximum\n",
1495 nr + 1, val, data->fan_from_reg_min(1, 0));
1496 } else {
1497 /*
1498 * Automatically pick the best divider, i.e. the one such
1499 * that the min limit will correspond to a register value
1500 * in the 96..192 range
1501 */
1502 new_div = 0;
1503 while (reg > 192 && new_div < 7) {
1504 reg >>= 1;
1505 new_div++;
1506 }
1507 data->fan_min[nr] = reg;
1508 }
1509
1510write_div:
1511 /*
1512 * Write both the fan clock divider (if it changed) and the new
1513 * fan min (unconditionally)
1514 */
1515 if (new_div != data->fan_div[nr]) {
1516 dev_dbg(dev, "fan%u clock divider changed from %u to %u\n",
1517 nr + 1, div_from_reg(data->fan_div[nr]),
1518 div_from_reg(new_div));
1519 data->fan_div[nr] = new_div;
1520 nct6775_write_fan_div_common(data, nr);
1521 /* Give the chip time to sample a new speed value */
1522 data->last_updated = jiffies;
1523 }
1524
1525write_min:
1526 nct6775_write_value(data, data->REG_FAN_MIN[nr], data->fan_min[nr]);
1527 mutex_unlock(&data->update_lock);
1528
1529 return count;
1530}
1531
Guenter Roeck5c25d952012-12-11 07:29:06 -08001532static ssize_t
1533show_fan_pulses(struct device *dev, struct device_attribute *attr, char *buf)
1534{
1535 struct nct6775_data *data = nct6775_update_device(dev);
1536 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1537 int p = data->fan_pulses[sattr->index];
1538
1539 return sprintf(buf, "%d\n", p ? : 4);
1540}
1541
1542static ssize_t
1543store_fan_pulses(struct device *dev, struct device_attribute *attr,
1544 const char *buf, size_t count)
1545{
1546 struct nct6775_data *data = dev_get_drvdata(dev);
1547 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1548 int nr = sattr->index;
1549 unsigned long val;
1550 int err;
1551
1552 err = kstrtoul(buf, 10, &val);
1553 if (err < 0)
1554 return err;
1555
1556 if (val > 4)
1557 return -EINVAL;
1558
1559 mutex_lock(&data->update_lock);
1560 data->fan_pulses[nr] = val & 3;
1561 nct6775_write_value(data, data->REG_FAN_PULSES[nr], val & 3);
1562 mutex_unlock(&data->update_lock);
1563
1564 return count;
1565}
1566
Guenter Roeckf73cf632013-03-18 09:22:50 -07001567static umode_t nct6775_fan_is_visible(struct kobject *kobj,
1568 struct attribute *attr, int index)
1569{
1570 struct device *dev = container_of(kobj, struct device, kobj);
1571 struct nct6775_data *data = dev_get_drvdata(dev);
1572 int fan = index / 5; /* fan index */
1573 int nr = index % 5; /* attribute index */
1574
1575 if (!(data->has_fan & (1 << fan)))
1576 return 0;
1577
1578 if (nr == 1 && data->ALARM_BITS[FAN_ALARM_BASE + fan] == -1)
1579 return 0;
1580 if (nr == 3 && !(data->has_fan_min & (1 << fan)))
1581 return 0;
1582 if (nr == 4 && data->kind != nct6775)
1583 return 0;
1584
1585 return attr->mode;
1586}
1587
1588SENSOR_TEMPLATE(fan_input, "fan%d_input", S_IRUGO, show_fan, NULL, 0);
1589SENSOR_TEMPLATE(fan_alarm, "fan%d_alarm", S_IRUGO, show_alarm, NULL,
1590 FAN_ALARM_BASE);
1591SENSOR_TEMPLATE(fan_pulses, "fan%d_pulses", S_IWUSR | S_IRUGO, show_fan_pulses,
1592 store_fan_pulses, 0);
1593SENSOR_TEMPLATE(fan_min, "fan%d_min", S_IWUSR | S_IRUGO, show_fan_min,
1594 store_fan_min, 0);
1595SENSOR_TEMPLATE(fan_div, "fan%d_div", S_IRUGO, show_fan_div, NULL, 0);
1596
1597/*
1598 * nct6775_fan_is_visible uses the index into the following array
1599 * to determine if attributes should be created or not.
1600 * Any change in order or content must be matched.
1601 */
1602static struct sensor_device_template *nct6775_attributes_fan_template[] = {
1603 &sensor_dev_template_fan_input,
1604 &sensor_dev_template_fan_alarm, /* 1 */
1605 &sensor_dev_template_fan_pulses,
1606 &sensor_dev_template_fan_min, /* 3 */
1607 &sensor_dev_template_fan_div, /* 4 */
1608 NULL
Guenter Roeck1c65dc32012-12-04 07:56:24 -08001609};
1610
Guenter Roeckf73cf632013-03-18 09:22:50 -07001611static struct sensor_template_group nct6775_fan_template_group = {
1612 .templates = nct6775_attributes_fan_template,
1613 .is_visible = nct6775_fan_is_visible,
1614 .base = 1,
Guenter Roeck1c65dc32012-12-04 07:56:24 -08001615};
1616
1617static ssize_t
Guenter Roeckaa136e52012-12-04 03:26:05 -08001618show_temp_label(struct device *dev, struct device_attribute *attr, char *buf)
1619{
1620 struct nct6775_data *data = nct6775_update_device(dev);
1621 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1622 int nr = sattr->index;
1623 return sprintf(buf, "%s\n", data->temp_label[data->temp_src[nr]]);
1624}
1625
1626static ssize_t
1627show_temp(struct device *dev, struct device_attribute *attr, char *buf)
1628{
1629 struct nct6775_data *data = nct6775_update_device(dev);
1630 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
1631 int nr = sattr->nr;
1632 int index = sattr->index;
1633
1634 return sprintf(buf, "%d\n", LM75_TEMP_FROM_REG(data->temp[index][nr]));
1635}
1636
1637static ssize_t
1638store_temp(struct device *dev, struct device_attribute *attr, const char *buf,
1639 size_t count)
1640{
1641 struct nct6775_data *data = dev_get_drvdata(dev);
1642 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
1643 int nr = sattr->nr;
1644 int index = sattr->index;
1645 int err;
1646 long val;
1647
1648 err = kstrtol(buf, 10, &val);
1649 if (err < 0)
1650 return err;
1651
1652 mutex_lock(&data->update_lock);
1653 data->temp[index][nr] = LM75_TEMP_TO_REG(val);
1654 nct6775_write_temp(data, data->reg_temp[index][nr],
1655 data->temp[index][nr]);
1656 mutex_unlock(&data->update_lock);
1657 return count;
1658}
1659
1660static ssize_t
1661show_temp_offset(struct device *dev, struct device_attribute *attr, char *buf)
1662{
1663 struct nct6775_data *data = nct6775_update_device(dev);
1664 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1665
1666 return sprintf(buf, "%d\n", data->temp_offset[sattr->index] * 1000);
1667}
1668
1669static ssize_t
1670store_temp_offset(struct device *dev, struct device_attribute *attr,
1671 const char *buf, size_t count)
1672{
1673 struct nct6775_data *data = dev_get_drvdata(dev);
1674 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1675 int nr = sattr->index;
1676 long val;
1677 int err;
1678
1679 err = kstrtol(buf, 10, &val);
1680 if (err < 0)
1681 return err;
1682
1683 val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), -128, 127);
1684
1685 mutex_lock(&data->update_lock);
1686 data->temp_offset[nr] = val;
1687 nct6775_write_value(data, data->REG_TEMP_OFFSET[nr], val);
1688 mutex_unlock(&data->update_lock);
1689
1690 return count;
1691}
1692
1693static ssize_t
1694show_temp_type(struct device *dev, struct device_attribute *attr, char *buf)
1695{
1696 struct nct6775_data *data = nct6775_update_device(dev);
1697 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1698 int nr = sattr->index;
1699 return sprintf(buf, "%d\n", (int)data->temp_type[nr]);
1700}
1701
1702static ssize_t
1703store_temp_type(struct device *dev, struct device_attribute *attr,
1704 const char *buf, size_t count)
1705{
1706 struct nct6775_data *data = nct6775_update_device(dev);
1707 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1708 int nr = sattr->index;
1709 unsigned long val;
1710 int err;
1711 u8 vbat, diode, bit;
1712
1713 err = kstrtoul(buf, 10, &val);
1714 if (err < 0)
1715 return err;
1716
1717 if (val != 1 && val != 3 && val != 4)
1718 return -EINVAL;
1719
1720 mutex_lock(&data->update_lock);
1721
1722 data->temp_type[nr] = val;
1723 vbat = nct6775_read_value(data, data->REG_VBAT) & ~(0x02 << nr);
1724 diode = nct6775_read_value(data, data->REG_DIODE) & ~(0x02 << nr);
1725 bit = 0x02 << nr;
1726 switch (val) {
1727 case 1: /* CPU diode (diode, current mode) */
1728 vbat |= bit;
1729 diode |= bit;
1730 break;
1731 case 3: /* diode, voltage mode */
1732 vbat |= bit;
1733 break;
1734 case 4: /* thermistor */
1735 break;
1736 }
1737 nct6775_write_value(data, data->REG_VBAT, vbat);
1738 nct6775_write_value(data, data->REG_DIODE, diode);
1739
1740 mutex_unlock(&data->update_lock);
1741 return count;
1742}
1743
Guenter Roeckf73cf632013-03-18 09:22:50 -07001744static umode_t nct6775_temp_is_visible(struct kobject *kobj,
1745 struct attribute *attr, int index)
1746{
1747 struct device *dev = container_of(kobj, struct device, kobj);
1748 struct nct6775_data *data = dev_get_drvdata(dev);
1749 int temp = index / 8; /* temp index */
1750 int nr = index % 8; /* attribute index */
1751
1752 if (!(data->have_temp & (1 << temp)))
1753 return 0;
1754
1755 if (nr == 2 && find_temp_source(data, temp, data->num_temp_alarms) < 0)
1756 return 0; /* alarm */
1757
1758 if (nr == 3 && !data->reg_temp[1][temp]) /* max */
1759 return 0;
1760
1761 if (nr == 4 && !data->reg_temp[2][temp]) /* max_hyst */
1762 return 0;
1763
1764 if (nr == 5 && !data->reg_temp[3][temp]) /* crit */
1765 return 0;
1766
1767 if (nr > 5 && !(data->have_temp_fixed & (1 << temp)))
1768 return 0;
1769
1770 return attr->mode;
1771}
1772
1773SENSOR_TEMPLATE_2(temp_input, "temp%d_input", S_IRUGO, show_temp, NULL, 0, 0);
1774SENSOR_TEMPLATE(temp_label, "temp%d_label", S_IRUGO, show_temp_label, NULL, 0);
1775SENSOR_TEMPLATE_2(temp_max, "temp%d_max", S_IRUGO | S_IWUSR, show_temp,
1776 store_temp, 0, 1);
1777SENSOR_TEMPLATE_2(temp_max_hyst, "temp%d_max_hyst", S_IRUGO | S_IWUSR,
1778 show_temp, store_temp, 0, 2);
1779SENSOR_TEMPLATE_2(temp_crit, "temp%d_crit", S_IRUGO | S_IWUSR, show_temp,
1780 store_temp, 0, 3);
1781SENSOR_TEMPLATE(temp_offset, "temp%d_offset", S_IRUGO | S_IWUSR,
1782 show_temp_offset, store_temp_offset, 0);
1783SENSOR_TEMPLATE(temp_type, "temp%d_type", S_IRUGO | S_IWUSR, show_temp_type,
1784 store_temp_type, 0);
1785SENSOR_TEMPLATE(temp_alarm, "temp%d_alarm", S_IRUGO, show_temp_alarm, NULL, 0);
1786
1787/*
1788 * nct6775_temp_is_visible uses the index into the following array
1789 * to determine if attributes should be created or not.
1790 * Any change in order or content must be matched.
1791 */
1792static struct sensor_device_template *nct6775_attributes_temp_template[] = {
1793 &sensor_dev_template_temp_input,
1794 &sensor_dev_template_temp_label,
1795 &sensor_dev_template_temp_alarm, /* 2 */
1796 &sensor_dev_template_temp_max, /* 3 */
1797 &sensor_dev_template_temp_max_hyst, /* 4 */
1798 &sensor_dev_template_temp_crit, /* 5 */
1799 &sensor_dev_template_temp_offset, /* 6 */
1800 &sensor_dev_template_temp_type, /* 7 */
1801 NULL
Guenter Roeckaa136e52012-12-04 03:26:05 -08001802};
1803
Guenter Roeckf73cf632013-03-18 09:22:50 -07001804static struct sensor_template_group nct6775_temp_template_group = {
1805 .templates = nct6775_attributes_temp_template,
1806 .is_visible = nct6775_temp_is_visible,
1807 .base = 1,
Guenter Roeckaa136e52012-12-04 03:26:05 -08001808};
1809
Guenter Roeckaa136e52012-12-04 03:26:05 -08001810static ssize_t
Guenter Roeck77eb5b32012-12-04 08:30:54 -08001811show_pwm_mode(struct device *dev, struct device_attribute *attr, char *buf)
1812{
1813 struct nct6775_data *data = nct6775_update_device(dev);
1814 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1815
1816 return sprintf(buf, "%d\n", !data->pwm_mode[sattr->index]);
1817}
1818
1819static ssize_t
1820store_pwm_mode(struct device *dev, struct device_attribute *attr,
1821 const char *buf, size_t count)
1822{
1823 struct nct6775_data *data = dev_get_drvdata(dev);
1824 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1825 int nr = sattr->index;
1826 unsigned long val;
1827 int err;
1828 u8 reg;
1829
1830 err = kstrtoul(buf, 10, &val);
1831 if (err < 0)
1832 return err;
1833
1834 if (val > 1)
1835 return -EINVAL;
1836
1837 /* Setting DC mode is not supported for all chips/channels */
1838 if (data->REG_PWM_MODE[nr] == 0) {
1839 if (val)
1840 return -EINVAL;
1841 return count;
1842 }
1843
1844 mutex_lock(&data->update_lock);
1845 data->pwm_mode[nr] = val;
1846 reg = nct6775_read_value(data, data->REG_PWM_MODE[nr]);
1847 reg &= ~data->PWM_MODE_MASK[nr];
1848 if (val)
1849 reg |= data->PWM_MODE_MASK[nr];
1850 nct6775_write_value(data, data->REG_PWM_MODE[nr], reg);
1851 mutex_unlock(&data->update_lock);
1852 return count;
1853}
1854
1855static ssize_t
1856show_pwm(struct device *dev, struct device_attribute *attr, char *buf)
1857{
1858 struct nct6775_data *data = nct6775_update_device(dev);
1859 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
1860 int nr = sattr->nr;
1861 int index = sattr->index;
1862 int pwm;
1863
1864 /*
1865 * For automatic fan control modes, show current pwm readings.
1866 * Otherwise, show the configured value.
1867 */
1868 if (index == 0 && data->pwm_enable[nr] > manual)
1869 pwm = nct6775_read_value(data, data->REG_PWM_READ[nr]);
1870 else
1871 pwm = data->pwm[index][nr];
1872
1873 return sprintf(buf, "%d\n", pwm);
1874}
1875
1876static ssize_t
1877store_pwm(struct device *dev, struct device_attribute *attr, const char *buf,
1878 size_t count)
1879{
1880 struct nct6775_data *data = dev_get_drvdata(dev);
1881 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
1882 int nr = sattr->nr;
1883 int index = sattr->index;
1884 unsigned long val;
Guenter Roeckbbd8dec2012-12-04 09:08:29 -08001885 int minval[7] = { 0, 1, 1, data->pwm[2][nr], 0, 0, 0 };
1886 int maxval[7]
1887 = { 255, 255, data->pwm[3][nr] ? : 255, 255, 255, 255, 255 };
Guenter Roeck77eb5b32012-12-04 08:30:54 -08001888 int err;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08001889 u8 reg;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08001890
1891 err = kstrtoul(buf, 10, &val);
1892 if (err < 0)
1893 return err;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08001894 val = clamp_val(val, minval[index], maxval[index]);
Guenter Roeck77eb5b32012-12-04 08:30:54 -08001895
1896 mutex_lock(&data->update_lock);
1897 data->pwm[index][nr] = val;
1898 nct6775_write_value(data, data->REG_PWM[index][nr], val);
Guenter Roeckcdcaece2012-12-04 09:04:52 -08001899 if (index == 2) { /* floor: disable if val == 0 */
1900 reg = nct6775_read_value(data, data->REG_TEMP_SEL[nr]);
1901 reg &= 0x7f;
1902 if (val)
1903 reg |= 0x80;
1904 nct6775_write_value(data, data->REG_TEMP_SEL[nr], reg);
1905 }
Guenter Roeck77eb5b32012-12-04 08:30:54 -08001906 mutex_unlock(&data->update_lock);
1907 return count;
1908}
1909
Guenter Roeckcdcaece2012-12-04 09:04:52 -08001910/* Returns 0 if OK, -EINVAL otherwise */
1911static int check_trip_points(struct nct6775_data *data, int nr)
1912{
1913 int i;
1914
1915 for (i = 0; i < data->auto_pwm_num - 1; i++) {
1916 if (data->auto_temp[nr][i] > data->auto_temp[nr][i + 1])
1917 return -EINVAL;
1918 }
1919 for (i = 0; i < data->auto_pwm_num - 1; i++) {
1920 if (data->auto_pwm[nr][i] > data->auto_pwm[nr][i + 1])
1921 return -EINVAL;
1922 }
1923 /* validate critical temperature and pwm if enabled (pwm > 0) */
1924 if (data->auto_pwm[nr][data->auto_pwm_num]) {
1925 if (data->auto_temp[nr][data->auto_pwm_num - 1] >
1926 data->auto_temp[nr][data->auto_pwm_num] ||
1927 data->auto_pwm[nr][data->auto_pwm_num - 1] >
1928 data->auto_pwm[nr][data->auto_pwm_num])
1929 return -EINVAL;
1930 }
1931 return 0;
1932}
1933
1934static void pwm_update_registers(struct nct6775_data *data, int nr)
1935{
1936 u8 reg;
1937
1938 switch (data->pwm_enable[nr]) {
1939 case off:
1940 case manual:
1941 break;
1942 case speed_cruise:
1943 reg = nct6775_read_value(data, data->REG_FAN_MODE[nr]);
1944 reg = (reg & ~data->tolerance_mask) |
1945 (data->target_speed_tolerance[nr] & data->tolerance_mask);
1946 nct6775_write_value(data, data->REG_FAN_MODE[nr], reg);
1947 nct6775_write_value(data, data->REG_TARGET[nr],
1948 data->target_speed[nr] & 0xff);
1949 if (data->REG_TOLERANCE_H) {
1950 reg = (data->target_speed[nr] >> 8) & 0x0f;
1951 reg |= (data->target_speed_tolerance[nr] & 0x38) << 1;
1952 nct6775_write_value(data,
1953 data->REG_TOLERANCE_H[nr],
1954 reg);
1955 }
1956 break;
1957 case thermal_cruise:
1958 nct6775_write_value(data, data->REG_TARGET[nr],
1959 data->target_temp[nr]);
1960 /* intentional */
1961 default:
1962 reg = nct6775_read_value(data, data->REG_FAN_MODE[nr]);
1963 reg = (reg & ~data->tolerance_mask) |
1964 data->temp_tolerance[0][nr];
1965 nct6775_write_value(data, data->REG_FAN_MODE[nr], reg);
1966 break;
1967 }
1968}
1969
Guenter Roeck77eb5b32012-12-04 08:30:54 -08001970static ssize_t
1971show_pwm_enable(struct device *dev, struct device_attribute *attr, char *buf)
1972{
1973 struct nct6775_data *data = nct6775_update_device(dev);
1974 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1975
1976 return sprintf(buf, "%d\n", data->pwm_enable[sattr->index]);
1977}
1978
1979static ssize_t
1980store_pwm_enable(struct device *dev, struct device_attribute *attr,
1981 const char *buf, size_t count)
1982{
1983 struct nct6775_data *data = dev_get_drvdata(dev);
1984 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1985 int nr = sattr->index;
1986 unsigned long val;
1987 int err;
1988 u16 reg;
1989
1990 err = kstrtoul(buf, 10, &val);
1991 if (err < 0)
1992 return err;
1993
1994 if (val > sf4)
1995 return -EINVAL;
1996
1997 if (val == sf3 && data->kind != nct6775)
1998 return -EINVAL;
1999
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002000 if (val == sf4 && check_trip_points(data, nr)) {
2001 dev_err(dev, "Inconsistent trip points, not switching to SmartFan IV mode\n");
2002 dev_err(dev, "Adjust trip points and try again\n");
2003 return -EINVAL;
2004 }
2005
Guenter Roeck77eb5b32012-12-04 08:30:54 -08002006 mutex_lock(&data->update_lock);
2007 data->pwm_enable[nr] = val;
2008 if (val == off) {
2009 /*
2010 * turn off pwm control: select manual mode, set pwm to maximum
2011 */
2012 data->pwm[0][nr] = 255;
2013 nct6775_write_value(data, data->REG_PWM[0][nr], 255);
2014 }
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002015 pwm_update_registers(data, nr);
Guenter Roeck77eb5b32012-12-04 08:30:54 -08002016 reg = nct6775_read_value(data, data->REG_FAN_MODE[nr]);
2017 reg &= 0x0f;
2018 reg |= pwm_enable_to_reg(val) << 4;
2019 nct6775_write_value(data, data->REG_FAN_MODE[nr], reg);
2020 mutex_unlock(&data->update_lock);
2021 return count;
2022}
2023
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002024static ssize_t
Guenter Roeckbbd8dec2012-12-04 09:08:29 -08002025show_pwm_temp_sel_common(struct nct6775_data *data, char *buf, int src)
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002026{
Guenter Roeckbbd8dec2012-12-04 09:08:29 -08002027 int i, sel = 0;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002028
2029 for (i = 0; i < NUM_TEMP; i++) {
2030 if (!(data->have_temp & (1 << i)))
2031 continue;
2032 if (src == data->temp_src[i]) {
2033 sel = i + 1;
2034 break;
2035 }
2036 }
2037
2038 return sprintf(buf, "%d\n", sel);
2039}
2040
2041static ssize_t
Guenter Roeckbbd8dec2012-12-04 09:08:29 -08002042show_pwm_temp_sel(struct device *dev, struct device_attribute *attr, char *buf)
2043{
2044 struct nct6775_data *data = nct6775_update_device(dev);
2045 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2046 int index = sattr->index;
2047
2048 return show_pwm_temp_sel_common(data, buf, data->pwm_temp_sel[index]);
2049}
2050
2051static ssize_t
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002052store_pwm_temp_sel(struct device *dev, struct device_attribute *attr,
2053 const char *buf, size_t count)
2054{
2055 struct nct6775_data *data = nct6775_update_device(dev);
2056 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2057 int nr = sattr->index;
2058 unsigned long val;
2059 int err, reg, src;
2060
2061 err = kstrtoul(buf, 10, &val);
2062 if (err < 0)
2063 return err;
2064 if (val == 0 || val > NUM_TEMP)
2065 return -EINVAL;
2066 if (!(data->have_temp & (1 << (val - 1))) || !data->temp_src[val - 1])
2067 return -EINVAL;
2068
2069 mutex_lock(&data->update_lock);
2070 src = data->temp_src[val - 1];
2071 data->pwm_temp_sel[nr] = src;
2072 reg = nct6775_read_value(data, data->REG_TEMP_SEL[nr]);
2073 reg &= 0xe0;
2074 reg |= src;
2075 nct6775_write_value(data, data->REG_TEMP_SEL[nr], reg);
2076 mutex_unlock(&data->update_lock);
2077
2078 return count;
2079}
2080
2081static ssize_t
Guenter Roeckbbd8dec2012-12-04 09:08:29 -08002082show_pwm_weight_temp_sel(struct device *dev, struct device_attribute *attr,
2083 char *buf)
2084{
2085 struct nct6775_data *data = nct6775_update_device(dev);
2086 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2087 int index = sattr->index;
2088
2089 return show_pwm_temp_sel_common(data, buf,
2090 data->pwm_weight_temp_sel[index]);
2091}
2092
2093static ssize_t
2094store_pwm_weight_temp_sel(struct device *dev, struct device_attribute *attr,
2095 const char *buf, size_t count)
2096{
2097 struct nct6775_data *data = nct6775_update_device(dev);
2098 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2099 int nr = sattr->index;
2100 unsigned long val;
2101 int err, reg, src;
2102
2103 err = kstrtoul(buf, 10, &val);
2104 if (err < 0)
2105 return err;
2106 if (val > NUM_TEMP)
2107 return -EINVAL;
2108 if (val && (!(data->have_temp & (1 << (val - 1))) ||
2109 !data->temp_src[val - 1]))
2110 return -EINVAL;
2111
2112 mutex_lock(&data->update_lock);
2113 if (val) {
2114 src = data->temp_src[val - 1];
2115 data->pwm_weight_temp_sel[nr] = src;
2116 reg = nct6775_read_value(data, data->REG_WEIGHT_TEMP_SEL[nr]);
2117 reg &= 0xe0;
2118 reg |= (src | 0x80);
2119 nct6775_write_value(data, data->REG_WEIGHT_TEMP_SEL[nr], reg);
2120 } else {
2121 data->pwm_weight_temp_sel[nr] = 0;
2122 reg = nct6775_read_value(data, data->REG_WEIGHT_TEMP_SEL[nr]);
2123 reg &= 0x7f;
2124 nct6775_write_value(data, data->REG_WEIGHT_TEMP_SEL[nr], reg);
2125 }
2126 mutex_unlock(&data->update_lock);
2127
2128 return count;
2129}
2130
2131static ssize_t
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002132show_target_temp(struct device *dev, struct device_attribute *attr, char *buf)
2133{
2134 struct nct6775_data *data = nct6775_update_device(dev);
2135 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2136
2137 return sprintf(buf, "%d\n", data->target_temp[sattr->index] * 1000);
2138}
2139
2140static ssize_t
2141store_target_temp(struct device *dev, struct device_attribute *attr,
2142 const char *buf, size_t count)
2143{
2144 struct nct6775_data *data = dev_get_drvdata(dev);
2145 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2146 int nr = sattr->index;
2147 unsigned long val;
2148 int err;
2149
2150 err = kstrtoul(buf, 10, &val);
2151 if (err < 0)
2152 return err;
2153
2154 val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0,
2155 data->target_temp_mask);
2156
2157 mutex_lock(&data->update_lock);
2158 data->target_temp[nr] = val;
2159 pwm_update_registers(data, nr);
2160 mutex_unlock(&data->update_lock);
2161 return count;
2162}
2163
2164static ssize_t
2165show_target_speed(struct device *dev, struct device_attribute *attr, char *buf)
2166{
2167 struct nct6775_data *data = nct6775_update_device(dev);
2168 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2169 int nr = sattr->index;
2170
2171 return sprintf(buf, "%d\n",
2172 fan_from_reg16(data->target_speed[nr],
2173 data->fan_div[nr]));
2174}
2175
2176static ssize_t
2177store_target_speed(struct device *dev, struct device_attribute *attr,
2178 const char *buf, size_t count)
2179{
2180 struct nct6775_data *data = dev_get_drvdata(dev);
2181 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2182 int nr = sattr->index;
2183 unsigned long val;
2184 int err;
2185 u16 speed;
2186
2187 err = kstrtoul(buf, 10, &val);
2188 if (err < 0)
2189 return err;
2190
2191 val = clamp_val(val, 0, 1350000U);
2192 speed = fan_to_reg(val, data->fan_div[nr]);
2193
2194 mutex_lock(&data->update_lock);
2195 data->target_speed[nr] = speed;
2196 pwm_update_registers(data, nr);
2197 mutex_unlock(&data->update_lock);
2198 return count;
2199}
2200
2201static ssize_t
2202show_temp_tolerance(struct device *dev, struct device_attribute *attr,
2203 char *buf)
2204{
2205 struct nct6775_data *data = nct6775_update_device(dev);
2206 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2207 int nr = sattr->nr;
2208 int index = sattr->index;
2209
2210 return sprintf(buf, "%d\n", data->temp_tolerance[index][nr] * 1000);
2211}
2212
2213static ssize_t
2214store_temp_tolerance(struct device *dev, struct device_attribute *attr,
2215 const char *buf, size_t count)
2216{
2217 struct nct6775_data *data = dev_get_drvdata(dev);
2218 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2219 int nr = sattr->nr;
2220 int index = sattr->index;
2221 unsigned long val;
2222 int err;
2223
2224 err = kstrtoul(buf, 10, &val);
2225 if (err < 0)
2226 return err;
2227
2228 /* Limit tolerance as needed */
2229 val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0, data->tolerance_mask);
2230
2231 mutex_lock(&data->update_lock);
2232 data->temp_tolerance[index][nr] = val;
2233 if (index)
2234 pwm_update_registers(data, nr);
2235 else
2236 nct6775_write_value(data,
2237 data->REG_CRITICAL_TEMP_TOLERANCE[nr],
2238 val);
2239 mutex_unlock(&data->update_lock);
2240 return count;
2241}
2242
2243/*
2244 * Fan speed tolerance is a tricky beast, since the associated register is
2245 * a tick counter, but the value is reported and configured as rpm.
2246 * Compute resulting low and high rpm values and report the difference.
2247 */
2248static ssize_t
2249show_speed_tolerance(struct device *dev, struct device_attribute *attr,
2250 char *buf)
2251{
2252 struct nct6775_data *data = nct6775_update_device(dev);
2253 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2254 int nr = sattr->index;
2255 int low = data->target_speed[nr] - data->target_speed_tolerance[nr];
2256 int high = data->target_speed[nr] + data->target_speed_tolerance[nr];
2257 int tolerance;
2258
2259 if (low <= 0)
2260 low = 1;
2261 if (high > 0xffff)
2262 high = 0xffff;
2263 if (high < low)
2264 high = low;
2265
2266 tolerance = (fan_from_reg16(low, data->fan_div[nr])
2267 - fan_from_reg16(high, data->fan_div[nr])) / 2;
2268
2269 return sprintf(buf, "%d\n", tolerance);
2270}
2271
2272static ssize_t
2273store_speed_tolerance(struct device *dev, struct device_attribute *attr,
2274 const char *buf, size_t count)
2275{
2276 struct nct6775_data *data = dev_get_drvdata(dev);
2277 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2278 int nr = sattr->index;
2279 unsigned long val;
2280 int err;
2281 int low, high;
2282
2283 err = kstrtoul(buf, 10, &val);
2284 if (err < 0)
2285 return err;
2286
2287 high = fan_from_reg16(data->target_speed[nr],
2288 data->fan_div[nr]) + val;
2289 low = fan_from_reg16(data->target_speed[nr],
2290 data->fan_div[nr]) - val;
2291 if (low <= 0)
2292 low = 1;
2293 if (high < low)
2294 high = low;
2295
2296 val = (fan_to_reg(low, data->fan_div[nr]) -
2297 fan_to_reg(high, data->fan_div[nr])) / 2;
2298
2299 /* Limit tolerance as needed */
2300 val = clamp_val(val, 0, data->speed_tolerance_limit);
2301
2302 mutex_lock(&data->update_lock);
2303 data->target_speed_tolerance[nr] = val;
2304 pwm_update_registers(data, nr);
2305 mutex_unlock(&data->update_lock);
2306 return count;
2307}
2308
Guenter Roeckf73cf632013-03-18 09:22:50 -07002309SENSOR_TEMPLATE_2(pwm, "pwm%d", S_IWUSR | S_IRUGO, show_pwm, store_pwm, 0, 0);
2310SENSOR_TEMPLATE(pwm_mode, "pwm%d_mode", S_IWUSR | S_IRUGO, show_pwm_mode,
2311 store_pwm_mode, 0);
2312SENSOR_TEMPLATE(pwm_enable, "pwm%d_enable", S_IWUSR | S_IRUGO, show_pwm_enable,
2313 store_pwm_enable, 0);
2314SENSOR_TEMPLATE(pwm_temp_sel, "pwm%d_temp_sel", S_IWUSR | S_IRUGO,
2315 show_pwm_temp_sel, store_pwm_temp_sel, 0);
2316SENSOR_TEMPLATE(pwm_target_temp, "pwm%d_target_temp", S_IWUSR | S_IRUGO,
2317 show_target_temp, store_target_temp, 0);
2318SENSOR_TEMPLATE(fan_target, "fan%d_target", S_IWUSR | S_IRUGO,
2319 show_target_speed, store_target_speed, 0);
2320SENSOR_TEMPLATE(fan_tolerance, "fan%d_tolerance", S_IWUSR | S_IRUGO,
2321 show_speed_tolerance, store_speed_tolerance, 0);
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002322
2323/* Smart Fan registers */
2324
2325static ssize_t
Guenter Roeckbbd8dec2012-12-04 09:08:29 -08002326show_weight_temp(struct device *dev, struct device_attribute *attr, char *buf)
2327{
2328 struct nct6775_data *data = nct6775_update_device(dev);
2329 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2330 int nr = sattr->nr;
2331 int index = sattr->index;
2332
2333 return sprintf(buf, "%d\n", data->weight_temp[index][nr] * 1000);
2334}
2335
2336static ssize_t
2337store_weight_temp(struct device *dev, struct device_attribute *attr,
2338 const char *buf, size_t count)
2339{
2340 struct nct6775_data *data = dev_get_drvdata(dev);
2341 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2342 int nr = sattr->nr;
2343 int index = sattr->index;
2344 unsigned long val;
2345 int err;
2346
2347 err = kstrtoul(buf, 10, &val);
2348 if (err < 0)
2349 return err;
2350
2351 val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0, 255);
2352
2353 mutex_lock(&data->update_lock);
2354 data->weight_temp[index][nr] = val;
2355 nct6775_write_value(data, data->REG_WEIGHT_TEMP[index][nr], val);
2356 mutex_unlock(&data->update_lock);
2357 return count;
2358}
2359
Guenter Roeckf73cf632013-03-18 09:22:50 -07002360SENSOR_TEMPLATE(pwm_weight_temp_sel, "pwm%d_weight_temp_sel", S_IWUSR | S_IRUGO,
2361 show_pwm_weight_temp_sel, store_pwm_weight_temp_sel, 0);
2362SENSOR_TEMPLATE_2(pwm_weight_temp_step, "pwm%d_weight_temp_step",
2363 S_IWUSR | S_IRUGO, show_weight_temp, store_weight_temp, 0, 0);
2364SENSOR_TEMPLATE_2(pwm_weight_temp_step_tol, "pwm%d_weight_temp_step_tol",
2365 S_IWUSR | S_IRUGO, show_weight_temp, store_weight_temp, 0, 1);
2366SENSOR_TEMPLATE_2(pwm_weight_temp_step_base, "pwm%d_weight_temp_step_base",
2367 S_IWUSR | S_IRUGO, show_weight_temp, store_weight_temp, 0, 2);
2368SENSOR_TEMPLATE_2(pwm_weight_duty_step, "pwm%d_weight_duty_step",
2369 S_IWUSR | S_IRUGO, show_pwm, store_pwm, 0, 5);
2370SENSOR_TEMPLATE_2(pwm_weight_duty_base, "pwm%d_weight_duty_base",
2371 S_IWUSR | S_IRUGO, show_pwm, store_pwm, 0, 6);
Guenter Roeckbbd8dec2012-12-04 09:08:29 -08002372
2373static ssize_t
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002374show_fan_time(struct device *dev, struct device_attribute *attr, char *buf)
2375{
2376 struct nct6775_data *data = nct6775_update_device(dev);
2377 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2378 int nr = sattr->nr;
2379 int index = sattr->index;
2380
2381 return sprintf(buf, "%d\n",
2382 step_time_from_reg(data->fan_time[index][nr],
2383 data->pwm_mode[nr]));
2384}
2385
2386static ssize_t
2387store_fan_time(struct device *dev, struct device_attribute *attr,
2388 const char *buf, size_t count)
2389{
2390 struct nct6775_data *data = dev_get_drvdata(dev);
2391 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2392 int nr = sattr->nr;
2393 int index = sattr->index;
2394 unsigned long val;
2395 int err;
2396
2397 err = kstrtoul(buf, 10, &val);
2398 if (err < 0)
2399 return err;
2400
2401 val = step_time_to_reg(val, data->pwm_mode[nr]);
2402 mutex_lock(&data->update_lock);
2403 data->fan_time[index][nr] = val;
2404 nct6775_write_value(data, data->REG_FAN_TIME[index][nr], val);
2405 mutex_unlock(&data->update_lock);
2406 return count;
2407}
2408
Guenter Roeck77eb5b32012-12-04 08:30:54 -08002409static ssize_t
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07002410show_name(struct device *dev, struct device_attribute *attr, char *buf)
2411{
2412 struct nct6775_data *data = dev_get_drvdata(dev);
2413
2414 return sprintf(buf, "%s\n", data->name);
2415}
2416
2417static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
2418
2419static ssize_t
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002420show_auto_pwm(struct device *dev, struct device_attribute *attr, char *buf)
2421{
2422 struct nct6775_data *data = nct6775_update_device(dev);
2423 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2424
2425 return sprintf(buf, "%d\n", data->auto_pwm[sattr->nr][sattr->index]);
2426}
2427
2428static ssize_t
2429store_auto_pwm(struct device *dev, struct device_attribute *attr,
2430 const char *buf, size_t count)
2431{
2432 struct nct6775_data *data = dev_get_drvdata(dev);
2433 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2434 int nr = sattr->nr;
2435 int point = sattr->index;
2436 unsigned long val;
2437 int err;
2438 u8 reg;
2439
2440 err = kstrtoul(buf, 10, &val);
2441 if (err < 0)
2442 return err;
2443 if (val > 255)
2444 return -EINVAL;
2445
2446 if (point == data->auto_pwm_num) {
2447 if (data->kind != nct6775 && !val)
2448 return -EINVAL;
2449 if (data->kind != nct6779 && val)
2450 val = 0xff;
2451 }
2452
2453 mutex_lock(&data->update_lock);
2454 data->auto_pwm[nr][point] = val;
2455 if (point < data->auto_pwm_num) {
2456 nct6775_write_value(data,
2457 NCT6775_AUTO_PWM(data, nr, point),
2458 data->auto_pwm[nr][point]);
2459 } else {
2460 switch (data->kind) {
2461 case nct6775:
2462 /* disable if needed (pwm == 0) */
2463 reg = nct6775_read_value(data,
2464 NCT6775_REG_CRITICAL_ENAB[nr]);
2465 if (val)
2466 reg |= 0x02;
2467 else
2468 reg &= ~0x02;
2469 nct6775_write_value(data, NCT6775_REG_CRITICAL_ENAB[nr],
2470 reg);
2471 break;
2472 case nct6776:
2473 break; /* always enabled, nothing to do */
2474 case nct6779:
2475 nct6775_write_value(data, NCT6779_REG_CRITICAL_PWM[nr],
2476 val);
2477 reg = nct6775_read_value(data,
2478 NCT6779_REG_CRITICAL_PWM_ENABLE[nr]);
2479 if (val == 255)
2480 reg &= ~0x01;
2481 else
2482 reg |= 0x01;
2483 nct6775_write_value(data,
2484 NCT6779_REG_CRITICAL_PWM_ENABLE[nr],
2485 reg);
2486 break;
2487 }
2488 }
2489 mutex_unlock(&data->update_lock);
2490 return count;
2491}
2492
2493static ssize_t
2494show_auto_temp(struct device *dev, struct device_attribute *attr, char *buf)
2495{
2496 struct nct6775_data *data = nct6775_update_device(dev);
2497 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2498 int nr = sattr->nr;
2499 int point = sattr->index;
2500
2501 /*
2502 * We don't know for sure if the temperature is signed or unsigned.
2503 * Assume it is unsigned.
2504 */
2505 return sprintf(buf, "%d\n", data->auto_temp[nr][point] * 1000);
2506}
2507
2508static ssize_t
2509store_auto_temp(struct device *dev, struct device_attribute *attr,
2510 const char *buf, size_t count)
2511{
2512 struct nct6775_data *data = dev_get_drvdata(dev);
2513 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2514 int nr = sattr->nr;
2515 int point = sattr->index;
2516 unsigned long val;
2517 int err;
2518
2519 err = kstrtoul(buf, 10, &val);
2520 if (err)
2521 return err;
2522 if (val > 255000)
2523 return -EINVAL;
2524
2525 mutex_lock(&data->update_lock);
2526 data->auto_temp[nr][point] = DIV_ROUND_CLOSEST(val, 1000);
2527 if (point < data->auto_pwm_num) {
2528 nct6775_write_value(data,
2529 NCT6775_AUTO_TEMP(data, nr, point),
2530 data->auto_temp[nr][point]);
2531 } else {
2532 nct6775_write_value(data, data->REG_CRITICAL_TEMP[nr],
2533 data->auto_temp[nr][point]);
2534 }
2535 mutex_unlock(&data->update_lock);
2536 return count;
2537}
2538
Guenter Roeckf73cf632013-03-18 09:22:50 -07002539static umode_t nct6775_pwm_is_visible(struct kobject *kobj,
2540 struct attribute *attr, int index)
2541{
2542 struct device *dev = container_of(kobj, struct device, kobj);
2543 struct nct6775_data *data = dev_get_drvdata(dev);
2544 int pwm = index / 36; /* pwm index */
2545 int nr = index % 36; /* attribute index */
2546
2547 if (!(data->has_pwm & (1 << pwm)))
2548 return 0;
2549
2550 if (nr == 19 && data->REG_PWM[3] == NULL) /* pwm_max */
2551 return 0;
2552 if (nr == 20 && data->REG_PWM[4] == NULL) /* pwm_step */
2553 return 0;
2554 if (nr == 21 && data->REG_PWM[6] == NULL) /* weight_duty_base */
2555 return 0;
2556
2557 if (nr >= 22 && nr <= 35) { /* auto point */
2558 int api = (nr - 22) / 2; /* auto point index */
2559
2560 if (api > data->auto_pwm_num)
2561 return 0;
2562 }
2563 return attr->mode;
2564}
2565
2566SENSOR_TEMPLATE_2(pwm_stop_time, "pwm%d_stop_time", S_IWUSR | S_IRUGO,
2567 show_fan_time, store_fan_time, 0, 0);
2568SENSOR_TEMPLATE_2(pwm_step_up_time, "pwm%d_step_up_time", S_IWUSR | S_IRUGO,
2569 show_fan_time, store_fan_time, 0, 1);
2570SENSOR_TEMPLATE_2(pwm_step_down_time, "pwm%d_step_down_time", S_IWUSR | S_IRUGO,
2571 show_fan_time, store_fan_time, 0, 2);
2572SENSOR_TEMPLATE_2(pwm_start, "pwm%d_start", S_IWUSR | S_IRUGO, show_pwm,
2573 store_pwm, 0, 1);
2574SENSOR_TEMPLATE_2(pwm_floor, "pwm%d_floor", S_IWUSR | S_IRUGO, show_pwm,
2575 store_pwm, 0, 2);
2576SENSOR_TEMPLATE_2(pwm_temp_tolerance, "pwm%d_temp_tolerance", S_IWUSR | S_IRUGO,
2577 show_temp_tolerance, store_temp_tolerance, 0, 0);
2578SENSOR_TEMPLATE_2(pwm_crit_temp_tolerance, "pwm%d_crit_temp_tolerance",
2579 S_IWUSR | S_IRUGO, show_temp_tolerance, store_temp_tolerance,
2580 0, 1);
2581
2582SENSOR_TEMPLATE_2(pwm_max, "pwm%d_max", S_IWUSR | S_IRUGO, show_pwm, store_pwm,
2583 0, 3);
2584
2585SENSOR_TEMPLATE_2(pwm_step, "pwm%d_step", S_IWUSR | S_IRUGO, show_pwm,
2586 store_pwm, 0, 4);
2587
2588SENSOR_TEMPLATE_2(pwm_auto_point1_pwm, "pwm%d_auto_point1_pwm",
2589 S_IWUSR | S_IRUGO, show_auto_pwm, store_auto_pwm, 0, 0);
2590SENSOR_TEMPLATE_2(pwm_auto_point1_temp, "pwm%d_auto_point1_temp",
2591 S_IWUSR | S_IRUGO, show_auto_temp, store_auto_temp, 0, 0);
2592
2593SENSOR_TEMPLATE_2(pwm_auto_point2_pwm, "pwm%d_auto_point2_pwm",
2594 S_IWUSR | S_IRUGO, show_auto_pwm, store_auto_pwm, 0, 1);
2595SENSOR_TEMPLATE_2(pwm_auto_point2_temp, "pwm%d_auto_point2_temp",
2596 S_IWUSR | S_IRUGO, show_auto_temp, store_auto_temp, 0, 1);
2597
2598SENSOR_TEMPLATE_2(pwm_auto_point3_pwm, "pwm%d_auto_point3_pwm",
2599 S_IWUSR | S_IRUGO, show_auto_pwm, store_auto_pwm, 0, 2);
2600SENSOR_TEMPLATE_2(pwm_auto_point3_temp, "pwm%d_auto_point3_temp",
2601 S_IWUSR | S_IRUGO, show_auto_temp, store_auto_temp, 0, 2);
2602
2603SENSOR_TEMPLATE_2(pwm_auto_point4_pwm, "pwm%d_auto_point4_pwm",
2604 S_IWUSR | S_IRUGO, show_auto_pwm, store_auto_pwm, 0, 3);
2605SENSOR_TEMPLATE_2(pwm_auto_point4_temp, "pwm%d_auto_point4_temp",
2606 S_IWUSR | S_IRUGO, show_auto_temp, store_auto_temp, 0, 3);
2607
2608SENSOR_TEMPLATE_2(pwm_auto_point5_pwm, "pwm%d_auto_point5_pwm",
2609 S_IWUSR | S_IRUGO, show_auto_pwm, store_auto_pwm, 0, 4);
2610SENSOR_TEMPLATE_2(pwm_auto_point5_temp, "pwm%d_auto_point5_temp",
2611 S_IWUSR | S_IRUGO, show_auto_temp, store_auto_temp, 0, 4);
2612
2613SENSOR_TEMPLATE_2(pwm_auto_point6_pwm, "pwm%d_auto_point6_pwm",
2614 S_IWUSR | S_IRUGO, show_auto_pwm, store_auto_pwm, 0, 5);
2615SENSOR_TEMPLATE_2(pwm_auto_point6_temp, "pwm%d_auto_point6_temp",
2616 S_IWUSR | S_IRUGO, show_auto_temp, store_auto_temp, 0, 5);
2617
2618SENSOR_TEMPLATE_2(pwm_auto_point7_pwm, "pwm%d_auto_point7_pwm",
2619 S_IWUSR | S_IRUGO, show_auto_pwm, store_auto_pwm, 0, 6);
2620SENSOR_TEMPLATE_2(pwm_auto_point7_temp, "pwm%d_auto_point7_temp",
2621 S_IWUSR | S_IRUGO, show_auto_temp, store_auto_temp, 0, 6);
2622
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002623/*
Guenter Roeckf73cf632013-03-18 09:22:50 -07002624 * nct6775_pwm_is_visible uses the index into the following array
2625 * to determine if attributes should be created or not.
2626 * Any change in order or content must be matched.
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002627 */
Guenter Roeckf73cf632013-03-18 09:22:50 -07002628static struct sensor_device_template *nct6775_attributes_pwm_template[] = {
2629 &sensor_dev_template_pwm,
2630 &sensor_dev_template_pwm_mode,
2631 &sensor_dev_template_pwm_enable,
2632 &sensor_dev_template_pwm_temp_sel,
2633 &sensor_dev_template_pwm_temp_tolerance,
2634 &sensor_dev_template_pwm_crit_temp_tolerance,
2635 &sensor_dev_template_pwm_target_temp,
2636 &sensor_dev_template_fan_target,
2637 &sensor_dev_template_fan_tolerance,
2638 &sensor_dev_template_pwm_stop_time,
2639 &sensor_dev_template_pwm_step_up_time,
2640 &sensor_dev_template_pwm_step_down_time,
2641 &sensor_dev_template_pwm_start,
2642 &sensor_dev_template_pwm_floor,
2643 &sensor_dev_template_pwm_weight_temp_sel,
2644 &sensor_dev_template_pwm_weight_temp_step,
2645 &sensor_dev_template_pwm_weight_temp_step_tol,
2646 &sensor_dev_template_pwm_weight_temp_step_base,
2647 &sensor_dev_template_pwm_weight_duty_step,
2648 &sensor_dev_template_pwm_max, /* 19 */
2649 &sensor_dev_template_pwm_step, /* 20 */
2650 &sensor_dev_template_pwm_weight_duty_base, /* 21 */
2651 &sensor_dev_template_pwm_auto_point1_pwm, /* 22 */
2652 &sensor_dev_template_pwm_auto_point1_temp,
2653 &sensor_dev_template_pwm_auto_point2_pwm,
2654 &sensor_dev_template_pwm_auto_point2_temp,
2655 &sensor_dev_template_pwm_auto_point3_pwm,
2656 &sensor_dev_template_pwm_auto_point3_temp,
2657 &sensor_dev_template_pwm_auto_point4_pwm,
2658 &sensor_dev_template_pwm_auto_point4_temp,
2659 &sensor_dev_template_pwm_auto_point5_pwm,
2660 &sensor_dev_template_pwm_auto_point5_temp,
2661 &sensor_dev_template_pwm_auto_point6_pwm,
2662 &sensor_dev_template_pwm_auto_point6_temp,
2663 &sensor_dev_template_pwm_auto_point7_pwm,
2664 &sensor_dev_template_pwm_auto_point7_temp, /* 35 */
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002665
Guenter Roeckf73cf632013-03-18 09:22:50 -07002666 NULL
2667};
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002668
Guenter Roeckf73cf632013-03-18 09:22:50 -07002669static struct sensor_template_group nct6775_pwm_template_group = {
2670 .templates = nct6775_attributes_pwm_template,
2671 .is_visible = nct6775_pwm_is_visible,
2672 .base = 1,
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002673};
2674
2675static ssize_t
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07002676show_vid(struct device *dev, struct device_attribute *attr, char *buf)
2677{
2678 struct nct6775_data *data = dev_get_drvdata(dev);
2679 return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm));
2680}
2681
2682static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL);
2683
Guenter Roecka6bd5872012-12-04 03:13:34 -08002684/* Case open detection */
2685
2686static ssize_t
2687clear_caseopen(struct device *dev, struct device_attribute *attr,
2688 const char *buf, size_t count)
2689{
2690 struct nct6775_data *data = dev_get_drvdata(dev);
2691 struct nct6775_sio_data *sio_data = dev->platform_data;
2692 int nr = to_sensor_dev_attr(attr)->index - INTRUSION_ALARM_BASE;
2693 unsigned long val;
2694 u8 reg;
2695 int ret;
2696
2697 if (kstrtoul(buf, 10, &val) || val != 0)
2698 return -EINVAL;
2699
2700 mutex_lock(&data->update_lock);
2701
2702 /*
2703 * Use CR registers to clear caseopen status.
2704 * The CR registers are the same for all chips, and not all chips
2705 * support clearing the caseopen status through "regular" registers.
2706 */
2707 ret = superio_enter(sio_data->sioreg);
2708 if (ret) {
2709 count = ret;
2710 goto error;
2711 }
2712
2713 superio_select(sio_data->sioreg, NCT6775_LD_ACPI);
2714 reg = superio_inb(sio_data->sioreg, NCT6775_REG_CR_CASEOPEN_CLR[nr]);
2715 reg |= NCT6775_CR_CASEOPEN_CLR_MASK[nr];
2716 superio_outb(sio_data->sioreg, NCT6775_REG_CR_CASEOPEN_CLR[nr], reg);
2717 reg &= ~NCT6775_CR_CASEOPEN_CLR_MASK[nr];
2718 superio_outb(sio_data->sioreg, NCT6775_REG_CR_CASEOPEN_CLR[nr], reg);
2719 superio_exit(sio_data->sioreg);
2720
2721 data->valid = false; /* Force cache refresh */
2722error:
2723 mutex_unlock(&data->update_lock);
2724 return count;
2725}
2726
Guenter Roeckf73cf632013-03-18 09:22:50 -07002727static SENSOR_DEVICE_ATTR(intrusion0_alarm, S_IWUSR | S_IRUGO, show_alarm,
2728 clear_caseopen, INTRUSION_ALARM_BASE);
2729static SENSOR_DEVICE_ATTR(intrusion1_alarm, S_IWUSR | S_IRUGO, show_alarm,
2730 clear_caseopen, INTRUSION_ALARM_BASE + 1);
2731
2732static umode_t nct6775_other_is_visible(struct kobject *kobj,
2733 struct attribute *attr, int index)
2734{
2735 struct device *dev = container_of(kobj, struct device, kobj);
2736 struct nct6775_data *data = dev_get_drvdata(dev);
2737
2738 if (index == 1 && !data->have_vid)
2739 return 0;
2740
2741 if (index == 2 || index == 3) {
2742 if (data->ALARM_BITS[INTRUSION_ALARM_BASE + index - 2] < 0)
2743 return 0;
2744 }
2745
2746 return attr->mode;
2747}
2748
2749/*
2750 * nct6775_other_is_visible uses the index into the following array
2751 * to determine if attributes should be created or not.
2752 * Any change in order or content must be matched.
2753 */
2754static struct attribute *nct6775_attributes_other[] = {
2755 &dev_attr_name.attr,
2756 &dev_attr_cpu0_vid.attr, /* 1 */
2757 &sensor_dev_attr_intrusion0_alarm.dev_attr.attr, /* 2 */
2758 &sensor_dev_attr_intrusion1_alarm.dev_attr.attr, /* 3 */
2759
2760 NULL
2761};
2762
2763static const struct attribute_group nct6775_group_other = {
2764 .attrs = nct6775_attributes_other,
2765 .is_visible = nct6775_other_is_visible,
Guenter Roecka6bd5872012-12-04 03:13:34 -08002766};
2767
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07002768/*
2769 * Driver and device management
2770 */
2771
2772static void nct6775_device_remove_files(struct device *dev)
2773{
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07002774 struct nct6775_data *data = dev_get_drvdata(dev);
2775
Guenter Roeckf73cf632013-03-18 09:22:50 -07002776 if (data->group_pwm)
2777 sysfs_remove_group(&dev->kobj, data->group_pwm);
2778 if (data->group_in)
2779 sysfs_remove_group(&dev->kobj, data->group_in);
2780 if (data->group_fan)
2781 sysfs_remove_group(&dev->kobj, data->group_fan);
2782 if (data->group_temp)
2783 sysfs_remove_group(&dev->kobj, data->group_temp);
Guenter Roeck77eb5b32012-12-04 08:30:54 -08002784
Guenter Roeckf73cf632013-03-18 09:22:50 -07002785 sysfs_remove_group(&dev->kobj, &nct6775_group_other);
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07002786}
2787
2788/* Get the monitoring functions started */
2789static inline void nct6775_init_device(struct nct6775_data *data)
2790{
Guenter Roeckaa136e52012-12-04 03:26:05 -08002791 int i;
2792 u8 tmp, diode;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07002793
2794 /* Start monitoring if needed */
2795 if (data->REG_CONFIG) {
2796 tmp = nct6775_read_value(data, data->REG_CONFIG);
2797 if (!(tmp & 0x01))
2798 nct6775_write_value(data, data->REG_CONFIG, tmp | 0x01);
2799 }
2800
Guenter Roeckaa136e52012-12-04 03:26:05 -08002801 /* Enable temperature sensors if needed */
2802 for (i = 0; i < NUM_TEMP; i++) {
2803 if (!(data->have_temp & (1 << i)))
2804 continue;
2805 if (!data->reg_temp_config[i])
2806 continue;
2807 tmp = nct6775_read_value(data, data->reg_temp_config[i]);
2808 if (tmp & 0x01)
2809 nct6775_write_value(data, data->reg_temp_config[i],
2810 tmp & 0xfe);
2811 }
2812
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07002813 /* Enable VBAT monitoring if needed */
2814 tmp = nct6775_read_value(data, data->REG_VBAT);
2815 if (!(tmp & 0x01))
2816 nct6775_write_value(data, data->REG_VBAT, tmp | 0x01);
Guenter Roeckaa136e52012-12-04 03:26:05 -08002817
2818 diode = nct6775_read_value(data, data->REG_DIODE);
2819
2820 for (i = 0; i < data->temp_fixed_num; i++) {
2821 if (!(data->have_temp_fixed & (1 << i)))
2822 continue;
2823 if ((tmp & (0x02 << i))) /* diode */
2824 data->temp_type[i] = 3 - ((diode >> i) & 0x02);
2825 else /* thermistor */
2826 data->temp_type[i] = 4;
2827 }
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07002828}
2829
Guenter Roeckf73cf632013-03-18 09:22:50 -07002830static void
Guenter Roeck1c65dc32012-12-04 07:56:24 -08002831nct6775_check_fan_inputs(const struct nct6775_sio_data *sio_data,
2832 struct nct6775_data *data)
2833{
2834 int regval;
2835 bool fan3pin, fan3min, fan4pin, fan4min, fan5pin;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08002836 bool pwm3pin, pwm4pin, pwm5pin;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08002837
2838 /* fan4 and fan5 share some pins with the GPIO and serial flash */
2839 if (data->kind == nct6775) {
2840 regval = superio_inb(sio_data->sioreg, 0x2c);
2841
2842 fan3pin = regval & (1 << 6);
2843 fan3min = fan3pin;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08002844 pwm3pin = regval & (1 << 7);
Guenter Roeck1c65dc32012-12-04 07:56:24 -08002845
2846 /* On NCT6775, fan4 shares pins with the fdc interface */
2847 fan4pin = !(superio_inb(sio_data->sioreg, 0x2A) & 0x80);
2848 fan4min = 0;
2849 fan5pin = 0;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08002850 pwm4pin = 0;
2851 pwm5pin = 0;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08002852 } else if (data->kind == nct6776) {
2853 bool gpok = superio_inb(sio_data->sioreg, 0x27) & 0x80;
2854
2855 superio_select(sio_data->sioreg, NCT6775_LD_HWM);
2856 regval = superio_inb(sio_data->sioreg, SIO_REG_ENABLE);
2857
2858 if (regval & 0x80)
2859 fan3pin = gpok;
2860 else
2861 fan3pin = !(superio_inb(sio_data->sioreg, 0x24) & 0x40);
2862
2863 if (regval & 0x40)
2864 fan4pin = gpok;
2865 else
2866 fan4pin = superio_inb(sio_data->sioreg, 0x1C) & 0x01;
2867
2868 if (regval & 0x20)
2869 fan5pin = gpok;
2870 else
2871 fan5pin = superio_inb(sio_data->sioreg, 0x1C) & 0x02;
2872
2873 fan4min = fan4pin;
2874 fan3min = fan3pin;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08002875 pwm3pin = fan3pin;
2876 pwm4pin = 0;
2877 pwm5pin = 0;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08002878 } else { /* NCT6779D */
2879 regval = superio_inb(sio_data->sioreg, 0x1c);
2880
2881 fan3pin = !(regval & (1 << 5));
2882 fan4pin = !(regval & (1 << 6));
2883 fan5pin = !(regval & (1 << 7));
2884
Guenter Roeck77eb5b32012-12-04 08:30:54 -08002885 pwm3pin = !(regval & (1 << 0));
2886 pwm4pin = !(regval & (1 << 1));
2887 pwm5pin = !(regval & (1 << 2));
2888
Guenter Roeck1c65dc32012-12-04 07:56:24 -08002889 fan3min = fan3pin;
2890 fan4min = fan4pin;
2891 }
2892
Guenter Roeck1c65dc32012-12-04 07:56:24 -08002893 data->has_fan = data->has_fan_min = 0x03; /* fan1 and fan2 */
2894 data->has_fan |= fan3pin << 2;
2895 data->has_fan_min |= fan3min << 2;
2896
2897 data->has_fan |= (fan4pin << 3) | (fan5pin << 4);
2898 data->has_fan_min |= (fan4min << 3) | (fan5pin << 4);
2899
Guenter Roeck77eb5b32012-12-04 08:30:54 -08002900 data->has_pwm = 0x03 | (pwm3pin << 2) | (pwm4pin << 3) | (pwm5pin << 4);
Guenter Roeck1c65dc32012-12-04 07:56:24 -08002901}
2902
Guenter Roeck8e9285b2012-12-04 08:03:37 -08002903static void add_temp_sensors(struct nct6775_data *data, const u16 *regp,
2904 int *available, int *mask)
2905{
2906 int i;
2907 u8 src;
2908
2909 for (i = 0; i < data->pwm_num && *available; i++) {
2910 int index;
2911
2912 if (!regp[i])
2913 continue;
2914 src = nct6775_read_value(data, regp[i]);
2915 src &= 0x1f;
2916 if (!src || (*mask & (1 << src)))
2917 continue;
2918 if (src >= data->temp_label_num ||
2919 !strlen(data->temp_label[src]))
2920 continue;
2921
2922 index = __ffs(*available);
2923 nct6775_write_value(data, data->REG_TEMP_SOURCE[index], src);
2924 *available &= ~(1 << index);
2925 *mask |= 1 << src;
2926 }
2927}
2928
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07002929static int nct6775_probe(struct platform_device *pdev)
2930{
2931 struct device *dev = &pdev->dev;
2932 struct nct6775_sio_data *sio_data = dev->platform_data;
2933 struct nct6775_data *data;
2934 struct resource *res;
Guenter Roeckaa136e52012-12-04 03:26:05 -08002935 int i, s, err = 0;
2936 int src, mask, available;
2937 const u16 *reg_temp, *reg_temp_over, *reg_temp_hyst, *reg_temp_config;
2938 const u16 *reg_temp_alternate, *reg_temp_crit;
2939 int num_reg_temp;
Guenter Roeck0fc1f8f2013-02-26 09:43:50 -08002940 u8 cr2a;
Guenter Roeckf73cf632013-03-18 09:22:50 -07002941 struct attribute_group *group;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07002942
2943 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
2944 if (!devm_request_region(&pdev->dev, res->start, IOREGION_LENGTH,
2945 DRVNAME))
2946 return -EBUSY;
2947
2948 data = devm_kzalloc(&pdev->dev, sizeof(struct nct6775_data),
2949 GFP_KERNEL);
2950 if (!data)
2951 return -ENOMEM;
2952
2953 data->kind = sio_data->kind;
2954 data->addr = res->start;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07002955 mutex_init(&data->update_lock);
2956 data->name = nct6775_device_names[data->kind];
2957 data->bank = 0xff; /* Force initial bank selection */
2958 platform_set_drvdata(pdev, data);
2959
2960 switch (data->kind) {
2961 case nct6775:
2962 data->in_num = 9;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08002963 data->pwm_num = 3;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002964 data->auto_pwm_num = 6;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08002965 data->has_fan_div = true;
Guenter Roeckaa136e52012-12-04 03:26:05 -08002966 data->temp_fixed_num = 3;
Guenter Roeckb1d2bff2013-06-22 16:15:31 -07002967 data->num_temp_alarms = 3;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07002968
2969 data->ALARM_BITS = NCT6775_ALARM_BITS;
2970
Guenter Roeck1c65dc32012-12-04 07:56:24 -08002971 data->fan_from_reg = fan_from_reg16;
2972 data->fan_from_reg_min = fan_from_reg8;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002973 data->target_temp_mask = 0x7f;
2974 data->tolerance_mask = 0x0f;
2975 data->speed_tolerance_limit = 15;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08002976
Guenter Roeckaa136e52012-12-04 03:26:05 -08002977 data->temp_label = nct6775_temp_label;
2978 data->temp_label_num = ARRAY_SIZE(nct6775_temp_label);
2979
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07002980 data->REG_CONFIG = NCT6775_REG_CONFIG;
2981 data->REG_VBAT = NCT6775_REG_VBAT;
Guenter Roeckaa136e52012-12-04 03:26:05 -08002982 data->REG_DIODE = NCT6775_REG_DIODE;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07002983 data->REG_VIN = NCT6775_REG_IN;
2984 data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN;
2985 data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002986 data->REG_TARGET = NCT6775_REG_TARGET;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08002987 data->REG_FAN = NCT6775_REG_FAN;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08002988 data->REG_FAN_MODE = NCT6775_REG_FAN_MODE;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08002989 data->REG_FAN_MIN = NCT6775_REG_FAN_MIN;
Guenter Roeck5c25d952012-12-11 07:29:06 -08002990 data->REG_FAN_PULSES = NCT6775_REG_FAN_PULSES;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002991 data->REG_FAN_TIME[0] = NCT6775_REG_FAN_STOP_TIME;
2992 data->REG_FAN_TIME[1] = NCT6775_REG_FAN_STEP_UP_TIME;
2993 data->REG_FAN_TIME[2] = NCT6775_REG_FAN_STEP_DOWN_TIME;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08002994 data->REG_PWM[0] = NCT6775_REG_PWM;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002995 data->REG_PWM[1] = NCT6775_REG_FAN_START_OUTPUT;
2996 data->REG_PWM[2] = NCT6775_REG_FAN_STOP_OUTPUT;
2997 data->REG_PWM[3] = NCT6775_REG_FAN_MAX_OUTPUT;
2998 data->REG_PWM[4] = NCT6775_REG_FAN_STEP_OUTPUT;
Guenter Roeckbbd8dec2012-12-04 09:08:29 -08002999 data->REG_PWM[5] = NCT6775_REG_WEIGHT_DUTY_STEP;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003000 data->REG_PWM_READ = NCT6775_REG_PWM_READ;
3001 data->REG_PWM_MODE = NCT6775_REG_PWM_MODE;
3002 data->PWM_MODE_MASK = NCT6775_PWM_MODE_MASK;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003003 data->REG_AUTO_TEMP = NCT6775_REG_AUTO_TEMP;
3004 data->REG_AUTO_PWM = NCT6775_REG_AUTO_PWM;
3005 data->REG_CRITICAL_TEMP = NCT6775_REG_CRITICAL_TEMP;
3006 data->REG_CRITICAL_TEMP_TOLERANCE
3007 = NCT6775_REG_CRITICAL_TEMP_TOLERANCE;
Guenter Roeckaa136e52012-12-04 03:26:05 -08003008 data->REG_TEMP_OFFSET = NCT6775_REG_TEMP_OFFSET;
3009 data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003010 data->REG_TEMP_SEL = NCT6775_REG_TEMP_SEL;
Guenter Roeckbbd8dec2012-12-04 09:08:29 -08003011 data->REG_WEIGHT_TEMP_SEL = NCT6775_REG_WEIGHT_TEMP_SEL;
3012 data->REG_WEIGHT_TEMP[0] = NCT6775_REG_WEIGHT_TEMP_STEP;
3013 data->REG_WEIGHT_TEMP[1] = NCT6775_REG_WEIGHT_TEMP_STEP_TOL;
3014 data->REG_WEIGHT_TEMP[2] = NCT6775_REG_WEIGHT_TEMP_BASE;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003015 data->REG_ALARM = NCT6775_REG_ALARM;
Guenter Roeckaa136e52012-12-04 03:26:05 -08003016
3017 reg_temp = NCT6775_REG_TEMP;
3018 num_reg_temp = ARRAY_SIZE(NCT6775_REG_TEMP);
3019 reg_temp_over = NCT6775_REG_TEMP_OVER;
3020 reg_temp_hyst = NCT6775_REG_TEMP_HYST;
3021 reg_temp_config = NCT6775_REG_TEMP_CONFIG;
3022 reg_temp_alternate = NCT6775_REG_TEMP_ALTERNATE;
3023 reg_temp_crit = NCT6775_REG_TEMP_CRIT;
3024
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003025 break;
3026 case nct6776:
3027 data->in_num = 9;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003028 data->pwm_num = 3;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003029 data->auto_pwm_num = 4;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003030 data->has_fan_div = false;
Guenter Roeckaa136e52012-12-04 03:26:05 -08003031 data->temp_fixed_num = 3;
Guenter Roeckb1d2bff2013-06-22 16:15:31 -07003032 data->num_temp_alarms = 3;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003033
3034 data->ALARM_BITS = NCT6776_ALARM_BITS;
3035
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003036 data->fan_from_reg = fan_from_reg13;
3037 data->fan_from_reg_min = fan_from_reg13;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003038 data->target_temp_mask = 0xff;
3039 data->tolerance_mask = 0x07;
3040 data->speed_tolerance_limit = 63;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003041
Guenter Roeckaa136e52012-12-04 03:26:05 -08003042 data->temp_label = nct6776_temp_label;
3043 data->temp_label_num = ARRAY_SIZE(nct6776_temp_label);
3044
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003045 data->REG_CONFIG = NCT6775_REG_CONFIG;
3046 data->REG_VBAT = NCT6775_REG_VBAT;
Guenter Roeckaa136e52012-12-04 03:26:05 -08003047 data->REG_DIODE = NCT6775_REG_DIODE;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003048 data->REG_VIN = NCT6775_REG_IN;
3049 data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN;
3050 data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003051 data->REG_TARGET = NCT6775_REG_TARGET;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003052 data->REG_FAN = NCT6775_REG_FAN;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003053 data->REG_FAN_MODE = NCT6775_REG_FAN_MODE;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003054 data->REG_FAN_MIN = NCT6776_REG_FAN_MIN;
Guenter Roeck5c25d952012-12-11 07:29:06 -08003055 data->REG_FAN_PULSES = NCT6776_REG_FAN_PULSES;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003056 data->REG_FAN_TIME[0] = NCT6775_REG_FAN_STOP_TIME;
3057 data->REG_FAN_TIME[1] = NCT6775_REG_FAN_STEP_UP_TIME;
3058 data->REG_FAN_TIME[2] = NCT6775_REG_FAN_STEP_DOWN_TIME;
3059 data->REG_TOLERANCE_H = NCT6776_REG_TOLERANCE_H;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003060 data->REG_PWM[0] = NCT6775_REG_PWM;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003061 data->REG_PWM[1] = NCT6775_REG_FAN_START_OUTPUT;
3062 data->REG_PWM[2] = NCT6775_REG_FAN_STOP_OUTPUT;
Guenter Roeckbbd8dec2012-12-04 09:08:29 -08003063 data->REG_PWM[5] = NCT6775_REG_WEIGHT_DUTY_STEP;
3064 data->REG_PWM[6] = NCT6776_REG_WEIGHT_DUTY_BASE;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003065 data->REG_PWM_READ = NCT6775_REG_PWM_READ;
3066 data->REG_PWM_MODE = NCT6776_REG_PWM_MODE;
3067 data->PWM_MODE_MASK = NCT6776_PWM_MODE_MASK;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003068 data->REG_AUTO_TEMP = NCT6775_REG_AUTO_TEMP;
3069 data->REG_AUTO_PWM = NCT6775_REG_AUTO_PWM;
3070 data->REG_CRITICAL_TEMP = NCT6775_REG_CRITICAL_TEMP;
3071 data->REG_CRITICAL_TEMP_TOLERANCE
3072 = NCT6775_REG_CRITICAL_TEMP_TOLERANCE;
Guenter Roeckaa136e52012-12-04 03:26:05 -08003073 data->REG_TEMP_OFFSET = NCT6775_REG_TEMP_OFFSET;
3074 data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003075 data->REG_TEMP_SEL = NCT6775_REG_TEMP_SEL;
Guenter Roeckbbd8dec2012-12-04 09:08:29 -08003076 data->REG_WEIGHT_TEMP_SEL = NCT6775_REG_WEIGHT_TEMP_SEL;
3077 data->REG_WEIGHT_TEMP[0] = NCT6775_REG_WEIGHT_TEMP_STEP;
3078 data->REG_WEIGHT_TEMP[1] = NCT6775_REG_WEIGHT_TEMP_STEP_TOL;
3079 data->REG_WEIGHT_TEMP[2] = NCT6775_REG_WEIGHT_TEMP_BASE;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003080 data->REG_ALARM = NCT6775_REG_ALARM;
Guenter Roeckaa136e52012-12-04 03:26:05 -08003081
3082 reg_temp = NCT6775_REG_TEMP;
3083 num_reg_temp = ARRAY_SIZE(NCT6775_REG_TEMP);
3084 reg_temp_over = NCT6775_REG_TEMP_OVER;
3085 reg_temp_hyst = NCT6775_REG_TEMP_HYST;
3086 reg_temp_config = NCT6776_REG_TEMP_CONFIG;
3087 reg_temp_alternate = NCT6776_REG_TEMP_ALTERNATE;
3088 reg_temp_crit = NCT6776_REG_TEMP_CRIT;
3089
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003090 break;
3091 case nct6779:
3092 data->in_num = 15;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003093 data->pwm_num = 5;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003094 data->auto_pwm_num = 4;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003095 data->has_fan_div = false;
Guenter Roeckaa136e52012-12-04 03:26:05 -08003096 data->temp_fixed_num = 6;
Guenter Roeckb1d2bff2013-06-22 16:15:31 -07003097 data->num_temp_alarms = 2;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003098
3099 data->ALARM_BITS = NCT6779_ALARM_BITS;
3100
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003101 data->fan_from_reg = fan_from_reg13;
3102 data->fan_from_reg_min = fan_from_reg13;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003103 data->target_temp_mask = 0xff;
3104 data->tolerance_mask = 0x07;
3105 data->speed_tolerance_limit = 63;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003106
Guenter Roeckaa136e52012-12-04 03:26:05 -08003107 data->temp_label = nct6779_temp_label;
3108 data->temp_label_num = ARRAY_SIZE(nct6779_temp_label);
3109
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003110 data->REG_CONFIG = NCT6775_REG_CONFIG;
3111 data->REG_VBAT = NCT6775_REG_VBAT;
Guenter Roeckaa136e52012-12-04 03:26:05 -08003112 data->REG_DIODE = NCT6775_REG_DIODE;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003113 data->REG_VIN = NCT6779_REG_IN;
3114 data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN;
3115 data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003116 data->REG_TARGET = NCT6775_REG_TARGET;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003117 data->REG_FAN = NCT6779_REG_FAN;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003118 data->REG_FAN_MODE = NCT6775_REG_FAN_MODE;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003119 data->REG_FAN_MIN = NCT6776_REG_FAN_MIN;
Guenter Roeck5c25d952012-12-11 07:29:06 -08003120 data->REG_FAN_PULSES = NCT6779_REG_FAN_PULSES;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003121 data->REG_FAN_TIME[0] = NCT6775_REG_FAN_STOP_TIME;
3122 data->REG_FAN_TIME[1] = NCT6775_REG_FAN_STEP_UP_TIME;
3123 data->REG_FAN_TIME[2] = NCT6775_REG_FAN_STEP_DOWN_TIME;
3124 data->REG_TOLERANCE_H = NCT6776_REG_TOLERANCE_H;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003125 data->REG_PWM[0] = NCT6775_REG_PWM;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003126 data->REG_PWM[1] = NCT6775_REG_FAN_START_OUTPUT;
3127 data->REG_PWM[2] = NCT6775_REG_FAN_STOP_OUTPUT;
Guenter Roeckbbd8dec2012-12-04 09:08:29 -08003128 data->REG_PWM[5] = NCT6775_REG_WEIGHT_DUTY_STEP;
3129 data->REG_PWM[6] = NCT6776_REG_WEIGHT_DUTY_BASE;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003130 data->REG_PWM_READ = NCT6775_REG_PWM_READ;
3131 data->REG_PWM_MODE = NCT6776_REG_PWM_MODE;
3132 data->PWM_MODE_MASK = NCT6776_PWM_MODE_MASK;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003133 data->REG_AUTO_TEMP = NCT6775_REG_AUTO_TEMP;
3134 data->REG_AUTO_PWM = NCT6775_REG_AUTO_PWM;
3135 data->REG_CRITICAL_TEMP = NCT6775_REG_CRITICAL_TEMP;
3136 data->REG_CRITICAL_TEMP_TOLERANCE
3137 = NCT6775_REG_CRITICAL_TEMP_TOLERANCE;
Guenter Roeckaa136e52012-12-04 03:26:05 -08003138 data->REG_TEMP_OFFSET = NCT6779_REG_TEMP_OFFSET;
3139 data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003140 data->REG_TEMP_SEL = NCT6775_REG_TEMP_SEL;
Guenter Roeckbbd8dec2012-12-04 09:08:29 -08003141 data->REG_WEIGHT_TEMP_SEL = NCT6775_REG_WEIGHT_TEMP_SEL;
3142 data->REG_WEIGHT_TEMP[0] = NCT6775_REG_WEIGHT_TEMP_STEP;
3143 data->REG_WEIGHT_TEMP[1] = NCT6775_REG_WEIGHT_TEMP_STEP_TOL;
3144 data->REG_WEIGHT_TEMP[2] = NCT6775_REG_WEIGHT_TEMP_BASE;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003145 data->REG_ALARM = NCT6779_REG_ALARM;
Guenter Roeckaa136e52012-12-04 03:26:05 -08003146
3147 reg_temp = NCT6779_REG_TEMP;
3148 num_reg_temp = ARRAY_SIZE(NCT6779_REG_TEMP);
3149 reg_temp_over = NCT6779_REG_TEMP_OVER;
3150 reg_temp_hyst = NCT6779_REG_TEMP_HYST;
3151 reg_temp_config = NCT6779_REG_TEMP_CONFIG;
3152 reg_temp_alternate = NCT6779_REG_TEMP_ALTERNATE;
3153 reg_temp_crit = NCT6779_REG_TEMP_CRIT;
3154
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003155 break;
3156 default:
3157 return -ENODEV;
3158 }
3159 data->have_in = (1 << data->in_num) - 1;
Guenter Roeckaa136e52012-12-04 03:26:05 -08003160 data->have_temp = 0;
3161
3162 /*
3163 * On some boards, not all available temperature sources are monitored,
3164 * even though some of the monitoring registers are unused.
3165 * Get list of unused monitoring registers, then detect if any fan
3166 * controls are configured to use unmonitored temperature sources.
3167 * If so, assign the unmonitored temperature sources to available
3168 * monitoring registers.
3169 */
3170 mask = 0;
3171 available = 0;
3172 for (i = 0; i < num_reg_temp; i++) {
3173 if (reg_temp[i] == 0)
3174 continue;
3175
3176 src = nct6775_read_value(data, data->REG_TEMP_SOURCE[i]) & 0x1f;
3177 if (!src || (mask & (1 << src)))
3178 available |= 1 << i;
3179
3180 mask |= 1 << src;
3181 }
3182
Guenter Roeck8e9285b2012-12-04 08:03:37 -08003183 /*
3184 * Now find unmonitored temperature registers and enable monitoring
3185 * if additional monitoring registers are available.
3186 */
3187 add_temp_sensors(data, data->REG_TEMP_SEL, &available, &mask);
3188 add_temp_sensors(data, data->REG_WEIGHT_TEMP_SEL, &available, &mask);
3189
Guenter Roeckaa136e52012-12-04 03:26:05 -08003190 mask = 0;
3191 s = NUM_TEMP_FIXED; /* First dynamic temperature attribute */
3192 for (i = 0; i < num_reg_temp; i++) {
3193 if (reg_temp[i] == 0)
3194 continue;
3195
3196 src = nct6775_read_value(data, data->REG_TEMP_SOURCE[i]) & 0x1f;
3197 if (!src || (mask & (1 << src)))
3198 continue;
3199
3200 if (src >= data->temp_label_num ||
3201 !strlen(data->temp_label[src])) {
3202 dev_info(dev,
3203 "Invalid temperature source %d at index %d, source register 0x%x, temp register 0x%x\n",
3204 src, i, data->REG_TEMP_SOURCE[i], reg_temp[i]);
3205 continue;
3206 }
3207
3208 mask |= 1 << src;
3209
3210 /* Use fixed index for SYSTIN(1), CPUTIN(2), AUXTIN(3) */
3211 if (src <= data->temp_fixed_num) {
3212 data->have_temp |= 1 << (src - 1);
3213 data->have_temp_fixed |= 1 << (src - 1);
3214 data->reg_temp[0][src - 1] = reg_temp[i];
3215 data->reg_temp[1][src - 1] = reg_temp_over[i];
3216 data->reg_temp[2][src - 1] = reg_temp_hyst[i];
3217 data->reg_temp_config[src - 1] = reg_temp_config[i];
3218 data->temp_src[src - 1] = src;
3219 continue;
3220 }
3221
3222 if (s >= NUM_TEMP)
3223 continue;
3224
3225 /* Use dynamic index for other sources */
3226 data->have_temp |= 1 << s;
3227 data->reg_temp[0][s] = reg_temp[i];
3228 data->reg_temp[1][s] = reg_temp_over[i];
3229 data->reg_temp[2][s] = reg_temp_hyst[i];
3230 data->reg_temp_config[s] = reg_temp_config[i];
3231 if (reg_temp_crit[src - 1])
3232 data->reg_temp[3][s] = reg_temp_crit[src - 1];
3233
3234 data->temp_src[s] = src;
3235 s++;
3236 }
3237
3238#ifdef USE_ALTERNATE
3239 /*
3240 * Go through the list of alternate temp registers and enable
3241 * if possible.
3242 * The temperature is already monitored if the respective bit in <mask>
3243 * is set.
3244 */
3245 for (i = 0; i < data->temp_label_num - 1; i++) {
3246 if (!reg_temp_alternate[i])
3247 continue;
3248 if (mask & (1 << (i + 1)))
3249 continue;
3250 if (i < data->temp_fixed_num) {
3251 if (data->have_temp & (1 << i))
3252 continue;
3253 data->have_temp |= 1 << i;
3254 data->have_temp_fixed |= 1 << i;
3255 data->reg_temp[0][i] = reg_temp_alternate[i];
Guenter Roeck169c05c2013-05-09 10:40:01 -07003256 if (i < num_reg_temp) {
3257 data->reg_temp[1][i] = reg_temp_over[i];
3258 data->reg_temp[2][i] = reg_temp_hyst[i];
3259 }
Guenter Roeckaa136e52012-12-04 03:26:05 -08003260 data->temp_src[i] = i + 1;
3261 continue;
3262 }
3263
3264 if (s >= NUM_TEMP) /* Abort if no more space */
3265 break;
3266
3267 data->have_temp |= 1 << s;
3268 data->reg_temp[0][s] = reg_temp_alternate[i];
3269 data->temp_src[s] = i + 1;
3270 s++;
3271 }
3272#endif /* USE_ALTERNATE */
3273
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003274 /* Initialize the chip */
3275 nct6775_init_device(data);
3276
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003277 err = superio_enter(sio_data->sioreg);
3278 if (err)
3279 return err;
3280
Guenter Roeck0fc1f8f2013-02-26 09:43:50 -08003281 cr2a = superio_inb(sio_data->sioreg, 0x2a);
3282 switch (data->kind) {
3283 case nct6775:
Guenter Roeckf73cf632013-03-18 09:22:50 -07003284 data->have_vid = (cr2a & 0x40);
Guenter Roeck0fc1f8f2013-02-26 09:43:50 -08003285 break;
3286 case nct6776:
Guenter Roeckf73cf632013-03-18 09:22:50 -07003287 data->have_vid = (cr2a & 0x60) == 0x40;
Guenter Roeck0fc1f8f2013-02-26 09:43:50 -08003288 break;
3289 case nct6779:
3290 break;
3291 }
3292
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003293 /*
3294 * Read VID value
3295 * We can get the VID input values directly at logical device D 0xe3.
3296 */
Guenter Roeckf73cf632013-03-18 09:22:50 -07003297 if (data->have_vid) {
Guenter Roeck0fc1f8f2013-02-26 09:43:50 -08003298 superio_select(sio_data->sioreg, NCT6775_LD_VID);
3299 data->vid = superio_inb(sio_data->sioreg, 0xe3);
3300 data->vrm = vid_which_vrm();
3301 }
Guenter Roeck47ece962012-12-04 07:59:32 -08003302
3303 if (fan_debounce) {
3304 u8 tmp;
3305
3306 superio_select(sio_data->sioreg, NCT6775_LD_HWM);
3307 tmp = superio_inb(sio_data->sioreg,
3308 NCT6775_REG_CR_FAN_DEBOUNCE);
3309 switch (data->kind) {
3310 case nct6775:
3311 tmp |= 0x1e;
3312 break;
3313 case nct6776:
3314 case nct6779:
3315 tmp |= 0x3e;
3316 break;
3317 }
3318 superio_outb(sio_data->sioreg, NCT6775_REG_CR_FAN_DEBOUNCE,
3319 tmp);
3320 dev_info(&pdev->dev, "Enabled fan debounce for chip %s\n",
3321 data->name);
3322 }
3323
Guenter Roeckf73cf632013-03-18 09:22:50 -07003324 nct6775_check_fan_inputs(sio_data, data);
3325
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003326 superio_exit(sio_data->sioreg);
3327
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003328 /* Read fan clock dividers immediately */
3329 nct6775_init_fan_common(dev, data);
3330
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003331 /* Register sysfs hooks */
Guenter Roeckf73cf632013-03-18 09:22:50 -07003332 group = nct6775_create_attr_group(dev, &nct6775_pwm_template_group,
3333 data->pwm_num);
3334 if (IS_ERR(group)) {
3335 err = PTR_ERR(group);
3336 goto exit_remove;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003337 }
Guenter Roeckf73cf632013-03-18 09:22:50 -07003338 data->group_pwm = group;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003339
Guenter Roeckf73cf632013-03-18 09:22:50 -07003340 group = nct6775_create_attr_group(dev, &nct6775_in_template_group,
3341 fls(data->have_in));
3342 if (IS_ERR(group)) {
3343 err = PTR_ERR(group);
3344 goto exit_remove;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003345 }
Guenter Roeckf73cf632013-03-18 09:22:50 -07003346 data->group_in = group;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003347
Guenter Roeckf73cf632013-03-18 09:22:50 -07003348 group = nct6775_create_attr_group(dev, &nct6775_fan_template_group,
3349 fls(data->has_fan));
3350 if (IS_ERR(group)) {
3351 err = PTR_ERR(group);
3352 goto exit_remove;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003353 }
Guenter Roeckf73cf632013-03-18 09:22:50 -07003354 data->group_fan = group;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003355
Guenter Roeckf73cf632013-03-18 09:22:50 -07003356 group = nct6775_create_attr_group(dev, &nct6775_temp_template_group,
3357 fls(data->have_temp));
3358 if (IS_ERR(group)) {
3359 err = PTR_ERR(group);
3360 goto exit_remove;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003361 }
Guenter Roeckf73cf632013-03-18 09:22:50 -07003362 data->group_temp = group;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003363
Guenter Roeckf73cf632013-03-18 09:22:50 -07003364 err = sysfs_create_group(&dev->kobj, &nct6775_group_other);
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003365 if (err)
3366 goto exit_remove;
3367
3368 data->hwmon_dev = hwmon_device_register(dev);
3369 if (IS_ERR(data->hwmon_dev)) {
3370 err = PTR_ERR(data->hwmon_dev);
3371 goto exit_remove;
3372 }
3373
3374 return 0;
3375
3376exit_remove:
3377 nct6775_device_remove_files(dev);
3378 return err;
3379}
3380
3381static int nct6775_remove(struct platform_device *pdev)
3382{
3383 struct nct6775_data *data = platform_get_drvdata(pdev);
3384
3385 hwmon_device_unregister(data->hwmon_dev);
3386 nct6775_device_remove_files(&pdev->dev);
3387
3388 return 0;
3389}
3390
Guenter Roeck84d19d92012-12-04 08:01:39 -08003391#ifdef CONFIG_PM
3392static int nct6775_suspend(struct device *dev)
3393{
3394 struct nct6775_data *data = nct6775_update_device(dev);
3395 struct nct6775_sio_data *sio_data = dev->platform_data;
3396
3397 mutex_lock(&data->update_lock);
3398 data->vbat = nct6775_read_value(data, data->REG_VBAT);
3399 if (sio_data->kind == nct6775) {
3400 data->fandiv1 = nct6775_read_value(data, NCT6775_REG_FANDIV1);
3401 data->fandiv2 = nct6775_read_value(data, NCT6775_REG_FANDIV2);
3402 }
3403 mutex_unlock(&data->update_lock);
3404
3405 return 0;
3406}
3407
3408static int nct6775_resume(struct device *dev)
3409{
3410 struct nct6775_data *data = dev_get_drvdata(dev);
3411 struct nct6775_sio_data *sio_data = dev->platform_data;
3412 int i, j;
3413
3414 mutex_lock(&data->update_lock);
3415 data->bank = 0xff; /* Force initial bank selection */
3416
3417 /* Restore limits */
3418 for (i = 0; i < data->in_num; i++) {
3419 if (!(data->have_in & (1 << i)))
3420 continue;
3421
3422 nct6775_write_value(data, data->REG_IN_MINMAX[0][i],
3423 data->in[i][1]);
3424 nct6775_write_value(data, data->REG_IN_MINMAX[1][i],
3425 data->in[i][2]);
3426 }
3427
Guenter Roeckc409fd42013-04-09 05:04:00 -07003428 for (i = 0; i < ARRAY_SIZE(data->fan_min); i++) {
Guenter Roeck84d19d92012-12-04 08:01:39 -08003429 if (!(data->has_fan_min & (1 << i)))
3430 continue;
3431
3432 nct6775_write_value(data, data->REG_FAN_MIN[i],
3433 data->fan_min[i]);
3434 }
3435
3436 for (i = 0; i < NUM_TEMP; i++) {
3437 if (!(data->have_temp & (1 << i)))
3438 continue;
3439
Guenter Roeckc409fd42013-04-09 05:04:00 -07003440 for (j = 1; j < ARRAY_SIZE(data->reg_temp); j++)
Guenter Roeck84d19d92012-12-04 08:01:39 -08003441 if (data->reg_temp[j][i])
3442 nct6775_write_temp(data, data->reg_temp[j][i],
3443 data->temp[j][i]);
3444 }
3445
3446 /* Restore other settings */
3447 nct6775_write_value(data, data->REG_VBAT, data->vbat);
3448 if (sio_data->kind == nct6775) {
3449 nct6775_write_value(data, NCT6775_REG_FANDIV1, data->fandiv1);
3450 nct6775_write_value(data, NCT6775_REG_FANDIV2, data->fandiv2);
3451 }
3452
3453 /* Force re-reading all values */
3454 data->valid = false;
3455 mutex_unlock(&data->update_lock);
3456
3457 return 0;
3458}
3459
3460static const struct dev_pm_ops nct6775_dev_pm_ops = {
3461 .suspend = nct6775_suspend,
3462 .resume = nct6775_resume,
3463};
3464
3465#define NCT6775_DEV_PM_OPS (&nct6775_dev_pm_ops)
3466#else
3467#define NCT6775_DEV_PM_OPS NULL
3468#endif /* CONFIG_PM */
3469
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003470static struct platform_driver nct6775_driver = {
3471 .driver = {
3472 .owner = THIS_MODULE,
3473 .name = DRVNAME,
Guenter Roeck84d19d92012-12-04 08:01:39 -08003474 .pm = NCT6775_DEV_PM_OPS,
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003475 },
3476 .probe = nct6775_probe,
3477 .remove = nct6775_remove,
3478};
3479
Guenter Roeck6d4b3622013-04-21 09:08:11 -07003480static const char * const nct6775_sio_names[] __initconst = {
Guenter Roeck2c7fd302013-04-02 08:53:19 -07003481 "NCT6775F",
3482 "NCT6776D/F",
3483 "NCT6779D",
3484};
3485
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003486/* nct6775_find() looks for a '627 in the Super-I/O config space */
3487static int __init nct6775_find(int sioaddr, unsigned short *addr,
3488 struct nct6775_sio_data *sio_data)
3489{
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003490 u16 val;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003491 int err;
3492
3493 err = superio_enter(sioaddr);
3494 if (err)
3495 return err;
3496
3497 if (force_id)
3498 val = force_id;
3499 else
3500 val = (superio_inb(sioaddr, SIO_REG_DEVID) << 8)
3501 | superio_inb(sioaddr, SIO_REG_DEVID + 1);
3502 switch (val & SIO_ID_MASK) {
3503 case SIO_NCT6775_ID:
3504 sio_data->kind = nct6775;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003505 break;
3506 case SIO_NCT6776_ID:
3507 sio_data->kind = nct6776;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003508 break;
3509 case SIO_NCT6779_ID:
3510 sio_data->kind = nct6779;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003511 break;
3512 default:
3513 if (val != 0xffff)
3514 pr_debug("unsupported chip ID: 0x%04x\n", val);
3515 superio_exit(sioaddr);
3516 return -ENODEV;
3517 }
3518
3519 /* We have a known chip, find the HWM I/O address */
3520 superio_select(sioaddr, NCT6775_LD_HWM);
3521 val = (superio_inb(sioaddr, SIO_REG_ADDR) << 8)
3522 | superio_inb(sioaddr, SIO_REG_ADDR + 1);
3523 *addr = val & IOREGION_ALIGNMENT;
3524 if (*addr == 0) {
3525 pr_err("Refusing to enable a Super-I/O device with a base I/O port 0\n");
3526 superio_exit(sioaddr);
3527 return -ENODEV;
3528 }
3529
3530 /* Activate logical device if needed */
3531 val = superio_inb(sioaddr, SIO_REG_ENABLE);
3532 if (!(val & 0x01)) {
3533 pr_warn("Forcibly enabling Super-I/O. Sensor is probably unusable.\n");
3534 superio_outb(sioaddr, SIO_REG_ENABLE, val | 0x01);
3535 }
3536
3537 superio_exit(sioaddr);
Guenter Roeck2c7fd302013-04-02 08:53:19 -07003538 pr_info("Found %s or compatible chip at %#x\n",
3539 nct6775_sio_names[sio_data->kind], *addr);
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003540 sio_data->sioreg = sioaddr;
3541
3542 return 0;
3543}
3544
3545/*
3546 * when Super-I/O functions move to a separate file, the Super-I/O
3547 * bus will manage the lifetime of the device and this module will only keep
3548 * track of the nct6775 driver. But since we platform_device_alloc(), we
3549 * must keep track of the device
3550 */
3551static struct platform_device *pdev;
3552
3553static int __init sensors_nct6775_init(void)
3554{
3555 int err;
3556 unsigned short address;
3557 struct resource res;
3558 struct nct6775_sio_data sio_data;
3559
3560 /*
3561 * initialize sio_data->kind and sio_data->sioreg.
3562 *
3563 * when Super-I/O functions move to a separate file, the Super-I/O
3564 * driver will probe 0x2e and 0x4e and auto-detect the presence of a
3565 * nct6775 hardware monitor, and call probe()
3566 */
3567 if (nct6775_find(0x2e, &address, &sio_data) &&
3568 nct6775_find(0x4e, &address, &sio_data))
3569 return -ENODEV;
3570
3571 err = platform_driver_register(&nct6775_driver);
3572 if (err)
3573 goto exit;
3574
3575 pdev = platform_device_alloc(DRVNAME, address);
3576 if (!pdev) {
3577 err = -ENOMEM;
3578 pr_err("Device allocation failed\n");
3579 goto exit_unregister;
3580 }
3581
3582 err = platform_device_add_data(pdev, &sio_data,
3583 sizeof(struct nct6775_sio_data));
3584 if (err) {
3585 pr_err("Platform data allocation failed\n");
3586 goto exit_device_put;
3587 }
3588
3589 memset(&res, 0, sizeof(res));
3590 res.name = DRVNAME;
3591 res.start = address + IOREGION_OFFSET;
3592 res.end = address + IOREGION_OFFSET + IOREGION_LENGTH - 1;
3593 res.flags = IORESOURCE_IO;
3594
3595 err = acpi_check_resource_conflict(&res);
3596 if (err)
3597 goto exit_device_put;
3598
3599 err = platform_device_add_resources(pdev, &res, 1);
3600 if (err) {
3601 pr_err("Device resource addition failed (%d)\n", err);
3602 goto exit_device_put;
3603 }
3604
3605 /* platform_device_add calls probe() */
3606 err = platform_device_add(pdev);
3607 if (err) {
3608 pr_err("Device addition failed (%d)\n", err);
3609 goto exit_device_put;
3610 }
3611
3612 return 0;
3613
3614exit_device_put:
3615 platform_device_put(pdev);
3616exit_unregister:
3617 platform_driver_unregister(&nct6775_driver);
3618exit:
3619 return err;
3620}
3621
3622static void __exit sensors_nct6775_exit(void)
3623{
3624 platform_device_unregister(pdev);
3625 platform_driver_unregister(&nct6775_driver);
3626}
3627
3628MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>");
3629MODULE_DESCRIPTION("NCT6775F/NCT6776F/NCT6779D driver");
3630MODULE_LICENSE("GPL");
3631
3632module_init(sensors_nct6775_init);
3633module_exit(sensors_nct6775_exit);