blob: 99cec18254203c5ebfa59ba0b1cbfdecabf77aac [file] [log] [blame]
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07001/*
2 * nct6775 - Driver for the hardware monitoring functionality of
3 * Nuvoton NCT677x Super-I/O chips
4 *
5 * Copyright (C) 2012 Guenter Roeck <linux@roeck-us.net>
6 *
7 * Derived from w83627ehf driver
8 * Copyright (C) 2005-2012 Jean Delvare <khali@linux-fr.org>
9 * Copyright (C) 2006 Yuan Mu (Winbond),
10 * Rudolf Marek <r.marek@assembler.cz>
11 * David Hubbard <david.c.hubbard@gmail.com>
12 * Daniel J Blueman <daniel.blueman@gmail.com>
13 * Copyright (C) 2010 Sheng-Yuan Huang (Nuvoton) (PS00)
14 *
15 * Shamelessly ripped from the w83627hf driver
16 * Copyright (C) 2003 Mark Studebaker
17 *
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 2 of the License, or
21 * (at your option) any later version.
22 *
23 * This program is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
27 *
28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, write to the Free Software
30 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
31 *
32 *
33 * Supports the following chips:
34 *
35 * Chip #vin #fan #pwm #temp chip IDs man ID
36 * nct6775f 9 4 3 6+3 0xb470 0xc1 0x5ca3
37 * nct6776f 9 5 3 6+3 0xc330 0xc1 0x5ca3
38 * nct6779d 15 5 5 2+6 0xc560 0xc1 0x5ca3
39 *
40 * #temp lists the number of monitored temperature sources (first value) plus
41 * the number of directly connectable temperature sensors (second value).
42 */
43
44#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
45
46#include <linux/module.h>
47#include <linux/init.h>
48#include <linux/slab.h>
49#include <linux/jiffies.h>
50#include <linux/platform_device.h>
51#include <linux/hwmon.h>
52#include <linux/hwmon-sysfs.h>
53#include <linux/hwmon-vid.h>
54#include <linux/err.h>
55#include <linux/mutex.h>
56#include <linux/acpi.h>
57#include <linux/io.h>
58#include "lm75.h"
59
Guenter Roeckaa136e52012-12-04 03:26:05 -080060#define USE_ALTERNATE
61
Guenter Roeck9de2e2e2012-05-20 19:29:48 -070062enum kinds { nct6775, nct6776, nct6779 };
63
64/* used to set data->name = nct6775_device_names[data->sio_kind] */
65static const char * const nct6775_device_names[] = {
66 "nct6775",
67 "nct6776",
68 "nct6779",
69};
70
71static unsigned short force_id;
72module_param(force_id, ushort, 0);
73MODULE_PARM_DESC(force_id, "Override the detected device ID");
74
Guenter Roeck47ece962012-12-04 07:59:32 -080075static unsigned short fan_debounce;
76module_param(fan_debounce, ushort, 0);
77MODULE_PARM_DESC(fan_debounce, "Enable debouncing for fan RPM signal");
78
Guenter Roeck9de2e2e2012-05-20 19:29:48 -070079#define DRVNAME "nct6775"
80
81/*
82 * Super-I/O constants and functions
83 */
84
Guenter Roecka6bd5872012-12-04 03:13:34 -080085#define NCT6775_LD_ACPI 0x0a
Guenter Roeck9de2e2e2012-05-20 19:29:48 -070086#define NCT6775_LD_HWM 0x0b
87#define NCT6775_LD_VID 0x0d
88
89#define SIO_REG_LDSEL 0x07 /* Logical device select */
90#define SIO_REG_DEVID 0x20 /* Device ID (2 bytes) */
91#define SIO_REG_ENABLE 0x30 /* Logical device enable */
92#define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */
93
94#define SIO_NCT6775_ID 0xb470
95#define SIO_NCT6776_ID 0xc330
96#define SIO_NCT6779_ID 0xc560
97#define SIO_ID_MASK 0xFFF0
98
Guenter Roeck77eb5b32012-12-04 08:30:54 -080099enum pwm_enable { off, manual, thermal_cruise, speed_cruise, sf3, sf4 };
100
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700101static inline void
102superio_outb(int ioreg, int reg, int val)
103{
104 outb(reg, ioreg);
105 outb(val, ioreg + 1);
106}
107
108static inline int
109superio_inb(int ioreg, int reg)
110{
111 outb(reg, ioreg);
112 return inb(ioreg + 1);
113}
114
115static inline void
116superio_select(int ioreg, int ld)
117{
118 outb(SIO_REG_LDSEL, ioreg);
119 outb(ld, ioreg + 1);
120}
121
122static inline int
123superio_enter(int ioreg)
124{
125 /*
126 * Try to reserve <ioreg> and <ioreg + 1> for exclusive access.
127 */
128 if (!request_muxed_region(ioreg, 2, DRVNAME))
129 return -EBUSY;
130
131 outb(0x87, ioreg);
132 outb(0x87, ioreg);
133
134 return 0;
135}
136
137static inline void
138superio_exit(int ioreg)
139{
140 outb(0xaa, ioreg);
141 outb(0x02, ioreg);
142 outb(0x02, ioreg + 1);
143 release_region(ioreg, 2);
144}
145
146/*
147 * ISA constants
148 */
149
150#define IOREGION_ALIGNMENT (~7)
151#define IOREGION_OFFSET 5
152#define IOREGION_LENGTH 2
153#define ADDR_REG_OFFSET 0
154#define DATA_REG_OFFSET 1
155
156#define NCT6775_REG_BANK 0x4E
157#define NCT6775_REG_CONFIG 0x40
158
159/*
160 * Not currently used:
161 * REG_MAN_ID has the value 0x5ca3 for all supported chips.
162 * REG_CHIP_ID == 0x88/0xa1/0xc1 depending on chip model.
163 * REG_MAN_ID is at port 0x4f
164 * REG_CHIP_ID is at port 0x58
165 */
166
Guenter Roeckaa136e52012-12-04 03:26:05 -0800167#define NUM_TEMP 10 /* Max number of temp attribute sets w/ limits*/
168#define NUM_TEMP_FIXED 6 /* Max number of fixed temp attribute sets */
169
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700170#define NUM_REG_ALARM 4 /* Max number of alarm registers */
171
172/* Common and NCT6775 specific data */
173
174/* Voltage min/max registers for nr=7..14 are in bank 5 */
175
176static const u16 NCT6775_REG_IN_MAX[] = {
177 0x2b, 0x2d, 0x2f, 0x31, 0x33, 0x35, 0x37, 0x554, 0x556, 0x558, 0x55a,
178 0x55c, 0x55e, 0x560, 0x562 };
179static const u16 NCT6775_REG_IN_MIN[] = {
180 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x555, 0x557, 0x559, 0x55b,
181 0x55d, 0x55f, 0x561, 0x563 };
182static const u16 NCT6775_REG_IN[] = {
183 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x550, 0x551, 0x552
184};
185
186#define NCT6775_REG_VBAT 0x5D
Guenter Roeckaa136e52012-12-04 03:26:05 -0800187#define NCT6775_REG_DIODE 0x5E
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700188
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800189#define NCT6775_REG_FANDIV1 0x506
190#define NCT6775_REG_FANDIV2 0x507
191
Guenter Roeck47ece962012-12-04 07:59:32 -0800192#define NCT6775_REG_CR_FAN_DEBOUNCE 0xf0
193
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700194static const u16 NCT6775_REG_ALARM[NUM_REG_ALARM] = { 0x459, 0x45A, 0x45B };
195
196/* 0..15 voltages, 16..23 fans, 24..31 temperatures */
197
198static const s8 NCT6775_ALARM_BITS[] = {
199 0, 1, 2, 3, 8, 21, 20, 16, /* in0.. in7 */
200 17, -1, -1, -1, -1, -1, -1, /* in8..in14 */
201 -1, /* unused */
Guenter Roeck41fa9a92013-06-23 13:04:04 -0700202 6, 7, 11, -1, -1, /* fan1..fan5 */
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700203 -1, -1, -1, /* unused */
204 4, 5, 13, -1, -1, -1, /* temp1..temp6 */
205 12, -1 }; /* intrusion0, intrusion1 */
206
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800207#define FAN_ALARM_BASE 16
Guenter Roeckaa136e52012-12-04 03:26:05 -0800208#define TEMP_ALARM_BASE 24
Guenter Roecka6bd5872012-12-04 03:13:34 -0800209#define INTRUSION_ALARM_BASE 30
210
211static const u8 NCT6775_REG_CR_CASEOPEN_CLR[] = { 0xe6, 0xee };
212static const u8 NCT6775_CR_CASEOPEN_CLR_MASK[] = { 0x20, 0x01 };
213
Guenter Roeck77eb5b32012-12-04 08:30:54 -0800214/* DC or PWM output fan configuration */
215static const u8 NCT6775_REG_PWM_MODE[] = { 0x04, 0x04, 0x12 };
216static const u8 NCT6775_PWM_MODE_MASK[] = { 0x01, 0x02, 0x01 };
217
Guenter Roeckcdcaece2012-12-04 09:04:52 -0800218/* Advanced Fan control, some values are common for all fans */
Guenter Roeck77eb5b32012-12-04 08:30:54 -0800219
Guenter Roeckcdcaece2012-12-04 09:04:52 -0800220static const u16 NCT6775_REG_TARGET[] = { 0x101, 0x201, 0x301, 0x801, 0x901 };
221static const u16 NCT6775_REG_FAN_MODE[] = { 0x102, 0x202, 0x302, 0x802, 0x902 };
222static const u16 NCT6775_REG_FAN_STEP_DOWN_TIME[] = {
223 0x103, 0x203, 0x303, 0x803, 0x903 };
224static const u16 NCT6775_REG_FAN_STEP_UP_TIME[] = {
225 0x104, 0x204, 0x304, 0x804, 0x904 };
226static const u16 NCT6775_REG_FAN_STOP_OUTPUT[] = {
227 0x105, 0x205, 0x305, 0x805, 0x905 };
228static const u16 NCT6775_REG_FAN_START_OUTPUT[]
229 = { 0x106, 0x206, 0x306, 0x806, 0x906 };
230static const u16 NCT6775_REG_FAN_MAX_OUTPUT[] = { 0x10a, 0x20a, 0x30a };
231static const u16 NCT6775_REG_FAN_STEP_OUTPUT[] = { 0x10b, 0x20b, 0x30b };
232
233static const u16 NCT6775_REG_FAN_STOP_TIME[] = {
234 0x107, 0x207, 0x307, 0x807, 0x907 };
Guenter Roeck77eb5b32012-12-04 08:30:54 -0800235static const u16 NCT6775_REG_PWM[] = { 0x109, 0x209, 0x309, 0x809, 0x909 };
236static const u16 NCT6775_REG_PWM_READ[] = { 0x01, 0x03, 0x11, 0x13, 0x15 };
237
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800238static const u16 NCT6775_REG_FAN[] = { 0x630, 0x632, 0x634, 0x636, 0x638 };
239static const u16 NCT6775_REG_FAN_MIN[] = { 0x3b, 0x3c, 0x3d };
Guenter Roeck5c25d952012-12-11 07:29:06 -0800240static const u16 NCT6775_REG_FAN_PULSES[] = { 0x641, 0x642, 0x643, 0x644, 0 };
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800241
Guenter Roeckaa136e52012-12-04 03:26:05 -0800242static const u16 NCT6775_REG_TEMP[] = {
243 0x27, 0x150, 0x250, 0x62b, 0x62c, 0x62d };
244
245static const u16 NCT6775_REG_TEMP_CONFIG[ARRAY_SIZE(NCT6775_REG_TEMP)] = {
246 0, 0x152, 0x252, 0x628, 0x629, 0x62A };
247static const u16 NCT6775_REG_TEMP_HYST[ARRAY_SIZE(NCT6775_REG_TEMP)] = {
248 0x3a, 0x153, 0x253, 0x673, 0x678, 0x67D };
249static const u16 NCT6775_REG_TEMP_OVER[ARRAY_SIZE(NCT6775_REG_TEMP)] = {
250 0x39, 0x155, 0x255, 0x672, 0x677, 0x67C };
251
252static const u16 NCT6775_REG_TEMP_SOURCE[ARRAY_SIZE(NCT6775_REG_TEMP)] = {
253 0x621, 0x622, 0x623, 0x624, 0x625, 0x626 };
254
Guenter Roeckcdcaece2012-12-04 09:04:52 -0800255static const u16 NCT6775_REG_TEMP_SEL[] = {
256 0x100, 0x200, 0x300, 0x800, 0x900 };
257
Guenter Roeckbbd8dec2012-12-04 09:08:29 -0800258static const u16 NCT6775_REG_WEIGHT_TEMP_SEL[] = {
259 0x139, 0x239, 0x339, 0x839, 0x939 };
260static const u16 NCT6775_REG_WEIGHT_TEMP_STEP[] = {
261 0x13a, 0x23a, 0x33a, 0x83a, 0x93a };
262static const u16 NCT6775_REG_WEIGHT_TEMP_STEP_TOL[] = {
263 0x13b, 0x23b, 0x33b, 0x83b, 0x93b };
264static const u16 NCT6775_REG_WEIGHT_DUTY_STEP[] = {
265 0x13c, 0x23c, 0x33c, 0x83c, 0x93c };
266static const u16 NCT6775_REG_WEIGHT_TEMP_BASE[] = {
267 0x13d, 0x23d, 0x33d, 0x83d, 0x93d };
268
Guenter Roeckaa136e52012-12-04 03:26:05 -0800269static const u16 NCT6775_REG_TEMP_OFFSET[] = { 0x454, 0x455, 0x456 };
270
Guenter Roeckcdcaece2012-12-04 09:04:52 -0800271static const u16 NCT6775_REG_AUTO_TEMP[] = {
272 0x121, 0x221, 0x321, 0x821, 0x921 };
273static const u16 NCT6775_REG_AUTO_PWM[] = {
274 0x127, 0x227, 0x327, 0x827, 0x927 };
275
276#define NCT6775_AUTO_TEMP(data, nr, p) ((data)->REG_AUTO_TEMP[nr] + (p))
277#define NCT6775_AUTO_PWM(data, nr, p) ((data)->REG_AUTO_PWM[nr] + (p))
278
279static const u16 NCT6775_REG_CRITICAL_ENAB[] = { 0x134, 0x234, 0x334 };
280
281static const u16 NCT6775_REG_CRITICAL_TEMP[] = {
282 0x135, 0x235, 0x335, 0x835, 0x935 };
283static const u16 NCT6775_REG_CRITICAL_TEMP_TOLERANCE[] = {
284 0x138, 0x238, 0x338, 0x838, 0x938 };
285
Guenter Roeckaa136e52012-12-04 03:26:05 -0800286static const char *const nct6775_temp_label[] = {
287 "",
288 "SYSTIN",
289 "CPUTIN",
290 "AUXTIN",
291 "AMD SB-TSI",
292 "PECI Agent 0",
293 "PECI Agent 1",
294 "PECI Agent 2",
295 "PECI Agent 3",
296 "PECI Agent 4",
297 "PECI Agent 5",
298 "PECI Agent 6",
299 "PECI Agent 7",
300 "PCH_CHIP_CPU_MAX_TEMP",
301 "PCH_CHIP_TEMP",
302 "PCH_CPU_TEMP",
303 "PCH_MCH_TEMP",
304 "PCH_DIM0_TEMP",
305 "PCH_DIM1_TEMP",
306 "PCH_DIM2_TEMP",
307 "PCH_DIM3_TEMP"
308};
309
310static const u16 NCT6775_REG_TEMP_ALTERNATE[ARRAY_SIZE(nct6775_temp_label) - 1]
311 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x661, 0x662, 0x664 };
312
313static const u16 NCT6775_REG_TEMP_CRIT[ARRAY_SIZE(nct6775_temp_label) - 1]
314 = { 0, 0, 0, 0, 0xa00, 0xa01, 0xa02, 0xa03, 0xa04, 0xa05, 0xa06,
315 0xa07 };
316
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700317/* NCT6776 specific data */
318
319static const s8 NCT6776_ALARM_BITS[] = {
320 0, 1, 2, 3, 8, 21, 20, 16, /* in0.. in7 */
321 17, -1, -1, -1, -1, -1, -1, /* in8..in14 */
322 -1, /* unused */
323 6, 7, 11, 10, 23, /* fan1..fan5 */
324 -1, -1, -1, /* unused */
325 4, 5, 13, -1, -1, -1, /* temp1..temp6 */
326 12, 9 }; /* intrusion0, intrusion1 */
327
Guenter Roeckcdcaece2012-12-04 09:04:52 -0800328static const u16 NCT6776_REG_TOLERANCE_H[] = {
329 0x10c, 0x20c, 0x30c, 0x80c, 0x90c };
330
Guenter Roeck77eb5b32012-12-04 08:30:54 -0800331static const u8 NCT6776_REG_PWM_MODE[] = { 0x04, 0, 0 };
332static const u8 NCT6776_PWM_MODE_MASK[] = { 0x01, 0, 0 };
333
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800334static const u16 NCT6776_REG_FAN_MIN[] = { 0x63a, 0x63c, 0x63e, 0x640, 0x642 };
Guenter Roeck5c25d952012-12-11 07:29:06 -0800335static const u16 NCT6776_REG_FAN_PULSES[] = { 0x644, 0x645, 0x646, 0, 0 };
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800336
Guenter Roeckbbd8dec2012-12-04 09:08:29 -0800337static const u16 NCT6776_REG_WEIGHT_DUTY_BASE[] = {
338 0x13e, 0x23e, 0x33e, 0x83e, 0x93e };
339
Guenter Roeckaa136e52012-12-04 03:26:05 -0800340static const u16 NCT6776_REG_TEMP_CONFIG[ARRAY_SIZE(NCT6775_REG_TEMP)] = {
341 0x18, 0x152, 0x252, 0x628, 0x629, 0x62A };
342
343static const char *const nct6776_temp_label[] = {
344 "",
345 "SYSTIN",
346 "CPUTIN",
347 "AUXTIN",
348 "SMBUSMASTER 0",
349 "SMBUSMASTER 1",
350 "SMBUSMASTER 2",
351 "SMBUSMASTER 3",
352 "SMBUSMASTER 4",
353 "SMBUSMASTER 5",
354 "SMBUSMASTER 6",
355 "SMBUSMASTER 7",
356 "PECI Agent 0",
357 "PECI Agent 1",
358 "PCH_CHIP_CPU_MAX_TEMP",
359 "PCH_CHIP_TEMP",
360 "PCH_CPU_TEMP",
361 "PCH_MCH_TEMP",
362 "PCH_DIM0_TEMP",
363 "PCH_DIM1_TEMP",
364 "PCH_DIM2_TEMP",
365 "PCH_DIM3_TEMP",
366 "BYTE_TEMP"
367};
368
369static const u16 NCT6776_REG_TEMP_ALTERNATE[ARRAY_SIZE(nct6776_temp_label) - 1]
370 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x401, 0x402, 0x404 };
371
372static const u16 NCT6776_REG_TEMP_CRIT[ARRAY_SIZE(nct6776_temp_label) - 1]
373 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x709, 0x70a };
374
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700375/* NCT6779 specific data */
376
377static const u16 NCT6779_REG_IN[] = {
378 0x480, 0x481, 0x482, 0x483, 0x484, 0x485, 0x486, 0x487,
379 0x488, 0x489, 0x48a, 0x48b, 0x48c, 0x48d, 0x48e };
380
381static const u16 NCT6779_REG_ALARM[NUM_REG_ALARM] = {
382 0x459, 0x45A, 0x45B, 0x568 };
383
384static const s8 NCT6779_ALARM_BITS[] = {
385 0, 1, 2, 3, 8, 21, 20, 16, /* in0.. in7 */
386 17, 24, 25, 26, 27, 28, 29, /* in8..in14 */
387 -1, /* unused */
388 6, 7, 11, 10, 23, /* fan1..fan5 */
389 -1, -1, -1, /* unused */
390 4, 5, 13, -1, -1, -1, /* temp1..temp6 */
391 12, 9 }; /* intrusion0, intrusion1 */
392
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800393static const u16 NCT6779_REG_FAN[] = { 0x4b0, 0x4b2, 0x4b4, 0x4b6, 0x4b8 };
Guenter Roeck5c25d952012-12-11 07:29:06 -0800394static const u16 NCT6779_REG_FAN_PULSES[] = {
395 0x644, 0x645, 0x646, 0x647, 0x648 };
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800396
Guenter Roeckcdcaece2012-12-04 09:04:52 -0800397static const u16 NCT6779_REG_CRITICAL_PWM_ENABLE[] = {
398 0x136, 0x236, 0x336, 0x836, 0x936 };
399static const u16 NCT6779_REG_CRITICAL_PWM[] = {
400 0x137, 0x237, 0x337, 0x837, 0x937 };
401
Guenter Roeckaa136e52012-12-04 03:26:05 -0800402static const u16 NCT6779_REG_TEMP[] = { 0x27, 0x150 };
403static const u16 NCT6779_REG_TEMP_CONFIG[ARRAY_SIZE(NCT6779_REG_TEMP)] = {
404 0x18, 0x152 };
405static const u16 NCT6779_REG_TEMP_HYST[ARRAY_SIZE(NCT6779_REG_TEMP)] = {
406 0x3a, 0x153 };
407static const u16 NCT6779_REG_TEMP_OVER[ARRAY_SIZE(NCT6779_REG_TEMP)] = {
408 0x39, 0x155 };
409
410static const u16 NCT6779_REG_TEMP_OFFSET[] = {
411 0x454, 0x455, 0x456, 0x44a, 0x44b, 0x44c };
412
413static const char *const nct6779_temp_label[] = {
414 "",
415 "SYSTIN",
416 "CPUTIN",
417 "AUXTIN0",
418 "AUXTIN1",
419 "AUXTIN2",
420 "AUXTIN3",
421 "",
422 "SMBUSMASTER 0",
423 "SMBUSMASTER 1",
424 "SMBUSMASTER 2",
425 "SMBUSMASTER 3",
426 "SMBUSMASTER 4",
427 "SMBUSMASTER 5",
428 "SMBUSMASTER 6",
429 "SMBUSMASTER 7",
430 "PECI Agent 0",
431 "PECI Agent 1",
432 "PCH_CHIP_CPU_MAX_TEMP",
433 "PCH_CHIP_TEMP",
434 "PCH_CPU_TEMP",
435 "PCH_MCH_TEMP",
436 "PCH_DIM0_TEMP",
437 "PCH_DIM1_TEMP",
438 "PCH_DIM2_TEMP",
439 "PCH_DIM3_TEMP",
440 "BYTE_TEMP"
441};
442
443static const u16 NCT6779_REG_TEMP_ALTERNATE[ARRAY_SIZE(nct6779_temp_label) - 1]
444 = { 0x490, 0x491, 0x492, 0x493, 0x494, 0x495, 0, 0,
445 0, 0, 0, 0, 0, 0, 0, 0,
446 0, 0x400, 0x401, 0x402, 0x404, 0x405, 0x406, 0x407,
447 0x408, 0 };
448
449static const u16 NCT6779_REG_TEMP_CRIT[ARRAY_SIZE(nct6779_temp_label) - 1]
450 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x709, 0x70a };
451
Guenter Roeck77eb5b32012-12-04 08:30:54 -0800452static enum pwm_enable reg_to_pwm_enable(int pwm, int mode)
453{
454 if (mode == 0 && pwm == 255)
455 return off;
456 return mode + 1;
457}
458
459static int pwm_enable_to_reg(enum pwm_enable mode)
460{
461 if (mode == off)
462 return 0;
463 return mode - 1;
464}
465
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700466/*
467 * Conversions
468 */
469
Guenter Roeckcdcaece2012-12-04 09:04:52 -0800470/* 1 is DC mode, output in ms */
471static unsigned int step_time_from_reg(u8 reg, u8 mode)
472{
473 return mode ? 400 * reg : 100 * reg;
474}
475
476static u8 step_time_to_reg(unsigned int msec, u8 mode)
477{
478 return clamp_val((mode ? (msec + 200) / 400 :
479 (msec + 50) / 100), 1, 255);
480}
481
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800482static unsigned int fan_from_reg8(u16 reg, unsigned int divreg)
483{
484 if (reg == 0 || reg == 255)
485 return 0;
486 return 1350000U / (reg << divreg);
487}
488
489static unsigned int fan_from_reg13(u16 reg, unsigned int divreg)
490{
491 if ((reg & 0xff1f) == 0xff1f)
492 return 0;
493
494 reg = (reg & 0x1f) | ((reg & 0xff00) >> 3);
495
496 if (reg == 0)
497 return 0;
498
499 return 1350000U / reg;
500}
501
502static unsigned int fan_from_reg16(u16 reg, unsigned int divreg)
503{
504 if (reg == 0 || reg == 0xffff)
505 return 0;
506
507 /*
508 * Even though the registers are 16 bit wide, the fan divisor
509 * still applies.
510 */
511 return 1350000U / (reg << divreg);
512}
513
Guenter Roeckcdcaece2012-12-04 09:04:52 -0800514static u16 fan_to_reg(u32 fan, unsigned int divreg)
515{
516 if (!fan)
517 return 0;
518
519 return (1350000U / fan) >> divreg;
520}
521
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800522static inline unsigned int
523div_from_reg(u8 reg)
524{
525 return 1 << reg;
526}
527
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700528/*
529 * Some of the voltage inputs have internal scaling, the tables below
530 * contain 8 (the ADC LSB in mV) * scaling factor * 100
531 */
532static const u16 scale_in[15] = {
533 800, 800, 1600, 1600, 800, 800, 800, 1600, 1600, 800, 800, 800, 800,
534 800, 800
535};
536
537static inline long in_from_reg(u8 reg, u8 nr)
538{
539 return DIV_ROUND_CLOSEST(reg * scale_in[nr], 100);
540}
541
542static inline u8 in_to_reg(u32 val, u8 nr)
543{
544 return clamp_val(DIV_ROUND_CLOSEST(val * 100, scale_in[nr]), 0, 255);
545}
546
547/*
548 * Data structures and manipulation thereof
549 */
550
551struct nct6775_data {
552 int addr; /* IO base of hw monitor block */
553 enum kinds kind;
554 const char *name;
555
556 struct device *hwmon_dev;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700557
Guenter Roeckaa136e52012-12-04 03:26:05 -0800558 u16 reg_temp[4][NUM_TEMP]; /* 0=temp, 1=temp_over, 2=temp_hyst,
559 * 3=temp_crit
560 */
561 u8 temp_src[NUM_TEMP];
562 u16 reg_temp_config[NUM_TEMP];
563 const char * const *temp_label;
564 int temp_label_num;
565
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700566 u16 REG_CONFIG;
567 u16 REG_VBAT;
Guenter Roeckaa136e52012-12-04 03:26:05 -0800568 u16 REG_DIODE;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700569
570 const s8 *ALARM_BITS;
571
572 const u16 *REG_VIN;
573 const u16 *REG_IN_MINMAX[2];
574
Guenter Roeckcdcaece2012-12-04 09:04:52 -0800575 const u16 *REG_TARGET;
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800576 const u16 *REG_FAN;
Guenter Roeck77eb5b32012-12-04 08:30:54 -0800577 const u16 *REG_FAN_MODE;
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800578 const u16 *REG_FAN_MIN;
Guenter Roeck5c25d952012-12-11 07:29:06 -0800579 const u16 *REG_FAN_PULSES;
Guenter Roeckcdcaece2012-12-04 09:04:52 -0800580 const u16 *REG_FAN_TIME[3];
581
582 const u16 *REG_TOLERANCE_H;
Guenter Roeckaa136e52012-12-04 03:26:05 -0800583
Guenter Roeck77eb5b32012-12-04 08:30:54 -0800584 const u8 *REG_PWM_MODE;
585 const u8 *PWM_MODE_MASK;
586
Guenter Roeckbbd8dec2012-12-04 09:08:29 -0800587 const u16 *REG_PWM[7]; /* [0]=pwm, [1]=pwm_start, [2]=pwm_floor,
588 * [3]=pwm_max, [4]=pwm_step,
589 * [5]=weight_duty_step, [6]=weight_duty_base
Guenter Roeckcdcaece2012-12-04 09:04:52 -0800590 */
Guenter Roeck77eb5b32012-12-04 08:30:54 -0800591 const u16 *REG_PWM_READ;
592
Guenter Roeckcdcaece2012-12-04 09:04:52 -0800593 const u16 *REG_AUTO_TEMP;
594 const u16 *REG_AUTO_PWM;
595
596 const u16 *REG_CRITICAL_TEMP;
597 const u16 *REG_CRITICAL_TEMP_TOLERANCE;
598
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800599 const u16 *REG_TEMP_SOURCE; /* temp register sources */
Guenter Roeckcdcaece2012-12-04 09:04:52 -0800600 const u16 *REG_TEMP_SEL;
Guenter Roeckbbd8dec2012-12-04 09:08:29 -0800601 const u16 *REG_WEIGHT_TEMP_SEL;
602 const u16 *REG_WEIGHT_TEMP[3]; /* 0=base, 1=tolerance, 2=step */
603
Guenter Roeckaa136e52012-12-04 03:26:05 -0800604 const u16 *REG_TEMP_OFFSET;
605
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700606 const u16 *REG_ALARM;
607
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800608 unsigned int (*fan_from_reg)(u16 reg, unsigned int divreg);
609 unsigned int (*fan_from_reg_min)(u16 reg, unsigned int divreg);
610
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700611 struct mutex update_lock;
612 bool valid; /* true if following fields are valid */
613 unsigned long last_updated; /* In jiffies */
614
615 /* Register values */
616 u8 bank; /* current register bank */
617 u8 in_num; /* number of in inputs we have */
618 u8 in[15][3]; /* [0]=in, [1]=in_max, [2]=in_min */
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800619 unsigned int rpm[5];
620 u16 fan_min[5];
Guenter Roeck5c25d952012-12-11 07:29:06 -0800621 u8 fan_pulses[5];
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800622 u8 fan_div[5];
Guenter Roeck77eb5b32012-12-04 08:30:54 -0800623 u8 has_pwm;
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800624 u8 has_fan; /* some fan inputs can be disabled */
625 u8 has_fan_min; /* some fans don't have min register */
626 bool has_fan_div;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700627
Guenter Roeckb1d2bff2013-06-22 16:15:31 -0700628 u8 num_temp_alarms; /* 2 or 3 */
Guenter Roeckaa136e52012-12-04 03:26:05 -0800629 u8 temp_fixed_num; /* 3 or 6 */
630 u8 temp_type[NUM_TEMP_FIXED];
631 s8 temp_offset[NUM_TEMP_FIXED];
632 s16 temp[4][NUM_TEMP]; /* 0=temp, 1=temp_over, 2=temp_hyst,
633 * 3=temp_crit */
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700634 u64 alarms;
635
Guenter Roeck77eb5b32012-12-04 08:30:54 -0800636 u8 pwm_num; /* number of pwm */
637 u8 pwm_mode[5]; /* 1->DC variable voltage, 0->PWM variable duty cycle */
638 enum pwm_enable pwm_enable[5];
639 /* 0->off
640 * 1->manual
641 * 2->thermal cruise mode (also called SmartFan I)
642 * 3->fan speed cruise mode
643 * 4->SmartFan III
644 * 5->enhanced variable thermal cruise (SmartFan IV)
645 */
Guenter Roeckbbd8dec2012-12-04 09:08:29 -0800646 u8 pwm[7][5]; /* [0]=pwm, [1]=pwm_start, [2]=pwm_floor,
647 * [3]=pwm_max, [4]=pwm_step,
648 * [5]=weight_duty_step, [6]=weight_duty_base
Guenter Roeckcdcaece2012-12-04 09:04:52 -0800649 */
650
651 u8 target_temp[5];
652 u8 target_temp_mask;
653 u32 target_speed[5];
654 u32 target_speed_tolerance[5];
655 u8 speed_tolerance_limit;
656
657 u8 temp_tolerance[2][5];
658 u8 tolerance_mask;
659
660 u8 fan_time[3][5]; /* 0 = stop_time, 1 = step_up, 2 = step_down */
661
662 /* Automatic fan speed control registers */
663 int auto_pwm_num;
664 u8 auto_pwm[5][7];
665 u8 auto_temp[5][7];
666 u8 pwm_temp_sel[5];
Guenter Roeckbbd8dec2012-12-04 09:08:29 -0800667 u8 pwm_weight_temp_sel[5];
668 u8 weight_temp[3][5]; /* 0->temp_step, 1->temp_step_tol,
669 * 2->temp_base
670 */
Guenter Roeck77eb5b32012-12-04 08:30:54 -0800671
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700672 u8 vid;
673 u8 vrm;
674
Guenter Roeckaa136e52012-12-04 03:26:05 -0800675 u16 have_temp;
676 u16 have_temp_fixed;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700677 u16 have_in;
Guenter Roeck84d19d92012-12-04 08:01:39 -0800678#ifdef CONFIG_PM
679 /* Remember extra register values over suspend/resume */
680 u8 vbat;
681 u8 fandiv1;
682 u8 fandiv2;
683#endif
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700684};
685
686struct nct6775_sio_data {
687 int sioreg;
688 enum kinds kind;
689};
690
691static bool is_word_sized(struct nct6775_data *data, u16 reg)
692{
693 switch (data->kind) {
694 case nct6775:
695 return (((reg & 0xff00) == 0x100 ||
696 (reg & 0xff00) == 0x200) &&
697 ((reg & 0x00ff) == 0x50 ||
698 (reg & 0x00ff) == 0x53 ||
699 (reg & 0x00ff) == 0x55)) ||
700 (reg & 0xfff0) == 0x630 ||
701 reg == 0x640 || reg == 0x642 ||
702 reg == 0x662 ||
703 ((reg & 0xfff0) == 0x650 && (reg & 0x000f) >= 0x06) ||
704 reg == 0x73 || reg == 0x75 || reg == 0x77;
705 case nct6776:
706 return (((reg & 0xff00) == 0x100 ||
707 (reg & 0xff00) == 0x200) &&
708 ((reg & 0x00ff) == 0x50 ||
709 (reg & 0x00ff) == 0x53 ||
710 (reg & 0x00ff) == 0x55)) ||
711 (reg & 0xfff0) == 0x630 ||
712 reg == 0x402 ||
713 reg == 0x640 || reg == 0x642 ||
714 ((reg & 0xfff0) == 0x650 && (reg & 0x000f) >= 0x06) ||
715 reg == 0x73 || reg == 0x75 || reg == 0x77;
716 case nct6779:
717 return reg == 0x150 || reg == 0x153 || reg == 0x155 ||
718 ((reg & 0xfff0) == 0x4b0 && (reg & 0x000f) < 0x09) ||
719 reg == 0x402 ||
720 reg == 0x63a || reg == 0x63c || reg == 0x63e ||
721 reg == 0x640 || reg == 0x642 ||
722 reg == 0x73 || reg == 0x75 || reg == 0x77 || reg == 0x79 ||
723 reg == 0x7b;
724 }
725 return false;
726}
727
728/*
729 * On older chips, only registers 0x50-0x5f are banked.
730 * On more recent chips, all registers are banked.
731 * Assume that is the case and set the bank number for each access.
732 * Cache the bank number so it only needs to be set if it changes.
733 */
734static inline void nct6775_set_bank(struct nct6775_data *data, u16 reg)
735{
736 u8 bank = reg >> 8;
737 if (data->bank != bank) {
738 outb_p(NCT6775_REG_BANK, data->addr + ADDR_REG_OFFSET);
739 outb_p(bank, data->addr + DATA_REG_OFFSET);
740 data->bank = bank;
741 }
742}
743
744static u16 nct6775_read_value(struct nct6775_data *data, u16 reg)
745{
746 int res, word_sized = is_word_sized(data, reg);
747
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700748 nct6775_set_bank(data, reg);
749 outb_p(reg & 0xff, data->addr + ADDR_REG_OFFSET);
750 res = inb_p(data->addr + DATA_REG_OFFSET);
751 if (word_sized) {
752 outb_p((reg & 0xff) + 1,
753 data->addr + ADDR_REG_OFFSET);
754 res = (res << 8) + inb_p(data->addr + DATA_REG_OFFSET);
755 }
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700756 return res;
757}
758
759static int nct6775_write_value(struct nct6775_data *data, u16 reg, u16 value)
760{
761 int word_sized = is_word_sized(data, reg);
762
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700763 nct6775_set_bank(data, reg);
764 outb_p(reg & 0xff, data->addr + ADDR_REG_OFFSET);
765 if (word_sized) {
766 outb_p(value >> 8, data->addr + DATA_REG_OFFSET);
767 outb_p((reg & 0xff) + 1,
768 data->addr + ADDR_REG_OFFSET);
769 }
770 outb_p(value & 0xff, data->addr + DATA_REG_OFFSET);
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700771 return 0;
772}
773
Guenter Roeckaa136e52012-12-04 03:26:05 -0800774/* We left-align 8-bit temperature values to make the code simpler */
775static u16 nct6775_read_temp(struct nct6775_data *data, u16 reg)
776{
777 u16 res;
778
779 res = nct6775_read_value(data, reg);
780 if (!is_word_sized(data, reg))
781 res <<= 8;
782
783 return res;
784}
785
786static int nct6775_write_temp(struct nct6775_data *data, u16 reg, u16 value)
787{
788 if (!is_word_sized(data, reg))
789 value >>= 8;
790 return nct6775_write_value(data, reg, value);
791}
792
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800793/* This function assumes that the caller holds data->update_lock */
794static void nct6775_write_fan_div(struct nct6775_data *data, int nr)
795{
796 u8 reg;
797
798 switch (nr) {
799 case 0:
800 reg = (nct6775_read_value(data, NCT6775_REG_FANDIV1) & 0x70)
801 | (data->fan_div[0] & 0x7);
802 nct6775_write_value(data, NCT6775_REG_FANDIV1, reg);
803 break;
804 case 1:
805 reg = (nct6775_read_value(data, NCT6775_REG_FANDIV1) & 0x7)
806 | ((data->fan_div[1] << 4) & 0x70);
807 nct6775_write_value(data, NCT6775_REG_FANDIV1, reg);
808 break;
809 case 2:
810 reg = (nct6775_read_value(data, NCT6775_REG_FANDIV2) & 0x70)
811 | (data->fan_div[2] & 0x7);
812 nct6775_write_value(data, NCT6775_REG_FANDIV2, reg);
813 break;
814 case 3:
815 reg = (nct6775_read_value(data, NCT6775_REG_FANDIV2) & 0x7)
816 | ((data->fan_div[3] << 4) & 0x70);
817 nct6775_write_value(data, NCT6775_REG_FANDIV2, reg);
818 break;
819 }
820}
821
822static void nct6775_write_fan_div_common(struct nct6775_data *data, int nr)
823{
824 if (data->kind == nct6775)
825 nct6775_write_fan_div(data, nr);
826}
827
828static void nct6775_update_fan_div(struct nct6775_data *data)
829{
830 u8 i;
831
832 i = nct6775_read_value(data, NCT6775_REG_FANDIV1);
833 data->fan_div[0] = i & 0x7;
834 data->fan_div[1] = (i & 0x70) >> 4;
835 i = nct6775_read_value(data, NCT6775_REG_FANDIV2);
836 data->fan_div[2] = i & 0x7;
Guenter Roeck6445e662013-04-21 09:13:28 -0700837 if (data->has_fan & (1 << 3))
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800838 data->fan_div[3] = (i & 0x70) >> 4;
839}
840
841static void nct6775_update_fan_div_common(struct nct6775_data *data)
842{
843 if (data->kind == nct6775)
844 nct6775_update_fan_div(data);
845}
846
847static void nct6775_init_fan_div(struct nct6775_data *data)
848{
849 int i;
850
851 nct6775_update_fan_div_common(data);
852 /*
853 * For all fans, start with highest divider value if the divider
854 * register is not initialized. This ensures that we get a
855 * reading from the fan count register, even if it is not optimal.
856 * We'll compute a better divider later on.
857 */
Guenter Roeckc409fd42013-04-09 05:04:00 -0700858 for (i = 0; i < ARRAY_SIZE(data->fan_div); i++) {
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800859 if (!(data->has_fan & (1 << i)))
860 continue;
861 if (data->fan_div[i] == 0) {
862 data->fan_div[i] = 7;
863 nct6775_write_fan_div_common(data, i);
864 }
865 }
866}
867
868static void nct6775_init_fan_common(struct device *dev,
869 struct nct6775_data *data)
870{
871 int i;
872 u8 reg;
873
874 if (data->has_fan_div)
875 nct6775_init_fan_div(data);
876
877 /*
878 * If fan_min is not set (0), set it to 0xff to disable it. This
879 * prevents the unnecessary warning when fanX_min is reported as 0.
880 */
Guenter Roeckc409fd42013-04-09 05:04:00 -0700881 for (i = 0; i < ARRAY_SIZE(data->fan_min); i++) {
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800882 if (data->has_fan_min & (1 << i)) {
883 reg = nct6775_read_value(data, data->REG_FAN_MIN[i]);
884 if (!reg)
885 nct6775_write_value(data, data->REG_FAN_MIN[i],
886 data->has_fan_div ? 0xff
887 : 0xff1f);
888 }
889 }
890}
891
892static void nct6775_select_fan_div(struct device *dev,
893 struct nct6775_data *data, int nr, u16 reg)
894{
895 u8 fan_div = data->fan_div[nr];
896 u16 fan_min;
897
898 if (!data->has_fan_div)
899 return;
900
901 /*
902 * If we failed to measure the fan speed, or the reported value is not
903 * in the optimal range, and the clock divider can be modified,
904 * let's try that for next time.
905 */
906 if (reg == 0x00 && fan_div < 0x07)
907 fan_div++;
908 else if (reg != 0x00 && reg < 0x30 && fan_div > 0)
909 fan_div--;
910
911 if (fan_div != data->fan_div[nr]) {
912 dev_dbg(dev, "Modifying fan%d clock divider from %u to %u\n",
913 nr + 1, div_from_reg(data->fan_div[nr]),
914 div_from_reg(fan_div));
915
916 /* Preserve min limit if possible */
917 if (data->has_fan_min & (1 << nr)) {
918 fan_min = data->fan_min[nr];
919 if (fan_div > data->fan_div[nr]) {
920 if (fan_min != 255 && fan_min > 1)
921 fan_min >>= 1;
922 } else {
923 if (fan_min != 255) {
924 fan_min <<= 1;
925 if (fan_min > 254)
926 fan_min = 254;
927 }
928 }
929 if (fan_min != data->fan_min[nr]) {
930 data->fan_min[nr] = fan_min;
931 nct6775_write_value(data, data->REG_FAN_MIN[nr],
932 fan_min);
933 }
934 }
935 data->fan_div[nr] = fan_div;
936 nct6775_write_fan_div_common(data, nr);
937 }
938}
939
Guenter Roeck77eb5b32012-12-04 08:30:54 -0800940static void nct6775_update_pwm(struct device *dev)
941{
942 struct nct6775_data *data = dev_get_drvdata(dev);
943 int i, j;
Guenter Roeckcdcaece2012-12-04 09:04:52 -0800944 int fanmodecfg, reg;
Guenter Roeck77eb5b32012-12-04 08:30:54 -0800945 bool duty_is_dc;
946
947 for (i = 0; i < data->pwm_num; i++) {
948 if (!(data->has_pwm & (1 << i)))
949 continue;
950
951 duty_is_dc = data->REG_PWM_MODE[i] &&
952 (nct6775_read_value(data, data->REG_PWM_MODE[i])
953 & data->PWM_MODE_MASK[i]);
954 data->pwm_mode[i] = duty_is_dc;
955
956 fanmodecfg = nct6775_read_value(data, data->REG_FAN_MODE[i]);
957 for (j = 0; j < ARRAY_SIZE(data->REG_PWM); j++) {
958 if (data->REG_PWM[j] && data->REG_PWM[j][i]) {
959 data->pwm[j][i]
960 = nct6775_read_value(data,
961 data->REG_PWM[j][i]);
962 }
963 }
964
965 data->pwm_enable[i] = reg_to_pwm_enable(data->pwm[0][i],
966 (fanmodecfg >> 4) & 7);
Guenter Roeckcdcaece2012-12-04 09:04:52 -0800967
968 if (!data->temp_tolerance[0][i] ||
969 data->pwm_enable[i] != speed_cruise)
970 data->temp_tolerance[0][i] = fanmodecfg & 0x0f;
971 if (!data->target_speed_tolerance[i] ||
972 data->pwm_enable[i] == speed_cruise) {
973 u8 t = fanmodecfg & 0x0f;
974 if (data->REG_TOLERANCE_H) {
975 t |= (nct6775_read_value(data,
976 data->REG_TOLERANCE_H[i]) & 0x70) >> 1;
977 }
978 data->target_speed_tolerance[i] = t;
979 }
980
981 data->temp_tolerance[1][i] =
982 nct6775_read_value(data,
983 data->REG_CRITICAL_TEMP_TOLERANCE[i]);
984
985 reg = nct6775_read_value(data, data->REG_TEMP_SEL[i]);
986 data->pwm_temp_sel[i] = reg & 0x1f;
987 /* If fan can stop, report floor as 0 */
988 if (reg & 0x80)
989 data->pwm[2][i] = 0;
Guenter Roeckbbd8dec2012-12-04 09:08:29 -0800990
991 reg = nct6775_read_value(data, data->REG_WEIGHT_TEMP_SEL[i]);
992 data->pwm_weight_temp_sel[i] = reg & 0x1f;
993 /* If weight is disabled, report weight source as 0 */
994 if (j == 1 && !(reg & 0x80))
995 data->pwm_weight_temp_sel[i] = 0;
996
997 /* Weight temp data */
Guenter Roeckc409fd42013-04-09 05:04:00 -0700998 for (j = 0; j < ARRAY_SIZE(data->weight_temp); j++) {
Guenter Roeckbbd8dec2012-12-04 09:08:29 -0800999 data->weight_temp[j][i]
1000 = nct6775_read_value(data,
1001 data->REG_WEIGHT_TEMP[j][i]);
1002 }
Guenter Roeckcdcaece2012-12-04 09:04:52 -08001003 }
1004}
1005
1006static void nct6775_update_pwm_limits(struct device *dev)
1007{
1008 struct nct6775_data *data = dev_get_drvdata(dev);
1009 int i, j;
1010 u8 reg;
1011 u16 reg_t;
1012
1013 for (i = 0; i < data->pwm_num; i++) {
1014 if (!(data->has_pwm & (1 << i)))
1015 continue;
1016
Guenter Roeckc409fd42013-04-09 05:04:00 -07001017 for (j = 0; j < ARRAY_SIZE(data->fan_time); j++) {
Guenter Roeckcdcaece2012-12-04 09:04:52 -08001018 data->fan_time[j][i] =
1019 nct6775_read_value(data, data->REG_FAN_TIME[j][i]);
1020 }
1021
1022 reg_t = nct6775_read_value(data, data->REG_TARGET[i]);
1023 /* Update only in matching mode or if never updated */
1024 if (!data->target_temp[i] ||
1025 data->pwm_enable[i] == thermal_cruise)
1026 data->target_temp[i] = reg_t & data->target_temp_mask;
1027 if (!data->target_speed[i] ||
1028 data->pwm_enable[i] == speed_cruise) {
1029 if (data->REG_TOLERANCE_H) {
1030 reg_t |= (nct6775_read_value(data,
1031 data->REG_TOLERANCE_H[i]) & 0x0f) << 8;
1032 }
1033 data->target_speed[i] = reg_t;
1034 }
1035
1036 for (j = 0; j < data->auto_pwm_num; j++) {
1037 data->auto_pwm[i][j] =
1038 nct6775_read_value(data,
1039 NCT6775_AUTO_PWM(data, i, j));
1040 data->auto_temp[i][j] =
1041 nct6775_read_value(data,
1042 NCT6775_AUTO_TEMP(data, i, j));
1043 }
1044
1045 /* critical auto_pwm temperature data */
1046 data->auto_temp[i][data->auto_pwm_num] =
1047 nct6775_read_value(data, data->REG_CRITICAL_TEMP[i]);
1048
1049 switch (data->kind) {
1050 case nct6775:
1051 reg = nct6775_read_value(data,
1052 NCT6775_REG_CRITICAL_ENAB[i]);
1053 data->auto_pwm[i][data->auto_pwm_num] =
1054 (reg & 0x02) ? 0xff : 0x00;
1055 break;
1056 case nct6776:
1057 data->auto_pwm[i][data->auto_pwm_num] = 0xff;
1058 break;
1059 case nct6779:
1060 reg = nct6775_read_value(data,
1061 NCT6779_REG_CRITICAL_PWM_ENABLE[i]);
1062 if (reg & 1)
1063 data->auto_pwm[i][data->auto_pwm_num] =
1064 nct6775_read_value(data,
1065 NCT6779_REG_CRITICAL_PWM[i]);
1066 else
1067 data->auto_pwm[i][data->auto_pwm_num] = 0xff;
1068 break;
1069 }
Guenter Roeck77eb5b32012-12-04 08:30:54 -08001070 }
1071}
1072
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07001073static struct nct6775_data *nct6775_update_device(struct device *dev)
1074{
1075 struct nct6775_data *data = dev_get_drvdata(dev);
Guenter Roeckaa136e52012-12-04 03:26:05 -08001076 int i, j;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07001077
1078 mutex_lock(&data->update_lock);
1079
Guenter Roeck6445e662013-04-21 09:13:28 -07001080 if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07001081 || !data->valid) {
Guenter Roeck1c65dc32012-12-04 07:56:24 -08001082 /* Fan clock dividers */
1083 nct6775_update_fan_div_common(data);
1084
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07001085 /* Measured voltages and limits */
1086 for (i = 0; i < data->in_num; i++) {
1087 if (!(data->have_in & (1 << i)))
1088 continue;
1089
1090 data->in[i][0] = nct6775_read_value(data,
1091 data->REG_VIN[i]);
1092 data->in[i][1] = nct6775_read_value(data,
1093 data->REG_IN_MINMAX[0][i]);
1094 data->in[i][2] = nct6775_read_value(data,
1095 data->REG_IN_MINMAX[1][i]);
1096 }
1097
Guenter Roeck1c65dc32012-12-04 07:56:24 -08001098 /* Measured fan speeds and limits */
Guenter Roeckc409fd42013-04-09 05:04:00 -07001099 for (i = 0; i < ARRAY_SIZE(data->rpm); i++) {
Guenter Roeck1c65dc32012-12-04 07:56:24 -08001100 u16 reg;
1101
1102 if (!(data->has_fan & (1 << i)))
1103 continue;
1104
1105 reg = nct6775_read_value(data, data->REG_FAN[i]);
1106 data->rpm[i] = data->fan_from_reg(reg,
1107 data->fan_div[i]);
1108
1109 if (data->has_fan_min & (1 << i))
1110 data->fan_min[i] = nct6775_read_value(data,
1111 data->REG_FAN_MIN[i]);
Guenter Roeck5c25d952012-12-11 07:29:06 -08001112 data->fan_pulses[i] =
1113 nct6775_read_value(data, data->REG_FAN_PULSES[i]);
Guenter Roeck1c65dc32012-12-04 07:56:24 -08001114
1115 nct6775_select_fan_div(dev, data, i, reg);
1116 }
1117
Guenter Roeck77eb5b32012-12-04 08:30:54 -08001118 nct6775_update_pwm(dev);
Guenter Roeckcdcaece2012-12-04 09:04:52 -08001119 nct6775_update_pwm_limits(dev);
Guenter Roeck77eb5b32012-12-04 08:30:54 -08001120
Guenter Roeckaa136e52012-12-04 03:26:05 -08001121 /* Measured temperatures and limits */
1122 for (i = 0; i < NUM_TEMP; i++) {
1123 if (!(data->have_temp & (1 << i)))
1124 continue;
Guenter Roeckc409fd42013-04-09 05:04:00 -07001125 for (j = 0; j < ARRAY_SIZE(data->reg_temp); j++) {
Guenter Roeckaa136e52012-12-04 03:26:05 -08001126 if (data->reg_temp[j][i])
1127 data->temp[j][i]
1128 = nct6775_read_temp(data,
1129 data->reg_temp[j][i]);
1130 }
1131 if (!(data->have_temp_fixed & (1 << i)))
1132 continue;
1133 data->temp_offset[i]
1134 = nct6775_read_value(data, data->REG_TEMP_OFFSET[i]);
1135 }
1136
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07001137 data->alarms = 0;
1138 for (i = 0; i < NUM_REG_ALARM; i++) {
1139 u8 alarm;
1140 if (!data->REG_ALARM[i])
1141 continue;
1142 alarm = nct6775_read_value(data, data->REG_ALARM[i]);
1143 data->alarms |= ((u64)alarm) << (i << 3);
1144 }
1145
1146 data->last_updated = jiffies;
1147 data->valid = true;
1148 }
1149
1150 mutex_unlock(&data->update_lock);
1151 return data;
1152}
1153
1154/*
1155 * Sysfs callback functions
1156 */
1157static ssize_t
1158show_in_reg(struct device *dev, struct device_attribute *attr, char *buf)
1159{
1160 struct nct6775_data *data = nct6775_update_device(dev);
1161 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
1162 int nr = sattr->nr;
1163 int index = sattr->index;
1164 return sprintf(buf, "%ld\n", in_from_reg(data->in[nr][index], nr));
1165}
1166
1167static ssize_t
1168store_in_reg(struct device *dev, struct device_attribute *attr, const char *buf,
1169 size_t count)
1170{
1171 struct nct6775_data *data = dev_get_drvdata(dev);
1172 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
1173 int nr = sattr->nr;
1174 int index = sattr->index;
1175 unsigned long val;
1176 int err = kstrtoul(buf, 10, &val);
1177 if (err < 0)
1178 return err;
1179 mutex_lock(&data->update_lock);
1180 data->in[nr][index] = in_to_reg(val, nr);
Guenter Roeck6445e662013-04-21 09:13:28 -07001181 nct6775_write_value(data, data->REG_IN_MINMAX[index - 1][nr],
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07001182 data->in[nr][index]);
1183 mutex_unlock(&data->update_lock);
1184 return count;
1185}
1186
1187static ssize_t
1188show_alarm(struct device *dev, struct device_attribute *attr, char *buf)
1189{
1190 struct nct6775_data *data = nct6775_update_device(dev);
1191 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1192 int nr = data->ALARM_BITS[sattr->index];
1193 return sprintf(buf, "%u\n",
1194 (unsigned int)((data->alarms >> nr) & 0x01));
1195}
1196
Guenter Roeckb1d2bff2013-06-22 16:15:31 -07001197static int find_temp_source(struct nct6775_data *data, int index, int count)
1198{
1199 int source = data->temp_src[index];
1200 int nr;
1201
1202 for (nr = 0; nr < count; nr++) {
1203 int src;
1204
1205 src = nct6775_read_value(data,
1206 data->REG_TEMP_SOURCE[nr]) & 0x1f;
1207 if (src == source)
1208 return nr;
1209 }
1210 return -1;
1211}
1212
1213static ssize_t
1214show_temp_alarm(struct device *dev, struct device_attribute *attr, char *buf)
1215{
1216 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1217 struct nct6775_data *data = nct6775_update_device(dev);
1218 unsigned int alarm = 0;
1219 int nr;
1220
1221 /*
1222 * For temperatures, there is no fixed mapping from registers to alarm
1223 * bits. Alarm bits are determined by the temperature source mapping.
1224 */
1225 nr = find_temp_source(data, sattr->index, data->num_temp_alarms);
1226 if (nr >= 0) {
1227 int bit = data->ALARM_BITS[nr + TEMP_ALARM_BASE];
1228 alarm = (data->alarms >> bit) & 0x01;
1229 }
1230 return sprintf(buf, "%u\n", alarm);
1231}
1232
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07001233static SENSOR_DEVICE_ATTR_2(in0_input, S_IRUGO, show_in_reg, NULL, 0, 0);
1234static SENSOR_DEVICE_ATTR_2(in1_input, S_IRUGO, show_in_reg, NULL, 1, 0);
1235static SENSOR_DEVICE_ATTR_2(in2_input, S_IRUGO, show_in_reg, NULL, 2, 0);
1236static SENSOR_DEVICE_ATTR_2(in3_input, S_IRUGO, show_in_reg, NULL, 3, 0);
1237static SENSOR_DEVICE_ATTR_2(in4_input, S_IRUGO, show_in_reg, NULL, 4, 0);
1238static SENSOR_DEVICE_ATTR_2(in5_input, S_IRUGO, show_in_reg, NULL, 5, 0);
1239static SENSOR_DEVICE_ATTR_2(in6_input, S_IRUGO, show_in_reg, NULL, 6, 0);
1240static SENSOR_DEVICE_ATTR_2(in7_input, S_IRUGO, show_in_reg, NULL, 7, 0);
1241static SENSOR_DEVICE_ATTR_2(in8_input, S_IRUGO, show_in_reg, NULL, 8, 0);
1242static SENSOR_DEVICE_ATTR_2(in9_input, S_IRUGO, show_in_reg, NULL, 9, 0);
1243static SENSOR_DEVICE_ATTR_2(in10_input, S_IRUGO, show_in_reg, NULL, 10, 0);
1244static SENSOR_DEVICE_ATTR_2(in11_input, S_IRUGO, show_in_reg, NULL, 11, 0);
1245static SENSOR_DEVICE_ATTR_2(in12_input, S_IRUGO, show_in_reg, NULL, 12, 0);
1246static SENSOR_DEVICE_ATTR_2(in13_input, S_IRUGO, show_in_reg, NULL, 13, 0);
1247static SENSOR_DEVICE_ATTR_2(in14_input, S_IRUGO, show_in_reg, NULL, 14, 0);
1248
1249static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0);
1250static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1);
1251static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 2);
1252static SENSOR_DEVICE_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, 3);
1253static SENSOR_DEVICE_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, 4);
1254static SENSOR_DEVICE_ATTR(in5_alarm, S_IRUGO, show_alarm, NULL, 5);
1255static SENSOR_DEVICE_ATTR(in6_alarm, S_IRUGO, show_alarm, NULL, 6);
1256static SENSOR_DEVICE_ATTR(in7_alarm, S_IRUGO, show_alarm, NULL, 7);
1257static SENSOR_DEVICE_ATTR(in8_alarm, S_IRUGO, show_alarm, NULL, 8);
1258static SENSOR_DEVICE_ATTR(in9_alarm, S_IRUGO, show_alarm, NULL, 9);
1259static SENSOR_DEVICE_ATTR(in10_alarm, S_IRUGO, show_alarm, NULL, 10);
1260static SENSOR_DEVICE_ATTR(in11_alarm, S_IRUGO, show_alarm, NULL, 11);
1261static SENSOR_DEVICE_ATTR(in12_alarm, S_IRUGO, show_alarm, NULL, 12);
1262static SENSOR_DEVICE_ATTR(in13_alarm, S_IRUGO, show_alarm, NULL, 13);
1263static SENSOR_DEVICE_ATTR(in14_alarm, S_IRUGO, show_alarm, NULL, 14);
1264
1265static SENSOR_DEVICE_ATTR_2(in0_min, S_IWUSR | S_IRUGO, show_in_reg,
1266 store_in_reg, 0, 1);
1267static SENSOR_DEVICE_ATTR_2(in1_min, S_IWUSR | S_IRUGO, show_in_reg,
1268 store_in_reg, 1, 1);
1269static SENSOR_DEVICE_ATTR_2(in2_min, S_IWUSR | S_IRUGO, show_in_reg,
1270 store_in_reg, 2, 1);
1271static SENSOR_DEVICE_ATTR_2(in3_min, S_IWUSR | S_IRUGO, show_in_reg,
1272 store_in_reg, 3, 1);
1273static SENSOR_DEVICE_ATTR_2(in4_min, S_IWUSR | S_IRUGO, show_in_reg,
1274 store_in_reg, 4, 1);
1275static SENSOR_DEVICE_ATTR_2(in5_min, S_IWUSR | S_IRUGO, show_in_reg,
1276 store_in_reg, 5, 1);
1277static SENSOR_DEVICE_ATTR_2(in6_min, S_IWUSR | S_IRUGO, show_in_reg,
1278 store_in_reg, 6, 1);
1279static SENSOR_DEVICE_ATTR_2(in7_min, S_IWUSR | S_IRUGO, show_in_reg,
1280 store_in_reg, 7, 1);
1281static SENSOR_DEVICE_ATTR_2(in8_min, S_IWUSR | S_IRUGO, show_in_reg,
1282 store_in_reg, 8, 1);
1283static SENSOR_DEVICE_ATTR_2(in9_min, S_IWUSR | S_IRUGO, show_in_reg,
1284 store_in_reg, 9, 1);
1285static SENSOR_DEVICE_ATTR_2(in10_min, S_IWUSR | S_IRUGO, show_in_reg,
1286 store_in_reg, 10, 1);
1287static SENSOR_DEVICE_ATTR_2(in11_min, S_IWUSR | S_IRUGO, show_in_reg,
1288 store_in_reg, 11, 1);
1289static SENSOR_DEVICE_ATTR_2(in12_min, S_IWUSR | S_IRUGO, show_in_reg,
1290 store_in_reg, 12, 1);
1291static SENSOR_DEVICE_ATTR_2(in13_min, S_IWUSR | S_IRUGO, show_in_reg,
1292 store_in_reg, 13, 1);
1293static SENSOR_DEVICE_ATTR_2(in14_min, S_IWUSR | S_IRUGO, show_in_reg,
1294 store_in_reg, 14, 1);
1295
1296static SENSOR_DEVICE_ATTR_2(in0_max, S_IWUSR | S_IRUGO, show_in_reg,
1297 store_in_reg, 0, 2);
1298static SENSOR_DEVICE_ATTR_2(in1_max, S_IWUSR | S_IRUGO, show_in_reg,
1299 store_in_reg, 1, 2);
1300static SENSOR_DEVICE_ATTR_2(in2_max, S_IWUSR | S_IRUGO, show_in_reg,
1301 store_in_reg, 2, 2);
1302static SENSOR_DEVICE_ATTR_2(in3_max, S_IWUSR | S_IRUGO, show_in_reg,
1303 store_in_reg, 3, 2);
1304static SENSOR_DEVICE_ATTR_2(in4_max, S_IWUSR | S_IRUGO, show_in_reg,
1305 store_in_reg, 4, 2);
1306static SENSOR_DEVICE_ATTR_2(in5_max, S_IWUSR | S_IRUGO, show_in_reg,
1307 store_in_reg, 5, 2);
1308static SENSOR_DEVICE_ATTR_2(in6_max, S_IWUSR | S_IRUGO, show_in_reg,
1309 store_in_reg, 6, 2);
1310static SENSOR_DEVICE_ATTR_2(in7_max, S_IWUSR | S_IRUGO, show_in_reg,
1311 store_in_reg, 7, 2);
1312static SENSOR_DEVICE_ATTR_2(in8_max, S_IWUSR | S_IRUGO, show_in_reg,
1313 store_in_reg, 8, 2);
1314static SENSOR_DEVICE_ATTR_2(in9_max, S_IWUSR | S_IRUGO, show_in_reg,
1315 store_in_reg, 9, 2);
1316static SENSOR_DEVICE_ATTR_2(in10_max, S_IWUSR | S_IRUGO, show_in_reg,
1317 store_in_reg, 10, 2);
1318static SENSOR_DEVICE_ATTR_2(in11_max, S_IWUSR | S_IRUGO, show_in_reg,
1319 store_in_reg, 11, 2);
1320static SENSOR_DEVICE_ATTR_2(in12_max, S_IWUSR | S_IRUGO, show_in_reg,
1321 store_in_reg, 12, 2);
1322static SENSOR_DEVICE_ATTR_2(in13_max, S_IWUSR | S_IRUGO, show_in_reg,
1323 store_in_reg, 13, 2);
1324static SENSOR_DEVICE_ATTR_2(in14_max, S_IWUSR | S_IRUGO, show_in_reg,
1325 store_in_reg, 14, 2);
1326
1327static struct attribute *nct6775_attributes_in[15][5] = {
1328 {
1329 &sensor_dev_attr_in0_input.dev_attr.attr,
1330 &sensor_dev_attr_in0_min.dev_attr.attr,
1331 &sensor_dev_attr_in0_max.dev_attr.attr,
1332 &sensor_dev_attr_in0_alarm.dev_attr.attr,
1333 NULL
1334 },
1335 {
1336 &sensor_dev_attr_in1_input.dev_attr.attr,
1337 &sensor_dev_attr_in1_min.dev_attr.attr,
1338 &sensor_dev_attr_in1_max.dev_attr.attr,
1339 &sensor_dev_attr_in1_alarm.dev_attr.attr,
1340 NULL
1341 },
1342 {
1343 &sensor_dev_attr_in2_input.dev_attr.attr,
1344 &sensor_dev_attr_in2_min.dev_attr.attr,
1345 &sensor_dev_attr_in2_max.dev_attr.attr,
1346 &sensor_dev_attr_in2_alarm.dev_attr.attr,
1347 NULL
1348 },
1349 {
1350 &sensor_dev_attr_in3_input.dev_attr.attr,
1351 &sensor_dev_attr_in3_min.dev_attr.attr,
1352 &sensor_dev_attr_in3_max.dev_attr.attr,
1353 &sensor_dev_attr_in3_alarm.dev_attr.attr,
1354 NULL
1355 },
1356 {
1357 &sensor_dev_attr_in4_input.dev_attr.attr,
1358 &sensor_dev_attr_in4_min.dev_attr.attr,
1359 &sensor_dev_attr_in4_max.dev_attr.attr,
1360 &sensor_dev_attr_in4_alarm.dev_attr.attr,
1361 NULL
1362 },
1363 {
1364 &sensor_dev_attr_in5_input.dev_attr.attr,
1365 &sensor_dev_attr_in5_min.dev_attr.attr,
1366 &sensor_dev_attr_in5_max.dev_attr.attr,
1367 &sensor_dev_attr_in5_alarm.dev_attr.attr,
1368 NULL
1369 },
1370 {
1371 &sensor_dev_attr_in6_input.dev_attr.attr,
1372 &sensor_dev_attr_in6_min.dev_attr.attr,
1373 &sensor_dev_attr_in6_max.dev_attr.attr,
1374 &sensor_dev_attr_in6_alarm.dev_attr.attr,
1375 NULL
1376 },
1377 {
1378 &sensor_dev_attr_in7_input.dev_attr.attr,
1379 &sensor_dev_attr_in7_min.dev_attr.attr,
1380 &sensor_dev_attr_in7_max.dev_attr.attr,
1381 &sensor_dev_attr_in7_alarm.dev_attr.attr,
1382 NULL
1383 },
1384 {
1385 &sensor_dev_attr_in8_input.dev_attr.attr,
1386 &sensor_dev_attr_in8_min.dev_attr.attr,
1387 &sensor_dev_attr_in8_max.dev_attr.attr,
1388 &sensor_dev_attr_in8_alarm.dev_attr.attr,
1389 NULL
1390 },
1391 {
1392 &sensor_dev_attr_in9_input.dev_attr.attr,
1393 &sensor_dev_attr_in9_min.dev_attr.attr,
1394 &sensor_dev_attr_in9_max.dev_attr.attr,
1395 &sensor_dev_attr_in9_alarm.dev_attr.attr,
1396 NULL
1397 },
1398 {
1399 &sensor_dev_attr_in10_input.dev_attr.attr,
1400 &sensor_dev_attr_in10_min.dev_attr.attr,
1401 &sensor_dev_attr_in10_max.dev_attr.attr,
1402 &sensor_dev_attr_in10_alarm.dev_attr.attr,
1403 NULL
1404 },
1405 {
1406 &sensor_dev_attr_in11_input.dev_attr.attr,
1407 &sensor_dev_attr_in11_min.dev_attr.attr,
1408 &sensor_dev_attr_in11_max.dev_attr.attr,
1409 &sensor_dev_attr_in11_alarm.dev_attr.attr,
1410 NULL
1411 },
1412 {
1413 &sensor_dev_attr_in12_input.dev_attr.attr,
1414 &sensor_dev_attr_in12_min.dev_attr.attr,
1415 &sensor_dev_attr_in12_max.dev_attr.attr,
1416 &sensor_dev_attr_in12_alarm.dev_attr.attr,
1417 NULL
1418 },
1419 {
1420 &sensor_dev_attr_in13_input.dev_attr.attr,
1421 &sensor_dev_attr_in13_min.dev_attr.attr,
1422 &sensor_dev_attr_in13_max.dev_attr.attr,
1423 &sensor_dev_attr_in13_alarm.dev_attr.attr,
1424 NULL
1425 },
1426 {
1427 &sensor_dev_attr_in14_input.dev_attr.attr,
1428 &sensor_dev_attr_in14_min.dev_attr.attr,
1429 &sensor_dev_attr_in14_max.dev_attr.attr,
1430 &sensor_dev_attr_in14_alarm.dev_attr.attr,
1431 NULL
1432 },
1433};
1434
1435static const struct attribute_group nct6775_group_in[15] = {
1436 { .attrs = nct6775_attributes_in[0] },
1437 { .attrs = nct6775_attributes_in[1] },
1438 { .attrs = nct6775_attributes_in[2] },
1439 { .attrs = nct6775_attributes_in[3] },
1440 { .attrs = nct6775_attributes_in[4] },
1441 { .attrs = nct6775_attributes_in[5] },
1442 { .attrs = nct6775_attributes_in[6] },
1443 { .attrs = nct6775_attributes_in[7] },
1444 { .attrs = nct6775_attributes_in[8] },
1445 { .attrs = nct6775_attributes_in[9] },
1446 { .attrs = nct6775_attributes_in[10] },
1447 { .attrs = nct6775_attributes_in[11] },
1448 { .attrs = nct6775_attributes_in[12] },
1449 { .attrs = nct6775_attributes_in[13] },
1450 { .attrs = nct6775_attributes_in[14] },
1451};
1452
1453static ssize_t
Guenter Roeck1c65dc32012-12-04 07:56:24 -08001454show_fan(struct device *dev, struct device_attribute *attr, char *buf)
1455{
1456 struct nct6775_data *data = nct6775_update_device(dev);
1457 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1458 int nr = sattr->index;
1459 return sprintf(buf, "%d\n", data->rpm[nr]);
1460}
1461
1462static ssize_t
1463show_fan_min(struct device *dev, struct device_attribute *attr, char *buf)
1464{
1465 struct nct6775_data *data = nct6775_update_device(dev);
1466 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1467 int nr = sattr->index;
1468 return sprintf(buf, "%d\n",
1469 data->fan_from_reg_min(data->fan_min[nr],
1470 data->fan_div[nr]));
1471}
1472
1473static ssize_t
1474show_fan_div(struct device *dev, struct device_attribute *attr, char *buf)
1475{
1476 struct nct6775_data *data = nct6775_update_device(dev);
1477 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1478 int nr = sattr->index;
1479 return sprintf(buf, "%u\n", div_from_reg(data->fan_div[nr]));
1480}
1481
1482static ssize_t
1483store_fan_min(struct device *dev, struct device_attribute *attr,
1484 const char *buf, size_t count)
1485{
1486 struct nct6775_data *data = dev_get_drvdata(dev);
1487 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1488 int nr = sattr->index;
1489 unsigned long val;
1490 int err;
1491 unsigned int reg;
1492 u8 new_div;
1493
1494 err = kstrtoul(buf, 10, &val);
1495 if (err < 0)
1496 return err;
1497
1498 mutex_lock(&data->update_lock);
1499 if (!data->has_fan_div) {
1500 /* NCT6776F or NCT6779D; we know this is a 13 bit register */
1501 if (!val) {
1502 val = 0xff1f;
1503 } else {
1504 if (val > 1350000U)
1505 val = 135000U;
1506 val = 1350000U / val;
1507 val = (val & 0x1f) | ((val << 3) & 0xff00);
1508 }
1509 data->fan_min[nr] = val;
1510 goto write_min; /* Leave fan divider alone */
1511 }
1512 if (!val) {
1513 /* No min limit, alarm disabled */
1514 data->fan_min[nr] = 255;
1515 new_div = data->fan_div[nr]; /* No change */
1516 dev_info(dev, "fan%u low limit and alarm disabled\n", nr + 1);
1517 goto write_div;
1518 }
1519 reg = 1350000U / val;
1520 if (reg >= 128 * 255) {
1521 /*
1522 * Speed below this value cannot possibly be represented,
1523 * even with the highest divider (128)
1524 */
1525 data->fan_min[nr] = 254;
1526 new_div = 7; /* 128 == (1 << 7) */
1527 dev_warn(dev,
1528 "fan%u low limit %lu below minimum %u, set to minimum\n",
1529 nr + 1, val, data->fan_from_reg_min(254, 7));
1530 } else if (!reg) {
1531 /*
1532 * Speed above this value cannot possibly be represented,
1533 * even with the lowest divider (1)
1534 */
1535 data->fan_min[nr] = 1;
1536 new_div = 0; /* 1 == (1 << 0) */
1537 dev_warn(dev,
1538 "fan%u low limit %lu above maximum %u, set to maximum\n",
1539 nr + 1, val, data->fan_from_reg_min(1, 0));
1540 } else {
1541 /*
1542 * Automatically pick the best divider, i.e. the one such
1543 * that the min limit will correspond to a register value
1544 * in the 96..192 range
1545 */
1546 new_div = 0;
1547 while (reg > 192 && new_div < 7) {
1548 reg >>= 1;
1549 new_div++;
1550 }
1551 data->fan_min[nr] = reg;
1552 }
1553
1554write_div:
1555 /*
1556 * Write both the fan clock divider (if it changed) and the new
1557 * fan min (unconditionally)
1558 */
1559 if (new_div != data->fan_div[nr]) {
1560 dev_dbg(dev, "fan%u clock divider changed from %u to %u\n",
1561 nr + 1, div_from_reg(data->fan_div[nr]),
1562 div_from_reg(new_div));
1563 data->fan_div[nr] = new_div;
1564 nct6775_write_fan_div_common(data, nr);
1565 /* Give the chip time to sample a new speed value */
1566 data->last_updated = jiffies;
1567 }
1568
1569write_min:
1570 nct6775_write_value(data, data->REG_FAN_MIN[nr], data->fan_min[nr]);
1571 mutex_unlock(&data->update_lock);
1572
1573 return count;
1574}
1575
Guenter Roeck5c25d952012-12-11 07:29:06 -08001576static ssize_t
1577show_fan_pulses(struct device *dev, struct device_attribute *attr, char *buf)
1578{
1579 struct nct6775_data *data = nct6775_update_device(dev);
1580 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1581 int p = data->fan_pulses[sattr->index];
1582
1583 return sprintf(buf, "%d\n", p ? : 4);
1584}
1585
1586static ssize_t
1587store_fan_pulses(struct device *dev, struct device_attribute *attr,
1588 const char *buf, size_t count)
1589{
1590 struct nct6775_data *data = dev_get_drvdata(dev);
1591 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1592 int nr = sattr->index;
1593 unsigned long val;
1594 int err;
1595
1596 err = kstrtoul(buf, 10, &val);
1597 if (err < 0)
1598 return err;
1599
1600 if (val > 4)
1601 return -EINVAL;
1602
1603 mutex_lock(&data->update_lock);
1604 data->fan_pulses[nr] = val & 3;
1605 nct6775_write_value(data, data->REG_FAN_PULSES[nr], val & 3);
1606 mutex_unlock(&data->update_lock);
1607
1608 return count;
1609}
1610
Guenter Roeck1c65dc32012-12-04 07:56:24 -08001611static struct sensor_device_attribute sda_fan_input[] = {
1612 SENSOR_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0),
1613 SENSOR_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1),
1614 SENSOR_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2),
1615 SENSOR_ATTR(fan4_input, S_IRUGO, show_fan, NULL, 3),
1616 SENSOR_ATTR(fan5_input, S_IRUGO, show_fan, NULL, 4),
1617};
1618
1619static struct sensor_device_attribute sda_fan_alarm[] = {
1620 SENSOR_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, FAN_ALARM_BASE),
1621 SENSOR_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, FAN_ALARM_BASE + 1),
1622 SENSOR_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL, FAN_ALARM_BASE + 2),
1623 SENSOR_ATTR(fan4_alarm, S_IRUGO, show_alarm, NULL, FAN_ALARM_BASE + 3),
1624 SENSOR_ATTR(fan5_alarm, S_IRUGO, show_alarm, NULL, FAN_ALARM_BASE + 4),
1625};
1626
1627static struct sensor_device_attribute sda_fan_min[] = {
1628 SENSOR_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan_min,
1629 store_fan_min, 0),
1630 SENSOR_ATTR(fan2_min, S_IWUSR | S_IRUGO, show_fan_min,
1631 store_fan_min, 1),
1632 SENSOR_ATTR(fan3_min, S_IWUSR | S_IRUGO, show_fan_min,
1633 store_fan_min, 2),
1634 SENSOR_ATTR(fan4_min, S_IWUSR | S_IRUGO, show_fan_min,
1635 store_fan_min, 3),
1636 SENSOR_ATTR(fan5_min, S_IWUSR | S_IRUGO, show_fan_min,
1637 store_fan_min, 4),
1638};
1639
Guenter Roeck5c25d952012-12-11 07:29:06 -08001640static struct sensor_device_attribute sda_fan_pulses[] = {
1641 SENSOR_ATTR(fan1_pulses, S_IWUSR | S_IRUGO, show_fan_pulses,
1642 store_fan_pulses, 0),
1643 SENSOR_ATTR(fan2_pulses, S_IWUSR | S_IRUGO, show_fan_pulses,
1644 store_fan_pulses, 1),
1645 SENSOR_ATTR(fan3_pulses, S_IWUSR | S_IRUGO, show_fan_pulses,
1646 store_fan_pulses, 2),
1647 SENSOR_ATTR(fan4_pulses, S_IWUSR | S_IRUGO, show_fan_pulses,
1648 store_fan_pulses, 3),
1649 SENSOR_ATTR(fan5_pulses, S_IWUSR | S_IRUGO, show_fan_pulses,
1650 store_fan_pulses, 4),
1651};
1652
Guenter Roeck1c65dc32012-12-04 07:56:24 -08001653static struct sensor_device_attribute sda_fan_div[] = {
1654 SENSOR_ATTR(fan1_div, S_IRUGO, show_fan_div, NULL, 0),
1655 SENSOR_ATTR(fan2_div, S_IRUGO, show_fan_div, NULL, 1),
1656 SENSOR_ATTR(fan3_div, S_IRUGO, show_fan_div, NULL, 2),
1657 SENSOR_ATTR(fan4_div, S_IRUGO, show_fan_div, NULL, 3),
1658 SENSOR_ATTR(fan5_div, S_IRUGO, show_fan_div, NULL, 4),
1659};
1660
1661static ssize_t
Guenter Roeckaa136e52012-12-04 03:26:05 -08001662show_temp_label(struct device *dev, struct device_attribute *attr, char *buf)
1663{
1664 struct nct6775_data *data = nct6775_update_device(dev);
1665 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1666 int nr = sattr->index;
1667 return sprintf(buf, "%s\n", data->temp_label[data->temp_src[nr]]);
1668}
1669
1670static ssize_t
1671show_temp(struct device *dev, struct device_attribute *attr, char *buf)
1672{
1673 struct nct6775_data *data = nct6775_update_device(dev);
1674 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
1675 int nr = sattr->nr;
1676 int index = sattr->index;
1677
1678 return sprintf(buf, "%d\n", LM75_TEMP_FROM_REG(data->temp[index][nr]));
1679}
1680
1681static ssize_t
1682store_temp(struct device *dev, struct device_attribute *attr, const char *buf,
1683 size_t count)
1684{
1685 struct nct6775_data *data = dev_get_drvdata(dev);
1686 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
1687 int nr = sattr->nr;
1688 int index = sattr->index;
1689 int err;
1690 long val;
1691
1692 err = kstrtol(buf, 10, &val);
1693 if (err < 0)
1694 return err;
1695
1696 mutex_lock(&data->update_lock);
1697 data->temp[index][nr] = LM75_TEMP_TO_REG(val);
1698 nct6775_write_temp(data, data->reg_temp[index][nr],
1699 data->temp[index][nr]);
1700 mutex_unlock(&data->update_lock);
1701 return count;
1702}
1703
1704static ssize_t
1705show_temp_offset(struct device *dev, struct device_attribute *attr, char *buf)
1706{
1707 struct nct6775_data *data = nct6775_update_device(dev);
1708 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1709
1710 return sprintf(buf, "%d\n", data->temp_offset[sattr->index] * 1000);
1711}
1712
1713static ssize_t
1714store_temp_offset(struct device *dev, struct device_attribute *attr,
1715 const char *buf, size_t count)
1716{
1717 struct nct6775_data *data = dev_get_drvdata(dev);
1718 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1719 int nr = sattr->index;
1720 long val;
1721 int err;
1722
1723 err = kstrtol(buf, 10, &val);
1724 if (err < 0)
1725 return err;
1726
1727 val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), -128, 127);
1728
1729 mutex_lock(&data->update_lock);
1730 data->temp_offset[nr] = val;
1731 nct6775_write_value(data, data->REG_TEMP_OFFSET[nr], val);
1732 mutex_unlock(&data->update_lock);
1733
1734 return count;
1735}
1736
1737static ssize_t
1738show_temp_type(struct device *dev, struct device_attribute *attr, char *buf)
1739{
1740 struct nct6775_data *data = nct6775_update_device(dev);
1741 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1742 int nr = sattr->index;
1743 return sprintf(buf, "%d\n", (int)data->temp_type[nr]);
1744}
1745
1746static ssize_t
1747store_temp_type(struct device *dev, struct device_attribute *attr,
1748 const char *buf, size_t count)
1749{
1750 struct nct6775_data *data = nct6775_update_device(dev);
1751 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1752 int nr = sattr->index;
1753 unsigned long val;
1754 int err;
1755 u8 vbat, diode, bit;
1756
1757 err = kstrtoul(buf, 10, &val);
1758 if (err < 0)
1759 return err;
1760
1761 if (val != 1 && val != 3 && val != 4)
1762 return -EINVAL;
1763
1764 mutex_lock(&data->update_lock);
1765
1766 data->temp_type[nr] = val;
1767 vbat = nct6775_read_value(data, data->REG_VBAT) & ~(0x02 << nr);
1768 diode = nct6775_read_value(data, data->REG_DIODE) & ~(0x02 << nr);
1769 bit = 0x02 << nr;
1770 switch (val) {
1771 case 1: /* CPU diode (diode, current mode) */
1772 vbat |= bit;
1773 diode |= bit;
1774 break;
1775 case 3: /* diode, voltage mode */
1776 vbat |= bit;
1777 break;
1778 case 4: /* thermistor */
1779 break;
1780 }
1781 nct6775_write_value(data, data->REG_VBAT, vbat);
1782 nct6775_write_value(data, data->REG_DIODE, diode);
1783
1784 mutex_unlock(&data->update_lock);
1785 return count;
1786}
1787
1788static struct sensor_device_attribute_2 sda_temp_input[] = {
1789 SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0),
1790 SENSOR_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 1, 0),
1791 SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 2, 0),
1792 SENSOR_ATTR_2(temp4_input, S_IRUGO, show_temp, NULL, 3, 0),
1793 SENSOR_ATTR_2(temp5_input, S_IRUGO, show_temp, NULL, 4, 0),
1794 SENSOR_ATTR_2(temp6_input, S_IRUGO, show_temp, NULL, 5, 0),
1795 SENSOR_ATTR_2(temp7_input, S_IRUGO, show_temp, NULL, 6, 0),
1796 SENSOR_ATTR_2(temp8_input, S_IRUGO, show_temp, NULL, 7, 0),
1797 SENSOR_ATTR_2(temp9_input, S_IRUGO, show_temp, NULL, 8, 0),
1798 SENSOR_ATTR_2(temp10_input, S_IRUGO, show_temp, NULL, 9, 0),
1799};
1800
1801static struct sensor_device_attribute sda_temp_label[] = {
1802 SENSOR_ATTR(temp1_label, S_IRUGO, show_temp_label, NULL, 0),
1803 SENSOR_ATTR(temp2_label, S_IRUGO, show_temp_label, NULL, 1),
1804 SENSOR_ATTR(temp3_label, S_IRUGO, show_temp_label, NULL, 2),
1805 SENSOR_ATTR(temp4_label, S_IRUGO, show_temp_label, NULL, 3),
1806 SENSOR_ATTR(temp5_label, S_IRUGO, show_temp_label, NULL, 4),
1807 SENSOR_ATTR(temp6_label, S_IRUGO, show_temp_label, NULL, 5),
1808 SENSOR_ATTR(temp7_label, S_IRUGO, show_temp_label, NULL, 6),
1809 SENSOR_ATTR(temp8_label, S_IRUGO, show_temp_label, NULL, 7),
1810 SENSOR_ATTR(temp9_label, S_IRUGO, show_temp_label, NULL, 8),
1811 SENSOR_ATTR(temp10_label, S_IRUGO, show_temp_label, NULL, 9),
1812};
1813
1814static struct sensor_device_attribute_2 sda_temp_max[] = {
1815 SENSOR_ATTR_2(temp1_max, S_IRUGO | S_IWUSR, show_temp, store_temp,
1816 0, 1),
1817 SENSOR_ATTR_2(temp2_max, S_IRUGO | S_IWUSR, show_temp, store_temp,
1818 1, 1),
1819 SENSOR_ATTR_2(temp3_max, S_IRUGO | S_IWUSR, show_temp, store_temp,
1820 2, 1),
1821 SENSOR_ATTR_2(temp4_max, S_IRUGO | S_IWUSR, show_temp, store_temp,
1822 3, 1),
1823 SENSOR_ATTR_2(temp5_max, S_IRUGO | S_IWUSR, show_temp, store_temp,
1824 4, 1),
1825 SENSOR_ATTR_2(temp6_max, S_IRUGO | S_IWUSR, show_temp, store_temp,
1826 5, 1),
1827 SENSOR_ATTR_2(temp7_max, S_IRUGO | S_IWUSR, show_temp, store_temp,
1828 6, 1),
1829 SENSOR_ATTR_2(temp8_max, S_IRUGO | S_IWUSR, show_temp, store_temp,
1830 7, 1),
1831 SENSOR_ATTR_2(temp9_max, S_IRUGO | S_IWUSR, show_temp, store_temp,
1832 8, 1),
1833 SENSOR_ATTR_2(temp10_max, S_IRUGO | S_IWUSR, show_temp, store_temp,
1834 9, 1),
1835};
1836
1837static struct sensor_device_attribute_2 sda_temp_max_hyst[] = {
1838 SENSOR_ATTR_2(temp1_max_hyst, S_IRUGO | S_IWUSR, show_temp, store_temp,
1839 0, 2),
1840 SENSOR_ATTR_2(temp2_max_hyst, S_IRUGO | S_IWUSR, show_temp, store_temp,
1841 1, 2),
1842 SENSOR_ATTR_2(temp3_max_hyst, S_IRUGO | S_IWUSR, show_temp, store_temp,
1843 2, 2),
1844 SENSOR_ATTR_2(temp4_max_hyst, S_IRUGO | S_IWUSR, show_temp, store_temp,
1845 3, 2),
1846 SENSOR_ATTR_2(temp5_max_hyst, S_IRUGO | S_IWUSR, show_temp, store_temp,
1847 4, 2),
1848 SENSOR_ATTR_2(temp6_max_hyst, S_IRUGO | S_IWUSR, show_temp, store_temp,
1849 5, 2),
1850 SENSOR_ATTR_2(temp7_max_hyst, S_IRUGO | S_IWUSR, show_temp, store_temp,
1851 6, 2),
1852 SENSOR_ATTR_2(temp8_max_hyst, S_IRUGO | S_IWUSR, show_temp, store_temp,
1853 7, 2),
1854 SENSOR_ATTR_2(temp9_max_hyst, S_IRUGO | S_IWUSR, show_temp, store_temp,
1855 8, 2),
1856 SENSOR_ATTR_2(temp10_max_hyst, S_IRUGO | S_IWUSR, show_temp, store_temp,
1857 9, 2),
1858};
1859
1860static struct sensor_device_attribute_2 sda_temp_crit[] = {
1861 SENSOR_ATTR_2(temp1_crit, S_IRUGO | S_IWUSR, show_temp, store_temp,
1862 0, 3),
1863 SENSOR_ATTR_2(temp2_crit, S_IRUGO | S_IWUSR, show_temp, store_temp,
1864 1, 3),
1865 SENSOR_ATTR_2(temp3_crit, S_IRUGO | S_IWUSR, show_temp, store_temp,
1866 2, 3),
1867 SENSOR_ATTR_2(temp4_crit, S_IRUGO | S_IWUSR, show_temp, store_temp,
1868 3, 3),
1869 SENSOR_ATTR_2(temp5_crit, S_IRUGO | S_IWUSR, show_temp, store_temp,
1870 4, 3),
1871 SENSOR_ATTR_2(temp6_crit, S_IRUGO | S_IWUSR, show_temp, store_temp,
1872 5, 3),
1873 SENSOR_ATTR_2(temp7_crit, S_IRUGO | S_IWUSR, show_temp, store_temp,
1874 6, 3),
1875 SENSOR_ATTR_2(temp8_crit, S_IRUGO | S_IWUSR, show_temp, store_temp,
1876 7, 3),
1877 SENSOR_ATTR_2(temp9_crit, S_IRUGO | S_IWUSR, show_temp, store_temp,
1878 8, 3),
1879 SENSOR_ATTR_2(temp10_crit, S_IRUGO | S_IWUSR, show_temp, store_temp,
1880 9, 3),
1881};
1882
1883static struct sensor_device_attribute sda_temp_offset[] = {
1884 SENSOR_ATTR(temp1_offset, S_IRUGO | S_IWUSR, show_temp_offset,
1885 store_temp_offset, 0),
1886 SENSOR_ATTR(temp2_offset, S_IRUGO | S_IWUSR, show_temp_offset,
1887 store_temp_offset, 1),
1888 SENSOR_ATTR(temp3_offset, S_IRUGO | S_IWUSR, show_temp_offset,
1889 store_temp_offset, 2),
1890 SENSOR_ATTR(temp4_offset, S_IRUGO | S_IWUSR, show_temp_offset,
1891 store_temp_offset, 3),
1892 SENSOR_ATTR(temp5_offset, S_IRUGO | S_IWUSR, show_temp_offset,
1893 store_temp_offset, 4),
1894 SENSOR_ATTR(temp6_offset, S_IRUGO | S_IWUSR, show_temp_offset,
1895 store_temp_offset, 5),
1896};
1897
1898static struct sensor_device_attribute sda_temp_type[] = {
1899 SENSOR_ATTR(temp1_type, S_IRUGO | S_IWUSR, show_temp_type,
1900 store_temp_type, 0),
1901 SENSOR_ATTR(temp2_type, S_IRUGO | S_IWUSR, show_temp_type,
1902 store_temp_type, 1),
1903 SENSOR_ATTR(temp3_type, S_IRUGO | S_IWUSR, show_temp_type,
1904 store_temp_type, 2),
1905 SENSOR_ATTR(temp4_type, S_IRUGO | S_IWUSR, show_temp_type,
1906 store_temp_type, 3),
1907 SENSOR_ATTR(temp5_type, S_IRUGO | S_IWUSR, show_temp_type,
1908 store_temp_type, 4),
1909 SENSOR_ATTR(temp6_type, S_IRUGO | S_IWUSR, show_temp_type,
1910 store_temp_type, 5),
1911};
1912
1913static struct sensor_device_attribute sda_temp_alarm[] = {
Guenter Roeckb1d2bff2013-06-22 16:15:31 -07001914 SENSOR_ATTR(temp1_alarm, S_IRUGO, show_temp_alarm, NULL, 0),
1915 SENSOR_ATTR(temp2_alarm, S_IRUGO, show_temp_alarm, NULL, 1),
1916 SENSOR_ATTR(temp3_alarm, S_IRUGO, show_temp_alarm, NULL, 2),
1917 SENSOR_ATTR(temp4_alarm, S_IRUGO, show_temp_alarm, NULL, 3),
1918 SENSOR_ATTR(temp5_alarm, S_IRUGO, show_temp_alarm, NULL, 4),
1919 SENSOR_ATTR(temp6_alarm, S_IRUGO, show_temp_alarm, NULL, 5),
1920 SENSOR_ATTR(temp7_alarm, S_IRUGO, show_temp_alarm, NULL, 6),
1921 SENSOR_ATTR(temp8_alarm, S_IRUGO, show_temp_alarm, NULL, 7),
1922 SENSOR_ATTR(temp9_alarm, S_IRUGO, show_temp_alarm, NULL, 8),
1923 SENSOR_ATTR(temp10_alarm, S_IRUGO, show_temp_alarm, NULL, 9),
Guenter Roeckaa136e52012-12-04 03:26:05 -08001924};
1925
Guenter Roeckaa136e52012-12-04 03:26:05 -08001926static ssize_t
Guenter Roeck77eb5b32012-12-04 08:30:54 -08001927show_pwm_mode(struct device *dev, struct device_attribute *attr, char *buf)
1928{
1929 struct nct6775_data *data = nct6775_update_device(dev);
1930 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1931
1932 return sprintf(buf, "%d\n", !data->pwm_mode[sattr->index]);
1933}
1934
1935static ssize_t
1936store_pwm_mode(struct device *dev, struct device_attribute *attr,
1937 const char *buf, size_t count)
1938{
1939 struct nct6775_data *data = dev_get_drvdata(dev);
1940 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1941 int nr = sattr->index;
1942 unsigned long val;
1943 int err;
1944 u8 reg;
1945
1946 err = kstrtoul(buf, 10, &val);
1947 if (err < 0)
1948 return err;
1949
1950 if (val > 1)
1951 return -EINVAL;
1952
1953 /* Setting DC mode is not supported for all chips/channels */
1954 if (data->REG_PWM_MODE[nr] == 0) {
1955 if (val)
1956 return -EINVAL;
1957 return count;
1958 }
1959
1960 mutex_lock(&data->update_lock);
1961 data->pwm_mode[nr] = val;
1962 reg = nct6775_read_value(data, data->REG_PWM_MODE[nr]);
1963 reg &= ~data->PWM_MODE_MASK[nr];
1964 if (val)
1965 reg |= data->PWM_MODE_MASK[nr];
1966 nct6775_write_value(data, data->REG_PWM_MODE[nr], reg);
1967 mutex_unlock(&data->update_lock);
1968 return count;
1969}
1970
1971static ssize_t
1972show_pwm(struct device *dev, struct device_attribute *attr, char *buf)
1973{
1974 struct nct6775_data *data = nct6775_update_device(dev);
1975 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
1976 int nr = sattr->nr;
1977 int index = sattr->index;
1978 int pwm;
1979
1980 /*
1981 * For automatic fan control modes, show current pwm readings.
1982 * Otherwise, show the configured value.
1983 */
1984 if (index == 0 && data->pwm_enable[nr] > manual)
1985 pwm = nct6775_read_value(data, data->REG_PWM_READ[nr]);
1986 else
1987 pwm = data->pwm[index][nr];
1988
1989 return sprintf(buf, "%d\n", pwm);
1990}
1991
1992static ssize_t
1993store_pwm(struct device *dev, struct device_attribute *attr, const char *buf,
1994 size_t count)
1995{
1996 struct nct6775_data *data = dev_get_drvdata(dev);
1997 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
1998 int nr = sattr->nr;
1999 int index = sattr->index;
2000 unsigned long val;
Guenter Roeckbbd8dec2012-12-04 09:08:29 -08002001 int minval[7] = { 0, 1, 1, data->pwm[2][nr], 0, 0, 0 };
2002 int maxval[7]
2003 = { 255, 255, data->pwm[3][nr] ? : 255, 255, 255, 255, 255 };
Guenter Roeck77eb5b32012-12-04 08:30:54 -08002004 int err;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002005 u8 reg;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08002006
2007 err = kstrtoul(buf, 10, &val);
2008 if (err < 0)
2009 return err;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002010 val = clamp_val(val, minval[index], maxval[index]);
Guenter Roeck77eb5b32012-12-04 08:30:54 -08002011
2012 mutex_lock(&data->update_lock);
2013 data->pwm[index][nr] = val;
2014 nct6775_write_value(data, data->REG_PWM[index][nr], val);
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002015 if (index == 2) { /* floor: disable if val == 0 */
2016 reg = nct6775_read_value(data, data->REG_TEMP_SEL[nr]);
2017 reg &= 0x7f;
2018 if (val)
2019 reg |= 0x80;
2020 nct6775_write_value(data, data->REG_TEMP_SEL[nr], reg);
2021 }
Guenter Roeck77eb5b32012-12-04 08:30:54 -08002022 mutex_unlock(&data->update_lock);
2023 return count;
2024}
2025
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002026/* Returns 0 if OK, -EINVAL otherwise */
2027static int check_trip_points(struct nct6775_data *data, int nr)
2028{
2029 int i;
2030
2031 for (i = 0; i < data->auto_pwm_num - 1; i++) {
2032 if (data->auto_temp[nr][i] > data->auto_temp[nr][i + 1])
2033 return -EINVAL;
2034 }
2035 for (i = 0; i < data->auto_pwm_num - 1; i++) {
2036 if (data->auto_pwm[nr][i] > data->auto_pwm[nr][i + 1])
2037 return -EINVAL;
2038 }
2039 /* validate critical temperature and pwm if enabled (pwm > 0) */
2040 if (data->auto_pwm[nr][data->auto_pwm_num]) {
2041 if (data->auto_temp[nr][data->auto_pwm_num - 1] >
2042 data->auto_temp[nr][data->auto_pwm_num] ||
2043 data->auto_pwm[nr][data->auto_pwm_num - 1] >
2044 data->auto_pwm[nr][data->auto_pwm_num])
2045 return -EINVAL;
2046 }
2047 return 0;
2048}
2049
2050static void pwm_update_registers(struct nct6775_data *data, int nr)
2051{
2052 u8 reg;
2053
2054 switch (data->pwm_enable[nr]) {
2055 case off:
2056 case manual:
2057 break;
2058 case speed_cruise:
2059 reg = nct6775_read_value(data, data->REG_FAN_MODE[nr]);
2060 reg = (reg & ~data->tolerance_mask) |
2061 (data->target_speed_tolerance[nr] & data->tolerance_mask);
2062 nct6775_write_value(data, data->REG_FAN_MODE[nr], reg);
2063 nct6775_write_value(data, data->REG_TARGET[nr],
2064 data->target_speed[nr] & 0xff);
2065 if (data->REG_TOLERANCE_H) {
2066 reg = (data->target_speed[nr] >> 8) & 0x0f;
2067 reg |= (data->target_speed_tolerance[nr] & 0x38) << 1;
2068 nct6775_write_value(data,
2069 data->REG_TOLERANCE_H[nr],
2070 reg);
2071 }
2072 break;
2073 case thermal_cruise:
2074 nct6775_write_value(data, data->REG_TARGET[nr],
2075 data->target_temp[nr]);
2076 /* intentional */
2077 default:
2078 reg = nct6775_read_value(data, data->REG_FAN_MODE[nr]);
2079 reg = (reg & ~data->tolerance_mask) |
2080 data->temp_tolerance[0][nr];
2081 nct6775_write_value(data, data->REG_FAN_MODE[nr], reg);
2082 break;
2083 }
2084}
2085
Guenter Roeck77eb5b32012-12-04 08:30:54 -08002086static ssize_t
2087show_pwm_enable(struct device *dev, struct device_attribute *attr, char *buf)
2088{
2089 struct nct6775_data *data = nct6775_update_device(dev);
2090 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2091
2092 return sprintf(buf, "%d\n", data->pwm_enable[sattr->index]);
2093}
2094
2095static ssize_t
2096store_pwm_enable(struct device *dev, struct device_attribute *attr,
2097 const char *buf, size_t count)
2098{
2099 struct nct6775_data *data = dev_get_drvdata(dev);
2100 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2101 int nr = sattr->index;
2102 unsigned long val;
2103 int err;
2104 u16 reg;
2105
2106 err = kstrtoul(buf, 10, &val);
2107 if (err < 0)
2108 return err;
2109
2110 if (val > sf4)
2111 return -EINVAL;
2112
2113 if (val == sf3 && data->kind != nct6775)
2114 return -EINVAL;
2115
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002116 if (val == sf4 && check_trip_points(data, nr)) {
2117 dev_err(dev, "Inconsistent trip points, not switching to SmartFan IV mode\n");
2118 dev_err(dev, "Adjust trip points and try again\n");
2119 return -EINVAL;
2120 }
2121
Guenter Roeck77eb5b32012-12-04 08:30:54 -08002122 mutex_lock(&data->update_lock);
2123 data->pwm_enable[nr] = val;
2124 if (val == off) {
2125 /*
2126 * turn off pwm control: select manual mode, set pwm to maximum
2127 */
2128 data->pwm[0][nr] = 255;
2129 nct6775_write_value(data, data->REG_PWM[0][nr], 255);
2130 }
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002131 pwm_update_registers(data, nr);
Guenter Roeck77eb5b32012-12-04 08:30:54 -08002132 reg = nct6775_read_value(data, data->REG_FAN_MODE[nr]);
2133 reg &= 0x0f;
2134 reg |= pwm_enable_to_reg(val) << 4;
2135 nct6775_write_value(data, data->REG_FAN_MODE[nr], reg);
2136 mutex_unlock(&data->update_lock);
2137 return count;
2138}
2139
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002140static ssize_t
Guenter Roeckbbd8dec2012-12-04 09:08:29 -08002141show_pwm_temp_sel_common(struct nct6775_data *data, char *buf, int src)
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002142{
Guenter Roeckbbd8dec2012-12-04 09:08:29 -08002143 int i, sel = 0;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002144
2145 for (i = 0; i < NUM_TEMP; i++) {
2146 if (!(data->have_temp & (1 << i)))
2147 continue;
2148 if (src == data->temp_src[i]) {
2149 sel = i + 1;
2150 break;
2151 }
2152 }
2153
2154 return sprintf(buf, "%d\n", sel);
2155}
2156
2157static ssize_t
Guenter Roeckbbd8dec2012-12-04 09:08:29 -08002158show_pwm_temp_sel(struct device *dev, struct device_attribute *attr, char *buf)
2159{
2160 struct nct6775_data *data = nct6775_update_device(dev);
2161 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2162 int index = sattr->index;
2163
2164 return show_pwm_temp_sel_common(data, buf, data->pwm_temp_sel[index]);
2165}
2166
2167static ssize_t
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002168store_pwm_temp_sel(struct device *dev, struct device_attribute *attr,
2169 const char *buf, size_t count)
2170{
2171 struct nct6775_data *data = nct6775_update_device(dev);
2172 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2173 int nr = sattr->index;
2174 unsigned long val;
2175 int err, reg, src;
2176
2177 err = kstrtoul(buf, 10, &val);
2178 if (err < 0)
2179 return err;
2180 if (val == 0 || val > NUM_TEMP)
2181 return -EINVAL;
2182 if (!(data->have_temp & (1 << (val - 1))) || !data->temp_src[val - 1])
2183 return -EINVAL;
2184
2185 mutex_lock(&data->update_lock);
2186 src = data->temp_src[val - 1];
2187 data->pwm_temp_sel[nr] = src;
2188 reg = nct6775_read_value(data, data->REG_TEMP_SEL[nr]);
2189 reg &= 0xe0;
2190 reg |= src;
2191 nct6775_write_value(data, data->REG_TEMP_SEL[nr], reg);
2192 mutex_unlock(&data->update_lock);
2193
2194 return count;
2195}
2196
2197static ssize_t
Guenter Roeckbbd8dec2012-12-04 09:08:29 -08002198show_pwm_weight_temp_sel(struct device *dev, struct device_attribute *attr,
2199 char *buf)
2200{
2201 struct nct6775_data *data = nct6775_update_device(dev);
2202 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2203 int index = sattr->index;
2204
2205 return show_pwm_temp_sel_common(data, buf,
2206 data->pwm_weight_temp_sel[index]);
2207}
2208
2209static ssize_t
2210store_pwm_weight_temp_sel(struct device *dev, struct device_attribute *attr,
2211 const char *buf, size_t count)
2212{
2213 struct nct6775_data *data = nct6775_update_device(dev);
2214 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2215 int nr = sattr->index;
2216 unsigned long val;
2217 int err, reg, src;
2218
2219 err = kstrtoul(buf, 10, &val);
2220 if (err < 0)
2221 return err;
2222 if (val > NUM_TEMP)
2223 return -EINVAL;
2224 if (val && (!(data->have_temp & (1 << (val - 1))) ||
2225 !data->temp_src[val - 1]))
2226 return -EINVAL;
2227
2228 mutex_lock(&data->update_lock);
2229 if (val) {
2230 src = data->temp_src[val - 1];
2231 data->pwm_weight_temp_sel[nr] = src;
2232 reg = nct6775_read_value(data, data->REG_WEIGHT_TEMP_SEL[nr]);
2233 reg &= 0xe0;
2234 reg |= (src | 0x80);
2235 nct6775_write_value(data, data->REG_WEIGHT_TEMP_SEL[nr], reg);
2236 } else {
2237 data->pwm_weight_temp_sel[nr] = 0;
2238 reg = nct6775_read_value(data, data->REG_WEIGHT_TEMP_SEL[nr]);
2239 reg &= 0x7f;
2240 nct6775_write_value(data, data->REG_WEIGHT_TEMP_SEL[nr], reg);
2241 }
2242 mutex_unlock(&data->update_lock);
2243
2244 return count;
2245}
2246
2247static ssize_t
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002248show_target_temp(struct device *dev, struct device_attribute *attr, char *buf)
2249{
2250 struct nct6775_data *data = nct6775_update_device(dev);
2251 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2252
2253 return sprintf(buf, "%d\n", data->target_temp[sattr->index] * 1000);
2254}
2255
2256static ssize_t
2257store_target_temp(struct device *dev, struct device_attribute *attr,
2258 const char *buf, size_t count)
2259{
2260 struct nct6775_data *data = dev_get_drvdata(dev);
2261 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2262 int nr = sattr->index;
2263 unsigned long val;
2264 int err;
2265
2266 err = kstrtoul(buf, 10, &val);
2267 if (err < 0)
2268 return err;
2269
2270 val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0,
2271 data->target_temp_mask);
2272
2273 mutex_lock(&data->update_lock);
2274 data->target_temp[nr] = val;
2275 pwm_update_registers(data, nr);
2276 mutex_unlock(&data->update_lock);
2277 return count;
2278}
2279
2280static ssize_t
2281show_target_speed(struct device *dev, struct device_attribute *attr, char *buf)
2282{
2283 struct nct6775_data *data = nct6775_update_device(dev);
2284 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2285 int nr = sattr->index;
2286
2287 return sprintf(buf, "%d\n",
2288 fan_from_reg16(data->target_speed[nr],
2289 data->fan_div[nr]));
2290}
2291
2292static ssize_t
2293store_target_speed(struct device *dev, struct device_attribute *attr,
2294 const char *buf, size_t count)
2295{
2296 struct nct6775_data *data = dev_get_drvdata(dev);
2297 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2298 int nr = sattr->index;
2299 unsigned long val;
2300 int err;
2301 u16 speed;
2302
2303 err = kstrtoul(buf, 10, &val);
2304 if (err < 0)
2305 return err;
2306
2307 val = clamp_val(val, 0, 1350000U);
2308 speed = fan_to_reg(val, data->fan_div[nr]);
2309
2310 mutex_lock(&data->update_lock);
2311 data->target_speed[nr] = speed;
2312 pwm_update_registers(data, nr);
2313 mutex_unlock(&data->update_lock);
2314 return count;
2315}
2316
2317static ssize_t
2318show_temp_tolerance(struct device *dev, struct device_attribute *attr,
2319 char *buf)
2320{
2321 struct nct6775_data *data = nct6775_update_device(dev);
2322 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2323 int nr = sattr->nr;
2324 int index = sattr->index;
2325
2326 return sprintf(buf, "%d\n", data->temp_tolerance[index][nr] * 1000);
2327}
2328
2329static ssize_t
2330store_temp_tolerance(struct device *dev, struct device_attribute *attr,
2331 const char *buf, size_t count)
2332{
2333 struct nct6775_data *data = dev_get_drvdata(dev);
2334 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2335 int nr = sattr->nr;
2336 int index = sattr->index;
2337 unsigned long val;
2338 int err;
2339
2340 err = kstrtoul(buf, 10, &val);
2341 if (err < 0)
2342 return err;
2343
2344 /* Limit tolerance as needed */
2345 val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0, data->tolerance_mask);
2346
2347 mutex_lock(&data->update_lock);
2348 data->temp_tolerance[index][nr] = val;
2349 if (index)
2350 pwm_update_registers(data, nr);
2351 else
2352 nct6775_write_value(data,
2353 data->REG_CRITICAL_TEMP_TOLERANCE[nr],
2354 val);
2355 mutex_unlock(&data->update_lock);
2356 return count;
2357}
2358
2359/*
2360 * Fan speed tolerance is a tricky beast, since the associated register is
2361 * a tick counter, but the value is reported and configured as rpm.
2362 * Compute resulting low and high rpm values and report the difference.
2363 */
2364static ssize_t
2365show_speed_tolerance(struct device *dev, struct device_attribute *attr,
2366 char *buf)
2367{
2368 struct nct6775_data *data = nct6775_update_device(dev);
2369 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2370 int nr = sattr->index;
2371 int low = data->target_speed[nr] - data->target_speed_tolerance[nr];
2372 int high = data->target_speed[nr] + data->target_speed_tolerance[nr];
2373 int tolerance;
2374
2375 if (low <= 0)
2376 low = 1;
2377 if (high > 0xffff)
2378 high = 0xffff;
2379 if (high < low)
2380 high = low;
2381
2382 tolerance = (fan_from_reg16(low, data->fan_div[nr])
2383 - fan_from_reg16(high, data->fan_div[nr])) / 2;
2384
2385 return sprintf(buf, "%d\n", tolerance);
2386}
2387
2388static ssize_t
2389store_speed_tolerance(struct device *dev, struct device_attribute *attr,
2390 const char *buf, size_t count)
2391{
2392 struct nct6775_data *data = dev_get_drvdata(dev);
2393 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2394 int nr = sattr->index;
2395 unsigned long val;
2396 int err;
2397 int low, high;
2398
2399 err = kstrtoul(buf, 10, &val);
2400 if (err < 0)
2401 return err;
2402
2403 high = fan_from_reg16(data->target_speed[nr],
2404 data->fan_div[nr]) + val;
2405 low = fan_from_reg16(data->target_speed[nr],
2406 data->fan_div[nr]) - val;
2407 if (low <= 0)
2408 low = 1;
2409 if (high < low)
2410 high = low;
2411
2412 val = (fan_to_reg(low, data->fan_div[nr]) -
2413 fan_to_reg(high, data->fan_div[nr])) / 2;
2414
2415 /* Limit tolerance as needed */
2416 val = clamp_val(val, 0, data->speed_tolerance_limit);
2417
2418 mutex_lock(&data->update_lock);
2419 data->target_speed_tolerance[nr] = val;
2420 pwm_update_registers(data, nr);
2421 mutex_unlock(&data->update_lock);
2422 return count;
2423}
2424
Guenter Roeck77eb5b32012-12-04 08:30:54 -08002425static SENSOR_DEVICE_ATTR_2(pwm1, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 0, 0);
2426static SENSOR_DEVICE_ATTR_2(pwm2, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 1, 0);
2427static SENSOR_DEVICE_ATTR_2(pwm3, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 2, 0);
2428static SENSOR_DEVICE_ATTR_2(pwm4, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 3, 0);
2429static SENSOR_DEVICE_ATTR_2(pwm5, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 4, 0);
2430
2431static SENSOR_DEVICE_ATTR(pwm1_mode, S_IWUSR | S_IRUGO, show_pwm_mode,
2432 store_pwm_mode, 0);
2433static SENSOR_DEVICE_ATTR(pwm2_mode, S_IWUSR | S_IRUGO, show_pwm_mode,
2434 store_pwm_mode, 1);
2435static SENSOR_DEVICE_ATTR(pwm3_mode, S_IWUSR | S_IRUGO, show_pwm_mode,
2436 store_pwm_mode, 2);
2437static SENSOR_DEVICE_ATTR(pwm4_mode, S_IWUSR | S_IRUGO, show_pwm_mode,
2438 store_pwm_mode, 3);
2439static SENSOR_DEVICE_ATTR(pwm5_mode, S_IWUSR | S_IRUGO, show_pwm_mode,
2440 store_pwm_mode, 4);
2441
2442static SENSOR_DEVICE_ATTR(pwm1_enable, S_IWUSR | S_IRUGO, show_pwm_enable,
2443 store_pwm_enable, 0);
2444static SENSOR_DEVICE_ATTR(pwm2_enable, S_IWUSR | S_IRUGO, show_pwm_enable,
2445 store_pwm_enable, 1);
2446static SENSOR_DEVICE_ATTR(pwm3_enable, S_IWUSR | S_IRUGO, show_pwm_enable,
2447 store_pwm_enable, 2);
2448static SENSOR_DEVICE_ATTR(pwm4_enable, S_IWUSR | S_IRUGO, show_pwm_enable,
2449 store_pwm_enable, 3);
2450static SENSOR_DEVICE_ATTR(pwm5_enable, S_IWUSR | S_IRUGO, show_pwm_enable,
2451 store_pwm_enable, 4);
2452
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002453static SENSOR_DEVICE_ATTR(pwm1_temp_sel, S_IWUSR | S_IRUGO,
2454 show_pwm_temp_sel, store_pwm_temp_sel, 0);
2455static SENSOR_DEVICE_ATTR(pwm2_temp_sel, S_IWUSR | S_IRUGO,
2456 show_pwm_temp_sel, store_pwm_temp_sel, 1);
2457static SENSOR_DEVICE_ATTR(pwm3_temp_sel, S_IWUSR | S_IRUGO,
2458 show_pwm_temp_sel, store_pwm_temp_sel, 2);
2459static SENSOR_DEVICE_ATTR(pwm4_temp_sel, S_IWUSR | S_IRUGO,
2460 show_pwm_temp_sel, store_pwm_temp_sel, 3);
2461static SENSOR_DEVICE_ATTR(pwm5_temp_sel, S_IWUSR | S_IRUGO,
2462 show_pwm_temp_sel, store_pwm_temp_sel, 4);
2463
2464static SENSOR_DEVICE_ATTR(pwm1_target_temp, S_IWUSR | S_IRUGO, show_target_temp,
2465 store_target_temp, 0);
2466static SENSOR_DEVICE_ATTR(pwm2_target_temp, S_IWUSR | S_IRUGO, show_target_temp,
2467 store_target_temp, 1);
2468static SENSOR_DEVICE_ATTR(pwm3_target_temp, S_IWUSR | S_IRUGO, show_target_temp,
2469 store_target_temp, 2);
2470static SENSOR_DEVICE_ATTR(pwm4_target_temp, S_IWUSR | S_IRUGO, show_target_temp,
2471 store_target_temp, 3);
2472static SENSOR_DEVICE_ATTR(pwm5_target_temp, S_IWUSR | S_IRUGO, show_target_temp,
2473 store_target_temp, 4);
2474
2475static SENSOR_DEVICE_ATTR(fan1_target, S_IWUSR | S_IRUGO, show_target_speed,
2476 store_target_speed, 0);
2477static SENSOR_DEVICE_ATTR(fan2_target, S_IWUSR | S_IRUGO, show_target_speed,
2478 store_target_speed, 1);
2479static SENSOR_DEVICE_ATTR(fan3_target, S_IWUSR | S_IRUGO, show_target_speed,
2480 store_target_speed, 2);
2481static SENSOR_DEVICE_ATTR(fan4_target, S_IWUSR | S_IRUGO, show_target_speed,
2482 store_target_speed, 3);
2483static SENSOR_DEVICE_ATTR(fan5_target, S_IWUSR | S_IRUGO, show_target_speed,
2484 store_target_speed, 4);
2485
2486static SENSOR_DEVICE_ATTR(fan1_tolerance, S_IWUSR | S_IRUGO,
2487 show_speed_tolerance, store_speed_tolerance, 0);
2488static SENSOR_DEVICE_ATTR(fan2_tolerance, S_IWUSR | S_IRUGO,
2489 show_speed_tolerance, store_speed_tolerance, 1);
2490static SENSOR_DEVICE_ATTR(fan3_tolerance, S_IWUSR | S_IRUGO,
2491 show_speed_tolerance, store_speed_tolerance, 2);
2492static SENSOR_DEVICE_ATTR(fan4_tolerance, S_IWUSR | S_IRUGO,
2493 show_speed_tolerance, store_speed_tolerance, 3);
2494static SENSOR_DEVICE_ATTR(fan5_tolerance, S_IWUSR | S_IRUGO,
2495 show_speed_tolerance, store_speed_tolerance, 4);
2496
2497/* Smart Fan registers */
2498
2499static ssize_t
Guenter Roeckbbd8dec2012-12-04 09:08:29 -08002500show_weight_temp(struct device *dev, struct device_attribute *attr, char *buf)
2501{
2502 struct nct6775_data *data = nct6775_update_device(dev);
2503 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2504 int nr = sattr->nr;
2505 int index = sattr->index;
2506
2507 return sprintf(buf, "%d\n", data->weight_temp[index][nr] * 1000);
2508}
2509
2510static ssize_t
2511store_weight_temp(struct device *dev, struct device_attribute *attr,
2512 const char *buf, size_t count)
2513{
2514 struct nct6775_data *data = dev_get_drvdata(dev);
2515 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2516 int nr = sattr->nr;
2517 int index = sattr->index;
2518 unsigned long val;
2519 int err;
2520
2521 err = kstrtoul(buf, 10, &val);
2522 if (err < 0)
2523 return err;
2524
2525 val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0, 255);
2526
2527 mutex_lock(&data->update_lock);
2528 data->weight_temp[index][nr] = val;
2529 nct6775_write_value(data, data->REG_WEIGHT_TEMP[index][nr], val);
2530 mutex_unlock(&data->update_lock);
2531 return count;
2532}
2533
2534static SENSOR_DEVICE_ATTR(pwm1_weight_temp_sel, S_IWUSR | S_IRUGO,
2535 show_pwm_weight_temp_sel, store_pwm_weight_temp_sel,
2536 0);
2537static SENSOR_DEVICE_ATTR(pwm2_weight_temp_sel, S_IWUSR | S_IRUGO,
2538 show_pwm_weight_temp_sel, store_pwm_weight_temp_sel,
2539 1);
2540static SENSOR_DEVICE_ATTR(pwm3_weight_temp_sel, S_IWUSR | S_IRUGO,
2541 show_pwm_weight_temp_sel, store_pwm_weight_temp_sel,
2542 2);
2543static SENSOR_DEVICE_ATTR(pwm4_weight_temp_sel, S_IWUSR | S_IRUGO,
2544 show_pwm_weight_temp_sel, store_pwm_weight_temp_sel,
2545 3);
2546static SENSOR_DEVICE_ATTR(pwm5_weight_temp_sel, S_IWUSR | S_IRUGO,
2547 show_pwm_weight_temp_sel, store_pwm_weight_temp_sel,
2548 4);
2549
2550static SENSOR_DEVICE_ATTR_2(pwm1_weight_temp_step, S_IWUSR | S_IRUGO,
2551 show_weight_temp, store_weight_temp, 0, 0);
2552static SENSOR_DEVICE_ATTR_2(pwm2_weight_temp_step, S_IWUSR | S_IRUGO,
2553 show_weight_temp, store_weight_temp, 1, 0);
2554static SENSOR_DEVICE_ATTR_2(pwm3_weight_temp_step, S_IWUSR | S_IRUGO,
2555 show_weight_temp, store_weight_temp, 2, 0);
2556static SENSOR_DEVICE_ATTR_2(pwm4_weight_temp_step, S_IWUSR | S_IRUGO,
2557 show_weight_temp, store_weight_temp, 3, 0);
2558static SENSOR_DEVICE_ATTR_2(pwm5_weight_temp_step, S_IWUSR | S_IRUGO,
2559 show_weight_temp, store_weight_temp, 4, 0);
2560
2561static SENSOR_DEVICE_ATTR_2(pwm1_weight_temp_step_tol, S_IWUSR | S_IRUGO,
2562 show_weight_temp, store_weight_temp, 0, 1);
2563static SENSOR_DEVICE_ATTR_2(pwm2_weight_temp_step_tol, S_IWUSR | S_IRUGO,
2564 show_weight_temp, store_weight_temp, 1, 1);
2565static SENSOR_DEVICE_ATTR_2(pwm3_weight_temp_step_tol, S_IWUSR | S_IRUGO,
2566 show_weight_temp, store_weight_temp, 2, 1);
2567static SENSOR_DEVICE_ATTR_2(pwm4_weight_temp_step_tol, S_IWUSR | S_IRUGO,
2568 show_weight_temp, store_weight_temp, 3, 1);
2569static SENSOR_DEVICE_ATTR_2(pwm5_weight_temp_step_tol, S_IWUSR | S_IRUGO,
2570 show_weight_temp, store_weight_temp, 4, 1);
2571
2572static SENSOR_DEVICE_ATTR_2(pwm1_weight_temp_step_base, S_IWUSR | S_IRUGO,
2573 show_weight_temp, store_weight_temp, 0, 2);
2574static SENSOR_DEVICE_ATTR_2(pwm2_weight_temp_step_base, S_IWUSR | S_IRUGO,
2575 show_weight_temp, store_weight_temp, 1, 2);
2576static SENSOR_DEVICE_ATTR_2(pwm3_weight_temp_step_base, S_IWUSR | S_IRUGO,
2577 show_weight_temp, store_weight_temp, 2, 2);
2578static SENSOR_DEVICE_ATTR_2(pwm4_weight_temp_step_base, S_IWUSR | S_IRUGO,
2579 show_weight_temp, store_weight_temp, 3, 2);
2580static SENSOR_DEVICE_ATTR_2(pwm5_weight_temp_step_base, S_IWUSR | S_IRUGO,
2581 show_weight_temp, store_weight_temp, 4, 2);
2582
2583static SENSOR_DEVICE_ATTR_2(pwm1_weight_duty_step, S_IWUSR | S_IRUGO,
2584 show_pwm, store_pwm, 0, 5);
2585static SENSOR_DEVICE_ATTR_2(pwm2_weight_duty_step, S_IWUSR | S_IRUGO,
2586 show_pwm, store_pwm, 1, 5);
2587static SENSOR_DEVICE_ATTR_2(pwm3_weight_duty_step, S_IWUSR | S_IRUGO,
2588 show_pwm, store_pwm, 2, 5);
2589static SENSOR_DEVICE_ATTR_2(pwm4_weight_duty_step, S_IWUSR | S_IRUGO,
2590 show_pwm, store_pwm, 3, 5);
2591static SENSOR_DEVICE_ATTR_2(pwm5_weight_duty_step, S_IWUSR | S_IRUGO,
2592 show_pwm, store_pwm, 4, 5);
2593
2594/* duty_base is not supported on all chips */
2595static struct sensor_device_attribute_2 sda_weight_duty_base[] = {
2596 SENSOR_ATTR_2(pwm1_weight_duty_base, S_IWUSR | S_IRUGO,
2597 show_pwm, store_pwm, 0, 6),
2598 SENSOR_ATTR_2(pwm2_weight_duty_base, S_IWUSR | S_IRUGO,
2599 show_pwm, store_pwm, 1, 6),
2600 SENSOR_ATTR_2(pwm3_weight_duty_base, S_IWUSR | S_IRUGO,
2601 show_pwm, store_pwm, 2, 6),
2602 SENSOR_ATTR_2(pwm4_weight_duty_base, S_IWUSR | S_IRUGO,
2603 show_pwm, store_pwm, 3, 6),
2604 SENSOR_ATTR_2(pwm5_weight_duty_base, S_IWUSR | S_IRUGO,
2605 show_pwm, store_pwm, 4, 6),
2606};
2607
2608static ssize_t
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002609show_fan_time(struct device *dev, struct device_attribute *attr, char *buf)
2610{
2611 struct nct6775_data *data = nct6775_update_device(dev);
2612 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2613 int nr = sattr->nr;
2614 int index = sattr->index;
2615
2616 return sprintf(buf, "%d\n",
2617 step_time_from_reg(data->fan_time[index][nr],
2618 data->pwm_mode[nr]));
2619}
2620
2621static ssize_t
2622store_fan_time(struct device *dev, struct device_attribute *attr,
2623 const char *buf, size_t count)
2624{
2625 struct nct6775_data *data = dev_get_drvdata(dev);
2626 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2627 int nr = sattr->nr;
2628 int index = sattr->index;
2629 unsigned long val;
2630 int err;
2631
2632 err = kstrtoul(buf, 10, &val);
2633 if (err < 0)
2634 return err;
2635
2636 val = step_time_to_reg(val, data->pwm_mode[nr]);
2637 mutex_lock(&data->update_lock);
2638 data->fan_time[index][nr] = val;
2639 nct6775_write_value(data, data->REG_FAN_TIME[index][nr], val);
2640 mutex_unlock(&data->update_lock);
2641 return count;
2642}
2643
Guenter Roeck77eb5b32012-12-04 08:30:54 -08002644static ssize_t
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07002645show_name(struct device *dev, struct device_attribute *attr, char *buf)
2646{
2647 struct nct6775_data *data = dev_get_drvdata(dev);
2648
2649 return sprintf(buf, "%s\n", data->name);
2650}
2651
2652static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
2653
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002654static SENSOR_DEVICE_ATTR_2(pwm1_stop_time, S_IWUSR | S_IRUGO, show_fan_time,
2655 store_fan_time, 0, 0);
2656static SENSOR_DEVICE_ATTR_2(pwm2_stop_time, S_IWUSR | S_IRUGO, show_fan_time,
2657 store_fan_time, 1, 0);
2658static SENSOR_DEVICE_ATTR_2(pwm3_stop_time, S_IWUSR | S_IRUGO, show_fan_time,
2659 store_fan_time, 2, 0);
2660static SENSOR_DEVICE_ATTR_2(pwm4_stop_time, S_IWUSR | S_IRUGO, show_fan_time,
2661 store_fan_time, 3, 0);
2662static SENSOR_DEVICE_ATTR_2(pwm5_stop_time, S_IWUSR | S_IRUGO, show_fan_time,
2663 store_fan_time, 4, 0);
2664
2665static SENSOR_DEVICE_ATTR_2(pwm1_step_up_time, S_IWUSR | S_IRUGO, show_fan_time,
2666 store_fan_time, 0, 1);
2667static SENSOR_DEVICE_ATTR_2(pwm2_step_up_time, S_IWUSR | S_IRUGO, show_fan_time,
2668 store_fan_time, 1, 1);
2669static SENSOR_DEVICE_ATTR_2(pwm3_step_up_time, S_IWUSR | S_IRUGO, show_fan_time,
2670 store_fan_time, 2, 1);
2671static SENSOR_DEVICE_ATTR_2(pwm4_step_up_time, S_IWUSR | S_IRUGO, show_fan_time,
2672 store_fan_time, 3, 1);
2673static SENSOR_DEVICE_ATTR_2(pwm5_step_up_time, S_IWUSR | S_IRUGO, show_fan_time,
2674 store_fan_time, 4, 1);
2675
2676static SENSOR_DEVICE_ATTR_2(pwm1_step_down_time, S_IWUSR | S_IRUGO,
2677 show_fan_time, store_fan_time, 0, 2);
2678static SENSOR_DEVICE_ATTR_2(pwm2_step_down_time, S_IWUSR | S_IRUGO,
2679 show_fan_time, store_fan_time, 1, 2);
2680static SENSOR_DEVICE_ATTR_2(pwm3_step_down_time, S_IWUSR | S_IRUGO,
2681 show_fan_time, store_fan_time, 2, 2);
2682static SENSOR_DEVICE_ATTR_2(pwm4_step_down_time, S_IWUSR | S_IRUGO,
2683 show_fan_time, store_fan_time, 3, 2);
2684static SENSOR_DEVICE_ATTR_2(pwm5_step_down_time, S_IWUSR | S_IRUGO,
2685 show_fan_time, store_fan_time, 4, 2);
2686
2687static SENSOR_DEVICE_ATTR_2(pwm1_start, S_IWUSR | S_IRUGO, show_pwm,
2688 store_pwm, 0, 1);
2689static SENSOR_DEVICE_ATTR_2(pwm2_start, S_IWUSR | S_IRUGO, show_pwm,
2690 store_pwm, 1, 1);
2691static SENSOR_DEVICE_ATTR_2(pwm3_start, S_IWUSR | S_IRUGO, show_pwm,
2692 store_pwm, 2, 1);
2693static SENSOR_DEVICE_ATTR_2(pwm4_start, S_IWUSR | S_IRUGO, show_pwm,
2694 store_pwm, 3, 1);
2695static SENSOR_DEVICE_ATTR_2(pwm5_start, S_IWUSR | S_IRUGO, show_pwm,
2696 store_pwm, 4, 1);
2697
2698static SENSOR_DEVICE_ATTR_2(pwm1_floor, S_IWUSR | S_IRUGO, show_pwm,
2699 store_pwm, 0, 2);
2700static SENSOR_DEVICE_ATTR_2(pwm2_floor, S_IWUSR | S_IRUGO, show_pwm,
2701 store_pwm, 1, 2);
2702static SENSOR_DEVICE_ATTR_2(pwm3_floor, S_IWUSR | S_IRUGO, show_pwm,
2703 store_pwm, 2, 2);
2704static SENSOR_DEVICE_ATTR_2(pwm4_floor, S_IWUSR | S_IRUGO, show_pwm,
2705 store_pwm, 3, 2);
2706static SENSOR_DEVICE_ATTR_2(pwm5_floor, S_IWUSR | S_IRUGO, show_pwm,
2707 store_pwm, 4, 2);
2708
2709static SENSOR_DEVICE_ATTR_2(pwm1_temp_tolerance, S_IWUSR | S_IRUGO,
2710 show_temp_tolerance, store_temp_tolerance, 0, 0);
2711static SENSOR_DEVICE_ATTR_2(pwm2_temp_tolerance, S_IWUSR | S_IRUGO,
2712 show_temp_tolerance, store_temp_tolerance, 1, 0);
2713static SENSOR_DEVICE_ATTR_2(pwm3_temp_tolerance, S_IWUSR | S_IRUGO,
2714 show_temp_tolerance, store_temp_tolerance, 2, 0);
2715static SENSOR_DEVICE_ATTR_2(pwm4_temp_tolerance, S_IWUSR | S_IRUGO,
2716 show_temp_tolerance, store_temp_tolerance, 3, 0);
2717static SENSOR_DEVICE_ATTR_2(pwm5_temp_tolerance, S_IWUSR | S_IRUGO,
2718 show_temp_tolerance, store_temp_tolerance, 4, 0);
2719
2720static SENSOR_DEVICE_ATTR_2(pwm1_crit_temp_tolerance, S_IWUSR | S_IRUGO,
2721 show_temp_tolerance, store_temp_tolerance, 0, 1);
2722static SENSOR_DEVICE_ATTR_2(pwm2_crit_temp_tolerance, S_IWUSR | S_IRUGO,
2723 show_temp_tolerance, store_temp_tolerance, 1, 1);
2724static SENSOR_DEVICE_ATTR_2(pwm3_crit_temp_tolerance, S_IWUSR | S_IRUGO,
2725 show_temp_tolerance, store_temp_tolerance, 2, 1);
2726static SENSOR_DEVICE_ATTR_2(pwm4_crit_temp_tolerance, S_IWUSR | S_IRUGO,
2727 show_temp_tolerance, store_temp_tolerance, 3, 1);
2728static SENSOR_DEVICE_ATTR_2(pwm5_crit_temp_tolerance, S_IWUSR | S_IRUGO,
2729 show_temp_tolerance, store_temp_tolerance, 4, 1);
2730
2731/* pwm_max is not supported on all chips */
2732static struct sensor_device_attribute_2 sda_pwm_max[] = {
2733 SENSOR_ATTR_2(pwm1_max, S_IWUSR | S_IRUGO, show_pwm, store_pwm,
2734 0, 3),
2735 SENSOR_ATTR_2(pwm2_max, S_IWUSR | S_IRUGO, show_pwm, store_pwm,
2736 1, 3),
2737 SENSOR_ATTR_2(pwm3_max, S_IWUSR | S_IRUGO, show_pwm, store_pwm,
2738 2, 3),
2739 SENSOR_ATTR_2(pwm4_max, S_IWUSR | S_IRUGO, show_pwm, store_pwm,
2740 3, 3),
2741 SENSOR_ATTR_2(pwm5_max, S_IWUSR | S_IRUGO, show_pwm, store_pwm,
2742 4, 3),
2743};
2744
2745/* pwm_step is not supported on all chips */
2746static struct sensor_device_attribute_2 sda_pwm_step[] = {
2747 SENSOR_ATTR_2(pwm1_step, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 0, 4),
2748 SENSOR_ATTR_2(pwm2_step, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 1, 4),
2749 SENSOR_ATTR_2(pwm3_step, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 2, 4),
2750 SENSOR_ATTR_2(pwm4_step, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 3, 4),
2751 SENSOR_ATTR_2(pwm5_step, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 4, 4),
2752};
2753
Guenter Roeckbbd8dec2012-12-04 09:08:29 -08002754static struct attribute *nct6775_attributes_pwm[5][20] = {
Guenter Roeck77eb5b32012-12-04 08:30:54 -08002755 {
2756 &sensor_dev_attr_pwm1.dev_attr.attr,
2757 &sensor_dev_attr_pwm1_mode.dev_attr.attr,
2758 &sensor_dev_attr_pwm1_enable.dev_attr.attr,
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002759 &sensor_dev_attr_pwm1_temp_sel.dev_attr.attr,
2760 &sensor_dev_attr_pwm1_temp_tolerance.dev_attr.attr,
2761 &sensor_dev_attr_pwm1_crit_temp_tolerance.dev_attr.attr,
2762 &sensor_dev_attr_pwm1_target_temp.dev_attr.attr,
2763 &sensor_dev_attr_fan1_target.dev_attr.attr,
2764 &sensor_dev_attr_fan1_tolerance.dev_attr.attr,
2765 &sensor_dev_attr_pwm1_stop_time.dev_attr.attr,
2766 &sensor_dev_attr_pwm1_step_up_time.dev_attr.attr,
2767 &sensor_dev_attr_pwm1_step_down_time.dev_attr.attr,
2768 &sensor_dev_attr_pwm1_start.dev_attr.attr,
2769 &sensor_dev_attr_pwm1_floor.dev_attr.attr,
Guenter Roeckbbd8dec2012-12-04 09:08:29 -08002770 &sensor_dev_attr_pwm1_weight_temp_sel.dev_attr.attr,
2771 &sensor_dev_attr_pwm1_weight_temp_step.dev_attr.attr,
2772 &sensor_dev_attr_pwm1_weight_temp_step_tol.dev_attr.attr,
2773 &sensor_dev_attr_pwm1_weight_temp_step_base.dev_attr.attr,
2774 &sensor_dev_attr_pwm1_weight_duty_step.dev_attr.attr,
Guenter Roeck77eb5b32012-12-04 08:30:54 -08002775 NULL
2776 },
2777 {
2778 &sensor_dev_attr_pwm2.dev_attr.attr,
2779 &sensor_dev_attr_pwm2_mode.dev_attr.attr,
2780 &sensor_dev_attr_pwm2_enable.dev_attr.attr,
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002781 &sensor_dev_attr_pwm2_temp_sel.dev_attr.attr,
2782 &sensor_dev_attr_pwm2_temp_tolerance.dev_attr.attr,
2783 &sensor_dev_attr_pwm2_crit_temp_tolerance.dev_attr.attr,
2784 &sensor_dev_attr_pwm2_target_temp.dev_attr.attr,
2785 &sensor_dev_attr_fan2_target.dev_attr.attr,
2786 &sensor_dev_attr_fan2_tolerance.dev_attr.attr,
2787 &sensor_dev_attr_pwm2_stop_time.dev_attr.attr,
2788 &sensor_dev_attr_pwm2_step_up_time.dev_attr.attr,
2789 &sensor_dev_attr_pwm2_step_down_time.dev_attr.attr,
2790 &sensor_dev_attr_pwm2_start.dev_attr.attr,
2791 &sensor_dev_attr_pwm2_floor.dev_attr.attr,
Guenter Roeckbbd8dec2012-12-04 09:08:29 -08002792 &sensor_dev_attr_pwm2_weight_temp_sel.dev_attr.attr,
2793 &sensor_dev_attr_pwm2_weight_temp_step.dev_attr.attr,
2794 &sensor_dev_attr_pwm2_weight_temp_step_tol.dev_attr.attr,
2795 &sensor_dev_attr_pwm2_weight_temp_step_base.dev_attr.attr,
2796 &sensor_dev_attr_pwm2_weight_duty_step.dev_attr.attr,
Guenter Roeck77eb5b32012-12-04 08:30:54 -08002797 NULL
2798 },
2799 {
2800 &sensor_dev_attr_pwm3.dev_attr.attr,
2801 &sensor_dev_attr_pwm3_mode.dev_attr.attr,
2802 &sensor_dev_attr_pwm3_enable.dev_attr.attr,
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002803 &sensor_dev_attr_pwm3_temp_sel.dev_attr.attr,
2804 &sensor_dev_attr_pwm3_temp_tolerance.dev_attr.attr,
2805 &sensor_dev_attr_pwm3_crit_temp_tolerance.dev_attr.attr,
2806 &sensor_dev_attr_pwm3_target_temp.dev_attr.attr,
2807 &sensor_dev_attr_fan3_target.dev_attr.attr,
2808 &sensor_dev_attr_fan3_tolerance.dev_attr.attr,
2809 &sensor_dev_attr_pwm3_stop_time.dev_attr.attr,
2810 &sensor_dev_attr_pwm3_step_up_time.dev_attr.attr,
2811 &sensor_dev_attr_pwm3_step_down_time.dev_attr.attr,
2812 &sensor_dev_attr_pwm3_start.dev_attr.attr,
2813 &sensor_dev_attr_pwm3_floor.dev_attr.attr,
Guenter Roeckbbd8dec2012-12-04 09:08:29 -08002814 &sensor_dev_attr_pwm3_weight_temp_sel.dev_attr.attr,
2815 &sensor_dev_attr_pwm3_weight_temp_step.dev_attr.attr,
2816 &sensor_dev_attr_pwm3_weight_temp_step_tol.dev_attr.attr,
2817 &sensor_dev_attr_pwm3_weight_temp_step_base.dev_attr.attr,
2818 &sensor_dev_attr_pwm3_weight_duty_step.dev_attr.attr,
Guenter Roeck77eb5b32012-12-04 08:30:54 -08002819 NULL
2820 },
2821 {
2822 &sensor_dev_attr_pwm4.dev_attr.attr,
2823 &sensor_dev_attr_pwm4_mode.dev_attr.attr,
2824 &sensor_dev_attr_pwm4_enable.dev_attr.attr,
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002825 &sensor_dev_attr_pwm4_temp_sel.dev_attr.attr,
2826 &sensor_dev_attr_pwm4_temp_tolerance.dev_attr.attr,
2827 &sensor_dev_attr_pwm4_crit_temp_tolerance.dev_attr.attr,
2828 &sensor_dev_attr_pwm4_target_temp.dev_attr.attr,
2829 &sensor_dev_attr_fan4_target.dev_attr.attr,
2830 &sensor_dev_attr_fan4_tolerance.dev_attr.attr,
2831 &sensor_dev_attr_pwm4_stop_time.dev_attr.attr,
2832 &sensor_dev_attr_pwm4_step_up_time.dev_attr.attr,
2833 &sensor_dev_attr_pwm4_step_down_time.dev_attr.attr,
2834 &sensor_dev_attr_pwm4_start.dev_attr.attr,
2835 &sensor_dev_attr_pwm4_floor.dev_attr.attr,
Guenter Roeckbbd8dec2012-12-04 09:08:29 -08002836 &sensor_dev_attr_pwm4_weight_temp_sel.dev_attr.attr,
2837 &sensor_dev_attr_pwm4_weight_temp_step.dev_attr.attr,
2838 &sensor_dev_attr_pwm4_weight_temp_step_tol.dev_attr.attr,
2839 &sensor_dev_attr_pwm4_weight_temp_step_base.dev_attr.attr,
2840 &sensor_dev_attr_pwm4_weight_duty_step.dev_attr.attr,
Guenter Roeck77eb5b32012-12-04 08:30:54 -08002841 NULL
2842 },
2843 {
2844 &sensor_dev_attr_pwm5.dev_attr.attr,
2845 &sensor_dev_attr_pwm5_mode.dev_attr.attr,
2846 &sensor_dev_attr_pwm5_enable.dev_attr.attr,
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002847 &sensor_dev_attr_pwm5_temp_sel.dev_attr.attr,
2848 &sensor_dev_attr_pwm5_temp_tolerance.dev_attr.attr,
2849 &sensor_dev_attr_pwm5_crit_temp_tolerance.dev_attr.attr,
2850 &sensor_dev_attr_pwm5_target_temp.dev_attr.attr,
2851 &sensor_dev_attr_fan5_target.dev_attr.attr,
2852 &sensor_dev_attr_fan5_tolerance.dev_attr.attr,
2853 &sensor_dev_attr_pwm5_stop_time.dev_attr.attr,
2854 &sensor_dev_attr_pwm5_step_up_time.dev_attr.attr,
2855 &sensor_dev_attr_pwm5_step_down_time.dev_attr.attr,
2856 &sensor_dev_attr_pwm5_start.dev_attr.attr,
2857 &sensor_dev_attr_pwm5_floor.dev_attr.attr,
Guenter Roeckbbd8dec2012-12-04 09:08:29 -08002858 &sensor_dev_attr_pwm5_weight_temp_sel.dev_attr.attr,
2859 &sensor_dev_attr_pwm5_weight_temp_step.dev_attr.attr,
2860 &sensor_dev_attr_pwm5_weight_temp_step_tol.dev_attr.attr,
2861 &sensor_dev_attr_pwm5_weight_temp_step_base.dev_attr.attr,
2862 &sensor_dev_attr_pwm5_weight_duty_step.dev_attr.attr,
Guenter Roeck77eb5b32012-12-04 08:30:54 -08002863 NULL
2864 },
2865};
2866
2867static const struct attribute_group nct6775_group_pwm[5] = {
2868 { .attrs = nct6775_attributes_pwm[0] },
2869 { .attrs = nct6775_attributes_pwm[1] },
2870 { .attrs = nct6775_attributes_pwm[2] },
2871 { .attrs = nct6775_attributes_pwm[3] },
2872 { .attrs = nct6775_attributes_pwm[4] },
2873};
2874
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07002875static ssize_t
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002876show_auto_pwm(struct device *dev, struct device_attribute *attr, char *buf)
2877{
2878 struct nct6775_data *data = nct6775_update_device(dev);
2879 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2880
2881 return sprintf(buf, "%d\n", data->auto_pwm[sattr->nr][sattr->index]);
2882}
2883
2884static ssize_t
2885store_auto_pwm(struct device *dev, struct device_attribute *attr,
2886 const char *buf, size_t count)
2887{
2888 struct nct6775_data *data = dev_get_drvdata(dev);
2889 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2890 int nr = sattr->nr;
2891 int point = sattr->index;
2892 unsigned long val;
2893 int err;
2894 u8 reg;
2895
2896 err = kstrtoul(buf, 10, &val);
2897 if (err < 0)
2898 return err;
2899 if (val > 255)
2900 return -EINVAL;
2901
2902 if (point == data->auto_pwm_num) {
2903 if (data->kind != nct6775 && !val)
2904 return -EINVAL;
2905 if (data->kind != nct6779 && val)
2906 val = 0xff;
2907 }
2908
2909 mutex_lock(&data->update_lock);
2910 data->auto_pwm[nr][point] = val;
2911 if (point < data->auto_pwm_num) {
2912 nct6775_write_value(data,
2913 NCT6775_AUTO_PWM(data, nr, point),
2914 data->auto_pwm[nr][point]);
2915 } else {
2916 switch (data->kind) {
2917 case nct6775:
2918 /* disable if needed (pwm == 0) */
2919 reg = nct6775_read_value(data,
2920 NCT6775_REG_CRITICAL_ENAB[nr]);
2921 if (val)
2922 reg |= 0x02;
2923 else
2924 reg &= ~0x02;
2925 nct6775_write_value(data, NCT6775_REG_CRITICAL_ENAB[nr],
2926 reg);
2927 break;
2928 case nct6776:
2929 break; /* always enabled, nothing to do */
2930 case nct6779:
2931 nct6775_write_value(data, NCT6779_REG_CRITICAL_PWM[nr],
2932 val);
2933 reg = nct6775_read_value(data,
2934 NCT6779_REG_CRITICAL_PWM_ENABLE[nr]);
2935 if (val == 255)
2936 reg &= ~0x01;
2937 else
2938 reg |= 0x01;
2939 nct6775_write_value(data,
2940 NCT6779_REG_CRITICAL_PWM_ENABLE[nr],
2941 reg);
2942 break;
2943 }
2944 }
2945 mutex_unlock(&data->update_lock);
2946 return count;
2947}
2948
2949static ssize_t
2950show_auto_temp(struct device *dev, struct device_attribute *attr, char *buf)
2951{
2952 struct nct6775_data *data = nct6775_update_device(dev);
2953 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2954 int nr = sattr->nr;
2955 int point = sattr->index;
2956
2957 /*
2958 * We don't know for sure if the temperature is signed or unsigned.
2959 * Assume it is unsigned.
2960 */
2961 return sprintf(buf, "%d\n", data->auto_temp[nr][point] * 1000);
2962}
2963
2964static ssize_t
2965store_auto_temp(struct device *dev, struct device_attribute *attr,
2966 const char *buf, size_t count)
2967{
2968 struct nct6775_data *data = dev_get_drvdata(dev);
2969 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2970 int nr = sattr->nr;
2971 int point = sattr->index;
2972 unsigned long val;
2973 int err;
2974
2975 err = kstrtoul(buf, 10, &val);
2976 if (err)
2977 return err;
2978 if (val > 255000)
2979 return -EINVAL;
2980
2981 mutex_lock(&data->update_lock);
2982 data->auto_temp[nr][point] = DIV_ROUND_CLOSEST(val, 1000);
2983 if (point < data->auto_pwm_num) {
2984 nct6775_write_value(data,
2985 NCT6775_AUTO_TEMP(data, nr, point),
2986 data->auto_temp[nr][point]);
2987 } else {
2988 nct6775_write_value(data, data->REG_CRITICAL_TEMP[nr],
2989 data->auto_temp[nr][point]);
2990 }
2991 mutex_unlock(&data->update_lock);
2992 return count;
2993}
2994
2995/*
2996 * The number of auto-point trip points is chip dependent.
2997 * Need to check support while generating/removing attribute files.
2998 */
2999static struct sensor_device_attribute_2 sda_auto_pwm_arrays[] = {
3000 SENSOR_ATTR_2(pwm1_auto_point1_pwm, S_IWUSR | S_IRUGO,
3001 show_auto_pwm, store_auto_pwm, 0, 0),
3002 SENSOR_ATTR_2(pwm1_auto_point1_temp, S_IWUSR | S_IRUGO,
3003 show_auto_temp, store_auto_temp, 0, 0),
3004 SENSOR_ATTR_2(pwm1_auto_point2_pwm, S_IWUSR | S_IRUGO,
3005 show_auto_pwm, store_auto_pwm, 0, 1),
3006 SENSOR_ATTR_2(pwm1_auto_point2_temp, S_IWUSR | S_IRUGO,
3007 show_auto_temp, store_auto_temp, 0, 1),
3008 SENSOR_ATTR_2(pwm1_auto_point3_pwm, S_IWUSR | S_IRUGO,
3009 show_auto_pwm, store_auto_pwm, 0, 2),
3010 SENSOR_ATTR_2(pwm1_auto_point3_temp, S_IWUSR | S_IRUGO,
3011 show_auto_temp, store_auto_temp, 0, 2),
3012 SENSOR_ATTR_2(pwm1_auto_point4_pwm, S_IWUSR | S_IRUGO,
3013 show_auto_pwm, store_auto_pwm, 0, 3),
3014 SENSOR_ATTR_2(pwm1_auto_point4_temp, S_IWUSR | S_IRUGO,
3015 show_auto_temp, store_auto_temp, 0, 3),
3016 SENSOR_ATTR_2(pwm1_auto_point5_pwm, S_IWUSR | S_IRUGO,
3017 show_auto_pwm, store_auto_pwm, 0, 4),
3018 SENSOR_ATTR_2(pwm1_auto_point5_temp, S_IWUSR | S_IRUGO,
3019 show_auto_temp, store_auto_temp, 0, 4),
3020 SENSOR_ATTR_2(pwm1_auto_point6_pwm, S_IWUSR | S_IRUGO,
3021 show_auto_pwm, store_auto_pwm, 0, 5),
3022 SENSOR_ATTR_2(pwm1_auto_point6_temp, S_IWUSR | S_IRUGO,
3023 show_auto_temp, store_auto_temp, 0, 5),
3024 SENSOR_ATTR_2(pwm1_auto_point7_pwm, S_IWUSR | S_IRUGO,
3025 show_auto_pwm, store_auto_pwm, 0, 6),
3026 SENSOR_ATTR_2(pwm1_auto_point7_temp, S_IWUSR | S_IRUGO,
3027 show_auto_temp, store_auto_temp, 0, 6),
3028
3029 SENSOR_ATTR_2(pwm2_auto_point1_pwm, S_IWUSR | S_IRUGO,
3030 show_auto_pwm, store_auto_pwm, 1, 0),
3031 SENSOR_ATTR_2(pwm2_auto_point1_temp, S_IWUSR | S_IRUGO,
3032 show_auto_temp, store_auto_temp, 1, 0),
3033 SENSOR_ATTR_2(pwm2_auto_point2_pwm, S_IWUSR | S_IRUGO,
3034 show_auto_pwm, store_auto_pwm, 1, 1),
3035 SENSOR_ATTR_2(pwm2_auto_point2_temp, S_IWUSR | S_IRUGO,
3036 show_auto_temp, store_auto_temp, 1, 1),
3037 SENSOR_ATTR_2(pwm2_auto_point3_pwm, S_IWUSR | S_IRUGO,
3038 show_auto_pwm, store_auto_pwm, 1, 2),
3039 SENSOR_ATTR_2(pwm2_auto_point3_temp, S_IWUSR | S_IRUGO,
3040 show_auto_temp, store_auto_temp, 1, 2),
3041 SENSOR_ATTR_2(pwm2_auto_point4_pwm, S_IWUSR | S_IRUGO,
3042 show_auto_pwm, store_auto_pwm, 1, 3),
3043 SENSOR_ATTR_2(pwm2_auto_point4_temp, S_IWUSR | S_IRUGO,
3044 show_auto_temp, store_auto_temp, 1, 3),
3045 SENSOR_ATTR_2(pwm2_auto_point5_pwm, S_IWUSR | S_IRUGO,
3046 show_auto_pwm, store_auto_pwm, 1, 4),
3047 SENSOR_ATTR_2(pwm2_auto_point5_temp, S_IWUSR | S_IRUGO,
3048 show_auto_temp, store_auto_temp, 1, 4),
3049 SENSOR_ATTR_2(pwm2_auto_point6_pwm, S_IWUSR | S_IRUGO,
3050 show_auto_pwm, store_auto_pwm, 1, 5),
3051 SENSOR_ATTR_2(pwm2_auto_point6_temp, S_IWUSR | S_IRUGO,
3052 show_auto_temp, store_auto_temp, 1, 5),
3053 SENSOR_ATTR_2(pwm2_auto_point7_pwm, S_IWUSR | S_IRUGO,
3054 show_auto_pwm, store_auto_pwm, 1, 6),
3055 SENSOR_ATTR_2(pwm2_auto_point7_temp, S_IWUSR | S_IRUGO,
3056 show_auto_temp, store_auto_temp, 1, 6),
3057
3058 SENSOR_ATTR_2(pwm3_auto_point1_pwm, S_IWUSR | S_IRUGO,
3059 show_auto_pwm, store_auto_pwm, 2, 0),
3060 SENSOR_ATTR_2(pwm3_auto_point1_temp, S_IWUSR | S_IRUGO,
3061 show_auto_temp, store_auto_temp, 2, 0),
3062 SENSOR_ATTR_2(pwm3_auto_point2_pwm, S_IWUSR | S_IRUGO,
3063 show_auto_pwm, store_auto_pwm, 2, 1),
3064 SENSOR_ATTR_2(pwm3_auto_point2_temp, S_IWUSR | S_IRUGO,
3065 show_auto_temp, store_auto_temp, 2, 1),
3066 SENSOR_ATTR_2(pwm3_auto_point3_pwm, S_IWUSR | S_IRUGO,
3067 show_auto_pwm, store_auto_pwm, 2, 2),
3068 SENSOR_ATTR_2(pwm3_auto_point3_temp, S_IWUSR | S_IRUGO,
3069 show_auto_temp, store_auto_temp, 2, 2),
3070 SENSOR_ATTR_2(pwm3_auto_point4_pwm, S_IWUSR | S_IRUGO,
3071 show_auto_pwm, store_auto_pwm, 2, 3),
3072 SENSOR_ATTR_2(pwm3_auto_point4_temp, S_IWUSR | S_IRUGO,
3073 show_auto_temp, store_auto_temp, 2, 3),
3074 SENSOR_ATTR_2(pwm3_auto_point5_pwm, S_IWUSR | S_IRUGO,
3075 show_auto_pwm, store_auto_pwm, 2, 4),
3076 SENSOR_ATTR_2(pwm3_auto_point5_temp, S_IWUSR | S_IRUGO,
3077 show_auto_temp, store_auto_temp, 2, 4),
3078 SENSOR_ATTR_2(pwm3_auto_point6_pwm, S_IWUSR | S_IRUGO,
3079 show_auto_pwm, store_auto_pwm, 2, 5),
3080 SENSOR_ATTR_2(pwm3_auto_point6_temp, S_IWUSR | S_IRUGO,
3081 show_auto_temp, store_auto_temp, 2, 5),
3082 SENSOR_ATTR_2(pwm3_auto_point7_pwm, S_IWUSR | S_IRUGO,
3083 show_auto_pwm, store_auto_pwm, 2, 6),
3084 SENSOR_ATTR_2(pwm3_auto_point7_temp, S_IWUSR | S_IRUGO,
3085 show_auto_temp, store_auto_temp, 2, 6),
3086
3087 SENSOR_ATTR_2(pwm4_auto_point1_pwm, S_IWUSR | S_IRUGO,
3088 show_auto_pwm, store_auto_pwm, 3, 0),
3089 SENSOR_ATTR_2(pwm4_auto_point1_temp, S_IWUSR | S_IRUGO,
3090 show_auto_temp, store_auto_temp, 3, 0),
3091 SENSOR_ATTR_2(pwm4_auto_point2_pwm, S_IWUSR | S_IRUGO,
3092 show_auto_pwm, store_auto_pwm, 3, 1),
3093 SENSOR_ATTR_2(pwm4_auto_point2_temp, S_IWUSR | S_IRUGO,
3094 show_auto_temp, store_auto_temp, 3, 1),
3095 SENSOR_ATTR_2(pwm4_auto_point3_pwm, S_IWUSR | S_IRUGO,
3096 show_auto_pwm, store_auto_pwm, 3, 2),
3097 SENSOR_ATTR_2(pwm4_auto_point3_temp, S_IWUSR | S_IRUGO,
3098 show_auto_temp, store_auto_temp, 3, 2),
3099 SENSOR_ATTR_2(pwm4_auto_point4_pwm, S_IWUSR | S_IRUGO,
3100 show_auto_pwm, store_auto_pwm, 3, 3),
3101 SENSOR_ATTR_2(pwm4_auto_point4_temp, S_IWUSR | S_IRUGO,
3102 show_auto_temp, store_auto_temp, 3, 3),
3103 SENSOR_ATTR_2(pwm4_auto_point5_pwm, S_IWUSR | S_IRUGO,
3104 show_auto_pwm, store_auto_pwm, 3, 4),
3105 SENSOR_ATTR_2(pwm4_auto_point5_temp, S_IWUSR | S_IRUGO,
3106 show_auto_temp, store_auto_temp, 3, 4),
3107 SENSOR_ATTR_2(pwm4_auto_point6_pwm, S_IWUSR | S_IRUGO,
3108 show_auto_pwm, store_auto_pwm, 3, 5),
3109 SENSOR_ATTR_2(pwm4_auto_point6_temp, S_IWUSR | S_IRUGO,
3110 show_auto_temp, store_auto_temp, 3, 5),
3111 SENSOR_ATTR_2(pwm4_auto_point7_pwm, S_IWUSR | S_IRUGO,
3112 show_auto_pwm, store_auto_pwm, 3, 6),
3113 SENSOR_ATTR_2(pwm4_auto_point7_temp, S_IWUSR | S_IRUGO,
3114 show_auto_temp, store_auto_temp, 3, 6),
3115
3116 SENSOR_ATTR_2(pwm5_auto_point1_pwm, S_IWUSR | S_IRUGO,
3117 show_auto_pwm, store_auto_pwm, 4, 0),
3118 SENSOR_ATTR_2(pwm5_auto_point1_temp, S_IWUSR | S_IRUGO,
3119 show_auto_temp, store_auto_temp, 4, 0),
3120 SENSOR_ATTR_2(pwm5_auto_point2_pwm, S_IWUSR | S_IRUGO,
3121 show_auto_pwm, store_auto_pwm, 4, 1),
3122 SENSOR_ATTR_2(pwm5_auto_point2_temp, S_IWUSR | S_IRUGO,
3123 show_auto_temp, store_auto_temp, 4, 1),
3124 SENSOR_ATTR_2(pwm5_auto_point3_pwm, S_IWUSR | S_IRUGO,
3125 show_auto_pwm, store_auto_pwm, 4, 2),
3126 SENSOR_ATTR_2(pwm5_auto_point3_temp, S_IWUSR | S_IRUGO,
3127 show_auto_temp, store_auto_temp, 4, 2),
3128 SENSOR_ATTR_2(pwm5_auto_point4_pwm, S_IWUSR | S_IRUGO,
3129 show_auto_pwm, store_auto_pwm, 4, 3),
3130 SENSOR_ATTR_2(pwm5_auto_point4_temp, S_IWUSR | S_IRUGO,
3131 show_auto_temp, store_auto_temp, 4, 3),
3132 SENSOR_ATTR_2(pwm5_auto_point5_pwm, S_IWUSR | S_IRUGO,
3133 show_auto_pwm, store_auto_pwm, 4, 4),
3134 SENSOR_ATTR_2(pwm5_auto_point5_temp, S_IWUSR | S_IRUGO,
3135 show_auto_temp, store_auto_temp, 4, 4),
3136 SENSOR_ATTR_2(pwm5_auto_point6_pwm, S_IWUSR | S_IRUGO,
3137 show_auto_pwm, store_auto_pwm, 4, 5),
3138 SENSOR_ATTR_2(pwm5_auto_point6_temp, S_IWUSR | S_IRUGO,
3139 show_auto_temp, store_auto_temp, 4, 5),
3140 SENSOR_ATTR_2(pwm5_auto_point7_pwm, S_IWUSR | S_IRUGO,
3141 show_auto_pwm, store_auto_pwm, 4, 6),
3142 SENSOR_ATTR_2(pwm5_auto_point7_temp, S_IWUSR | S_IRUGO,
3143 show_auto_temp, store_auto_temp, 4, 6),
3144};
3145
3146static ssize_t
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003147show_vid(struct device *dev, struct device_attribute *attr, char *buf)
3148{
3149 struct nct6775_data *data = dev_get_drvdata(dev);
3150 return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm));
3151}
3152
3153static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL);
3154
Guenter Roecka6bd5872012-12-04 03:13:34 -08003155/* Case open detection */
3156
3157static ssize_t
3158clear_caseopen(struct device *dev, struct device_attribute *attr,
3159 const char *buf, size_t count)
3160{
3161 struct nct6775_data *data = dev_get_drvdata(dev);
3162 struct nct6775_sio_data *sio_data = dev->platform_data;
3163 int nr = to_sensor_dev_attr(attr)->index - INTRUSION_ALARM_BASE;
3164 unsigned long val;
3165 u8 reg;
3166 int ret;
3167
3168 if (kstrtoul(buf, 10, &val) || val != 0)
3169 return -EINVAL;
3170
3171 mutex_lock(&data->update_lock);
3172
3173 /*
3174 * Use CR registers to clear caseopen status.
3175 * The CR registers are the same for all chips, and not all chips
3176 * support clearing the caseopen status through "regular" registers.
3177 */
3178 ret = superio_enter(sio_data->sioreg);
3179 if (ret) {
3180 count = ret;
3181 goto error;
3182 }
3183
3184 superio_select(sio_data->sioreg, NCT6775_LD_ACPI);
3185 reg = superio_inb(sio_data->sioreg, NCT6775_REG_CR_CASEOPEN_CLR[nr]);
3186 reg |= NCT6775_CR_CASEOPEN_CLR_MASK[nr];
3187 superio_outb(sio_data->sioreg, NCT6775_REG_CR_CASEOPEN_CLR[nr], reg);
3188 reg &= ~NCT6775_CR_CASEOPEN_CLR_MASK[nr];
3189 superio_outb(sio_data->sioreg, NCT6775_REG_CR_CASEOPEN_CLR[nr], reg);
3190 superio_exit(sio_data->sioreg);
3191
3192 data->valid = false; /* Force cache refresh */
3193error:
3194 mutex_unlock(&data->update_lock);
3195 return count;
3196}
3197
3198static struct sensor_device_attribute sda_caseopen[] = {
3199 SENSOR_ATTR(intrusion0_alarm, S_IWUSR | S_IRUGO, show_alarm,
3200 clear_caseopen, INTRUSION_ALARM_BASE),
3201 SENSOR_ATTR(intrusion1_alarm, S_IWUSR | S_IRUGO, show_alarm,
3202 clear_caseopen, INTRUSION_ALARM_BASE + 1),
3203};
3204
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003205/*
3206 * Driver and device management
3207 */
3208
3209static void nct6775_device_remove_files(struct device *dev)
3210{
3211 /*
3212 * some entries in the following arrays may not have been used in
3213 * device_create_file(), but device_remove_file() will ignore them
3214 */
3215 int i;
3216 struct nct6775_data *data = dev_get_drvdata(dev);
3217
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003218 for (i = 0; i < data->pwm_num; i++)
3219 sysfs_remove_group(&dev->kobj, &nct6775_group_pwm[i]);
3220
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003221 for (i = 0; i < ARRAY_SIZE(sda_pwm_max); i++)
3222 device_remove_file(dev, &sda_pwm_max[i].dev_attr);
3223
3224 for (i = 0; i < ARRAY_SIZE(sda_pwm_step); i++)
3225 device_remove_file(dev, &sda_pwm_step[i].dev_attr);
3226
Guenter Roeckbbd8dec2012-12-04 09:08:29 -08003227 for (i = 0; i < ARRAY_SIZE(sda_weight_duty_base); i++)
3228 device_remove_file(dev, &sda_weight_duty_base[i].dev_attr);
3229
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003230 for (i = 0; i < ARRAY_SIZE(sda_auto_pwm_arrays); i++)
3231 device_remove_file(dev, &sda_auto_pwm_arrays[i].dev_attr);
3232
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003233 for (i = 0; i < data->in_num; i++)
3234 sysfs_remove_group(&dev->kobj, &nct6775_group_in[i]);
3235
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003236 for (i = 0; i < 5; i++) {
3237 device_remove_file(dev, &sda_fan_input[i].dev_attr);
3238 device_remove_file(dev, &sda_fan_alarm[i].dev_attr);
3239 device_remove_file(dev, &sda_fan_div[i].dev_attr);
3240 device_remove_file(dev, &sda_fan_min[i].dev_attr);
Guenter Roeck5c25d952012-12-11 07:29:06 -08003241 device_remove_file(dev, &sda_fan_pulses[i].dev_attr);
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003242 }
Guenter Roeckaa136e52012-12-04 03:26:05 -08003243 for (i = 0; i < NUM_TEMP; i++) {
3244 if (!(data->have_temp & (1 << i)))
3245 continue;
3246 device_remove_file(dev, &sda_temp_input[i].dev_attr);
3247 device_remove_file(dev, &sda_temp_label[i].dev_attr);
3248 device_remove_file(dev, &sda_temp_max[i].dev_attr);
3249 device_remove_file(dev, &sda_temp_max_hyst[i].dev_attr);
3250 device_remove_file(dev, &sda_temp_crit[i].dev_attr);
Guenter Roeckb1d2bff2013-06-22 16:15:31 -07003251 device_remove_file(dev, &sda_temp_alarm[i].dev_attr);
Guenter Roeckaa136e52012-12-04 03:26:05 -08003252 if (!(data->have_temp_fixed & (1 << i)))
3253 continue;
3254 device_remove_file(dev, &sda_temp_type[i].dev_attr);
3255 device_remove_file(dev, &sda_temp_offset[i].dev_attr);
Guenter Roeckaa136e52012-12-04 03:26:05 -08003256 }
3257
Guenter Roecka6bd5872012-12-04 03:13:34 -08003258 device_remove_file(dev, &sda_caseopen[0].dev_attr);
3259 device_remove_file(dev, &sda_caseopen[1].dev_attr);
3260
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003261 device_remove_file(dev, &dev_attr_name);
3262 device_remove_file(dev, &dev_attr_cpu0_vid);
3263}
3264
3265/* Get the monitoring functions started */
3266static inline void nct6775_init_device(struct nct6775_data *data)
3267{
Guenter Roeckaa136e52012-12-04 03:26:05 -08003268 int i;
3269 u8 tmp, diode;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003270
3271 /* Start monitoring if needed */
3272 if (data->REG_CONFIG) {
3273 tmp = nct6775_read_value(data, data->REG_CONFIG);
3274 if (!(tmp & 0x01))
3275 nct6775_write_value(data, data->REG_CONFIG, tmp | 0x01);
3276 }
3277
Guenter Roeckaa136e52012-12-04 03:26:05 -08003278 /* Enable temperature sensors if needed */
3279 for (i = 0; i < NUM_TEMP; i++) {
3280 if (!(data->have_temp & (1 << i)))
3281 continue;
3282 if (!data->reg_temp_config[i])
3283 continue;
3284 tmp = nct6775_read_value(data, data->reg_temp_config[i]);
3285 if (tmp & 0x01)
3286 nct6775_write_value(data, data->reg_temp_config[i],
3287 tmp & 0xfe);
3288 }
3289
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003290 /* Enable VBAT monitoring if needed */
3291 tmp = nct6775_read_value(data, data->REG_VBAT);
3292 if (!(tmp & 0x01))
3293 nct6775_write_value(data, data->REG_VBAT, tmp | 0x01);
Guenter Roeckaa136e52012-12-04 03:26:05 -08003294
3295 diode = nct6775_read_value(data, data->REG_DIODE);
3296
3297 for (i = 0; i < data->temp_fixed_num; i++) {
3298 if (!(data->have_temp_fixed & (1 << i)))
3299 continue;
3300 if ((tmp & (0x02 << i))) /* diode */
3301 data->temp_type[i] = 3 - ((diode >> i) & 0x02);
3302 else /* thermistor */
3303 data->temp_type[i] = 4;
3304 }
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003305}
3306
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003307static int
3308nct6775_check_fan_inputs(const struct nct6775_sio_data *sio_data,
3309 struct nct6775_data *data)
3310{
3311 int regval;
3312 bool fan3pin, fan3min, fan4pin, fan4min, fan5pin;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003313 bool pwm3pin, pwm4pin, pwm5pin;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003314 int ret;
3315
3316 ret = superio_enter(sio_data->sioreg);
3317 if (ret)
3318 return ret;
3319
3320 /* fan4 and fan5 share some pins with the GPIO and serial flash */
3321 if (data->kind == nct6775) {
3322 regval = superio_inb(sio_data->sioreg, 0x2c);
3323
3324 fan3pin = regval & (1 << 6);
3325 fan3min = fan3pin;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003326 pwm3pin = regval & (1 << 7);
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003327
3328 /* On NCT6775, fan4 shares pins with the fdc interface */
3329 fan4pin = !(superio_inb(sio_data->sioreg, 0x2A) & 0x80);
3330 fan4min = 0;
3331 fan5pin = 0;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003332 pwm4pin = 0;
3333 pwm5pin = 0;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003334 } else if (data->kind == nct6776) {
3335 bool gpok = superio_inb(sio_data->sioreg, 0x27) & 0x80;
3336
3337 superio_select(sio_data->sioreg, NCT6775_LD_HWM);
3338 regval = superio_inb(sio_data->sioreg, SIO_REG_ENABLE);
3339
3340 if (regval & 0x80)
3341 fan3pin = gpok;
3342 else
3343 fan3pin = !(superio_inb(sio_data->sioreg, 0x24) & 0x40);
3344
3345 if (regval & 0x40)
3346 fan4pin = gpok;
3347 else
3348 fan4pin = superio_inb(sio_data->sioreg, 0x1C) & 0x01;
3349
3350 if (regval & 0x20)
3351 fan5pin = gpok;
3352 else
3353 fan5pin = superio_inb(sio_data->sioreg, 0x1C) & 0x02;
3354
3355 fan4min = fan4pin;
3356 fan3min = fan3pin;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003357 pwm3pin = fan3pin;
3358 pwm4pin = 0;
3359 pwm5pin = 0;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003360 } else { /* NCT6779D */
3361 regval = superio_inb(sio_data->sioreg, 0x1c);
3362
3363 fan3pin = !(regval & (1 << 5));
3364 fan4pin = !(regval & (1 << 6));
3365 fan5pin = !(regval & (1 << 7));
3366
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003367 pwm3pin = !(regval & (1 << 0));
3368 pwm4pin = !(regval & (1 << 1));
3369 pwm5pin = !(regval & (1 << 2));
3370
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003371 fan3min = fan3pin;
3372 fan4min = fan4pin;
3373 }
3374
3375 superio_exit(sio_data->sioreg);
3376
3377 data->has_fan = data->has_fan_min = 0x03; /* fan1 and fan2 */
3378 data->has_fan |= fan3pin << 2;
3379 data->has_fan_min |= fan3min << 2;
3380
3381 data->has_fan |= (fan4pin << 3) | (fan5pin << 4);
3382 data->has_fan_min |= (fan4min << 3) | (fan5pin << 4);
3383
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003384 data->has_pwm = 0x03 | (pwm3pin << 2) | (pwm4pin << 3) | (pwm5pin << 4);
3385
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003386 return 0;
3387}
3388
Guenter Roeck8e9285b2012-12-04 08:03:37 -08003389static void add_temp_sensors(struct nct6775_data *data, const u16 *regp,
3390 int *available, int *mask)
3391{
3392 int i;
3393 u8 src;
3394
3395 for (i = 0; i < data->pwm_num && *available; i++) {
3396 int index;
3397
3398 if (!regp[i])
3399 continue;
3400 src = nct6775_read_value(data, regp[i]);
3401 src &= 0x1f;
3402 if (!src || (*mask & (1 << src)))
3403 continue;
3404 if (src >= data->temp_label_num ||
3405 !strlen(data->temp_label[src]))
3406 continue;
3407
3408 index = __ffs(*available);
3409 nct6775_write_value(data, data->REG_TEMP_SOURCE[index], src);
3410 *available &= ~(1 << index);
3411 *mask |= 1 << src;
3412 }
3413}
3414
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003415static int nct6775_probe(struct platform_device *pdev)
3416{
3417 struct device *dev = &pdev->dev;
3418 struct nct6775_sio_data *sio_data = dev->platform_data;
3419 struct nct6775_data *data;
3420 struct resource *res;
Guenter Roeckaa136e52012-12-04 03:26:05 -08003421 int i, s, err = 0;
3422 int src, mask, available;
3423 const u16 *reg_temp, *reg_temp_over, *reg_temp_hyst, *reg_temp_config;
3424 const u16 *reg_temp_alternate, *reg_temp_crit;
3425 int num_reg_temp;
Guenter Roeck0fc1f8f2013-02-26 09:43:50 -08003426 bool have_vid = false;
3427 u8 cr2a;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003428
3429 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
3430 if (!devm_request_region(&pdev->dev, res->start, IOREGION_LENGTH,
3431 DRVNAME))
3432 return -EBUSY;
3433
3434 data = devm_kzalloc(&pdev->dev, sizeof(struct nct6775_data),
3435 GFP_KERNEL);
3436 if (!data)
3437 return -ENOMEM;
3438
3439 data->kind = sio_data->kind;
3440 data->addr = res->start;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003441 mutex_init(&data->update_lock);
3442 data->name = nct6775_device_names[data->kind];
3443 data->bank = 0xff; /* Force initial bank selection */
3444 platform_set_drvdata(pdev, data);
3445
3446 switch (data->kind) {
3447 case nct6775:
3448 data->in_num = 9;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003449 data->pwm_num = 3;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003450 data->auto_pwm_num = 6;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003451 data->has_fan_div = true;
Guenter Roeckaa136e52012-12-04 03:26:05 -08003452 data->temp_fixed_num = 3;
Guenter Roeckb1d2bff2013-06-22 16:15:31 -07003453 data->num_temp_alarms = 3;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003454
3455 data->ALARM_BITS = NCT6775_ALARM_BITS;
3456
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003457 data->fan_from_reg = fan_from_reg16;
3458 data->fan_from_reg_min = fan_from_reg8;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003459 data->target_temp_mask = 0x7f;
3460 data->tolerance_mask = 0x0f;
3461 data->speed_tolerance_limit = 15;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003462
Guenter Roeckaa136e52012-12-04 03:26:05 -08003463 data->temp_label = nct6775_temp_label;
3464 data->temp_label_num = ARRAY_SIZE(nct6775_temp_label);
3465
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003466 data->REG_CONFIG = NCT6775_REG_CONFIG;
3467 data->REG_VBAT = NCT6775_REG_VBAT;
Guenter Roeckaa136e52012-12-04 03:26:05 -08003468 data->REG_DIODE = NCT6775_REG_DIODE;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003469 data->REG_VIN = NCT6775_REG_IN;
3470 data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN;
3471 data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003472 data->REG_TARGET = NCT6775_REG_TARGET;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003473 data->REG_FAN = NCT6775_REG_FAN;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003474 data->REG_FAN_MODE = NCT6775_REG_FAN_MODE;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003475 data->REG_FAN_MIN = NCT6775_REG_FAN_MIN;
Guenter Roeck5c25d952012-12-11 07:29:06 -08003476 data->REG_FAN_PULSES = NCT6775_REG_FAN_PULSES;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003477 data->REG_FAN_TIME[0] = NCT6775_REG_FAN_STOP_TIME;
3478 data->REG_FAN_TIME[1] = NCT6775_REG_FAN_STEP_UP_TIME;
3479 data->REG_FAN_TIME[2] = NCT6775_REG_FAN_STEP_DOWN_TIME;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003480 data->REG_PWM[0] = NCT6775_REG_PWM;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003481 data->REG_PWM[1] = NCT6775_REG_FAN_START_OUTPUT;
3482 data->REG_PWM[2] = NCT6775_REG_FAN_STOP_OUTPUT;
3483 data->REG_PWM[3] = NCT6775_REG_FAN_MAX_OUTPUT;
3484 data->REG_PWM[4] = NCT6775_REG_FAN_STEP_OUTPUT;
Guenter Roeckbbd8dec2012-12-04 09:08:29 -08003485 data->REG_PWM[5] = NCT6775_REG_WEIGHT_DUTY_STEP;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003486 data->REG_PWM_READ = NCT6775_REG_PWM_READ;
3487 data->REG_PWM_MODE = NCT6775_REG_PWM_MODE;
3488 data->PWM_MODE_MASK = NCT6775_PWM_MODE_MASK;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003489 data->REG_AUTO_TEMP = NCT6775_REG_AUTO_TEMP;
3490 data->REG_AUTO_PWM = NCT6775_REG_AUTO_PWM;
3491 data->REG_CRITICAL_TEMP = NCT6775_REG_CRITICAL_TEMP;
3492 data->REG_CRITICAL_TEMP_TOLERANCE
3493 = NCT6775_REG_CRITICAL_TEMP_TOLERANCE;
Guenter Roeckaa136e52012-12-04 03:26:05 -08003494 data->REG_TEMP_OFFSET = NCT6775_REG_TEMP_OFFSET;
3495 data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003496 data->REG_TEMP_SEL = NCT6775_REG_TEMP_SEL;
Guenter Roeckbbd8dec2012-12-04 09:08:29 -08003497 data->REG_WEIGHT_TEMP_SEL = NCT6775_REG_WEIGHT_TEMP_SEL;
3498 data->REG_WEIGHT_TEMP[0] = NCT6775_REG_WEIGHT_TEMP_STEP;
3499 data->REG_WEIGHT_TEMP[1] = NCT6775_REG_WEIGHT_TEMP_STEP_TOL;
3500 data->REG_WEIGHT_TEMP[2] = NCT6775_REG_WEIGHT_TEMP_BASE;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003501 data->REG_ALARM = NCT6775_REG_ALARM;
Guenter Roeckaa136e52012-12-04 03:26:05 -08003502
3503 reg_temp = NCT6775_REG_TEMP;
3504 num_reg_temp = ARRAY_SIZE(NCT6775_REG_TEMP);
3505 reg_temp_over = NCT6775_REG_TEMP_OVER;
3506 reg_temp_hyst = NCT6775_REG_TEMP_HYST;
3507 reg_temp_config = NCT6775_REG_TEMP_CONFIG;
3508 reg_temp_alternate = NCT6775_REG_TEMP_ALTERNATE;
3509 reg_temp_crit = NCT6775_REG_TEMP_CRIT;
3510
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003511 break;
3512 case nct6776:
3513 data->in_num = 9;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003514 data->pwm_num = 3;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003515 data->auto_pwm_num = 4;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003516 data->has_fan_div = false;
Guenter Roeckaa136e52012-12-04 03:26:05 -08003517 data->temp_fixed_num = 3;
Guenter Roeckb1d2bff2013-06-22 16:15:31 -07003518 data->num_temp_alarms = 3;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003519
3520 data->ALARM_BITS = NCT6776_ALARM_BITS;
3521
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003522 data->fan_from_reg = fan_from_reg13;
3523 data->fan_from_reg_min = fan_from_reg13;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003524 data->target_temp_mask = 0xff;
3525 data->tolerance_mask = 0x07;
3526 data->speed_tolerance_limit = 63;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003527
Guenter Roeckaa136e52012-12-04 03:26:05 -08003528 data->temp_label = nct6776_temp_label;
3529 data->temp_label_num = ARRAY_SIZE(nct6776_temp_label);
3530
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003531 data->REG_CONFIG = NCT6775_REG_CONFIG;
3532 data->REG_VBAT = NCT6775_REG_VBAT;
Guenter Roeckaa136e52012-12-04 03:26:05 -08003533 data->REG_DIODE = NCT6775_REG_DIODE;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003534 data->REG_VIN = NCT6775_REG_IN;
3535 data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN;
3536 data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003537 data->REG_TARGET = NCT6775_REG_TARGET;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003538 data->REG_FAN = NCT6775_REG_FAN;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003539 data->REG_FAN_MODE = NCT6775_REG_FAN_MODE;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003540 data->REG_FAN_MIN = NCT6776_REG_FAN_MIN;
Guenter Roeck5c25d952012-12-11 07:29:06 -08003541 data->REG_FAN_PULSES = NCT6776_REG_FAN_PULSES;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003542 data->REG_FAN_TIME[0] = NCT6775_REG_FAN_STOP_TIME;
3543 data->REG_FAN_TIME[1] = NCT6775_REG_FAN_STEP_UP_TIME;
3544 data->REG_FAN_TIME[2] = NCT6775_REG_FAN_STEP_DOWN_TIME;
3545 data->REG_TOLERANCE_H = NCT6776_REG_TOLERANCE_H;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003546 data->REG_PWM[0] = NCT6775_REG_PWM;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003547 data->REG_PWM[1] = NCT6775_REG_FAN_START_OUTPUT;
3548 data->REG_PWM[2] = NCT6775_REG_FAN_STOP_OUTPUT;
Guenter Roeckbbd8dec2012-12-04 09:08:29 -08003549 data->REG_PWM[5] = NCT6775_REG_WEIGHT_DUTY_STEP;
3550 data->REG_PWM[6] = NCT6776_REG_WEIGHT_DUTY_BASE;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003551 data->REG_PWM_READ = NCT6775_REG_PWM_READ;
3552 data->REG_PWM_MODE = NCT6776_REG_PWM_MODE;
3553 data->PWM_MODE_MASK = NCT6776_PWM_MODE_MASK;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003554 data->REG_AUTO_TEMP = NCT6775_REG_AUTO_TEMP;
3555 data->REG_AUTO_PWM = NCT6775_REG_AUTO_PWM;
3556 data->REG_CRITICAL_TEMP = NCT6775_REG_CRITICAL_TEMP;
3557 data->REG_CRITICAL_TEMP_TOLERANCE
3558 = NCT6775_REG_CRITICAL_TEMP_TOLERANCE;
Guenter Roeckaa136e52012-12-04 03:26:05 -08003559 data->REG_TEMP_OFFSET = NCT6775_REG_TEMP_OFFSET;
3560 data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003561 data->REG_TEMP_SEL = NCT6775_REG_TEMP_SEL;
Guenter Roeckbbd8dec2012-12-04 09:08:29 -08003562 data->REG_WEIGHT_TEMP_SEL = NCT6775_REG_WEIGHT_TEMP_SEL;
3563 data->REG_WEIGHT_TEMP[0] = NCT6775_REG_WEIGHT_TEMP_STEP;
3564 data->REG_WEIGHT_TEMP[1] = NCT6775_REG_WEIGHT_TEMP_STEP_TOL;
3565 data->REG_WEIGHT_TEMP[2] = NCT6775_REG_WEIGHT_TEMP_BASE;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003566 data->REG_ALARM = NCT6775_REG_ALARM;
Guenter Roeckaa136e52012-12-04 03:26:05 -08003567
3568 reg_temp = NCT6775_REG_TEMP;
3569 num_reg_temp = ARRAY_SIZE(NCT6775_REG_TEMP);
3570 reg_temp_over = NCT6775_REG_TEMP_OVER;
3571 reg_temp_hyst = NCT6775_REG_TEMP_HYST;
3572 reg_temp_config = NCT6776_REG_TEMP_CONFIG;
3573 reg_temp_alternate = NCT6776_REG_TEMP_ALTERNATE;
3574 reg_temp_crit = NCT6776_REG_TEMP_CRIT;
3575
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003576 break;
3577 case nct6779:
3578 data->in_num = 15;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003579 data->pwm_num = 5;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003580 data->auto_pwm_num = 4;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003581 data->has_fan_div = false;
Guenter Roeckaa136e52012-12-04 03:26:05 -08003582 data->temp_fixed_num = 6;
Guenter Roeckb1d2bff2013-06-22 16:15:31 -07003583 data->num_temp_alarms = 2;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003584
3585 data->ALARM_BITS = NCT6779_ALARM_BITS;
3586
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003587 data->fan_from_reg = fan_from_reg13;
3588 data->fan_from_reg_min = fan_from_reg13;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003589 data->target_temp_mask = 0xff;
3590 data->tolerance_mask = 0x07;
3591 data->speed_tolerance_limit = 63;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003592
Guenter Roeckaa136e52012-12-04 03:26:05 -08003593 data->temp_label = nct6779_temp_label;
3594 data->temp_label_num = ARRAY_SIZE(nct6779_temp_label);
3595
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003596 data->REG_CONFIG = NCT6775_REG_CONFIG;
3597 data->REG_VBAT = NCT6775_REG_VBAT;
Guenter Roeckaa136e52012-12-04 03:26:05 -08003598 data->REG_DIODE = NCT6775_REG_DIODE;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003599 data->REG_VIN = NCT6779_REG_IN;
3600 data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN;
3601 data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003602 data->REG_TARGET = NCT6775_REG_TARGET;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003603 data->REG_FAN = NCT6779_REG_FAN;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003604 data->REG_FAN_MODE = NCT6775_REG_FAN_MODE;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003605 data->REG_FAN_MIN = NCT6776_REG_FAN_MIN;
Guenter Roeck5c25d952012-12-11 07:29:06 -08003606 data->REG_FAN_PULSES = NCT6779_REG_FAN_PULSES;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003607 data->REG_FAN_TIME[0] = NCT6775_REG_FAN_STOP_TIME;
3608 data->REG_FAN_TIME[1] = NCT6775_REG_FAN_STEP_UP_TIME;
3609 data->REG_FAN_TIME[2] = NCT6775_REG_FAN_STEP_DOWN_TIME;
3610 data->REG_TOLERANCE_H = NCT6776_REG_TOLERANCE_H;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003611 data->REG_PWM[0] = NCT6775_REG_PWM;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003612 data->REG_PWM[1] = NCT6775_REG_FAN_START_OUTPUT;
3613 data->REG_PWM[2] = NCT6775_REG_FAN_STOP_OUTPUT;
Guenter Roeckbbd8dec2012-12-04 09:08:29 -08003614 data->REG_PWM[5] = NCT6775_REG_WEIGHT_DUTY_STEP;
3615 data->REG_PWM[6] = NCT6776_REG_WEIGHT_DUTY_BASE;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003616 data->REG_PWM_READ = NCT6775_REG_PWM_READ;
3617 data->REG_PWM_MODE = NCT6776_REG_PWM_MODE;
3618 data->PWM_MODE_MASK = NCT6776_PWM_MODE_MASK;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003619 data->REG_AUTO_TEMP = NCT6775_REG_AUTO_TEMP;
3620 data->REG_AUTO_PWM = NCT6775_REG_AUTO_PWM;
3621 data->REG_CRITICAL_TEMP = NCT6775_REG_CRITICAL_TEMP;
3622 data->REG_CRITICAL_TEMP_TOLERANCE
3623 = NCT6775_REG_CRITICAL_TEMP_TOLERANCE;
Guenter Roeckaa136e52012-12-04 03:26:05 -08003624 data->REG_TEMP_OFFSET = NCT6779_REG_TEMP_OFFSET;
3625 data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003626 data->REG_TEMP_SEL = NCT6775_REG_TEMP_SEL;
Guenter Roeckbbd8dec2012-12-04 09:08:29 -08003627 data->REG_WEIGHT_TEMP_SEL = NCT6775_REG_WEIGHT_TEMP_SEL;
3628 data->REG_WEIGHT_TEMP[0] = NCT6775_REG_WEIGHT_TEMP_STEP;
3629 data->REG_WEIGHT_TEMP[1] = NCT6775_REG_WEIGHT_TEMP_STEP_TOL;
3630 data->REG_WEIGHT_TEMP[2] = NCT6775_REG_WEIGHT_TEMP_BASE;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003631 data->REG_ALARM = NCT6779_REG_ALARM;
Guenter Roeckaa136e52012-12-04 03:26:05 -08003632
3633 reg_temp = NCT6779_REG_TEMP;
3634 num_reg_temp = ARRAY_SIZE(NCT6779_REG_TEMP);
3635 reg_temp_over = NCT6779_REG_TEMP_OVER;
3636 reg_temp_hyst = NCT6779_REG_TEMP_HYST;
3637 reg_temp_config = NCT6779_REG_TEMP_CONFIG;
3638 reg_temp_alternate = NCT6779_REG_TEMP_ALTERNATE;
3639 reg_temp_crit = NCT6779_REG_TEMP_CRIT;
3640
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003641 break;
3642 default:
3643 return -ENODEV;
3644 }
3645 data->have_in = (1 << data->in_num) - 1;
Guenter Roeckaa136e52012-12-04 03:26:05 -08003646 data->have_temp = 0;
3647
3648 /*
3649 * On some boards, not all available temperature sources are monitored,
3650 * even though some of the monitoring registers are unused.
3651 * Get list of unused monitoring registers, then detect if any fan
3652 * controls are configured to use unmonitored temperature sources.
3653 * If so, assign the unmonitored temperature sources to available
3654 * monitoring registers.
3655 */
3656 mask = 0;
3657 available = 0;
3658 for (i = 0; i < num_reg_temp; i++) {
3659 if (reg_temp[i] == 0)
3660 continue;
3661
3662 src = nct6775_read_value(data, data->REG_TEMP_SOURCE[i]) & 0x1f;
3663 if (!src || (mask & (1 << src)))
3664 available |= 1 << i;
3665
3666 mask |= 1 << src;
3667 }
3668
Guenter Roeck8e9285b2012-12-04 08:03:37 -08003669 /*
3670 * Now find unmonitored temperature registers and enable monitoring
3671 * if additional monitoring registers are available.
3672 */
3673 add_temp_sensors(data, data->REG_TEMP_SEL, &available, &mask);
3674 add_temp_sensors(data, data->REG_WEIGHT_TEMP_SEL, &available, &mask);
3675
Guenter Roeckaa136e52012-12-04 03:26:05 -08003676 mask = 0;
3677 s = NUM_TEMP_FIXED; /* First dynamic temperature attribute */
3678 for (i = 0; i < num_reg_temp; i++) {
3679 if (reg_temp[i] == 0)
3680 continue;
3681
3682 src = nct6775_read_value(data, data->REG_TEMP_SOURCE[i]) & 0x1f;
3683 if (!src || (mask & (1 << src)))
3684 continue;
3685
3686 if (src >= data->temp_label_num ||
3687 !strlen(data->temp_label[src])) {
3688 dev_info(dev,
3689 "Invalid temperature source %d at index %d, source register 0x%x, temp register 0x%x\n",
3690 src, i, data->REG_TEMP_SOURCE[i], reg_temp[i]);
3691 continue;
3692 }
3693
3694 mask |= 1 << src;
3695
3696 /* Use fixed index for SYSTIN(1), CPUTIN(2), AUXTIN(3) */
3697 if (src <= data->temp_fixed_num) {
3698 data->have_temp |= 1 << (src - 1);
3699 data->have_temp_fixed |= 1 << (src - 1);
3700 data->reg_temp[0][src - 1] = reg_temp[i];
3701 data->reg_temp[1][src - 1] = reg_temp_over[i];
3702 data->reg_temp[2][src - 1] = reg_temp_hyst[i];
3703 data->reg_temp_config[src - 1] = reg_temp_config[i];
3704 data->temp_src[src - 1] = src;
3705 continue;
3706 }
3707
3708 if (s >= NUM_TEMP)
3709 continue;
3710
3711 /* Use dynamic index for other sources */
3712 data->have_temp |= 1 << s;
3713 data->reg_temp[0][s] = reg_temp[i];
3714 data->reg_temp[1][s] = reg_temp_over[i];
3715 data->reg_temp[2][s] = reg_temp_hyst[i];
3716 data->reg_temp_config[s] = reg_temp_config[i];
3717 if (reg_temp_crit[src - 1])
3718 data->reg_temp[3][s] = reg_temp_crit[src - 1];
3719
3720 data->temp_src[s] = src;
3721 s++;
3722 }
3723
3724#ifdef USE_ALTERNATE
3725 /*
3726 * Go through the list of alternate temp registers and enable
3727 * if possible.
3728 * The temperature is already monitored if the respective bit in <mask>
3729 * is set.
3730 */
3731 for (i = 0; i < data->temp_label_num - 1; i++) {
3732 if (!reg_temp_alternate[i])
3733 continue;
3734 if (mask & (1 << (i + 1)))
3735 continue;
3736 if (i < data->temp_fixed_num) {
3737 if (data->have_temp & (1 << i))
3738 continue;
3739 data->have_temp |= 1 << i;
3740 data->have_temp_fixed |= 1 << i;
3741 data->reg_temp[0][i] = reg_temp_alternate[i];
Guenter Roeck169c05c2013-05-09 10:40:01 -07003742 if (i < num_reg_temp) {
3743 data->reg_temp[1][i] = reg_temp_over[i];
3744 data->reg_temp[2][i] = reg_temp_hyst[i];
3745 }
Guenter Roeckaa136e52012-12-04 03:26:05 -08003746 data->temp_src[i] = i + 1;
3747 continue;
3748 }
3749
3750 if (s >= NUM_TEMP) /* Abort if no more space */
3751 break;
3752
3753 data->have_temp |= 1 << s;
3754 data->reg_temp[0][s] = reg_temp_alternate[i];
3755 data->temp_src[s] = i + 1;
3756 s++;
3757 }
3758#endif /* USE_ALTERNATE */
3759
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003760 /* Initialize the chip */
3761 nct6775_init_device(data);
3762
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003763 err = superio_enter(sio_data->sioreg);
3764 if (err)
3765 return err;
3766
Guenter Roeck0fc1f8f2013-02-26 09:43:50 -08003767 cr2a = superio_inb(sio_data->sioreg, 0x2a);
3768 switch (data->kind) {
3769 case nct6775:
3770 have_vid = (cr2a & 0x40);
3771 break;
3772 case nct6776:
3773 have_vid = (cr2a & 0x60) == 0x40;
3774 break;
3775 case nct6779:
3776 break;
3777 }
3778
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003779 /*
3780 * Read VID value
3781 * We can get the VID input values directly at logical device D 0xe3.
3782 */
Guenter Roeck0fc1f8f2013-02-26 09:43:50 -08003783 if (have_vid) {
3784 superio_select(sio_data->sioreg, NCT6775_LD_VID);
3785 data->vid = superio_inb(sio_data->sioreg, 0xe3);
3786 data->vrm = vid_which_vrm();
3787 }
Guenter Roeck47ece962012-12-04 07:59:32 -08003788
3789 if (fan_debounce) {
3790 u8 tmp;
3791
3792 superio_select(sio_data->sioreg, NCT6775_LD_HWM);
3793 tmp = superio_inb(sio_data->sioreg,
3794 NCT6775_REG_CR_FAN_DEBOUNCE);
3795 switch (data->kind) {
3796 case nct6775:
3797 tmp |= 0x1e;
3798 break;
3799 case nct6776:
3800 case nct6779:
3801 tmp |= 0x3e;
3802 break;
3803 }
3804 superio_outb(sio_data->sioreg, NCT6775_REG_CR_FAN_DEBOUNCE,
3805 tmp);
3806 dev_info(&pdev->dev, "Enabled fan debounce for chip %s\n",
3807 data->name);
3808 }
3809
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003810 superio_exit(sio_data->sioreg);
3811
Guenter Roeck0fc1f8f2013-02-26 09:43:50 -08003812 if (have_vid) {
3813 err = device_create_file(dev, &dev_attr_cpu0_vid);
3814 if (err)
3815 return err;
3816 }
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003817
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003818 err = nct6775_check_fan_inputs(sio_data, data);
3819 if (err)
3820 goto exit_remove;
3821
3822 /* Read fan clock dividers immediately */
3823 nct6775_init_fan_common(dev, data);
3824
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003825 /* Register sysfs hooks */
3826 for (i = 0; i < data->pwm_num; i++) {
3827 if (!(data->has_pwm & (1 << i)))
3828 continue;
3829
3830 err = sysfs_create_group(&dev->kobj, &nct6775_group_pwm[i]);
3831 if (err)
3832 goto exit_remove;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003833
3834 if (data->REG_PWM[3]) {
3835 err = device_create_file(dev,
3836 &sda_pwm_max[i].dev_attr);
3837 if (err)
3838 goto exit_remove;
3839 }
3840 if (data->REG_PWM[4]) {
3841 err = device_create_file(dev,
3842 &sda_pwm_step[i].dev_attr);
3843 if (err)
3844 goto exit_remove;
3845 }
Guenter Roeckbbd8dec2012-12-04 09:08:29 -08003846 if (data->REG_PWM[6]) {
3847 err = device_create_file(dev,
3848 &sda_weight_duty_base[i].dev_attr);
3849 if (err)
3850 goto exit_remove;
3851 }
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003852 }
3853 for (i = 0; i < ARRAY_SIZE(sda_auto_pwm_arrays); i++) {
3854 struct sensor_device_attribute_2 *attr =
3855 &sda_auto_pwm_arrays[i];
3856
3857 if (!(data->has_pwm & (1 << attr->nr)))
3858 continue;
3859 if (attr->index > data->auto_pwm_num)
3860 continue;
3861 err = device_create_file(dev, &attr->dev_attr);
3862 if (err)
3863 goto exit_remove;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003864 }
3865
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003866 for (i = 0; i < data->in_num; i++) {
3867 if (!(data->have_in & (1 << i)))
3868 continue;
3869 err = sysfs_create_group(&dev->kobj, &nct6775_group_in[i]);
3870 if (err)
3871 goto exit_remove;
3872 }
3873
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003874 for (i = 0; i < 5; i++) {
3875 if (data->has_fan & (1 << i)) {
3876 err = device_create_file(dev,
3877 &sda_fan_input[i].dev_attr);
3878 if (err)
3879 goto exit_remove;
Guenter Roeck41fa9a92013-06-23 13:04:04 -07003880 if (data->ALARM_BITS[FAN_ALARM_BASE + i] >= 0) {
3881 err = device_create_file(dev,
3882 &sda_fan_alarm[i].dev_attr);
3883 if (err)
3884 goto exit_remove;
3885 }
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003886 if (data->kind != nct6776 &&
3887 data->kind != nct6779) {
3888 err = device_create_file(dev,
3889 &sda_fan_div[i].dev_attr);
3890 if (err)
3891 goto exit_remove;
3892 }
3893 if (data->has_fan_min & (1 << i)) {
3894 err = device_create_file(dev,
3895 &sda_fan_min[i].dev_attr);
3896 if (err)
3897 goto exit_remove;
3898 }
Guenter Roeck5c25d952012-12-11 07:29:06 -08003899 err = device_create_file(dev,
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003900 &sda_fan_pulses[i].dev_attr);
Guenter Roeck5c25d952012-12-11 07:29:06 -08003901 if (err)
3902 goto exit_remove;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003903 }
3904 }
3905
Guenter Roeckaa136e52012-12-04 03:26:05 -08003906 for (i = 0; i < NUM_TEMP; i++) {
3907 if (!(data->have_temp & (1 << i)))
3908 continue;
3909 err = device_create_file(dev, &sda_temp_input[i].dev_attr);
3910 if (err)
3911 goto exit_remove;
3912 if (data->temp_label) {
3913 err = device_create_file(dev,
3914 &sda_temp_label[i].dev_attr);
3915 if (err)
3916 goto exit_remove;
3917 }
3918 if (data->reg_temp[1][i]) {
3919 err = device_create_file(dev,
3920 &sda_temp_max[i].dev_attr);
3921 if (err)
3922 goto exit_remove;
3923 }
3924 if (data->reg_temp[2][i]) {
3925 err = device_create_file(dev,
3926 &sda_temp_max_hyst[i].dev_attr);
3927 if (err)
3928 goto exit_remove;
3929 }
3930 if (data->reg_temp[3][i]) {
3931 err = device_create_file(dev,
3932 &sda_temp_crit[i].dev_attr);
3933 if (err)
3934 goto exit_remove;
3935 }
Guenter Roeckb1d2bff2013-06-22 16:15:31 -07003936 if (find_temp_source(data, i, data->num_temp_alarms) >= 0) {
3937 err = device_create_file(dev,
3938 &sda_temp_alarm[i].dev_attr);
3939 if (err)
3940 goto exit_remove;
3941 }
Guenter Roeckaa136e52012-12-04 03:26:05 -08003942 if (!(data->have_temp_fixed & (1 << i)))
3943 continue;
3944 err = device_create_file(dev, &sda_temp_type[i].dev_attr);
3945 if (err)
3946 goto exit_remove;
3947 err = device_create_file(dev, &sda_temp_offset[i].dev_attr);
3948 if (err)
3949 goto exit_remove;
Guenter Roeckaa136e52012-12-04 03:26:05 -08003950 }
3951
Guenter Roecka6bd5872012-12-04 03:13:34 -08003952 for (i = 0; i < ARRAY_SIZE(sda_caseopen); i++) {
3953 if (data->ALARM_BITS[INTRUSION_ALARM_BASE + i] < 0)
3954 continue;
3955 err = device_create_file(dev, &sda_caseopen[i].dev_attr);
3956 if (err)
3957 goto exit_remove;
3958 }
3959
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003960 err = device_create_file(dev, &dev_attr_name);
3961 if (err)
3962 goto exit_remove;
3963
3964 data->hwmon_dev = hwmon_device_register(dev);
3965 if (IS_ERR(data->hwmon_dev)) {
3966 err = PTR_ERR(data->hwmon_dev);
3967 goto exit_remove;
3968 }
3969
3970 return 0;
3971
3972exit_remove:
3973 nct6775_device_remove_files(dev);
3974 return err;
3975}
3976
3977static int nct6775_remove(struct platform_device *pdev)
3978{
3979 struct nct6775_data *data = platform_get_drvdata(pdev);
3980
3981 hwmon_device_unregister(data->hwmon_dev);
3982 nct6775_device_remove_files(&pdev->dev);
3983
3984 return 0;
3985}
3986
Guenter Roeck84d19d92012-12-04 08:01:39 -08003987#ifdef CONFIG_PM
3988static int nct6775_suspend(struct device *dev)
3989{
3990 struct nct6775_data *data = nct6775_update_device(dev);
3991 struct nct6775_sio_data *sio_data = dev->platform_data;
3992
3993 mutex_lock(&data->update_lock);
3994 data->vbat = nct6775_read_value(data, data->REG_VBAT);
3995 if (sio_data->kind == nct6775) {
3996 data->fandiv1 = nct6775_read_value(data, NCT6775_REG_FANDIV1);
3997 data->fandiv2 = nct6775_read_value(data, NCT6775_REG_FANDIV2);
3998 }
3999 mutex_unlock(&data->update_lock);
4000
4001 return 0;
4002}
4003
4004static int nct6775_resume(struct device *dev)
4005{
4006 struct nct6775_data *data = dev_get_drvdata(dev);
4007 struct nct6775_sio_data *sio_data = dev->platform_data;
4008 int i, j;
4009
4010 mutex_lock(&data->update_lock);
4011 data->bank = 0xff; /* Force initial bank selection */
4012
4013 /* Restore limits */
4014 for (i = 0; i < data->in_num; i++) {
4015 if (!(data->have_in & (1 << i)))
4016 continue;
4017
4018 nct6775_write_value(data, data->REG_IN_MINMAX[0][i],
4019 data->in[i][1]);
4020 nct6775_write_value(data, data->REG_IN_MINMAX[1][i],
4021 data->in[i][2]);
4022 }
4023
Guenter Roeckc409fd42013-04-09 05:04:00 -07004024 for (i = 0; i < ARRAY_SIZE(data->fan_min); i++) {
Guenter Roeck84d19d92012-12-04 08:01:39 -08004025 if (!(data->has_fan_min & (1 << i)))
4026 continue;
4027
4028 nct6775_write_value(data, data->REG_FAN_MIN[i],
4029 data->fan_min[i]);
4030 }
4031
4032 for (i = 0; i < NUM_TEMP; i++) {
4033 if (!(data->have_temp & (1 << i)))
4034 continue;
4035
Guenter Roeckc409fd42013-04-09 05:04:00 -07004036 for (j = 1; j < ARRAY_SIZE(data->reg_temp); j++)
Guenter Roeck84d19d92012-12-04 08:01:39 -08004037 if (data->reg_temp[j][i])
4038 nct6775_write_temp(data, data->reg_temp[j][i],
4039 data->temp[j][i]);
4040 }
4041
4042 /* Restore other settings */
4043 nct6775_write_value(data, data->REG_VBAT, data->vbat);
4044 if (sio_data->kind == nct6775) {
4045 nct6775_write_value(data, NCT6775_REG_FANDIV1, data->fandiv1);
4046 nct6775_write_value(data, NCT6775_REG_FANDIV2, data->fandiv2);
4047 }
4048
4049 /* Force re-reading all values */
4050 data->valid = false;
4051 mutex_unlock(&data->update_lock);
4052
4053 return 0;
4054}
4055
4056static const struct dev_pm_ops nct6775_dev_pm_ops = {
4057 .suspend = nct6775_suspend,
4058 .resume = nct6775_resume,
4059};
4060
4061#define NCT6775_DEV_PM_OPS (&nct6775_dev_pm_ops)
4062#else
4063#define NCT6775_DEV_PM_OPS NULL
4064#endif /* CONFIG_PM */
4065
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07004066static struct platform_driver nct6775_driver = {
4067 .driver = {
4068 .owner = THIS_MODULE,
4069 .name = DRVNAME,
Guenter Roeck84d19d92012-12-04 08:01:39 -08004070 .pm = NCT6775_DEV_PM_OPS,
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07004071 },
4072 .probe = nct6775_probe,
4073 .remove = nct6775_remove,
4074};
4075
Guenter Roeck6d4b3622013-04-21 09:08:11 -07004076static const char * const nct6775_sio_names[] __initconst = {
Guenter Roeck2c7fd302013-04-02 08:53:19 -07004077 "NCT6775F",
4078 "NCT6776D/F",
4079 "NCT6779D",
4080};
4081
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07004082/* nct6775_find() looks for a '627 in the Super-I/O config space */
4083static int __init nct6775_find(int sioaddr, unsigned short *addr,
4084 struct nct6775_sio_data *sio_data)
4085{
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07004086 u16 val;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07004087 int err;
4088
4089 err = superio_enter(sioaddr);
4090 if (err)
4091 return err;
4092
4093 if (force_id)
4094 val = force_id;
4095 else
4096 val = (superio_inb(sioaddr, SIO_REG_DEVID) << 8)
4097 | superio_inb(sioaddr, SIO_REG_DEVID + 1);
4098 switch (val & SIO_ID_MASK) {
4099 case SIO_NCT6775_ID:
4100 sio_data->kind = nct6775;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07004101 break;
4102 case SIO_NCT6776_ID:
4103 sio_data->kind = nct6776;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07004104 break;
4105 case SIO_NCT6779_ID:
4106 sio_data->kind = nct6779;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07004107 break;
4108 default:
4109 if (val != 0xffff)
4110 pr_debug("unsupported chip ID: 0x%04x\n", val);
4111 superio_exit(sioaddr);
4112 return -ENODEV;
4113 }
4114
4115 /* We have a known chip, find the HWM I/O address */
4116 superio_select(sioaddr, NCT6775_LD_HWM);
4117 val = (superio_inb(sioaddr, SIO_REG_ADDR) << 8)
4118 | superio_inb(sioaddr, SIO_REG_ADDR + 1);
4119 *addr = val & IOREGION_ALIGNMENT;
4120 if (*addr == 0) {
4121 pr_err("Refusing to enable a Super-I/O device with a base I/O port 0\n");
4122 superio_exit(sioaddr);
4123 return -ENODEV;
4124 }
4125
4126 /* Activate logical device if needed */
4127 val = superio_inb(sioaddr, SIO_REG_ENABLE);
4128 if (!(val & 0x01)) {
4129 pr_warn("Forcibly enabling Super-I/O. Sensor is probably unusable.\n");
4130 superio_outb(sioaddr, SIO_REG_ENABLE, val | 0x01);
4131 }
4132
4133 superio_exit(sioaddr);
Guenter Roeck2c7fd302013-04-02 08:53:19 -07004134 pr_info("Found %s or compatible chip at %#x\n",
4135 nct6775_sio_names[sio_data->kind], *addr);
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07004136 sio_data->sioreg = sioaddr;
4137
4138 return 0;
4139}
4140
4141/*
4142 * when Super-I/O functions move to a separate file, the Super-I/O
4143 * bus will manage the lifetime of the device and this module will only keep
4144 * track of the nct6775 driver. But since we platform_device_alloc(), we
4145 * must keep track of the device
4146 */
4147static struct platform_device *pdev;
4148
4149static int __init sensors_nct6775_init(void)
4150{
4151 int err;
4152 unsigned short address;
4153 struct resource res;
4154 struct nct6775_sio_data sio_data;
4155
4156 /*
4157 * initialize sio_data->kind and sio_data->sioreg.
4158 *
4159 * when Super-I/O functions move to a separate file, the Super-I/O
4160 * driver will probe 0x2e and 0x4e and auto-detect the presence of a
4161 * nct6775 hardware monitor, and call probe()
4162 */
4163 if (nct6775_find(0x2e, &address, &sio_data) &&
4164 nct6775_find(0x4e, &address, &sio_data))
4165 return -ENODEV;
4166
4167 err = platform_driver_register(&nct6775_driver);
4168 if (err)
4169 goto exit;
4170
4171 pdev = platform_device_alloc(DRVNAME, address);
4172 if (!pdev) {
4173 err = -ENOMEM;
4174 pr_err("Device allocation failed\n");
4175 goto exit_unregister;
4176 }
4177
4178 err = platform_device_add_data(pdev, &sio_data,
4179 sizeof(struct nct6775_sio_data));
4180 if (err) {
4181 pr_err("Platform data allocation failed\n");
4182 goto exit_device_put;
4183 }
4184
4185 memset(&res, 0, sizeof(res));
4186 res.name = DRVNAME;
4187 res.start = address + IOREGION_OFFSET;
4188 res.end = address + IOREGION_OFFSET + IOREGION_LENGTH - 1;
4189 res.flags = IORESOURCE_IO;
4190
4191 err = acpi_check_resource_conflict(&res);
4192 if (err)
4193 goto exit_device_put;
4194
4195 err = platform_device_add_resources(pdev, &res, 1);
4196 if (err) {
4197 pr_err("Device resource addition failed (%d)\n", err);
4198 goto exit_device_put;
4199 }
4200
4201 /* platform_device_add calls probe() */
4202 err = platform_device_add(pdev);
4203 if (err) {
4204 pr_err("Device addition failed (%d)\n", err);
4205 goto exit_device_put;
4206 }
4207
4208 return 0;
4209
4210exit_device_put:
4211 platform_device_put(pdev);
4212exit_unregister:
4213 platform_driver_unregister(&nct6775_driver);
4214exit:
4215 return err;
4216}
4217
4218static void __exit sensors_nct6775_exit(void)
4219{
4220 platform_device_unregister(pdev);
4221 platform_driver_unregister(&nct6775_driver);
4222}
4223
4224MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>");
4225MODULE_DESCRIPTION("NCT6775F/NCT6776F/NCT6779D driver");
4226MODULE_LICENSE("GPL");
4227
4228module_init(sensors_nct6775_init);
4229module_exit(sensors_nct6775_exit);