blob: 47b1d8947e4d267df502bf4828678001d48e2c7d [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 */
202 6, 7, 11, 10, 23, /* fan1..fan5 */
203 -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 Roeckaa136e52012-12-04 03:26:05 -0800258static const u16 NCT6775_REG_TEMP_OFFSET[] = { 0x454, 0x455, 0x456 };
259
Guenter Roeckcdcaece2012-12-04 09:04:52 -0800260static const u16 NCT6775_REG_AUTO_TEMP[] = {
261 0x121, 0x221, 0x321, 0x821, 0x921 };
262static const u16 NCT6775_REG_AUTO_PWM[] = {
263 0x127, 0x227, 0x327, 0x827, 0x927 };
264
265#define NCT6775_AUTO_TEMP(data, nr, p) ((data)->REG_AUTO_TEMP[nr] + (p))
266#define NCT6775_AUTO_PWM(data, nr, p) ((data)->REG_AUTO_PWM[nr] + (p))
267
268static const u16 NCT6775_REG_CRITICAL_ENAB[] = { 0x134, 0x234, 0x334 };
269
270static const u16 NCT6775_REG_CRITICAL_TEMP[] = {
271 0x135, 0x235, 0x335, 0x835, 0x935 };
272static const u16 NCT6775_REG_CRITICAL_TEMP_TOLERANCE[] = {
273 0x138, 0x238, 0x338, 0x838, 0x938 };
274
Guenter Roeckaa136e52012-12-04 03:26:05 -0800275static const char *const nct6775_temp_label[] = {
276 "",
277 "SYSTIN",
278 "CPUTIN",
279 "AUXTIN",
280 "AMD SB-TSI",
281 "PECI Agent 0",
282 "PECI Agent 1",
283 "PECI Agent 2",
284 "PECI Agent 3",
285 "PECI Agent 4",
286 "PECI Agent 5",
287 "PECI Agent 6",
288 "PECI Agent 7",
289 "PCH_CHIP_CPU_MAX_TEMP",
290 "PCH_CHIP_TEMP",
291 "PCH_CPU_TEMP",
292 "PCH_MCH_TEMP",
293 "PCH_DIM0_TEMP",
294 "PCH_DIM1_TEMP",
295 "PCH_DIM2_TEMP",
296 "PCH_DIM3_TEMP"
297};
298
299static const u16 NCT6775_REG_TEMP_ALTERNATE[ARRAY_SIZE(nct6775_temp_label) - 1]
300 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x661, 0x662, 0x664 };
301
302static const u16 NCT6775_REG_TEMP_CRIT[ARRAY_SIZE(nct6775_temp_label) - 1]
303 = { 0, 0, 0, 0, 0xa00, 0xa01, 0xa02, 0xa03, 0xa04, 0xa05, 0xa06,
304 0xa07 };
305
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700306/* NCT6776 specific data */
307
308static const s8 NCT6776_ALARM_BITS[] = {
309 0, 1, 2, 3, 8, 21, 20, 16, /* in0.. in7 */
310 17, -1, -1, -1, -1, -1, -1, /* in8..in14 */
311 -1, /* unused */
312 6, 7, 11, 10, 23, /* fan1..fan5 */
313 -1, -1, -1, /* unused */
314 4, 5, 13, -1, -1, -1, /* temp1..temp6 */
315 12, 9 }; /* intrusion0, intrusion1 */
316
Guenter Roeckcdcaece2012-12-04 09:04:52 -0800317static const u16 NCT6776_REG_TOLERANCE_H[] = {
318 0x10c, 0x20c, 0x30c, 0x80c, 0x90c };
319
Guenter Roeck77eb5b32012-12-04 08:30:54 -0800320static const u8 NCT6776_REG_PWM_MODE[] = { 0x04, 0, 0 };
321static const u8 NCT6776_PWM_MODE_MASK[] = { 0x01, 0, 0 };
322
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800323static const u16 NCT6776_REG_FAN_MIN[] = { 0x63a, 0x63c, 0x63e, 0x640, 0x642 };
Guenter Roeck5c25d952012-12-11 07:29:06 -0800324static const u16 NCT6776_REG_FAN_PULSES[] = { 0x644, 0x645, 0x646, 0, 0 };
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800325
Guenter Roeckaa136e52012-12-04 03:26:05 -0800326static const u16 NCT6776_REG_TEMP_CONFIG[ARRAY_SIZE(NCT6775_REG_TEMP)] = {
327 0x18, 0x152, 0x252, 0x628, 0x629, 0x62A };
328
329static const char *const nct6776_temp_label[] = {
330 "",
331 "SYSTIN",
332 "CPUTIN",
333 "AUXTIN",
334 "SMBUSMASTER 0",
335 "SMBUSMASTER 1",
336 "SMBUSMASTER 2",
337 "SMBUSMASTER 3",
338 "SMBUSMASTER 4",
339 "SMBUSMASTER 5",
340 "SMBUSMASTER 6",
341 "SMBUSMASTER 7",
342 "PECI Agent 0",
343 "PECI Agent 1",
344 "PCH_CHIP_CPU_MAX_TEMP",
345 "PCH_CHIP_TEMP",
346 "PCH_CPU_TEMP",
347 "PCH_MCH_TEMP",
348 "PCH_DIM0_TEMP",
349 "PCH_DIM1_TEMP",
350 "PCH_DIM2_TEMP",
351 "PCH_DIM3_TEMP",
352 "BYTE_TEMP"
353};
354
355static const u16 NCT6776_REG_TEMP_ALTERNATE[ARRAY_SIZE(nct6776_temp_label) - 1]
356 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x401, 0x402, 0x404 };
357
358static const u16 NCT6776_REG_TEMP_CRIT[ARRAY_SIZE(nct6776_temp_label) - 1]
359 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x709, 0x70a };
360
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700361/* NCT6779 specific data */
362
363static const u16 NCT6779_REG_IN[] = {
364 0x480, 0x481, 0x482, 0x483, 0x484, 0x485, 0x486, 0x487,
365 0x488, 0x489, 0x48a, 0x48b, 0x48c, 0x48d, 0x48e };
366
367static const u16 NCT6779_REG_ALARM[NUM_REG_ALARM] = {
368 0x459, 0x45A, 0x45B, 0x568 };
369
370static const s8 NCT6779_ALARM_BITS[] = {
371 0, 1, 2, 3, 8, 21, 20, 16, /* in0.. in7 */
372 17, 24, 25, 26, 27, 28, 29, /* in8..in14 */
373 -1, /* unused */
374 6, 7, 11, 10, 23, /* fan1..fan5 */
375 -1, -1, -1, /* unused */
376 4, 5, 13, -1, -1, -1, /* temp1..temp6 */
377 12, 9 }; /* intrusion0, intrusion1 */
378
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800379static const u16 NCT6779_REG_FAN[] = { 0x4b0, 0x4b2, 0x4b4, 0x4b6, 0x4b8 };
Guenter Roeck5c25d952012-12-11 07:29:06 -0800380static const u16 NCT6779_REG_FAN_PULSES[] = {
381 0x644, 0x645, 0x646, 0x647, 0x648 };
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800382
Guenter Roeckcdcaece2012-12-04 09:04:52 -0800383static const u16 NCT6779_REG_CRITICAL_PWM_ENABLE[] = {
384 0x136, 0x236, 0x336, 0x836, 0x936 };
385static const u16 NCT6779_REG_CRITICAL_PWM[] = {
386 0x137, 0x237, 0x337, 0x837, 0x937 };
387
Guenter Roeckaa136e52012-12-04 03:26:05 -0800388static const u16 NCT6779_REG_TEMP[] = { 0x27, 0x150 };
389static const u16 NCT6779_REG_TEMP_CONFIG[ARRAY_SIZE(NCT6779_REG_TEMP)] = {
390 0x18, 0x152 };
391static const u16 NCT6779_REG_TEMP_HYST[ARRAY_SIZE(NCT6779_REG_TEMP)] = {
392 0x3a, 0x153 };
393static const u16 NCT6779_REG_TEMP_OVER[ARRAY_SIZE(NCT6779_REG_TEMP)] = {
394 0x39, 0x155 };
395
396static const u16 NCT6779_REG_TEMP_OFFSET[] = {
397 0x454, 0x455, 0x456, 0x44a, 0x44b, 0x44c };
398
399static const char *const nct6779_temp_label[] = {
400 "",
401 "SYSTIN",
402 "CPUTIN",
403 "AUXTIN0",
404 "AUXTIN1",
405 "AUXTIN2",
406 "AUXTIN3",
407 "",
408 "SMBUSMASTER 0",
409 "SMBUSMASTER 1",
410 "SMBUSMASTER 2",
411 "SMBUSMASTER 3",
412 "SMBUSMASTER 4",
413 "SMBUSMASTER 5",
414 "SMBUSMASTER 6",
415 "SMBUSMASTER 7",
416 "PECI Agent 0",
417 "PECI Agent 1",
418 "PCH_CHIP_CPU_MAX_TEMP",
419 "PCH_CHIP_TEMP",
420 "PCH_CPU_TEMP",
421 "PCH_MCH_TEMP",
422 "PCH_DIM0_TEMP",
423 "PCH_DIM1_TEMP",
424 "PCH_DIM2_TEMP",
425 "PCH_DIM3_TEMP",
426 "BYTE_TEMP"
427};
428
429static const u16 NCT6779_REG_TEMP_ALTERNATE[ARRAY_SIZE(nct6779_temp_label) - 1]
430 = { 0x490, 0x491, 0x492, 0x493, 0x494, 0x495, 0, 0,
431 0, 0, 0, 0, 0, 0, 0, 0,
432 0, 0x400, 0x401, 0x402, 0x404, 0x405, 0x406, 0x407,
433 0x408, 0 };
434
435static const u16 NCT6779_REG_TEMP_CRIT[ARRAY_SIZE(nct6779_temp_label) - 1]
436 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x709, 0x70a };
437
Guenter Roeck77eb5b32012-12-04 08:30:54 -0800438static enum pwm_enable reg_to_pwm_enable(int pwm, int mode)
439{
440 if (mode == 0 && pwm == 255)
441 return off;
442 return mode + 1;
443}
444
445static int pwm_enable_to_reg(enum pwm_enable mode)
446{
447 if (mode == off)
448 return 0;
449 return mode - 1;
450}
451
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700452/*
453 * Conversions
454 */
455
Guenter Roeckcdcaece2012-12-04 09:04:52 -0800456/* 1 is DC mode, output in ms */
457static unsigned int step_time_from_reg(u8 reg, u8 mode)
458{
459 return mode ? 400 * reg : 100 * reg;
460}
461
462static u8 step_time_to_reg(unsigned int msec, u8 mode)
463{
464 return clamp_val((mode ? (msec + 200) / 400 :
465 (msec + 50) / 100), 1, 255);
466}
467
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800468static unsigned int fan_from_reg8(u16 reg, unsigned int divreg)
469{
470 if (reg == 0 || reg == 255)
471 return 0;
472 return 1350000U / (reg << divreg);
473}
474
475static unsigned int fan_from_reg13(u16 reg, unsigned int divreg)
476{
477 if ((reg & 0xff1f) == 0xff1f)
478 return 0;
479
480 reg = (reg & 0x1f) | ((reg & 0xff00) >> 3);
481
482 if (reg == 0)
483 return 0;
484
485 return 1350000U / reg;
486}
487
488static unsigned int fan_from_reg16(u16 reg, unsigned int divreg)
489{
490 if (reg == 0 || reg == 0xffff)
491 return 0;
492
493 /*
494 * Even though the registers are 16 bit wide, the fan divisor
495 * still applies.
496 */
497 return 1350000U / (reg << divreg);
498}
499
Guenter Roeckcdcaece2012-12-04 09:04:52 -0800500static u16 fan_to_reg(u32 fan, unsigned int divreg)
501{
502 if (!fan)
503 return 0;
504
505 return (1350000U / fan) >> divreg;
506}
507
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800508static inline unsigned int
509div_from_reg(u8 reg)
510{
511 return 1 << reg;
512}
513
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700514/*
515 * Some of the voltage inputs have internal scaling, the tables below
516 * contain 8 (the ADC LSB in mV) * scaling factor * 100
517 */
518static const u16 scale_in[15] = {
519 800, 800, 1600, 1600, 800, 800, 800, 1600, 1600, 800, 800, 800, 800,
520 800, 800
521};
522
523static inline long in_from_reg(u8 reg, u8 nr)
524{
525 return DIV_ROUND_CLOSEST(reg * scale_in[nr], 100);
526}
527
528static inline u8 in_to_reg(u32 val, u8 nr)
529{
530 return clamp_val(DIV_ROUND_CLOSEST(val * 100, scale_in[nr]), 0, 255);
531}
532
533/*
534 * Data structures and manipulation thereof
535 */
536
537struct nct6775_data {
538 int addr; /* IO base of hw monitor block */
539 enum kinds kind;
540 const char *name;
541
542 struct device *hwmon_dev;
543 struct mutex lock;
544
Guenter Roeckaa136e52012-12-04 03:26:05 -0800545 u16 reg_temp[4][NUM_TEMP]; /* 0=temp, 1=temp_over, 2=temp_hyst,
546 * 3=temp_crit
547 */
548 u8 temp_src[NUM_TEMP];
549 u16 reg_temp_config[NUM_TEMP];
550 const char * const *temp_label;
551 int temp_label_num;
552
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700553 u16 REG_CONFIG;
554 u16 REG_VBAT;
Guenter Roeckaa136e52012-12-04 03:26:05 -0800555 u16 REG_DIODE;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700556
557 const s8 *ALARM_BITS;
558
559 const u16 *REG_VIN;
560 const u16 *REG_IN_MINMAX[2];
561
Guenter Roeckcdcaece2012-12-04 09:04:52 -0800562 const u16 *REG_TARGET;
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800563 const u16 *REG_FAN;
Guenter Roeck77eb5b32012-12-04 08:30:54 -0800564 const u16 *REG_FAN_MODE;
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800565 const u16 *REG_FAN_MIN;
Guenter Roeck5c25d952012-12-11 07:29:06 -0800566 const u16 *REG_FAN_PULSES;
Guenter Roeckcdcaece2012-12-04 09:04:52 -0800567 const u16 *REG_FAN_TIME[3];
568
569 const u16 *REG_TOLERANCE_H;
Guenter Roeckaa136e52012-12-04 03:26:05 -0800570
Guenter Roeck77eb5b32012-12-04 08:30:54 -0800571 const u8 *REG_PWM_MODE;
572 const u8 *PWM_MODE_MASK;
573
Guenter Roeckcdcaece2012-12-04 09:04:52 -0800574 const u16 *REG_PWM[5]; /* [0]=pwm, [1]=pwm_start, [2]=pwm_floor,
575 * [3]=pwm_max, [4]=pwm_step
576 */
Guenter Roeck77eb5b32012-12-04 08:30:54 -0800577 const u16 *REG_PWM_READ;
578
Guenter Roeckcdcaece2012-12-04 09:04:52 -0800579 const u16 *REG_AUTO_TEMP;
580 const u16 *REG_AUTO_PWM;
581
582 const u16 *REG_CRITICAL_TEMP;
583 const u16 *REG_CRITICAL_TEMP_TOLERANCE;
584
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800585 const u16 *REG_TEMP_SOURCE; /* temp register sources */
Guenter Roeckcdcaece2012-12-04 09:04:52 -0800586 const u16 *REG_TEMP_SEL;
Guenter Roeckaa136e52012-12-04 03:26:05 -0800587 const u16 *REG_TEMP_OFFSET;
588
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700589 const u16 *REG_ALARM;
590
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800591 unsigned int (*fan_from_reg)(u16 reg, unsigned int divreg);
592 unsigned int (*fan_from_reg_min)(u16 reg, unsigned int divreg);
593
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700594 struct mutex update_lock;
595 bool valid; /* true if following fields are valid */
596 unsigned long last_updated; /* In jiffies */
597
598 /* Register values */
599 u8 bank; /* current register bank */
600 u8 in_num; /* number of in inputs we have */
601 u8 in[15][3]; /* [0]=in, [1]=in_max, [2]=in_min */
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800602 unsigned int rpm[5];
603 u16 fan_min[5];
Guenter Roeck5c25d952012-12-11 07:29:06 -0800604 u8 fan_pulses[5];
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800605 u8 fan_div[5];
Guenter Roeck77eb5b32012-12-04 08:30:54 -0800606 u8 has_pwm;
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800607 u8 has_fan; /* some fan inputs can be disabled */
608 u8 has_fan_min; /* some fans don't have min register */
609 bool has_fan_div;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700610
Guenter Roeckaa136e52012-12-04 03:26:05 -0800611 u8 temp_fixed_num; /* 3 or 6 */
612 u8 temp_type[NUM_TEMP_FIXED];
613 s8 temp_offset[NUM_TEMP_FIXED];
614 s16 temp[4][NUM_TEMP]; /* 0=temp, 1=temp_over, 2=temp_hyst,
615 * 3=temp_crit */
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700616 u64 alarms;
617
Guenter Roeck77eb5b32012-12-04 08:30:54 -0800618 u8 pwm_num; /* number of pwm */
619 u8 pwm_mode[5]; /* 1->DC variable voltage, 0->PWM variable duty cycle */
620 enum pwm_enable pwm_enable[5];
621 /* 0->off
622 * 1->manual
623 * 2->thermal cruise mode (also called SmartFan I)
624 * 3->fan speed cruise mode
625 * 4->SmartFan III
626 * 5->enhanced variable thermal cruise (SmartFan IV)
627 */
Guenter Roeckcdcaece2012-12-04 09:04:52 -0800628 u8 pwm[5][5]; /* [0]=pwm, [1]=pwm_start, [2]=pwm_floor,
629 * [3]=pwm_max, [4]=pwm_step
630 */
631
632 u8 target_temp[5];
633 u8 target_temp_mask;
634 u32 target_speed[5];
635 u32 target_speed_tolerance[5];
636 u8 speed_tolerance_limit;
637
638 u8 temp_tolerance[2][5];
639 u8 tolerance_mask;
640
641 u8 fan_time[3][5]; /* 0 = stop_time, 1 = step_up, 2 = step_down */
642
643 /* Automatic fan speed control registers */
644 int auto_pwm_num;
645 u8 auto_pwm[5][7];
646 u8 auto_temp[5][7];
647 u8 pwm_temp_sel[5];
Guenter Roeck77eb5b32012-12-04 08:30:54 -0800648
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700649 u8 vid;
650 u8 vrm;
651
Guenter Roeckaa136e52012-12-04 03:26:05 -0800652 u16 have_temp;
653 u16 have_temp_fixed;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700654 u16 have_in;
Guenter Roeck84d19d92012-12-04 08:01:39 -0800655#ifdef CONFIG_PM
656 /* Remember extra register values over suspend/resume */
657 u8 vbat;
658 u8 fandiv1;
659 u8 fandiv2;
660#endif
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700661};
662
663struct nct6775_sio_data {
664 int sioreg;
665 enum kinds kind;
666};
667
668static bool is_word_sized(struct nct6775_data *data, u16 reg)
669{
670 switch (data->kind) {
671 case nct6775:
672 return (((reg & 0xff00) == 0x100 ||
673 (reg & 0xff00) == 0x200) &&
674 ((reg & 0x00ff) == 0x50 ||
675 (reg & 0x00ff) == 0x53 ||
676 (reg & 0x00ff) == 0x55)) ||
677 (reg & 0xfff0) == 0x630 ||
678 reg == 0x640 || reg == 0x642 ||
679 reg == 0x662 ||
680 ((reg & 0xfff0) == 0x650 && (reg & 0x000f) >= 0x06) ||
681 reg == 0x73 || reg == 0x75 || reg == 0x77;
682 case nct6776:
683 return (((reg & 0xff00) == 0x100 ||
684 (reg & 0xff00) == 0x200) &&
685 ((reg & 0x00ff) == 0x50 ||
686 (reg & 0x00ff) == 0x53 ||
687 (reg & 0x00ff) == 0x55)) ||
688 (reg & 0xfff0) == 0x630 ||
689 reg == 0x402 ||
690 reg == 0x640 || reg == 0x642 ||
691 ((reg & 0xfff0) == 0x650 && (reg & 0x000f) >= 0x06) ||
692 reg == 0x73 || reg == 0x75 || reg == 0x77;
693 case nct6779:
694 return reg == 0x150 || reg == 0x153 || reg == 0x155 ||
695 ((reg & 0xfff0) == 0x4b0 && (reg & 0x000f) < 0x09) ||
696 reg == 0x402 ||
697 reg == 0x63a || reg == 0x63c || reg == 0x63e ||
698 reg == 0x640 || reg == 0x642 ||
699 reg == 0x73 || reg == 0x75 || reg == 0x77 || reg == 0x79 ||
700 reg == 0x7b;
701 }
702 return false;
703}
704
705/*
706 * On older chips, only registers 0x50-0x5f are banked.
707 * On more recent chips, all registers are banked.
708 * Assume that is the case and set the bank number for each access.
709 * Cache the bank number so it only needs to be set if it changes.
710 */
711static inline void nct6775_set_bank(struct nct6775_data *data, u16 reg)
712{
713 u8 bank = reg >> 8;
714 if (data->bank != bank) {
715 outb_p(NCT6775_REG_BANK, data->addr + ADDR_REG_OFFSET);
716 outb_p(bank, data->addr + DATA_REG_OFFSET);
717 data->bank = bank;
718 }
719}
720
721static u16 nct6775_read_value(struct nct6775_data *data, u16 reg)
722{
723 int res, word_sized = is_word_sized(data, reg);
724
725 mutex_lock(&data->lock);
726
727 nct6775_set_bank(data, reg);
728 outb_p(reg & 0xff, data->addr + ADDR_REG_OFFSET);
729 res = inb_p(data->addr + DATA_REG_OFFSET);
730 if (word_sized) {
731 outb_p((reg & 0xff) + 1,
732 data->addr + ADDR_REG_OFFSET);
733 res = (res << 8) + inb_p(data->addr + DATA_REG_OFFSET);
734 }
735
736 mutex_unlock(&data->lock);
737 return res;
738}
739
740static int nct6775_write_value(struct nct6775_data *data, u16 reg, u16 value)
741{
742 int word_sized = is_word_sized(data, reg);
743
744 mutex_lock(&data->lock);
745
746 nct6775_set_bank(data, reg);
747 outb_p(reg & 0xff, data->addr + ADDR_REG_OFFSET);
748 if (word_sized) {
749 outb_p(value >> 8, data->addr + DATA_REG_OFFSET);
750 outb_p((reg & 0xff) + 1,
751 data->addr + ADDR_REG_OFFSET);
752 }
753 outb_p(value & 0xff, data->addr + DATA_REG_OFFSET);
754
755 mutex_unlock(&data->lock);
756 return 0;
757}
758
Guenter Roeckaa136e52012-12-04 03:26:05 -0800759/* We left-align 8-bit temperature values to make the code simpler */
760static u16 nct6775_read_temp(struct nct6775_data *data, u16 reg)
761{
762 u16 res;
763
764 res = nct6775_read_value(data, reg);
765 if (!is_word_sized(data, reg))
766 res <<= 8;
767
768 return res;
769}
770
771static int nct6775_write_temp(struct nct6775_data *data, u16 reg, u16 value)
772{
773 if (!is_word_sized(data, reg))
774 value >>= 8;
775 return nct6775_write_value(data, reg, value);
776}
777
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800778/* This function assumes that the caller holds data->update_lock */
779static void nct6775_write_fan_div(struct nct6775_data *data, int nr)
780{
781 u8 reg;
782
783 switch (nr) {
784 case 0:
785 reg = (nct6775_read_value(data, NCT6775_REG_FANDIV1) & 0x70)
786 | (data->fan_div[0] & 0x7);
787 nct6775_write_value(data, NCT6775_REG_FANDIV1, reg);
788 break;
789 case 1:
790 reg = (nct6775_read_value(data, NCT6775_REG_FANDIV1) & 0x7)
791 | ((data->fan_div[1] << 4) & 0x70);
792 nct6775_write_value(data, NCT6775_REG_FANDIV1, reg);
793 break;
794 case 2:
795 reg = (nct6775_read_value(data, NCT6775_REG_FANDIV2) & 0x70)
796 | (data->fan_div[2] & 0x7);
797 nct6775_write_value(data, NCT6775_REG_FANDIV2, reg);
798 break;
799 case 3:
800 reg = (nct6775_read_value(data, NCT6775_REG_FANDIV2) & 0x7)
801 | ((data->fan_div[3] << 4) & 0x70);
802 nct6775_write_value(data, NCT6775_REG_FANDIV2, reg);
803 break;
804 }
805}
806
807static void nct6775_write_fan_div_common(struct nct6775_data *data, int nr)
808{
809 if (data->kind == nct6775)
810 nct6775_write_fan_div(data, nr);
811}
812
813static void nct6775_update_fan_div(struct nct6775_data *data)
814{
815 u8 i;
816
817 i = nct6775_read_value(data, NCT6775_REG_FANDIV1);
818 data->fan_div[0] = i & 0x7;
819 data->fan_div[1] = (i & 0x70) >> 4;
820 i = nct6775_read_value(data, NCT6775_REG_FANDIV2);
821 data->fan_div[2] = i & 0x7;
822 if (data->has_fan & (1<<3))
823 data->fan_div[3] = (i & 0x70) >> 4;
824}
825
826static void nct6775_update_fan_div_common(struct nct6775_data *data)
827{
828 if (data->kind == nct6775)
829 nct6775_update_fan_div(data);
830}
831
832static void nct6775_init_fan_div(struct nct6775_data *data)
833{
834 int i;
835
836 nct6775_update_fan_div_common(data);
837 /*
838 * For all fans, start with highest divider value if the divider
839 * register is not initialized. This ensures that we get a
840 * reading from the fan count register, even if it is not optimal.
841 * We'll compute a better divider later on.
842 */
843 for (i = 0; i < 3; i++) {
844 if (!(data->has_fan & (1 << i)))
845 continue;
846 if (data->fan_div[i] == 0) {
847 data->fan_div[i] = 7;
848 nct6775_write_fan_div_common(data, i);
849 }
850 }
851}
852
853static void nct6775_init_fan_common(struct device *dev,
854 struct nct6775_data *data)
855{
856 int i;
857 u8 reg;
858
859 if (data->has_fan_div)
860 nct6775_init_fan_div(data);
861
862 /*
863 * If fan_min is not set (0), set it to 0xff to disable it. This
864 * prevents the unnecessary warning when fanX_min is reported as 0.
865 */
866 for (i = 0; i < 5; i++) {
867 if (data->has_fan_min & (1 << i)) {
868 reg = nct6775_read_value(data, data->REG_FAN_MIN[i]);
869 if (!reg)
870 nct6775_write_value(data, data->REG_FAN_MIN[i],
871 data->has_fan_div ? 0xff
872 : 0xff1f);
873 }
874 }
875}
876
877static void nct6775_select_fan_div(struct device *dev,
878 struct nct6775_data *data, int nr, u16 reg)
879{
880 u8 fan_div = data->fan_div[nr];
881 u16 fan_min;
882
883 if (!data->has_fan_div)
884 return;
885
886 /*
887 * If we failed to measure the fan speed, or the reported value is not
888 * in the optimal range, and the clock divider can be modified,
889 * let's try that for next time.
890 */
891 if (reg == 0x00 && fan_div < 0x07)
892 fan_div++;
893 else if (reg != 0x00 && reg < 0x30 && fan_div > 0)
894 fan_div--;
895
896 if (fan_div != data->fan_div[nr]) {
897 dev_dbg(dev, "Modifying fan%d clock divider from %u to %u\n",
898 nr + 1, div_from_reg(data->fan_div[nr]),
899 div_from_reg(fan_div));
900
901 /* Preserve min limit if possible */
902 if (data->has_fan_min & (1 << nr)) {
903 fan_min = data->fan_min[nr];
904 if (fan_div > data->fan_div[nr]) {
905 if (fan_min != 255 && fan_min > 1)
906 fan_min >>= 1;
907 } else {
908 if (fan_min != 255) {
909 fan_min <<= 1;
910 if (fan_min > 254)
911 fan_min = 254;
912 }
913 }
914 if (fan_min != data->fan_min[nr]) {
915 data->fan_min[nr] = fan_min;
916 nct6775_write_value(data, data->REG_FAN_MIN[nr],
917 fan_min);
918 }
919 }
920 data->fan_div[nr] = fan_div;
921 nct6775_write_fan_div_common(data, nr);
922 }
923}
924
Guenter Roeck77eb5b32012-12-04 08:30:54 -0800925static void nct6775_update_pwm(struct device *dev)
926{
927 struct nct6775_data *data = dev_get_drvdata(dev);
928 int i, j;
Guenter Roeckcdcaece2012-12-04 09:04:52 -0800929 int fanmodecfg, reg;
Guenter Roeck77eb5b32012-12-04 08:30:54 -0800930 bool duty_is_dc;
931
932 for (i = 0; i < data->pwm_num; i++) {
933 if (!(data->has_pwm & (1 << i)))
934 continue;
935
936 duty_is_dc = data->REG_PWM_MODE[i] &&
937 (nct6775_read_value(data, data->REG_PWM_MODE[i])
938 & data->PWM_MODE_MASK[i]);
939 data->pwm_mode[i] = duty_is_dc;
940
941 fanmodecfg = nct6775_read_value(data, data->REG_FAN_MODE[i]);
942 for (j = 0; j < ARRAY_SIZE(data->REG_PWM); j++) {
943 if (data->REG_PWM[j] && data->REG_PWM[j][i]) {
944 data->pwm[j][i]
945 = nct6775_read_value(data,
946 data->REG_PWM[j][i]);
947 }
948 }
949
950 data->pwm_enable[i] = reg_to_pwm_enable(data->pwm[0][i],
951 (fanmodecfg >> 4) & 7);
Guenter Roeckcdcaece2012-12-04 09:04:52 -0800952
953 if (!data->temp_tolerance[0][i] ||
954 data->pwm_enable[i] != speed_cruise)
955 data->temp_tolerance[0][i] = fanmodecfg & 0x0f;
956 if (!data->target_speed_tolerance[i] ||
957 data->pwm_enable[i] == speed_cruise) {
958 u8 t = fanmodecfg & 0x0f;
959 if (data->REG_TOLERANCE_H) {
960 t |= (nct6775_read_value(data,
961 data->REG_TOLERANCE_H[i]) & 0x70) >> 1;
962 }
963 data->target_speed_tolerance[i] = t;
964 }
965
966 data->temp_tolerance[1][i] =
967 nct6775_read_value(data,
968 data->REG_CRITICAL_TEMP_TOLERANCE[i]);
969
970 reg = nct6775_read_value(data, data->REG_TEMP_SEL[i]);
971 data->pwm_temp_sel[i] = reg & 0x1f;
972 /* If fan can stop, report floor as 0 */
973 if (reg & 0x80)
974 data->pwm[2][i] = 0;
975 }
976}
977
978static void nct6775_update_pwm_limits(struct device *dev)
979{
980 struct nct6775_data *data = dev_get_drvdata(dev);
981 int i, j;
982 u8 reg;
983 u16 reg_t;
984
985 for (i = 0; i < data->pwm_num; i++) {
986 if (!(data->has_pwm & (1 << i)))
987 continue;
988
989 for (j = 0; j < 3; j++) {
990 data->fan_time[j][i] =
991 nct6775_read_value(data, data->REG_FAN_TIME[j][i]);
992 }
993
994 reg_t = nct6775_read_value(data, data->REG_TARGET[i]);
995 /* Update only in matching mode or if never updated */
996 if (!data->target_temp[i] ||
997 data->pwm_enable[i] == thermal_cruise)
998 data->target_temp[i] = reg_t & data->target_temp_mask;
999 if (!data->target_speed[i] ||
1000 data->pwm_enable[i] == speed_cruise) {
1001 if (data->REG_TOLERANCE_H) {
1002 reg_t |= (nct6775_read_value(data,
1003 data->REG_TOLERANCE_H[i]) & 0x0f) << 8;
1004 }
1005 data->target_speed[i] = reg_t;
1006 }
1007
1008 for (j = 0; j < data->auto_pwm_num; j++) {
1009 data->auto_pwm[i][j] =
1010 nct6775_read_value(data,
1011 NCT6775_AUTO_PWM(data, i, j));
1012 data->auto_temp[i][j] =
1013 nct6775_read_value(data,
1014 NCT6775_AUTO_TEMP(data, i, j));
1015 }
1016
1017 /* critical auto_pwm temperature data */
1018 data->auto_temp[i][data->auto_pwm_num] =
1019 nct6775_read_value(data, data->REG_CRITICAL_TEMP[i]);
1020
1021 switch (data->kind) {
1022 case nct6775:
1023 reg = nct6775_read_value(data,
1024 NCT6775_REG_CRITICAL_ENAB[i]);
1025 data->auto_pwm[i][data->auto_pwm_num] =
1026 (reg & 0x02) ? 0xff : 0x00;
1027 break;
1028 case nct6776:
1029 data->auto_pwm[i][data->auto_pwm_num] = 0xff;
1030 break;
1031 case nct6779:
1032 reg = nct6775_read_value(data,
1033 NCT6779_REG_CRITICAL_PWM_ENABLE[i]);
1034 if (reg & 1)
1035 data->auto_pwm[i][data->auto_pwm_num] =
1036 nct6775_read_value(data,
1037 NCT6779_REG_CRITICAL_PWM[i]);
1038 else
1039 data->auto_pwm[i][data->auto_pwm_num] = 0xff;
1040 break;
1041 }
Guenter Roeck77eb5b32012-12-04 08:30:54 -08001042 }
1043}
1044
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07001045static struct nct6775_data *nct6775_update_device(struct device *dev)
1046{
1047 struct nct6775_data *data = dev_get_drvdata(dev);
Guenter Roeckaa136e52012-12-04 03:26:05 -08001048 int i, j;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07001049
1050 mutex_lock(&data->update_lock);
1051
1052 if (time_after(jiffies, data->last_updated + HZ + HZ/2)
1053 || !data->valid) {
Guenter Roeck1c65dc32012-12-04 07:56:24 -08001054 /* Fan clock dividers */
1055 nct6775_update_fan_div_common(data);
1056
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07001057 /* Measured voltages and limits */
1058 for (i = 0; i < data->in_num; i++) {
1059 if (!(data->have_in & (1 << i)))
1060 continue;
1061
1062 data->in[i][0] = nct6775_read_value(data,
1063 data->REG_VIN[i]);
1064 data->in[i][1] = nct6775_read_value(data,
1065 data->REG_IN_MINMAX[0][i]);
1066 data->in[i][2] = nct6775_read_value(data,
1067 data->REG_IN_MINMAX[1][i]);
1068 }
1069
Guenter Roeck1c65dc32012-12-04 07:56:24 -08001070 /* Measured fan speeds and limits */
1071 for (i = 0; i < 5; i++) {
1072 u16 reg;
1073
1074 if (!(data->has_fan & (1 << i)))
1075 continue;
1076
1077 reg = nct6775_read_value(data, data->REG_FAN[i]);
1078 data->rpm[i] = data->fan_from_reg(reg,
1079 data->fan_div[i]);
1080
1081 if (data->has_fan_min & (1 << i))
1082 data->fan_min[i] = nct6775_read_value(data,
1083 data->REG_FAN_MIN[i]);
Guenter Roeck5c25d952012-12-11 07:29:06 -08001084 data->fan_pulses[i] =
1085 nct6775_read_value(data, data->REG_FAN_PULSES[i]);
Guenter Roeck1c65dc32012-12-04 07:56:24 -08001086
1087 nct6775_select_fan_div(dev, data, i, reg);
1088 }
1089
Guenter Roeck77eb5b32012-12-04 08:30:54 -08001090 nct6775_update_pwm(dev);
Guenter Roeckcdcaece2012-12-04 09:04:52 -08001091 nct6775_update_pwm_limits(dev);
Guenter Roeck77eb5b32012-12-04 08:30:54 -08001092
Guenter Roeckaa136e52012-12-04 03:26:05 -08001093 /* Measured temperatures and limits */
1094 for (i = 0; i < NUM_TEMP; i++) {
1095 if (!(data->have_temp & (1 << i)))
1096 continue;
1097 for (j = 0; j < 4; j++) {
1098 if (data->reg_temp[j][i])
1099 data->temp[j][i]
1100 = nct6775_read_temp(data,
1101 data->reg_temp[j][i]);
1102 }
1103 if (!(data->have_temp_fixed & (1 << i)))
1104 continue;
1105 data->temp_offset[i]
1106 = nct6775_read_value(data, data->REG_TEMP_OFFSET[i]);
1107 }
1108
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07001109 data->alarms = 0;
1110 for (i = 0; i < NUM_REG_ALARM; i++) {
1111 u8 alarm;
1112 if (!data->REG_ALARM[i])
1113 continue;
1114 alarm = nct6775_read_value(data, data->REG_ALARM[i]);
1115 data->alarms |= ((u64)alarm) << (i << 3);
1116 }
1117
1118 data->last_updated = jiffies;
1119 data->valid = true;
1120 }
1121
1122 mutex_unlock(&data->update_lock);
1123 return data;
1124}
1125
1126/*
1127 * Sysfs callback functions
1128 */
1129static ssize_t
1130show_in_reg(struct device *dev, struct device_attribute *attr, char *buf)
1131{
1132 struct nct6775_data *data = nct6775_update_device(dev);
1133 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
1134 int nr = sattr->nr;
1135 int index = sattr->index;
1136 return sprintf(buf, "%ld\n", in_from_reg(data->in[nr][index], nr));
1137}
1138
1139static ssize_t
1140store_in_reg(struct device *dev, struct device_attribute *attr, const char *buf,
1141 size_t count)
1142{
1143 struct nct6775_data *data = dev_get_drvdata(dev);
1144 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
1145 int nr = sattr->nr;
1146 int index = sattr->index;
1147 unsigned long val;
1148 int err = kstrtoul(buf, 10, &val);
1149 if (err < 0)
1150 return err;
1151 mutex_lock(&data->update_lock);
1152 data->in[nr][index] = in_to_reg(val, nr);
1153 nct6775_write_value(data, data->REG_IN_MINMAX[index-1][nr],
1154 data->in[nr][index]);
1155 mutex_unlock(&data->update_lock);
1156 return count;
1157}
1158
1159static ssize_t
1160show_alarm(struct device *dev, struct device_attribute *attr, char *buf)
1161{
1162 struct nct6775_data *data = nct6775_update_device(dev);
1163 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1164 int nr = data->ALARM_BITS[sattr->index];
1165 return sprintf(buf, "%u\n",
1166 (unsigned int)((data->alarms >> nr) & 0x01));
1167}
1168
1169static SENSOR_DEVICE_ATTR_2(in0_input, S_IRUGO, show_in_reg, NULL, 0, 0);
1170static SENSOR_DEVICE_ATTR_2(in1_input, S_IRUGO, show_in_reg, NULL, 1, 0);
1171static SENSOR_DEVICE_ATTR_2(in2_input, S_IRUGO, show_in_reg, NULL, 2, 0);
1172static SENSOR_DEVICE_ATTR_2(in3_input, S_IRUGO, show_in_reg, NULL, 3, 0);
1173static SENSOR_DEVICE_ATTR_2(in4_input, S_IRUGO, show_in_reg, NULL, 4, 0);
1174static SENSOR_DEVICE_ATTR_2(in5_input, S_IRUGO, show_in_reg, NULL, 5, 0);
1175static SENSOR_DEVICE_ATTR_2(in6_input, S_IRUGO, show_in_reg, NULL, 6, 0);
1176static SENSOR_DEVICE_ATTR_2(in7_input, S_IRUGO, show_in_reg, NULL, 7, 0);
1177static SENSOR_DEVICE_ATTR_2(in8_input, S_IRUGO, show_in_reg, NULL, 8, 0);
1178static SENSOR_DEVICE_ATTR_2(in9_input, S_IRUGO, show_in_reg, NULL, 9, 0);
1179static SENSOR_DEVICE_ATTR_2(in10_input, S_IRUGO, show_in_reg, NULL, 10, 0);
1180static SENSOR_DEVICE_ATTR_2(in11_input, S_IRUGO, show_in_reg, NULL, 11, 0);
1181static SENSOR_DEVICE_ATTR_2(in12_input, S_IRUGO, show_in_reg, NULL, 12, 0);
1182static SENSOR_DEVICE_ATTR_2(in13_input, S_IRUGO, show_in_reg, NULL, 13, 0);
1183static SENSOR_DEVICE_ATTR_2(in14_input, S_IRUGO, show_in_reg, NULL, 14, 0);
1184
1185static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0);
1186static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1);
1187static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 2);
1188static SENSOR_DEVICE_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, 3);
1189static SENSOR_DEVICE_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, 4);
1190static SENSOR_DEVICE_ATTR(in5_alarm, S_IRUGO, show_alarm, NULL, 5);
1191static SENSOR_DEVICE_ATTR(in6_alarm, S_IRUGO, show_alarm, NULL, 6);
1192static SENSOR_DEVICE_ATTR(in7_alarm, S_IRUGO, show_alarm, NULL, 7);
1193static SENSOR_DEVICE_ATTR(in8_alarm, S_IRUGO, show_alarm, NULL, 8);
1194static SENSOR_DEVICE_ATTR(in9_alarm, S_IRUGO, show_alarm, NULL, 9);
1195static SENSOR_DEVICE_ATTR(in10_alarm, S_IRUGO, show_alarm, NULL, 10);
1196static SENSOR_DEVICE_ATTR(in11_alarm, S_IRUGO, show_alarm, NULL, 11);
1197static SENSOR_DEVICE_ATTR(in12_alarm, S_IRUGO, show_alarm, NULL, 12);
1198static SENSOR_DEVICE_ATTR(in13_alarm, S_IRUGO, show_alarm, NULL, 13);
1199static SENSOR_DEVICE_ATTR(in14_alarm, S_IRUGO, show_alarm, NULL, 14);
1200
1201static SENSOR_DEVICE_ATTR_2(in0_min, S_IWUSR | S_IRUGO, show_in_reg,
1202 store_in_reg, 0, 1);
1203static SENSOR_DEVICE_ATTR_2(in1_min, S_IWUSR | S_IRUGO, show_in_reg,
1204 store_in_reg, 1, 1);
1205static SENSOR_DEVICE_ATTR_2(in2_min, S_IWUSR | S_IRUGO, show_in_reg,
1206 store_in_reg, 2, 1);
1207static SENSOR_DEVICE_ATTR_2(in3_min, S_IWUSR | S_IRUGO, show_in_reg,
1208 store_in_reg, 3, 1);
1209static SENSOR_DEVICE_ATTR_2(in4_min, S_IWUSR | S_IRUGO, show_in_reg,
1210 store_in_reg, 4, 1);
1211static SENSOR_DEVICE_ATTR_2(in5_min, S_IWUSR | S_IRUGO, show_in_reg,
1212 store_in_reg, 5, 1);
1213static SENSOR_DEVICE_ATTR_2(in6_min, S_IWUSR | S_IRUGO, show_in_reg,
1214 store_in_reg, 6, 1);
1215static SENSOR_DEVICE_ATTR_2(in7_min, S_IWUSR | S_IRUGO, show_in_reg,
1216 store_in_reg, 7, 1);
1217static SENSOR_DEVICE_ATTR_2(in8_min, S_IWUSR | S_IRUGO, show_in_reg,
1218 store_in_reg, 8, 1);
1219static SENSOR_DEVICE_ATTR_2(in9_min, S_IWUSR | S_IRUGO, show_in_reg,
1220 store_in_reg, 9, 1);
1221static SENSOR_DEVICE_ATTR_2(in10_min, S_IWUSR | S_IRUGO, show_in_reg,
1222 store_in_reg, 10, 1);
1223static SENSOR_DEVICE_ATTR_2(in11_min, S_IWUSR | S_IRUGO, show_in_reg,
1224 store_in_reg, 11, 1);
1225static SENSOR_DEVICE_ATTR_2(in12_min, S_IWUSR | S_IRUGO, show_in_reg,
1226 store_in_reg, 12, 1);
1227static SENSOR_DEVICE_ATTR_2(in13_min, S_IWUSR | S_IRUGO, show_in_reg,
1228 store_in_reg, 13, 1);
1229static SENSOR_DEVICE_ATTR_2(in14_min, S_IWUSR | S_IRUGO, show_in_reg,
1230 store_in_reg, 14, 1);
1231
1232static SENSOR_DEVICE_ATTR_2(in0_max, S_IWUSR | S_IRUGO, show_in_reg,
1233 store_in_reg, 0, 2);
1234static SENSOR_DEVICE_ATTR_2(in1_max, S_IWUSR | S_IRUGO, show_in_reg,
1235 store_in_reg, 1, 2);
1236static SENSOR_DEVICE_ATTR_2(in2_max, S_IWUSR | S_IRUGO, show_in_reg,
1237 store_in_reg, 2, 2);
1238static SENSOR_DEVICE_ATTR_2(in3_max, S_IWUSR | S_IRUGO, show_in_reg,
1239 store_in_reg, 3, 2);
1240static SENSOR_DEVICE_ATTR_2(in4_max, S_IWUSR | S_IRUGO, show_in_reg,
1241 store_in_reg, 4, 2);
1242static SENSOR_DEVICE_ATTR_2(in5_max, S_IWUSR | S_IRUGO, show_in_reg,
1243 store_in_reg, 5, 2);
1244static SENSOR_DEVICE_ATTR_2(in6_max, S_IWUSR | S_IRUGO, show_in_reg,
1245 store_in_reg, 6, 2);
1246static SENSOR_DEVICE_ATTR_2(in7_max, S_IWUSR | S_IRUGO, show_in_reg,
1247 store_in_reg, 7, 2);
1248static SENSOR_DEVICE_ATTR_2(in8_max, S_IWUSR | S_IRUGO, show_in_reg,
1249 store_in_reg, 8, 2);
1250static SENSOR_DEVICE_ATTR_2(in9_max, S_IWUSR | S_IRUGO, show_in_reg,
1251 store_in_reg, 9, 2);
1252static SENSOR_DEVICE_ATTR_2(in10_max, S_IWUSR | S_IRUGO, show_in_reg,
1253 store_in_reg, 10, 2);
1254static SENSOR_DEVICE_ATTR_2(in11_max, S_IWUSR | S_IRUGO, show_in_reg,
1255 store_in_reg, 11, 2);
1256static SENSOR_DEVICE_ATTR_2(in12_max, S_IWUSR | S_IRUGO, show_in_reg,
1257 store_in_reg, 12, 2);
1258static SENSOR_DEVICE_ATTR_2(in13_max, S_IWUSR | S_IRUGO, show_in_reg,
1259 store_in_reg, 13, 2);
1260static SENSOR_DEVICE_ATTR_2(in14_max, S_IWUSR | S_IRUGO, show_in_reg,
1261 store_in_reg, 14, 2);
1262
1263static struct attribute *nct6775_attributes_in[15][5] = {
1264 {
1265 &sensor_dev_attr_in0_input.dev_attr.attr,
1266 &sensor_dev_attr_in0_min.dev_attr.attr,
1267 &sensor_dev_attr_in0_max.dev_attr.attr,
1268 &sensor_dev_attr_in0_alarm.dev_attr.attr,
1269 NULL
1270 },
1271 {
1272 &sensor_dev_attr_in1_input.dev_attr.attr,
1273 &sensor_dev_attr_in1_min.dev_attr.attr,
1274 &sensor_dev_attr_in1_max.dev_attr.attr,
1275 &sensor_dev_attr_in1_alarm.dev_attr.attr,
1276 NULL
1277 },
1278 {
1279 &sensor_dev_attr_in2_input.dev_attr.attr,
1280 &sensor_dev_attr_in2_min.dev_attr.attr,
1281 &sensor_dev_attr_in2_max.dev_attr.attr,
1282 &sensor_dev_attr_in2_alarm.dev_attr.attr,
1283 NULL
1284 },
1285 {
1286 &sensor_dev_attr_in3_input.dev_attr.attr,
1287 &sensor_dev_attr_in3_min.dev_attr.attr,
1288 &sensor_dev_attr_in3_max.dev_attr.attr,
1289 &sensor_dev_attr_in3_alarm.dev_attr.attr,
1290 NULL
1291 },
1292 {
1293 &sensor_dev_attr_in4_input.dev_attr.attr,
1294 &sensor_dev_attr_in4_min.dev_attr.attr,
1295 &sensor_dev_attr_in4_max.dev_attr.attr,
1296 &sensor_dev_attr_in4_alarm.dev_attr.attr,
1297 NULL
1298 },
1299 {
1300 &sensor_dev_attr_in5_input.dev_attr.attr,
1301 &sensor_dev_attr_in5_min.dev_attr.attr,
1302 &sensor_dev_attr_in5_max.dev_attr.attr,
1303 &sensor_dev_attr_in5_alarm.dev_attr.attr,
1304 NULL
1305 },
1306 {
1307 &sensor_dev_attr_in6_input.dev_attr.attr,
1308 &sensor_dev_attr_in6_min.dev_attr.attr,
1309 &sensor_dev_attr_in6_max.dev_attr.attr,
1310 &sensor_dev_attr_in6_alarm.dev_attr.attr,
1311 NULL
1312 },
1313 {
1314 &sensor_dev_attr_in7_input.dev_attr.attr,
1315 &sensor_dev_attr_in7_min.dev_attr.attr,
1316 &sensor_dev_attr_in7_max.dev_attr.attr,
1317 &sensor_dev_attr_in7_alarm.dev_attr.attr,
1318 NULL
1319 },
1320 {
1321 &sensor_dev_attr_in8_input.dev_attr.attr,
1322 &sensor_dev_attr_in8_min.dev_attr.attr,
1323 &sensor_dev_attr_in8_max.dev_attr.attr,
1324 &sensor_dev_attr_in8_alarm.dev_attr.attr,
1325 NULL
1326 },
1327 {
1328 &sensor_dev_attr_in9_input.dev_attr.attr,
1329 &sensor_dev_attr_in9_min.dev_attr.attr,
1330 &sensor_dev_attr_in9_max.dev_attr.attr,
1331 &sensor_dev_attr_in9_alarm.dev_attr.attr,
1332 NULL
1333 },
1334 {
1335 &sensor_dev_attr_in10_input.dev_attr.attr,
1336 &sensor_dev_attr_in10_min.dev_attr.attr,
1337 &sensor_dev_attr_in10_max.dev_attr.attr,
1338 &sensor_dev_attr_in10_alarm.dev_attr.attr,
1339 NULL
1340 },
1341 {
1342 &sensor_dev_attr_in11_input.dev_attr.attr,
1343 &sensor_dev_attr_in11_min.dev_attr.attr,
1344 &sensor_dev_attr_in11_max.dev_attr.attr,
1345 &sensor_dev_attr_in11_alarm.dev_attr.attr,
1346 NULL
1347 },
1348 {
1349 &sensor_dev_attr_in12_input.dev_attr.attr,
1350 &sensor_dev_attr_in12_min.dev_attr.attr,
1351 &sensor_dev_attr_in12_max.dev_attr.attr,
1352 &sensor_dev_attr_in12_alarm.dev_attr.attr,
1353 NULL
1354 },
1355 {
1356 &sensor_dev_attr_in13_input.dev_attr.attr,
1357 &sensor_dev_attr_in13_min.dev_attr.attr,
1358 &sensor_dev_attr_in13_max.dev_attr.attr,
1359 &sensor_dev_attr_in13_alarm.dev_attr.attr,
1360 NULL
1361 },
1362 {
1363 &sensor_dev_attr_in14_input.dev_attr.attr,
1364 &sensor_dev_attr_in14_min.dev_attr.attr,
1365 &sensor_dev_attr_in14_max.dev_attr.attr,
1366 &sensor_dev_attr_in14_alarm.dev_attr.attr,
1367 NULL
1368 },
1369};
1370
1371static const struct attribute_group nct6775_group_in[15] = {
1372 { .attrs = nct6775_attributes_in[0] },
1373 { .attrs = nct6775_attributes_in[1] },
1374 { .attrs = nct6775_attributes_in[2] },
1375 { .attrs = nct6775_attributes_in[3] },
1376 { .attrs = nct6775_attributes_in[4] },
1377 { .attrs = nct6775_attributes_in[5] },
1378 { .attrs = nct6775_attributes_in[6] },
1379 { .attrs = nct6775_attributes_in[7] },
1380 { .attrs = nct6775_attributes_in[8] },
1381 { .attrs = nct6775_attributes_in[9] },
1382 { .attrs = nct6775_attributes_in[10] },
1383 { .attrs = nct6775_attributes_in[11] },
1384 { .attrs = nct6775_attributes_in[12] },
1385 { .attrs = nct6775_attributes_in[13] },
1386 { .attrs = nct6775_attributes_in[14] },
1387};
1388
1389static ssize_t
Guenter Roeck1c65dc32012-12-04 07:56:24 -08001390show_fan(struct device *dev, struct device_attribute *attr, char *buf)
1391{
1392 struct nct6775_data *data = nct6775_update_device(dev);
1393 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1394 int nr = sattr->index;
1395 return sprintf(buf, "%d\n", data->rpm[nr]);
1396}
1397
1398static ssize_t
1399show_fan_min(struct device *dev, struct device_attribute *attr, char *buf)
1400{
1401 struct nct6775_data *data = nct6775_update_device(dev);
1402 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1403 int nr = sattr->index;
1404 return sprintf(buf, "%d\n",
1405 data->fan_from_reg_min(data->fan_min[nr],
1406 data->fan_div[nr]));
1407}
1408
1409static ssize_t
1410show_fan_div(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, "%u\n", div_from_reg(data->fan_div[nr]));
1416}
1417
1418static ssize_t
1419store_fan_min(struct device *dev, struct device_attribute *attr,
1420 const char *buf, size_t count)
1421{
1422 struct nct6775_data *data = dev_get_drvdata(dev);
1423 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1424 int nr = sattr->index;
1425 unsigned long val;
1426 int err;
1427 unsigned int reg;
1428 u8 new_div;
1429
1430 err = kstrtoul(buf, 10, &val);
1431 if (err < 0)
1432 return err;
1433
1434 mutex_lock(&data->update_lock);
1435 if (!data->has_fan_div) {
1436 /* NCT6776F or NCT6779D; we know this is a 13 bit register */
1437 if (!val) {
1438 val = 0xff1f;
1439 } else {
1440 if (val > 1350000U)
1441 val = 135000U;
1442 val = 1350000U / val;
1443 val = (val & 0x1f) | ((val << 3) & 0xff00);
1444 }
1445 data->fan_min[nr] = val;
1446 goto write_min; /* Leave fan divider alone */
1447 }
1448 if (!val) {
1449 /* No min limit, alarm disabled */
1450 data->fan_min[nr] = 255;
1451 new_div = data->fan_div[nr]; /* No change */
1452 dev_info(dev, "fan%u low limit and alarm disabled\n", nr + 1);
1453 goto write_div;
1454 }
1455 reg = 1350000U / val;
1456 if (reg >= 128 * 255) {
1457 /*
1458 * Speed below this value cannot possibly be represented,
1459 * even with the highest divider (128)
1460 */
1461 data->fan_min[nr] = 254;
1462 new_div = 7; /* 128 == (1 << 7) */
1463 dev_warn(dev,
1464 "fan%u low limit %lu below minimum %u, set to minimum\n",
1465 nr + 1, val, data->fan_from_reg_min(254, 7));
1466 } else if (!reg) {
1467 /*
1468 * Speed above this value cannot possibly be represented,
1469 * even with the lowest divider (1)
1470 */
1471 data->fan_min[nr] = 1;
1472 new_div = 0; /* 1 == (1 << 0) */
1473 dev_warn(dev,
1474 "fan%u low limit %lu above maximum %u, set to maximum\n",
1475 nr + 1, val, data->fan_from_reg_min(1, 0));
1476 } else {
1477 /*
1478 * Automatically pick the best divider, i.e. the one such
1479 * that the min limit will correspond to a register value
1480 * in the 96..192 range
1481 */
1482 new_div = 0;
1483 while (reg > 192 && new_div < 7) {
1484 reg >>= 1;
1485 new_div++;
1486 }
1487 data->fan_min[nr] = reg;
1488 }
1489
1490write_div:
1491 /*
1492 * Write both the fan clock divider (if it changed) and the new
1493 * fan min (unconditionally)
1494 */
1495 if (new_div != data->fan_div[nr]) {
1496 dev_dbg(dev, "fan%u clock divider changed from %u to %u\n",
1497 nr + 1, div_from_reg(data->fan_div[nr]),
1498 div_from_reg(new_div));
1499 data->fan_div[nr] = new_div;
1500 nct6775_write_fan_div_common(data, nr);
1501 /* Give the chip time to sample a new speed value */
1502 data->last_updated = jiffies;
1503 }
1504
1505write_min:
1506 nct6775_write_value(data, data->REG_FAN_MIN[nr], data->fan_min[nr]);
1507 mutex_unlock(&data->update_lock);
1508
1509 return count;
1510}
1511
Guenter Roeck5c25d952012-12-11 07:29:06 -08001512static ssize_t
1513show_fan_pulses(struct device *dev, struct device_attribute *attr, char *buf)
1514{
1515 struct nct6775_data *data = nct6775_update_device(dev);
1516 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1517 int p = data->fan_pulses[sattr->index];
1518
1519 return sprintf(buf, "%d\n", p ? : 4);
1520}
1521
1522static ssize_t
1523store_fan_pulses(struct device *dev, struct device_attribute *attr,
1524 const char *buf, size_t count)
1525{
1526 struct nct6775_data *data = dev_get_drvdata(dev);
1527 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1528 int nr = sattr->index;
1529 unsigned long val;
1530 int err;
1531
1532 err = kstrtoul(buf, 10, &val);
1533 if (err < 0)
1534 return err;
1535
1536 if (val > 4)
1537 return -EINVAL;
1538
1539 mutex_lock(&data->update_lock);
1540 data->fan_pulses[nr] = val & 3;
1541 nct6775_write_value(data, data->REG_FAN_PULSES[nr], val & 3);
1542 mutex_unlock(&data->update_lock);
1543
1544 return count;
1545}
1546
Guenter Roeck1c65dc32012-12-04 07:56:24 -08001547static struct sensor_device_attribute sda_fan_input[] = {
1548 SENSOR_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0),
1549 SENSOR_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1),
1550 SENSOR_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2),
1551 SENSOR_ATTR(fan4_input, S_IRUGO, show_fan, NULL, 3),
1552 SENSOR_ATTR(fan5_input, S_IRUGO, show_fan, NULL, 4),
1553};
1554
1555static struct sensor_device_attribute sda_fan_alarm[] = {
1556 SENSOR_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, FAN_ALARM_BASE),
1557 SENSOR_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, FAN_ALARM_BASE + 1),
1558 SENSOR_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL, FAN_ALARM_BASE + 2),
1559 SENSOR_ATTR(fan4_alarm, S_IRUGO, show_alarm, NULL, FAN_ALARM_BASE + 3),
1560 SENSOR_ATTR(fan5_alarm, S_IRUGO, show_alarm, NULL, FAN_ALARM_BASE + 4),
1561};
1562
1563static struct sensor_device_attribute sda_fan_min[] = {
1564 SENSOR_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan_min,
1565 store_fan_min, 0),
1566 SENSOR_ATTR(fan2_min, S_IWUSR | S_IRUGO, show_fan_min,
1567 store_fan_min, 1),
1568 SENSOR_ATTR(fan3_min, S_IWUSR | S_IRUGO, show_fan_min,
1569 store_fan_min, 2),
1570 SENSOR_ATTR(fan4_min, S_IWUSR | S_IRUGO, show_fan_min,
1571 store_fan_min, 3),
1572 SENSOR_ATTR(fan5_min, S_IWUSR | S_IRUGO, show_fan_min,
1573 store_fan_min, 4),
1574};
1575
Guenter Roeck5c25d952012-12-11 07:29:06 -08001576static struct sensor_device_attribute sda_fan_pulses[] = {
1577 SENSOR_ATTR(fan1_pulses, S_IWUSR | S_IRUGO, show_fan_pulses,
1578 store_fan_pulses, 0),
1579 SENSOR_ATTR(fan2_pulses, S_IWUSR | S_IRUGO, show_fan_pulses,
1580 store_fan_pulses, 1),
1581 SENSOR_ATTR(fan3_pulses, S_IWUSR | S_IRUGO, show_fan_pulses,
1582 store_fan_pulses, 2),
1583 SENSOR_ATTR(fan4_pulses, S_IWUSR | S_IRUGO, show_fan_pulses,
1584 store_fan_pulses, 3),
1585 SENSOR_ATTR(fan5_pulses, S_IWUSR | S_IRUGO, show_fan_pulses,
1586 store_fan_pulses, 4),
1587};
1588
Guenter Roeck1c65dc32012-12-04 07:56:24 -08001589static struct sensor_device_attribute sda_fan_div[] = {
1590 SENSOR_ATTR(fan1_div, S_IRUGO, show_fan_div, NULL, 0),
1591 SENSOR_ATTR(fan2_div, S_IRUGO, show_fan_div, NULL, 1),
1592 SENSOR_ATTR(fan3_div, S_IRUGO, show_fan_div, NULL, 2),
1593 SENSOR_ATTR(fan4_div, S_IRUGO, show_fan_div, NULL, 3),
1594 SENSOR_ATTR(fan5_div, S_IRUGO, show_fan_div, NULL, 4),
1595};
1596
1597static ssize_t
Guenter Roeckaa136e52012-12-04 03:26:05 -08001598show_temp_label(struct device *dev, struct device_attribute *attr, char *buf)
1599{
1600 struct nct6775_data *data = nct6775_update_device(dev);
1601 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1602 int nr = sattr->index;
1603 return sprintf(buf, "%s\n", data->temp_label[data->temp_src[nr]]);
1604}
1605
1606static ssize_t
1607show_temp(struct device *dev, struct device_attribute *attr, char *buf)
1608{
1609 struct nct6775_data *data = nct6775_update_device(dev);
1610 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
1611 int nr = sattr->nr;
1612 int index = sattr->index;
1613
1614 return sprintf(buf, "%d\n", LM75_TEMP_FROM_REG(data->temp[index][nr]));
1615}
1616
1617static ssize_t
1618store_temp(struct device *dev, struct device_attribute *attr, const char *buf,
1619 size_t count)
1620{
1621 struct nct6775_data *data = dev_get_drvdata(dev);
1622 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
1623 int nr = sattr->nr;
1624 int index = sattr->index;
1625 int err;
1626 long val;
1627
1628 err = kstrtol(buf, 10, &val);
1629 if (err < 0)
1630 return err;
1631
1632 mutex_lock(&data->update_lock);
1633 data->temp[index][nr] = LM75_TEMP_TO_REG(val);
1634 nct6775_write_temp(data, data->reg_temp[index][nr],
1635 data->temp[index][nr]);
1636 mutex_unlock(&data->update_lock);
1637 return count;
1638}
1639
1640static ssize_t
1641show_temp_offset(struct device *dev, struct device_attribute *attr, char *buf)
1642{
1643 struct nct6775_data *data = nct6775_update_device(dev);
1644 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1645
1646 return sprintf(buf, "%d\n", data->temp_offset[sattr->index] * 1000);
1647}
1648
1649static ssize_t
1650store_temp_offset(struct device *dev, struct device_attribute *attr,
1651 const char *buf, size_t count)
1652{
1653 struct nct6775_data *data = dev_get_drvdata(dev);
1654 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1655 int nr = sattr->index;
1656 long val;
1657 int err;
1658
1659 err = kstrtol(buf, 10, &val);
1660 if (err < 0)
1661 return err;
1662
1663 val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), -128, 127);
1664
1665 mutex_lock(&data->update_lock);
1666 data->temp_offset[nr] = val;
1667 nct6775_write_value(data, data->REG_TEMP_OFFSET[nr], val);
1668 mutex_unlock(&data->update_lock);
1669
1670 return count;
1671}
1672
1673static ssize_t
1674show_temp_type(struct device *dev, struct device_attribute *attr, char *buf)
1675{
1676 struct nct6775_data *data = nct6775_update_device(dev);
1677 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1678 int nr = sattr->index;
1679 return sprintf(buf, "%d\n", (int)data->temp_type[nr]);
1680}
1681
1682static ssize_t
1683store_temp_type(struct device *dev, struct device_attribute *attr,
1684 const char *buf, size_t count)
1685{
1686 struct nct6775_data *data = nct6775_update_device(dev);
1687 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1688 int nr = sattr->index;
1689 unsigned long val;
1690 int err;
1691 u8 vbat, diode, bit;
1692
1693 err = kstrtoul(buf, 10, &val);
1694 if (err < 0)
1695 return err;
1696
1697 if (val != 1 && val != 3 && val != 4)
1698 return -EINVAL;
1699
1700 mutex_lock(&data->update_lock);
1701
1702 data->temp_type[nr] = val;
1703 vbat = nct6775_read_value(data, data->REG_VBAT) & ~(0x02 << nr);
1704 diode = nct6775_read_value(data, data->REG_DIODE) & ~(0x02 << nr);
1705 bit = 0x02 << nr;
1706 switch (val) {
1707 case 1: /* CPU diode (diode, current mode) */
1708 vbat |= bit;
1709 diode |= bit;
1710 break;
1711 case 3: /* diode, voltage mode */
1712 vbat |= bit;
1713 break;
1714 case 4: /* thermistor */
1715 break;
1716 }
1717 nct6775_write_value(data, data->REG_VBAT, vbat);
1718 nct6775_write_value(data, data->REG_DIODE, diode);
1719
1720 mutex_unlock(&data->update_lock);
1721 return count;
1722}
1723
1724static struct sensor_device_attribute_2 sda_temp_input[] = {
1725 SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0),
1726 SENSOR_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 1, 0),
1727 SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 2, 0),
1728 SENSOR_ATTR_2(temp4_input, S_IRUGO, show_temp, NULL, 3, 0),
1729 SENSOR_ATTR_2(temp5_input, S_IRUGO, show_temp, NULL, 4, 0),
1730 SENSOR_ATTR_2(temp6_input, S_IRUGO, show_temp, NULL, 5, 0),
1731 SENSOR_ATTR_2(temp7_input, S_IRUGO, show_temp, NULL, 6, 0),
1732 SENSOR_ATTR_2(temp8_input, S_IRUGO, show_temp, NULL, 7, 0),
1733 SENSOR_ATTR_2(temp9_input, S_IRUGO, show_temp, NULL, 8, 0),
1734 SENSOR_ATTR_2(temp10_input, S_IRUGO, show_temp, NULL, 9, 0),
1735};
1736
1737static struct sensor_device_attribute sda_temp_label[] = {
1738 SENSOR_ATTR(temp1_label, S_IRUGO, show_temp_label, NULL, 0),
1739 SENSOR_ATTR(temp2_label, S_IRUGO, show_temp_label, NULL, 1),
1740 SENSOR_ATTR(temp3_label, S_IRUGO, show_temp_label, NULL, 2),
1741 SENSOR_ATTR(temp4_label, S_IRUGO, show_temp_label, NULL, 3),
1742 SENSOR_ATTR(temp5_label, S_IRUGO, show_temp_label, NULL, 4),
1743 SENSOR_ATTR(temp6_label, S_IRUGO, show_temp_label, NULL, 5),
1744 SENSOR_ATTR(temp7_label, S_IRUGO, show_temp_label, NULL, 6),
1745 SENSOR_ATTR(temp8_label, S_IRUGO, show_temp_label, NULL, 7),
1746 SENSOR_ATTR(temp9_label, S_IRUGO, show_temp_label, NULL, 8),
1747 SENSOR_ATTR(temp10_label, S_IRUGO, show_temp_label, NULL, 9),
1748};
1749
1750static struct sensor_device_attribute_2 sda_temp_max[] = {
1751 SENSOR_ATTR_2(temp1_max, S_IRUGO | S_IWUSR, show_temp, store_temp,
1752 0, 1),
1753 SENSOR_ATTR_2(temp2_max, S_IRUGO | S_IWUSR, show_temp, store_temp,
1754 1, 1),
1755 SENSOR_ATTR_2(temp3_max, S_IRUGO | S_IWUSR, show_temp, store_temp,
1756 2, 1),
1757 SENSOR_ATTR_2(temp4_max, S_IRUGO | S_IWUSR, show_temp, store_temp,
1758 3, 1),
1759 SENSOR_ATTR_2(temp5_max, S_IRUGO | S_IWUSR, show_temp, store_temp,
1760 4, 1),
1761 SENSOR_ATTR_2(temp6_max, S_IRUGO | S_IWUSR, show_temp, store_temp,
1762 5, 1),
1763 SENSOR_ATTR_2(temp7_max, S_IRUGO | S_IWUSR, show_temp, store_temp,
1764 6, 1),
1765 SENSOR_ATTR_2(temp8_max, S_IRUGO | S_IWUSR, show_temp, store_temp,
1766 7, 1),
1767 SENSOR_ATTR_2(temp9_max, S_IRUGO | S_IWUSR, show_temp, store_temp,
1768 8, 1),
1769 SENSOR_ATTR_2(temp10_max, S_IRUGO | S_IWUSR, show_temp, store_temp,
1770 9, 1),
1771};
1772
1773static struct sensor_device_attribute_2 sda_temp_max_hyst[] = {
1774 SENSOR_ATTR_2(temp1_max_hyst, S_IRUGO | S_IWUSR, show_temp, store_temp,
1775 0, 2),
1776 SENSOR_ATTR_2(temp2_max_hyst, S_IRUGO | S_IWUSR, show_temp, store_temp,
1777 1, 2),
1778 SENSOR_ATTR_2(temp3_max_hyst, S_IRUGO | S_IWUSR, show_temp, store_temp,
1779 2, 2),
1780 SENSOR_ATTR_2(temp4_max_hyst, S_IRUGO | S_IWUSR, show_temp, store_temp,
1781 3, 2),
1782 SENSOR_ATTR_2(temp5_max_hyst, S_IRUGO | S_IWUSR, show_temp, store_temp,
1783 4, 2),
1784 SENSOR_ATTR_2(temp6_max_hyst, S_IRUGO | S_IWUSR, show_temp, store_temp,
1785 5, 2),
1786 SENSOR_ATTR_2(temp7_max_hyst, S_IRUGO | S_IWUSR, show_temp, store_temp,
1787 6, 2),
1788 SENSOR_ATTR_2(temp8_max_hyst, S_IRUGO | S_IWUSR, show_temp, store_temp,
1789 7, 2),
1790 SENSOR_ATTR_2(temp9_max_hyst, S_IRUGO | S_IWUSR, show_temp, store_temp,
1791 8, 2),
1792 SENSOR_ATTR_2(temp10_max_hyst, S_IRUGO | S_IWUSR, show_temp, store_temp,
1793 9, 2),
1794};
1795
1796static struct sensor_device_attribute_2 sda_temp_crit[] = {
1797 SENSOR_ATTR_2(temp1_crit, S_IRUGO | S_IWUSR, show_temp, store_temp,
1798 0, 3),
1799 SENSOR_ATTR_2(temp2_crit, S_IRUGO | S_IWUSR, show_temp, store_temp,
1800 1, 3),
1801 SENSOR_ATTR_2(temp3_crit, S_IRUGO | S_IWUSR, show_temp, store_temp,
1802 2, 3),
1803 SENSOR_ATTR_2(temp4_crit, S_IRUGO | S_IWUSR, show_temp, store_temp,
1804 3, 3),
1805 SENSOR_ATTR_2(temp5_crit, S_IRUGO | S_IWUSR, show_temp, store_temp,
1806 4, 3),
1807 SENSOR_ATTR_2(temp6_crit, S_IRUGO | S_IWUSR, show_temp, store_temp,
1808 5, 3),
1809 SENSOR_ATTR_2(temp7_crit, S_IRUGO | S_IWUSR, show_temp, store_temp,
1810 6, 3),
1811 SENSOR_ATTR_2(temp8_crit, S_IRUGO | S_IWUSR, show_temp, store_temp,
1812 7, 3),
1813 SENSOR_ATTR_2(temp9_crit, S_IRUGO | S_IWUSR, show_temp, store_temp,
1814 8, 3),
1815 SENSOR_ATTR_2(temp10_crit, S_IRUGO | S_IWUSR, show_temp, store_temp,
1816 9, 3),
1817};
1818
1819static struct sensor_device_attribute sda_temp_offset[] = {
1820 SENSOR_ATTR(temp1_offset, S_IRUGO | S_IWUSR, show_temp_offset,
1821 store_temp_offset, 0),
1822 SENSOR_ATTR(temp2_offset, S_IRUGO | S_IWUSR, show_temp_offset,
1823 store_temp_offset, 1),
1824 SENSOR_ATTR(temp3_offset, S_IRUGO | S_IWUSR, show_temp_offset,
1825 store_temp_offset, 2),
1826 SENSOR_ATTR(temp4_offset, S_IRUGO | S_IWUSR, show_temp_offset,
1827 store_temp_offset, 3),
1828 SENSOR_ATTR(temp5_offset, S_IRUGO | S_IWUSR, show_temp_offset,
1829 store_temp_offset, 4),
1830 SENSOR_ATTR(temp6_offset, S_IRUGO | S_IWUSR, show_temp_offset,
1831 store_temp_offset, 5),
1832};
1833
1834static struct sensor_device_attribute sda_temp_type[] = {
1835 SENSOR_ATTR(temp1_type, S_IRUGO | S_IWUSR, show_temp_type,
1836 store_temp_type, 0),
1837 SENSOR_ATTR(temp2_type, S_IRUGO | S_IWUSR, show_temp_type,
1838 store_temp_type, 1),
1839 SENSOR_ATTR(temp3_type, S_IRUGO | S_IWUSR, show_temp_type,
1840 store_temp_type, 2),
1841 SENSOR_ATTR(temp4_type, S_IRUGO | S_IWUSR, show_temp_type,
1842 store_temp_type, 3),
1843 SENSOR_ATTR(temp5_type, S_IRUGO | S_IWUSR, show_temp_type,
1844 store_temp_type, 4),
1845 SENSOR_ATTR(temp6_type, S_IRUGO | S_IWUSR, show_temp_type,
1846 store_temp_type, 5),
1847};
1848
1849static struct sensor_device_attribute sda_temp_alarm[] = {
1850 SENSOR_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL,
1851 TEMP_ALARM_BASE),
1852 SENSOR_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL,
1853 TEMP_ALARM_BASE + 1),
1854 SENSOR_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL,
1855 TEMP_ALARM_BASE + 2),
1856 SENSOR_ATTR(temp4_alarm, S_IRUGO, show_alarm, NULL,
1857 TEMP_ALARM_BASE + 3),
1858 SENSOR_ATTR(temp5_alarm, S_IRUGO, show_alarm, NULL,
1859 TEMP_ALARM_BASE + 4),
1860 SENSOR_ATTR(temp6_alarm, S_IRUGO, show_alarm, NULL,
1861 TEMP_ALARM_BASE + 5),
1862};
1863
1864#define NUM_TEMP_ALARM ARRAY_SIZE(sda_temp_alarm)
1865
1866static ssize_t
Guenter Roeck77eb5b32012-12-04 08:30:54 -08001867show_pwm_mode(struct device *dev, struct device_attribute *attr, char *buf)
1868{
1869 struct nct6775_data *data = nct6775_update_device(dev);
1870 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1871
1872 return sprintf(buf, "%d\n", !data->pwm_mode[sattr->index]);
1873}
1874
1875static ssize_t
1876store_pwm_mode(struct device *dev, struct device_attribute *attr,
1877 const char *buf, size_t count)
1878{
1879 struct nct6775_data *data = dev_get_drvdata(dev);
1880 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1881 int nr = sattr->index;
1882 unsigned long val;
1883 int err;
1884 u8 reg;
1885
1886 err = kstrtoul(buf, 10, &val);
1887 if (err < 0)
1888 return err;
1889
1890 if (val > 1)
1891 return -EINVAL;
1892
1893 /* Setting DC mode is not supported for all chips/channels */
1894 if (data->REG_PWM_MODE[nr] == 0) {
1895 if (val)
1896 return -EINVAL;
1897 return count;
1898 }
1899
1900 mutex_lock(&data->update_lock);
1901 data->pwm_mode[nr] = val;
1902 reg = nct6775_read_value(data, data->REG_PWM_MODE[nr]);
1903 reg &= ~data->PWM_MODE_MASK[nr];
1904 if (val)
1905 reg |= data->PWM_MODE_MASK[nr];
1906 nct6775_write_value(data, data->REG_PWM_MODE[nr], reg);
1907 mutex_unlock(&data->update_lock);
1908 return count;
1909}
1910
1911static ssize_t
1912show_pwm(struct device *dev, struct device_attribute *attr, char *buf)
1913{
1914 struct nct6775_data *data = nct6775_update_device(dev);
1915 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
1916 int nr = sattr->nr;
1917 int index = sattr->index;
1918 int pwm;
1919
1920 /*
1921 * For automatic fan control modes, show current pwm readings.
1922 * Otherwise, show the configured value.
1923 */
1924 if (index == 0 && data->pwm_enable[nr] > manual)
1925 pwm = nct6775_read_value(data, data->REG_PWM_READ[nr]);
1926 else
1927 pwm = data->pwm[index][nr];
1928
1929 return sprintf(buf, "%d\n", pwm);
1930}
1931
1932static ssize_t
1933store_pwm(struct device *dev, struct device_attribute *attr, const char *buf,
1934 size_t count)
1935{
1936 struct nct6775_data *data = dev_get_drvdata(dev);
1937 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
1938 int nr = sattr->nr;
1939 int index = sattr->index;
1940 unsigned long val;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08001941 int minval[5] = { 0, 1, 1, data->pwm[2][nr], 0 };
1942 int maxval[5]
1943 = { 255, 255, data->pwm[3][nr] ? : 255, 255, 255 };
Guenter Roeck77eb5b32012-12-04 08:30:54 -08001944 int err;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08001945 u8 reg;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08001946
1947 err = kstrtoul(buf, 10, &val);
1948 if (err < 0)
1949 return err;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08001950 val = clamp_val(val, minval[index], maxval[index]);
Guenter Roeck77eb5b32012-12-04 08:30:54 -08001951
1952 mutex_lock(&data->update_lock);
1953 data->pwm[index][nr] = val;
1954 nct6775_write_value(data, data->REG_PWM[index][nr], val);
Guenter Roeckcdcaece2012-12-04 09:04:52 -08001955 if (index == 2) { /* floor: disable if val == 0 */
1956 reg = nct6775_read_value(data, data->REG_TEMP_SEL[nr]);
1957 reg &= 0x7f;
1958 if (val)
1959 reg |= 0x80;
1960 nct6775_write_value(data, data->REG_TEMP_SEL[nr], reg);
1961 }
Guenter Roeck77eb5b32012-12-04 08:30:54 -08001962 mutex_unlock(&data->update_lock);
1963 return count;
1964}
1965
Guenter Roeckcdcaece2012-12-04 09:04:52 -08001966/* Returns 0 if OK, -EINVAL otherwise */
1967static int check_trip_points(struct nct6775_data *data, int nr)
1968{
1969 int i;
1970
1971 for (i = 0; i < data->auto_pwm_num - 1; i++) {
1972 if (data->auto_temp[nr][i] > data->auto_temp[nr][i + 1])
1973 return -EINVAL;
1974 }
1975 for (i = 0; i < data->auto_pwm_num - 1; i++) {
1976 if (data->auto_pwm[nr][i] > data->auto_pwm[nr][i + 1])
1977 return -EINVAL;
1978 }
1979 /* validate critical temperature and pwm if enabled (pwm > 0) */
1980 if (data->auto_pwm[nr][data->auto_pwm_num]) {
1981 if (data->auto_temp[nr][data->auto_pwm_num - 1] >
1982 data->auto_temp[nr][data->auto_pwm_num] ||
1983 data->auto_pwm[nr][data->auto_pwm_num - 1] >
1984 data->auto_pwm[nr][data->auto_pwm_num])
1985 return -EINVAL;
1986 }
1987 return 0;
1988}
1989
1990static void pwm_update_registers(struct nct6775_data *data, int nr)
1991{
1992 u8 reg;
1993
1994 switch (data->pwm_enable[nr]) {
1995 case off:
1996 case manual:
1997 break;
1998 case speed_cruise:
1999 reg = nct6775_read_value(data, data->REG_FAN_MODE[nr]);
2000 reg = (reg & ~data->tolerance_mask) |
2001 (data->target_speed_tolerance[nr] & data->tolerance_mask);
2002 nct6775_write_value(data, data->REG_FAN_MODE[nr], reg);
2003 nct6775_write_value(data, data->REG_TARGET[nr],
2004 data->target_speed[nr] & 0xff);
2005 if (data->REG_TOLERANCE_H) {
2006 reg = (data->target_speed[nr] >> 8) & 0x0f;
2007 reg |= (data->target_speed_tolerance[nr] & 0x38) << 1;
2008 nct6775_write_value(data,
2009 data->REG_TOLERANCE_H[nr],
2010 reg);
2011 }
2012 break;
2013 case thermal_cruise:
2014 nct6775_write_value(data, data->REG_TARGET[nr],
2015 data->target_temp[nr]);
2016 /* intentional */
2017 default:
2018 reg = nct6775_read_value(data, data->REG_FAN_MODE[nr]);
2019 reg = (reg & ~data->tolerance_mask) |
2020 data->temp_tolerance[0][nr];
2021 nct6775_write_value(data, data->REG_FAN_MODE[nr], reg);
2022 break;
2023 }
2024}
2025
Guenter Roeck77eb5b32012-12-04 08:30:54 -08002026static ssize_t
2027show_pwm_enable(struct device *dev, struct device_attribute *attr, char *buf)
2028{
2029 struct nct6775_data *data = nct6775_update_device(dev);
2030 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2031
2032 return sprintf(buf, "%d\n", data->pwm_enable[sattr->index]);
2033}
2034
2035static ssize_t
2036store_pwm_enable(struct device *dev, struct device_attribute *attr,
2037 const char *buf, size_t count)
2038{
2039 struct nct6775_data *data = dev_get_drvdata(dev);
2040 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2041 int nr = sattr->index;
2042 unsigned long val;
2043 int err;
2044 u16 reg;
2045
2046 err = kstrtoul(buf, 10, &val);
2047 if (err < 0)
2048 return err;
2049
2050 if (val > sf4)
2051 return -EINVAL;
2052
2053 if (val == sf3 && data->kind != nct6775)
2054 return -EINVAL;
2055
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002056 if (val == sf4 && check_trip_points(data, nr)) {
2057 dev_err(dev, "Inconsistent trip points, not switching to SmartFan IV mode\n");
2058 dev_err(dev, "Adjust trip points and try again\n");
2059 return -EINVAL;
2060 }
2061
Guenter Roeck77eb5b32012-12-04 08:30:54 -08002062 mutex_lock(&data->update_lock);
2063 data->pwm_enable[nr] = val;
2064 if (val == off) {
2065 /*
2066 * turn off pwm control: select manual mode, set pwm to maximum
2067 */
2068 data->pwm[0][nr] = 255;
2069 nct6775_write_value(data, data->REG_PWM[0][nr], 255);
2070 }
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002071 pwm_update_registers(data, nr);
Guenter Roeck77eb5b32012-12-04 08:30:54 -08002072 reg = nct6775_read_value(data, data->REG_FAN_MODE[nr]);
2073 reg &= 0x0f;
2074 reg |= pwm_enable_to_reg(val) << 4;
2075 nct6775_write_value(data, data->REG_FAN_MODE[nr], reg);
2076 mutex_unlock(&data->update_lock);
2077 return count;
2078}
2079
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002080static ssize_t
2081show_pwm_temp_sel(struct device *dev, struct device_attribute *attr, char *buf)
2082{
2083 struct nct6775_data *data = nct6775_update_device(dev);
2084 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2085 int i, src, sel = 0;
2086
2087 src = data->pwm_temp_sel[sattr->index];
2088
2089 for (i = 0; i < NUM_TEMP; i++) {
2090 if (!(data->have_temp & (1 << i)))
2091 continue;
2092 if (src == data->temp_src[i]) {
2093 sel = i + 1;
2094 break;
2095 }
2096 }
2097
2098 return sprintf(buf, "%d\n", sel);
2099}
2100
2101static ssize_t
2102store_pwm_temp_sel(struct device *dev, struct device_attribute *attr,
2103 const char *buf, size_t count)
2104{
2105 struct nct6775_data *data = nct6775_update_device(dev);
2106 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2107 int nr = sattr->index;
2108 unsigned long val;
2109 int err, reg, src;
2110
2111 err = kstrtoul(buf, 10, &val);
2112 if (err < 0)
2113 return err;
2114 if (val == 0 || val > NUM_TEMP)
2115 return -EINVAL;
2116 if (!(data->have_temp & (1 << (val - 1))) || !data->temp_src[val - 1])
2117 return -EINVAL;
2118
2119 mutex_lock(&data->update_lock);
2120 src = data->temp_src[val - 1];
2121 data->pwm_temp_sel[nr] = src;
2122 reg = nct6775_read_value(data, data->REG_TEMP_SEL[nr]);
2123 reg &= 0xe0;
2124 reg |= src;
2125 nct6775_write_value(data, data->REG_TEMP_SEL[nr], reg);
2126 mutex_unlock(&data->update_lock);
2127
2128 return count;
2129}
2130
2131static ssize_t
2132show_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 Roeck77eb5b32012-12-04 08:30:54 -08002309static SENSOR_DEVICE_ATTR_2(pwm1, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 0, 0);
2310static SENSOR_DEVICE_ATTR_2(pwm2, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 1, 0);
2311static SENSOR_DEVICE_ATTR_2(pwm3, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 2, 0);
2312static SENSOR_DEVICE_ATTR_2(pwm4, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 3, 0);
2313static SENSOR_DEVICE_ATTR_2(pwm5, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 4, 0);
2314
2315static SENSOR_DEVICE_ATTR(pwm1_mode, S_IWUSR | S_IRUGO, show_pwm_mode,
2316 store_pwm_mode, 0);
2317static SENSOR_DEVICE_ATTR(pwm2_mode, S_IWUSR | S_IRUGO, show_pwm_mode,
2318 store_pwm_mode, 1);
2319static SENSOR_DEVICE_ATTR(pwm3_mode, S_IWUSR | S_IRUGO, show_pwm_mode,
2320 store_pwm_mode, 2);
2321static SENSOR_DEVICE_ATTR(pwm4_mode, S_IWUSR | S_IRUGO, show_pwm_mode,
2322 store_pwm_mode, 3);
2323static SENSOR_DEVICE_ATTR(pwm5_mode, S_IWUSR | S_IRUGO, show_pwm_mode,
2324 store_pwm_mode, 4);
2325
2326static SENSOR_DEVICE_ATTR(pwm1_enable, S_IWUSR | S_IRUGO, show_pwm_enable,
2327 store_pwm_enable, 0);
2328static SENSOR_DEVICE_ATTR(pwm2_enable, S_IWUSR | S_IRUGO, show_pwm_enable,
2329 store_pwm_enable, 1);
2330static SENSOR_DEVICE_ATTR(pwm3_enable, S_IWUSR | S_IRUGO, show_pwm_enable,
2331 store_pwm_enable, 2);
2332static SENSOR_DEVICE_ATTR(pwm4_enable, S_IWUSR | S_IRUGO, show_pwm_enable,
2333 store_pwm_enable, 3);
2334static SENSOR_DEVICE_ATTR(pwm5_enable, S_IWUSR | S_IRUGO, show_pwm_enable,
2335 store_pwm_enable, 4);
2336
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002337static SENSOR_DEVICE_ATTR(pwm1_temp_sel, S_IWUSR | S_IRUGO,
2338 show_pwm_temp_sel, store_pwm_temp_sel, 0);
2339static SENSOR_DEVICE_ATTR(pwm2_temp_sel, S_IWUSR | S_IRUGO,
2340 show_pwm_temp_sel, store_pwm_temp_sel, 1);
2341static SENSOR_DEVICE_ATTR(pwm3_temp_sel, S_IWUSR | S_IRUGO,
2342 show_pwm_temp_sel, store_pwm_temp_sel, 2);
2343static SENSOR_DEVICE_ATTR(pwm4_temp_sel, S_IWUSR | S_IRUGO,
2344 show_pwm_temp_sel, store_pwm_temp_sel, 3);
2345static SENSOR_DEVICE_ATTR(pwm5_temp_sel, S_IWUSR | S_IRUGO,
2346 show_pwm_temp_sel, store_pwm_temp_sel, 4);
2347
2348static SENSOR_DEVICE_ATTR(pwm1_target_temp, S_IWUSR | S_IRUGO, show_target_temp,
2349 store_target_temp, 0);
2350static SENSOR_DEVICE_ATTR(pwm2_target_temp, S_IWUSR | S_IRUGO, show_target_temp,
2351 store_target_temp, 1);
2352static SENSOR_DEVICE_ATTR(pwm3_target_temp, S_IWUSR | S_IRUGO, show_target_temp,
2353 store_target_temp, 2);
2354static SENSOR_DEVICE_ATTR(pwm4_target_temp, S_IWUSR | S_IRUGO, show_target_temp,
2355 store_target_temp, 3);
2356static SENSOR_DEVICE_ATTR(pwm5_target_temp, S_IWUSR | S_IRUGO, show_target_temp,
2357 store_target_temp, 4);
2358
2359static SENSOR_DEVICE_ATTR(fan1_target, S_IWUSR | S_IRUGO, show_target_speed,
2360 store_target_speed, 0);
2361static SENSOR_DEVICE_ATTR(fan2_target, S_IWUSR | S_IRUGO, show_target_speed,
2362 store_target_speed, 1);
2363static SENSOR_DEVICE_ATTR(fan3_target, S_IWUSR | S_IRUGO, show_target_speed,
2364 store_target_speed, 2);
2365static SENSOR_DEVICE_ATTR(fan4_target, S_IWUSR | S_IRUGO, show_target_speed,
2366 store_target_speed, 3);
2367static SENSOR_DEVICE_ATTR(fan5_target, S_IWUSR | S_IRUGO, show_target_speed,
2368 store_target_speed, 4);
2369
2370static SENSOR_DEVICE_ATTR(fan1_tolerance, S_IWUSR | S_IRUGO,
2371 show_speed_tolerance, store_speed_tolerance, 0);
2372static SENSOR_DEVICE_ATTR(fan2_tolerance, S_IWUSR | S_IRUGO,
2373 show_speed_tolerance, store_speed_tolerance, 1);
2374static SENSOR_DEVICE_ATTR(fan3_tolerance, S_IWUSR | S_IRUGO,
2375 show_speed_tolerance, store_speed_tolerance, 2);
2376static SENSOR_DEVICE_ATTR(fan4_tolerance, S_IWUSR | S_IRUGO,
2377 show_speed_tolerance, store_speed_tolerance, 3);
2378static SENSOR_DEVICE_ATTR(fan5_tolerance, S_IWUSR | S_IRUGO,
2379 show_speed_tolerance, store_speed_tolerance, 4);
2380
2381/* Smart Fan registers */
2382
2383static ssize_t
2384show_fan_time(struct device *dev, struct device_attribute *attr, char *buf)
2385{
2386 struct nct6775_data *data = nct6775_update_device(dev);
2387 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2388 int nr = sattr->nr;
2389 int index = sattr->index;
2390
2391 return sprintf(buf, "%d\n",
2392 step_time_from_reg(data->fan_time[index][nr],
2393 data->pwm_mode[nr]));
2394}
2395
2396static ssize_t
2397store_fan_time(struct device *dev, struct device_attribute *attr,
2398 const char *buf, size_t count)
2399{
2400 struct nct6775_data *data = dev_get_drvdata(dev);
2401 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2402 int nr = sattr->nr;
2403 int index = sattr->index;
2404 unsigned long val;
2405 int err;
2406
2407 err = kstrtoul(buf, 10, &val);
2408 if (err < 0)
2409 return err;
2410
2411 val = step_time_to_reg(val, data->pwm_mode[nr]);
2412 mutex_lock(&data->update_lock);
2413 data->fan_time[index][nr] = val;
2414 nct6775_write_value(data, data->REG_FAN_TIME[index][nr], val);
2415 mutex_unlock(&data->update_lock);
2416 return count;
2417}
2418
Guenter Roeck77eb5b32012-12-04 08:30:54 -08002419static ssize_t
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07002420show_name(struct device *dev, struct device_attribute *attr, char *buf)
2421{
2422 struct nct6775_data *data = dev_get_drvdata(dev);
2423
2424 return sprintf(buf, "%s\n", data->name);
2425}
2426
2427static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
2428
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002429static SENSOR_DEVICE_ATTR_2(pwm1_stop_time, S_IWUSR | S_IRUGO, show_fan_time,
2430 store_fan_time, 0, 0);
2431static SENSOR_DEVICE_ATTR_2(pwm2_stop_time, S_IWUSR | S_IRUGO, show_fan_time,
2432 store_fan_time, 1, 0);
2433static SENSOR_DEVICE_ATTR_2(pwm3_stop_time, S_IWUSR | S_IRUGO, show_fan_time,
2434 store_fan_time, 2, 0);
2435static SENSOR_DEVICE_ATTR_2(pwm4_stop_time, S_IWUSR | S_IRUGO, show_fan_time,
2436 store_fan_time, 3, 0);
2437static SENSOR_DEVICE_ATTR_2(pwm5_stop_time, S_IWUSR | S_IRUGO, show_fan_time,
2438 store_fan_time, 4, 0);
2439
2440static SENSOR_DEVICE_ATTR_2(pwm1_step_up_time, S_IWUSR | S_IRUGO, show_fan_time,
2441 store_fan_time, 0, 1);
2442static SENSOR_DEVICE_ATTR_2(pwm2_step_up_time, S_IWUSR | S_IRUGO, show_fan_time,
2443 store_fan_time, 1, 1);
2444static SENSOR_DEVICE_ATTR_2(pwm3_step_up_time, S_IWUSR | S_IRUGO, show_fan_time,
2445 store_fan_time, 2, 1);
2446static SENSOR_DEVICE_ATTR_2(pwm4_step_up_time, S_IWUSR | S_IRUGO, show_fan_time,
2447 store_fan_time, 3, 1);
2448static SENSOR_DEVICE_ATTR_2(pwm5_step_up_time, S_IWUSR | S_IRUGO, show_fan_time,
2449 store_fan_time, 4, 1);
2450
2451static SENSOR_DEVICE_ATTR_2(pwm1_step_down_time, S_IWUSR | S_IRUGO,
2452 show_fan_time, store_fan_time, 0, 2);
2453static SENSOR_DEVICE_ATTR_2(pwm2_step_down_time, S_IWUSR | S_IRUGO,
2454 show_fan_time, store_fan_time, 1, 2);
2455static SENSOR_DEVICE_ATTR_2(pwm3_step_down_time, S_IWUSR | S_IRUGO,
2456 show_fan_time, store_fan_time, 2, 2);
2457static SENSOR_DEVICE_ATTR_2(pwm4_step_down_time, S_IWUSR | S_IRUGO,
2458 show_fan_time, store_fan_time, 3, 2);
2459static SENSOR_DEVICE_ATTR_2(pwm5_step_down_time, S_IWUSR | S_IRUGO,
2460 show_fan_time, store_fan_time, 4, 2);
2461
2462static SENSOR_DEVICE_ATTR_2(pwm1_start, S_IWUSR | S_IRUGO, show_pwm,
2463 store_pwm, 0, 1);
2464static SENSOR_DEVICE_ATTR_2(pwm2_start, S_IWUSR | S_IRUGO, show_pwm,
2465 store_pwm, 1, 1);
2466static SENSOR_DEVICE_ATTR_2(pwm3_start, S_IWUSR | S_IRUGO, show_pwm,
2467 store_pwm, 2, 1);
2468static SENSOR_DEVICE_ATTR_2(pwm4_start, S_IWUSR | S_IRUGO, show_pwm,
2469 store_pwm, 3, 1);
2470static SENSOR_DEVICE_ATTR_2(pwm5_start, S_IWUSR | S_IRUGO, show_pwm,
2471 store_pwm, 4, 1);
2472
2473static SENSOR_DEVICE_ATTR_2(pwm1_floor, S_IWUSR | S_IRUGO, show_pwm,
2474 store_pwm, 0, 2);
2475static SENSOR_DEVICE_ATTR_2(pwm2_floor, S_IWUSR | S_IRUGO, show_pwm,
2476 store_pwm, 1, 2);
2477static SENSOR_DEVICE_ATTR_2(pwm3_floor, S_IWUSR | S_IRUGO, show_pwm,
2478 store_pwm, 2, 2);
2479static SENSOR_DEVICE_ATTR_2(pwm4_floor, S_IWUSR | S_IRUGO, show_pwm,
2480 store_pwm, 3, 2);
2481static SENSOR_DEVICE_ATTR_2(pwm5_floor, S_IWUSR | S_IRUGO, show_pwm,
2482 store_pwm, 4, 2);
2483
2484static SENSOR_DEVICE_ATTR_2(pwm1_temp_tolerance, S_IWUSR | S_IRUGO,
2485 show_temp_tolerance, store_temp_tolerance, 0, 0);
2486static SENSOR_DEVICE_ATTR_2(pwm2_temp_tolerance, S_IWUSR | S_IRUGO,
2487 show_temp_tolerance, store_temp_tolerance, 1, 0);
2488static SENSOR_DEVICE_ATTR_2(pwm3_temp_tolerance, S_IWUSR | S_IRUGO,
2489 show_temp_tolerance, store_temp_tolerance, 2, 0);
2490static SENSOR_DEVICE_ATTR_2(pwm4_temp_tolerance, S_IWUSR | S_IRUGO,
2491 show_temp_tolerance, store_temp_tolerance, 3, 0);
2492static SENSOR_DEVICE_ATTR_2(pwm5_temp_tolerance, S_IWUSR | S_IRUGO,
2493 show_temp_tolerance, store_temp_tolerance, 4, 0);
2494
2495static SENSOR_DEVICE_ATTR_2(pwm1_crit_temp_tolerance, S_IWUSR | S_IRUGO,
2496 show_temp_tolerance, store_temp_tolerance, 0, 1);
2497static SENSOR_DEVICE_ATTR_2(pwm2_crit_temp_tolerance, S_IWUSR | S_IRUGO,
2498 show_temp_tolerance, store_temp_tolerance, 1, 1);
2499static SENSOR_DEVICE_ATTR_2(pwm3_crit_temp_tolerance, S_IWUSR | S_IRUGO,
2500 show_temp_tolerance, store_temp_tolerance, 2, 1);
2501static SENSOR_DEVICE_ATTR_2(pwm4_crit_temp_tolerance, S_IWUSR | S_IRUGO,
2502 show_temp_tolerance, store_temp_tolerance, 3, 1);
2503static SENSOR_DEVICE_ATTR_2(pwm5_crit_temp_tolerance, S_IWUSR | S_IRUGO,
2504 show_temp_tolerance, store_temp_tolerance, 4, 1);
2505
2506/* pwm_max is not supported on all chips */
2507static struct sensor_device_attribute_2 sda_pwm_max[] = {
2508 SENSOR_ATTR_2(pwm1_max, S_IWUSR | S_IRUGO, show_pwm, store_pwm,
2509 0, 3),
2510 SENSOR_ATTR_2(pwm2_max, S_IWUSR | S_IRUGO, show_pwm, store_pwm,
2511 1, 3),
2512 SENSOR_ATTR_2(pwm3_max, S_IWUSR | S_IRUGO, show_pwm, store_pwm,
2513 2, 3),
2514 SENSOR_ATTR_2(pwm4_max, S_IWUSR | S_IRUGO, show_pwm, store_pwm,
2515 3, 3),
2516 SENSOR_ATTR_2(pwm5_max, S_IWUSR | S_IRUGO, show_pwm, store_pwm,
2517 4, 3),
2518};
2519
2520/* pwm_step is not supported on all chips */
2521static struct sensor_device_attribute_2 sda_pwm_step[] = {
2522 SENSOR_ATTR_2(pwm1_step, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 0, 4),
2523 SENSOR_ATTR_2(pwm2_step, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 1, 4),
2524 SENSOR_ATTR_2(pwm3_step, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 2, 4),
2525 SENSOR_ATTR_2(pwm4_step, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 3, 4),
2526 SENSOR_ATTR_2(pwm5_step, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 4, 4),
2527};
2528
2529static struct attribute *nct6775_attributes_pwm[5][15] = {
Guenter Roeck77eb5b32012-12-04 08:30:54 -08002530 {
2531 &sensor_dev_attr_pwm1.dev_attr.attr,
2532 &sensor_dev_attr_pwm1_mode.dev_attr.attr,
2533 &sensor_dev_attr_pwm1_enable.dev_attr.attr,
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002534 &sensor_dev_attr_pwm1_temp_sel.dev_attr.attr,
2535 &sensor_dev_attr_pwm1_temp_tolerance.dev_attr.attr,
2536 &sensor_dev_attr_pwm1_crit_temp_tolerance.dev_attr.attr,
2537 &sensor_dev_attr_pwm1_target_temp.dev_attr.attr,
2538 &sensor_dev_attr_fan1_target.dev_attr.attr,
2539 &sensor_dev_attr_fan1_tolerance.dev_attr.attr,
2540 &sensor_dev_attr_pwm1_stop_time.dev_attr.attr,
2541 &sensor_dev_attr_pwm1_step_up_time.dev_attr.attr,
2542 &sensor_dev_attr_pwm1_step_down_time.dev_attr.attr,
2543 &sensor_dev_attr_pwm1_start.dev_attr.attr,
2544 &sensor_dev_attr_pwm1_floor.dev_attr.attr,
Guenter Roeck77eb5b32012-12-04 08:30:54 -08002545 NULL
2546 },
2547 {
2548 &sensor_dev_attr_pwm2.dev_attr.attr,
2549 &sensor_dev_attr_pwm2_mode.dev_attr.attr,
2550 &sensor_dev_attr_pwm2_enable.dev_attr.attr,
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002551 &sensor_dev_attr_pwm2_temp_sel.dev_attr.attr,
2552 &sensor_dev_attr_pwm2_temp_tolerance.dev_attr.attr,
2553 &sensor_dev_attr_pwm2_crit_temp_tolerance.dev_attr.attr,
2554 &sensor_dev_attr_pwm2_target_temp.dev_attr.attr,
2555 &sensor_dev_attr_fan2_target.dev_attr.attr,
2556 &sensor_dev_attr_fan2_tolerance.dev_attr.attr,
2557 &sensor_dev_attr_pwm2_stop_time.dev_attr.attr,
2558 &sensor_dev_attr_pwm2_step_up_time.dev_attr.attr,
2559 &sensor_dev_attr_pwm2_step_down_time.dev_attr.attr,
2560 &sensor_dev_attr_pwm2_start.dev_attr.attr,
2561 &sensor_dev_attr_pwm2_floor.dev_attr.attr,
Guenter Roeck77eb5b32012-12-04 08:30:54 -08002562 NULL
2563 },
2564 {
2565 &sensor_dev_attr_pwm3.dev_attr.attr,
2566 &sensor_dev_attr_pwm3_mode.dev_attr.attr,
2567 &sensor_dev_attr_pwm3_enable.dev_attr.attr,
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002568 &sensor_dev_attr_pwm3_temp_sel.dev_attr.attr,
2569 &sensor_dev_attr_pwm3_temp_tolerance.dev_attr.attr,
2570 &sensor_dev_attr_pwm3_crit_temp_tolerance.dev_attr.attr,
2571 &sensor_dev_attr_pwm3_target_temp.dev_attr.attr,
2572 &sensor_dev_attr_fan3_target.dev_attr.attr,
2573 &sensor_dev_attr_fan3_tolerance.dev_attr.attr,
2574 &sensor_dev_attr_pwm3_stop_time.dev_attr.attr,
2575 &sensor_dev_attr_pwm3_step_up_time.dev_attr.attr,
2576 &sensor_dev_attr_pwm3_step_down_time.dev_attr.attr,
2577 &sensor_dev_attr_pwm3_start.dev_attr.attr,
2578 &sensor_dev_attr_pwm3_floor.dev_attr.attr,
Guenter Roeck77eb5b32012-12-04 08:30:54 -08002579 NULL
2580 },
2581 {
2582 &sensor_dev_attr_pwm4.dev_attr.attr,
2583 &sensor_dev_attr_pwm4_mode.dev_attr.attr,
2584 &sensor_dev_attr_pwm4_enable.dev_attr.attr,
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002585 &sensor_dev_attr_pwm4_temp_sel.dev_attr.attr,
2586 &sensor_dev_attr_pwm4_temp_tolerance.dev_attr.attr,
2587 &sensor_dev_attr_pwm4_crit_temp_tolerance.dev_attr.attr,
2588 &sensor_dev_attr_pwm4_target_temp.dev_attr.attr,
2589 &sensor_dev_attr_fan4_target.dev_attr.attr,
2590 &sensor_dev_attr_fan4_tolerance.dev_attr.attr,
2591 &sensor_dev_attr_pwm4_stop_time.dev_attr.attr,
2592 &sensor_dev_attr_pwm4_step_up_time.dev_attr.attr,
2593 &sensor_dev_attr_pwm4_step_down_time.dev_attr.attr,
2594 &sensor_dev_attr_pwm4_start.dev_attr.attr,
2595 &sensor_dev_attr_pwm4_floor.dev_attr.attr,
Guenter Roeck77eb5b32012-12-04 08:30:54 -08002596 NULL
2597 },
2598 {
2599 &sensor_dev_attr_pwm5.dev_attr.attr,
2600 &sensor_dev_attr_pwm5_mode.dev_attr.attr,
2601 &sensor_dev_attr_pwm5_enable.dev_attr.attr,
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002602 &sensor_dev_attr_pwm5_temp_sel.dev_attr.attr,
2603 &sensor_dev_attr_pwm5_temp_tolerance.dev_attr.attr,
2604 &sensor_dev_attr_pwm5_crit_temp_tolerance.dev_attr.attr,
2605 &sensor_dev_attr_pwm5_target_temp.dev_attr.attr,
2606 &sensor_dev_attr_fan5_target.dev_attr.attr,
2607 &sensor_dev_attr_fan5_tolerance.dev_attr.attr,
2608 &sensor_dev_attr_pwm5_stop_time.dev_attr.attr,
2609 &sensor_dev_attr_pwm5_step_up_time.dev_attr.attr,
2610 &sensor_dev_attr_pwm5_step_down_time.dev_attr.attr,
2611 &sensor_dev_attr_pwm5_start.dev_attr.attr,
2612 &sensor_dev_attr_pwm5_floor.dev_attr.attr,
Guenter Roeck77eb5b32012-12-04 08:30:54 -08002613 NULL
2614 },
2615};
2616
2617static const struct attribute_group nct6775_group_pwm[5] = {
2618 { .attrs = nct6775_attributes_pwm[0] },
2619 { .attrs = nct6775_attributes_pwm[1] },
2620 { .attrs = nct6775_attributes_pwm[2] },
2621 { .attrs = nct6775_attributes_pwm[3] },
2622 { .attrs = nct6775_attributes_pwm[4] },
2623};
2624
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07002625static ssize_t
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002626show_auto_pwm(struct device *dev, struct device_attribute *attr, char *buf)
2627{
2628 struct nct6775_data *data = nct6775_update_device(dev);
2629 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2630
2631 return sprintf(buf, "%d\n", data->auto_pwm[sattr->nr][sattr->index]);
2632}
2633
2634static ssize_t
2635store_auto_pwm(struct device *dev, struct device_attribute *attr,
2636 const char *buf, size_t count)
2637{
2638 struct nct6775_data *data = dev_get_drvdata(dev);
2639 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2640 int nr = sattr->nr;
2641 int point = sattr->index;
2642 unsigned long val;
2643 int err;
2644 u8 reg;
2645
2646 err = kstrtoul(buf, 10, &val);
2647 if (err < 0)
2648 return err;
2649 if (val > 255)
2650 return -EINVAL;
2651
2652 if (point == data->auto_pwm_num) {
2653 if (data->kind != nct6775 && !val)
2654 return -EINVAL;
2655 if (data->kind != nct6779 && val)
2656 val = 0xff;
2657 }
2658
2659 mutex_lock(&data->update_lock);
2660 data->auto_pwm[nr][point] = val;
2661 if (point < data->auto_pwm_num) {
2662 nct6775_write_value(data,
2663 NCT6775_AUTO_PWM(data, nr, point),
2664 data->auto_pwm[nr][point]);
2665 } else {
2666 switch (data->kind) {
2667 case nct6775:
2668 /* disable if needed (pwm == 0) */
2669 reg = nct6775_read_value(data,
2670 NCT6775_REG_CRITICAL_ENAB[nr]);
2671 if (val)
2672 reg |= 0x02;
2673 else
2674 reg &= ~0x02;
2675 nct6775_write_value(data, NCT6775_REG_CRITICAL_ENAB[nr],
2676 reg);
2677 break;
2678 case nct6776:
2679 break; /* always enabled, nothing to do */
2680 case nct6779:
2681 nct6775_write_value(data, NCT6779_REG_CRITICAL_PWM[nr],
2682 val);
2683 reg = nct6775_read_value(data,
2684 NCT6779_REG_CRITICAL_PWM_ENABLE[nr]);
2685 if (val == 255)
2686 reg &= ~0x01;
2687 else
2688 reg |= 0x01;
2689 nct6775_write_value(data,
2690 NCT6779_REG_CRITICAL_PWM_ENABLE[nr],
2691 reg);
2692 break;
2693 }
2694 }
2695 mutex_unlock(&data->update_lock);
2696 return count;
2697}
2698
2699static ssize_t
2700show_auto_temp(struct device *dev, struct device_attribute *attr, char *buf)
2701{
2702 struct nct6775_data *data = nct6775_update_device(dev);
2703 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2704 int nr = sattr->nr;
2705 int point = sattr->index;
2706
2707 /*
2708 * We don't know for sure if the temperature is signed or unsigned.
2709 * Assume it is unsigned.
2710 */
2711 return sprintf(buf, "%d\n", data->auto_temp[nr][point] * 1000);
2712}
2713
2714static ssize_t
2715store_auto_temp(struct device *dev, struct device_attribute *attr,
2716 const char *buf, size_t count)
2717{
2718 struct nct6775_data *data = dev_get_drvdata(dev);
2719 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2720 int nr = sattr->nr;
2721 int point = sattr->index;
2722 unsigned long val;
2723 int err;
2724
2725 err = kstrtoul(buf, 10, &val);
2726 if (err)
2727 return err;
2728 if (val > 255000)
2729 return -EINVAL;
2730
2731 mutex_lock(&data->update_lock);
2732 data->auto_temp[nr][point] = DIV_ROUND_CLOSEST(val, 1000);
2733 if (point < data->auto_pwm_num) {
2734 nct6775_write_value(data,
2735 NCT6775_AUTO_TEMP(data, nr, point),
2736 data->auto_temp[nr][point]);
2737 } else {
2738 nct6775_write_value(data, data->REG_CRITICAL_TEMP[nr],
2739 data->auto_temp[nr][point]);
2740 }
2741 mutex_unlock(&data->update_lock);
2742 return count;
2743}
2744
2745/*
2746 * The number of auto-point trip points is chip dependent.
2747 * Need to check support while generating/removing attribute files.
2748 */
2749static struct sensor_device_attribute_2 sda_auto_pwm_arrays[] = {
2750 SENSOR_ATTR_2(pwm1_auto_point1_pwm, S_IWUSR | S_IRUGO,
2751 show_auto_pwm, store_auto_pwm, 0, 0),
2752 SENSOR_ATTR_2(pwm1_auto_point1_temp, S_IWUSR | S_IRUGO,
2753 show_auto_temp, store_auto_temp, 0, 0),
2754 SENSOR_ATTR_2(pwm1_auto_point2_pwm, S_IWUSR | S_IRUGO,
2755 show_auto_pwm, store_auto_pwm, 0, 1),
2756 SENSOR_ATTR_2(pwm1_auto_point2_temp, S_IWUSR | S_IRUGO,
2757 show_auto_temp, store_auto_temp, 0, 1),
2758 SENSOR_ATTR_2(pwm1_auto_point3_pwm, S_IWUSR | S_IRUGO,
2759 show_auto_pwm, store_auto_pwm, 0, 2),
2760 SENSOR_ATTR_2(pwm1_auto_point3_temp, S_IWUSR | S_IRUGO,
2761 show_auto_temp, store_auto_temp, 0, 2),
2762 SENSOR_ATTR_2(pwm1_auto_point4_pwm, S_IWUSR | S_IRUGO,
2763 show_auto_pwm, store_auto_pwm, 0, 3),
2764 SENSOR_ATTR_2(pwm1_auto_point4_temp, S_IWUSR | S_IRUGO,
2765 show_auto_temp, store_auto_temp, 0, 3),
2766 SENSOR_ATTR_2(pwm1_auto_point5_pwm, S_IWUSR | S_IRUGO,
2767 show_auto_pwm, store_auto_pwm, 0, 4),
2768 SENSOR_ATTR_2(pwm1_auto_point5_temp, S_IWUSR | S_IRUGO,
2769 show_auto_temp, store_auto_temp, 0, 4),
2770 SENSOR_ATTR_2(pwm1_auto_point6_pwm, S_IWUSR | S_IRUGO,
2771 show_auto_pwm, store_auto_pwm, 0, 5),
2772 SENSOR_ATTR_2(pwm1_auto_point6_temp, S_IWUSR | S_IRUGO,
2773 show_auto_temp, store_auto_temp, 0, 5),
2774 SENSOR_ATTR_2(pwm1_auto_point7_pwm, S_IWUSR | S_IRUGO,
2775 show_auto_pwm, store_auto_pwm, 0, 6),
2776 SENSOR_ATTR_2(pwm1_auto_point7_temp, S_IWUSR | S_IRUGO,
2777 show_auto_temp, store_auto_temp, 0, 6),
2778
2779 SENSOR_ATTR_2(pwm2_auto_point1_pwm, S_IWUSR | S_IRUGO,
2780 show_auto_pwm, store_auto_pwm, 1, 0),
2781 SENSOR_ATTR_2(pwm2_auto_point1_temp, S_IWUSR | S_IRUGO,
2782 show_auto_temp, store_auto_temp, 1, 0),
2783 SENSOR_ATTR_2(pwm2_auto_point2_pwm, S_IWUSR | S_IRUGO,
2784 show_auto_pwm, store_auto_pwm, 1, 1),
2785 SENSOR_ATTR_2(pwm2_auto_point2_temp, S_IWUSR | S_IRUGO,
2786 show_auto_temp, store_auto_temp, 1, 1),
2787 SENSOR_ATTR_2(pwm2_auto_point3_pwm, S_IWUSR | S_IRUGO,
2788 show_auto_pwm, store_auto_pwm, 1, 2),
2789 SENSOR_ATTR_2(pwm2_auto_point3_temp, S_IWUSR | S_IRUGO,
2790 show_auto_temp, store_auto_temp, 1, 2),
2791 SENSOR_ATTR_2(pwm2_auto_point4_pwm, S_IWUSR | S_IRUGO,
2792 show_auto_pwm, store_auto_pwm, 1, 3),
2793 SENSOR_ATTR_2(pwm2_auto_point4_temp, S_IWUSR | S_IRUGO,
2794 show_auto_temp, store_auto_temp, 1, 3),
2795 SENSOR_ATTR_2(pwm2_auto_point5_pwm, S_IWUSR | S_IRUGO,
2796 show_auto_pwm, store_auto_pwm, 1, 4),
2797 SENSOR_ATTR_2(pwm2_auto_point5_temp, S_IWUSR | S_IRUGO,
2798 show_auto_temp, store_auto_temp, 1, 4),
2799 SENSOR_ATTR_2(pwm2_auto_point6_pwm, S_IWUSR | S_IRUGO,
2800 show_auto_pwm, store_auto_pwm, 1, 5),
2801 SENSOR_ATTR_2(pwm2_auto_point6_temp, S_IWUSR | S_IRUGO,
2802 show_auto_temp, store_auto_temp, 1, 5),
2803 SENSOR_ATTR_2(pwm2_auto_point7_pwm, S_IWUSR | S_IRUGO,
2804 show_auto_pwm, store_auto_pwm, 1, 6),
2805 SENSOR_ATTR_2(pwm2_auto_point7_temp, S_IWUSR | S_IRUGO,
2806 show_auto_temp, store_auto_temp, 1, 6),
2807
2808 SENSOR_ATTR_2(pwm3_auto_point1_pwm, S_IWUSR | S_IRUGO,
2809 show_auto_pwm, store_auto_pwm, 2, 0),
2810 SENSOR_ATTR_2(pwm3_auto_point1_temp, S_IWUSR | S_IRUGO,
2811 show_auto_temp, store_auto_temp, 2, 0),
2812 SENSOR_ATTR_2(pwm3_auto_point2_pwm, S_IWUSR | S_IRUGO,
2813 show_auto_pwm, store_auto_pwm, 2, 1),
2814 SENSOR_ATTR_2(pwm3_auto_point2_temp, S_IWUSR | S_IRUGO,
2815 show_auto_temp, store_auto_temp, 2, 1),
2816 SENSOR_ATTR_2(pwm3_auto_point3_pwm, S_IWUSR | S_IRUGO,
2817 show_auto_pwm, store_auto_pwm, 2, 2),
2818 SENSOR_ATTR_2(pwm3_auto_point3_temp, S_IWUSR | S_IRUGO,
2819 show_auto_temp, store_auto_temp, 2, 2),
2820 SENSOR_ATTR_2(pwm3_auto_point4_pwm, S_IWUSR | S_IRUGO,
2821 show_auto_pwm, store_auto_pwm, 2, 3),
2822 SENSOR_ATTR_2(pwm3_auto_point4_temp, S_IWUSR | S_IRUGO,
2823 show_auto_temp, store_auto_temp, 2, 3),
2824 SENSOR_ATTR_2(pwm3_auto_point5_pwm, S_IWUSR | S_IRUGO,
2825 show_auto_pwm, store_auto_pwm, 2, 4),
2826 SENSOR_ATTR_2(pwm3_auto_point5_temp, S_IWUSR | S_IRUGO,
2827 show_auto_temp, store_auto_temp, 2, 4),
2828 SENSOR_ATTR_2(pwm3_auto_point6_pwm, S_IWUSR | S_IRUGO,
2829 show_auto_pwm, store_auto_pwm, 2, 5),
2830 SENSOR_ATTR_2(pwm3_auto_point6_temp, S_IWUSR | S_IRUGO,
2831 show_auto_temp, store_auto_temp, 2, 5),
2832 SENSOR_ATTR_2(pwm3_auto_point7_pwm, S_IWUSR | S_IRUGO,
2833 show_auto_pwm, store_auto_pwm, 2, 6),
2834 SENSOR_ATTR_2(pwm3_auto_point7_temp, S_IWUSR | S_IRUGO,
2835 show_auto_temp, store_auto_temp, 2, 6),
2836
2837 SENSOR_ATTR_2(pwm4_auto_point1_pwm, S_IWUSR | S_IRUGO,
2838 show_auto_pwm, store_auto_pwm, 3, 0),
2839 SENSOR_ATTR_2(pwm4_auto_point1_temp, S_IWUSR | S_IRUGO,
2840 show_auto_temp, store_auto_temp, 3, 0),
2841 SENSOR_ATTR_2(pwm4_auto_point2_pwm, S_IWUSR | S_IRUGO,
2842 show_auto_pwm, store_auto_pwm, 3, 1),
2843 SENSOR_ATTR_2(pwm4_auto_point2_temp, S_IWUSR | S_IRUGO,
2844 show_auto_temp, store_auto_temp, 3, 1),
2845 SENSOR_ATTR_2(pwm4_auto_point3_pwm, S_IWUSR | S_IRUGO,
2846 show_auto_pwm, store_auto_pwm, 3, 2),
2847 SENSOR_ATTR_2(pwm4_auto_point3_temp, S_IWUSR | S_IRUGO,
2848 show_auto_temp, store_auto_temp, 3, 2),
2849 SENSOR_ATTR_2(pwm4_auto_point4_pwm, S_IWUSR | S_IRUGO,
2850 show_auto_pwm, store_auto_pwm, 3, 3),
2851 SENSOR_ATTR_2(pwm4_auto_point4_temp, S_IWUSR | S_IRUGO,
2852 show_auto_temp, store_auto_temp, 3, 3),
2853 SENSOR_ATTR_2(pwm4_auto_point5_pwm, S_IWUSR | S_IRUGO,
2854 show_auto_pwm, store_auto_pwm, 3, 4),
2855 SENSOR_ATTR_2(pwm4_auto_point5_temp, S_IWUSR | S_IRUGO,
2856 show_auto_temp, store_auto_temp, 3, 4),
2857 SENSOR_ATTR_2(pwm4_auto_point6_pwm, S_IWUSR | S_IRUGO,
2858 show_auto_pwm, store_auto_pwm, 3, 5),
2859 SENSOR_ATTR_2(pwm4_auto_point6_temp, S_IWUSR | S_IRUGO,
2860 show_auto_temp, store_auto_temp, 3, 5),
2861 SENSOR_ATTR_2(pwm4_auto_point7_pwm, S_IWUSR | S_IRUGO,
2862 show_auto_pwm, store_auto_pwm, 3, 6),
2863 SENSOR_ATTR_2(pwm4_auto_point7_temp, S_IWUSR | S_IRUGO,
2864 show_auto_temp, store_auto_temp, 3, 6),
2865
2866 SENSOR_ATTR_2(pwm5_auto_point1_pwm, S_IWUSR | S_IRUGO,
2867 show_auto_pwm, store_auto_pwm, 4, 0),
2868 SENSOR_ATTR_2(pwm5_auto_point1_temp, S_IWUSR | S_IRUGO,
2869 show_auto_temp, store_auto_temp, 4, 0),
2870 SENSOR_ATTR_2(pwm5_auto_point2_pwm, S_IWUSR | S_IRUGO,
2871 show_auto_pwm, store_auto_pwm, 4, 1),
2872 SENSOR_ATTR_2(pwm5_auto_point2_temp, S_IWUSR | S_IRUGO,
2873 show_auto_temp, store_auto_temp, 4, 1),
2874 SENSOR_ATTR_2(pwm5_auto_point3_pwm, S_IWUSR | S_IRUGO,
2875 show_auto_pwm, store_auto_pwm, 4, 2),
2876 SENSOR_ATTR_2(pwm5_auto_point3_temp, S_IWUSR | S_IRUGO,
2877 show_auto_temp, store_auto_temp, 4, 2),
2878 SENSOR_ATTR_2(pwm5_auto_point4_pwm, S_IWUSR | S_IRUGO,
2879 show_auto_pwm, store_auto_pwm, 4, 3),
2880 SENSOR_ATTR_2(pwm5_auto_point4_temp, S_IWUSR | S_IRUGO,
2881 show_auto_temp, store_auto_temp, 4, 3),
2882 SENSOR_ATTR_2(pwm5_auto_point5_pwm, S_IWUSR | S_IRUGO,
2883 show_auto_pwm, store_auto_pwm, 4, 4),
2884 SENSOR_ATTR_2(pwm5_auto_point5_temp, S_IWUSR | S_IRUGO,
2885 show_auto_temp, store_auto_temp, 4, 4),
2886 SENSOR_ATTR_2(pwm5_auto_point6_pwm, S_IWUSR | S_IRUGO,
2887 show_auto_pwm, store_auto_pwm, 4, 5),
2888 SENSOR_ATTR_2(pwm5_auto_point6_temp, S_IWUSR | S_IRUGO,
2889 show_auto_temp, store_auto_temp, 4, 5),
2890 SENSOR_ATTR_2(pwm5_auto_point7_pwm, S_IWUSR | S_IRUGO,
2891 show_auto_pwm, store_auto_pwm, 4, 6),
2892 SENSOR_ATTR_2(pwm5_auto_point7_temp, S_IWUSR | S_IRUGO,
2893 show_auto_temp, store_auto_temp, 4, 6),
2894};
2895
2896static ssize_t
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07002897show_vid(struct device *dev, struct device_attribute *attr, char *buf)
2898{
2899 struct nct6775_data *data = dev_get_drvdata(dev);
2900 return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm));
2901}
2902
2903static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL);
2904
Guenter Roecka6bd5872012-12-04 03:13:34 -08002905/* Case open detection */
2906
2907static ssize_t
2908clear_caseopen(struct device *dev, struct device_attribute *attr,
2909 const char *buf, size_t count)
2910{
2911 struct nct6775_data *data = dev_get_drvdata(dev);
2912 struct nct6775_sio_data *sio_data = dev->platform_data;
2913 int nr = to_sensor_dev_attr(attr)->index - INTRUSION_ALARM_BASE;
2914 unsigned long val;
2915 u8 reg;
2916 int ret;
2917
2918 if (kstrtoul(buf, 10, &val) || val != 0)
2919 return -EINVAL;
2920
2921 mutex_lock(&data->update_lock);
2922
2923 /*
2924 * Use CR registers to clear caseopen status.
2925 * The CR registers are the same for all chips, and not all chips
2926 * support clearing the caseopen status through "regular" registers.
2927 */
2928 ret = superio_enter(sio_data->sioreg);
2929 if (ret) {
2930 count = ret;
2931 goto error;
2932 }
2933
2934 superio_select(sio_data->sioreg, NCT6775_LD_ACPI);
2935 reg = superio_inb(sio_data->sioreg, NCT6775_REG_CR_CASEOPEN_CLR[nr]);
2936 reg |= NCT6775_CR_CASEOPEN_CLR_MASK[nr];
2937 superio_outb(sio_data->sioreg, NCT6775_REG_CR_CASEOPEN_CLR[nr], reg);
2938 reg &= ~NCT6775_CR_CASEOPEN_CLR_MASK[nr];
2939 superio_outb(sio_data->sioreg, NCT6775_REG_CR_CASEOPEN_CLR[nr], reg);
2940 superio_exit(sio_data->sioreg);
2941
2942 data->valid = false; /* Force cache refresh */
2943error:
2944 mutex_unlock(&data->update_lock);
2945 return count;
2946}
2947
2948static struct sensor_device_attribute sda_caseopen[] = {
2949 SENSOR_ATTR(intrusion0_alarm, S_IWUSR | S_IRUGO, show_alarm,
2950 clear_caseopen, INTRUSION_ALARM_BASE),
2951 SENSOR_ATTR(intrusion1_alarm, S_IWUSR | S_IRUGO, show_alarm,
2952 clear_caseopen, INTRUSION_ALARM_BASE + 1),
2953};
2954
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07002955/*
2956 * Driver and device management
2957 */
2958
2959static void nct6775_device_remove_files(struct device *dev)
2960{
2961 /*
2962 * some entries in the following arrays may not have been used in
2963 * device_create_file(), but device_remove_file() will ignore them
2964 */
2965 int i;
2966 struct nct6775_data *data = dev_get_drvdata(dev);
2967
Guenter Roeck77eb5b32012-12-04 08:30:54 -08002968 for (i = 0; i < data->pwm_num; i++)
2969 sysfs_remove_group(&dev->kobj, &nct6775_group_pwm[i]);
2970
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002971 for (i = 0; i < ARRAY_SIZE(sda_pwm_max); i++)
2972 device_remove_file(dev, &sda_pwm_max[i].dev_attr);
2973
2974 for (i = 0; i < ARRAY_SIZE(sda_pwm_step); i++)
2975 device_remove_file(dev, &sda_pwm_step[i].dev_attr);
2976
2977 for (i = 0; i < ARRAY_SIZE(sda_auto_pwm_arrays); i++)
2978 device_remove_file(dev, &sda_auto_pwm_arrays[i].dev_attr);
2979
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07002980 for (i = 0; i < data->in_num; i++)
2981 sysfs_remove_group(&dev->kobj, &nct6775_group_in[i]);
2982
Guenter Roeck1c65dc32012-12-04 07:56:24 -08002983 for (i = 0; i < 5; i++) {
2984 device_remove_file(dev, &sda_fan_input[i].dev_attr);
2985 device_remove_file(dev, &sda_fan_alarm[i].dev_attr);
2986 device_remove_file(dev, &sda_fan_div[i].dev_attr);
2987 device_remove_file(dev, &sda_fan_min[i].dev_attr);
Guenter Roeck5c25d952012-12-11 07:29:06 -08002988 device_remove_file(dev, &sda_fan_pulses[i].dev_attr);
Guenter Roeck1c65dc32012-12-04 07:56:24 -08002989 }
Guenter Roeckaa136e52012-12-04 03:26:05 -08002990 for (i = 0; i < NUM_TEMP; i++) {
2991 if (!(data->have_temp & (1 << i)))
2992 continue;
2993 device_remove_file(dev, &sda_temp_input[i].dev_attr);
2994 device_remove_file(dev, &sda_temp_label[i].dev_attr);
2995 device_remove_file(dev, &sda_temp_max[i].dev_attr);
2996 device_remove_file(dev, &sda_temp_max_hyst[i].dev_attr);
2997 device_remove_file(dev, &sda_temp_crit[i].dev_attr);
2998 if (!(data->have_temp_fixed & (1 << i)))
2999 continue;
3000 device_remove_file(dev, &sda_temp_type[i].dev_attr);
3001 device_remove_file(dev, &sda_temp_offset[i].dev_attr);
3002 if (i >= NUM_TEMP_ALARM)
3003 continue;
3004 device_remove_file(dev, &sda_temp_alarm[i].dev_attr);
3005 }
3006
Guenter Roecka6bd5872012-12-04 03:13:34 -08003007 device_remove_file(dev, &sda_caseopen[0].dev_attr);
3008 device_remove_file(dev, &sda_caseopen[1].dev_attr);
3009
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003010 device_remove_file(dev, &dev_attr_name);
3011 device_remove_file(dev, &dev_attr_cpu0_vid);
3012}
3013
3014/* Get the monitoring functions started */
3015static inline void nct6775_init_device(struct nct6775_data *data)
3016{
Guenter Roeckaa136e52012-12-04 03:26:05 -08003017 int i;
3018 u8 tmp, diode;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003019
3020 /* Start monitoring if needed */
3021 if (data->REG_CONFIG) {
3022 tmp = nct6775_read_value(data, data->REG_CONFIG);
3023 if (!(tmp & 0x01))
3024 nct6775_write_value(data, data->REG_CONFIG, tmp | 0x01);
3025 }
3026
Guenter Roeckaa136e52012-12-04 03:26:05 -08003027 /* Enable temperature sensors if needed */
3028 for (i = 0; i < NUM_TEMP; i++) {
3029 if (!(data->have_temp & (1 << i)))
3030 continue;
3031 if (!data->reg_temp_config[i])
3032 continue;
3033 tmp = nct6775_read_value(data, data->reg_temp_config[i]);
3034 if (tmp & 0x01)
3035 nct6775_write_value(data, data->reg_temp_config[i],
3036 tmp & 0xfe);
3037 }
3038
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003039 /* Enable VBAT monitoring if needed */
3040 tmp = nct6775_read_value(data, data->REG_VBAT);
3041 if (!(tmp & 0x01))
3042 nct6775_write_value(data, data->REG_VBAT, tmp | 0x01);
Guenter Roeckaa136e52012-12-04 03:26:05 -08003043
3044 diode = nct6775_read_value(data, data->REG_DIODE);
3045
3046 for (i = 0; i < data->temp_fixed_num; i++) {
3047 if (!(data->have_temp_fixed & (1 << i)))
3048 continue;
3049 if ((tmp & (0x02 << i))) /* diode */
3050 data->temp_type[i] = 3 - ((diode >> i) & 0x02);
3051 else /* thermistor */
3052 data->temp_type[i] = 4;
3053 }
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003054}
3055
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003056static int
3057nct6775_check_fan_inputs(const struct nct6775_sio_data *sio_data,
3058 struct nct6775_data *data)
3059{
3060 int regval;
3061 bool fan3pin, fan3min, fan4pin, fan4min, fan5pin;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003062 bool pwm3pin, pwm4pin, pwm5pin;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003063 int ret;
3064
3065 ret = superio_enter(sio_data->sioreg);
3066 if (ret)
3067 return ret;
3068
3069 /* fan4 and fan5 share some pins with the GPIO and serial flash */
3070 if (data->kind == nct6775) {
3071 regval = superio_inb(sio_data->sioreg, 0x2c);
3072
3073 fan3pin = regval & (1 << 6);
3074 fan3min = fan3pin;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003075 pwm3pin = regval & (1 << 7);
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003076
3077 /* On NCT6775, fan4 shares pins with the fdc interface */
3078 fan4pin = !(superio_inb(sio_data->sioreg, 0x2A) & 0x80);
3079 fan4min = 0;
3080 fan5pin = 0;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003081 pwm4pin = 0;
3082 pwm5pin = 0;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003083 } else if (data->kind == nct6776) {
3084 bool gpok = superio_inb(sio_data->sioreg, 0x27) & 0x80;
3085
3086 superio_select(sio_data->sioreg, NCT6775_LD_HWM);
3087 regval = superio_inb(sio_data->sioreg, SIO_REG_ENABLE);
3088
3089 if (regval & 0x80)
3090 fan3pin = gpok;
3091 else
3092 fan3pin = !(superio_inb(sio_data->sioreg, 0x24) & 0x40);
3093
3094 if (regval & 0x40)
3095 fan4pin = gpok;
3096 else
3097 fan4pin = superio_inb(sio_data->sioreg, 0x1C) & 0x01;
3098
3099 if (regval & 0x20)
3100 fan5pin = gpok;
3101 else
3102 fan5pin = superio_inb(sio_data->sioreg, 0x1C) & 0x02;
3103
3104 fan4min = fan4pin;
3105 fan3min = fan3pin;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003106 pwm3pin = fan3pin;
3107 pwm4pin = 0;
3108 pwm5pin = 0;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003109 } else { /* NCT6779D */
3110 regval = superio_inb(sio_data->sioreg, 0x1c);
3111
3112 fan3pin = !(regval & (1 << 5));
3113 fan4pin = !(regval & (1 << 6));
3114 fan5pin = !(regval & (1 << 7));
3115
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003116 pwm3pin = !(regval & (1 << 0));
3117 pwm4pin = !(regval & (1 << 1));
3118 pwm5pin = !(regval & (1 << 2));
3119
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003120 fan3min = fan3pin;
3121 fan4min = fan4pin;
3122 }
3123
3124 superio_exit(sio_data->sioreg);
3125
3126 data->has_fan = data->has_fan_min = 0x03; /* fan1 and fan2 */
3127 data->has_fan |= fan3pin << 2;
3128 data->has_fan_min |= fan3min << 2;
3129
3130 data->has_fan |= (fan4pin << 3) | (fan5pin << 4);
3131 data->has_fan_min |= (fan4min << 3) | (fan5pin << 4);
3132
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003133 data->has_pwm = 0x03 | (pwm3pin << 2) | (pwm4pin << 3) | (pwm5pin << 4);
3134
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003135 return 0;
3136}
3137
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003138static int nct6775_probe(struct platform_device *pdev)
3139{
3140 struct device *dev = &pdev->dev;
3141 struct nct6775_sio_data *sio_data = dev->platform_data;
3142 struct nct6775_data *data;
3143 struct resource *res;
Guenter Roeckaa136e52012-12-04 03:26:05 -08003144 int i, s, err = 0;
3145 int src, mask, available;
3146 const u16 *reg_temp, *reg_temp_over, *reg_temp_hyst, *reg_temp_config;
3147 const u16 *reg_temp_alternate, *reg_temp_crit;
3148 int num_reg_temp;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003149
3150 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
3151 if (!devm_request_region(&pdev->dev, res->start, IOREGION_LENGTH,
3152 DRVNAME))
3153 return -EBUSY;
3154
3155 data = devm_kzalloc(&pdev->dev, sizeof(struct nct6775_data),
3156 GFP_KERNEL);
3157 if (!data)
3158 return -ENOMEM;
3159
3160 data->kind = sio_data->kind;
3161 data->addr = res->start;
3162 mutex_init(&data->lock);
3163 mutex_init(&data->update_lock);
3164 data->name = nct6775_device_names[data->kind];
3165 data->bank = 0xff; /* Force initial bank selection */
3166 platform_set_drvdata(pdev, data);
3167
3168 switch (data->kind) {
3169 case nct6775:
3170 data->in_num = 9;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003171 data->pwm_num = 3;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003172 data->auto_pwm_num = 6;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003173 data->has_fan_div = true;
Guenter Roeckaa136e52012-12-04 03:26:05 -08003174 data->temp_fixed_num = 3;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003175
3176 data->ALARM_BITS = NCT6775_ALARM_BITS;
3177
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003178 data->fan_from_reg = fan_from_reg16;
3179 data->fan_from_reg_min = fan_from_reg8;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003180 data->target_temp_mask = 0x7f;
3181 data->tolerance_mask = 0x0f;
3182 data->speed_tolerance_limit = 15;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003183
Guenter Roeckaa136e52012-12-04 03:26:05 -08003184 data->temp_label = nct6775_temp_label;
3185 data->temp_label_num = ARRAY_SIZE(nct6775_temp_label);
3186
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003187 data->REG_CONFIG = NCT6775_REG_CONFIG;
3188 data->REG_VBAT = NCT6775_REG_VBAT;
Guenter Roeckaa136e52012-12-04 03:26:05 -08003189 data->REG_DIODE = NCT6775_REG_DIODE;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003190 data->REG_VIN = NCT6775_REG_IN;
3191 data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN;
3192 data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003193 data->REG_TARGET = NCT6775_REG_TARGET;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003194 data->REG_FAN = NCT6775_REG_FAN;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003195 data->REG_FAN_MODE = NCT6775_REG_FAN_MODE;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003196 data->REG_FAN_MIN = NCT6775_REG_FAN_MIN;
Guenter Roeck5c25d952012-12-11 07:29:06 -08003197 data->REG_FAN_PULSES = NCT6775_REG_FAN_PULSES;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003198 data->REG_FAN_TIME[0] = NCT6775_REG_FAN_STOP_TIME;
3199 data->REG_FAN_TIME[1] = NCT6775_REG_FAN_STEP_UP_TIME;
3200 data->REG_FAN_TIME[2] = NCT6775_REG_FAN_STEP_DOWN_TIME;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003201 data->REG_PWM[0] = NCT6775_REG_PWM;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003202 data->REG_PWM[1] = NCT6775_REG_FAN_START_OUTPUT;
3203 data->REG_PWM[2] = NCT6775_REG_FAN_STOP_OUTPUT;
3204 data->REG_PWM[3] = NCT6775_REG_FAN_MAX_OUTPUT;
3205 data->REG_PWM[4] = NCT6775_REG_FAN_STEP_OUTPUT;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003206 data->REG_PWM_READ = NCT6775_REG_PWM_READ;
3207 data->REG_PWM_MODE = NCT6775_REG_PWM_MODE;
3208 data->PWM_MODE_MASK = NCT6775_PWM_MODE_MASK;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003209 data->REG_AUTO_TEMP = NCT6775_REG_AUTO_TEMP;
3210 data->REG_AUTO_PWM = NCT6775_REG_AUTO_PWM;
3211 data->REG_CRITICAL_TEMP = NCT6775_REG_CRITICAL_TEMP;
3212 data->REG_CRITICAL_TEMP_TOLERANCE
3213 = NCT6775_REG_CRITICAL_TEMP_TOLERANCE;
Guenter Roeckaa136e52012-12-04 03:26:05 -08003214 data->REG_TEMP_OFFSET = NCT6775_REG_TEMP_OFFSET;
3215 data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003216 data->REG_TEMP_SEL = NCT6775_REG_TEMP_SEL;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003217 data->REG_ALARM = NCT6775_REG_ALARM;
Guenter Roeckaa136e52012-12-04 03:26:05 -08003218
3219 reg_temp = NCT6775_REG_TEMP;
3220 num_reg_temp = ARRAY_SIZE(NCT6775_REG_TEMP);
3221 reg_temp_over = NCT6775_REG_TEMP_OVER;
3222 reg_temp_hyst = NCT6775_REG_TEMP_HYST;
3223 reg_temp_config = NCT6775_REG_TEMP_CONFIG;
3224 reg_temp_alternate = NCT6775_REG_TEMP_ALTERNATE;
3225 reg_temp_crit = NCT6775_REG_TEMP_CRIT;
3226
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003227 break;
3228 case nct6776:
3229 data->in_num = 9;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003230 data->pwm_num = 3;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003231 data->auto_pwm_num = 4;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003232 data->has_fan_div = false;
Guenter Roeckaa136e52012-12-04 03:26:05 -08003233 data->temp_fixed_num = 3;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003234
3235 data->ALARM_BITS = NCT6776_ALARM_BITS;
3236
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003237 data->fan_from_reg = fan_from_reg13;
3238 data->fan_from_reg_min = fan_from_reg13;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003239 data->target_temp_mask = 0xff;
3240 data->tolerance_mask = 0x07;
3241 data->speed_tolerance_limit = 63;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003242
Guenter Roeckaa136e52012-12-04 03:26:05 -08003243 data->temp_label = nct6776_temp_label;
3244 data->temp_label_num = ARRAY_SIZE(nct6776_temp_label);
3245
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003246 data->REG_CONFIG = NCT6775_REG_CONFIG;
3247 data->REG_VBAT = NCT6775_REG_VBAT;
Guenter Roeckaa136e52012-12-04 03:26:05 -08003248 data->REG_DIODE = NCT6775_REG_DIODE;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003249 data->REG_VIN = NCT6775_REG_IN;
3250 data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN;
3251 data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003252 data->REG_TARGET = NCT6775_REG_TARGET;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003253 data->REG_FAN = NCT6775_REG_FAN;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003254 data->REG_FAN_MODE = NCT6775_REG_FAN_MODE;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003255 data->REG_FAN_MIN = NCT6776_REG_FAN_MIN;
Guenter Roeck5c25d952012-12-11 07:29:06 -08003256 data->REG_FAN_PULSES = NCT6776_REG_FAN_PULSES;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003257 data->REG_FAN_TIME[0] = NCT6775_REG_FAN_STOP_TIME;
3258 data->REG_FAN_TIME[1] = NCT6775_REG_FAN_STEP_UP_TIME;
3259 data->REG_FAN_TIME[2] = NCT6775_REG_FAN_STEP_DOWN_TIME;
3260 data->REG_TOLERANCE_H = NCT6776_REG_TOLERANCE_H;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003261 data->REG_PWM[0] = NCT6775_REG_PWM;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003262 data->REG_PWM[1] = NCT6775_REG_FAN_START_OUTPUT;
3263 data->REG_PWM[2] = NCT6775_REG_FAN_STOP_OUTPUT;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003264 data->REG_PWM_READ = NCT6775_REG_PWM_READ;
3265 data->REG_PWM_MODE = NCT6776_REG_PWM_MODE;
3266 data->PWM_MODE_MASK = NCT6776_PWM_MODE_MASK;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003267 data->REG_AUTO_TEMP = NCT6775_REG_AUTO_TEMP;
3268 data->REG_AUTO_PWM = NCT6775_REG_AUTO_PWM;
3269 data->REG_CRITICAL_TEMP = NCT6775_REG_CRITICAL_TEMP;
3270 data->REG_CRITICAL_TEMP_TOLERANCE
3271 = NCT6775_REG_CRITICAL_TEMP_TOLERANCE;
Guenter Roeckaa136e52012-12-04 03:26:05 -08003272 data->REG_TEMP_OFFSET = NCT6775_REG_TEMP_OFFSET;
3273 data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003274 data->REG_TEMP_SEL = NCT6775_REG_TEMP_SEL;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003275 data->REG_ALARM = NCT6775_REG_ALARM;
Guenter Roeckaa136e52012-12-04 03:26:05 -08003276
3277 reg_temp = NCT6775_REG_TEMP;
3278 num_reg_temp = ARRAY_SIZE(NCT6775_REG_TEMP);
3279 reg_temp_over = NCT6775_REG_TEMP_OVER;
3280 reg_temp_hyst = NCT6775_REG_TEMP_HYST;
3281 reg_temp_config = NCT6776_REG_TEMP_CONFIG;
3282 reg_temp_alternate = NCT6776_REG_TEMP_ALTERNATE;
3283 reg_temp_crit = NCT6776_REG_TEMP_CRIT;
3284
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003285 break;
3286 case nct6779:
3287 data->in_num = 15;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003288 data->pwm_num = 5;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003289 data->auto_pwm_num = 4;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003290 data->has_fan_div = false;
Guenter Roeckaa136e52012-12-04 03:26:05 -08003291 data->temp_fixed_num = 6;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003292
3293 data->ALARM_BITS = NCT6779_ALARM_BITS;
3294
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003295 data->fan_from_reg = fan_from_reg13;
3296 data->fan_from_reg_min = fan_from_reg13;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003297 data->target_temp_mask = 0xff;
3298 data->tolerance_mask = 0x07;
3299 data->speed_tolerance_limit = 63;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003300
Guenter Roeckaa136e52012-12-04 03:26:05 -08003301 data->temp_label = nct6779_temp_label;
3302 data->temp_label_num = ARRAY_SIZE(nct6779_temp_label);
3303
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003304 data->REG_CONFIG = NCT6775_REG_CONFIG;
3305 data->REG_VBAT = NCT6775_REG_VBAT;
Guenter Roeckaa136e52012-12-04 03:26:05 -08003306 data->REG_DIODE = NCT6775_REG_DIODE;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003307 data->REG_VIN = NCT6779_REG_IN;
3308 data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN;
3309 data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003310 data->REG_TARGET = NCT6775_REG_TARGET;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003311 data->REG_FAN = NCT6779_REG_FAN;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003312 data->REG_FAN_MODE = NCT6775_REG_FAN_MODE;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003313 data->REG_FAN_MIN = NCT6776_REG_FAN_MIN;
Guenter Roeck5c25d952012-12-11 07:29:06 -08003314 data->REG_FAN_PULSES = NCT6779_REG_FAN_PULSES;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003315 data->REG_FAN_TIME[0] = NCT6775_REG_FAN_STOP_TIME;
3316 data->REG_FAN_TIME[1] = NCT6775_REG_FAN_STEP_UP_TIME;
3317 data->REG_FAN_TIME[2] = NCT6775_REG_FAN_STEP_DOWN_TIME;
3318 data->REG_TOLERANCE_H = NCT6776_REG_TOLERANCE_H;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003319 data->REG_PWM[0] = NCT6775_REG_PWM;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003320 data->REG_PWM[1] = NCT6775_REG_FAN_START_OUTPUT;
3321 data->REG_PWM[2] = NCT6775_REG_FAN_STOP_OUTPUT;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003322 data->REG_PWM_READ = NCT6775_REG_PWM_READ;
3323 data->REG_PWM_MODE = NCT6776_REG_PWM_MODE;
3324 data->PWM_MODE_MASK = NCT6776_PWM_MODE_MASK;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003325 data->REG_AUTO_TEMP = NCT6775_REG_AUTO_TEMP;
3326 data->REG_AUTO_PWM = NCT6775_REG_AUTO_PWM;
3327 data->REG_CRITICAL_TEMP = NCT6775_REG_CRITICAL_TEMP;
3328 data->REG_CRITICAL_TEMP_TOLERANCE
3329 = NCT6775_REG_CRITICAL_TEMP_TOLERANCE;
Guenter Roeckaa136e52012-12-04 03:26:05 -08003330 data->REG_TEMP_OFFSET = NCT6779_REG_TEMP_OFFSET;
3331 data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003332 data->REG_TEMP_SEL = NCT6775_REG_TEMP_SEL;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003333 data->REG_ALARM = NCT6779_REG_ALARM;
Guenter Roeckaa136e52012-12-04 03:26:05 -08003334
3335 reg_temp = NCT6779_REG_TEMP;
3336 num_reg_temp = ARRAY_SIZE(NCT6779_REG_TEMP);
3337 reg_temp_over = NCT6779_REG_TEMP_OVER;
3338 reg_temp_hyst = NCT6779_REG_TEMP_HYST;
3339 reg_temp_config = NCT6779_REG_TEMP_CONFIG;
3340 reg_temp_alternate = NCT6779_REG_TEMP_ALTERNATE;
3341 reg_temp_crit = NCT6779_REG_TEMP_CRIT;
3342
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003343 break;
3344 default:
3345 return -ENODEV;
3346 }
3347 data->have_in = (1 << data->in_num) - 1;
Guenter Roeckaa136e52012-12-04 03:26:05 -08003348 data->have_temp = 0;
3349
3350 /*
3351 * On some boards, not all available temperature sources are monitored,
3352 * even though some of the monitoring registers are unused.
3353 * Get list of unused monitoring registers, then detect if any fan
3354 * controls are configured to use unmonitored temperature sources.
3355 * If so, assign the unmonitored temperature sources to available
3356 * monitoring registers.
3357 */
3358 mask = 0;
3359 available = 0;
3360 for (i = 0; i < num_reg_temp; i++) {
3361 if (reg_temp[i] == 0)
3362 continue;
3363
3364 src = nct6775_read_value(data, data->REG_TEMP_SOURCE[i]) & 0x1f;
3365 if (!src || (mask & (1 << src)))
3366 available |= 1 << i;
3367
3368 mask |= 1 << src;
3369 }
3370
3371 mask = 0;
3372 s = NUM_TEMP_FIXED; /* First dynamic temperature attribute */
3373 for (i = 0; i < num_reg_temp; i++) {
3374 if (reg_temp[i] == 0)
3375 continue;
3376
3377 src = nct6775_read_value(data, data->REG_TEMP_SOURCE[i]) & 0x1f;
3378 if (!src || (mask & (1 << src)))
3379 continue;
3380
3381 if (src >= data->temp_label_num ||
3382 !strlen(data->temp_label[src])) {
3383 dev_info(dev,
3384 "Invalid temperature source %d at index %d, source register 0x%x, temp register 0x%x\n",
3385 src, i, data->REG_TEMP_SOURCE[i], reg_temp[i]);
3386 continue;
3387 }
3388
3389 mask |= 1 << src;
3390
3391 /* Use fixed index for SYSTIN(1), CPUTIN(2), AUXTIN(3) */
3392 if (src <= data->temp_fixed_num) {
3393 data->have_temp |= 1 << (src - 1);
3394 data->have_temp_fixed |= 1 << (src - 1);
3395 data->reg_temp[0][src - 1] = reg_temp[i];
3396 data->reg_temp[1][src - 1] = reg_temp_over[i];
3397 data->reg_temp[2][src - 1] = reg_temp_hyst[i];
3398 data->reg_temp_config[src - 1] = reg_temp_config[i];
3399 data->temp_src[src - 1] = src;
3400 continue;
3401 }
3402
3403 if (s >= NUM_TEMP)
3404 continue;
3405
3406 /* Use dynamic index for other sources */
3407 data->have_temp |= 1 << s;
3408 data->reg_temp[0][s] = reg_temp[i];
3409 data->reg_temp[1][s] = reg_temp_over[i];
3410 data->reg_temp[2][s] = reg_temp_hyst[i];
3411 data->reg_temp_config[s] = reg_temp_config[i];
3412 if (reg_temp_crit[src - 1])
3413 data->reg_temp[3][s] = reg_temp_crit[src - 1];
3414
3415 data->temp_src[s] = src;
3416 s++;
3417 }
3418
3419#ifdef USE_ALTERNATE
3420 /*
3421 * Go through the list of alternate temp registers and enable
3422 * if possible.
3423 * The temperature is already monitored if the respective bit in <mask>
3424 * is set.
3425 */
3426 for (i = 0; i < data->temp_label_num - 1; i++) {
3427 if (!reg_temp_alternate[i])
3428 continue;
3429 if (mask & (1 << (i + 1)))
3430 continue;
3431 if (i < data->temp_fixed_num) {
3432 if (data->have_temp & (1 << i))
3433 continue;
3434 data->have_temp |= 1 << i;
3435 data->have_temp_fixed |= 1 << i;
3436 data->reg_temp[0][i] = reg_temp_alternate[i];
3437 data->reg_temp[1][i] = reg_temp_over[i];
3438 data->reg_temp[2][i] = reg_temp_hyst[i];
3439 data->temp_src[i] = i + 1;
3440 continue;
3441 }
3442
3443 if (s >= NUM_TEMP) /* Abort if no more space */
3444 break;
3445
3446 data->have_temp |= 1 << s;
3447 data->reg_temp[0][s] = reg_temp_alternate[i];
3448 data->temp_src[s] = i + 1;
3449 s++;
3450 }
3451#endif /* USE_ALTERNATE */
3452
3453 switch (data->kind) {
3454 case nct6775:
3455 break;
3456 case nct6776:
3457 /*
3458 * On NCT6776, AUXTIN and VIN3 pins are shared.
3459 * Only way to detect it is to check if AUXTIN is used
3460 * as a temperature source, and if that source is
3461 * enabled.
3462 *
3463 * If that is the case, disable in6, which reports VIN3.
3464 * Otherwise disable temp3.
3465 */
3466 if (data->have_temp & (1 << 2)) {
3467 u8 reg = nct6775_read_value(data,
3468 data->reg_temp_config[2]);
3469 if (reg & 0x01)
3470 data->have_temp &= ~(1 << 2);
3471 else
3472 data->have_in &= ~(1 << 6);
3473 }
3474 break;
3475 case nct6779:
3476 /*
3477 * Shared pins:
3478 * VIN4 / AUXTIN0
3479 * VIN5 / AUXTIN1
3480 * VIN6 / AUXTIN2
3481 * VIN7 / AUXTIN3
3482 *
3483 * There does not seem to be a clean way to detect if VINx or
3484 * AUXTINx is active, so for keep both sensor types enabled
3485 * for now.
3486 */
3487 break;
3488 }
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003489
3490 /* Initialize the chip */
3491 nct6775_init_device(data);
3492
3493 data->vrm = vid_which_vrm();
3494 err = superio_enter(sio_data->sioreg);
3495 if (err)
3496 return err;
3497
3498 /*
3499 * Read VID value
3500 * We can get the VID input values directly at logical device D 0xe3.
3501 */
3502 superio_select(sio_data->sioreg, NCT6775_LD_VID);
3503 data->vid = superio_inb(sio_data->sioreg, 0xe3);
Guenter Roeck47ece962012-12-04 07:59:32 -08003504
3505 if (fan_debounce) {
3506 u8 tmp;
3507
3508 superio_select(sio_data->sioreg, NCT6775_LD_HWM);
3509 tmp = superio_inb(sio_data->sioreg,
3510 NCT6775_REG_CR_FAN_DEBOUNCE);
3511 switch (data->kind) {
3512 case nct6775:
3513 tmp |= 0x1e;
3514 break;
3515 case nct6776:
3516 case nct6779:
3517 tmp |= 0x3e;
3518 break;
3519 }
3520 superio_outb(sio_data->sioreg, NCT6775_REG_CR_FAN_DEBOUNCE,
3521 tmp);
3522 dev_info(&pdev->dev, "Enabled fan debounce for chip %s\n",
3523 data->name);
3524 }
3525
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003526 superio_exit(sio_data->sioreg);
3527
3528 err = device_create_file(dev, &dev_attr_cpu0_vid);
3529 if (err)
3530 return err;
3531
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003532 err = nct6775_check_fan_inputs(sio_data, data);
3533 if (err)
3534 goto exit_remove;
3535
3536 /* Read fan clock dividers immediately */
3537 nct6775_init_fan_common(dev, data);
3538
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003539 /* Register sysfs hooks */
3540 for (i = 0; i < data->pwm_num; i++) {
3541 if (!(data->has_pwm & (1 << i)))
3542 continue;
3543
3544 err = sysfs_create_group(&dev->kobj, &nct6775_group_pwm[i]);
3545 if (err)
3546 goto exit_remove;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003547
3548 if (data->REG_PWM[3]) {
3549 err = device_create_file(dev,
3550 &sda_pwm_max[i].dev_attr);
3551 if (err)
3552 goto exit_remove;
3553 }
3554 if (data->REG_PWM[4]) {
3555 err = device_create_file(dev,
3556 &sda_pwm_step[i].dev_attr);
3557 if (err)
3558 goto exit_remove;
3559 }
3560 }
3561 for (i = 0; i < ARRAY_SIZE(sda_auto_pwm_arrays); i++) {
3562 struct sensor_device_attribute_2 *attr =
3563 &sda_auto_pwm_arrays[i];
3564
3565 if (!(data->has_pwm & (1 << attr->nr)))
3566 continue;
3567 if (attr->index > data->auto_pwm_num)
3568 continue;
3569 err = device_create_file(dev, &attr->dev_attr);
3570 if (err)
3571 goto exit_remove;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003572 }
3573
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003574 for (i = 0; i < data->in_num; i++) {
3575 if (!(data->have_in & (1 << i)))
3576 continue;
3577 err = sysfs_create_group(&dev->kobj, &nct6775_group_in[i]);
3578 if (err)
3579 goto exit_remove;
3580 }
3581
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003582 for (i = 0; i < 5; i++) {
3583 if (data->has_fan & (1 << i)) {
3584 err = device_create_file(dev,
3585 &sda_fan_input[i].dev_attr);
3586 if (err)
3587 goto exit_remove;
3588 err = device_create_file(dev,
3589 &sda_fan_alarm[i].dev_attr);
3590 if (err)
3591 goto exit_remove;
3592 if (data->kind != nct6776 &&
3593 data->kind != nct6779) {
3594 err = device_create_file(dev,
3595 &sda_fan_div[i].dev_attr);
3596 if (err)
3597 goto exit_remove;
3598 }
3599 if (data->has_fan_min & (1 << i)) {
3600 err = device_create_file(dev,
3601 &sda_fan_min[i].dev_attr);
3602 if (err)
3603 goto exit_remove;
3604 }
Guenter Roeck5c25d952012-12-11 07:29:06 -08003605 err = device_create_file(dev,
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003606 &sda_fan_pulses[i].dev_attr);
Guenter Roeck5c25d952012-12-11 07:29:06 -08003607 if (err)
3608 goto exit_remove;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003609 }
3610 }
3611
Guenter Roeckaa136e52012-12-04 03:26:05 -08003612 for (i = 0; i < NUM_TEMP; i++) {
3613 if (!(data->have_temp & (1 << i)))
3614 continue;
3615 err = device_create_file(dev, &sda_temp_input[i].dev_attr);
3616 if (err)
3617 goto exit_remove;
3618 if (data->temp_label) {
3619 err = device_create_file(dev,
3620 &sda_temp_label[i].dev_attr);
3621 if (err)
3622 goto exit_remove;
3623 }
3624 if (data->reg_temp[1][i]) {
3625 err = device_create_file(dev,
3626 &sda_temp_max[i].dev_attr);
3627 if (err)
3628 goto exit_remove;
3629 }
3630 if (data->reg_temp[2][i]) {
3631 err = device_create_file(dev,
3632 &sda_temp_max_hyst[i].dev_attr);
3633 if (err)
3634 goto exit_remove;
3635 }
3636 if (data->reg_temp[3][i]) {
3637 err = device_create_file(dev,
3638 &sda_temp_crit[i].dev_attr);
3639 if (err)
3640 goto exit_remove;
3641 }
3642 if (!(data->have_temp_fixed & (1 << i)))
3643 continue;
3644 err = device_create_file(dev, &sda_temp_type[i].dev_attr);
3645 if (err)
3646 goto exit_remove;
3647 err = device_create_file(dev, &sda_temp_offset[i].dev_attr);
3648 if (err)
3649 goto exit_remove;
3650 if (i >= NUM_TEMP_ALARM ||
3651 data->ALARM_BITS[TEMP_ALARM_BASE + i] < 0)
3652 continue;
3653 err = device_create_file(dev, &sda_temp_alarm[i].dev_attr);
3654 if (err)
3655 goto exit_remove;
3656 }
3657
Guenter Roecka6bd5872012-12-04 03:13:34 -08003658 for (i = 0; i < ARRAY_SIZE(sda_caseopen); i++) {
3659 if (data->ALARM_BITS[INTRUSION_ALARM_BASE + i] < 0)
3660 continue;
3661 err = device_create_file(dev, &sda_caseopen[i].dev_attr);
3662 if (err)
3663 goto exit_remove;
3664 }
3665
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003666 err = device_create_file(dev, &dev_attr_name);
3667 if (err)
3668 goto exit_remove;
3669
3670 data->hwmon_dev = hwmon_device_register(dev);
3671 if (IS_ERR(data->hwmon_dev)) {
3672 err = PTR_ERR(data->hwmon_dev);
3673 goto exit_remove;
3674 }
3675
3676 return 0;
3677
3678exit_remove:
3679 nct6775_device_remove_files(dev);
3680 return err;
3681}
3682
3683static int nct6775_remove(struct platform_device *pdev)
3684{
3685 struct nct6775_data *data = platform_get_drvdata(pdev);
3686
3687 hwmon_device_unregister(data->hwmon_dev);
3688 nct6775_device_remove_files(&pdev->dev);
3689
3690 return 0;
3691}
3692
Guenter Roeck84d19d92012-12-04 08:01:39 -08003693#ifdef CONFIG_PM
3694static int nct6775_suspend(struct device *dev)
3695{
3696 struct nct6775_data *data = nct6775_update_device(dev);
3697 struct nct6775_sio_data *sio_data = dev->platform_data;
3698
3699 mutex_lock(&data->update_lock);
3700 data->vbat = nct6775_read_value(data, data->REG_VBAT);
3701 if (sio_data->kind == nct6775) {
3702 data->fandiv1 = nct6775_read_value(data, NCT6775_REG_FANDIV1);
3703 data->fandiv2 = nct6775_read_value(data, NCT6775_REG_FANDIV2);
3704 }
3705 mutex_unlock(&data->update_lock);
3706
3707 return 0;
3708}
3709
3710static int nct6775_resume(struct device *dev)
3711{
3712 struct nct6775_data *data = dev_get_drvdata(dev);
3713 struct nct6775_sio_data *sio_data = dev->platform_data;
3714 int i, j;
3715
3716 mutex_lock(&data->update_lock);
3717 data->bank = 0xff; /* Force initial bank selection */
3718
3719 /* Restore limits */
3720 for (i = 0; i < data->in_num; i++) {
3721 if (!(data->have_in & (1 << i)))
3722 continue;
3723
3724 nct6775_write_value(data, data->REG_IN_MINMAX[0][i],
3725 data->in[i][1]);
3726 nct6775_write_value(data, data->REG_IN_MINMAX[1][i],
3727 data->in[i][2]);
3728 }
3729
3730 for (i = 0; i < 5; i++) {
3731 if (!(data->has_fan_min & (1 << i)))
3732 continue;
3733
3734 nct6775_write_value(data, data->REG_FAN_MIN[i],
3735 data->fan_min[i]);
3736 }
3737
3738 for (i = 0; i < NUM_TEMP; i++) {
3739 if (!(data->have_temp & (1 << i)))
3740 continue;
3741
3742 for (j = 1; j < 4; j++)
3743 if (data->reg_temp[j][i])
3744 nct6775_write_temp(data, data->reg_temp[j][i],
3745 data->temp[j][i]);
3746 }
3747
3748 /* Restore other settings */
3749 nct6775_write_value(data, data->REG_VBAT, data->vbat);
3750 if (sio_data->kind == nct6775) {
3751 nct6775_write_value(data, NCT6775_REG_FANDIV1, data->fandiv1);
3752 nct6775_write_value(data, NCT6775_REG_FANDIV2, data->fandiv2);
3753 }
3754
3755 /* Force re-reading all values */
3756 data->valid = false;
3757 mutex_unlock(&data->update_lock);
3758
3759 return 0;
3760}
3761
3762static const struct dev_pm_ops nct6775_dev_pm_ops = {
3763 .suspend = nct6775_suspend,
3764 .resume = nct6775_resume,
3765};
3766
3767#define NCT6775_DEV_PM_OPS (&nct6775_dev_pm_ops)
3768#else
3769#define NCT6775_DEV_PM_OPS NULL
3770#endif /* CONFIG_PM */
3771
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003772static struct platform_driver nct6775_driver = {
3773 .driver = {
3774 .owner = THIS_MODULE,
3775 .name = DRVNAME,
Guenter Roeck84d19d92012-12-04 08:01:39 -08003776 .pm = NCT6775_DEV_PM_OPS,
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003777 },
3778 .probe = nct6775_probe,
3779 .remove = nct6775_remove,
3780};
3781
3782/* nct6775_find() looks for a '627 in the Super-I/O config space */
3783static int __init nct6775_find(int sioaddr, unsigned short *addr,
3784 struct nct6775_sio_data *sio_data)
3785{
3786 static const char sio_name_NCT6775[] __initconst = "NCT6775F";
3787 static const char sio_name_NCT6776[] __initconst = "NCT6776F";
3788 static const char sio_name_NCT6779[] __initconst = "NCT6779D";
3789
3790 u16 val;
3791 const char *sio_name;
3792 int err;
3793
3794 err = superio_enter(sioaddr);
3795 if (err)
3796 return err;
3797
3798 if (force_id)
3799 val = force_id;
3800 else
3801 val = (superio_inb(sioaddr, SIO_REG_DEVID) << 8)
3802 | superio_inb(sioaddr, SIO_REG_DEVID + 1);
3803 switch (val & SIO_ID_MASK) {
3804 case SIO_NCT6775_ID:
3805 sio_data->kind = nct6775;
3806 sio_name = sio_name_NCT6775;
3807 break;
3808 case SIO_NCT6776_ID:
3809 sio_data->kind = nct6776;
3810 sio_name = sio_name_NCT6776;
3811 break;
3812 case SIO_NCT6779_ID:
3813 sio_data->kind = nct6779;
3814 sio_name = sio_name_NCT6779;
3815 break;
3816 default:
3817 if (val != 0xffff)
3818 pr_debug("unsupported chip ID: 0x%04x\n", val);
3819 superio_exit(sioaddr);
3820 return -ENODEV;
3821 }
3822
3823 /* We have a known chip, find the HWM I/O address */
3824 superio_select(sioaddr, NCT6775_LD_HWM);
3825 val = (superio_inb(sioaddr, SIO_REG_ADDR) << 8)
3826 | superio_inb(sioaddr, SIO_REG_ADDR + 1);
3827 *addr = val & IOREGION_ALIGNMENT;
3828 if (*addr == 0) {
3829 pr_err("Refusing to enable a Super-I/O device with a base I/O port 0\n");
3830 superio_exit(sioaddr);
3831 return -ENODEV;
3832 }
3833
3834 /* Activate logical device if needed */
3835 val = superio_inb(sioaddr, SIO_REG_ENABLE);
3836 if (!(val & 0x01)) {
3837 pr_warn("Forcibly enabling Super-I/O. Sensor is probably unusable.\n");
3838 superio_outb(sioaddr, SIO_REG_ENABLE, val | 0x01);
3839 }
3840
3841 superio_exit(sioaddr);
3842 pr_info("Found %s chip at %#x\n", sio_name, *addr);
3843 sio_data->sioreg = sioaddr;
3844
3845 return 0;
3846}
3847
3848/*
3849 * when Super-I/O functions move to a separate file, the Super-I/O
3850 * bus will manage the lifetime of the device and this module will only keep
3851 * track of the nct6775 driver. But since we platform_device_alloc(), we
3852 * must keep track of the device
3853 */
3854static struct platform_device *pdev;
3855
3856static int __init sensors_nct6775_init(void)
3857{
3858 int err;
3859 unsigned short address;
3860 struct resource res;
3861 struct nct6775_sio_data sio_data;
3862
3863 /*
3864 * initialize sio_data->kind and sio_data->sioreg.
3865 *
3866 * when Super-I/O functions move to a separate file, the Super-I/O
3867 * driver will probe 0x2e and 0x4e and auto-detect the presence of a
3868 * nct6775 hardware monitor, and call probe()
3869 */
3870 if (nct6775_find(0x2e, &address, &sio_data) &&
3871 nct6775_find(0x4e, &address, &sio_data))
3872 return -ENODEV;
3873
3874 err = platform_driver_register(&nct6775_driver);
3875 if (err)
3876 goto exit;
3877
3878 pdev = platform_device_alloc(DRVNAME, address);
3879 if (!pdev) {
3880 err = -ENOMEM;
3881 pr_err("Device allocation failed\n");
3882 goto exit_unregister;
3883 }
3884
3885 err = platform_device_add_data(pdev, &sio_data,
3886 sizeof(struct nct6775_sio_data));
3887 if (err) {
3888 pr_err("Platform data allocation failed\n");
3889 goto exit_device_put;
3890 }
3891
3892 memset(&res, 0, sizeof(res));
3893 res.name = DRVNAME;
3894 res.start = address + IOREGION_OFFSET;
3895 res.end = address + IOREGION_OFFSET + IOREGION_LENGTH - 1;
3896 res.flags = IORESOURCE_IO;
3897
3898 err = acpi_check_resource_conflict(&res);
3899 if (err)
3900 goto exit_device_put;
3901
3902 err = platform_device_add_resources(pdev, &res, 1);
3903 if (err) {
3904 pr_err("Device resource addition failed (%d)\n", err);
3905 goto exit_device_put;
3906 }
3907
3908 /* platform_device_add calls probe() */
3909 err = platform_device_add(pdev);
3910 if (err) {
3911 pr_err("Device addition failed (%d)\n", err);
3912 goto exit_device_put;
3913 }
3914
3915 return 0;
3916
3917exit_device_put:
3918 platform_device_put(pdev);
3919exit_unregister:
3920 platform_driver_unregister(&nct6775_driver);
3921exit:
3922 return err;
3923}
3924
3925static void __exit sensors_nct6775_exit(void)
3926{
3927 platform_device_unregister(pdev);
3928 platform_driver_unregister(&nct6775_driver);
3929}
3930
3931MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>");
3932MODULE_DESCRIPTION("NCT6775F/NCT6776F/NCT6779D driver");
3933MODULE_LICENSE("GPL");
3934
3935module_init(sensors_nct6775_init);
3936module_exit(sensors_nct6775_exit);