blob: 752fbd7efb328e8b300f2d72cdb0b5b909392b14 [file] [log] [blame]
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07001/*
2 * nct6775 - Driver for the hardware monitoring functionality of
3 * Nuvoton NCT677x Super-I/O chips
4 *
5 * Copyright (C) 2012 Guenter Roeck <linux@roeck-us.net>
6 *
7 * Derived from w83627ehf driver
8 * Copyright (C) 2005-2012 Jean Delvare <khali@linux-fr.org>
9 * Copyright (C) 2006 Yuan Mu (Winbond),
10 * Rudolf Marek <r.marek@assembler.cz>
11 * David Hubbard <david.c.hubbard@gmail.com>
12 * Daniel J Blueman <daniel.blueman@gmail.com>
13 * Copyright (C) 2010 Sheng-Yuan Huang (Nuvoton) (PS00)
14 *
15 * Shamelessly ripped from the w83627hf driver
16 * Copyright (C) 2003 Mark Studebaker
17 *
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 2 of the License, or
21 * (at your option) any later version.
22 *
23 * This program is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
27 *
28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, write to the Free Software
30 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
31 *
32 *
33 * Supports the following chips:
34 *
35 * Chip #vin #fan #pwm #temp chip IDs man ID
36 * nct6775f 9 4 3 6+3 0xb470 0xc1 0x5ca3
37 * nct6776f 9 5 3 6+3 0xc330 0xc1 0x5ca3
38 * nct6779d 15 5 5 2+6 0xc560 0xc1 0x5ca3
39 *
40 * #temp lists the number of monitored temperature sources (first value) plus
41 * the number of directly connectable temperature sensors (second value).
42 */
43
44#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
45
46#include <linux/module.h>
47#include <linux/init.h>
48#include <linux/slab.h>
49#include <linux/jiffies.h>
50#include <linux/platform_device.h>
51#include <linux/hwmon.h>
52#include <linux/hwmon-sysfs.h>
53#include <linux/hwmon-vid.h>
54#include <linux/err.h>
55#include <linux/mutex.h>
56#include <linux/acpi.h>
57#include <linux/io.h>
58#include "lm75.h"
59
Guenter Roeckaa136e52012-12-04 03:26:05 -080060#define USE_ALTERNATE
61
Guenter Roeck9de2e2e2012-05-20 19:29:48 -070062enum kinds { nct6775, nct6776, nct6779 };
63
64/* used to set data->name = nct6775_device_names[data->sio_kind] */
65static const char * const nct6775_device_names[] = {
66 "nct6775",
67 "nct6776",
68 "nct6779",
69};
70
71static unsigned short force_id;
72module_param(force_id, ushort, 0);
73MODULE_PARM_DESC(force_id, "Override the detected device ID");
74
Guenter Roeck47ece962012-12-04 07:59:32 -080075static unsigned short fan_debounce;
76module_param(fan_debounce, ushort, 0);
77MODULE_PARM_DESC(fan_debounce, "Enable debouncing for fan RPM signal");
78
Guenter Roeck9de2e2e2012-05-20 19:29:48 -070079#define DRVNAME "nct6775"
80
81/*
82 * Super-I/O constants and functions
83 */
84
Guenter Roecka6bd5872012-12-04 03:13:34 -080085#define NCT6775_LD_ACPI 0x0a
Guenter Roeck9de2e2e2012-05-20 19:29:48 -070086#define NCT6775_LD_HWM 0x0b
87#define NCT6775_LD_VID 0x0d
88
89#define SIO_REG_LDSEL 0x07 /* Logical device select */
90#define SIO_REG_DEVID 0x20 /* Device ID (2 bytes) */
91#define SIO_REG_ENABLE 0x30 /* Logical device enable */
92#define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */
93
94#define SIO_NCT6775_ID 0xb470
95#define SIO_NCT6776_ID 0xc330
96#define SIO_NCT6779_ID 0xc560
97#define SIO_ID_MASK 0xFFF0
98
Guenter Roeck77eb5b32012-12-04 08:30:54 -080099enum pwm_enable { off, manual, thermal_cruise, speed_cruise, sf3, sf4 };
100
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700101static inline void
102superio_outb(int ioreg, int reg, int val)
103{
104 outb(reg, ioreg);
105 outb(val, ioreg + 1);
106}
107
108static inline int
109superio_inb(int ioreg, int reg)
110{
111 outb(reg, ioreg);
112 return inb(ioreg + 1);
113}
114
115static inline void
116superio_select(int ioreg, int ld)
117{
118 outb(SIO_REG_LDSEL, ioreg);
119 outb(ld, ioreg + 1);
120}
121
122static inline int
123superio_enter(int ioreg)
124{
125 /*
126 * Try to reserve <ioreg> and <ioreg + 1> for exclusive access.
127 */
128 if (!request_muxed_region(ioreg, 2, DRVNAME))
129 return -EBUSY;
130
131 outb(0x87, ioreg);
132 outb(0x87, ioreg);
133
134 return 0;
135}
136
137static inline void
138superio_exit(int ioreg)
139{
140 outb(0xaa, ioreg);
141 outb(0x02, ioreg);
142 outb(0x02, ioreg + 1);
143 release_region(ioreg, 2);
144}
145
146/*
147 * ISA constants
148 */
149
150#define IOREGION_ALIGNMENT (~7)
151#define IOREGION_OFFSET 5
152#define IOREGION_LENGTH 2
153#define ADDR_REG_OFFSET 0
154#define DATA_REG_OFFSET 1
155
156#define NCT6775_REG_BANK 0x4E
157#define NCT6775_REG_CONFIG 0x40
158
159/*
160 * Not currently used:
161 * REG_MAN_ID has the value 0x5ca3 for all supported chips.
162 * REG_CHIP_ID == 0x88/0xa1/0xc1 depending on chip model.
163 * REG_MAN_ID is at port 0x4f
164 * REG_CHIP_ID is at port 0x58
165 */
166
Guenter Roeckaa136e52012-12-04 03:26:05 -0800167#define NUM_TEMP 10 /* Max number of temp attribute sets w/ limits*/
168#define NUM_TEMP_FIXED 6 /* Max number of fixed temp attribute sets */
169
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700170#define NUM_REG_ALARM 4 /* Max number of alarm registers */
171
172/* Common and NCT6775 specific data */
173
174/* Voltage min/max registers for nr=7..14 are in bank 5 */
175
176static const u16 NCT6775_REG_IN_MAX[] = {
177 0x2b, 0x2d, 0x2f, 0x31, 0x33, 0x35, 0x37, 0x554, 0x556, 0x558, 0x55a,
178 0x55c, 0x55e, 0x560, 0x562 };
179static const u16 NCT6775_REG_IN_MIN[] = {
180 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x555, 0x557, 0x559, 0x55b,
181 0x55d, 0x55f, 0x561, 0x563 };
182static const u16 NCT6775_REG_IN[] = {
183 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x550, 0x551, 0x552
184};
185
186#define NCT6775_REG_VBAT 0x5D
Guenter Roeckaa136e52012-12-04 03:26:05 -0800187#define NCT6775_REG_DIODE 0x5E
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700188
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800189#define NCT6775_REG_FANDIV1 0x506
190#define NCT6775_REG_FANDIV2 0x507
191
Guenter Roeck47ece962012-12-04 07:59:32 -0800192#define NCT6775_REG_CR_FAN_DEBOUNCE 0xf0
193
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700194static const u16 NCT6775_REG_ALARM[NUM_REG_ALARM] = { 0x459, 0x45A, 0x45B };
195
196/* 0..15 voltages, 16..23 fans, 24..31 temperatures */
197
198static const s8 NCT6775_ALARM_BITS[] = {
199 0, 1, 2, 3, 8, 21, 20, 16, /* in0.. in7 */
200 17, -1, -1, -1, -1, -1, -1, /* in8..in14 */
201 -1, /* unused */
202 6, 7, 11, 10, 23, /* fan1..fan5 */
203 -1, -1, -1, /* unused */
204 4, 5, 13, -1, -1, -1, /* temp1..temp6 */
205 12, -1 }; /* intrusion0, intrusion1 */
206
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800207#define FAN_ALARM_BASE 16
Guenter Roeckaa136e52012-12-04 03:26:05 -0800208#define TEMP_ALARM_BASE 24
Guenter Roecka6bd5872012-12-04 03:13:34 -0800209#define INTRUSION_ALARM_BASE 30
210
211static const u8 NCT6775_REG_CR_CASEOPEN_CLR[] = { 0xe6, 0xee };
212static const u8 NCT6775_CR_CASEOPEN_CLR_MASK[] = { 0x20, 0x01 };
213
Guenter Roeck77eb5b32012-12-04 08:30:54 -0800214/* DC or PWM output fan configuration */
215static const u8 NCT6775_REG_PWM_MODE[] = { 0x04, 0x04, 0x12 };
216static const u8 NCT6775_PWM_MODE_MASK[] = { 0x01, 0x02, 0x01 };
217
Guenter Roeckcdcaece2012-12-04 09:04:52 -0800218/* Advanced Fan control, some values are common for all fans */
Guenter Roeck77eb5b32012-12-04 08:30:54 -0800219
Guenter Roeckcdcaece2012-12-04 09:04:52 -0800220static const u16 NCT6775_REG_TARGET[] = { 0x101, 0x201, 0x301, 0x801, 0x901 };
221static const u16 NCT6775_REG_FAN_MODE[] = { 0x102, 0x202, 0x302, 0x802, 0x902 };
222static const u16 NCT6775_REG_FAN_STEP_DOWN_TIME[] = {
223 0x103, 0x203, 0x303, 0x803, 0x903 };
224static const u16 NCT6775_REG_FAN_STEP_UP_TIME[] = {
225 0x104, 0x204, 0x304, 0x804, 0x904 };
226static const u16 NCT6775_REG_FAN_STOP_OUTPUT[] = {
227 0x105, 0x205, 0x305, 0x805, 0x905 };
228static const u16 NCT6775_REG_FAN_START_OUTPUT[]
229 = { 0x106, 0x206, 0x306, 0x806, 0x906 };
230static const u16 NCT6775_REG_FAN_MAX_OUTPUT[] = { 0x10a, 0x20a, 0x30a };
231static const u16 NCT6775_REG_FAN_STEP_OUTPUT[] = { 0x10b, 0x20b, 0x30b };
232
233static const u16 NCT6775_REG_FAN_STOP_TIME[] = {
234 0x107, 0x207, 0x307, 0x807, 0x907 };
Guenter Roeck77eb5b32012-12-04 08:30:54 -0800235static const u16 NCT6775_REG_PWM[] = { 0x109, 0x209, 0x309, 0x809, 0x909 };
236static const u16 NCT6775_REG_PWM_READ[] = { 0x01, 0x03, 0x11, 0x13, 0x15 };
237
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800238static const u16 NCT6775_REG_FAN[] = { 0x630, 0x632, 0x634, 0x636, 0x638 };
239static const u16 NCT6775_REG_FAN_MIN[] = { 0x3b, 0x3c, 0x3d };
Guenter Roeck5c25d952012-12-11 07:29:06 -0800240static const u16 NCT6775_REG_FAN_PULSES[] = { 0x641, 0x642, 0x643, 0x644, 0 };
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800241
Guenter Roeckaa136e52012-12-04 03:26:05 -0800242static const u16 NCT6775_REG_TEMP[] = {
243 0x27, 0x150, 0x250, 0x62b, 0x62c, 0x62d };
244
245static const u16 NCT6775_REG_TEMP_CONFIG[ARRAY_SIZE(NCT6775_REG_TEMP)] = {
246 0, 0x152, 0x252, 0x628, 0x629, 0x62A };
247static const u16 NCT6775_REG_TEMP_HYST[ARRAY_SIZE(NCT6775_REG_TEMP)] = {
248 0x3a, 0x153, 0x253, 0x673, 0x678, 0x67D };
249static const u16 NCT6775_REG_TEMP_OVER[ARRAY_SIZE(NCT6775_REG_TEMP)] = {
250 0x39, 0x155, 0x255, 0x672, 0x677, 0x67C };
251
252static const u16 NCT6775_REG_TEMP_SOURCE[ARRAY_SIZE(NCT6775_REG_TEMP)] = {
253 0x621, 0x622, 0x623, 0x624, 0x625, 0x626 };
254
Guenter Roeckcdcaece2012-12-04 09:04:52 -0800255static const u16 NCT6775_REG_TEMP_SEL[] = {
256 0x100, 0x200, 0x300, 0x800, 0x900 };
257
Guenter 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;
557 struct mutex lock;
558
Guenter Roeckaa136e52012-12-04 03:26:05 -0800559 u16 reg_temp[4][NUM_TEMP]; /* 0=temp, 1=temp_over, 2=temp_hyst,
560 * 3=temp_crit
561 */
562 u8 temp_src[NUM_TEMP];
563 u16 reg_temp_config[NUM_TEMP];
564 const char * const *temp_label;
565 int temp_label_num;
566
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700567 u16 REG_CONFIG;
568 u16 REG_VBAT;
Guenter Roeckaa136e52012-12-04 03:26:05 -0800569 u16 REG_DIODE;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700570
571 const s8 *ALARM_BITS;
572
573 const u16 *REG_VIN;
574 const u16 *REG_IN_MINMAX[2];
575
Guenter Roeckcdcaece2012-12-04 09:04:52 -0800576 const u16 *REG_TARGET;
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800577 const u16 *REG_FAN;
Guenter Roeck77eb5b32012-12-04 08:30:54 -0800578 const u16 *REG_FAN_MODE;
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800579 const u16 *REG_FAN_MIN;
Guenter Roeck5c25d952012-12-11 07:29:06 -0800580 const u16 *REG_FAN_PULSES;
Guenter Roeckcdcaece2012-12-04 09:04:52 -0800581 const u16 *REG_FAN_TIME[3];
582
583 const u16 *REG_TOLERANCE_H;
Guenter Roeckaa136e52012-12-04 03:26:05 -0800584
Guenter Roeck77eb5b32012-12-04 08:30:54 -0800585 const u8 *REG_PWM_MODE;
586 const u8 *PWM_MODE_MASK;
587
Guenter Roeckbbd8dec2012-12-04 09:08:29 -0800588 const u16 *REG_PWM[7]; /* [0]=pwm, [1]=pwm_start, [2]=pwm_floor,
589 * [3]=pwm_max, [4]=pwm_step,
590 * [5]=weight_duty_step, [6]=weight_duty_base
Guenter Roeckcdcaece2012-12-04 09:04:52 -0800591 */
Guenter Roeck77eb5b32012-12-04 08:30:54 -0800592 const u16 *REG_PWM_READ;
593
Guenter Roeckcdcaece2012-12-04 09:04:52 -0800594 const u16 *REG_AUTO_TEMP;
595 const u16 *REG_AUTO_PWM;
596
597 const u16 *REG_CRITICAL_TEMP;
598 const u16 *REG_CRITICAL_TEMP_TOLERANCE;
599
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800600 const u16 *REG_TEMP_SOURCE; /* temp register sources */
Guenter Roeckcdcaece2012-12-04 09:04:52 -0800601 const u16 *REG_TEMP_SEL;
Guenter Roeckbbd8dec2012-12-04 09:08:29 -0800602 const u16 *REG_WEIGHT_TEMP_SEL;
603 const u16 *REG_WEIGHT_TEMP[3]; /* 0=base, 1=tolerance, 2=step */
604
Guenter Roeckaa136e52012-12-04 03:26:05 -0800605 const u16 *REG_TEMP_OFFSET;
606
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700607 const u16 *REG_ALARM;
608
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800609 unsigned int (*fan_from_reg)(u16 reg, unsigned int divreg);
610 unsigned int (*fan_from_reg_min)(u16 reg, unsigned int divreg);
611
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700612 struct mutex update_lock;
613 bool valid; /* true if following fields are valid */
614 unsigned long last_updated; /* In jiffies */
615
616 /* Register values */
617 u8 bank; /* current register bank */
618 u8 in_num; /* number of in inputs we have */
619 u8 in[15][3]; /* [0]=in, [1]=in_max, [2]=in_min */
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800620 unsigned int rpm[5];
621 u16 fan_min[5];
Guenter Roeck5c25d952012-12-11 07:29:06 -0800622 u8 fan_pulses[5];
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800623 u8 fan_div[5];
Guenter Roeck77eb5b32012-12-04 08:30:54 -0800624 u8 has_pwm;
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800625 u8 has_fan; /* some fan inputs can be disabled */
626 u8 has_fan_min; /* some fans don't have min register */
627 bool has_fan_div;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -0700628
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
748 mutex_lock(&data->lock);
749
750 nct6775_set_bank(data, reg);
751 outb_p(reg & 0xff, data->addr + ADDR_REG_OFFSET);
752 res = inb_p(data->addr + DATA_REG_OFFSET);
753 if (word_sized) {
754 outb_p((reg & 0xff) + 1,
755 data->addr + ADDR_REG_OFFSET);
756 res = (res << 8) + inb_p(data->addr + DATA_REG_OFFSET);
757 }
758
759 mutex_unlock(&data->lock);
760 return res;
761}
762
763static int nct6775_write_value(struct nct6775_data *data, u16 reg, u16 value)
764{
765 int word_sized = is_word_sized(data, reg);
766
767 mutex_lock(&data->lock);
768
769 nct6775_set_bank(data, reg);
770 outb_p(reg & 0xff, data->addr + ADDR_REG_OFFSET);
771 if (word_sized) {
772 outb_p(value >> 8, data->addr + DATA_REG_OFFSET);
773 outb_p((reg & 0xff) + 1,
774 data->addr + ADDR_REG_OFFSET);
775 }
776 outb_p(value & 0xff, data->addr + DATA_REG_OFFSET);
777
778 mutex_unlock(&data->lock);
779 return 0;
780}
781
Guenter Roeckaa136e52012-12-04 03:26:05 -0800782/* We left-align 8-bit temperature values to make the code simpler */
783static u16 nct6775_read_temp(struct nct6775_data *data, u16 reg)
784{
785 u16 res;
786
787 res = nct6775_read_value(data, reg);
788 if (!is_word_sized(data, reg))
789 res <<= 8;
790
791 return res;
792}
793
794static int nct6775_write_temp(struct nct6775_data *data, u16 reg, u16 value)
795{
796 if (!is_word_sized(data, reg))
797 value >>= 8;
798 return nct6775_write_value(data, reg, value);
799}
800
Guenter Roeck1c65dc32012-12-04 07:56:24 -0800801/* This function assumes that the caller holds data->update_lock */
802static void nct6775_write_fan_div(struct nct6775_data *data, int nr)
803{
804 u8 reg;
805
806 switch (nr) {
807 case 0:
808 reg = (nct6775_read_value(data, NCT6775_REG_FANDIV1) & 0x70)
809 | (data->fan_div[0] & 0x7);
810 nct6775_write_value(data, NCT6775_REG_FANDIV1, reg);
811 break;
812 case 1:
813 reg = (nct6775_read_value(data, NCT6775_REG_FANDIV1) & 0x7)
814 | ((data->fan_div[1] << 4) & 0x70);
815 nct6775_write_value(data, NCT6775_REG_FANDIV1, reg);
816 break;
817 case 2:
818 reg = (nct6775_read_value(data, NCT6775_REG_FANDIV2) & 0x70)
819 | (data->fan_div[2] & 0x7);
820 nct6775_write_value(data, NCT6775_REG_FANDIV2, reg);
821 break;
822 case 3:
823 reg = (nct6775_read_value(data, NCT6775_REG_FANDIV2) & 0x7)
824 | ((data->fan_div[3] << 4) & 0x70);
825 nct6775_write_value(data, NCT6775_REG_FANDIV2, reg);
826 break;
827 }
828}
829
830static void nct6775_write_fan_div_common(struct nct6775_data *data, int nr)
831{
832 if (data->kind == nct6775)
833 nct6775_write_fan_div(data, nr);
834}
835
836static void nct6775_update_fan_div(struct nct6775_data *data)
837{
838 u8 i;
839
840 i = nct6775_read_value(data, NCT6775_REG_FANDIV1);
841 data->fan_div[0] = i & 0x7;
842 data->fan_div[1] = (i & 0x70) >> 4;
843 i = nct6775_read_value(data, NCT6775_REG_FANDIV2);
844 data->fan_div[2] = i & 0x7;
845 if (data->has_fan & (1<<3))
846 data->fan_div[3] = (i & 0x70) >> 4;
847}
848
849static void nct6775_update_fan_div_common(struct nct6775_data *data)
850{
851 if (data->kind == nct6775)
852 nct6775_update_fan_div(data);
853}
854
855static void nct6775_init_fan_div(struct nct6775_data *data)
856{
857 int i;
858
859 nct6775_update_fan_div_common(data);
860 /*
861 * For all fans, start with highest divider value if the divider
862 * register is not initialized. This ensures that we get a
863 * reading from the fan count register, even if it is not optimal.
864 * We'll compute a better divider later on.
865 */
866 for (i = 0; i < 3; i++) {
867 if (!(data->has_fan & (1 << i)))
868 continue;
869 if (data->fan_div[i] == 0) {
870 data->fan_div[i] = 7;
871 nct6775_write_fan_div_common(data, i);
872 }
873 }
874}
875
876static void nct6775_init_fan_common(struct device *dev,
877 struct nct6775_data *data)
878{
879 int i;
880 u8 reg;
881
882 if (data->has_fan_div)
883 nct6775_init_fan_div(data);
884
885 /*
886 * If fan_min is not set (0), set it to 0xff to disable it. This
887 * prevents the unnecessary warning when fanX_min is reported as 0.
888 */
889 for (i = 0; i < 5; i++) {
890 if (data->has_fan_min & (1 << i)) {
891 reg = nct6775_read_value(data, data->REG_FAN_MIN[i]);
892 if (!reg)
893 nct6775_write_value(data, data->REG_FAN_MIN[i],
894 data->has_fan_div ? 0xff
895 : 0xff1f);
896 }
897 }
898}
899
900static void nct6775_select_fan_div(struct device *dev,
901 struct nct6775_data *data, int nr, u16 reg)
902{
903 u8 fan_div = data->fan_div[nr];
904 u16 fan_min;
905
906 if (!data->has_fan_div)
907 return;
908
909 /*
910 * If we failed to measure the fan speed, or the reported value is not
911 * in the optimal range, and the clock divider can be modified,
912 * let's try that for next time.
913 */
914 if (reg == 0x00 && fan_div < 0x07)
915 fan_div++;
916 else if (reg != 0x00 && reg < 0x30 && fan_div > 0)
917 fan_div--;
918
919 if (fan_div != data->fan_div[nr]) {
920 dev_dbg(dev, "Modifying fan%d clock divider from %u to %u\n",
921 nr + 1, div_from_reg(data->fan_div[nr]),
922 div_from_reg(fan_div));
923
924 /* Preserve min limit if possible */
925 if (data->has_fan_min & (1 << nr)) {
926 fan_min = data->fan_min[nr];
927 if (fan_div > data->fan_div[nr]) {
928 if (fan_min != 255 && fan_min > 1)
929 fan_min >>= 1;
930 } else {
931 if (fan_min != 255) {
932 fan_min <<= 1;
933 if (fan_min > 254)
934 fan_min = 254;
935 }
936 }
937 if (fan_min != data->fan_min[nr]) {
938 data->fan_min[nr] = fan_min;
939 nct6775_write_value(data, data->REG_FAN_MIN[nr],
940 fan_min);
941 }
942 }
943 data->fan_div[nr] = fan_div;
944 nct6775_write_fan_div_common(data, nr);
945 }
946}
947
Guenter Roeck77eb5b32012-12-04 08:30:54 -0800948static void nct6775_update_pwm(struct device *dev)
949{
950 struct nct6775_data *data = dev_get_drvdata(dev);
951 int i, j;
Guenter Roeckcdcaece2012-12-04 09:04:52 -0800952 int fanmodecfg, reg;
Guenter Roeck77eb5b32012-12-04 08:30:54 -0800953 bool duty_is_dc;
954
955 for (i = 0; i < data->pwm_num; i++) {
956 if (!(data->has_pwm & (1 << i)))
957 continue;
958
959 duty_is_dc = data->REG_PWM_MODE[i] &&
960 (nct6775_read_value(data, data->REG_PWM_MODE[i])
961 & data->PWM_MODE_MASK[i]);
962 data->pwm_mode[i] = duty_is_dc;
963
964 fanmodecfg = nct6775_read_value(data, data->REG_FAN_MODE[i]);
965 for (j = 0; j < ARRAY_SIZE(data->REG_PWM); j++) {
966 if (data->REG_PWM[j] && data->REG_PWM[j][i]) {
967 data->pwm[j][i]
968 = nct6775_read_value(data,
969 data->REG_PWM[j][i]);
970 }
971 }
972
973 data->pwm_enable[i] = reg_to_pwm_enable(data->pwm[0][i],
974 (fanmodecfg >> 4) & 7);
Guenter Roeckcdcaece2012-12-04 09:04:52 -0800975
976 if (!data->temp_tolerance[0][i] ||
977 data->pwm_enable[i] != speed_cruise)
978 data->temp_tolerance[0][i] = fanmodecfg & 0x0f;
979 if (!data->target_speed_tolerance[i] ||
980 data->pwm_enable[i] == speed_cruise) {
981 u8 t = fanmodecfg & 0x0f;
982 if (data->REG_TOLERANCE_H) {
983 t |= (nct6775_read_value(data,
984 data->REG_TOLERANCE_H[i]) & 0x70) >> 1;
985 }
986 data->target_speed_tolerance[i] = t;
987 }
988
989 data->temp_tolerance[1][i] =
990 nct6775_read_value(data,
991 data->REG_CRITICAL_TEMP_TOLERANCE[i]);
992
993 reg = nct6775_read_value(data, data->REG_TEMP_SEL[i]);
994 data->pwm_temp_sel[i] = reg & 0x1f;
995 /* If fan can stop, report floor as 0 */
996 if (reg & 0x80)
997 data->pwm[2][i] = 0;
Guenter Roeckbbd8dec2012-12-04 09:08:29 -0800998
999 reg = nct6775_read_value(data, data->REG_WEIGHT_TEMP_SEL[i]);
1000 data->pwm_weight_temp_sel[i] = reg & 0x1f;
1001 /* If weight is disabled, report weight source as 0 */
1002 if (j == 1 && !(reg & 0x80))
1003 data->pwm_weight_temp_sel[i] = 0;
1004
1005 /* Weight temp data */
1006 for (j = 0; j < 3; j++) {
1007 data->weight_temp[j][i]
1008 = nct6775_read_value(data,
1009 data->REG_WEIGHT_TEMP[j][i]);
1010 }
Guenter Roeckcdcaece2012-12-04 09:04:52 -08001011 }
1012}
1013
1014static void nct6775_update_pwm_limits(struct device *dev)
1015{
1016 struct nct6775_data *data = dev_get_drvdata(dev);
1017 int i, j;
1018 u8 reg;
1019 u16 reg_t;
1020
1021 for (i = 0; i < data->pwm_num; i++) {
1022 if (!(data->has_pwm & (1 << i)))
1023 continue;
1024
1025 for (j = 0; j < 3; j++) {
1026 data->fan_time[j][i] =
1027 nct6775_read_value(data, data->REG_FAN_TIME[j][i]);
1028 }
1029
1030 reg_t = nct6775_read_value(data, data->REG_TARGET[i]);
1031 /* Update only in matching mode or if never updated */
1032 if (!data->target_temp[i] ||
1033 data->pwm_enable[i] == thermal_cruise)
1034 data->target_temp[i] = reg_t & data->target_temp_mask;
1035 if (!data->target_speed[i] ||
1036 data->pwm_enable[i] == speed_cruise) {
1037 if (data->REG_TOLERANCE_H) {
1038 reg_t |= (nct6775_read_value(data,
1039 data->REG_TOLERANCE_H[i]) & 0x0f) << 8;
1040 }
1041 data->target_speed[i] = reg_t;
1042 }
1043
1044 for (j = 0; j < data->auto_pwm_num; j++) {
1045 data->auto_pwm[i][j] =
1046 nct6775_read_value(data,
1047 NCT6775_AUTO_PWM(data, i, j));
1048 data->auto_temp[i][j] =
1049 nct6775_read_value(data,
1050 NCT6775_AUTO_TEMP(data, i, j));
1051 }
1052
1053 /* critical auto_pwm temperature data */
1054 data->auto_temp[i][data->auto_pwm_num] =
1055 nct6775_read_value(data, data->REG_CRITICAL_TEMP[i]);
1056
1057 switch (data->kind) {
1058 case nct6775:
1059 reg = nct6775_read_value(data,
1060 NCT6775_REG_CRITICAL_ENAB[i]);
1061 data->auto_pwm[i][data->auto_pwm_num] =
1062 (reg & 0x02) ? 0xff : 0x00;
1063 break;
1064 case nct6776:
1065 data->auto_pwm[i][data->auto_pwm_num] = 0xff;
1066 break;
1067 case nct6779:
1068 reg = nct6775_read_value(data,
1069 NCT6779_REG_CRITICAL_PWM_ENABLE[i]);
1070 if (reg & 1)
1071 data->auto_pwm[i][data->auto_pwm_num] =
1072 nct6775_read_value(data,
1073 NCT6779_REG_CRITICAL_PWM[i]);
1074 else
1075 data->auto_pwm[i][data->auto_pwm_num] = 0xff;
1076 break;
1077 }
Guenter Roeck77eb5b32012-12-04 08:30:54 -08001078 }
1079}
1080
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07001081static struct nct6775_data *nct6775_update_device(struct device *dev)
1082{
1083 struct nct6775_data *data = dev_get_drvdata(dev);
Guenter Roeckaa136e52012-12-04 03:26:05 -08001084 int i, j;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07001085
1086 mutex_lock(&data->update_lock);
1087
1088 if (time_after(jiffies, data->last_updated + HZ + HZ/2)
1089 || !data->valid) {
Guenter Roeck1c65dc32012-12-04 07:56:24 -08001090 /* Fan clock dividers */
1091 nct6775_update_fan_div_common(data);
1092
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07001093 /* Measured voltages and limits */
1094 for (i = 0; i < data->in_num; i++) {
1095 if (!(data->have_in & (1 << i)))
1096 continue;
1097
1098 data->in[i][0] = nct6775_read_value(data,
1099 data->REG_VIN[i]);
1100 data->in[i][1] = nct6775_read_value(data,
1101 data->REG_IN_MINMAX[0][i]);
1102 data->in[i][2] = nct6775_read_value(data,
1103 data->REG_IN_MINMAX[1][i]);
1104 }
1105
Guenter Roeck1c65dc32012-12-04 07:56:24 -08001106 /* Measured fan speeds and limits */
1107 for (i = 0; i < 5; i++) {
1108 u16 reg;
1109
1110 if (!(data->has_fan & (1 << i)))
1111 continue;
1112
1113 reg = nct6775_read_value(data, data->REG_FAN[i]);
1114 data->rpm[i] = data->fan_from_reg(reg,
1115 data->fan_div[i]);
1116
1117 if (data->has_fan_min & (1 << i))
1118 data->fan_min[i] = nct6775_read_value(data,
1119 data->REG_FAN_MIN[i]);
Guenter Roeck5c25d952012-12-11 07:29:06 -08001120 data->fan_pulses[i] =
1121 nct6775_read_value(data, data->REG_FAN_PULSES[i]);
Guenter Roeck1c65dc32012-12-04 07:56:24 -08001122
1123 nct6775_select_fan_div(dev, data, i, reg);
1124 }
1125
Guenter Roeck77eb5b32012-12-04 08:30:54 -08001126 nct6775_update_pwm(dev);
Guenter Roeckcdcaece2012-12-04 09:04:52 -08001127 nct6775_update_pwm_limits(dev);
Guenter Roeck77eb5b32012-12-04 08:30:54 -08001128
Guenter Roeckaa136e52012-12-04 03:26:05 -08001129 /* Measured temperatures and limits */
1130 for (i = 0; i < NUM_TEMP; i++) {
1131 if (!(data->have_temp & (1 << i)))
1132 continue;
1133 for (j = 0; j < 4; j++) {
1134 if (data->reg_temp[j][i])
1135 data->temp[j][i]
1136 = nct6775_read_temp(data,
1137 data->reg_temp[j][i]);
1138 }
1139 if (!(data->have_temp_fixed & (1 << i)))
1140 continue;
1141 data->temp_offset[i]
1142 = nct6775_read_value(data, data->REG_TEMP_OFFSET[i]);
1143 }
1144
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07001145 data->alarms = 0;
1146 for (i = 0; i < NUM_REG_ALARM; i++) {
1147 u8 alarm;
1148 if (!data->REG_ALARM[i])
1149 continue;
1150 alarm = nct6775_read_value(data, data->REG_ALARM[i]);
1151 data->alarms |= ((u64)alarm) << (i << 3);
1152 }
1153
1154 data->last_updated = jiffies;
1155 data->valid = true;
1156 }
1157
1158 mutex_unlock(&data->update_lock);
1159 return data;
1160}
1161
1162/*
1163 * Sysfs callback functions
1164 */
1165static ssize_t
1166show_in_reg(struct device *dev, struct device_attribute *attr, char *buf)
1167{
1168 struct nct6775_data *data = nct6775_update_device(dev);
1169 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
1170 int nr = sattr->nr;
1171 int index = sattr->index;
1172 return sprintf(buf, "%ld\n", in_from_reg(data->in[nr][index], nr));
1173}
1174
1175static ssize_t
1176store_in_reg(struct device *dev, struct device_attribute *attr, const char *buf,
1177 size_t count)
1178{
1179 struct nct6775_data *data = dev_get_drvdata(dev);
1180 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
1181 int nr = sattr->nr;
1182 int index = sattr->index;
1183 unsigned long val;
1184 int err = kstrtoul(buf, 10, &val);
1185 if (err < 0)
1186 return err;
1187 mutex_lock(&data->update_lock);
1188 data->in[nr][index] = in_to_reg(val, nr);
1189 nct6775_write_value(data, data->REG_IN_MINMAX[index-1][nr],
1190 data->in[nr][index]);
1191 mutex_unlock(&data->update_lock);
1192 return count;
1193}
1194
1195static ssize_t
1196show_alarm(struct device *dev, struct device_attribute *attr, char *buf)
1197{
1198 struct nct6775_data *data = nct6775_update_device(dev);
1199 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1200 int nr = data->ALARM_BITS[sattr->index];
1201 return sprintf(buf, "%u\n",
1202 (unsigned int)((data->alarms >> nr) & 0x01));
1203}
1204
1205static SENSOR_DEVICE_ATTR_2(in0_input, S_IRUGO, show_in_reg, NULL, 0, 0);
1206static SENSOR_DEVICE_ATTR_2(in1_input, S_IRUGO, show_in_reg, NULL, 1, 0);
1207static SENSOR_DEVICE_ATTR_2(in2_input, S_IRUGO, show_in_reg, NULL, 2, 0);
1208static SENSOR_DEVICE_ATTR_2(in3_input, S_IRUGO, show_in_reg, NULL, 3, 0);
1209static SENSOR_DEVICE_ATTR_2(in4_input, S_IRUGO, show_in_reg, NULL, 4, 0);
1210static SENSOR_DEVICE_ATTR_2(in5_input, S_IRUGO, show_in_reg, NULL, 5, 0);
1211static SENSOR_DEVICE_ATTR_2(in6_input, S_IRUGO, show_in_reg, NULL, 6, 0);
1212static SENSOR_DEVICE_ATTR_2(in7_input, S_IRUGO, show_in_reg, NULL, 7, 0);
1213static SENSOR_DEVICE_ATTR_2(in8_input, S_IRUGO, show_in_reg, NULL, 8, 0);
1214static SENSOR_DEVICE_ATTR_2(in9_input, S_IRUGO, show_in_reg, NULL, 9, 0);
1215static SENSOR_DEVICE_ATTR_2(in10_input, S_IRUGO, show_in_reg, NULL, 10, 0);
1216static SENSOR_DEVICE_ATTR_2(in11_input, S_IRUGO, show_in_reg, NULL, 11, 0);
1217static SENSOR_DEVICE_ATTR_2(in12_input, S_IRUGO, show_in_reg, NULL, 12, 0);
1218static SENSOR_DEVICE_ATTR_2(in13_input, S_IRUGO, show_in_reg, NULL, 13, 0);
1219static SENSOR_DEVICE_ATTR_2(in14_input, S_IRUGO, show_in_reg, NULL, 14, 0);
1220
1221static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0);
1222static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1);
1223static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 2);
1224static SENSOR_DEVICE_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, 3);
1225static SENSOR_DEVICE_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, 4);
1226static SENSOR_DEVICE_ATTR(in5_alarm, S_IRUGO, show_alarm, NULL, 5);
1227static SENSOR_DEVICE_ATTR(in6_alarm, S_IRUGO, show_alarm, NULL, 6);
1228static SENSOR_DEVICE_ATTR(in7_alarm, S_IRUGO, show_alarm, NULL, 7);
1229static SENSOR_DEVICE_ATTR(in8_alarm, S_IRUGO, show_alarm, NULL, 8);
1230static SENSOR_DEVICE_ATTR(in9_alarm, S_IRUGO, show_alarm, NULL, 9);
1231static SENSOR_DEVICE_ATTR(in10_alarm, S_IRUGO, show_alarm, NULL, 10);
1232static SENSOR_DEVICE_ATTR(in11_alarm, S_IRUGO, show_alarm, NULL, 11);
1233static SENSOR_DEVICE_ATTR(in12_alarm, S_IRUGO, show_alarm, NULL, 12);
1234static SENSOR_DEVICE_ATTR(in13_alarm, S_IRUGO, show_alarm, NULL, 13);
1235static SENSOR_DEVICE_ATTR(in14_alarm, S_IRUGO, show_alarm, NULL, 14);
1236
1237static SENSOR_DEVICE_ATTR_2(in0_min, S_IWUSR | S_IRUGO, show_in_reg,
1238 store_in_reg, 0, 1);
1239static SENSOR_DEVICE_ATTR_2(in1_min, S_IWUSR | S_IRUGO, show_in_reg,
1240 store_in_reg, 1, 1);
1241static SENSOR_DEVICE_ATTR_2(in2_min, S_IWUSR | S_IRUGO, show_in_reg,
1242 store_in_reg, 2, 1);
1243static SENSOR_DEVICE_ATTR_2(in3_min, S_IWUSR | S_IRUGO, show_in_reg,
1244 store_in_reg, 3, 1);
1245static SENSOR_DEVICE_ATTR_2(in4_min, S_IWUSR | S_IRUGO, show_in_reg,
1246 store_in_reg, 4, 1);
1247static SENSOR_DEVICE_ATTR_2(in5_min, S_IWUSR | S_IRUGO, show_in_reg,
1248 store_in_reg, 5, 1);
1249static SENSOR_DEVICE_ATTR_2(in6_min, S_IWUSR | S_IRUGO, show_in_reg,
1250 store_in_reg, 6, 1);
1251static SENSOR_DEVICE_ATTR_2(in7_min, S_IWUSR | S_IRUGO, show_in_reg,
1252 store_in_reg, 7, 1);
1253static SENSOR_DEVICE_ATTR_2(in8_min, S_IWUSR | S_IRUGO, show_in_reg,
1254 store_in_reg, 8, 1);
1255static SENSOR_DEVICE_ATTR_2(in9_min, S_IWUSR | S_IRUGO, show_in_reg,
1256 store_in_reg, 9, 1);
1257static SENSOR_DEVICE_ATTR_2(in10_min, S_IWUSR | S_IRUGO, show_in_reg,
1258 store_in_reg, 10, 1);
1259static SENSOR_DEVICE_ATTR_2(in11_min, S_IWUSR | S_IRUGO, show_in_reg,
1260 store_in_reg, 11, 1);
1261static SENSOR_DEVICE_ATTR_2(in12_min, S_IWUSR | S_IRUGO, show_in_reg,
1262 store_in_reg, 12, 1);
1263static SENSOR_DEVICE_ATTR_2(in13_min, S_IWUSR | S_IRUGO, show_in_reg,
1264 store_in_reg, 13, 1);
1265static SENSOR_DEVICE_ATTR_2(in14_min, S_IWUSR | S_IRUGO, show_in_reg,
1266 store_in_reg, 14, 1);
1267
1268static SENSOR_DEVICE_ATTR_2(in0_max, S_IWUSR | S_IRUGO, show_in_reg,
1269 store_in_reg, 0, 2);
1270static SENSOR_DEVICE_ATTR_2(in1_max, S_IWUSR | S_IRUGO, show_in_reg,
1271 store_in_reg, 1, 2);
1272static SENSOR_DEVICE_ATTR_2(in2_max, S_IWUSR | S_IRUGO, show_in_reg,
1273 store_in_reg, 2, 2);
1274static SENSOR_DEVICE_ATTR_2(in3_max, S_IWUSR | S_IRUGO, show_in_reg,
1275 store_in_reg, 3, 2);
1276static SENSOR_DEVICE_ATTR_2(in4_max, S_IWUSR | S_IRUGO, show_in_reg,
1277 store_in_reg, 4, 2);
1278static SENSOR_DEVICE_ATTR_2(in5_max, S_IWUSR | S_IRUGO, show_in_reg,
1279 store_in_reg, 5, 2);
1280static SENSOR_DEVICE_ATTR_2(in6_max, S_IWUSR | S_IRUGO, show_in_reg,
1281 store_in_reg, 6, 2);
1282static SENSOR_DEVICE_ATTR_2(in7_max, S_IWUSR | S_IRUGO, show_in_reg,
1283 store_in_reg, 7, 2);
1284static SENSOR_DEVICE_ATTR_2(in8_max, S_IWUSR | S_IRUGO, show_in_reg,
1285 store_in_reg, 8, 2);
1286static SENSOR_DEVICE_ATTR_2(in9_max, S_IWUSR | S_IRUGO, show_in_reg,
1287 store_in_reg, 9, 2);
1288static SENSOR_DEVICE_ATTR_2(in10_max, S_IWUSR | S_IRUGO, show_in_reg,
1289 store_in_reg, 10, 2);
1290static SENSOR_DEVICE_ATTR_2(in11_max, S_IWUSR | S_IRUGO, show_in_reg,
1291 store_in_reg, 11, 2);
1292static SENSOR_DEVICE_ATTR_2(in12_max, S_IWUSR | S_IRUGO, show_in_reg,
1293 store_in_reg, 12, 2);
1294static SENSOR_DEVICE_ATTR_2(in13_max, S_IWUSR | S_IRUGO, show_in_reg,
1295 store_in_reg, 13, 2);
1296static SENSOR_DEVICE_ATTR_2(in14_max, S_IWUSR | S_IRUGO, show_in_reg,
1297 store_in_reg, 14, 2);
1298
1299static struct attribute *nct6775_attributes_in[15][5] = {
1300 {
1301 &sensor_dev_attr_in0_input.dev_attr.attr,
1302 &sensor_dev_attr_in0_min.dev_attr.attr,
1303 &sensor_dev_attr_in0_max.dev_attr.attr,
1304 &sensor_dev_attr_in0_alarm.dev_attr.attr,
1305 NULL
1306 },
1307 {
1308 &sensor_dev_attr_in1_input.dev_attr.attr,
1309 &sensor_dev_attr_in1_min.dev_attr.attr,
1310 &sensor_dev_attr_in1_max.dev_attr.attr,
1311 &sensor_dev_attr_in1_alarm.dev_attr.attr,
1312 NULL
1313 },
1314 {
1315 &sensor_dev_attr_in2_input.dev_attr.attr,
1316 &sensor_dev_attr_in2_min.dev_attr.attr,
1317 &sensor_dev_attr_in2_max.dev_attr.attr,
1318 &sensor_dev_attr_in2_alarm.dev_attr.attr,
1319 NULL
1320 },
1321 {
1322 &sensor_dev_attr_in3_input.dev_attr.attr,
1323 &sensor_dev_attr_in3_min.dev_attr.attr,
1324 &sensor_dev_attr_in3_max.dev_attr.attr,
1325 &sensor_dev_attr_in3_alarm.dev_attr.attr,
1326 NULL
1327 },
1328 {
1329 &sensor_dev_attr_in4_input.dev_attr.attr,
1330 &sensor_dev_attr_in4_min.dev_attr.attr,
1331 &sensor_dev_attr_in4_max.dev_attr.attr,
1332 &sensor_dev_attr_in4_alarm.dev_attr.attr,
1333 NULL
1334 },
1335 {
1336 &sensor_dev_attr_in5_input.dev_attr.attr,
1337 &sensor_dev_attr_in5_min.dev_attr.attr,
1338 &sensor_dev_attr_in5_max.dev_attr.attr,
1339 &sensor_dev_attr_in5_alarm.dev_attr.attr,
1340 NULL
1341 },
1342 {
1343 &sensor_dev_attr_in6_input.dev_attr.attr,
1344 &sensor_dev_attr_in6_min.dev_attr.attr,
1345 &sensor_dev_attr_in6_max.dev_attr.attr,
1346 &sensor_dev_attr_in6_alarm.dev_attr.attr,
1347 NULL
1348 },
1349 {
1350 &sensor_dev_attr_in7_input.dev_attr.attr,
1351 &sensor_dev_attr_in7_min.dev_attr.attr,
1352 &sensor_dev_attr_in7_max.dev_attr.attr,
1353 &sensor_dev_attr_in7_alarm.dev_attr.attr,
1354 NULL
1355 },
1356 {
1357 &sensor_dev_attr_in8_input.dev_attr.attr,
1358 &sensor_dev_attr_in8_min.dev_attr.attr,
1359 &sensor_dev_attr_in8_max.dev_attr.attr,
1360 &sensor_dev_attr_in8_alarm.dev_attr.attr,
1361 NULL
1362 },
1363 {
1364 &sensor_dev_attr_in9_input.dev_attr.attr,
1365 &sensor_dev_attr_in9_min.dev_attr.attr,
1366 &sensor_dev_attr_in9_max.dev_attr.attr,
1367 &sensor_dev_attr_in9_alarm.dev_attr.attr,
1368 NULL
1369 },
1370 {
1371 &sensor_dev_attr_in10_input.dev_attr.attr,
1372 &sensor_dev_attr_in10_min.dev_attr.attr,
1373 &sensor_dev_attr_in10_max.dev_attr.attr,
1374 &sensor_dev_attr_in10_alarm.dev_attr.attr,
1375 NULL
1376 },
1377 {
1378 &sensor_dev_attr_in11_input.dev_attr.attr,
1379 &sensor_dev_attr_in11_min.dev_attr.attr,
1380 &sensor_dev_attr_in11_max.dev_attr.attr,
1381 &sensor_dev_attr_in11_alarm.dev_attr.attr,
1382 NULL
1383 },
1384 {
1385 &sensor_dev_attr_in12_input.dev_attr.attr,
1386 &sensor_dev_attr_in12_min.dev_attr.attr,
1387 &sensor_dev_attr_in12_max.dev_attr.attr,
1388 &sensor_dev_attr_in12_alarm.dev_attr.attr,
1389 NULL
1390 },
1391 {
1392 &sensor_dev_attr_in13_input.dev_attr.attr,
1393 &sensor_dev_attr_in13_min.dev_attr.attr,
1394 &sensor_dev_attr_in13_max.dev_attr.attr,
1395 &sensor_dev_attr_in13_alarm.dev_attr.attr,
1396 NULL
1397 },
1398 {
1399 &sensor_dev_attr_in14_input.dev_attr.attr,
1400 &sensor_dev_attr_in14_min.dev_attr.attr,
1401 &sensor_dev_attr_in14_max.dev_attr.attr,
1402 &sensor_dev_attr_in14_alarm.dev_attr.attr,
1403 NULL
1404 },
1405};
1406
1407static const struct attribute_group nct6775_group_in[15] = {
1408 { .attrs = nct6775_attributes_in[0] },
1409 { .attrs = nct6775_attributes_in[1] },
1410 { .attrs = nct6775_attributes_in[2] },
1411 { .attrs = nct6775_attributes_in[3] },
1412 { .attrs = nct6775_attributes_in[4] },
1413 { .attrs = nct6775_attributes_in[5] },
1414 { .attrs = nct6775_attributes_in[6] },
1415 { .attrs = nct6775_attributes_in[7] },
1416 { .attrs = nct6775_attributes_in[8] },
1417 { .attrs = nct6775_attributes_in[9] },
1418 { .attrs = nct6775_attributes_in[10] },
1419 { .attrs = nct6775_attributes_in[11] },
1420 { .attrs = nct6775_attributes_in[12] },
1421 { .attrs = nct6775_attributes_in[13] },
1422 { .attrs = nct6775_attributes_in[14] },
1423};
1424
1425static ssize_t
Guenter Roeck1c65dc32012-12-04 07:56:24 -08001426show_fan(struct device *dev, struct device_attribute *attr, char *buf)
1427{
1428 struct nct6775_data *data = nct6775_update_device(dev);
1429 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1430 int nr = sattr->index;
1431 return sprintf(buf, "%d\n", data->rpm[nr]);
1432}
1433
1434static ssize_t
1435show_fan_min(struct device *dev, struct device_attribute *attr, char *buf)
1436{
1437 struct nct6775_data *data = nct6775_update_device(dev);
1438 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1439 int nr = sattr->index;
1440 return sprintf(buf, "%d\n",
1441 data->fan_from_reg_min(data->fan_min[nr],
1442 data->fan_div[nr]));
1443}
1444
1445static ssize_t
1446show_fan_div(struct device *dev, struct device_attribute *attr, char *buf)
1447{
1448 struct nct6775_data *data = nct6775_update_device(dev);
1449 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1450 int nr = sattr->index;
1451 return sprintf(buf, "%u\n", div_from_reg(data->fan_div[nr]));
1452}
1453
1454static ssize_t
1455store_fan_min(struct device *dev, struct device_attribute *attr,
1456 const char *buf, size_t count)
1457{
1458 struct nct6775_data *data = dev_get_drvdata(dev);
1459 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1460 int nr = sattr->index;
1461 unsigned long val;
1462 int err;
1463 unsigned int reg;
1464 u8 new_div;
1465
1466 err = kstrtoul(buf, 10, &val);
1467 if (err < 0)
1468 return err;
1469
1470 mutex_lock(&data->update_lock);
1471 if (!data->has_fan_div) {
1472 /* NCT6776F or NCT6779D; we know this is a 13 bit register */
1473 if (!val) {
1474 val = 0xff1f;
1475 } else {
1476 if (val > 1350000U)
1477 val = 135000U;
1478 val = 1350000U / val;
1479 val = (val & 0x1f) | ((val << 3) & 0xff00);
1480 }
1481 data->fan_min[nr] = val;
1482 goto write_min; /* Leave fan divider alone */
1483 }
1484 if (!val) {
1485 /* No min limit, alarm disabled */
1486 data->fan_min[nr] = 255;
1487 new_div = data->fan_div[nr]; /* No change */
1488 dev_info(dev, "fan%u low limit and alarm disabled\n", nr + 1);
1489 goto write_div;
1490 }
1491 reg = 1350000U / val;
1492 if (reg >= 128 * 255) {
1493 /*
1494 * Speed below this value cannot possibly be represented,
1495 * even with the highest divider (128)
1496 */
1497 data->fan_min[nr] = 254;
1498 new_div = 7; /* 128 == (1 << 7) */
1499 dev_warn(dev,
1500 "fan%u low limit %lu below minimum %u, set to minimum\n",
1501 nr + 1, val, data->fan_from_reg_min(254, 7));
1502 } else if (!reg) {
1503 /*
1504 * Speed above this value cannot possibly be represented,
1505 * even with the lowest divider (1)
1506 */
1507 data->fan_min[nr] = 1;
1508 new_div = 0; /* 1 == (1 << 0) */
1509 dev_warn(dev,
1510 "fan%u low limit %lu above maximum %u, set to maximum\n",
1511 nr + 1, val, data->fan_from_reg_min(1, 0));
1512 } else {
1513 /*
1514 * Automatically pick the best divider, i.e. the one such
1515 * that the min limit will correspond to a register value
1516 * in the 96..192 range
1517 */
1518 new_div = 0;
1519 while (reg > 192 && new_div < 7) {
1520 reg >>= 1;
1521 new_div++;
1522 }
1523 data->fan_min[nr] = reg;
1524 }
1525
1526write_div:
1527 /*
1528 * Write both the fan clock divider (if it changed) and the new
1529 * fan min (unconditionally)
1530 */
1531 if (new_div != data->fan_div[nr]) {
1532 dev_dbg(dev, "fan%u clock divider changed from %u to %u\n",
1533 nr + 1, div_from_reg(data->fan_div[nr]),
1534 div_from_reg(new_div));
1535 data->fan_div[nr] = new_div;
1536 nct6775_write_fan_div_common(data, nr);
1537 /* Give the chip time to sample a new speed value */
1538 data->last_updated = jiffies;
1539 }
1540
1541write_min:
1542 nct6775_write_value(data, data->REG_FAN_MIN[nr], data->fan_min[nr]);
1543 mutex_unlock(&data->update_lock);
1544
1545 return count;
1546}
1547
Guenter Roeck5c25d952012-12-11 07:29:06 -08001548static ssize_t
1549show_fan_pulses(struct device *dev, struct device_attribute *attr, char *buf)
1550{
1551 struct nct6775_data *data = nct6775_update_device(dev);
1552 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1553 int p = data->fan_pulses[sattr->index];
1554
1555 return sprintf(buf, "%d\n", p ? : 4);
1556}
1557
1558static ssize_t
1559store_fan_pulses(struct device *dev, struct device_attribute *attr,
1560 const char *buf, size_t count)
1561{
1562 struct nct6775_data *data = dev_get_drvdata(dev);
1563 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1564 int nr = sattr->index;
1565 unsigned long val;
1566 int err;
1567
1568 err = kstrtoul(buf, 10, &val);
1569 if (err < 0)
1570 return err;
1571
1572 if (val > 4)
1573 return -EINVAL;
1574
1575 mutex_lock(&data->update_lock);
1576 data->fan_pulses[nr] = val & 3;
1577 nct6775_write_value(data, data->REG_FAN_PULSES[nr], val & 3);
1578 mutex_unlock(&data->update_lock);
1579
1580 return count;
1581}
1582
Guenter Roeck1c65dc32012-12-04 07:56:24 -08001583static struct sensor_device_attribute sda_fan_input[] = {
1584 SENSOR_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0),
1585 SENSOR_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1),
1586 SENSOR_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2),
1587 SENSOR_ATTR(fan4_input, S_IRUGO, show_fan, NULL, 3),
1588 SENSOR_ATTR(fan5_input, S_IRUGO, show_fan, NULL, 4),
1589};
1590
1591static struct sensor_device_attribute sda_fan_alarm[] = {
1592 SENSOR_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, FAN_ALARM_BASE),
1593 SENSOR_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, FAN_ALARM_BASE + 1),
1594 SENSOR_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL, FAN_ALARM_BASE + 2),
1595 SENSOR_ATTR(fan4_alarm, S_IRUGO, show_alarm, NULL, FAN_ALARM_BASE + 3),
1596 SENSOR_ATTR(fan5_alarm, S_IRUGO, show_alarm, NULL, FAN_ALARM_BASE + 4),
1597};
1598
1599static struct sensor_device_attribute sda_fan_min[] = {
1600 SENSOR_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan_min,
1601 store_fan_min, 0),
1602 SENSOR_ATTR(fan2_min, S_IWUSR | S_IRUGO, show_fan_min,
1603 store_fan_min, 1),
1604 SENSOR_ATTR(fan3_min, S_IWUSR | S_IRUGO, show_fan_min,
1605 store_fan_min, 2),
1606 SENSOR_ATTR(fan4_min, S_IWUSR | S_IRUGO, show_fan_min,
1607 store_fan_min, 3),
1608 SENSOR_ATTR(fan5_min, S_IWUSR | S_IRUGO, show_fan_min,
1609 store_fan_min, 4),
1610};
1611
Guenter Roeck5c25d952012-12-11 07:29:06 -08001612static struct sensor_device_attribute sda_fan_pulses[] = {
1613 SENSOR_ATTR(fan1_pulses, S_IWUSR | S_IRUGO, show_fan_pulses,
1614 store_fan_pulses, 0),
1615 SENSOR_ATTR(fan2_pulses, S_IWUSR | S_IRUGO, show_fan_pulses,
1616 store_fan_pulses, 1),
1617 SENSOR_ATTR(fan3_pulses, S_IWUSR | S_IRUGO, show_fan_pulses,
1618 store_fan_pulses, 2),
1619 SENSOR_ATTR(fan4_pulses, S_IWUSR | S_IRUGO, show_fan_pulses,
1620 store_fan_pulses, 3),
1621 SENSOR_ATTR(fan5_pulses, S_IWUSR | S_IRUGO, show_fan_pulses,
1622 store_fan_pulses, 4),
1623};
1624
Guenter Roeck1c65dc32012-12-04 07:56:24 -08001625static struct sensor_device_attribute sda_fan_div[] = {
1626 SENSOR_ATTR(fan1_div, S_IRUGO, show_fan_div, NULL, 0),
1627 SENSOR_ATTR(fan2_div, S_IRUGO, show_fan_div, NULL, 1),
1628 SENSOR_ATTR(fan3_div, S_IRUGO, show_fan_div, NULL, 2),
1629 SENSOR_ATTR(fan4_div, S_IRUGO, show_fan_div, NULL, 3),
1630 SENSOR_ATTR(fan5_div, S_IRUGO, show_fan_div, NULL, 4),
1631};
1632
1633static ssize_t
Guenter Roeckaa136e52012-12-04 03:26:05 -08001634show_temp_label(struct device *dev, struct device_attribute *attr, char *buf)
1635{
1636 struct nct6775_data *data = nct6775_update_device(dev);
1637 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1638 int nr = sattr->index;
1639 return sprintf(buf, "%s\n", data->temp_label[data->temp_src[nr]]);
1640}
1641
1642static ssize_t
1643show_temp(struct device *dev, struct device_attribute *attr, char *buf)
1644{
1645 struct nct6775_data *data = nct6775_update_device(dev);
1646 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
1647 int nr = sattr->nr;
1648 int index = sattr->index;
1649
1650 return sprintf(buf, "%d\n", LM75_TEMP_FROM_REG(data->temp[index][nr]));
1651}
1652
1653static ssize_t
1654store_temp(struct device *dev, struct device_attribute *attr, const char *buf,
1655 size_t count)
1656{
1657 struct nct6775_data *data = dev_get_drvdata(dev);
1658 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
1659 int nr = sattr->nr;
1660 int index = sattr->index;
1661 int err;
1662 long val;
1663
1664 err = kstrtol(buf, 10, &val);
1665 if (err < 0)
1666 return err;
1667
1668 mutex_lock(&data->update_lock);
1669 data->temp[index][nr] = LM75_TEMP_TO_REG(val);
1670 nct6775_write_temp(data, data->reg_temp[index][nr],
1671 data->temp[index][nr]);
1672 mutex_unlock(&data->update_lock);
1673 return count;
1674}
1675
1676static ssize_t
1677show_temp_offset(struct device *dev, struct device_attribute *attr, char *buf)
1678{
1679 struct nct6775_data *data = nct6775_update_device(dev);
1680 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1681
1682 return sprintf(buf, "%d\n", data->temp_offset[sattr->index] * 1000);
1683}
1684
1685static ssize_t
1686store_temp_offset(struct device *dev, struct device_attribute *attr,
1687 const char *buf, size_t count)
1688{
1689 struct nct6775_data *data = dev_get_drvdata(dev);
1690 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1691 int nr = sattr->index;
1692 long val;
1693 int err;
1694
1695 err = kstrtol(buf, 10, &val);
1696 if (err < 0)
1697 return err;
1698
1699 val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), -128, 127);
1700
1701 mutex_lock(&data->update_lock);
1702 data->temp_offset[nr] = val;
1703 nct6775_write_value(data, data->REG_TEMP_OFFSET[nr], val);
1704 mutex_unlock(&data->update_lock);
1705
1706 return count;
1707}
1708
1709static ssize_t
1710show_temp_type(struct device *dev, struct device_attribute *attr, char *buf)
1711{
1712 struct nct6775_data *data = nct6775_update_device(dev);
1713 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1714 int nr = sattr->index;
1715 return sprintf(buf, "%d\n", (int)data->temp_type[nr]);
1716}
1717
1718static ssize_t
1719store_temp_type(struct device *dev, struct device_attribute *attr,
1720 const char *buf, size_t count)
1721{
1722 struct nct6775_data *data = nct6775_update_device(dev);
1723 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1724 int nr = sattr->index;
1725 unsigned long val;
1726 int err;
1727 u8 vbat, diode, bit;
1728
1729 err = kstrtoul(buf, 10, &val);
1730 if (err < 0)
1731 return err;
1732
1733 if (val != 1 && val != 3 && val != 4)
1734 return -EINVAL;
1735
1736 mutex_lock(&data->update_lock);
1737
1738 data->temp_type[nr] = val;
1739 vbat = nct6775_read_value(data, data->REG_VBAT) & ~(0x02 << nr);
1740 diode = nct6775_read_value(data, data->REG_DIODE) & ~(0x02 << nr);
1741 bit = 0x02 << nr;
1742 switch (val) {
1743 case 1: /* CPU diode (diode, current mode) */
1744 vbat |= bit;
1745 diode |= bit;
1746 break;
1747 case 3: /* diode, voltage mode */
1748 vbat |= bit;
1749 break;
1750 case 4: /* thermistor */
1751 break;
1752 }
1753 nct6775_write_value(data, data->REG_VBAT, vbat);
1754 nct6775_write_value(data, data->REG_DIODE, diode);
1755
1756 mutex_unlock(&data->update_lock);
1757 return count;
1758}
1759
1760static struct sensor_device_attribute_2 sda_temp_input[] = {
1761 SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0),
1762 SENSOR_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 1, 0),
1763 SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 2, 0),
1764 SENSOR_ATTR_2(temp4_input, S_IRUGO, show_temp, NULL, 3, 0),
1765 SENSOR_ATTR_2(temp5_input, S_IRUGO, show_temp, NULL, 4, 0),
1766 SENSOR_ATTR_2(temp6_input, S_IRUGO, show_temp, NULL, 5, 0),
1767 SENSOR_ATTR_2(temp7_input, S_IRUGO, show_temp, NULL, 6, 0),
1768 SENSOR_ATTR_2(temp8_input, S_IRUGO, show_temp, NULL, 7, 0),
1769 SENSOR_ATTR_2(temp9_input, S_IRUGO, show_temp, NULL, 8, 0),
1770 SENSOR_ATTR_2(temp10_input, S_IRUGO, show_temp, NULL, 9, 0),
1771};
1772
1773static struct sensor_device_attribute sda_temp_label[] = {
1774 SENSOR_ATTR(temp1_label, S_IRUGO, show_temp_label, NULL, 0),
1775 SENSOR_ATTR(temp2_label, S_IRUGO, show_temp_label, NULL, 1),
1776 SENSOR_ATTR(temp3_label, S_IRUGO, show_temp_label, NULL, 2),
1777 SENSOR_ATTR(temp4_label, S_IRUGO, show_temp_label, NULL, 3),
1778 SENSOR_ATTR(temp5_label, S_IRUGO, show_temp_label, NULL, 4),
1779 SENSOR_ATTR(temp6_label, S_IRUGO, show_temp_label, NULL, 5),
1780 SENSOR_ATTR(temp7_label, S_IRUGO, show_temp_label, NULL, 6),
1781 SENSOR_ATTR(temp8_label, S_IRUGO, show_temp_label, NULL, 7),
1782 SENSOR_ATTR(temp9_label, S_IRUGO, show_temp_label, NULL, 8),
1783 SENSOR_ATTR(temp10_label, S_IRUGO, show_temp_label, NULL, 9),
1784};
1785
1786static struct sensor_device_attribute_2 sda_temp_max[] = {
1787 SENSOR_ATTR_2(temp1_max, S_IRUGO | S_IWUSR, show_temp, store_temp,
1788 0, 1),
1789 SENSOR_ATTR_2(temp2_max, S_IRUGO | S_IWUSR, show_temp, store_temp,
1790 1, 1),
1791 SENSOR_ATTR_2(temp3_max, S_IRUGO | S_IWUSR, show_temp, store_temp,
1792 2, 1),
1793 SENSOR_ATTR_2(temp4_max, S_IRUGO | S_IWUSR, show_temp, store_temp,
1794 3, 1),
1795 SENSOR_ATTR_2(temp5_max, S_IRUGO | S_IWUSR, show_temp, store_temp,
1796 4, 1),
1797 SENSOR_ATTR_2(temp6_max, S_IRUGO | S_IWUSR, show_temp, store_temp,
1798 5, 1),
1799 SENSOR_ATTR_2(temp7_max, S_IRUGO | S_IWUSR, show_temp, store_temp,
1800 6, 1),
1801 SENSOR_ATTR_2(temp8_max, S_IRUGO | S_IWUSR, show_temp, store_temp,
1802 7, 1),
1803 SENSOR_ATTR_2(temp9_max, S_IRUGO | S_IWUSR, show_temp, store_temp,
1804 8, 1),
1805 SENSOR_ATTR_2(temp10_max, S_IRUGO | S_IWUSR, show_temp, store_temp,
1806 9, 1),
1807};
1808
1809static struct sensor_device_attribute_2 sda_temp_max_hyst[] = {
1810 SENSOR_ATTR_2(temp1_max_hyst, S_IRUGO | S_IWUSR, show_temp, store_temp,
1811 0, 2),
1812 SENSOR_ATTR_2(temp2_max_hyst, S_IRUGO | S_IWUSR, show_temp, store_temp,
1813 1, 2),
1814 SENSOR_ATTR_2(temp3_max_hyst, S_IRUGO | S_IWUSR, show_temp, store_temp,
1815 2, 2),
1816 SENSOR_ATTR_2(temp4_max_hyst, S_IRUGO | S_IWUSR, show_temp, store_temp,
1817 3, 2),
1818 SENSOR_ATTR_2(temp5_max_hyst, S_IRUGO | S_IWUSR, show_temp, store_temp,
1819 4, 2),
1820 SENSOR_ATTR_2(temp6_max_hyst, S_IRUGO | S_IWUSR, show_temp, store_temp,
1821 5, 2),
1822 SENSOR_ATTR_2(temp7_max_hyst, S_IRUGO | S_IWUSR, show_temp, store_temp,
1823 6, 2),
1824 SENSOR_ATTR_2(temp8_max_hyst, S_IRUGO | S_IWUSR, show_temp, store_temp,
1825 7, 2),
1826 SENSOR_ATTR_2(temp9_max_hyst, S_IRUGO | S_IWUSR, show_temp, store_temp,
1827 8, 2),
1828 SENSOR_ATTR_2(temp10_max_hyst, S_IRUGO | S_IWUSR, show_temp, store_temp,
1829 9, 2),
1830};
1831
1832static struct sensor_device_attribute_2 sda_temp_crit[] = {
1833 SENSOR_ATTR_2(temp1_crit, S_IRUGO | S_IWUSR, show_temp, store_temp,
1834 0, 3),
1835 SENSOR_ATTR_2(temp2_crit, S_IRUGO | S_IWUSR, show_temp, store_temp,
1836 1, 3),
1837 SENSOR_ATTR_2(temp3_crit, S_IRUGO | S_IWUSR, show_temp, store_temp,
1838 2, 3),
1839 SENSOR_ATTR_2(temp4_crit, S_IRUGO | S_IWUSR, show_temp, store_temp,
1840 3, 3),
1841 SENSOR_ATTR_2(temp5_crit, S_IRUGO | S_IWUSR, show_temp, store_temp,
1842 4, 3),
1843 SENSOR_ATTR_2(temp6_crit, S_IRUGO | S_IWUSR, show_temp, store_temp,
1844 5, 3),
1845 SENSOR_ATTR_2(temp7_crit, S_IRUGO | S_IWUSR, show_temp, store_temp,
1846 6, 3),
1847 SENSOR_ATTR_2(temp8_crit, S_IRUGO | S_IWUSR, show_temp, store_temp,
1848 7, 3),
1849 SENSOR_ATTR_2(temp9_crit, S_IRUGO | S_IWUSR, show_temp, store_temp,
1850 8, 3),
1851 SENSOR_ATTR_2(temp10_crit, S_IRUGO | S_IWUSR, show_temp, store_temp,
1852 9, 3),
1853};
1854
1855static struct sensor_device_attribute sda_temp_offset[] = {
1856 SENSOR_ATTR(temp1_offset, S_IRUGO | S_IWUSR, show_temp_offset,
1857 store_temp_offset, 0),
1858 SENSOR_ATTR(temp2_offset, S_IRUGO | S_IWUSR, show_temp_offset,
1859 store_temp_offset, 1),
1860 SENSOR_ATTR(temp3_offset, S_IRUGO | S_IWUSR, show_temp_offset,
1861 store_temp_offset, 2),
1862 SENSOR_ATTR(temp4_offset, S_IRUGO | S_IWUSR, show_temp_offset,
1863 store_temp_offset, 3),
1864 SENSOR_ATTR(temp5_offset, S_IRUGO | S_IWUSR, show_temp_offset,
1865 store_temp_offset, 4),
1866 SENSOR_ATTR(temp6_offset, S_IRUGO | S_IWUSR, show_temp_offset,
1867 store_temp_offset, 5),
1868};
1869
1870static struct sensor_device_attribute sda_temp_type[] = {
1871 SENSOR_ATTR(temp1_type, S_IRUGO | S_IWUSR, show_temp_type,
1872 store_temp_type, 0),
1873 SENSOR_ATTR(temp2_type, S_IRUGO | S_IWUSR, show_temp_type,
1874 store_temp_type, 1),
1875 SENSOR_ATTR(temp3_type, S_IRUGO | S_IWUSR, show_temp_type,
1876 store_temp_type, 2),
1877 SENSOR_ATTR(temp4_type, S_IRUGO | S_IWUSR, show_temp_type,
1878 store_temp_type, 3),
1879 SENSOR_ATTR(temp5_type, S_IRUGO | S_IWUSR, show_temp_type,
1880 store_temp_type, 4),
1881 SENSOR_ATTR(temp6_type, S_IRUGO | S_IWUSR, show_temp_type,
1882 store_temp_type, 5),
1883};
1884
1885static struct sensor_device_attribute sda_temp_alarm[] = {
1886 SENSOR_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL,
1887 TEMP_ALARM_BASE),
1888 SENSOR_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL,
1889 TEMP_ALARM_BASE + 1),
1890 SENSOR_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL,
1891 TEMP_ALARM_BASE + 2),
1892 SENSOR_ATTR(temp4_alarm, S_IRUGO, show_alarm, NULL,
1893 TEMP_ALARM_BASE + 3),
1894 SENSOR_ATTR(temp5_alarm, S_IRUGO, show_alarm, NULL,
1895 TEMP_ALARM_BASE + 4),
1896 SENSOR_ATTR(temp6_alarm, S_IRUGO, show_alarm, NULL,
1897 TEMP_ALARM_BASE + 5),
1898};
1899
1900#define NUM_TEMP_ALARM ARRAY_SIZE(sda_temp_alarm)
1901
1902static ssize_t
Guenter Roeck77eb5b32012-12-04 08:30:54 -08001903show_pwm_mode(struct device *dev, struct device_attribute *attr, char *buf)
1904{
1905 struct nct6775_data *data = nct6775_update_device(dev);
1906 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1907
1908 return sprintf(buf, "%d\n", !data->pwm_mode[sattr->index]);
1909}
1910
1911static ssize_t
1912store_pwm_mode(struct device *dev, struct device_attribute *attr,
1913 const char *buf, size_t count)
1914{
1915 struct nct6775_data *data = dev_get_drvdata(dev);
1916 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1917 int nr = sattr->index;
1918 unsigned long val;
1919 int err;
1920 u8 reg;
1921
1922 err = kstrtoul(buf, 10, &val);
1923 if (err < 0)
1924 return err;
1925
1926 if (val > 1)
1927 return -EINVAL;
1928
1929 /* Setting DC mode is not supported for all chips/channels */
1930 if (data->REG_PWM_MODE[nr] == 0) {
1931 if (val)
1932 return -EINVAL;
1933 return count;
1934 }
1935
1936 mutex_lock(&data->update_lock);
1937 data->pwm_mode[nr] = val;
1938 reg = nct6775_read_value(data, data->REG_PWM_MODE[nr]);
1939 reg &= ~data->PWM_MODE_MASK[nr];
1940 if (val)
1941 reg |= data->PWM_MODE_MASK[nr];
1942 nct6775_write_value(data, data->REG_PWM_MODE[nr], reg);
1943 mutex_unlock(&data->update_lock);
1944 return count;
1945}
1946
1947static ssize_t
1948show_pwm(struct device *dev, struct device_attribute *attr, char *buf)
1949{
1950 struct nct6775_data *data = nct6775_update_device(dev);
1951 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
1952 int nr = sattr->nr;
1953 int index = sattr->index;
1954 int pwm;
1955
1956 /*
1957 * For automatic fan control modes, show current pwm readings.
1958 * Otherwise, show the configured value.
1959 */
1960 if (index == 0 && data->pwm_enable[nr] > manual)
1961 pwm = nct6775_read_value(data, data->REG_PWM_READ[nr]);
1962 else
1963 pwm = data->pwm[index][nr];
1964
1965 return sprintf(buf, "%d\n", pwm);
1966}
1967
1968static ssize_t
1969store_pwm(struct device *dev, struct device_attribute *attr, const char *buf,
1970 size_t count)
1971{
1972 struct nct6775_data *data = dev_get_drvdata(dev);
1973 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
1974 int nr = sattr->nr;
1975 int index = sattr->index;
1976 unsigned long val;
Guenter Roeckbbd8dec2012-12-04 09:08:29 -08001977 int minval[7] = { 0, 1, 1, data->pwm[2][nr], 0, 0, 0 };
1978 int maxval[7]
1979 = { 255, 255, data->pwm[3][nr] ? : 255, 255, 255, 255, 255 };
Guenter Roeck77eb5b32012-12-04 08:30:54 -08001980 int err;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08001981 u8 reg;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08001982
1983 err = kstrtoul(buf, 10, &val);
1984 if (err < 0)
1985 return err;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08001986 val = clamp_val(val, minval[index], maxval[index]);
Guenter Roeck77eb5b32012-12-04 08:30:54 -08001987
1988 mutex_lock(&data->update_lock);
1989 data->pwm[index][nr] = val;
1990 nct6775_write_value(data, data->REG_PWM[index][nr], val);
Guenter Roeckcdcaece2012-12-04 09:04:52 -08001991 if (index == 2) { /* floor: disable if val == 0 */
1992 reg = nct6775_read_value(data, data->REG_TEMP_SEL[nr]);
1993 reg &= 0x7f;
1994 if (val)
1995 reg |= 0x80;
1996 nct6775_write_value(data, data->REG_TEMP_SEL[nr], reg);
1997 }
Guenter Roeck77eb5b32012-12-04 08:30:54 -08001998 mutex_unlock(&data->update_lock);
1999 return count;
2000}
2001
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002002/* Returns 0 if OK, -EINVAL otherwise */
2003static int check_trip_points(struct nct6775_data *data, int nr)
2004{
2005 int i;
2006
2007 for (i = 0; i < data->auto_pwm_num - 1; i++) {
2008 if (data->auto_temp[nr][i] > data->auto_temp[nr][i + 1])
2009 return -EINVAL;
2010 }
2011 for (i = 0; i < data->auto_pwm_num - 1; i++) {
2012 if (data->auto_pwm[nr][i] > data->auto_pwm[nr][i + 1])
2013 return -EINVAL;
2014 }
2015 /* validate critical temperature and pwm if enabled (pwm > 0) */
2016 if (data->auto_pwm[nr][data->auto_pwm_num]) {
2017 if (data->auto_temp[nr][data->auto_pwm_num - 1] >
2018 data->auto_temp[nr][data->auto_pwm_num] ||
2019 data->auto_pwm[nr][data->auto_pwm_num - 1] >
2020 data->auto_pwm[nr][data->auto_pwm_num])
2021 return -EINVAL;
2022 }
2023 return 0;
2024}
2025
2026static void pwm_update_registers(struct nct6775_data *data, int nr)
2027{
2028 u8 reg;
2029
2030 switch (data->pwm_enable[nr]) {
2031 case off:
2032 case manual:
2033 break;
2034 case speed_cruise:
2035 reg = nct6775_read_value(data, data->REG_FAN_MODE[nr]);
2036 reg = (reg & ~data->tolerance_mask) |
2037 (data->target_speed_tolerance[nr] & data->tolerance_mask);
2038 nct6775_write_value(data, data->REG_FAN_MODE[nr], reg);
2039 nct6775_write_value(data, data->REG_TARGET[nr],
2040 data->target_speed[nr] & 0xff);
2041 if (data->REG_TOLERANCE_H) {
2042 reg = (data->target_speed[nr] >> 8) & 0x0f;
2043 reg |= (data->target_speed_tolerance[nr] & 0x38) << 1;
2044 nct6775_write_value(data,
2045 data->REG_TOLERANCE_H[nr],
2046 reg);
2047 }
2048 break;
2049 case thermal_cruise:
2050 nct6775_write_value(data, data->REG_TARGET[nr],
2051 data->target_temp[nr]);
2052 /* intentional */
2053 default:
2054 reg = nct6775_read_value(data, data->REG_FAN_MODE[nr]);
2055 reg = (reg & ~data->tolerance_mask) |
2056 data->temp_tolerance[0][nr];
2057 nct6775_write_value(data, data->REG_FAN_MODE[nr], reg);
2058 break;
2059 }
2060}
2061
Guenter Roeck77eb5b32012-12-04 08:30:54 -08002062static ssize_t
2063show_pwm_enable(struct device *dev, struct device_attribute *attr, char *buf)
2064{
2065 struct nct6775_data *data = nct6775_update_device(dev);
2066 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2067
2068 return sprintf(buf, "%d\n", data->pwm_enable[sattr->index]);
2069}
2070
2071static ssize_t
2072store_pwm_enable(struct device *dev, struct device_attribute *attr,
2073 const char *buf, size_t count)
2074{
2075 struct nct6775_data *data = dev_get_drvdata(dev);
2076 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2077 int nr = sattr->index;
2078 unsigned long val;
2079 int err;
2080 u16 reg;
2081
2082 err = kstrtoul(buf, 10, &val);
2083 if (err < 0)
2084 return err;
2085
2086 if (val > sf4)
2087 return -EINVAL;
2088
2089 if (val == sf3 && data->kind != nct6775)
2090 return -EINVAL;
2091
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002092 if (val == sf4 && check_trip_points(data, nr)) {
2093 dev_err(dev, "Inconsistent trip points, not switching to SmartFan IV mode\n");
2094 dev_err(dev, "Adjust trip points and try again\n");
2095 return -EINVAL;
2096 }
2097
Guenter Roeck77eb5b32012-12-04 08:30:54 -08002098 mutex_lock(&data->update_lock);
2099 data->pwm_enable[nr] = val;
2100 if (val == off) {
2101 /*
2102 * turn off pwm control: select manual mode, set pwm to maximum
2103 */
2104 data->pwm[0][nr] = 255;
2105 nct6775_write_value(data, data->REG_PWM[0][nr], 255);
2106 }
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002107 pwm_update_registers(data, nr);
Guenter Roeck77eb5b32012-12-04 08:30:54 -08002108 reg = nct6775_read_value(data, data->REG_FAN_MODE[nr]);
2109 reg &= 0x0f;
2110 reg |= pwm_enable_to_reg(val) << 4;
2111 nct6775_write_value(data, data->REG_FAN_MODE[nr], reg);
2112 mutex_unlock(&data->update_lock);
2113 return count;
2114}
2115
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002116static ssize_t
Guenter Roeckbbd8dec2012-12-04 09:08:29 -08002117show_pwm_temp_sel_common(struct nct6775_data *data, char *buf, int src)
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002118{
Guenter Roeckbbd8dec2012-12-04 09:08:29 -08002119 int i, sel = 0;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002120
2121 for (i = 0; i < NUM_TEMP; i++) {
2122 if (!(data->have_temp & (1 << i)))
2123 continue;
2124 if (src == data->temp_src[i]) {
2125 sel = i + 1;
2126 break;
2127 }
2128 }
2129
2130 return sprintf(buf, "%d\n", sel);
2131}
2132
2133static ssize_t
Guenter Roeckbbd8dec2012-12-04 09:08:29 -08002134show_pwm_temp_sel(struct device *dev, struct device_attribute *attr, char *buf)
2135{
2136 struct nct6775_data *data = nct6775_update_device(dev);
2137 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2138 int index = sattr->index;
2139
2140 return show_pwm_temp_sel_common(data, buf, data->pwm_temp_sel[index]);
2141}
2142
2143static ssize_t
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002144store_pwm_temp_sel(struct device *dev, struct device_attribute *attr,
2145 const char *buf, size_t count)
2146{
2147 struct nct6775_data *data = nct6775_update_device(dev);
2148 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2149 int nr = sattr->index;
2150 unsigned long val;
2151 int err, reg, src;
2152
2153 err = kstrtoul(buf, 10, &val);
2154 if (err < 0)
2155 return err;
2156 if (val == 0 || val > NUM_TEMP)
2157 return -EINVAL;
2158 if (!(data->have_temp & (1 << (val - 1))) || !data->temp_src[val - 1])
2159 return -EINVAL;
2160
2161 mutex_lock(&data->update_lock);
2162 src = data->temp_src[val - 1];
2163 data->pwm_temp_sel[nr] = src;
2164 reg = nct6775_read_value(data, data->REG_TEMP_SEL[nr]);
2165 reg &= 0xe0;
2166 reg |= src;
2167 nct6775_write_value(data, data->REG_TEMP_SEL[nr], reg);
2168 mutex_unlock(&data->update_lock);
2169
2170 return count;
2171}
2172
2173static ssize_t
Guenter Roeckbbd8dec2012-12-04 09:08:29 -08002174show_pwm_weight_temp_sel(struct device *dev, struct device_attribute *attr,
2175 char *buf)
2176{
2177 struct nct6775_data *data = nct6775_update_device(dev);
2178 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2179 int index = sattr->index;
2180
2181 return show_pwm_temp_sel_common(data, buf,
2182 data->pwm_weight_temp_sel[index]);
2183}
2184
2185static ssize_t
2186store_pwm_weight_temp_sel(struct device *dev, struct device_attribute *attr,
2187 const char *buf, size_t count)
2188{
2189 struct nct6775_data *data = nct6775_update_device(dev);
2190 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2191 int nr = sattr->index;
2192 unsigned long val;
2193 int err, reg, src;
2194
2195 err = kstrtoul(buf, 10, &val);
2196 if (err < 0)
2197 return err;
2198 if (val > NUM_TEMP)
2199 return -EINVAL;
2200 if (val && (!(data->have_temp & (1 << (val - 1))) ||
2201 !data->temp_src[val - 1]))
2202 return -EINVAL;
2203
2204 mutex_lock(&data->update_lock);
2205 if (val) {
2206 src = data->temp_src[val - 1];
2207 data->pwm_weight_temp_sel[nr] = src;
2208 reg = nct6775_read_value(data, data->REG_WEIGHT_TEMP_SEL[nr]);
2209 reg &= 0xe0;
2210 reg |= (src | 0x80);
2211 nct6775_write_value(data, data->REG_WEIGHT_TEMP_SEL[nr], reg);
2212 } else {
2213 data->pwm_weight_temp_sel[nr] = 0;
2214 reg = nct6775_read_value(data, data->REG_WEIGHT_TEMP_SEL[nr]);
2215 reg &= 0x7f;
2216 nct6775_write_value(data, data->REG_WEIGHT_TEMP_SEL[nr], reg);
2217 }
2218 mutex_unlock(&data->update_lock);
2219
2220 return count;
2221}
2222
2223static ssize_t
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002224show_target_temp(struct device *dev, struct device_attribute *attr, char *buf)
2225{
2226 struct nct6775_data *data = nct6775_update_device(dev);
2227 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2228
2229 return sprintf(buf, "%d\n", data->target_temp[sattr->index] * 1000);
2230}
2231
2232static ssize_t
2233store_target_temp(struct device *dev, struct device_attribute *attr,
2234 const char *buf, size_t count)
2235{
2236 struct nct6775_data *data = dev_get_drvdata(dev);
2237 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2238 int nr = sattr->index;
2239 unsigned long val;
2240 int err;
2241
2242 err = kstrtoul(buf, 10, &val);
2243 if (err < 0)
2244 return err;
2245
2246 val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0,
2247 data->target_temp_mask);
2248
2249 mutex_lock(&data->update_lock);
2250 data->target_temp[nr] = val;
2251 pwm_update_registers(data, nr);
2252 mutex_unlock(&data->update_lock);
2253 return count;
2254}
2255
2256static ssize_t
2257show_target_speed(struct device *dev, struct device_attribute *attr, char *buf)
2258{
2259 struct nct6775_data *data = nct6775_update_device(dev);
2260 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2261 int nr = sattr->index;
2262
2263 return sprintf(buf, "%d\n",
2264 fan_from_reg16(data->target_speed[nr],
2265 data->fan_div[nr]));
2266}
2267
2268static ssize_t
2269store_target_speed(struct device *dev, struct device_attribute *attr,
2270 const char *buf, size_t count)
2271{
2272 struct nct6775_data *data = dev_get_drvdata(dev);
2273 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2274 int nr = sattr->index;
2275 unsigned long val;
2276 int err;
2277 u16 speed;
2278
2279 err = kstrtoul(buf, 10, &val);
2280 if (err < 0)
2281 return err;
2282
2283 val = clamp_val(val, 0, 1350000U);
2284 speed = fan_to_reg(val, data->fan_div[nr]);
2285
2286 mutex_lock(&data->update_lock);
2287 data->target_speed[nr] = speed;
2288 pwm_update_registers(data, nr);
2289 mutex_unlock(&data->update_lock);
2290 return count;
2291}
2292
2293static ssize_t
2294show_temp_tolerance(struct device *dev, struct device_attribute *attr,
2295 char *buf)
2296{
2297 struct nct6775_data *data = nct6775_update_device(dev);
2298 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2299 int nr = sattr->nr;
2300 int index = sattr->index;
2301
2302 return sprintf(buf, "%d\n", data->temp_tolerance[index][nr] * 1000);
2303}
2304
2305static ssize_t
2306store_temp_tolerance(struct device *dev, struct device_attribute *attr,
2307 const char *buf, size_t count)
2308{
2309 struct nct6775_data *data = dev_get_drvdata(dev);
2310 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2311 int nr = sattr->nr;
2312 int index = sattr->index;
2313 unsigned long val;
2314 int err;
2315
2316 err = kstrtoul(buf, 10, &val);
2317 if (err < 0)
2318 return err;
2319
2320 /* Limit tolerance as needed */
2321 val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0, data->tolerance_mask);
2322
2323 mutex_lock(&data->update_lock);
2324 data->temp_tolerance[index][nr] = val;
2325 if (index)
2326 pwm_update_registers(data, nr);
2327 else
2328 nct6775_write_value(data,
2329 data->REG_CRITICAL_TEMP_TOLERANCE[nr],
2330 val);
2331 mutex_unlock(&data->update_lock);
2332 return count;
2333}
2334
2335/*
2336 * Fan speed tolerance is a tricky beast, since the associated register is
2337 * a tick counter, but the value is reported and configured as rpm.
2338 * Compute resulting low and high rpm values and report the difference.
2339 */
2340static ssize_t
2341show_speed_tolerance(struct device *dev, struct device_attribute *attr,
2342 char *buf)
2343{
2344 struct nct6775_data *data = nct6775_update_device(dev);
2345 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2346 int nr = sattr->index;
2347 int low = data->target_speed[nr] - data->target_speed_tolerance[nr];
2348 int high = data->target_speed[nr] + data->target_speed_tolerance[nr];
2349 int tolerance;
2350
2351 if (low <= 0)
2352 low = 1;
2353 if (high > 0xffff)
2354 high = 0xffff;
2355 if (high < low)
2356 high = low;
2357
2358 tolerance = (fan_from_reg16(low, data->fan_div[nr])
2359 - fan_from_reg16(high, data->fan_div[nr])) / 2;
2360
2361 return sprintf(buf, "%d\n", tolerance);
2362}
2363
2364static ssize_t
2365store_speed_tolerance(struct device *dev, struct device_attribute *attr,
2366 const char *buf, size_t count)
2367{
2368 struct nct6775_data *data = dev_get_drvdata(dev);
2369 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
2370 int nr = sattr->index;
2371 unsigned long val;
2372 int err;
2373 int low, high;
2374
2375 err = kstrtoul(buf, 10, &val);
2376 if (err < 0)
2377 return err;
2378
2379 high = fan_from_reg16(data->target_speed[nr],
2380 data->fan_div[nr]) + val;
2381 low = fan_from_reg16(data->target_speed[nr],
2382 data->fan_div[nr]) - val;
2383 if (low <= 0)
2384 low = 1;
2385 if (high < low)
2386 high = low;
2387
2388 val = (fan_to_reg(low, data->fan_div[nr]) -
2389 fan_to_reg(high, data->fan_div[nr])) / 2;
2390
2391 /* Limit tolerance as needed */
2392 val = clamp_val(val, 0, data->speed_tolerance_limit);
2393
2394 mutex_lock(&data->update_lock);
2395 data->target_speed_tolerance[nr] = val;
2396 pwm_update_registers(data, nr);
2397 mutex_unlock(&data->update_lock);
2398 return count;
2399}
2400
Guenter Roeck77eb5b32012-12-04 08:30:54 -08002401static SENSOR_DEVICE_ATTR_2(pwm1, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 0, 0);
2402static SENSOR_DEVICE_ATTR_2(pwm2, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 1, 0);
2403static SENSOR_DEVICE_ATTR_2(pwm3, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 2, 0);
2404static SENSOR_DEVICE_ATTR_2(pwm4, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 3, 0);
2405static SENSOR_DEVICE_ATTR_2(pwm5, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 4, 0);
2406
2407static SENSOR_DEVICE_ATTR(pwm1_mode, S_IWUSR | S_IRUGO, show_pwm_mode,
2408 store_pwm_mode, 0);
2409static SENSOR_DEVICE_ATTR(pwm2_mode, S_IWUSR | S_IRUGO, show_pwm_mode,
2410 store_pwm_mode, 1);
2411static SENSOR_DEVICE_ATTR(pwm3_mode, S_IWUSR | S_IRUGO, show_pwm_mode,
2412 store_pwm_mode, 2);
2413static SENSOR_DEVICE_ATTR(pwm4_mode, S_IWUSR | S_IRUGO, show_pwm_mode,
2414 store_pwm_mode, 3);
2415static SENSOR_DEVICE_ATTR(pwm5_mode, S_IWUSR | S_IRUGO, show_pwm_mode,
2416 store_pwm_mode, 4);
2417
2418static SENSOR_DEVICE_ATTR(pwm1_enable, S_IWUSR | S_IRUGO, show_pwm_enable,
2419 store_pwm_enable, 0);
2420static SENSOR_DEVICE_ATTR(pwm2_enable, S_IWUSR | S_IRUGO, show_pwm_enable,
2421 store_pwm_enable, 1);
2422static SENSOR_DEVICE_ATTR(pwm3_enable, S_IWUSR | S_IRUGO, show_pwm_enable,
2423 store_pwm_enable, 2);
2424static SENSOR_DEVICE_ATTR(pwm4_enable, S_IWUSR | S_IRUGO, show_pwm_enable,
2425 store_pwm_enable, 3);
2426static SENSOR_DEVICE_ATTR(pwm5_enable, S_IWUSR | S_IRUGO, show_pwm_enable,
2427 store_pwm_enable, 4);
2428
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002429static SENSOR_DEVICE_ATTR(pwm1_temp_sel, S_IWUSR | S_IRUGO,
2430 show_pwm_temp_sel, store_pwm_temp_sel, 0);
2431static SENSOR_DEVICE_ATTR(pwm2_temp_sel, S_IWUSR | S_IRUGO,
2432 show_pwm_temp_sel, store_pwm_temp_sel, 1);
2433static SENSOR_DEVICE_ATTR(pwm3_temp_sel, S_IWUSR | S_IRUGO,
2434 show_pwm_temp_sel, store_pwm_temp_sel, 2);
2435static SENSOR_DEVICE_ATTR(pwm4_temp_sel, S_IWUSR | S_IRUGO,
2436 show_pwm_temp_sel, store_pwm_temp_sel, 3);
2437static SENSOR_DEVICE_ATTR(pwm5_temp_sel, S_IWUSR | S_IRUGO,
2438 show_pwm_temp_sel, store_pwm_temp_sel, 4);
2439
2440static SENSOR_DEVICE_ATTR(pwm1_target_temp, S_IWUSR | S_IRUGO, show_target_temp,
2441 store_target_temp, 0);
2442static SENSOR_DEVICE_ATTR(pwm2_target_temp, S_IWUSR | S_IRUGO, show_target_temp,
2443 store_target_temp, 1);
2444static SENSOR_DEVICE_ATTR(pwm3_target_temp, S_IWUSR | S_IRUGO, show_target_temp,
2445 store_target_temp, 2);
2446static SENSOR_DEVICE_ATTR(pwm4_target_temp, S_IWUSR | S_IRUGO, show_target_temp,
2447 store_target_temp, 3);
2448static SENSOR_DEVICE_ATTR(pwm5_target_temp, S_IWUSR | S_IRUGO, show_target_temp,
2449 store_target_temp, 4);
2450
2451static SENSOR_DEVICE_ATTR(fan1_target, S_IWUSR | S_IRUGO, show_target_speed,
2452 store_target_speed, 0);
2453static SENSOR_DEVICE_ATTR(fan2_target, S_IWUSR | S_IRUGO, show_target_speed,
2454 store_target_speed, 1);
2455static SENSOR_DEVICE_ATTR(fan3_target, S_IWUSR | S_IRUGO, show_target_speed,
2456 store_target_speed, 2);
2457static SENSOR_DEVICE_ATTR(fan4_target, S_IWUSR | S_IRUGO, show_target_speed,
2458 store_target_speed, 3);
2459static SENSOR_DEVICE_ATTR(fan5_target, S_IWUSR | S_IRUGO, show_target_speed,
2460 store_target_speed, 4);
2461
2462static SENSOR_DEVICE_ATTR(fan1_tolerance, S_IWUSR | S_IRUGO,
2463 show_speed_tolerance, store_speed_tolerance, 0);
2464static SENSOR_DEVICE_ATTR(fan2_tolerance, S_IWUSR | S_IRUGO,
2465 show_speed_tolerance, store_speed_tolerance, 1);
2466static SENSOR_DEVICE_ATTR(fan3_tolerance, S_IWUSR | S_IRUGO,
2467 show_speed_tolerance, store_speed_tolerance, 2);
2468static SENSOR_DEVICE_ATTR(fan4_tolerance, S_IWUSR | S_IRUGO,
2469 show_speed_tolerance, store_speed_tolerance, 3);
2470static SENSOR_DEVICE_ATTR(fan5_tolerance, S_IWUSR | S_IRUGO,
2471 show_speed_tolerance, store_speed_tolerance, 4);
2472
2473/* Smart Fan registers */
2474
2475static ssize_t
Guenter Roeckbbd8dec2012-12-04 09:08:29 -08002476show_weight_temp(struct device *dev, struct device_attribute *attr, char *buf)
2477{
2478 struct nct6775_data *data = nct6775_update_device(dev);
2479 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2480 int nr = sattr->nr;
2481 int index = sattr->index;
2482
2483 return sprintf(buf, "%d\n", data->weight_temp[index][nr] * 1000);
2484}
2485
2486static ssize_t
2487store_weight_temp(struct device *dev, struct device_attribute *attr,
2488 const char *buf, size_t count)
2489{
2490 struct nct6775_data *data = dev_get_drvdata(dev);
2491 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2492 int nr = sattr->nr;
2493 int index = sattr->index;
2494 unsigned long val;
2495 int err;
2496
2497 err = kstrtoul(buf, 10, &val);
2498 if (err < 0)
2499 return err;
2500
2501 val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0, 255);
2502
2503 mutex_lock(&data->update_lock);
2504 data->weight_temp[index][nr] = val;
2505 nct6775_write_value(data, data->REG_WEIGHT_TEMP[index][nr], val);
2506 mutex_unlock(&data->update_lock);
2507 return count;
2508}
2509
2510static SENSOR_DEVICE_ATTR(pwm1_weight_temp_sel, S_IWUSR | S_IRUGO,
2511 show_pwm_weight_temp_sel, store_pwm_weight_temp_sel,
2512 0);
2513static SENSOR_DEVICE_ATTR(pwm2_weight_temp_sel, S_IWUSR | S_IRUGO,
2514 show_pwm_weight_temp_sel, store_pwm_weight_temp_sel,
2515 1);
2516static SENSOR_DEVICE_ATTR(pwm3_weight_temp_sel, S_IWUSR | S_IRUGO,
2517 show_pwm_weight_temp_sel, store_pwm_weight_temp_sel,
2518 2);
2519static SENSOR_DEVICE_ATTR(pwm4_weight_temp_sel, S_IWUSR | S_IRUGO,
2520 show_pwm_weight_temp_sel, store_pwm_weight_temp_sel,
2521 3);
2522static SENSOR_DEVICE_ATTR(pwm5_weight_temp_sel, S_IWUSR | S_IRUGO,
2523 show_pwm_weight_temp_sel, store_pwm_weight_temp_sel,
2524 4);
2525
2526static SENSOR_DEVICE_ATTR_2(pwm1_weight_temp_step, S_IWUSR | S_IRUGO,
2527 show_weight_temp, store_weight_temp, 0, 0);
2528static SENSOR_DEVICE_ATTR_2(pwm2_weight_temp_step, S_IWUSR | S_IRUGO,
2529 show_weight_temp, store_weight_temp, 1, 0);
2530static SENSOR_DEVICE_ATTR_2(pwm3_weight_temp_step, S_IWUSR | S_IRUGO,
2531 show_weight_temp, store_weight_temp, 2, 0);
2532static SENSOR_DEVICE_ATTR_2(pwm4_weight_temp_step, S_IWUSR | S_IRUGO,
2533 show_weight_temp, store_weight_temp, 3, 0);
2534static SENSOR_DEVICE_ATTR_2(pwm5_weight_temp_step, S_IWUSR | S_IRUGO,
2535 show_weight_temp, store_weight_temp, 4, 0);
2536
2537static SENSOR_DEVICE_ATTR_2(pwm1_weight_temp_step_tol, S_IWUSR | S_IRUGO,
2538 show_weight_temp, store_weight_temp, 0, 1);
2539static SENSOR_DEVICE_ATTR_2(pwm2_weight_temp_step_tol, S_IWUSR | S_IRUGO,
2540 show_weight_temp, store_weight_temp, 1, 1);
2541static SENSOR_DEVICE_ATTR_2(pwm3_weight_temp_step_tol, S_IWUSR | S_IRUGO,
2542 show_weight_temp, store_weight_temp, 2, 1);
2543static SENSOR_DEVICE_ATTR_2(pwm4_weight_temp_step_tol, S_IWUSR | S_IRUGO,
2544 show_weight_temp, store_weight_temp, 3, 1);
2545static SENSOR_DEVICE_ATTR_2(pwm5_weight_temp_step_tol, S_IWUSR | S_IRUGO,
2546 show_weight_temp, store_weight_temp, 4, 1);
2547
2548static SENSOR_DEVICE_ATTR_2(pwm1_weight_temp_step_base, S_IWUSR | S_IRUGO,
2549 show_weight_temp, store_weight_temp, 0, 2);
2550static SENSOR_DEVICE_ATTR_2(pwm2_weight_temp_step_base, S_IWUSR | S_IRUGO,
2551 show_weight_temp, store_weight_temp, 1, 2);
2552static SENSOR_DEVICE_ATTR_2(pwm3_weight_temp_step_base, S_IWUSR | S_IRUGO,
2553 show_weight_temp, store_weight_temp, 2, 2);
2554static SENSOR_DEVICE_ATTR_2(pwm4_weight_temp_step_base, S_IWUSR | S_IRUGO,
2555 show_weight_temp, store_weight_temp, 3, 2);
2556static SENSOR_DEVICE_ATTR_2(pwm5_weight_temp_step_base, S_IWUSR | S_IRUGO,
2557 show_weight_temp, store_weight_temp, 4, 2);
2558
2559static SENSOR_DEVICE_ATTR_2(pwm1_weight_duty_step, S_IWUSR | S_IRUGO,
2560 show_pwm, store_pwm, 0, 5);
2561static SENSOR_DEVICE_ATTR_2(pwm2_weight_duty_step, S_IWUSR | S_IRUGO,
2562 show_pwm, store_pwm, 1, 5);
2563static SENSOR_DEVICE_ATTR_2(pwm3_weight_duty_step, S_IWUSR | S_IRUGO,
2564 show_pwm, store_pwm, 2, 5);
2565static SENSOR_DEVICE_ATTR_2(pwm4_weight_duty_step, S_IWUSR | S_IRUGO,
2566 show_pwm, store_pwm, 3, 5);
2567static SENSOR_DEVICE_ATTR_2(pwm5_weight_duty_step, S_IWUSR | S_IRUGO,
2568 show_pwm, store_pwm, 4, 5);
2569
2570/* duty_base is not supported on all chips */
2571static struct sensor_device_attribute_2 sda_weight_duty_base[] = {
2572 SENSOR_ATTR_2(pwm1_weight_duty_base, S_IWUSR | S_IRUGO,
2573 show_pwm, store_pwm, 0, 6),
2574 SENSOR_ATTR_2(pwm2_weight_duty_base, S_IWUSR | S_IRUGO,
2575 show_pwm, store_pwm, 1, 6),
2576 SENSOR_ATTR_2(pwm3_weight_duty_base, S_IWUSR | S_IRUGO,
2577 show_pwm, store_pwm, 2, 6),
2578 SENSOR_ATTR_2(pwm4_weight_duty_base, S_IWUSR | S_IRUGO,
2579 show_pwm, store_pwm, 3, 6),
2580 SENSOR_ATTR_2(pwm5_weight_duty_base, S_IWUSR | S_IRUGO,
2581 show_pwm, store_pwm, 4, 6),
2582};
2583
2584static ssize_t
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002585show_fan_time(struct device *dev, struct device_attribute *attr, char *buf)
2586{
2587 struct nct6775_data *data = nct6775_update_device(dev);
2588 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2589 int nr = sattr->nr;
2590 int index = sattr->index;
2591
2592 return sprintf(buf, "%d\n",
2593 step_time_from_reg(data->fan_time[index][nr],
2594 data->pwm_mode[nr]));
2595}
2596
2597static ssize_t
2598store_fan_time(struct device *dev, struct device_attribute *attr,
2599 const char *buf, size_t count)
2600{
2601 struct nct6775_data *data = dev_get_drvdata(dev);
2602 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2603 int nr = sattr->nr;
2604 int index = sattr->index;
2605 unsigned long val;
2606 int err;
2607
2608 err = kstrtoul(buf, 10, &val);
2609 if (err < 0)
2610 return err;
2611
2612 val = step_time_to_reg(val, data->pwm_mode[nr]);
2613 mutex_lock(&data->update_lock);
2614 data->fan_time[index][nr] = val;
2615 nct6775_write_value(data, data->REG_FAN_TIME[index][nr], val);
2616 mutex_unlock(&data->update_lock);
2617 return count;
2618}
2619
Guenter Roeck77eb5b32012-12-04 08:30:54 -08002620static ssize_t
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07002621show_name(struct device *dev, struct device_attribute *attr, char *buf)
2622{
2623 struct nct6775_data *data = dev_get_drvdata(dev);
2624
2625 return sprintf(buf, "%s\n", data->name);
2626}
2627
2628static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
2629
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002630static SENSOR_DEVICE_ATTR_2(pwm1_stop_time, S_IWUSR | S_IRUGO, show_fan_time,
2631 store_fan_time, 0, 0);
2632static SENSOR_DEVICE_ATTR_2(pwm2_stop_time, S_IWUSR | S_IRUGO, show_fan_time,
2633 store_fan_time, 1, 0);
2634static SENSOR_DEVICE_ATTR_2(pwm3_stop_time, S_IWUSR | S_IRUGO, show_fan_time,
2635 store_fan_time, 2, 0);
2636static SENSOR_DEVICE_ATTR_2(pwm4_stop_time, S_IWUSR | S_IRUGO, show_fan_time,
2637 store_fan_time, 3, 0);
2638static SENSOR_DEVICE_ATTR_2(pwm5_stop_time, S_IWUSR | S_IRUGO, show_fan_time,
2639 store_fan_time, 4, 0);
2640
2641static SENSOR_DEVICE_ATTR_2(pwm1_step_up_time, S_IWUSR | S_IRUGO, show_fan_time,
2642 store_fan_time, 0, 1);
2643static SENSOR_DEVICE_ATTR_2(pwm2_step_up_time, S_IWUSR | S_IRUGO, show_fan_time,
2644 store_fan_time, 1, 1);
2645static SENSOR_DEVICE_ATTR_2(pwm3_step_up_time, S_IWUSR | S_IRUGO, show_fan_time,
2646 store_fan_time, 2, 1);
2647static SENSOR_DEVICE_ATTR_2(pwm4_step_up_time, S_IWUSR | S_IRUGO, show_fan_time,
2648 store_fan_time, 3, 1);
2649static SENSOR_DEVICE_ATTR_2(pwm5_step_up_time, S_IWUSR | S_IRUGO, show_fan_time,
2650 store_fan_time, 4, 1);
2651
2652static SENSOR_DEVICE_ATTR_2(pwm1_step_down_time, S_IWUSR | S_IRUGO,
2653 show_fan_time, store_fan_time, 0, 2);
2654static SENSOR_DEVICE_ATTR_2(pwm2_step_down_time, S_IWUSR | S_IRUGO,
2655 show_fan_time, store_fan_time, 1, 2);
2656static SENSOR_DEVICE_ATTR_2(pwm3_step_down_time, S_IWUSR | S_IRUGO,
2657 show_fan_time, store_fan_time, 2, 2);
2658static SENSOR_DEVICE_ATTR_2(pwm4_step_down_time, S_IWUSR | S_IRUGO,
2659 show_fan_time, store_fan_time, 3, 2);
2660static SENSOR_DEVICE_ATTR_2(pwm5_step_down_time, S_IWUSR | S_IRUGO,
2661 show_fan_time, store_fan_time, 4, 2);
2662
2663static SENSOR_DEVICE_ATTR_2(pwm1_start, S_IWUSR | S_IRUGO, show_pwm,
2664 store_pwm, 0, 1);
2665static SENSOR_DEVICE_ATTR_2(pwm2_start, S_IWUSR | S_IRUGO, show_pwm,
2666 store_pwm, 1, 1);
2667static SENSOR_DEVICE_ATTR_2(pwm3_start, S_IWUSR | S_IRUGO, show_pwm,
2668 store_pwm, 2, 1);
2669static SENSOR_DEVICE_ATTR_2(pwm4_start, S_IWUSR | S_IRUGO, show_pwm,
2670 store_pwm, 3, 1);
2671static SENSOR_DEVICE_ATTR_2(pwm5_start, S_IWUSR | S_IRUGO, show_pwm,
2672 store_pwm, 4, 1);
2673
2674static SENSOR_DEVICE_ATTR_2(pwm1_floor, S_IWUSR | S_IRUGO, show_pwm,
2675 store_pwm, 0, 2);
2676static SENSOR_DEVICE_ATTR_2(pwm2_floor, S_IWUSR | S_IRUGO, show_pwm,
2677 store_pwm, 1, 2);
2678static SENSOR_DEVICE_ATTR_2(pwm3_floor, S_IWUSR | S_IRUGO, show_pwm,
2679 store_pwm, 2, 2);
2680static SENSOR_DEVICE_ATTR_2(pwm4_floor, S_IWUSR | S_IRUGO, show_pwm,
2681 store_pwm, 3, 2);
2682static SENSOR_DEVICE_ATTR_2(pwm5_floor, S_IWUSR | S_IRUGO, show_pwm,
2683 store_pwm, 4, 2);
2684
2685static SENSOR_DEVICE_ATTR_2(pwm1_temp_tolerance, S_IWUSR | S_IRUGO,
2686 show_temp_tolerance, store_temp_tolerance, 0, 0);
2687static SENSOR_DEVICE_ATTR_2(pwm2_temp_tolerance, S_IWUSR | S_IRUGO,
2688 show_temp_tolerance, store_temp_tolerance, 1, 0);
2689static SENSOR_DEVICE_ATTR_2(pwm3_temp_tolerance, S_IWUSR | S_IRUGO,
2690 show_temp_tolerance, store_temp_tolerance, 2, 0);
2691static SENSOR_DEVICE_ATTR_2(pwm4_temp_tolerance, S_IWUSR | S_IRUGO,
2692 show_temp_tolerance, store_temp_tolerance, 3, 0);
2693static SENSOR_DEVICE_ATTR_2(pwm5_temp_tolerance, S_IWUSR | S_IRUGO,
2694 show_temp_tolerance, store_temp_tolerance, 4, 0);
2695
2696static SENSOR_DEVICE_ATTR_2(pwm1_crit_temp_tolerance, S_IWUSR | S_IRUGO,
2697 show_temp_tolerance, store_temp_tolerance, 0, 1);
2698static SENSOR_DEVICE_ATTR_2(pwm2_crit_temp_tolerance, S_IWUSR | S_IRUGO,
2699 show_temp_tolerance, store_temp_tolerance, 1, 1);
2700static SENSOR_DEVICE_ATTR_2(pwm3_crit_temp_tolerance, S_IWUSR | S_IRUGO,
2701 show_temp_tolerance, store_temp_tolerance, 2, 1);
2702static SENSOR_DEVICE_ATTR_2(pwm4_crit_temp_tolerance, S_IWUSR | S_IRUGO,
2703 show_temp_tolerance, store_temp_tolerance, 3, 1);
2704static SENSOR_DEVICE_ATTR_2(pwm5_crit_temp_tolerance, S_IWUSR | S_IRUGO,
2705 show_temp_tolerance, store_temp_tolerance, 4, 1);
2706
2707/* pwm_max is not supported on all chips */
2708static struct sensor_device_attribute_2 sda_pwm_max[] = {
2709 SENSOR_ATTR_2(pwm1_max, S_IWUSR | S_IRUGO, show_pwm, store_pwm,
2710 0, 3),
2711 SENSOR_ATTR_2(pwm2_max, S_IWUSR | S_IRUGO, show_pwm, store_pwm,
2712 1, 3),
2713 SENSOR_ATTR_2(pwm3_max, S_IWUSR | S_IRUGO, show_pwm, store_pwm,
2714 2, 3),
2715 SENSOR_ATTR_2(pwm4_max, S_IWUSR | S_IRUGO, show_pwm, store_pwm,
2716 3, 3),
2717 SENSOR_ATTR_2(pwm5_max, S_IWUSR | S_IRUGO, show_pwm, store_pwm,
2718 4, 3),
2719};
2720
2721/* pwm_step is not supported on all chips */
2722static struct sensor_device_attribute_2 sda_pwm_step[] = {
2723 SENSOR_ATTR_2(pwm1_step, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 0, 4),
2724 SENSOR_ATTR_2(pwm2_step, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 1, 4),
2725 SENSOR_ATTR_2(pwm3_step, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 2, 4),
2726 SENSOR_ATTR_2(pwm4_step, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 3, 4),
2727 SENSOR_ATTR_2(pwm5_step, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 4, 4),
2728};
2729
Guenter Roeckbbd8dec2012-12-04 09:08:29 -08002730static struct attribute *nct6775_attributes_pwm[5][20] = {
Guenter Roeck77eb5b32012-12-04 08:30:54 -08002731 {
2732 &sensor_dev_attr_pwm1.dev_attr.attr,
2733 &sensor_dev_attr_pwm1_mode.dev_attr.attr,
2734 &sensor_dev_attr_pwm1_enable.dev_attr.attr,
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002735 &sensor_dev_attr_pwm1_temp_sel.dev_attr.attr,
2736 &sensor_dev_attr_pwm1_temp_tolerance.dev_attr.attr,
2737 &sensor_dev_attr_pwm1_crit_temp_tolerance.dev_attr.attr,
2738 &sensor_dev_attr_pwm1_target_temp.dev_attr.attr,
2739 &sensor_dev_attr_fan1_target.dev_attr.attr,
2740 &sensor_dev_attr_fan1_tolerance.dev_attr.attr,
2741 &sensor_dev_attr_pwm1_stop_time.dev_attr.attr,
2742 &sensor_dev_attr_pwm1_step_up_time.dev_attr.attr,
2743 &sensor_dev_attr_pwm1_step_down_time.dev_attr.attr,
2744 &sensor_dev_attr_pwm1_start.dev_attr.attr,
2745 &sensor_dev_attr_pwm1_floor.dev_attr.attr,
Guenter Roeckbbd8dec2012-12-04 09:08:29 -08002746 &sensor_dev_attr_pwm1_weight_temp_sel.dev_attr.attr,
2747 &sensor_dev_attr_pwm1_weight_temp_step.dev_attr.attr,
2748 &sensor_dev_attr_pwm1_weight_temp_step_tol.dev_attr.attr,
2749 &sensor_dev_attr_pwm1_weight_temp_step_base.dev_attr.attr,
2750 &sensor_dev_attr_pwm1_weight_duty_step.dev_attr.attr,
Guenter Roeck77eb5b32012-12-04 08:30:54 -08002751 NULL
2752 },
2753 {
2754 &sensor_dev_attr_pwm2.dev_attr.attr,
2755 &sensor_dev_attr_pwm2_mode.dev_attr.attr,
2756 &sensor_dev_attr_pwm2_enable.dev_attr.attr,
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002757 &sensor_dev_attr_pwm2_temp_sel.dev_attr.attr,
2758 &sensor_dev_attr_pwm2_temp_tolerance.dev_attr.attr,
2759 &sensor_dev_attr_pwm2_crit_temp_tolerance.dev_attr.attr,
2760 &sensor_dev_attr_pwm2_target_temp.dev_attr.attr,
2761 &sensor_dev_attr_fan2_target.dev_attr.attr,
2762 &sensor_dev_attr_fan2_tolerance.dev_attr.attr,
2763 &sensor_dev_attr_pwm2_stop_time.dev_attr.attr,
2764 &sensor_dev_attr_pwm2_step_up_time.dev_attr.attr,
2765 &sensor_dev_attr_pwm2_step_down_time.dev_attr.attr,
2766 &sensor_dev_attr_pwm2_start.dev_attr.attr,
2767 &sensor_dev_attr_pwm2_floor.dev_attr.attr,
Guenter Roeckbbd8dec2012-12-04 09:08:29 -08002768 &sensor_dev_attr_pwm2_weight_temp_sel.dev_attr.attr,
2769 &sensor_dev_attr_pwm2_weight_temp_step.dev_attr.attr,
2770 &sensor_dev_attr_pwm2_weight_temp_step_tol.dev_attr.attr,
2771 &sensor_dev_attr_pwm2_weight_temp_step_base.dev_attr.attr,
2772 &sensor_dev_attr_pwm2_weight_duty_step.dev_attr.attr,
Guenter Roeck77eb5b32012-12-04 08:30:54 -08002773 NULL
2774 },
2775 {
2776 &sensor_dev_attr_pwm3.dev_attr.attr,
2777 &sensor_dev_attr_pwm3_mode.dev_attr.attr,
2778 &sensor_dev_attr_pwm3_enable.dev_attr.attr,
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002779 &sensor_dev_attr_pwm3_temp_sel.dev_attr.attr,
2780 &sensor_dev_attr_pwm3_temp_tolerance.dev_attr.attr,
2781 &sensor_dev_attr_pwm3_crit_temp_tolerance.dev_attr.attr,
2782 &sensor_dev_attr_pwm3_target_temp.dev_attr.attr,
2783 &sensor_dev_attr_fan3_target.dev_attr.attr,
2784 &sensor_dev_attr_fan3_tolerance.dev_attr.attr,
2785 &sensor_dev_attr_pwm3_stop_time.dev_attr.attr,
2786 &sensor_dev_attr_pwm3_step_up_time.dev_attr.attr,
2787 &sensor_dev_attr_pwm3_step_down_time.dev_attr.attr,
2788 &sensor_dev_attr_pwm3_start.dev_attr.attr,
2789 &sensor_dev_attr_pwm3_floor.dev_attr.attr,
Guenter Roeckbbd8dec2012-12-04 09:08:29 -08002790 &sensor_dev_attr_pwm3_weight_temp_sel.dev_attr.attr,
2791 &sensor_dev_attr_pwm3_weight_temp_step.dev_attr.attr,
2792 &sensor_dev_attr_pwm3_weight_temp_step_tol.dev_attr.attr,
2793 &sensor_dev_attr_pwm3_weight_temp_step_base.dev_attr.attr,
2794 &sensor_dev_attr_pwm3_weight_duty_step.dev_attr.attr,
Guenter Roeck77eb5b32012-12-04 08:30:54 -08002795 NULL
2796 },
2797 {
2798 &sensor_dev_attr_pwm4.dev_attr.attr,
2799 &sensor_dev_attr_pwm4_mode.dev_attr.attr,
2800 &sensor_dev_attr_pwm4_enable.dev_attr.attr,
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002801 &sensor_dev_attr_pwm4_temp_sel.dev_attr.attr,
2802 &sensor_dev_attr_pwm4_temp_tolerance.dev_attr.attr,
2803 &sensor_dev_attr_pwm4_crit_temp_tolerance.dev_attr.attr,
2804 &sensor_dev_attr_pwm4_target_temp.dev_attr.attr,
2805 &sensor_dev_attr_fan4_target.dev_attr.attr,
2806 &sensor_dev_attr_fan4_tolerance.dev_attr.attr,
2807 &sensor_dev_attr_pwm4_stop_time.dev_attr.attr,
2808 &sensor_dev_attr_pwm4_step_up_time.dev_attr.attr,
2809 &sensor_dev_attr_pwm4_step_down_time.dev_attr.attr,
2810 &sensor_dev_attr_pwm4_start.dev_attr.attr,
2811 &sensor_dev_attr_pwm4_floor.dev_attr.attr,
Guenter Roeckbbd8dec2012-12-04 09:08:29 -08002812 &sensor_dev_attr_pwm4_weight_temp_sel.dev_attr.attr,
2813 &sensor_dev_attr_pwm4_weight_temp_step.dev_attr.attr,
2814 &sensor_dev_attr_pwm4_weight_temp_step_tol.dev_attr.attr,
2815 &sensor_dev_attr_pwm4_weight_temp_step_base.dev_attr.attr,
2816 &sensor_dev_attr_pwm4_weight_duty_step.dev_attr.attr,
Guenter Roeck77eb5b32012-12-04 08:30:54 -08002817 NULL
2818 },
2819 {
2820 &sensor_dev_attr_pwm5.dev_attr.attr,
2821 &sensor_dev_attr_pwm5_mode.dev_attr.attr,
2822 &sensor_dev_attr_pwm5_enable.dev_attr.attr,
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002823 &sensor_dev_attr_pwm5_temp_sel.dev_attr.attr,
2824 &sensor_dev_attr_pwm5_temp_tolerance.dev_attr.attr,
2825 &sensor_dev_attr_pwm5_crit_temp_tolerance.dev_attr.attr,
2826 &sensor_dev_attr_pwm5_target_temp.dev_attr.attr,
2827 &sensor_dev_attr_fan5_target.dev_attr.attr,
2828 &sensor_dev_attr_fan5_tolerance.dev_attr.attr,
2829 &sensor_dev_attr_pwm5_stop_time.dev_attr.attr,
2830 &sensor_dev_attr_pwm5_step_up_time.dev_attr.attr,
2831 &sensor_dev_attr_pwm5_step_down_time.dev_attr.attr,
2832 &sensor_dev_attr_pwm5_start.dev_attr.attr,
2833 &sensor_dev_attr_pwm5_floor.dev_attr.attr,
Guenter Roeckbbd8dec2012-12-04 09:08:29 -08002834 &sensor_dev_attr_pwm5_weight_temp_sel.dev_attr.attr,
2835 &sensor_dev_attr_pwm5_weight_temp_step.dev_attr.attr,
2836 &sensor_dev_attr_pwm5_weight_temp_step_tol.dev_attr.attr,
2837 &sensor_dev_attr_pwm5_weight_temp_step_base.dev_attr.attr,
2838 &sensor_dev_attr_pwm5_weight_duty_step.dev_attr.attr,
Guenter Roeck77eb5b32012-12-04 08:30:54 -08002839 NULL
2840 },
2841};
2842
2843static const struct attribute_group nct6775_group_pwm[5] = {
2844 { .attrs = nct6775_attributes_pwm[0] },
2845 { .attrs = nct6775_attributes_pwm[1] },
2846 { .attrs = nct6775_attributes_pwm[2] },
2847 { .attrs = nct6775_attributes_pwm[3] },
2848 { .attrs = nct6775_attributes_pwm[4] },
2849};
2850
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07002851static ssize_t
Guenter Roeckcdcaece2012-12-04 09:04:52 -08002852show_auto_pwm(struct device *dev, struct device_attribute *attr, char *buf)
2853{
2854 struct nct6775_data *data = nct6775_update_device(dev);
2855 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2856
2857 return sprintf(buf, "%d\n", data->auto_pwm[sattr->nr][sattr->index]);
2858}
2859
2860static ssize_t
2861store_auto_pwm(struct device *dev, struct device_attribute *attr,
2862 const char *buf, size_t count)
2863{
2864 struct nct6775_data *data = dev_get_drvdata(dev);
2865 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2866 int nr = sattr->nr;
2867 int point = sattr->index;
2868 unsigned long val;
2869 int err;
2870 u8 reg;
2871
2872 err = kstrtoul(buf, 10, &val);
2873 if (err < 0)
2874 return err;
2875 if (val > 255)
2876 return -EINVAL;
2877
2878 if (point == data->auto_pwm_num) {
2879 if (data->kind != nct6775 && !val)
2880 return -EINVAL;
2881 if (data->kind != nct6779 && val)
2882 val = 0xff;
2883 }
2884
2885 mutex_lock(&data->update_lock);
2886 data->auto_pwm[nr][point] = val;
2887 if (point < data->auto_pwm_num) {
2888 nct6775_write_value(data,
2889 NCT6775_AUTO_PWM(data, nr, point),
2890 data->auto_pwm[nr][point]);
2891 } else {
2892 switch (data->kind) {
2893 case nct6775:
2894 /* disable if needed (pwm == 0) */
2895 reg = nct6775_read_value(data,
2896 NCT6775_REG_CRITICAL_ENAB[nr]);
2897 if (val)
2898 reg |= 0x02;
2899 else
2900 reg &= ~0x02;
2901 nct6775_write_value(data, NCT6775_REG_CRITICAL_ENAB[nr],
2902 reg);
2903 break;
2904 case nct6776:
2905 break; /* always enabled, nothing to do */
2906 case nct6779:
2907 nct6775_write_value(data, NCT6779_REG_CRITICAL_PWM[nr],
2908 val);
2909 reg = nct6775_read_value(data,
2910 NCT6779_REG_CRITICAL_PWM_ENABLE[nr]);
2911 if (val == 255)
2912 reg &= ~0x01;
2913 else
2914 reg |= 0x01;
2915 nct6775_write_value(data,
2916 NCT6779_REG_CRITICAL_PWM_ENABLE[nr],
2917 reg);
2918 break;
2919 }
2920 }
2921 mutex_unlock(&data->update_lock);
2922 return count;
2923}
2924
2925static ssize_t
2926show_auto_temp(struct device *dev, struct device_attribute *attr, char *buf)
2927{
2928 struct nct6775_data *data = nct6775_update_device(dev);
2929 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2930 int nr = sattr->nr;
2931 int point = sattr->index;
2932
2933 /*
2934 * We don't know for sure if the temperature is signed or unsigned.
2935 * Assume it is unsigned.
2936 */
2937 return sprintf(buf, "%d\n", data->auto_temp[nr][point] * 1000);
2938}
2939
2940static ssize_t
2941store_auto_temp(struct device *dev, struct device_attribute *attr,
2942 const char *buf, size_t count)
2943{
2944 struct nct6775_data *data = dev_get_drvdata(dev);
2945 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
2946 int nr = sattr->nr;
2947 int point = sattr->index;
2948 unsigned long val;
2949 int err;
2950
2951 err = kstrtoul(buf, 10, &val);
2952 if (err)
2953 return err;
2954 if (val > 255000)
2955 return -EINVAL;
2956
2957 mutex_lock(&data->update_lock);
2958 data->auto_temp[nr][point] = DIV_ROUND_CLOSEST(val, 1000);
2959 if (point < data->auto_pwm_num) {
2960 nct6775_write_value(data,
2961 NCT6775_AUTO_TEMP(data, nr, point),
2962 data->auto_temp[nr][point]);
2963 } else {
2964 nct6775_write_value(data, data->REG_CRITICAL_TEMP[nr],
2965 data->auto_temp[nr][point]);
2966 }
2967 mutex_unlock(&data->update_lock);
2968 return count;
2969}
2970
2971/*
2972 * The number of auto-point trip points is chip dependent.
2973 * Need to check support while generating/removing attribute files.
2974 */
2975static struct sensor_device_attribute_2 sda_auto_pwm_arrays[] = {
2976 SENSOR_ATTR_2(pwm1_auto_point1_pwm, S_IWUSR | S_IRUGO,
2977 show_auto_pwm, store_auto_pwm, 0, 0),
2978 SENSOR_ATTR_2(pwm1_auto_point1_temp, S_IWUSR | S_IRUGO,
2979 show_auto_temp, store_auto_temp, 0, 0),
2980 SENSOR_ATTR_2(pwm1_auto_point2_pwm, S_IWUSR | S_IRUGO,
2981 show_auto_pwm, store_auto_pwm, 0, 1),
2982 SENSOR_ATTR_2(pwm1_auto_point2_temp, S_IWUSR | S_IRUGO,
2983 show_auto_temp, store_auto_temp, 0, 1),
2984 SENSOR_ATTR_2(pwm1_auto_point3_pwm, S_IWUSR | S_IRUGO,
2985 show_auto_pwm, store_auto_pwm, 0, 2),
2986 SENSOR_ATTR_2(pwm1_auto_point3_temp, S_IWUSR | S_IRUGO,
2987 show_auto_temp, store_auto_temp, 0, 2),
2988 SENSOR_ATTR_2(pwm1_auto_point4_pwm, S_IWUSR | S_IRUGO,
2989 show_auto_pwm, store_auto_pwm, 0, 3),
2990 SENSOR_ATTR_2(pwm1_auto_point4_temp, S_IWUSR | S_IRUGO,
2991 show_auto_temp, store_auto_temp, 0, 3),
2992 SENSOR_ATTR_2(pwm1_auto_point5_pwm, S_IWUSR | S_IRUGO,
2993 show_auto_pwm, store_auto_pwm, 0, 4),
2994 SENSOR_ATTR_2(pwm1_auto_point5_temp, S_IWUSR | S_IRUGO,
2995 show_auto_temp, store_auto_temp, 0, 4),
2996 SENSOR_ATTR_2(pwm1_auto_point6_pwm, S_IWUSR | S_IRUGO,
2997 show_auto_pwm, store_auto_pwm, 0, 5),
2998 SENSOR_ATTR_2(pwm1_auto_point6_temp, S_IWUSR | S_IRUGO,
2999 show_auto_temp, store_auto_temp, 0, 5),
3000 SENSOR_ATTR_2(pwm1_auto_point7_pwm, S_IWUSR | S_IRUGO,
3001 show_auto_pwm, store_auto_pwm, 0, 6),
3002 SENSOR_ATTR_2(pwm1_auto_point7_temp, S_IWUSR | S_IRUGO,
3003 show_auto_temp, store_auto_temp, 0, 6),
3004
3005 SENSOR_ATTR_2(pwm2_auto_point1_pwm, S_IWUSR | S_IRUGO,
3006 show_auto_pwm, store_auto_pwm, 1, 0),
3007 SENSOR_ATTR_2(pwm2_auto_point1_temp, S_IWUSR | S_IRUGO,
3008 show_auto_temp, store_auto_temp, 1, 0),
3009 SENSOR_ATTR_2(pwm2_auto_point2_pwm, S_IWUSR | S_IRUGO,
3010 show_auto_pwm, store_auto_pwm, 1, 1),
3011 SENSOR_ATTR_2(pwm2_auto_point2_temp, S_IWUSR | S_IRUGO,
3012 show_auto_temp, store_auto_temp, 1, 1),
3013 SENSOR_ATTR_2(pwm2_auto_point3_pwm, S_IWUSR | S_IRUGO,
3014 show_auto_pwm, store_auto_pwm, 1, 2),
3015 SENSOR_ATTR_2(pwm2_auto_point3_temp, S_IWUSR | S_IRUGO,
3016 show_auto_temp, store_auto_temp, 1, 2),
3017 SENSOR_ATTR_2(pwm2_auto_point4_pwm, S_IWUSR | S_IRUGO,
3018 show_auto_pwm, store_auto_pwm, 1, 3),
3019 SENSOR_ATTR_2(pwm2_auto_point4_temp, S_IWUSR | S_IRUGO,
3020 show_auto_temp, store_auto_temp, 1, 3),
3021 SENSOR_ATTR_2(pwm2_auto_point5_pwm, S_IWUSR | S_IRUGO,
3022 show_auto_pwm, store_auto_pwm, 1, 4),
3023 SENSOR_ATTR_2(pwm2_auto_point5_temp, S_IWUSR | S_IRUGO,
3024 show_auto_temp, store_auto_temp, 1, 4),
3025 SENSOR_ATTR_2(pwm2_auto_point6_pwm, S_IWUSR | S_IRUGO,
3026 show_auto_pwm, store_auto_pwm, 1, 5),
3027 SENSOR_ATTR_2(pwm2_auto_point6_temp, S_IWUSR | S_IRUGO,
3028 show_auto_temp, store_auto_temp, 1, 5),
3029 SENSOR_ATTR_2(pwm2_auto_point7_pwm, S_IWUSR | S_IRUGO,
3030 show_auto_pwm, store_auto_pwm, 1, 6),
3031 SENSOR_ATTR_2(pwm2_auto_point7_temp, S_IWUSR | S_IRUGO,
3032 show_auto_temp, store_auto_temp, 1, 6),
3033
3034 SENSOR_ATTR_2(pwm3_auto_point1_pwm, S_IWUSR | S_IRUGO,
3035 show_auto_pwm, store_auto_pwm, 2, 0),
3036 SENSOR_ATTR_2(pwm3_auto_point1_temp, S_IWUSR | S_IRUGO,
3037 show_auto_temp, store_auto_temp, 2, 0),
3038 SENSOR_ATTR_2(pwm3_auto_point2_pwm, S_IWUSR | S_IRUGO,
3039 show_auto_pwm, store_auto_pwm, 2, 1),
3040 SENSOR_ATTR_2(pwm3_auto_point2_temp, S_IWUSR | S_IRUGO,
3041 show_auto_temp, store_auto_temp, 2, 1),
3042 SENSOR_ATTR_2(pwm3_auto_point3_pwm, S_IWUSR | S_IRUGO,
3043 show_auto_pwm, store_auto_pwm, 2, 2),
3044 SENSOR_ATTR_2(pwm3_auto_point3_temp, S_IWUSR | S_IRUGO,
3045 show_auto_temp, store_auto_temp, 2, 2),
3046 SENSOR_ATTR_2(pwm3_auto_point4_pwm, S_IWUSR | S_IRUGO,
3047 show_auto_pwm, store_auto_pwm, 2, 3),
3048 SENSOR_ATTR_2(pwm3_auto_point4_temp, S_IWUSR | S_IRUGO,
3049 show_auto_temp, store_auto_temp, 2, 3),
3050 SENSOR_ATTR_2(pwm3_auto_point5_pwm, S_IWUSR | S_IRUGO,
3051 show_auto_pwm, store_auto_pwm, 2, 4),
3052 SENSOR_ATTR_2(pwm3_auto_point5_temp, S_IWUSR | S_IRUGO,
3053 show_auto_temp, store_auto_temp, 2, 4),
3054 SENSOR_ATTR_2(pwm3_auto_point6_pwm, S_IWUSR | S_IRUGO,
3055 show_auto_pwm, store_auto_pwm, 2, 5),
3056 SENSOR_ATTR_2(pwm3_auto_point6_temp, S_IWUSR | S_IRUGO,
3057 show_auto_temp, store_auto_temp, 2, 5),
3058 SENSOR_ATTR_2(pwm3_auto_point7_pwm, S_IWUSR | S_IRUGO,
3059 show_auto_pwm, store_auto_pwm, 2, 6),
3060 SENSOR_ATTR_2(pwm3_auto_point7_temp, S_IWUSR | S_IRUGO,
3061 show_auto_temp, store_auto_temp, 2, 6),
3062
3063 SENSOR_ATTR_2(pwm4_auto_point1_pwm, S_IWUSR | S_IRUGO,
3064 show_auto_pwm, store_auto_pwm, 3, 0),
3065 SENSOR_ATTR_2(pwm4_auto_point1_temp, S_IWUSR | S_IRUGO,
3066 show_auto_temp, store_auto_temp, 3, 0),
3067 SENSOR_ATTR_2(pwm4_auto_point2_pwm, S_IWUSR | S_IRUGO,
3068 show_auto_pwm, store_auto_pwm, 3, 1),
3069 SENSOR_ATTR_2(pwm4_auto_point2_temp, S_IWUSR | S_IRUGO,
3070 show_auto_temp, store_auto_temp, 3, 1),
3071 SENSOR_ATTR_2(pwm4_auto_point3_pwm, S_IWUSR | S_IRUGO,
3072 show_auto_pwm, store_auto_pwm, 3, 2),
3073 SENSOR_ATTR_2(pwm4_auto_point3_temp, S_IWUSR | S_IRUGO,
3074 show_auto_temp, store_auto_temp, 3, 2),
3075 SENSOR_ATTR_2(pwm4_auto_point4_pwm, S_IWUSR | S_IRUGO,
3076 show_auto_pwm, store_auto_pwm, 3, 3),
3077 SENSOR_ATTR_2(pwm4_auto_point4_temp, S_IWUSR | S_IRUGO,
3078 show_auto_temp, store_auto_temp, 3, 3),
3079 SENSOR_ATTR_2(pwm4_auto_point5_pwm, S_IWUSR | S_IRUGO,
3080 show_auto_pwm, store_auto_pwm, 3, 4),
3081 SENSOR_ATTR_2(pwm4_auto_point5_temp, S_IWUSR | S_IRUGO,
3082 show_auto_temp, store_auto_temp, 3, 4),
3083 SENSOR_ATTR_2(pwm4_auto_point6_pwm, S_IWUSR | S_IRUGO,
3084 show_auto_pwm, store_auto_pwm, 3, 5),
3085 SENSOR_ATTR_2(pwm4_auto_point6_temp, S_IWUSR | S_IRUGO,
3086 show_auto_temp, store_auto_temp, 3, 5),
3087 SENSOR_ATTR_2(pwm4_auto_point7_pwm, S_IWUSR | S_IRUGO,
3088 show_auto_pwm, store_auto_pwm, 3, 6),
3089 SENSOR_ATTR_2(pwm4_auto_point7_temp, S_IWUSR | S_IRUGO,
3090 show_auto_temp, store_auto_temp, 3, 6),
3091
3092 SENSOR_ATTR_2(pwm5_auto_point1_pwm, S_IWUSR | S_IRUGO,
3093 show_auto_pwm, store_auto_pwm, 4, 0),
3094 SENSOR_ATTR_2(pwm5_auto_point1_temp, S_IWUSR | S_IRUGO,
3095 show_auto_temp, store_auto_temp, 4, 0),
3096 SENSOR_ATTR_2(pwm5_auto_point2_pwm, S_IWUSR | S_IRUGO,
3097 show_auto_pwm, store_auto_pwm, 4, 1),
3098 SENSOR_ATTR_2(pwm5_auto_point2_temp, S_IWUSR | S_IRUGO,
3099 show_auto_temp, store_auto_temp, 4, 1),
3100 SENSOR_ATTR_2(pwm5_auto_point3_pwm, S_IWUSR | S_IRUGO,
3101 show_auto_pwm, store_auto_pwm, 4, 2),
3102 SENSOR_ATTR_2(pwm5_auto_point3_temp, S_IWUSR | S_IRUGO,
3103 show_auto_temp, store_auto_temp, 4, 2),
3104 SENSOR_ATTR_2(pwm5_auto_point4_pwm, S_IWUSR | S_IRUGO,
3105 show_auto_pwm, store_auto_pwm, 4, 3),
3106 SENSOR_ATTR_2(pwm5_auto_point4_temp, S_IWUSR | S_IRUGO,
3107 show_auto_temp, store_auto_temp, 4, 3),
3108 SENSOR_ATTR_2(pwm5_auto_point5_pwm, S_IWUSR | S_IRUGO,
3109 show_auto_pwm, store_auto_pwm, 4, 4),
3110 SENSOR_ATTR_2(pwm5_auto_point5_temp, S_IWUSR | S_IRUGO,
3111 show_auto_temp, store_auto_temp, 4, 4),
3112 SENSOR_ATTR_2(pwm5_auto_point6_pwm, S_IWUSR | S_IRUGO,
3113 show_auto_pwm, store_auto_pwm, 4, 5),
3114 SENSOR_ATTR_2(pwm5_auto_point6_temp, S_IWUSR | S_IRUGO,
3115 show_auto_temp, store_auto_temp, 4, 5),
3116 SENSOR_ATTR_2(pwm5_auto_point7_pwm, S_IWUSR | S_IRUGO,
3117 show_auto_pwm, store_auto_pwm, 4, 6),
3118 SENSOR_ATTR_2(pwm5_auto_point7_temp, S_IWUSR | S_IRUGO,
3119 show_auto_temp, store_auto_temp, 4, 6),
3120};
3121
3122static ssize_t
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003123show_vid(struct device *dev, struct device_attribute *attr, char *buf)
3124{
3125 struct nct6775_data *data = dev_get_drvdata(dev);
3126 return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm));
3127}
3128
3129static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL);
3130
Guenter Roecka6bd5872012-12-04 03:13:34 -08003131/* Case open detection */
3132
3133static ssize_t
3134clear_caseopen(struct device *dev, struct device_attribute *attr,
3135 const char *buf, size_t count)
3136{
3137 struct nct6775_data *data = dev_get_drvdata(dev);
3138 struct nct6775_sio_data *sio_data = dev->platform_data;
3139 int nr = to_sensor_dev_attr(attr)->index - INTRUSION_ALARM_BASE;
3140 unsigned long val;
3141 u8 reg;
3142 int ret;
3143
3144 if (kstrtoul(buf, 10, &val) || val != 0)
3145 return -EINVAL;
3146
3147 mutex_lock(&data->update_lock);
3148
3149 /*
3150 * Use CR registers to clear caseopen status.
3151 * The CR registers are the same for all chips, and not all chips
3152 * support clearing the caseopen status through "regular" registers.
3153 */
3154 ret = superio_enter(sio_data->sioreg);
3155 if (ret) {
3156 count = ret;
3157 goto error;
3158 }
3159
3160 superio_select(sio_data->sioreg, NCT6775_LD_ACPI);
3161 reg = superio_inb(sio_data->sioreg, NCT6775_REG_CR_CASEOPEN_CLR[nr]);
3162 reg |= NCT6775_CR_CASEOPEN_CLR_MASK[nr];
3163 superio_outb(sio_data->sioreg, NCT6775_REG_CR_CASEOPEN_CLR[nr], reg);
3164 reg &= ~NCT6775_CR_CASEOPEN_CLR_MASK[nr];
3165 superio_outb(sio_data->sioreg, NCT6775_REG_CR_CASEOPEN_CLR[nr], reg);
3166 superio_exit(sio_data->sioreg);
3167
3168 data->valid = false; /* Force cache refresh */
3169error:
3170 mutex_unlock(&data->update_lock);
3171 return count;
3172}
3173
3174static struct sensor_device_attribute sda_caseopen[] = {
3175 SENSOR_ATTR(intrusion0_alarm, S_IWUSR | S_IRUGO, show_alarm,
3176 clear_caseopen, INTRUSION_ALARM_BASE),
3177 SENSOR_ATTR(intrusion1_alarm, S_IWUSR | S_IRUGO, show_alarm,
3178 clear_caseopen, INTRUSION_ALARM_BASE + 1),
3179};
3180
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003181/*
3182 * Driver and device management
3183 */
3184
3185static void nct6775_device_remove_files(struct device *dev)
3186{
3187 /*
3188 * some entries in the following arrays may not have been used in
3189 * device_create_file(), but device_remove_file() will ignore them
3190 */
3191 int i;
3192 struct nct6775_data *data = dev_get_drvdata(dev);
3193
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003194 for (i = 0; i < data->pwm_num; i++)
3195 sysfs_remove_group(&dev->kobj, &nct6775_group_pwm[i]);
3196
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003197 for (i = 0; i < ARRAY_SIZE(sda_pwm_max); i++)
3198 device_remove_file(dev, &sda_pwm_max[i].dev_attr);
3199
3200 for (i = 0; i < ARRAY_SIZE(sda_pwm_step); i++)
3201 device_remove_file(dev, &sda_pwm_step[i].dev_attr);
3202
Guenter Roeckbbd8dec2012-12-04 09:08:29 -08003203 for (i = 0; i < ARRAY_SIZE(sda_weight_duty_base); i++)
3204 device_remove_file(dev, &sda_weight_duty_base[i].dev_attr);
3205
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003206 for (i = 0; i < ARRAY_SIZE(sda_auto_pwm_arrays); i++)
3207 device_remove_file(dev, &sda_auto_pwm_arrays[i].dev_attr);
3208
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003209 for (i = 0; i < data->in_num; i++)
3210 sysfs_remove_group(&dev->kobj, &nct6775_group_in[i]);
3211
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003212 for (i = 0; i < 5; i++) {
3213 device_remove_file(dev, &sda_fan_input[i].dev_attr);
3214 device_remove_file(dev, &sda_fan_alarm[i].dev_attr);
3215 device_remove_file(dev, &sda_fan_div[i].dev_attr);
3216 device_remove_file(dev, &sda_fan_min[i].dev_attr);
Guenter Roeck5c25d952012-12-11 07:29:06 -08003217 device_remove_file(dev, &sda_fan_pulses[i].dev_attr);
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003218 }
Guenter Roeckaa136e52012-12-04 03:26:05 -08003219 for (i = 0; i < NUM_TEMP; i++) {
3220 if (!(data->have_temp & (1 << i)))
3221 continue;
3222 device_remove_file(dev, &sda_temp_input[i].dev_attr);
3223 device_remove_file(dev, &sda_temp_label[i].dev_attr);
3224 device_remove_file(dev, &sda_temp_max[i].dev_attr);
3225 device_remove_file(dev, &sda_temp_max_hyst[i].dev_attr);
3226 device_remove_file(dev, &sda_temp_crit[i].dev_attr);
3227 if (!(data->have_temp_fixed & (1 << i)))
3228 continue;
3229 device_remove_file(dev, &sda_temp_type[i].dev_attr);
3230 device_remove_file(dev, &sda_temp_offset[i].dev_attr);
3231 if (i >= NUM_TEMP_ALARM)
3232 continue;
3233 device_remove_file(dev, &sda_temp_alarm[i].dev_attr);
3234 }
3235
Guenter Roecka6bd5872012-12-04 03:13:34 -08003236 device_remove_file(dev, &sda_caseopen[0].dev_attr);
3237 device_remove_file(dev, &sda_caseopen[1].dev_attr);
3238
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003239 device_remove_file(dev, &dev_attr_name);
3240 device_remove_file(dev, &dev_attr_cpu0_vid);
3241}
3242
3243/* Get the monitoring functions started */
3244static inline void nct6775_init_device(struct nct6775_data *data)
3245{
Guenter Roeckaa136e52012-12-04 03:26:05 -08003246 int i;
3247 u8 tmp, diode;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003248
3249 /* Start monitoring if needed */
3250 if (data->REG_CONFIG) {
3251 tmp = nct6775_read_value(data, data->REG_CONFIG);
3252 if (!(tmp & 0x01))
3253 nct6775_write_value(data, data->REG_CONFIG, tmp | 0x01);
3254 }
3255
Guenter Roeckaa136e52012-12-04 03:26:05 -08003256 /* Enable temperature sensors if needed */
3257 for (i = 0; i < NUM_TEMP; i++) {
3258 if (!(data->have_temp & (1 << i)))
3259 continue;
3260 if (!data->reg_temp_config[i])
3261 continue;
3262 tmp = nct6775_read_value(data, data->reg_temp_config[i]);
3263 if (tmp & 0x01)
3264 nct6775_write_value(data, data->reg_temp_config[i],
3265 tmp & 0xfe);
3266 }
3267
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003268 /* Enable VBAT monitoring if needed */
3269 tmp = nct6775_read_value(data, data->REG_VBAT);
3270 if (!(tmp & 0x01))
3271 nct6775_write_value(data, data->REG_VBAT, tmp | 0x01);
Guenter Roeckaa136e52012-12-04 03:26:05 -08003272
3273 diode = nct6775_read_value(data, data->REG_DIODE);
3274
3275 for (i = 0; i < data->temp_fixed_num; i++) {
3276 if (!(data->have_temp_fixed & (1 << i)))
3277 continue;
3278 if ((tmp & (0x02 << i))) /* diode */
3279 data->temp_type[i] = 3 - ((diode >> i) & 0x02);
3280 else /* thermistor */
3281 data->temp_type[i] = 4;
3282 }
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003283}
3284
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003285static int
3286nct6775_check_fan_inputs(const struct nct6775_sio_data *sio_data,
3287 struct nct6775_data *data)
3288{
3289 int regval;
3290 bool fan3pin, fan3min, fan4pin, fan4min, fan5pin;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003291 bool pwm3pin, pwm4pin, pwm5pin;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003292 int ret;
3293
3294 ret = superio_enter(sio_data->sioreg);
3295 if (ret)
3296 return ret;
3297
3298 /* fan4 and fan5 share some pins with the GPIO and serial flash */
3299 if (data->kind == nct6775) {
3300 regval = superio_inb(sio_data->sioreg, 0x2c);
3301
3302 fan3pin = regval & (1 << 6);
3303 fan3min = fan3pin;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003304 pwm3pin = regval & (1 << 7);
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003305
3306 /* On NCT6775, fan4 shares pins with the fdc interface */
3307 fan4pin = !(superio_inb(sio_data->sioreg, 0x2A) & 0x80);
3308 fan4min = 0;
3309 fan5pin = 0;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003310 pwm4pin = 0;
3311 pwm5pin = 0;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003312 } else if (data->kind == nct6776) {
3313 bool gpok = superio_inb(sio_data->sioreg, 0x27) & 0x80;
3314
3315 superio_select(sio_data->sioreg, NCT6775_LD_HWM);
3316 regval = superio_inb(sio_data->sioreg, SIO_REG_ENABLE);
3317
3318 if (regval & 0x80)
3319 fan3pin = gpok;
3320 else
3321 fan3pin = !(superio_inb(sio_data->sioreg, 0x24) & 0x40);
3322
3323 if (regval & 0x40)
3324 fan4pin = gpok;
3325 else
3326 fan4pin = superio_inb(sio_data->sioreg, 0x1C) & 0x01;
3327
3328 if (regval & 0x20)
3329 fan5pin = gpok;
3330 else
3331 fan5pin = superio_inb(sio_data->sioreg, 0x1C) & 0x02;
3332
3333 fan4min = fan4pin;
3334 fan3min = fan3pin;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003335 pwm3pin = fan3pin;
3336 pwm4pin = 0;
3337 pwm5pin = 0;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003338 } else { /* NCT6779D */
3339 regval = superio_inb(sio_data->sioreg, 0x1c);
3340
3341 fan3pin = !(regval & (1 << 5));
3342 fan4pin = !(regval & (1 << 6));
3343 fan5pin = !(regval & (1 << 7));
3344
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003345 pwm3pin = !(regval & (1 << 0));
3346 pwm4pin = !(regval & (1 << 1));
3347 pwm5pin = !(regval & (1 << 2));
3348
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003349 fan3min = fan3pin;
3350 fan4min = fan4pin;
3351 }
3352
3353 superio_exit(sio_data->sioreg);
3354
3355 data->has_fan = data->has_fan_min = 0x03; /* fan1 and fan2 */
3356 data->has_fan |= fan3pin << 2;
3357 data->has_fan_min |= fan3min << 2;
3358
3359 data->has_fan |= (fan4pin << 3) | (fan5pin << 4);
3360 data->has_fan_min |= (fan4min << 3) | (fan5pin << 4);
3361
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003362 data->has_pwm = 0x03 | (pwm3pin << 2) | (pwm4pin << 3) | (pwm5pin << 4);
3363
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003364 return 0;
3365}
3366
Guenter Roeck8e9285b2012-12-04 08:03:37 -08003367static void add_temp_sensors(struct nct6775_data *data, const u16 *regp,
3368 int *available, int *mask)
3369{
3370 int i;
3371 u8 src;
3372
3373 for (i = 0; i < data->pwm_num && *available; i++) {
3374 int index;
3375
3376 if (!regp[i])
3377 continue;
3378 src = nct6775_read_value(data, regp[i]);
3379 src &= 0x1f;
3380 if (!src || (*mask & (1 << src)))
3381 continue;
3382 if (src >= data->temp_label_num ||
3383 !strlen(data->temp_label[src]))
3384 continue;
3385
3386 index = __ffs(*available);
3387 nct6775_write_value(data, data->REG_TEMP_SOURCE[index], src);
3388 *available &= ~(1 << index);
3389 *mask |= 1 << src;
3390 }
3391}
3392
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003393static int nct6775_probe(struct platform_device *pdev)
3394{
3395 struct device *dev = &pdev->dev;
3396 struct nct6775_sio_data *sio_data = dev->platform_data;
3397 struct nct6775_data *data;
3398 struct resource *res;
Guenter Roeckaa136e52012-12-04 03:26:05 -08003399 int i, s, err = 0;
3400 int src, mask, available;
3401 const u16 *reg_temp, *reg_temp_over, *reg_temp_hyst, *reg_temp_config;
3402 const u16 *reg_temp_alternate, *reg_temp_crit;
3403 int num_reg_temp;
Guenter Roeck0fc1f8f2013-02-26 09:43:50 -08003404 bool have_vid = false;
3405 u8 cr2a;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003406
3407 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
3408 if (!devm_request_region(&pdev->dev, res->start, IOREGION_LENGTH,
3409 DRVNAME))
3410 return -EBUSY;
3411
3412 data = devm_kzalloc(&pdev->dev, sizeof(struct nct6775_data),
3413 GFP_KERNEL);
3414 if (!data)
3415 return -ENOMEM;
3416
3417 data->kind = sio_data->kind;
3418 data->addr = res->start;
3419 mutex_init(&data->lock);
3420 mutex_init(&data->update_lock);
3421 data->name = nct6775_device_names[data->kind];
3422 data->bank = 0xff; /* Force initial bank selection */
3423 platform_set_drvdata(pdev, data);
3424
3425 switch (data->kind) {
3426 case nct6775:
3427 data->in_num = 9;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003428 data->pwm_num = 3;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003429 data->auto_pwm_num = 6;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003430 data->has_fan_div = true;
Guenter Roeckaa136e52012-12-04 03:26:05 -08003431 data->temp_fixed_num = 3;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003432
3433 data->ALARM_BITS = NCT6775_ALARM_BITS;
3434
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003435 data->fan_from_reg = fan_from_reg16;
3436 data->fan_from_reg_min = fan_from_reg8;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003437 data->target_temp_mask = 0x7f;
3438 data->tolerance_mask = 0x0f;
3439 data->speed_tolerance_limit = 15;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003440
Guenter Roeckaa136e52012-12-04 03:26:05 -08003441 data->temp_label = nct6775_temp_label;
3442 data->temp_label_num = ARRAY_SIZE(nct6775_temp_label);
3443
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003444 data->REG_CONFIG = NCT6775_REG_CONFIG;
3445 data->REG_VBAT = NCT6775_REG_VBAT;
Guenter Roeckaa136e52012-12-04 03:26:05 -08003446 data->REG_DIODE = NCT6775_REG_DIODE;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003447 data->REG_VIN = NCT6775_REG_IN;
3448 data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN;
3449 data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003450 data->REG_TARGET = NCT6775_REG_TARGET;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003451 data->REG_FAN = NCT6775_REG_FAN;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003452 data->REG_FAN_MODE = NCT6775_REG_FAN_MODE;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003453 data->REG_FAN_MIN = NCT6775_REG_FAN_MIN;
Guenter Roeck5c25d952012-12-11 07:29:06 -08003454 data->REG_FAN_PULSES = NCT6775_REG_FAN_PULSES;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003455 data->REG_FAN_TIME[0] = NCT6775_REG_FAN_STOP_TIME;
3456 data->REG_FAN_TIME[1] = NCT6775_REG_FAN_STEP_UP_TIME;
3457 data->REG_FAN_TIME[2] = NCT6775_REG_FAN_STEP_DOWN_TIME;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003458 data->REG_PWM[0] = NCT6775_REG_PWM;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003459 data->REG_PWM[1] = NCT6775_REG_FAN_START_OUTPUT;
3460 data->REG_PWM[2] = NCT6775_REG_FAN_STOP_OUTPUT;
3461 data->REG_PWM[3] = NCT6775_REG_FAN_MAX_OUTPUT;
3462 data->REG_PWM[4] = NCT6775_REG_FAN_STEP_OUTPUT;
Guenter Roeckbbd8dec2012-12-04 09:08:29 -08003463 data->REG_PWM[5] = NCT6775_REG_WEIGHT_DUTY_STEP;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003464 data->REG_PWM_READ = NCT6775_REG_PWM_READ;
3465 data->REG_PWM_MODE = NCT6775_REG_PWM_MODE;
3466 data->PWM_MODE_MASK = NCT6775_PWM_MODE_MASK;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003467 data->REG_AUTO_TEMP = NCT6775_REG_AUTO_TEMP;
3468 data->REG_AUTO_PWM = NCT6775_REG_AUTO_PWM;
3469 data->REG_CRITICAL_TEMP = NCT6775_REG_CRITICAL_TEMP;
3470 data->REG_CRITICAL_TEMP_TOLERANCE
3471 = NCT6775_REG_CRITICAL_TEMP_TOLERANCE;
Guenter Roeckaa136e52012-12-04 03:26:05 -08003472 data->REG_TEMP_OFFSET = NCT6775_REG_TEMP_OFFSET;
3473 data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003474 data->REG_TEMP_SEL = NCT6775_REG_TEMP_SEL;
Guenter Roeckbbd8dec2012-12-04 09:08:29 -08003475 data->REG_WEIGHT_TEMP_SEL = NCT6775_REG_WEIGHT_TEMP_SEL;
3476 data->REG_WEIGHT_TEMP[0] = NCT6775_REG_WEIGHT_TEMP_STEP;
3477 data->REG_WEIGHT_TEMP[1] = NCT6775_REG_WEIGHT_TEMP_STEP_TOL;
3478 data->REG_WEIGHT_TEMP[2] = NCT6775_REG_WEIGHT_TEMP_BASE;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003479 data->REG_ALARM = NCT6775_REG_ALARM;
Guenter Roeckaa136e52012-12-04 03:26:05 -08003480
3481 reg_temp = NCT6775_REG_TEMP;
3482 num_reg_temp = ARRAY_SIZE(NCT6775_REG_TEMP);
3483 reg_temp_over = NCT6775_REG_TEMP_OVER;
3484 reg_temp_hyst = NCT6775_REG_TEMP_HYST;
3485 reg_temp_config = NCT6775_REG_TEMP_CONFIG;
3486 reg_temp_alternate = NCT6775_REG_TEMP_ALTERNATE;
3487 reg_temp_crit = NCT6775_REG_TEMP_CRIT;
3488
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003489 break;
3490 case nct6776:
3491 data->in_num = 9;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003492 data->pwm_num = 3;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003493 data->auto_pwm_num = 4;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003494 data->has_fan_div = false;
Guenter Roeckaa136e52012-12-04 03:26:05 -08003495 data->temp_fixed_num = 3;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003496
3497 data->ALARM_BITS = NCT6776_ALARM_BITS;
3498
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003499 data->fan_from_reg = fan_from_reg13;
3500 data->fan_from_reg_min = fan_from_reg13;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003501 data->target_temp_mask = 0xff;
3502 data->tolerance_mask = 0x07;
3503 data->speed_tolerance_limit = 63;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003504
Guenter Roeckaa136e52012-12-04 03:26:05 -08003505 data->temp_label = nct6776_temp_label;
3506 data->temp_label_num = ARRAY_SIZE(nct6776_temp_label);
3507
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003508 data->REG_CONFIG = NCT6775_REG_CONFIG;
3509 data->REG_VBAT = NCT6775_REG_VBAT;
Guenter Roeckaa136e52012-12-04 03:26:05 -08003510 data->REG_DIODE = NCT6775_REG_DIODE;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003511 data->REG_VIN = NCT6775_REG_IN;
3512 data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN;
3513 data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003514 data->REG_TARGET = NCT6775_REG_TARGET;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003515 data->REG_FAN = NCT6775_REG_FAN;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003516 data->REG_FAN_MODE = NCT6775_REG_FAN_MODE;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003517 data->REG_FAN_MIN = NCT6776_REG_FAN_MIN;
Guenter Roeck5c25d952012-12-11 07:29:06 -08003518 data->REG_FAN_PULSES = NCT6776_REG_FAN_PULSES;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003519 data->REG_FAN_TIME[0] = NCT6775_REG_FAN_STOP_TIME;
3520 data->REG_FAN_TIME[1] = NCT6775_REG_FAN_STEP_UP_TIME;
3521 data->REG_FAN_TIME[2] = NCT6775_REG_FAN_STEP_DOWN_TIME;
3522 data->REG_TOLERANCE_H = NCT6776_REG_TOLERANCE_H;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003523 data->REG_PWM[0] = NCT6775_REG_PWM;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003524 data->REG_PWM[1] = NCT6775_REG_FAN_START_OUTPUT;
3525 data->REG_PWM[2] = NCT6775_REG_FAN_STOP_OUTPUT;
Guenter Roeckbbd8dec2012-12-04 09:08:29 -08003526 data->REG_PWM[5] = NCT6775_REG_WEIGHT_DUTY_STEP;
3527 data->REG_PWM[6] = NCT6776_REG_WEIGHT_DUTY_BASE;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003528 data->REG_PWM_READ = NCT6775_REG_PWM_READ;
3529 data->REG_PWM_MODE = NCT6776_REG_PWM_MODE;
3530 data->PWM_MODE_MASK = NCT6776_PWM_MODE_MASK;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003531 data->REG_AUTO_TEMP = NCT6775_REG_AUTO_TEMP;
3532 data->REG_AUTO_PWM = NCT6775_REG_AUTO_PWM;
3533 data->REG_CRITICAL_TEMP = NCT6775_REG_CRITICAL_TEMP;
3534 data->REG_CRITICAL_TEMP_TOLERANCE
3535 = NCT6775_REG_CRITICAL_TEMP_TOLERANCE;
Guenter Roeckaa136e52012-12-04 03:26:05 -08003536 data->REG_TEMP_OFFSET = NCT6775_REG_TEMP_OFFSET;
3537 data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003538 data->REG_TEMP_SEL = NCT6775_REG_TEMP_SEL;
Guenter Roeckbbd8dec2012-12-04 09:08:29 -08003539 data->REG_WEIGHT_TEMP_SEL = NCT6775_REG_WEIGHT_TEMP_SEL;
3540 data->REG_WEIGHT_TEMP[0] = NCT6775_REG_WEIGHT_TEMP_STEP;
3541 data->REG_WEIGHT_TEMP[1] = NCT6775_REG_WEIGHT_TEMP_STEP_TOL;
3542 data->REG_WEIGHT_TEMP[2] = NCT6775_REG_WEIGHT_TEMP_BASE;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003543 data->REG_ALARM = NCT6775_REG_ALARM;
Guenter Roeckaa136e52012-12-04 03:26:05 -08003544
3545 reg_temp = NCT6775_REG_TEMP;
3546 num_reg_temp = ARRAY_SIZE(NCT6775_REG_TEMP);
3547 reg_temp_over = NCT6775_REG_TEMP_OVER;
3548 reg_temp_hyst = NCT6775_REG_TEMP_HYST;
3549 reg_temp_config = NCT6776_REG_TEMP_CONFIG;
3550 reg_temp_alternate = NCT6776_REG_TEMP_ALTERNATE;
3551 reg_temp_crit = NCT6776_REG_TEMP_CRIT;
3552
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003553 break;
3554 case nct6779:
3555 data->in_num = 15;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003556 data->pwm_num = 5;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003557 data->auto_pwm_num = 4;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003558 data->has_fan_div = false;
Guenter Roeckaa136e52012-12-04 03:26:05 -08003559 data->temp_fixed_num = 6;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003560
3561 data->ALARM_BITS = NCT6779_ALARM_BITS;
3562
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003563 data->fan_from_reg = fan_from_reg13;
3564 data->fan_from_reg_min = fan_from_reg13;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003565 data->target_temp_mask = 0xff;
3566 data->tolerance_mask = 0x07;
3567 data->speed_tolerance_limit = 63;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003568
Guenter Roeckaa136e52012-12-04 03:26:05 -08003569 data->temp_label = nct6779_temp_label;
3570 data->temp_label_num = ARRAY_SIZE(nct6779_temp_label);
3571
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003572 data->REG_CONFIG = NCT6775_REG_CONFIG;
3573 data->REG_VBAT = NCT6775_REG_VBAT;
Guenter Roeckaa136e52012-12-04 03:26:05 -08003574 data->REG_DIODE = NCT6775_REG_DIODE;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003575 data->REG_VIN = NCT6779_REG_IN;
3576 data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN;
3577 data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003578 data->REG_TARGET = NCT6775_REG_TARGET;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003579 data->REG_FAN = NCT6779_REG_FAN;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003580 data->REG_FAN_MODE = NCT6775_REG_FAN_MODE;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003581 data->REG_FAN_MIN = NCT6776_REG_FAN_MIN;
Guenter Roeck5c25d952012-12-11 07:29:06 -08003582 data->REG_FAN_PULSES = NCT6779_REG_FAN_PULSES;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003583 data->REG_FAN_TIME[0] = NCT6775_REG_FAN_STOP_TIME;
3584 data->REG_FAN_TIME[1] = NCT6775_REG_FAN_STEP_UP_TIME;
3585 data->REG_FAN_TIME[2] = NCT6775_REG_FAN_STEP_DOWN_TIME;
3586 data->REG_TOLERANCE_H = NCT6776_REG_TOLERANCE_H;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003587 data->REG_PWM[0] = NCT6775_REG_PWM;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003588 data->REG_PWM[1] = NCT6775_REG_FAN_START_OUTPUT;
3589 data->REG_PWM[2] = NCT6775_REG_FAN_STOP_OUTPUT;
Guenter Roeckbbd8dec2012-12-04 09:08:29 -08003590 data->REG_PWM[5] = NCT6775_REG_WEIGHT_DUTY_STEP;
3591 data->REG_PWM[6] = NCT6776_REG_WEIGHT_DUTY_BASE;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003592 data->REG_PWM_READ = NCT6775_REG_PWM_READ;
3593 data->REG_PWM_MODE = NCT6776_REG_PWM_MODE;
3594 data->PWM_MODE_MASK = NCT6776_PWM_MODE_MASK;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003595 data->REG_AUTO_TEMP = NCT6775_REG_AUTO_TEMP;
3596 data->REG_AUTO_PWM = NCT6775_REG_AUTO_PWM;
3597 data->REG_CRITICAL_TEMP = NCT6775_REG_CRITICAL_TEMP;
3598 data->REG_CRITICAL_TEMP_TOLERANCE
3599 = NCT6775_REG_CRITICAL_TEMP_TOLERANCE;
Guenter Roeckaa136e52012-12-04 03:26:05 -08003600 data->REG_TEMP_OFFSET = NCT6779_REG_TEMP_OFFSET;
3601 data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003602 data->REG_TEMP_SEL = NCT6775_REG_TEMP_SEL;
Guenter Roeckbbd8dec2012-12-04 09:08:29 -08003603 data->REG_WEIGHT_TEMP_SEL = NCT6775_REG_WEIGHT_TEMP_SEL;
3604 data->REG_WEIGHT_TEMP[0] = NCT6775_REG_WEIGHT_TEMP_STEP;
3605 data->REG_WEIGHT_TEMP[1] = NCT6775_REG_WEIGHT_TEMP_STEP_TOL;
3606 data->REG_WEIGHT_TEMP[2] = NCT6775_REG_WEIGHT_TEMP_BASE;
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003607 data->REG_ALARM = NCT6779_REG_ALARM;
Guenter Roeckaa136e52012-12-04 03:26:05 -08003608
3609 reg_temp = NCT6779_REG_TEMP;
3610 num_reg_temp = ARRAY_SIZE(NCT6779_REG_TEMP);
3611 reg_temp_over = NCT6779_REG_TEMP_OVER;
3612 reg_temp_hyst = NCT6779_REG_TEMP_HYST;
3613 reg_temp_config = NCT6779_REG_TEMP_CONFIG;
3614 reg_temp_alternate = NCT6779_REG_TEMP_ALTERNATE;
3615 reg_temp_crit = NCT6779_REG_TEMP_CRIT;
3616
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003617 break;
3618 default:
3619 return -ENODEV;
3620 }
3621 data->have_in = (1 << data->in_num) - 1;
Guenter Roeckaa136e52012-12-04 03:26:05 -08003622 data->have_temp = 0;
3623
3624 /*
3625 * On some boards, not all available temperature sources are monitored,
3626 * even though some of the monitoring registers are unused.
3627 * Get list of unused monitoring registers, then detect if any fan
3628 * controls are configured to use unmonitored temperature sources.
3629 * If so, assign the unmonitored temperature sources to available
3630 * monitoring registers.
3631 */
3632 mask = 0;
3633 available = 0;
3634 for (i = 0; i < num_reg_temp; i++) {
3635 if (reg_temp[i] == 0)
3636 continue;
3637
3638 src = nct6775_read_value(data, data->REG_TEMP_SOURCE[i]) & 0x1f;
3639 if (!src || (mask & (1 << src)))
3640 available |= 1 << i;
3641
3642 mask |= 1 << src;
3643 }
3644
Guenter Roeck8e9285b2012-12-04 08:03:37 -08003645 /*
3646 * Now find unmonitored temperature registers and enable monitoring
3647 * if additional monitoring registers are available.
3648 */
3649 add_temp_sensors(data, data->REG_TEMP_SEL, &available, &mask);
3650 add_temp_sensors(data, data->REG_WEIGHT_TEMP_SEL, &available, &mask);
3651
Guenter Roeckaa136e52012-12-04 03:26:05 -08003652 mask = 0;
3653 s = NUM_TEMP_FIXED; /* First dynamic temperature attribute */
3654 for (i = 0; i < num_reg_temp; i++) {
3655 if (reg_temp[i] == 0)
3656 continue;
3657
3658 src = nct6775_read_value(data, data->REG_TEMP_SOURCE[i]) & 0x1f;
3659 if (!src || (mask & (1 << src)))
3660 continue;
3661
3662 if (src >= data->temp_label_num ||
3663 !strlen(data->temp_label[src])) {
3664 dev_info(dev,
3665 "Invalid temperature source %d at index %d, source register 0x%x, temp register 0x%x\n",
3666 src, i, data->REG_TEMP_SOURCE[i], reg_temp[i]);
3667 continue;
3668 }
3669
3670 mask |= 1 << src;
3671
3672 /* Use fixed index for SYSTIN(1), CPUTIN(2), AUXTIN(3) */
3673 if (src <= data->temp_fixed_num) {
3674 data->have_temp |= 1 << (src - 1);
3675 data->have_temp_fixed |= 1 << (src - 1);
3676 data->reg_temp[0][src - 1] = reg_temp[i];
3677 data->reg_temp[1][src - 1] = reg_temp_over[i];
3678 data->reg_temp[2][src - 1] = reg_temp_hyst[i];
3679 data->reg_temp_config[src - 1] = reg_temp_config[i];
3680 data->temp_src[src - 1] = src;
3681 continue;
3682 }
3683
3684 if (s >= NUM_TEMP)
3685 continue;
3686
3687 /* Use dynamic index for other sources */
3688 data->have_temp |= 1 << s;
3689 data->reg_temp[0][s] = reg_temp[i];
3690 data->reg_temp[1][s] = reg_temp_over[i];
3691 data->reg_temp[2][s] = reg_temp_hyst[i];
3692 data->reg_temp_config[s] = reg_temp_config[i];
3693 if (reg_temp_crit[src - 1])
3694 data->reg_temp[3][s] = reg_temp_crit[src - 1];
3695
3696 data->temp_src[s] = src;
3697 s++;
3698 }
3699
3700#ifdef USE_ALTERNATE
3701 /*
3702 * Go through the list of alternate temp registers and enable
3703 * if possible.
3704 * The temperature is already monitored if the respective bit in <mask>
3705 * is set.
3706 */
3707 for (i = 0; i < data->temp_label_num - 1; i++) {
3708 if (!reg_temp_alternate[i])
3709 continue;
3710 if (mask & (1 << (i + 1)))
3711 continue;
3712 if (i < data->temp_fixed_num) {
3713 if (data->have_temp & (1 << i))
3714 continue;
3715 data->have_temp |= 1 << i;
3716 data->have_temp_fixed |= 1 << i;
3717 data->reg_temp[0][i] = reg_temp_alternate[i];
3718 data->reg_temp[1][i] = reg_temp_over[i];
3719 data->reg_temp[2][i] = reg_temp_hyst[i];
3720 data->temp_src[i] = i + 1;
3721 continue;
3722 }
3723
3724 if (s >= NUM_TEMP) /* Abort if no more space */
3725 break;
3726
3727 data->have_temp |= 1 << s;
3728 data->reg_temp[0][s] = reg_temp_alternate[i];
3729 data->temp_src[s] = i + 1;
3730 s++;
3731 }
3732#endif /* USE_ALTERNATE */
3733
3734 switch (data->kind) {
3735 case nct6775:
3736 break;
3737 case nct6776:
3738 /*
3739 * On NCT6776, AUXTIN and VIN3 pins are shared.
3740 * Only way to detect it is to check if AUXTIN is used
3741 * as a temperature source, and if that source is
3742 * enabled.
3743 *
3744 * If that is the case, disable in6, which reports VIN3.
3745 * Otherwise disable temp3.
3746 */
3747 if (data->have_temp & (1 << 2)) {
3748 u8 reg = nct6775_read_value(data,
3749 data->reg_temp_config[2]);
3750 if (reg & 0x01)
3751 data->have_temp &= ~(1 << 2);
3752 else
3753 data->have_in &= ~(1 << 6);
3754 }
3755 break;
3756 case nct6779:
3757 /*
3758 * Shared pins:
3759 * VIN4 / AUXTIN0
3760 * VIN5 / AUXTIN1
3761 * VIN6 / AUXTIN2
3762 * VIN7 / AUXTIN3
3763 *
3764 * There does not seem to be a clean way to detect if VINx or
3765 * AUXTINx is active, so for keep both sensor types enabled
3766 * for now.
3767 */
3768 break;
3769 }
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003770
3771 /* Initialize the chip */
3772 nct6775_init_device(data);
3773
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003774 err = superio_enter(sio_data->sioreg);
3775 if (err)
3776 return err;
3777
Guenter Roeck0fc1f8f2013-02-26 09:43:50 -08003778 cr2a = superio_inb(sio_data->sioreg, 0x2a);
3779 switch (data->kind) {
3780 case nct6775:
3781 have_vid = (cr2a & 0x40);
3782 break;
3783 case nct6776:
3784 have_vid = (cr2a & 0x60) == 0x40;
3785 break;
3786 case nct6779:
3787 break;
3788 }
3789
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003790 /*
3791 * Read VID value
3792 * We can get the VID input values directly at logical device D 0xe3.
3793 */
Guenter Roeck0fc1f8f2013-02-26 09:43:50 -08003794 if (have_vid) {
3795 superio_select(sio_data->sioreg, NCT6775_LD_VID);
3796 data->vid = superio_inb(sio_data->sioreg, 0xe3);
3797 data->vrm = vid_which_vrm();
3798 }
Guenter Roeck47ece962012-12-04 07:59:32 -08003799
3800 if (fan_debounce) {
3801 u8 tmp;
3802
3803 superio_select(sio_data->sioreg, NCT6775_LD_HWM);
3804 tmp = superio_inb(sio_data->sioreg,
3805 NCT6775_REG_CR_FAN_DEBOUNCE);
3806 switch (data->kind) {
3807 case nct6775:
3808 tmp |= 0x1e;
3809 break;
3810 case nct6776:
3811 case nct6779:
3812 tmp |= 0x3e;
3813 break;
3814 }
3815 superio_outb(sio_data->sioreg, NCT6775_REG_CR_FAN_DEBOUNCE,
3816 tmp);
3817 dev_info(&pdev->dev, "Enabled fan debounce for chip %s\n",
3818 data->name);
3819 }
3820
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003821 superio_exit(sio_data->sioreg);
3822
Guenter Roeck0fc1f8f2013-02-26 09:43:50 -08003823 if (have_vid) {
3824 err = device_create_file(dev, &dev_attr_cpu0_vid);
3825 if (err)
3826 return err;
3827 }
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003828
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003829 err = nct6775_check_fan_inputs(sio_data, data);
3830 if (err)
3831 goto exit_remove;
3832
3833 /* Read fan clock dividers immediately */
3834 nct6775_init_fan_common(dev, data);
3835
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003836 /* Register sysfs hooks */
3837 for (i = 0; i < data->pwm_num; i++) {
3838 if (!(data->has_pwm & (1 << i)))
3839 continue;
3840
3841 err = sysfs_create_group(&dev->kobj, &nct6775_group_pwm[i]);
3842 if (err)
3843 goto exit_remove;
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003844
3845 if (data->REG_PWM[3]) {
3846 err = device_create_file(dev,
3847 &sda_pwm_max[i].dev_attr);
3848 if (err)
3849 goto exit_remove;
3850 }
3851 if (data->REG_PWM[4]) {
3852 err = device_create_file(dev,
3853 &sda_pwm_step[i].dev_attr);
3854 if (err)
3855 goto exit_remove;
3856 }
Guenter Roeckbbd8dec2012-12-04 09:08:29 -08003857 if (data->REG_PWM[6]) {
3858 err = device_create_file(dev,
3859 &sda_weight_duty_base[i].dev_attr);
3860 if (err)
3861 goto exit_remove;
3862 }
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003863 }
3864 for (i = 0; i < ARRAY_SIZE(sda_auto_pwm_arrays); i++) {
3865 struct sensor_device_attribute_2 *attr =
3866 &sda_auto_pwm_arrays[i];
3867
3868 if (!(data->has_pwm & (1 << attr->nr)))
3869 continue;
3870 if (attr->index > data->auto_pwm_num)
3871 continue;
3872 err = device_create_file(dev, &attr->dev_attr);
3873 if (err)
3874 goto exit_remove;
Guenter Roeck77eb5b32012-12-04 08:30:54 -08003875 }
3876
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003877 for (i = 0; i < data->in_num; i++) {
3878 if (!(data->have_in & (1 << i)))
3879 continue;
3880 err = sysfs_create_group(&dev->kobj, &nct6775_group_in[i]);
3881 if (err)
3882 goto exit_remove;
3883 }
3884
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003885 for (i = 0; i < 5; i++) {
3886 if (data->has_fan & (1 << i)) {
3887 err = device_create_file(dev,
3888 &sda_fan_input[i].dev_attr);
3889 if (err)
3890 goto exit_remove;
3891 err = device_create_file(dev,
3892 &sda_fan_alarm[i].dev_attr);
3893 if (err)
3894 goto exit_remove;
3895 if (data->kind != nct6776 &&
3896 data->kind != nct6779) {
3897 err = device_create_file(dev,
3898 &sda_fan_div[i].dev_attr);
3899 if (err)
3900 goto exit_remove;
3901 }
3902 if (data->has_fan_min & (1 << i)) {
3903 err = device_create_file(dev,
3904 &sda_fan_min[i].dev_attr);
3905 if (err)
3906 goto exit_remove;
3907 }
Guenter Roeck5c25d952012-12-11 07:29:06 -08003908 err = device_create_file(dev,
Guenter Roeckcdcaece2012-12-04 09:04:52 -08003909 &sda_fan_pulses[i].dev_attr);
Guenter Roeck5c25d952012-12-11 07:29:06 -08003910 if (err)
3911 goto exit_remove;
Guenter Roeck1c65dc32012-12-04 07:56:24 -08003912 }
3913 }
3914
Guenter Roeckaa136e52012-12-04 03:26:05 -08003915 for (i = 0; i < NUM_TEMP; i++) {
3916 if (!(data->have_temp & (1 << i)))
3917 continue;
3918 err = device_create_file(dev, &sda_temp_input[i].dev_attr);
3919 if (err)
3920 goto exit_remove;
3921 if (data->temp_label) {
3922 err = device_create_file(dev,
3923 &sda_temp_label[i].dev_attr);
3924 if (err)
3925 goto exit_remove;
3926 }
3927 if (data->reg_temp[1][i]) {
3928 err = device_create_file(dev,
3929 &sda_temp_max[i].dev_attr);
3930 if (err)
3931 goto exit_remove;
3932 }
3933 if (data->reg_temp[2][i]) {
3934 err = device_create_file(dev,
3935 &sda_temp_max_hyst[i].dev_attr);
3936 if (err)
3937 goto exit_remove;
3938 }
3939 if (data->reg_temp[3][i]) {
3940 err = device_create_file(dev,
3941 &sda_temp_crit[i].dev_attr);
3942 if (err)
3943 goto exit_remove;
3944 }
3945 if (!(data->have_temp_fixed & (1 << i)))
3946 continue;
3947 err = device_create_file(dev, &sda_temp_type[i].dev_attr);
3948 if (err)
3949 goto exit_remove;
3950 err = device_create_file(dev, &sda_temp_offset[i].dev_attr);
3951 if (err)
3952 goto exit_remove;
3953 if (i >= NUM_TEMP_ALARM ||
3954 data->ALARM_BITS[TEMP_ALARM_BASE + i] < 0)
3955 continue;
3956 err = device_create_file(dev, &sda_temp_alarm[i].dev_attr);
3957 if (err)
3958 goto exit_remove;
3959 }
3960
Guenter Roecka6bd5872012-12-04 03:13:34 -08003961 for (i = 0; i < ARRAY_SIZE(sda_caseopen); i++) {
3962 if (data->ALARM_BITS[INTRUSION_ALARM_BASE + i] < 0)
3963 continue;
3964 err = device_create_file(dev, &sda_caseopen[i].dev_attr);
3965 if (err)
3966 goto exit_remove;
3967 }
3968
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07003969 err = device_create_file(dev, &dev_attr_name);
3970 if (err)
3971 goto exit_remove;
3972
3973 data->hwmon_dev = hwmon_device_register(dev);
3974 if (IS_ERR(data->hwmon_dev)) {
3975 err = PTR_ERR(data->hwmon_dev);
3976 goto exit_remove;
3977 }
3978
3979 return 0;
3980
3981exit_remove:
3982 nct6775_device_remove_files(dev);
3983 return err;
3984}
3985
3986static int nct6775_remove(struct platform_device *pdev)
3987{
3988 struct nct6775_data *data = platform_get_drvdata(pdev);
3989
3990 hwmon_device_unregister(data->hwmon_dev);
3991 nct6775_device_remove_files(&pdev->dev);
3992
3993 return 0;
3994}
3995
Guenter Roeck84d19d92012-12-04 08:01:39 -08003996#ifdef CONFIG_PM
3997static int nct6775_suspend(struct device *dev)
3998{
3999 struct nct6775_data *data = nct6775_update_device(dev);
4000 struct nct6775_sio_data *sio_data = dev->platform_data;
4001
4002 mutex_lock(&data->update_lock);
4003 data->vbat = nct6775_read_value(data, data->REG_VBAT);
4004 if (sio_data->kind == nct6775) {
4005 data->fandiv1 = nct6775_read_value(data, NCT6775_REG_FANDIV1);
4006 data->fandiv2 = nct6775_read_value(data, NCT6775_REG_FANDIV2);
4007 }
4008 mutex_unlock(&data->update_lock);
4009
4010 return 0;
4011}
4012
4013static int nct6775_resume(struct device *dev)
4014{
4015 struct nct6775_data *data = dev_get_drvdata(dev);
4016 struct nct6775_sio_data *sio_data = dev->platform_data;
4017 int i, j;
4018
4019 mutex_lock(&data->update_lock);
4020 data->bank = 0xff; /* Force initial bank selection */
4021
4022 /* Restore limits */
4023 for (i = 0; i < data->in_num; i++) {
4024 if (!(data->have_in & (1 << i)))
4025 continue;
4026
4027 nct6775_write_value(data, data->REG_IN_MINMAX[0][i],
4028 data->in[i][1]);
4029 nct6775_write_value(data, data->REG_IN_MINMAX[1][i],
4030 data->in[i][2]);
4031 }
4032
4033 for (i = 0; i < 5; i++) {
4034 if (!(data->has_fan_min & (1 << i)))
4035 continue;
4036
4037 nct6775_write_value(data, data->REG_FAN_MIN[i],
4038 data->fan_min[i]);
4039 }
4040
4041 for (i = 0; i < NUM_TEMP; i++) {
4042 if (!(data->have_temp & (1 << i)))
4043 continue;
4044
4045 for (j = 1; j < 4; j++)
4046 if (data->reg_temp[j][i])
4047 nct6775_write_temp(data, data->reg_temp[j][i],
4048 data->temp[j][i]);
4049 }
4050
4051 /* Restore other settings */
4052 nct6775_write_value(data, data->REG_VBAT, data->vbat);
4053 if (sio_data->kind == nct6775) {
4054 nct6775_write_value(data, NCT6775_REG_FANDIV1, data->fandiv1);
4055 nct6775_write_value(data, NCT6775_REG_FANDIV2, data->fandiv2);
4056 }
4057
4058 /* Force re-reading all values */
4059 data->valid = false;
4060 mutex_unlock(&data->update_lock);
4061
4062 return 0;
4063}
4064
4065static const struct dev_pm_ops nct6775_dev_pm_ops = {
4066 .suspend = nct6775_suspend,
4067 .resume = nct6775_resume,
4068};
4069
4070#define NCT6775_DEV_PM_OPS (&nct6775_dev_pm_ops)
4071#else
4072#define NCT6775_DEV_PM_OPS NULL
4073#endif /* CONFIG_PM */
4074
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07004075static struct platform_driver nct6775_driver = {
4076 .driver = {
4077 .owner = THIS_MODULE,
4078 .name = DRVNAME,
Guenter Roeck84d19d92012-12-04 08:01:39 -08004079 .pm = NCT6775_DEV_PM_OPS,
Guenter Roeck9de2e2e2012-05-20 19:29:48 -07004080 },
4081 .probe = nct6775_probe,
4082 .remove = nct6775_remove,
4083};
4084
4085/* nct6775_find() looks for a '627 in the Super-I/O config space */
4086static int __init nct6775_find(int sioaddr, unsigned short *addr,
4087 struct nct6775_sio_data *sio_data)
4088{
4089 static const char sio_name_NCT6775[] __initconst = "NCT6775F";
4090 static const char sio_name_NCT6776[] __initconst = "NCT6776F";
4091 static const char sio_name_NCT6779[] __initconst = "NCT6779D";
4092
4093 u16 val;
4094 const char *sio_name;
4095 int err;
4096
4097 err = superio_enter(sioaddr);
4098 if (err)
4099 return err;
4100
4101 if (force_id)
4102 val = force_id;
4103 else
4104 val = (superio_inb(sioaddr, SIO_REG_DEVID) << 8)
4105 | superio_inb(sioaddr, SIO_REG_DEVID + 1);
4106 switch (val & SIO_ID_MASK) {
4107 case SIO_NCT6775_ID:
4108 sio_data->kind = nct6775;
4109 sio_name = sio_name_NCT6775;
4110 break;
4111 case SIO_NCT6776_ID:
4112 sio_data->kind = nct6776;
4113 sio_name = sio_name_NCT6776;
4114 break;
4115 case SIO_NCT6779_ID:
4116 sio_data->kind = nct6779;
4117 sio_name = sio_name_NCT6779;
4118 break;
4119 default:
4120 if (val != 0xffff)
4121 pr_debug("unsupported chip ID: 0x%04x\n", val);
4122 superio_exit(sioaddr);
4123 return -ENODEV;
4124 }
4125
4126 /* We have a known chip, find the HWM I/O address */
4127 superio_select(sioaddr, NCT6775_LD_HWM);
4128 val = (superio_inb(sioaddr, SIO_REG_ADDR) << 8)
4129 | superio_inb(sioaddr, SIO_REG_ADDR + 1);
4130 *addr = val & IOREGION_ALIGNMENT;
4131 if (*addr == 0) {
4132 pr_err("Refusing to enable a Super-I/O device with a base I/O port 0\n");
4133 superio_exit(sioaddr);
4134 return -ENODEV;
4135 }
4136
4137 /* Activate logical device if needed */
4138 val = superio_inb(sioaddr, SIO_REG_ENABLE);
4139 if (!(val & 0x01)) {
4140 pr_warn("Forcibly enabling Super-I/O. Sensor is probably unusable.\n");
4141 superio_outb(sioaddr, SIO_REG_ENABLE, val | 0x01);
4142 }
4143
4144 superio_exit(sioaddr);
4145 pr_info("Found %s chip at %#x\n", sio_name, *addr);
4146 sio_data->sioreg = sioaddr;
4147
4148 return 0;
4149}
4150
4151/*
4152 * when Super-I/O functions move to a separate file, the Super-I/O
4153 * bus will manage the lifetime of the device and this module will only keep
4154 * track of the nct6775 driver. But since we platform_device_alloc(), we
4155 * must keep track of the device
4156 */
4157static struct platform_device *pdev;
4158
4159static int __init sensors_nct6775_init(void)
4160{
4161 int err;
4162 unsigned short address;
4163 struct resource res;
4164 struct nct6775_sio_data sio_data;
4165
4166 /*
4167 * initialize sio_data->kind and sio_data->sioreg.
4168 *
4169 * when Super-I/O functions move to a separate file, the Super-I/O
4170 * driver will probe 0x2e and 0x4e and auto-detect the presence of a
4171 * nct6775 hardware monitor, and call probe()
4172 */
4173 if (nct6775_find(0x2e, &address, &sio_data) &&
4174 nct6775_find(0x4e, &address, &sio_data))
4175 return -ENODEV;
4176
4177 err = platform_driver_register(&nct6775_driver);
4178 if (err)
4179 goto exit;
4180
4181 pdev = platform_device_alloc(DRVNAME, address);
4182 if (!pdev) {
4183 err = -ENOMEM;
4184 pr_err("Device allocation failed\n");
4185 goto exit_unregister;
4186 }
4187
4188 err = platform_device_add_data(pdev, &sio_data,
4189 sizeof(struct nct6775_sio_data));
4190 if (err) {
4191 pr_err("Platform data allocation failed\n");
4192 goto exit_device_put;
4193 }
4194
4195 memset(&res, 0, sizeof(res));
4196 res.name = DRVNAME;
4197 res.start = address + IOREGION_OFFSET;
4198 res.end = address + IOREGION_OFFSET + IOREGION_LENGTH - 1;
4199 res.flags = IORESOURCE_IO;
4200
4201 err = acpi_check_resource_conflict(&res);
4202 if (err)
4203 goto exit_device_put;
4204
4205 err = platform_device_add_resources(pdev, &res, 1);
4206 if (err) {
4207 pr_err("Device resource addition failed (%d)\n", err);
4208 goto exit_device_put;
4209 }
4210
4211 /* platform_device_add calls probe() */
4212 err = platform_device_add(pdev);
4213 if (err) {
4214 pr_err("Device addition failed (%d)\n", err);
4215 goto exit_device_put;
4216 }
4217
4218 return 0;
4219
4220exit_device_put:
4221 platform_device_put(pdev);
4222exit_unregister:
4223 platform_driver_unregister(&nct6775_driver);
4224exit:
4225 return err;
4226}
4227
4228static void __exit sensors_nct6775_exit(void)
4229{
4230 platform_device_unregister(pdev);
4231 platform_driver_unregister(&nct6775_driver);
4232}
4233
4234MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>");
4235MODULE_DESCRIPTION("NCT6775F/NCT6776F/NCT6779D driver");
4236MODULE_LICENSE("GPL");
4237
4238module_init(sensors_nct6775_init);
4239module_exit(sensors_nct6775_exit);