blob: cb35461d52d9403f81d9c71507a9888040c6fb92 [file] [log] [blame]
Jean Delvareba224e22006-12-12 18:18:29 +01001/*
2 * pc87427.c - hardware monitoring driver for the
3 * National Semiconductor PC87427 Super-I/O chip
Jean Delvare008e5f32010-08-14 21:08:59 +02004 * Copyright (C) 2006, 2008, 2010 Jean Delvare <khali@linux-fr.org>
Jean Delvareba224e22006-12-12 18:18:29 +01005 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * Supports the following chips:
16 *
17 * Chip #vin #fan #pwm #temp devid
Jean Delvare008e5f32010-08-14 21:08:59 +020018 * PC87427 - 8 4 6 0xF2
Jean Delvareba224e22006-12-12 18:18:29 +010019 *
20 * This driver assumes that no more than one chip is present.
Jean Delvare008e5f32010-08-14 21:08:59 +020021 * Only fans are fully supported so far. Temperatures are in read-only
22 * mode, and voltages aren't supported at all.
Jean Delvareba224e22006-12-12 18:18:29 +010023 */
24
Joe Perches5e24e0c2011-01-12 21:55:11 +010025#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
26
Jean Delvareba224e22006-12-12 18:18:29 +010027#include <linux/module.h>
28#include <linux/init.h>
29#include <linux/slab.h>
30#include <linux/jiffies.h>
31#include <linux/platform_device.h>
32#include <linux/hwmon.h>
33#include <linux/hwmon-sysfs.h>
34#include <linux/err.h>
35#include <linux/mutex.h>
36#include <linux/sysfs.h>
Jean Delvarece7ee4e2007-05-08 17:21:59 +020037#include <linux/ioport.h>
Jean Delvareb9acb642009-01-07 16:37:35 +010038#include <linux/acpi.h>
H Hartley Sweeten6055fae2009-09-15 17:18:13 +020039#include <linux/io.h>
Jean Delvareba224e22006-12-12 18:18:29 +010040
Jean Delvare67b671b2007-12-06 23:13:42 +010041static unsigned short force_id;
42module_param(force_id, ushort, 0);
43MODULE_PARM_DESC(force_id, "Override the detected device ID");
44
Jean Delvareba224e22006-12-12 18:18:29 +010045static struct platform_device *pdev;
46
47#define DRVNAME "pc87427"
48
49/* The lock mutex protects both the I/O accesses (needed because the
50 device is using banked registers) and the register cache (needed to keep
51 the data in the registers and the cache in sync at any time). */
52struct pc87427_data {
Tony Jones1beeffe2007-08-20 13:46:20 -070053 struct device *hwmon_dev;
Jean Delvareba224e22006-12-12 18:18:29 +010054 struct mutex lock;
55 int address[2];
56 const char *name;
57
58 unsigned long last_updated; /* in jiffies */
59 u8 fan_enabled; /* bit vector */
60 u16 fan[8]; /* register values */
61 u16 fan_min[8]; /* register values */
62 u8 fan_status[8]; /* register values */
Jean Delvare328716b2010-08-14 21:08:58 +020063
64 u8 pwm_enabled; /* bit vector */
65 u8 pwm_auto_ok; /* bit vector */
66 u8 pwm_enable[4]; /* register values */
67 u8 pwm[4]; /* register values */
Jean Delvare008e5f32010-08-14 21:08:59 +020068
69 u8 temp_enabled; /* bit vector */
70 s16 temp[6]; /* register values */
71 s8 temp_min[6]; /* register values */
72 s8 temp_max[6]; /* register values */
73 s8 temp_crit[6]; /* register values */
74 u8 temp_status[6]; /* register values */
75 u8 temp_type[6]; /* register values */
Jean Delvareba224e22006-12-12 18:18:29 +010076};
77
Jean Delvare4e7d99e2010-08-14 21:08:56 +020078struct pc87427_sio_data {
Jean Delvare9d32df12010-08-14 21:08:58 +020079 unsigned short address[2];
Jean Delvare4e7d99e2010-08-14 21:08:56 +020080 u8 has_fanin;
Jean Delvare328716b2010-08-14 21:08:58 +020081 u8 has_fanout;
Jean Delvare4e7d99e2010-08-14 21:08:56 +020082};
83
Jean Delvareba224e22006-12-12 18:18:29 +010084/*
85 * Super-I/O registers and operations
86 */
87
88#define SIOREG_LDSEL 0x07 /* Logical device select */
89#define SIOREG_DEVID 0x20 /* Device ID */
Jean Delvare4e7d99e2010-08-14 21:08:56 +020090#define SIOREG_CF2 0x22 /* Configuration 2 */
91#define SIOREG_CF3 0x23 /* Configuration 3 */
92#define SIOREG_CF4 0x24 /* Configuration 4 */
Jean Delvare328716b2010-08-14 21:08:58 +020093#define SIOREG_CF5 0x25 /* Configuration 5 */
Jean Delvare4e7d99e2010-08-14 21:08:56 +020094#define SIOREG_CFB 0x2B /* Configuration B */
Jean Delvare328716b2010-08-14 21:08:58 +020095#define SIOREG_CFC 0x2C /* Configuration C */
Jean Delvare4e7d99e2010-08-14 21:08:56 +020096#define SIOREG_CFD 0x2D /* Configuration D */
Jean Delvareba224e22006-12-12 18:18:29 +010097#define SIOREG_ACT 0x30 /* Device activation */
98#define SIOREG_MAP 0x50 /* I/O or memory mapping */
99#define SIOREG_IOBASE 0x60 /* I/O base address */
100
101static const u8 logdev[2] = { 0x09, 0x14 };
102static const char *logdev_str[2] = { DRVNAME " FMC", DRVNAME " HMC" };
103#define LD_FAN 0
104#define LD_IN 1
105#define LD_TEMP 1
106
107static inline void superio_outb(int sioaddr, int reg, int val)
108{
109 outb(reg, sioaddr);
110 outb(val, sioaddr + 1);
111}
112
113static inline int superio_inb(int sioaddr, int reg)
114{
115 outb(reg, sioaddr);
116 return inb(sioaddr + 1);
117}
118
119static inline void superio_exit(int sioaddr)
120{
121 outb(0x02, sioaddr);
122 outb(0x02, sioaddr + 1);
123}
124
125/*
126 * Logical devices
127 */
128
129#define REGION_LENGTH 32
130#define PC87427_REG_BANK 0x0f
131#define BANK_FM(nr) (nr)
132#define BANK_FT(nr) (0x08 + (nr))
133#define BANK_FC(nr) (0x10 + (nr) * 2)
Jean Delvare008e5f32010-08-14 21:08:59 +0200134#define BANK_TM(nr) (nr)
135#define BANK_VM(nr) (0x08 + (nr))
Jean Delvareba224e22006-12-12 18:18:29 +0100136
137/*
138 * I/O access functions
139 */
140
141/* ldi is the logical device index */
142static inline int pc87427_read8(struct pc87427_data *data, u8 ldi, u8 reg)
143{
144 return inb(data->address[ldi] + reg);
145}
146
147/* Must be called with data->lock held, except during init */
148static inline int pc87427_read8_bank(struct pc87427_data *data, u8 ldi,
149 u8 bank, u8 reg)
150{
151 outb(bank, data->address[ldi] + PC87427_REG_BANK);
152 return inb(data->address[ldi] + reg);
153}
154
155/* Must be called with data->lock held, except during init */
156static inline void pc87427_write8_bank(struct pc87427_data *data, u8 ldi,
157 u8 bank, u8 reg, u8 value)
158{
159 outb(bank, data->address[ldi] + PC87427_REG_BANK);
160 outb(value, data->address[ldi] + reg);
161}
162
163/*
164 * Fan registers and conversions
165 */
166
167/* fan data registers are 16-bit wide */
168#define PC87427_REG_FAN 0x12
169#define PC87427_REG_FAN_MIN 0x14
170#define PC87427_REG_FAN_STATUS 0x10
171
172#define FAN_STATUS_STALL (1 << 3)
173#define FAN_STATUS_LOSPD (1 << 1)
174#define FAN_STATUS_MONEN (1 << 0)
175
176/* Dedicated function to read all registers related to a given fan input.
177 This saves us quite a few locks and bank selections.
178 Must be called with data->lock held.
179 nr is from 0 to 7 */
180static void pc87427_readall_fan(struct pc87427_data *data, u8 nr)
181{
182 int iobase = data->address[LD_FAN];
183
184 outb(BANK_FM(nr), iobase + PC87427_REG_BANK);
185 data->fan[nr] = inw(iobase + PC87427_REG_FAN);
186 data->fan_min[nr] = inw(iobase + PC87427_REG_FAN_MIN);
187 data->fan_status[nr] = inb(iobase + PC87427_REG_FAN_STATUS);
188 /* Clear fan alarm bits */
189 outb(data->fan_status[nr], iobase + PC87427_REG_FAN_STATUS);
190}
191
192/* The 2 LSB of fan speed registers are used for something different.
193 The actual 2 LSB of the measurements are not available. */
194static inline unsigned long fan_from_reg(u16 reg)
195{
196 reg &= 0xfffc;
197 if (reg == 0x0000 || reg == 0xfffc)
198 return 0;
199 return 5400000UL / reg;
200}
201
202/* The 2 LSB of the fan speed limit registers are not significant. */
203static inline u16 fan_to_reg(unsigned long val)
204{
205 if (val < 83UL)
206 return 0xffff;
207 if (val >= 1350000UL)
208 return 0x0004;
209 return ((1350000UL + val / 2) / val) << 2;
210}
211
212/*
Jean Delvare328716b2010-08-14 21:08:58 +0200213 * PWM registers and conversions
214 */
215
216#define PC87427_REG_PWM_ENABLE 0x10
217#define PC87427_REG_PWM_DUTY 0x12
218
219#define PWM_ENABLE_MODE_MASK (7 << 4)
220#define PWM_ENABLE_CTLEN (1 << 0)
221
222#define PWM_MODE_MANUAL (0 << 4)
223#define PWM_MODE_AUTO (1 << 4)
224#define PWM_MODE_OFF (2 << 4)
225#define PWM_MODE_ON (7 << 4)
226
227/* Dedicated function to read all registers related to a given PWM output.
228 This saves us quite a few locks and bank selections.
229 Must be called with data->lock held.
230 nr is from 0 to 3 */
231static void pc87427_readall_pwm(struct pc87427_data *data, u8 nr)
232{
233 int iobase = data->address[LD_FAN];
234
235 outb(BANK_FC(nr), iobase + PC87427_REG_BANK);
236 data->pwm_enable[nr] = inb(iobase + PC87427_REG_PWM_ENABLE);
237 data->pwm[nr] = inb(iobase + PC87427_REG_PWM_DUTY);
238}
239
240static inline int pwm_enable_from_reg(u8 reg)
241{
242 switch (reg & PWM_ENABLE_MODE_MASK) {
243 case PWM_MODE_ON:
244 return 0;
245 case PWM_MODE_MANUAL:
246 case PWM_MODE_OFF:
247 return 1;
248 case PWM_MODE_AUTO:
249 return 2;
250 default:
251 return -EPROTO;
252 }
253}
254
255static inline u8 pwm_enable_to_reg(unsigned long val, u8 pwmval)
256{
257 switch (val) {
258 default:
259 return PWM_MODE_ON;
260 case 1:
261 return pwmval ? PWM_MODE_MANUAL : PWM_MODE_OFF;
262 case 2:
263 return PWM_MODE_AUTO;
264 }
265}
266
267/*
Jean Delvare008e5f32010-08-14 21:08:59 +0200268 * Temperature registers and conversions
269 */
270
271#define PC87427_REG_TEMP_STATUS 0x10
272#define PC87427_REG_TEMP 0x14
273#define PC87427_REG_TEMP_MAX 0x18
274#define PC87427_REG_TEMP_MIN 0x19
275#define PC87427_REG_TEMP_CRIT 0x1a
276#define PC87427_REG_TEMP_TYPE 0x1d
277
278#define TEMP_STATUS_CHANEN (1 << 0)
279#define TEMP_STATUS_LOWFLG (1 << 1)
280#define TEMP_STATUS_HIGHFLG (1 << 2)
281#define TEMP_STATUS_CRITFLG (1 << 3)
282#define TEMP_STATUS_SENSERR (1 << 5)
283#define TEMP_TYPE_MASK (3 << 5)
284
285#define TEMP_TYPE_THERMISTOR (1 << 5)
286#define TEMP_TYPE_REMOTE_DIODE (2 << 5)
287#define TEMP_TYPE_LOCAL_DIODE (3 << 5)
288
289/* Dedicated function to read all registers related to a given temperature
290 input. This saves us quite a few locks and bank selections.
291 Must be called with data->lock held.
292 nr is from 0 to 5 */
293static void pc87427_readall_temp(struct pc87427_data *data, u8 nr)
294{
295 int iobase = data->address[LD_TEMP];
296
297 outb(BANK_TM(nr), iobase + PC87427_REG_BANK);
298 data->temp[nr] = le16_to_cpu(inw(iobase + PC87427_REG_TEMP));
299 data->temp_max[nr] = inb(iobase + PC87427_REG_TEMP_MAX);
300 data->temp_min[nr] = inb(iobase + PC87427_REG_TEMP_MIN);
301 data->temp_crit[nr] = inb(iobase + PC87427_REG_TEMP_CRIT);
302 data->temp_type[nr] = inb(iobase + PC87427_REG_TEMP_TYPE);
303 data->temp_status[nr] = inb(iobase + PC87427_REG_TEMP_STATUS);
304 /* Clear fan alarm bits */
305 outb(data->temp_status[nr], iobase + PC87427_REG_TEMP_STATUS);
306}
307
308static inline unsigned int temp_type_from_reg(u8 reg)
309{
310 switch (reg & TEMP_TYPE_MASK) {
311 case TEMP_TYPE_THERMISTOR:
312 return 4;
313 case TEMP_TYPE_REMOTE_DIODE:
314 case TEMP_TYPE_LOCAL_DIODE:
315 return 3;
316 default:
317 return 0;
318 }
319}
320
321/* We assume 8-bit thermal sensors; 9-bit thermal sensors are possible
322 too, but I have no idea how to figure out when they are used. */
323static inline long temp_from_reg(s16 reg)
324{
325 return reg * 1000 / 256;
326}
327
328static inline long temp_from_reg8(s8 reg)
329{
330 return reg * 1000;
331}
332
333/*
Jean Delvareba224e22006-12-12 18:18:29 +0100334 * Data interface
335 */
336
337static struct pc87427_data *pc87427_update_device(struct device *dev)
338{
339 struct pc87427_data *data = dev_get_drvdata(dev);
340 int i;
341
342 mutex_lock(&data->lock);
343 if (!time_after(jiffies, data->last_updated + HZ)
344 && data->last_updated)
345 goto done;
346
347 /* Fans */
348 for (i = 0; i < 8; i++) {
349 if (!(data->fan_enabled & (1 << i)))
350 continue;
351 pc87427_readall_fan(data, i);
352 }
Jean Delvare328716b2010-08-14 21:08:58 +0200353
354 /* PWM outputs */
355 for (i = 0; i < 4; i++) {
356 if (!(data->pwm_enabled & (1 << i)))
357 continue;
358 pc87427_readall_pwm(data, i);
359 }
360
Jean Delvare008e5f32010-08-14 21:08:59 +0200361 /* Temperature channels */
362 for (i = 0; i < 6; i++) {
363 if (!(data->temp_enabled & (1 << i)))
364 continue;
365 pc87427_readall_temp(data, i);
366 }
367
Jean Delvareba224e22006-12-12 18:18:29 +0100368 data->last_updated = jiffies;
369
370done:
371 mutex_unlock(&data->lock);
372 return data;
373}
374
375static ssize_t show_fan_input(struct device *dev, struct device_attribute
376 *devattr, char *buf)
377{
Jean Delvareba224e22006-12-12 18:18:29 +0100378 struct pc87427_data *data = pc87427_update_device(dev);
Jean Delvare0d22d582010-08-14 21:08:57 +0200379 int nr = to_sensor_dev_attr(devattr)->index;
Jean Delvareba224e22006-12-12 18:18:29 +0100380
381 return sprintf(buf, "%lu\n", fan_from_reg(data->fan[nr]));
382}
383
384static ssize_t show_fan_min(struct device *dev, struct device_attribute
385 *devattr, char *buf)
386{
Jean Delvareba224e22006-12-12 18:18:29 +0100387 struct pc87427_data *data = pc87427_update_device(dev);
Jean Delvare0d22d582010-08-14 21:08:57 +0200388 int nr = to_sensor_dev_attr(devattr)->index;
Jean Delvareba224e22006-12-12 18:18:29 +0100389
390 return sprintf(buf, "%lu\n", fan_from_reg(data->fan_min[nr]));
391}
392
393static ssize_t show_fan_alarm(struct device *dev, struct device_attribute
394 *devattr, char *buf)
395{
Jean Delvareba224e22006-12-12 18:18:29 +0100396 struct pc87427_data *data = pc87427_update_device(dev);
Jean Delvare0d22d582010-08-14 21:08:57 +0200397 int nr = to_sensor_dev_attr(devattr)->index;
Jean Delvareba224e22006-12-12 18:18:29 +0100398
399 return sprintf(buf, "%d\n", !!(data->fan_status[nr]
400 & FAN_STATUS_LOSPD));
401}
402
403static ssize_t show_fan_fault(struct device *dev, struct device_attribute
404 *devattr, char *buf)
405{
Jean Delvareba224e22006-12-12 18:18:29 +0100406 struct pc87427_data *data = pc87427_update_device(dev);
Jean Delvare0d22d582010-08-14 21:08:57 +0200407 int nr = to_sensor_dev_attr(devattr)->index;
Jean Delvareba224e22006-12-12 18:18:29 +0100408
409 return sprintf(buf, "%d\n", !!(data->fan_status[nr]
410 & FAN_STATUS_STALL));
411}
412
413static ssize_t set_fan_min(struct device *dev, struct device_attribute
414 *devattr, const char *buf, size_t count)
415{
416 struct pc87427_data *data = dev_get_drvdata(dev);
Jean Delvare0d22d582010-08-14 21:08:57 +0200417 int nr = to_sensor_dev_attr(devattr)->index;
418 unsigned long val;
Jean Delvareba224e22006-12-12 18:18:29 +0100419 int iobase = data->address[LD_FAN];
420
Frans Meulenbroeks179c4fd2012-01-04 20:58:52 +0100421 if (kstrtoul(buf, 10, &val) < 0)
Jean Delvare0d22d582010-08-14 21:08:57 +0200422 return -EINVAL;
423
Jean Delvareba224e22006-12-12 18:18:29 +0100424 mutex_lock(&data->lock);
425 outb(BANK_FM(nr), iobase + PC87427_REG_BANK);
426 /* The low speed limit registers are read-only while monitoring
427 is enabled, so we have to disable monitoring, then change the
428 limit, and finally enable monitoring again. */
429 outb(0, iobase + PC87427_REG_FAN_STATUS);
430 data->fan_min[nr] = fan_to_reg(val);
431 outw(data->fan_min[nr], iobase + PC87427_REG_FAN_MIN);
432 outb(FAN_STATUS_MONEN, iobase + PC87427_REG_FAN_STATUS);
433 mutex_unlock(&data->lock);
434
435 return count;
436}
437
438static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan_input, NULL, 0);
439static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan_input, NULL, 1);
440static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, show_fan_input, NULL, 2);
441static SENSOR_DEVICE_ATTR(fan4_input, S_IRUGO, show_fan_input, NULL, 3);
442static SENSOR_DEVICE_ATTR(fan5_input, S_IRUGO, show_fan_input, NULL, 4);
443static SENSOR_DEVICE_ATTR(fan6_input, S_IRUGO, show_fan_input, NULL, 5);
444static SENSOR_DEVICE_ATTR(fan7_input, S_IRUGO, show_fan_input, NULL, 6);
445static SENSOR_DEVICE_ATTR(fan8_input, S_IRUGO, show_fan_input, NULL, 7);
446
447static SENSOR_DEVICE_ATTR(fan1_min, S_IWUSR | S_IRUGO,
448 show_fan_min, set_fan_min, 0);
449static SENSOR_DEVICE_ATTR(fan2_min, S_IWUSR | S_IRUGO,
450 show_fan_min, set_fan_min, 1);
451static SENSOR_DEVICE_ATTR(fan3_min, S_IWUSR | S_IRUGO,
452 show_fan_min, set_fan_min, 2);
453static SENSOR_DEVICE_ATTR(fan4_min, S_IWUSR | S_IRUGO,
454 show_fan_min, set_fan_min, 3);
455static SENSOR_DEVICE_ATTR(fan5_min, S_IWUSR | S_IRUGO,
456 show_fan_min, set_fan_min, 4);
457static SENSOR_DEVICE_ATTR(fan6_min, S_IWUSR | S_IRUGO,
458 show_fan_min, set_fan_min, 5);
459static SENSOR_DEVICE_ATTR(fan7_min, S_IWUSR | S_IRUGO,
460 show_fan_min, set_fan_min, 6);
461static SENSOR_DEVICE_ATTR(fan8_min, S_IWUSR | S_IRUGO,
462 show_fan_min, set_fan_min, 7);
463
464static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_fan_alarm, NULL, 0);
465static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_fan_alarm, NULL, 1);
466static SENSOR_DEVICE_ATTR(fan3_alarm, S_IRUGO, show_fan_alarm, NULL, 2);
467static SENSOR_DEVICE_ATTR(fan4_alarm, S_IRUGO, show_fan_alarm, NULL, 3);
468static SENSOR_DEVICE_ATTR(fan5_alarm, S_IRUGO, show_fan_alarm, NULL, 4);
469static SENSOR_DEVICE_ATTR(fan6_alarm, S_IRUGO, show_fan_alarm, NULL, 5);
470static SENSOR_DEVICE_ATTR(fan7_alarm, S_IRUGO, show_fan_alarm, NULL, 6);
471static SENSOR_DEVICE_ATTR(fan8_alarm, S_IRUGO, show_fan_alarm, NULL, 7);
472
473static SENSOR_DEVICE_ATTR(fan1_fault, S_IRUGO, show_fan_fault, NULL, 0);
474static SENSOR_DEVICE_ATTR(fan2_fault, S_IRUGO, show_fan_fault, NULL, 1);
475static SENSOR_DEVICE_ATTR(fan3_fault, S_IRUGO, show_fan_fault, NULL, 2);
476static SENSOR_DEVICE_ATTR(fan4_fault, S_IRUGO, show_fan_fault, NULL, 3);
477static SENSOR_DEVICE_ATTR(fan5_fault, S_IRUGO, show_fan_fault, NULL, 4);
478static SENSOR_DEVICE_ATTR(fan6_fault, S_IRUGO, show_fan_fault, NULL, 5);
479static SENSOR_DEVICE_ATTR(fan7_fault, S_IRUGO, show_fan_fault, NULL, 6);
480static SENSOR_DEVICE_ATTR(fan8_fault, S_IRUGO, show_fan_fault, NULL, 7);
481
482static struct attribute *pc87427_attributes_fan[8][5] = {
483 {
484 &sensor_dev_attr_fan1_input.dev_attr.attr,
485 &sensor_dev_attr_fan1_min.dev_attr.attr,
486 &sensor_dev_attr_fan1_alarm.dev_attr.attr,
487 &sensor_dev_attr_fan1_fault.dev_attr.attr,
488 NULL
489 }, {
490 &sensor_dev_attr_fan2_input.dev_attr.attr,
491 &sensor_dev_attr_fan2_min.dev_attr.attr,
492 &sensor_dev_attr_fan2_alarm.dev_attr.attr,
493 &sensor_dev_attr_fan2_fault.dev_attr.attr,
494 NULL
495 }, {
496 &sensor_dev_attr_fan3_input.dev_attr.attr,
497 &sensor_dev_attr_fan3_min.dev_attr.attr,
498 &sensor_dev_attr_fan3_alarm.dev_attr.attr,
499 &sensor_dev_attr_fan3_fault.dev_attr.attr,
500 NULL
501 }, {
502 &sensor_dev_attr_fan4_input.dev_attr.attr,
503 &sensor_dev_attr_fan4_min.dev_attr.attr,
504 &sensor_dev_attr_fan4_alarm.dev_attr.attr,
505 &sensor_dev_attr_fan4_fault.dev_attr.attr,
506 NULL
507 }, {
508 &sensor_dev_attr_fan5_input.dev_attr.attr,
509 &sensor_dev_attr_fan5_min.dev_attr.attr,
510 &sensor_dev_attr_fan5_alarm.dev_attr.attr,
511 &sensor_dev_attr_fan5_fault.dev_attr.attr,
512 NULL
513 }, {
514 &sensor_dev_attr_fan6_input.dev_attr.attr,
515 &sensor_dev_attr_fan6_min.dev_attr.attr,
516 &sensor_dev_attr_fan6_alarm.dev_attr.attr,
517 &sensor_dev_attr_fan6_fault.dev_attr.attr,
518 NULL
519 }, {
520 &sensor_dev_attr_fan7_input.dev_attr.attr,
521 &sensor_dev_attr_fan7_min.dev_attr.attr,
522 &sensor_dev_attr_fan7_alarm.dev_attr.attr,
523 &sensor_dev_attr_fan7_fault.dev_attr.attr,
524 NULL
525 }, {
526 &sensor_dev_attr_fan8_input.dev_attr.attr,
527 &sensor_dev_attr_fan8_min.dev_attr.attr,
528 &sensor_dev_attr_fan8_alarm.dev_attr.attr,
529 &sensor_dev_attr_fan8_fault.dev_attr.attr,
530 NULL
531 }
532};
533
534static const struct attribute_group pc87427_group_fan[8] = {
535 { .attrs = pc87427_attributes_fan[0] },
536 { .attrs = pc87427_attributes_fan[1] },
537 { .attrs = pc87427_attributes_fan[2] },
538 { .attrs = pc87427_attributes_fan[3] },
539 { .attrs = pc87427_attributes_fan[4] },
540 { .attrs = pc87427_attributes_fan[5] },
541 { .attrs = pc87427_attributes_fan[6] },
542 { .attrs = pc87427_attributes_fan[7] },
543};
544
Jean Delvare328716b2010-08-14 21:08:58 +0200545/* Must be called with data->lock held and pc87427_readall_pwm() freshly
546 called */
547static void update_pwm_enable(struct pc87427_data *data, int nr, u8 mode)
548{
549 int iobase = data->address[LD_FAN];
550 data->pwm_enable[nr] &= ~PWM_ENABLE_MODE_MASK;
551 data->pwm_enable[nr] |= mode;
552 outb(data->pwm_enable[nr], iobase + PC87427_REG_PWM_ENABLE);
553}
554
555static ssize_t show_pwm_enable(struct device *dev, struct device_attribute
556 *devattr, char *buf)
557{
558 struct pc87427_data *data = pc87427_update_device(dev);
559 int nr = to_sensor_dev_attr(devattr)->index;
560 int pwm_enable;
561
562 pwm_enable = pwm_enable_from_reg(data->pwm_enable[nr]);
563 if (pwm_enable < 0)
564 return pwm_enable;
565 return sprintf(buf, "%d\n", pwm_enable);
566}
567
568static ssize_t set_pwm_enable(struct device *dev, struct device_attribute
569 *devattr, const char *buf, size_t count)
570{
571 struct pc87427_data *data = dev_get_drvdata(dev);
572 int nr = to_sensor_dev_attr(devattr)->index;
573 unsigned long val;
574
Frans Meulenbroeks179c4fd2012-01-04 20:58:52 +0100575 if (kstrtoul(buf, 10, &val) < 0 || val > 2)
Jean Delvare328716b2010-08-14 21:08:58 +0200576 return -EINVAL;
577 /* Can't go to automatic mode if it isn't configured */
578 if (val == 2 && !(data->pwm_auto_ok & (1 << nr)))
579 return -EINVAL;
580
581 mutex_lock(&data->lock);
582 pc87427_readall_pwm(data, nr);
583 update_pwm_enable(data, nr, pwm_enable_to_reg(val, data->pwm[nr]));
584 mutex_unlock(&data->lock);
585
586 return count;
587}
588
589static ssize_t show_pwm(struct device *dev, struct device_attribute
590 *devattr, char *buf)
591{
592 struct pc87427_data *data = pc87427_update_device(dev);
593 int nr = to_sensor_dev_attr(devattr)->index;
594
595 return sprintf(buf, "%d\n", (int)data->pwm[nr]);
596}
597
598static ssize_t set_pwm(struct device *dev, struct device_attribute
599 *devattr, const char *buf, size_t count)
600{
601 struct pc87427_data *data = dev_get_drvdata(dev);
602 int nr = to_sensor_dev_attr(devattr)->index;
603 unsigned long val;
604 int iobase = data->address[LD_FAN];
605 u8 mode;
606
Frans Meulenbroeks179c4fd2012-01-04 20:58:52 +0100607 if (kstrtoul(buf, 10, &val) < 0 || val > 0xff)
Jean Delvare328716b2010-08-14 21:08:58 +0200608 return -EINVAL;
609
610 mutex_lock(&data->lock);
611 pc87427_readall_pwm(data, nr);
612 mode = data->pwm_enable[nr] & PWM_ENABLE_MODE_MASK;
613 if (mode != PWM_MODE_MANUAL && mode != PWM_MODE_OFF) {
614 dev_notice(dev, "Can't set PWM%d duty cycle while not in "
615 "manual mode\n", nr + 1);
616 mutex_unlock(&data->lock);
617 return -EPERM;
618 }
619
620 /* We may have to change the mode */
621 if (mode == PWM_MODE_MANUAL && val == 0) {
622 /* Transition from Manual to Off */
623 update_pwm_enable(data, nr, PWM_MODE_OFF);
624 mode = PWM_MODE_OFF;
625 dev_dbg(dev, "Switching PWM%d from %s to %s\n", nr + 1,
626 "manual", "off");
627 } else if (mode == PWM_MODE_OFF && val != 0) {
628 /* Transition from Off to Manual */
629 update_pwm_enable(data, nr, PWM_MODE_MANUAL);
630 mode = PWM_MODE_MANUAL;
631 dev_dbg(dev, "Switching PWM%d from %s to %s\n", nr + 1,
632 "off", "manual");
633 }
634
635 data->pwm[nr] = val;
636 if (mode == PWM_MODE_MANUAL)
637 outb(val, iobase + PC87427_REG_PWM_DUTY);
638 mutex_unlock(&data->lock);
639
640 return count;
641}
642
643static SENSOR_DEVICE_ATTR(pwm1_enable, S_IWUSR | S_IRUGO,
644 show_pwm_enable, set_pwm_enable, 0);
645static SENSOR_DEVICE_ATTR(pwm2_enable, S_IWUSR | S_IRUGO,
646 show_pwm_enable, set_pwm_enable, 1);
647static SENSOR_DEVICE_ATTR(pwm3_enable, S_IWUSR | S_IRUGO,
648 show_pwm_enable, set_pwm_enable, 2);
649static SENSOR_DEVICE_ATTR(pwm4_enable, S_IWUSR | S_IRUGO,
650 show_pwm_enable, set_pwm_enable, 3);
651
652static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 0);
653static SENSOR_DEVICE_ATTR(pwm2, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 1);
654static SENSOR_DEVICE_ATTR(pwm3, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 2);
655static SENSOR_DEVICE_ATTR(pwm4, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 3);
656
657static struct attribute *pc87427_attributes_pwm[4][3] = {
658 {
659 &sensor_dev_attr_pwm1_enable.dev_attr.attr,
660 &sensor_dev_attr_pwm1.dev_attr.attr,
661 NULL
662 }, {
663 &sensor_dev_attr_pwm2_enable.dev_attr.attr,
664 &sensor_dev_attr_pwm2.dev_attr.attr,
665 NULL
666 }, {
667 &sensor_dev_attr_pwm3_enable.dev_attr.attr,
668 &sensor_dev_attr_pwm3.dev_attr.attr,
669 NULL
670 }, {
671 &sensor_dev_attr_pwm4_enable.dev_attr.attr,
672 &sensor_dev_attr_pwm4.dev_attr.attr,
673 NULL
674 }
675};
676
677static const struct attribute_group pc87427_group_pwm[4] = {
678 { .attrs = pc87427_attributes_pwm[0] },
679 { .attrs = pc87427_attributes_pwm[1] },
680 { .attrs = pc87427_attributes_pwm[2] },
681 { .attrs = pc87427_attributes_pwm[3] },
682};
683
Jean Delvare008e5f32010-08-14 21:08:59 +0200684static ssize_t show_temp_input(struct device *dev, struct device_attribute
685 *devattr, char *buf)
686{
687 struct pc87427_data *data = pc87427_update_device(dev);
688 int nr = to_sensor_dev_attr(devattr)->index;
689
690 return sprintf(buf, "%ld\n", temp_from_reg(data->temp[nr]));
691}
692
693static ssize_t show_temp_min(struct device *dev, struct device_attribute
694 *devattr, char *buf)
695{
696 struct pc87427_data *data = pc87427_update_device(dev);
697 int nr = to_sensor_dev_attr(devattr)->index;
698
699 return sprintf(buf, "%ld\n", temp_from_reg8(data->temp_min[nr]));
700}
701
702static ssize_t show_temp_max(struct device *dev, struct device_attribute
703 *devattr, char *buf)
704{
705 struct pc87427_data *data = pc87427_update_device(dev);
706 int nr = to_sensor_dev_attr(devattr)->index;
707
708 return sprintf(buf, "%ld\n", temp_from_reg8(data->temp_max[nr]));
709}
710
711static ssize_t show_temp_crit(struct device *dev, struct device_attribute
712 *devattr, char *buf)
713{
714 struct pc87427_data *data = pc87427_update_device(dev);
715 int nr = to_sensor_dev_attr(devattr)->index;
716
717 return sprintf(buf, "%ld\n", temp_from_reg8(data->temp_crit[nr]));
718}
719
720static ssize_t show_temp_type(struct device *dev, struct device_attribute
721 *devattr, char *buf)
722{
723 struct pc87427_data *data = pc87427_update_device(dev);
724 int nr = to_sensor_dev_attr(devattr)->index;
725
726 return sprintf(buf, "%u\n", temp_type_from_reg(data->temp_type[nr]));
727}
728
729static ssize_t show_temp_min_alarm(struct device *dev, struct device_attribute
730 *devattr, char *buf)
731{
732 struct pc87427_data *data = pc87427_update_device(dev);
733 int nr = to_sensor_dev_attr(devattr)->index;
734
735 return sprintf(buf, "%d\n", !!(data->temp_status[nr]
736 & TEMP_STATUS_LOWFLG));
737}
738
739static ssize_t show_temp_max_alarm(struct device *dev, struct device_attribute
740 *devattr, char *buf)
741{
742 struct pc87427_data *data = pc87427_update_device(dev);
743 int nr = to_sensor_dev_attr(devattr)->index;
744
745 return sprintf(buf, "%d\n", !!(data->temp_status[nr]
746 & TEMP_STATUS_HIGHFLG));
747}
748
749static ssize_t show_temp_crit_alarm(struct device *dev, struct device_attribute
750 *devattr, char *buf)
751{
752 struct pc87427_data *data = pc87427_update_device(dev);
753 int nr = to_sensor_dev_attr(devattr)->index;
754
755 return sprintf(buf, "%d\n", !!(data->temp_status[nr]
756 & TEMP_STATUS_CRITFLG));
757}
758
759static ssize_t show_temp_fault(struct device *dev, struct device_attribute
760 *devattr, char *buf)
761{
762 struct pc87427_data *data = pc87427_update_device(dev);
763 int nr = to_sensor_dev_attr(devattr)->index;
764
765 return sprintf(buf, "%d\n", !!(data->temp_status[nr]
766 & TEMP_STATUS_SENSERR));
767}
768
769static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_input, NULL, 0);
770static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp_input, NULL, 1);
771static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp_input, NULL, 2);
772static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_temp_input, NULL, 3);
773static SENSOR_DEVICE_ATTR(temp5_input, S_IRUGO, show_temp_input, NULL, 4);
774static SENSOR_DEVICE_ATTR(temp6_input, S_IRUGO, show_temp_input, NULL, 5);
775
776static SENSOR_DEVICE_ATTR(temp1_min, S_IRUGO, show_temp_min, NULL, 0);
777static SENSOR_DEVICE_ATTR(temp2_min, S_IRUGO, show_temp_min, NULL, 1);
778static SENSOR_DEVICE_ATTR(temp3_min, S_IRUGO, show_temp_min, NULL, 2);
779static SENSOR_DEVICE_ATTR(temp4_min, S_IRUGO, show_temp_min, NULL, 3);
780static SENSOR_DEVICE_ATTR(temp5_min, S_IRUGO, show_temp_min, NULL, 4);
781static SENSOR_DEVICE_ATTR(temp6_min, S_IRUGO, show_temp_min, NULL, 5);
782
783static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO, show_temp_max, NULL, 0);
784static SENSOR_DEVICE_ATTR(temp2_max, S_IRUGO, show_temp_max, NULL, 1);
785static SENSOR_DEVICE_ATTR(temp3_max, S_IRUGO, show_temp_max, NULL, 2);
786static SENSOR_DEVICE_ATTR(temp4_max, S_IRUGO, show_temp_max, NULL, 3);
787static SENSOR_DEVICE_ATTR(temp5_max, S_IRUGO, show_temp_max, NULL, 4);
788static SENSOR_DEVICE_ATTR(temp6_max, S_IRUGO, show_temp_max, NULL, 5);
789
790static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, show_temp_crit, NULL, 0);
791static SENSOR_DEVICE_ATTR(temp2_crit, S_IRUGO, show_temp_crit, NULL, 1);
792static SENSOR_DEVICE_ATTR(temp3_crit, S_IRUGO, show_temp_crit, NULL, 2);
793static SENSOR_DEVICE_ATTR(temp4_crit, S_IRUGO, show_temp_crit, NULL, 3);
794static SENSOR_DEVICE_ATTR(temp5_crit, S_IRUGO, show_temp_crit, NULL, 4);
795static SENSOR_DEVICE_ATTR(temp6_crit, S_IRUGO, show_temp_crit, NULL, 5);
796
797static SENSOR_DEVICE_ATTR(temp1_type, S_IRUGO, show_temp_type, NULL, 0);
798static SENSOR_DEVICE_ATTR(temp2_type, S_IRUGO, show_temp_type, NULL, 1);
799static SENSOR_DEVICE_ATTR(temp3_type, S_IRUGO, show_temp_type, NULL, 2);
800static SENSOR_DEVICE_ATTR(temp4_type, S_IRUGO, show_temp_type, NULL, 3);
801static SENSOR_DEVICE_ATTR(temp5_type, S_IRUGO, show_temp_type, NULL, 4);
802static SENSOR_DEVICE_ATTR(temp6_type, S_IRUGO, show_temp_type, NULL, 5);
803
804static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO,
805 show_temp_min_alarm, NULL, 0);
806static SENSOR_DEVICE_ATTR(temp2_min_alarm, S_IRUGO,
807 show_temp_min_alarm, NULL, 1);
808static SENSOR_DEVICE_ATTR(temp3_min_alarm, S_IRUGO,
809 show_temp_min_alarm, NULL, 2);
810static SENSOR_DEVICE_ATTR(temp4_min_alarm, S_IRUGO,
811 show_temp_min_alarm, NULL, 3);
812static SENSOR_DEVICE_ATTR(temp5_min_alarm, S_IRUGO,
813 show_temp_min_alarm, NULL, 4);
814static SENSOR_DEVICE_ATTR(temp6_min_alarm, S_IRUGO,
815 show_temp_min_alarm, NULL, 5);
816
817static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO,
818 show_temp_max_alarm, NULL, 0);
819static SENSOR_DEVICE_ATTR(temp2_max_alarm, S_IRUGO,
820 show_temp_max_alarm, NULL, 1);
821static SENSOR_DEVICE_ATTR(temp3_max_alarm, S_IRUGO,
822 show_temp_max_alarm, NULL, 2);
823static SENSOR_DEVICE_ATTR(temp4_max_alarm, S_IRUGO,
824 show_temp_max_alarm, NULL, 3);
825static SENSOR_DEVICE_ATTR(temp5_max_alarm, S_IRUGO,
826 show_temp_max_alarm, NULL, 4);
827static SENSOR_DEVICE_ATTR(temp6_max_alarm, S_IRUGO,
828 show_temp_max_alarm, NULL, 5);
829
830static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO,
831 show_temp_crit_alarm, NULL, 0);
832static SENSOR_DEVICE_ATTR(temp2_crit_alarm, S_IRUGO,
833 show_temp_crit_alarm, NULL, 1);
834static SENSOR_DEVICE_ATTR(temp3_crit_alarm, S_IRUGO,
835 show_temp_crit_alarm, NULL, 2);
836static SENSOR_DEVICE_ATTR(temp4_crit_alarm, S_IRUGO,
837 show_temp_crit_alarm, NULL, 3);
838static SENSOR_DEVICE_ATTR(temp5_crit_alarm, S_IRUGO,
839 show_temp_crit_alarm, NULL, 4);
840static SENSOR_DEVICE_ATTR(temp6_crit_alarm, S_IRUGO,
841 show_temp_crit_alarm, NULL, 5);
842
843static SENSOR_DEVICE_ATTR(temp1_fault, S_IRUGO, show_temp_fault, NULL, 0);
844static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_temp_fault, NULL, 1);
845static SENSOR_DEVICE_ATTR(temp3_fault, S_IRUGO, show_temp_fault, NULL, 2);
846static SENSOR_DEVICE_ATTR(temp4_fault, S_IRUGO, show_temp_fault, NULL, 3);
847static SENSOR_DEVICE_ATTR(temp5_fault, S_IRUGO, show_temp_fault, NULL, 4);
848static SENSOR_DEVICE_ATTR(temp6_fault, S_IRUGO, show_temp_fault, NULL, 5);
849
850static struct attribute *pc87427_attributes_temp[6][10] = {
851 {
852 &sensor_dev_attr_temp1_input.dev_attr.attr,
853 &sensor_dev_attr_temp1_min.dev_attr.attr,
854 &sensor_dev_attr_temp1_max.dev_attr.attr,
855 &sensor_dev_attr_temp1_crit.dev_attr.attr,
856 &sensor_dev_attr_temp1_type.dev_attr.attr,
857 &sensor_dev_attr_temp1_min_alarm.dev_attr.attr,
858 &sensor_dev_attr_temp1_max_alarm.dev_attr.attr,
859 &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr,
860 &sensor_dev_attr_temp1_fault.dev_attr.attr,
861 NULL
862 }, {
863 &sensor_dev_attr_temp2_input.dev_attr.attr,
864 &sensor_dev_attr_temp2_min.dev_attr.attr,
865 &sensor_dev_attr_temp2_max.dev_attr.attr,
866 &sensor_dev_attr_temp2_crit.dev_attr.attr,
867 &sensor_dev_attr_temp2_type.dev_attr.attr,
868 &sensor_dev_attr_temp2_min_alarm.dev_attr.attr,
869 &sensor_dev_attr_temp2_max_alarm.dev_attr.attr,
870 &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr,
871 &sensor_dev_attr_temp2_fault.dev_attr.attr,
872 NULL
873 }, {
874 &sensor_dev_attr_temp3_input.dev_attr.attr,
875 &sensor_dev_attr_temp3_min.dev_attr.attr,
876 &sensor_dev_attr_temp3_max.dev_attr.attr,
877 &sensor_dev_attr_temp3_crit.dev_attr.attr,
878 &sensor_dev_attr_temp3_type.dev_attr.attr,
879 &sensor_dev_attr_temp3_min_alarm.dev_attr.attr,
880 &sensor_dev_attr_temp3_max_alarm.dev_attr.attr,
881 &sensor_dev_attr_temp3_crit_alarm.dev_attr.attr,
882 &sensor_dev_attr_temp3_fault.dev_attr.attr,
883 NULL
884 }, {
885 &sensor_dev_attr_temp4_input.dev_attr.attr,
886 &sensor_dev_attr_temp4_min.dev_attr.attr,
887 &sensor_dev_attr_temp4_max.dev_attr.attr,
888 &sensor_dev_attr_temp4_crit.dev_attr.attr,
889 &sensor_dev_attr_temp4_type.dev_attr.attr,
890 &sensor_dev_attr_temp4_min_alarm.dev_attr.attr,
891 &sensor_dev_attr_temp4_max_alarm.dev_attr.attr,
892 &sensor_dev_attr_temp4_crit_alarm.dev_attr.attr,
893 &sensor_dev_attr_temp4_fault.dev_attr.attr,
894 NULL
895 }, {
896 &sensor_dev_attr_temp5_input.dev_attr.attr,
897 &sensor_dev_attr_temp5_min.dev_attr.attr,
898 &sensor_dev_attr_temp5_max.dev_attr.attr,
899 &sensor_dev_attr_temp5_crit.dev_attr.attr,
900 &sensor_dev_attr_temp5_type.dev_attr.attr,
901 &sensor_dev_attr_temp5_min_alarm.dev_attr.attr,
902 &sensor_dev_attr_temp5_max_alarm.dev_attr.attr,
903 &sensor_dev_attr_temp5_crit_alarm.dev_attr.attr,
904 &sensor_dev_attr_temp5_fault.dev_attr.attr,
905 NULL
906 }, {
907 &sensor_dev_attr_temp6_input.dev_attr.attr,
908 &sensor_dev_attr_temp6_min.dev_attr.attr,
909 &sensor_dev_attr_temp6_max.dev_attr.attr,
910 &sensor_dev_attr_temp6_crit.dev_attr.attr,
911 &sensor_dev_attr_temp6_type.dev_attr.attr,
912 &sensor_dev_attr_temp6_min_alarm.dev_attr.attr,
913 &sensor_dev_attr_temp6_max_alarm.dev_attr.attr,
914 &sensor_dev_attr_temp6_crit_alarm.dev_attr.attr,
915 &sensor_dev_attr_temp6_fault.dev_attr.attr,
916 NULL
917 }
918};
919
920static const struct attribute_group pc87427_group_temp[6] = {
921 { .attrs = pc87427_attributes_temp[0] },
922 { .attrs = pc87427_attributes_temp[1] },
923 { .attrs = pc87427_attributes_temp[2] },
924 { .attrs = pc87427_attributes_temp[3] },
925 { .attrs = pc87427_attributes_temp[4] },
926 { .attrs = pc87427_attributes_temp[5] },
927};
928
Jean Delvareba224e22006-12-12 18:18:29 +0100929static ssize_t show_name(struct device *dev, struct device_attribute
930 *devattr, char *buf)
931{
932 struct pc87427_data *data = dev_get_drvdata(dev);
933
934 return sprintf(buf, "%s\n", data->name);
935}
936static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
937
938
939/*
940 * Device detection, attach and detach
941 */
942
Jean Delvare9d32df12010-08-14 21:08:58 +0200943static void pc87427_release_regions(struct platform_device *pdev, int count)
944{
945 struct resource *res;
946 int i;
947
948 for (i = 0; i < count; i++) {
949 res = platform_get_resource(pdev, IORESOURCE_IO, i);
950 release_region(res->start, resource_size(res));
951 }
952}
953
954static int __devinit pc87427_request_regions(struct platform_device *pdev,
955 int count)
956{
957 struct resource *res;
958 int i, err = 0;
959
960 for (i = 0; i < count; i++) {
961 res = platform_get_resource(pdev, IORESOURCE_IO, i);
962 if (!res) {
963 err = -ENOENT;
964 dev_err(&pdev->dev, "Missing resource #%d\n", i);
965 break;
966 }
967 if (!request_region(res->start, resource_size(res), DRVNAME)) {
968 err = -EBUSY;
969 dev_err(&pdev->dev,
970 "Failed to request region 0x%lx-0x%lx\n",
971 (unsigned long)res->start,
972 (unsigned long)res->end);
973 break;
974 }
975 }
976
977 if (err && i)
978 pc87427_release_regions(pdev, i);
979
980 return err;
981}
982
Jean Delvareba224e22006-12-12 18:18:29 +0100983static void __devinit pc87427_init_device(struct device *dev)
984{
Jean Delvare4e7d99e2010-08-14 21:08:56 +0200985 struct pc87427_sio_data *sio_data = dev->platform_data;
Jean Delvareba224e22006-12-12 18:18:29 +0100986 struct pc87427_data *data = dev_get_drvdata(dev);
987 int i;
988 u8 reg;
989
990 /* The FMC module should be ready */
991 reg = pc87427_read8(data, LD_FAN, PC87427_REG_BANK);
992 if (!(reg & 0x80))
Jean Delvare008e5f32010-08-14 21:08:59 +0200993 dev_warn(dev, "%s module not ready!\n", "FMC");
Jean Delvareba224e22006-12-12 18:18:29 +0100994
995 /* Check which fans are enabled */
996 for (i = 0; i < 8; i++) {
Jean Delvare4e7d99e2010-08-14 21:08:56 +0200997 if (!(sio_data->has_fanin & (1 << i))) /* Not wired */
998 continue;
Jean Delvareba224e22006-12-12 18:18:29 +0100999 reg = pc87427_read8_bank(data, LD_FAN, BANK_FM(i),
1000 PC87427_REG_FAN_STATUS);
1001 if (reg & FAN_STATUS_MONEN)
1002 data->fan_enabled |= (1 << i);
1003 }
1004
1005 if (!data->fan_enabled) {
Jean Delvare4e7d99e2010-08-14 21:08:56 +02001006 dev_dbg(dev, "Enabling monitoring of all fans\n");
1007 for (i = 0; i < 8; i++) {
1008 if (!(sio_data->has_fanin & (1 << i))) /* Not wired */
1009 continue;
Jean Delvareba224e22006-12-12 18:18:29 +01001010 pc87427_write8_bank(data, LD_FAN, BANK_FM(i),
1011 PC87427_REG_FAN_STATUS,
1012 FAN_STATUS_MONEN);
Jean Delvare4e7d99e2010-08-14 21:08:56 +02001013 }
1014 data->fan_enabled = sio_data->has_fanin;
Jean Delvareba224e22006-12-12 18:18:29 +01001015 }
Jean Delvare328716b2010-08-14 21:08:58 +02001016
1017 /* Check which PWM outputs are enabled */
1018 for (i = 0; i < 4; i++) {
1019 if (!(sio_data->has_fanout & (1 << i))) /* Not wired */
1020 continue;
1021 reg = pc87427_read8_bank(data, LD_FAN, BANK_FC(i),
1022 PC87427_REG_PWM_ENABLE);
1023 if (reg & PWM_ENABLE_CTLEN)
1024 data->pwm_enabled |= (1 << i);
1025
1026 /* We don't expose an interface to reconfigure the automatic
1027 fan control mode, so only allow to return to this mode if
1028 it was originally set. */
1029 if ((reg & PWM_ENABLE_MODE_MASK) == PWM_MODE_AUTO) {
1030 dev_dbg(dev, "PWM%d is in automatic control mode\n",
1031 i + 1);
1032 data->pwm_auto_ok |= (1 << i);
1033 }
1034 }
Jean Delvare008e5f32010-08-14 21:08:59 +02001035
1036 /* The HMC module should be ready */
1037 reg = pc87427_read8(data, LD_TEMP, PC87427_REG_BANK);
1038 if (!(reg & 0x80))
1039 dev_warn(dev, "%s module not ready!\n", "HMC");
1040
1041 /* Check which temperature channels are enabled */
1042 for (i = 0; i < 6; i++) {
1043 reg = pc87427_read8_bank(data, LD_TEMP, BANK_TM(i),
1044 PC87427_REG_TEMP_STATUS);
1045 if (reg & TEMP_STATUS_CHANEN)
1046 data->temp_enabled |= (1 << i);
1047 }
Jean Delvareba224e22006-12-12 18:18:29 +01001048}
1049
Jean Delvarec6b87242010-08-14 21:09:00 +02001050static void pc87427_remove_files(struct device *dev)
1051{
1052 struct pc87427_data *data = dev_get_drvdata(dev);
1053 int i;
1054
1055 device_remove_file(dev, &dev_attr_name);
1056 for (i = 0; i < 8; i++) {
1057 if (!(data->fan_enabled & (1 << i)))
1058 continue;
1059 sysfs_remove_group(&dev->kobj, &pc87427_group_fan[i]);
1060 }
1061 for (i = 0; i < 4; i++) {
1062 if (!(data->pwm_enabled & (1 << i)))
1063 continue;
1064 sysfs_remove_group(&dev->kobj, &pc87427_group_pwm[i]);
1065 }
1066 for (i = 0; i < 6; i++) {
1067 if (!(data->temp_enabled & (1 << i)))
1068 continue;
1069 sysfs_remove_group(&dev->kobj, &pc87427_group_temp[i]);
1070 }
1071}
1072
Jean Delvareba224e22006-12-12 18:18:29 +01001073static int __devinit pc87427_probe(struct platform_device *pdev)
1074{
Jean Delvare9d32df12010-08-14 21:08:58 +02001075 struct pc87427_sio_data *sio_data = pdev->dev.platform_data;
Jean Delvareba224e22006-12-12 18:18:29 +01001076 struct pc87427_data *data;
Jean Delvare9d32df12010-08-14 21:08:58 +02001077 int i, err, res_count;
Jean Delvareba224e22006-12-12 18:18:29 +01001078
Jean Delvare0d22d582010-08-14 21:08:57 +02001079 data = kzalloc(sizeof(struct pc87427_data), GFP_KERNEL);
1080 if (!data) {
Jean Delvareba224e22006-12-12 18:18:29 +01001081 err = -ENOMEM;
Joe Perches5e24e0c2011-01-12 21:55:11 +01001082 pr_err("Out of memory\n");
Jean Delvareba224e22006-12-12 18:18:29 +01001083 goto exit;
1084 }
1085
Jean Delvare9d32df12010-08-14 21:08:58 +02001086 data->address[0] = sio_data->address[0];
1087 data->address[1] = sio_data->address[1];
1088 res_count = (data->address[0] != 0) + (data->address[1] != 0);
1089
1090 err = pc87427_request_regions(pdev, res_count);
1091 if (err)
Jean Delvarece7ee4e2007-05-08 17:21:59 +02001092 goto exit_kfree;
Jean Delvareba224e22006-12-12 18:18:29 +01001093
1094 mutex_init(&data->lock);
1095 data->name = "pc87427";
1096 platform_set_drvdata(pdev, data);
1097 pc87427_init_device(&pdev->dev);
1098
1099 /* Register sysfs hooks */
Jean Delvare0d22d582010-08-14 21:08:57 +02001100 err = device_create_file(&pdev->dev, &dev_attr_name);
1101 if (err)
Jean Delvarece7ee4e2007-05-08 17:21:59 +02001102 goto exit_release_region;
Jean Delvareba224e22006-12-12 18:18:29 +01001103 for (i = 0; i < 8; i++) {
1104 if (!(data->fan_enabled & (1 << i)))
1105 continue;
Jean Delvare0d22d582010-08-14 21:08:57 +02001106 err = sysfs_create_group(&pdev->dev.kobj,
1107 &pc87427_group_fan[i]);
1108 if (err)
Jean Delvareba224e22006-12-12 18:18:29 +01001109 goto exit_remove_files;
1110 }
Jean Delvare328716b2010-08-14 21:08:58 +02001111 for (i = 0; i < 4; i++) {
1112 if (!(data->pwm_enabled & (1 << i)))
1113 continue;
1114 err = sysfs_create_group(&pdev->dev.kobj,
1115 &pc87427_group_pwm[i]);
1116 if (err)
1117 goto exit_remove_files;
1118 }
Jean Delvare008e5f32010-08-14 21:08:59 +02001119 for (i = 0; i < 6; i++) {
1120 if (!(data->temp_enabled & (1 << i)))
1121 continue;
1122 err = sysfs_create_group(&pdev->dev.kobj,
1123 &pc87427_group_temp[i]);
1124 if (err)
1125 goto exit_remove_files;
1126 }
Jean Delvareba224e22006-12-12 18:18:29 +01001127
Tony Jones1beeffe2007-08-20 13:46:20 -07001128 data->hwmon_dev = hwmon_device_register(&pdev->dev);
1129 if (IS_ERR(data->hwmon_dev)) {
1130 err = PTR_ERR(data->hwmon_dev);
Jean Delvareba224e22006-12-12 18:18:29 +01001131 dev_err(&pdev->dev, "Class registration failed (%d)\n", err);
1132 goto exit_remove_files;
1133 }
1134
1135 return 0;
1136
1137exit_remove_files:
Jean Delvarec6b87242010-08-14 21:09:00 +02001138 pc87427_remove_files(&pdev->dev);
Jean Delvarece7ee4e2007-05-08 17:21:59 +02001139exit_release_region:
Jean Delvare9d32df12010-08-14 21:08:58 +02001140 pc87427_release_regions(pdev, res_count);
Jean Delvareba224e22006-12-12 18:18:29 +01001141exit_kfree:
1142 platform_set_drvdata(pdev, NULL);
1143 kfree(data);
1144exit:
1145 return err;
1146}
1147
1148static int __devexit pc87427_remove(struct platform_device *pdev)
1149{
1150 struct pc87427_data *data = platform_get_drvdata(pdev);
Jean Delvarec6b87242010-08-14 21:09:00 +02001151 int res_count;
Jean Delvare9d32df12010-08-14 21:08:58 +02001152
1153 res_count = (data->address[0] != 0) + (data->address[1] != 0);
Jean Delvareba224e22006-12-12 18:18:29 +01001154
Tony Jones1beeffe2007-08-20 13:46:20 -07001155 hwmon_device_unregister(data->hwmon_dev);
Jean Delvarec6b87242010-08-14 21:09:00 +02001156 pc87427_remove_files(&pdev->dev);
Jean Delvare04a62172007-06-12 13:57:19 +02001157 platform_set_drvdata(pdev, NULL);
Jean Delvareba224e22006-12-12 18:18:29 +01001158 kfree(data);
1159
Jean Delvare9d32df12010-08-14 21:08:58 +02001160 pc87427_release_regions(pdev, res_count);
Jean Delvarece7ee4e2007-05-08 17:21:59 +02001161
Jean Delvareba224e22006-12-12 18:18:29 +01001162 return 0;
1163}
1164
1165
1166static struct platform_driver pc87427_driver = {
1167 .driver = {
1168 .owner = THIS_MODULE,
1169 .name = DRVNAME,
1170 },
1171 .probe = pc87427_probe,
1172 .remove = __devexit_p(pc87427_remove),
1173};
1174
Jean Delvare9d32df12010-08-14 21:08:58 +02001175static int __init pc87427_device_add(const struct pc87427_sio_data *sio_data)
Jean Delvareba224e22006-12-12 18:18:29 +01001176{
Jean Delvare9d32df12010-08-14 21:08:58 +02001177 struct resource res[2] = {
1178 { .flags = IORESOURCE_IO },
1179 { .flags = IORESOURCE_IO },
Jean Delvareba224e22006-12-12 18:18:29 +01001180 };
Jean Delvare9d32df12010-08-14 21:08:58 +02001181 int err, i, res_count;
Jean Delvareba224e22006-12-12 18:18:29 +01001182
Jean Delvare9d32df12010-08-14 21:08:58 +02001183 res_count = 0;
1184 for (i = 0; i < 2; i++) {
1185 if (!sio_data->address[i])
1186 continue;
1187 res[res_count].start = sio_data->address[i];
1188 res[res_count].end = sio_data->address[i] + REGION_LENGTH - 1;
1189 res[res_count].name = logdev_str[i];
Jean Delvareb9acb642009-01-07 16:37:35 +01001190
Jean Delvare9d32df12010-08-14 21:08:58 +02001191 err = acpi_check_resource_conflict(&res[res_count]);
1192 if (err)
1193 goto exit;
1194
1195 res_count++;
1196 }
1197
1198 pdev = platform_device_alloc(DRVNAME, res[0].start);
Jean Delvareba224e22006-12-12 18:18:29 +01001199 if (!pdev) {
1200 err = -ENOMEM;
Joe Perches5e24e0c2011-01-12 21:55:11 +01001201 pr_err("Device allocation failed\n");
Jean Delvareba224e22006-12-12 18:18:29 +01001202 goto exit;
1203 }
1204
Jean Delvare9d32df12010-08-14 21:08:58 +02001205 err = platform_device_add_resources(pdev, res, res_count);
Jean Delvareba224e22006-12-12 18:18:29 +01001206 if (err) {
Joe Perches5e24e0c2011-01-12 21:55:11 +01001207 pr_err("Device resource addition failed (%d)\n", err);
Jean Delvareba224e22006-12-12 18:18:29 +01001208 goto exit_device_put;
1209 }
1210
Jean Delvare4e7d99e2010-08-14 21:08:56 +02001211 err = platform_device_add_data(pdev, sio_data,
1212 sizeof(struct pc87427_sio_data));
1213 if (err) {
Joe Perches5e24e0c2011-01-12 21:55:11 +01001214 pr_err("Platform data allocation failed\n");
Jean Delvare4e7d99e2010-08-14 21:08:56 +02001215 goto exit_device_put;
1216 }
1217
Jean Delvareba224e22006-12-12 18:18:29 +01001218 err = platform_device_add(pdev);
1219 if (err) {
Joe Perches5e24e0c2011-01-12 21:55:11 +01001220 pr_err("Device addition failed (%d)\n", err);
Jean Delvareba224e22006-12-12 18:18:29 +01001221 goto exit_device_put;
1222 }
1223
1224 return 0;
1225
1226exit_device_put:
1227 platform_device_put(pdev);
1228exit:
1229 return err;
1230}
1231
Jean Delvare9d32df12010-08-14 21:08:58 +02001232static int __init pc87427_find(int sioaddr, struct pc87427_sio_data *sio_data)
Jean Delvareba224e22006-12-12 18:18:29 +01001233{
1234 u16 val;
Jean Delvare4e7d99e2010-08-14 21:08:56 +02001235 u8 cfg, cfg_b;
Jean Delvareba224e22006-12-12 18:18:29 +01001236 int i, err = 0;
1237
1238 /* Identify device */
Jean Delvare67b671b2007-12-06 23:13:42 +01001239 val = force_id ? force_id : superio_inb(sioaddr, SIOREG_DEVID);
Jean Delvareba224e22006-12-12 18:18:29 +01001240 if (val != 0xf2) { /* PC87427 */
1241 err = -ENODEV;
1242 goto exit;
1243 }
1244
1245 for (i = 0; i < 2; i++) {
Jean Delvare9d32df12010-08-14 21:08:58 +02001246 sio_data->address[i] = 0;
Jean Delvareba224e22006-12-12 18:18:29 +01001247 /* Select logical device */
1248 superio_outb(sioaddr, SIOREG_LDSEL, logdev[i]);
1249
1250 val = superio_inb(sioaddr, SIOREG_ACT);
1251 if (!(val & 0x01)) {
Joe Perches5e24e0c2011-01-12 21:55:11 +01001252 pr_info("Logical device 0x%02x not activated\n",
1253 logdev[i]);
Jean Delvareba224e22006-12-12 18:18:29 +01001254 continue;
1255 }
1256
1257 val = superio_inb(sioaddr, SIOREG_MAP);
1258 if (val & 0x01) {
Joe Perches5e24e0c2011-01-12 21:55:11 +01001259 pr_warn("Logical device 0x%02x is memory-mapped, "
1260 "can't use\n", logdev[i]);
Jean Delvareba224e22006-12-12 18:18:29 +01001261 continue;
1262 }
1263
1264 val = (superio_inb(sioaddr, SIOREG_IOBASE) << 8)
1265 | superio_inb(sioaddr, SIOREG_IOBASE + 1);
1266 if (!val) {
Joe Perches5e24e0c2011-01-12 21:55:11 +01001267 pr_info("I/O base address not set for logical device "
1268 "0x%02x\n", logdev[i]);
Jean Delvareba224e22006-12-12 18:18:29 +01001269 continue;
1270 }
Jean Delvare9d32df12010-08-14 21:08:58 +02001271 sio_data->address[i] = val;
1272 }
1273
1274 /* No point in loading the driver if everything is disabled */
1275 if (!sio_data->address[0] && !sio_data->address[1]) {
1276 err = -ENODEV;
1277 goto exit;
Jean Delvareba224e22006-12-12 18:18:29 +01001278 }
1279
Jean Delvare4e7d99e2010-08-14 21:08:56 +02001280 /* Check which fan inputs are wired */
1281 sio_data->has_fanin = (1 << 2) | (1 << 3); /* FANIN2, FANIN3 */
1282
1283 cfg = superio_inb(sioaddr, SIOREG_CF2);
1284 if (!(cfg & (1 << 3)))
1285 sio_data->has_fanin |= (1 << 0); /* FANIN0 */
1286 if (!(cfg & (1 << 2)))
1287 sio_data->has_fanin |= (1 << 4); /* FANIN4 */
1288
1289 cfg = superio_inb(sioaddr, SIOREG_CFD);
1290 if (!(cfg & (1 << 0)))
1291 sio_data->has_fanin |= (1 << 1); /* FANIN1 */
1292
1293 cfg = superio_inb(sioaddr, SIOREG_CF4);
1294 if (!(cfg & (1 << 0)))
1295 sio_data->has_fanin |= (1 << 7); /* FANIN7 */
1296 cfg_b = superio_inb(sioaddr, SIOREG_CFB);
1297 if (!(cfg & (1 << 1)) && (cfg_b & (1 << 3)))
1298 sio_data->has_fanin |= (1 << 5); /* FANIN5 */
1299 cfg = superio_inb(sioaddr, SIOREG_CF3);
1300 if ((cfg & (1 << 3)) && !(cfg_b & (1 << 5)))
1301 sio_data->has_fanin |= (1 << 6); /* FANIN6 */
1302
Jean Delvare328716b2010-08-14 21:08:58 +02001303 /* Check which fan outputs are wired */
1304 sio_data->has_fanout = (1 << 0); /* FANOUT0 */
1305 if (cfg_b & (1 << 0))
1306 sio_data->has_fanout |= (1 << 3); /* FANOUT3 */
1307
1308 cfg = superio_inb(sioaddr, SIOREG_CFC);
1309 if (!(cfg & (1 << 4))) {
1310 if (cfg_b & (1 << 1))
1311 sio_data->has_fanout |= (1 << 1); /* FANOUT1 */
1312 if (cfg_b & (1 << 2))
1313 sio_data->has_fanout |= (1 << 2); /* FANOUT2 */
1314 }
1315
1316 /* FANOUT1 and FANOUT2 can each be routed to 2 different pins */
1317 cfg = superio_inb(sioaddr, SIOREG_CF5);
1318 if (cfg & (1 << 6))
1319 sio_data->has_fanout |= (1 << 1); /* FANOUT1 */
1320 if (cfg & (1 << 5))
1321 sio_data->has_fanout |= (1 << 2); /* FANOUT2 */
1322
Jean Delvareba224e22006-12-12 18:18:29 +01001323exit:
1324 superio_exit(sioaddr);
1325 return err;
1326}
1327
1328static int __init pc87427_init(void)
1329{
1330 int err;
Jean Delvare4e7d99e2010-08-14 21:08:56 +02001331 struct pc87427_sio_data sio_data;
Jean Delvareba224e22006-12-12 18:18:29 +01001332
Jean Delvare9d32df12010-08-14 21:08:58 +02001333 if (pc87427_find(0x2e, &sio_data)
1334 && pc87427_find(0x4e, &sio_data))
Jean Delvareba224e22006-12-12 18:18:29 +01001335 return -ENODEV;
1336
1337 err = platform_driver_register(&pc87427_driver);
1338 if (err)
1339 goto exit;
1340
1341 /* Sets global pdev as a side effect */
Jean Delvare9d32df12010-08-14 21:08:58 +02001342 err = pc87427_device_add(&sio_data);
Jean Delvareba224e22006-12-12 18:18:29 +01001343 if (err)
1344 goto exit_driver;
1345
1346 return 0;
1347
1348exit_driver:
1349 platform_driver_unregister(&pc87427_driver);
1350exit:
1351 return err;
1352}
1353
1354static void __exit pc87427_exit(void)
1355{
1356 platform_device_unregister(pdev);
1357 platform_driver_unregister(&pc87427_driver);
1358}
1359
1360MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
1361MODULE_DESCRIPTION("PC87427 hardware monitoring driver");
1362MODULE_LICENSE("GPL");
1363
1364module_init(pc87427_init);
1365module_exit(pc87427_exit);