]> bbs.cooldavid.org Git - net-next-2.6.git/blame - drivers/hwmon/pc87427.c
hwmon: (pc87427) Add support for manual fan speed control
[net-next-2.6.git] / drivers / hwmon / pc87427.c
CommitLineData
ba224e2c
JD
1/*
2 * pc87427.c - hardware monitoring driver for the
3 * National Semiconductor PC87427 Super-I/O chip
4e7d99e1 4 * Copyright (C) 2006, 2008 Jean Delvare <khali@linux-fr.org>
ba224e2c
JD
5 *
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
328716bc 18 * PC87427 - 8 4 - 0xF2
ba224e2c
JD
19 *
20 * This driver assumes that no more than one chip is present.
328716bc 21 * Only fans are supported so far, although the chip can do much more.
ba224e2c
JD
22 */
23
24#include <linux/module.h>
25#include <linux/init.h>
26#include <linux/slab.h>
27#include <linux/jiffies.h>
28#include <linux/platform_device.h>
29#include <linux/hwmon.h>
30#include <linux/hwmon-sysfs.h>
31#include <linux/err.h>
32#include <linux/mutex.h>
33#include <linux/sysfs.h>
ce7ee4e8 34#include <linux/ioport.h>
b9acb64a 35#include <linux/acpi.h>
6055fae8 36#include <linux/io.h>
ba224e2c 37
67b671bc
JD
38static unsigned short force_id;
39module_param(force_id, ushort, 0);
40MODULE_PARM_DESC(force_id, "Override the detected device ID");
41
ba224e2c
JD
42static struct platform_device *pdev;
43
44#define DRVNAME "pc87427"
45
46/* The lock mutex protects both the I/O accesses (needed because the
47 device is using banked registers) and the register cache (needed to keep
48 the data in the registers and the cache in sync at any time). */
49struct pc87427_data {
1beeffe4 50 struct device *hwmon_dev;
ba224e2c
JD
51 struct mutex lock;
52 int address[2];
53 const char *name;
54
55 unsigned long last_updated; /* in jiffies */
56 u8 fan_enabled; /* bit vector */
57 u16 fan[8]; /* register values */
58 u16 fan_min[8]; /* register values */
59 u8 fan_status[8]; /* register values */
328716bc
JD
60
61 u8 pwm_enabled; /* bit vector */
62 u8 pwm_auto_ok; /* bit vector */
63 u8 pwm_enable[4]; /* register values */
64 u8 pwm[4]; /* register values */
ba224e2c
JD
65};
66
4e7d99e1
JD
67struct pc87427_sio_data {
68 u8 has_fanin;
328716bc 69 u8 has_fanout;
4e7d99e1
JD
70};
71
ba224e2c
JD
72/*
73 * Super-I/O registers and operations
74 */
75
76#define SIOREG_LDSEL 0x07 /* Logical device select */
77#define SIOREG_DEVID 0x20 /* Device ID */
4e7d99e1
JD
78#define SIOREG_CF2 0x22 /* Configuration 2 */
79#define SIOREG_CF3 0x23 /* Configuration 3 */
80#define SIOREG_CF4 0x24 /* Configuration 4 */
328716bc 81#define SIOREG_CF5 0x25 /* Configuration 5 */
4e7d99e1 82#define SIOREG_CFB 0x2B /* Configuration B */
328716bc 83#define SIOREG_CFC 0x2C /* Configuration C */
4e7d99e1 84#define SIOREG_CFD 0x2D /* Configuration D */
ba224e2c
JD
85#define SIOREG_ACT 0x30 /* Device activation */
86#define SIOREG_MAP 0x50 /* I/O or memory mapping */
87#define SIOREG_IOBASE 0x60 /* I/O base address */
88
89static const u8 logdev[2] = { 0x09, 0x14 };
90static const char *logdev_str[2] = { DRVNAME " FMC", DRVNAME " HMC" };
91#define LD_FAN 0
92#define LD_IN 1
93#define LD_TEMP 1
94
95static inline void superio_outb(int sioaddr, int reg, int val)
96{
97 outb(reg, sioaddr);
98 outb(val, sioaddr + 1);
99}
100
101static inline int superio_inb(int sioaddr, int reg)
102{
103 outb(reg, sioaddr);
104 return inb(sioaddr + 1);
105}
106
107static inline void superio_exit(int sioaddr)
108{
109 outb(0x02, sioaddr);
110 outb(0x02, sioaddr + 1);
111}
112
113/*
114 * Logical devices
115 */
116
117#define REGION_LENGTH 32
118#define PC87427_REG_BANK 0x0f
119#define BANK_FM(nr) (nr)
120#define BANK_FT(nr) (0x08 + (nr))
121#define BANK_FC(nr) (0x10 + (nr) * 2)
122
123/*
124 * I/O access functions
125 */
126
127/* ldi is the logical device index */
128static inline int pc87427_read8(struct pc87427_data *data, u8 ldi, u8 reg)
129{
130 return inb(data->address[ldi] + reg);
131}
132
133/* Must be called with data->lock held, except during init */
134static inline int pc87427_read8_bank(struct pc87427_data *data, u8 ldi,
135 u8 bank, u8 reg)
136{
137 outb(bank, data->address[ldi] + PC87427_REG_BANK);
138 return inb(data->address[ldi] + reg);
139}
140
141/* Must be called with data->lock held, except during init */
142static inline void pc87427_write8_bank(struct pc87427_data *data, u8 ldi,
143 u8 bank, u8 reg, u8 value)
144{
145 outb(bank, data->address[ldi] + PC87427_REG_BANK);
146 outb(value, data->address[ldi] + reg);
147}
148
149/*
150 * Fan registers and conversions
151 */
152
153/* fan data registers are 16-bit wide */
154#define PC87427_REG_FAN 0x12
155#define PC87427_REG_FAN_MIN 0x14
156#define PC87427_REG_FAN_STATUS 0x10
157
158#define FAN_STATUS_STALL (1 << 3)
159#define FAN_STATUS_LOSPD (1 << 1)
160#define FAN_STATUS_MONEN (1 << 0)
161
162/* Dedicated function to read all registers related to a given fan input.
163 This saves us quite a few locks and bank selections.
164 Must be called with data->lock held.
165 nr is from 0 to 7 */
166static void pc87427_readall_fan(struct pc87427_data *data, u8 nr)
167{
168 int iobase = data->address[LD_FAN];
169
170 outb(BANK_FM(nr), iobase + PC87427_REG_BANK);
171 data->fan[nr] = inw(iobase + PC87427_REG_FAN);
172 data->fan_min[nr] = inw(iobase + PC87427_REG_FAN_MIN);
173 data->fan_status[nr] = inb(iobase + PC87427_REG_FAN_STATUS);
174 /* Clear fan alarm bits */
175 outb(data->fan_status[nr], iobase + PC87427_REG_FAN_STATUS);
176}
177
178/* The 2 LSB of fan speed registers are used for something different.
179 The actual 2 LSB of the measurements are not available. */
180static inline unsigned long fan_from_reg(u16 reg)
181{
182 reg &= 0xfffc;
183 if (reg == 0x0000 || reg == 0xfffc)
184 return 0;
185 return 5400000UL / reg;
186}
187
188/* The 2 LSB of the fan speed limit registers are not significant. */
189static inline u16 fan_to_reg(unsigned long val)
190{
191 if (val < 83UL)
192 return 0xffff;
193 if (val >= 1350000UL)
194 return 0x0004;
195 return ((1350000UL + val / 2) / val) << 2;
196}
197
328716bc
JD
198/*
199 * PWM registers and conversions
200 */
201
202#define PC87427_REG_PWM_ENABLE 0x10
203#define PC87427_REG_PWM_DUTY 0x12
204
205#define PWM_ENABLE_MODE_MASK (7 << 4)
206#define PWM_ENABLE_CTLEN (1 << 0)
207
208#define PWM_MODE_MANUAL (0 << 4)
209#define PWM_MODE_AUTO (1 << 4)
210#define PWM_MODE_OFF (2 << 4)
211#define PWM_MODE_ON (7 << 4)
212
213/* Dedicated function to read all registers related to a given PWM output.
214 This saves us quite a few locks and bank selections.
215 Must be called with data->lock held.
216 nr is from 0 to 3 */
217static void pc87427_readall_pwm(struct pc87427_data *data, u8 nr)
218{
219 int iobase = data->address[LD_FAN];
220
221 outb(BANK_FC(nr), iobase + PC87427_REG_BANK);
222 data->pwm_enable[nr] = inb(iobase + PC87427_REG_PWM_ENABLE);
223 data->pwm[nr] = inb(iobase + PC87427_REG_PWM_DUTY);
224}
225
226static inline int pwm_enable_from_reg(u8 reg)
227{
228 switch (reg & PWM_ENABLE_MODE_MASK) {
229 case PWM_MODE_ON:
230 return 0;
231 case PWM_MODE_MANUAL:
232 case PWM_MODE_OFF:
233 return 1;
234 case PWM_MODE_AUTO:
235 return 2;
236 default:
237 return -EPROTO;
238 }
239}
240
241static inline u8 pwm_enable_to_reg(unsigned long val, u8 pwmval)
242{
243 switch (val) {
244 default:
245 return PWM_MODE_ON;
246 case 1:
247 return pwmval ? PWM_MODE_MANUAL : PWM_MODE_OFF;
248 case 2:
249 return PWM_MODE_AUTO;
250 }
251}
252
ba224e2c
JD
253/*
254 * Data interface
255 */
256
257static struct pc87427_data *pc87427_update_device(struct device *dev)
258{
259 struct pc87427_data *data = dev_get_drvdata(dev);
260 int i;
261
262 mutex_lock(&data->lock);
263 if (!time_after(jiffies, data->last_updated + HZ)
264 && data->last_updated)
265 goto done;
266
267 /* Fans */
268 for (i = 0; i < 8; i++) {
269 if (!(data->fan_enabled & (1 << i)))
270 continue;
271 pc87427_readall_fan(data, i);
272 }
328716bc
JD
273
274 /* PWM outputs */
275 for (i = 0; i < 4; i++) {
276 if (!(data->pwm_enabled & (1 << i)))
277 continue;
278 pc87427_readall_pwm(data, i);
279 }
280
ba224e2c
JD
281 data->last_updated = jiffies;
282
283done:
284 mutex_unlock(&data->lock);
285 return data;
286}
287
288static ssize_t show_fan_input(struct device *dev, struct device_attribute
289 *devattr, char *buf)
290{
ba224e2c 291 struct pc87427_data *data = pc87427_update_device(dev);
0d22d583 292 int nr = to_sensor_dev_attr(devattr)->index;
ba224e2c
JD
293
294 return sprintf(buf, "%lu\n", fan_from_reg(data->fan[nr]));
295}
296
297static ssize_t show_fan_min(struct device *dev, struct device_attribute
298 *devattr, char *buf)
299{
ba224e2c 300 struct pc87427_data *data = pc87427_update_device(dev);
0d22d583 301 int nr = to_sensor_dev_attr(devattr)->index;
ba224e2c
JD
302
303 return sprintf(buf, "%lu\n", fan_from_reg(data->fan_min[nr]));
304}
305
306static ssize_t show_fan_alarm(struct device *dev, struct device_attribute
307 *devattr, char *buf)
308{
ba224e2c 309 struct pc87427_data *data = pc87427_update_device(dev);
0d22d583 310 int nr = to_sensor_dev_attr(devattr)->index;
ba224e2c
JD
311
312 return sprintf(buf, "%d\n", !!(data->fan_status[nr]
313 & FAN_STATUS_LOSPD));
314}
315
316static ssize_t show_fan_fault(struct device *dev, struct device_attribute
317 *devattr, char *buf)
318{
ba224e2c 319 struct pc87427_data *data = pc87427_update_device(dev);
0d22d583 320 int nr = to_sensor_dev_attr(devattr)->index;
ba224e2c
JD
321
322 return sprintf(buf, "%d\n", !!(data->fan_status[nr]
323 & FAN_STATUS_STALL));
324}
325
326static ssize_t set_fan_min(struct device *dev, struct device_attribute
327 *devattr, const char *buf, size_t count)
328{
329 struct pc87427_data *data = dev_get_drvdata(dev);
0d22d583
JD
330 int nr = to_sensor_dev_attr(devattr)->index;
331 unsigned long val;
ba224e2c
JD
332 int iobase = data->address[LD_FAN];
333
0d22d583
JD
334 if (strict_strtoul(buf, 10, &val) < 0)
335 return -EINVAL;
336
ba224e2c
JD
337 mutex_lock(&data->lock);
338 outb(BANK_FM(nr), iobase + PC87427_REG_BANK);
339 /* The low speed limit registers are read-only while monitoring
340 is enabled, so we have to disable monitoring, then change the
341 limit, and finally enable monitoring again. */
342 outb(0, iobase + PC87427_REG_FAN_STATUS);
343 data->fan_min[nr] = fan_to_reg(val);
344 outw(data->fan_min[nr], iobase + PC87427_REG_FAN_MIN);
345 outb(FAN_STATUS_MONEN, iobase + PC87427_REG_FAN_STATUS);
346 mutex_unlock(&data->lock);
347
348 return count;
349}
350
351static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan_input, NULL, 0);
352static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan_input, NULL, 1);
353static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, show_fan_input, NULL, 2);
354static SENSOR_DEVICE_ATTR(fan4_input, S_IRUGO, show_fan_input, NULL, 3);
355static SENSOR_DEVICE_ATTR(fan5_input, S_IRUGO, show_fan_input, NULL, 4);
356static SENSOR_DEVICE_ATTR(fan6_input, S_IRUGO, show_fan_input, NULL, 5);
357static SENSOR_DEVICE_ATTR(fan7_input, S_IRUGO, show_fan_input, NULL, 6);
358static SENSOR_DEVICE_ATTR(fan8_input, S_IRUGO, show_fan_input, NULL, 7);
359
360static SENSOR_DEVICE_ATTR(fan1_min, S_IWUSR | S_IRUGO,
361 show_fan_min, set_fan_min, 0);
362static SENSOR_DEVICE_ATTR(fan2_min, S_IWUSR | S_IRUGO,
363 show_fan_min, set_fan_min, 1);
364static SENSOR_DEVICE_ATTR(fan3_min, S_IWUSR | S_IRUGO,
365 show_fan_min, set_fan_min, 2);
366static SENSOR_DEVICE_ATTR(fan4_min, S_IWUSR | S_IRUGO,
367 show_fan_min, set_fan_min, 3);
368static SENSOR_DEVICE_ATTR(fan5_min, S_IWUSR | S_IRUGO,
369 show_fan_min, set_fan_min, 4);
370static SENSOR_DEVICE_ATTR(fan6_min, S_IWUSR | S_IRUGO,
371 show_fan_min, set_fan_min, 5);
372static SENSOR_DEVICE_ATTR(fan7_min, S_IWUSR | S_IRUGO,
373 show_fan_min, set_fan_min, 6);
374static SENSOR_DEVICE_ATTR(fan8_min, S_IWUSR | S_IRUGO,
375 show_fan_min, set_fan_min, 7);
376
377static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_fan_alarm, NULL, 0);
378static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_fan_alarm, NULL, 1);
379static SENSOR_DEVICE_ATTR(fan3_alarm, S_IRUGO, show_fan_alarm, NULL, 2);
380static SENSOR_DEVICE_ATTR(fan4_alarm, S_IRUGO, show_fan_alarm, NULL, 3);
381static SENSOR_DEVICE_ATTR(fan5_alarm, S_IRUGO, show_fan_alarm, NULL, 4);
382static SENSOR_DEVICE_ATTR(fan6_alarm, S_IRUGO, show_fan_alarm, NULL, 5);
383static SENSOR_DEVICE_ATTR(fan7_alarm, S_IRUGO, show_fan_alarm, NULL, 6);
384static SENSOR_DEVICE_ATTR(fan8_alarm, S_IRUGO, show_fan_alarm, NULL, 7);
385
386static SENSOR_DEVICE_ATTR(fan1_fault, S_IRUGO, show_fan_fault, NULL, 0);
387static SENSOR_DEVICE_ATTR(fan2_fault, S_IRUGO, show_fan_fault, NULL, 1);
388static SENSOR_DEVICE_ATTR(fan3_fault, S_IRUGO, show_fan_fault, NULL, 2);
389static SENSOR_DEVICE_ATTR(fan4_fault, S_IRUGO, show_fan_fault, NULL, 3);
390static SENSOR_DEVICE_ATTR(fan5_fault, S_IRUGO, show_fan_fault, NULL, 4);
391static SENSOR_DEVICE_ATTR(fan6_fault, S_IRUGO, show_fan_fault, NULL, 5);
392static SENSOR_DEVICE_ATTR(fan7_fault, S_IRUGO, show_fan_fault, NULL, 6);
393static SENSOR_DEVICE_ATTR(fan8_fault, S_IRUGO, show_fan_fault, NULL, 7);
394
395static struct attribute *pc87427_attributes_fan[8][5] = {
396 {
397 &sensor_dev_attr_fan1_input.dev_attr.attr,
398 &sensor_dev_attr_fan1_min.dev_attr.attr,
399 &sensor_dev_attr_fan1_alarm.dev_attr.attr,
400 &sensor_dev_attr_fan1_fault.dev_attr.attr,
401 NULL
402 }, {
403 &sensor_dev_attr_fan2_input.dev_attr.attr,
404 &sensor_dev_attr_fan2_min.dev_attr.attr,
405 &sensor_dev_attr_fan2_alarm.dev_attr.attr,
406 &sensor_dev_attr_fan2_fault.dev_attr.attr,
407 NULL
408 }, {
409 &sensor_dev_attr_fan3_input.dev_attr.attr,
410 &sensor_dev_attr_fan3_min.dev_attr.attr,
411 &sensor_dev_attr_fan3_alarm.dev_attr.attr,
412 &sensor_dev_attr_fan3_fault.dev_attr.attr,
413 NULL
414 }, {
415 &sensor_dev_attr_fan4_input.dev_attr.attr,
416 &sensor_dev_attr_fan4_min.dev_attr.attr,
417 &sensor_dev_attr_fan4_alarm.dev_attr.attr,
418 &sensor_dev_attr_fan4_fault.dev_attr.attr,
419 NULL
420 }, {
421 &sensor_dev_attr_fan5_input.dev_attr.attr,
422 &sensor_dev_attr_fan5_min.dev_attr.attr,
423 &sensor_dev_attr_fan5_alarm.dev_attr.attr,
424 &sensor_dev_attr_fan5_fault.dev_attr.attr,
425 NULL
426 }, {
427 &sensor_dev_attr_fan6_input.dev_attr.attr,
428 &sensor_dev_attr_fan6_min.dev_attr.attr,
429 &sensor_dev_attr_fan6_alarm.dev_attr.attr,
430 &sensor_dev_attr_fan6_fault.dev_attr.attr,
431 NULL
432 }, {
433 &sensor_dev_attr_fan7_input.dev_attr.attr,
434 &sensor_dev_attr_fan7_min.dev_attr.attr,
435 &sensor_dev_attr_fan7_alarm.dev_attr.attr,
436 &sensor_dev_attr_fan7_fault.dev_attr.attr,
437 NULL
438 }, {
439 &sensor_dev_attr_fan8_input.dev_attr.attr,
440 &sensor_dev_attr_fan8_min.dev_attr.attr,
441 &sensor_dev_attr_fan8_alarm.dev_attr.attr,
442 &sensor_dev_attr_fan8_fault.dev_attr.attr,
443 NULL
444 }
445};
446
447static const struct attribute_group pc87427_group_fan[8] = {
448 { .attrs = pc87427_attributes_fan[0] },
449 { .attrs = pc87427_attributes_fan[1] },
450 { .attrs = pc87427_attributes_fan[2] },
451 { .attrs = pc87427_attributes_fan[3] },
452 { .attrs = pc87427_attributes_fan[4] },
453 { .attrs = pc87427_attributes_fan[5] },
454 { .attrs = pc87427_attributes_fan[6] },
455 { .attrs = pc87427_attributes_fan[7] },
456};
457
328716bc
JD
458/* Must be called with data->lock held and pc87427_readall_pwm() freshly
459 called */
460static void update_pwm_enable(struct pc87427_data *data, int nr, u8 mode)
461{
462 int iobase = data->address[LD_FAN];
463 data->pwm_enable[nr] &= ~PWM_ENABLE_MODE_MASK;
464 data->pwm_enable[nr] |= mode;
465 outb(data->pwm_enable[nr], iobase + PC87427_REG_PWM_ENABLE);
466}
467
468static ssize_t show_pwm_enable(struct device *dev, struct device_attribute
469 *devattr, char *buf)
470{
471 struct pc87427_data *data = pc87427_update_device(dev);
472 int nr = to_sensor_dev_attr(devattr)->index;
473 int pwm_enable;
474
475 pwm_enable = pwm_enable_from_reg(data->pwm_enable[nr]);
476 if (pwm_enable < 0)
477 return pwm_enable;
478 return sprintf(buf, "%d\n", pwm_enable);
479}
480
481static ssize_t set_pwm_enable(struct device *dev, struct device_attribute
482 *devattr, const char *buf, size_t count)
483{
484 struct pc87427_data *data = dev_get_drvdata(dev);
485 int nr = to_sensor_dev_attr(devattr)->index;
486 unsigned long val;
487
488 if (strict_strtoul(buf, 10, &val) < 0 || val > 2)
489 return -EINVAL;
490 /* Can't go to automatic mode if it isn't configured */
491 if (val == 2 && !(data->pwm_auto_ok & (1 << nr)))
492 return -EINVAL;
493
494 mutex_lock(&data->lock);
495 pc87427_readall_pwm(data, nr);
496 update_pwm_enable(data, nr, pwm_enable_to_reg(val, data->pwm[nr]));
497 mutex_unlock(&data->lock);
498
499 return count;
500}
501
502static ssize_t show_pwm(struct device *dev, struct device_attribute
503 *devattr, char *buf)
504{
505 struct pc87427_data *data = pc87427_update_device(dev);
506 int nr = to_sensor_dev_attr(devattr)->index;
507
508 return sprintf(buf, "%d\n", (int)data->pwm[nr]);
509}
510
511static ssize_t set_pwm(struct device *dev, struct device_attribute
512 *devattr, const char *buf, size_t count)
513{
514 struct pc87427_data *data = dev_get_drvdata(dev);
515 int nr = to_sensor_dev_attr(devattr)->index;
516 unsigned long val;
517 int iobase = data->address[LD_FAN];
518 u8 mode;
519
520 if (strict_strtoul(buf, 10, &val) < 0 || val > 0xff)
521 return -EINVAL;
522
523 mutex_lock(&data->lock);
524 pc87427_readall_pwm(data, nr);
525 mode = data->pwm_enable[nr] & PWM_ENABLE_MODE_MASK;
526 if (mode != PWM_MODE_MANUAL && mode != PWM_MODE_OFF) {
527 dev_notice(dev, "Can't set PWM%d duty cycle while not in "
528 "manual mode\n", nr + 1);
529 mutex_unlock(&data->lock);
530 return -EPERM;
531 }
532
533 /* We may have to change the mode */
534 if (mode == PWM_MODE_MANUAL && val == 0) {
535 /* Transition from Manual to Off */
536 update_pwm_enable(data, nr, PWM_MODE_OFF);
537 mode = PWM_MODE_OFF;
538 dev_dbg(dev, "Switching PWM%d from %s to %s\n", nr + 1,
539 "manual", "off");
540 } else if (mode == PWM_MODE_OFF && val != 0) {
541 /* Transition from Off to Manual */
542 update_pwm_enable(data, nr, PWM_MODE_MANUAL);
543 mode = PWM_MODE_MANUAL;
544 dev_dbg(dev, "Switching PWM%d from %s to %s\n", nr + 1,
545 "off", "manual");
546 }
547
548 data->pwm[nr] = val;
549 if (mode == PWM_MODE_MANUAL)
550 outb(val, iobase + PC87427_REG_PWM_DUTY);
551 mutex_unlock(&data->lock);
552
553 return count;
554}
555
556static SENSOR_DEVICE_ATTR(pwm1_enable, S_IWUSR | S_IRUGO,
557 show_pwm_enable, set_pwm_enable, 0);
558static SENSOR_DEVICE_ATTR(pwm2_enable, S_IWUSR | S_IRUGO,
559 show_pwm_enable, set_pwm_enable, 1);
560static SENSOR_DEVICE_ATTR(pwm3_enable, S_IWUSR | S_IRUGO,
561 show_pwm_enable, set_pwm_enable, 2);
562static SENSOR_DEVICE_ATTR(pwm4_enable, S_IWUSR | S_IRUGO,
563 show_pwm_enable, set_pwm_enable, 3);
564
565static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 0);
566static SENSOR_DEVICE_ATTR(pwm2, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 1);
567static SENSOR_DEVICE_ATTR(pwm3, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 2);
568static SENSOR_DEVICE_ATTR(pwm4, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 3);
569
570static struct attribute *pc87427_attributes_pwm[4][3] = {
571 {
572 &sensor_dev_attr_pwm1_enable.dev_attr.attr,
573 &sensor_dev_attr_pwm1.dev_attr.attr,
574 NULL
575 }, {
576 &sensor_dev_attr_pwm2_enable.dev_attr.attr,
577 &sensor_dev_attr_pwm2.dev_attr.attr,
578 NULL
579 }, {
580 &sensor_dev_attr_pwm3_enable.dev_attr.attr,
581 &sensor_dev_attr_pwm3.dev_attr.attr,
582 NULL
583 }, {
584 &sensor_dev_attr_pwm4_enable.dev_attr.attr,
585 &sensor_dev_attr_pwm4.dev_attr.attr,
586 NULL
587 }
588};
589
590static const struct attribute_group pc87427_group_pwm[4] = {
591 { .attrs = pc87427_attributes_pwm[0] },
592 { .attrs = pc87427_attributes_pwm[1] },
593 { .attrs = pc87427_attributes_pwm[2] },
594 { .attrs = pc87427_attributes_pwm[3] },
595};
596
ba224e2c
JD
597static ssize_t show_name(struct device *dev, struct device_attribute
598 *devattr, char *buf)
599{
600 struct pc87427_data *data = dev_get_drvdata(dev);
601
602 return sprintf(buf, "%s\n", data->name);
603}
604static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
605
606
607/*
608 * Device detection, attach and detach
609 */
610
611static void __devinit pc87427_init_device(struct device *dev)
612{
4e7d99e1 613 struct pc87427_sio_data *sio_data = dev->platform_data;
ba224e2c
JD
614 struct pc87427_data *data = dev_get_drvdata(dev);
615 int i;
616 u8 reg;
617
618 /* The FMC module should be ready */
619 reg = pc87427_read8(data, LD_FAN, PC87427_REG_BANK);
620 if (!(reg & 0x80))
621 dev_warn(dev, "FMC module not ready!\n");
622
623 /* Check which fans are enabled */
624 for (i = 0; i < 8; i++) {
4e7d99e1
JD
625 if (!(sio_data->has_fanin & (1 << i))) /* Not wired */
626 continue;
ba224e2c
JD
627 reg = pc87427_read8_bank(data, LD_FAN, BANK_FM(i),
628 PC87427_REG_FAN_STATUS);
629 if (reg & FAN_STATUS_MONEN)
630 data->fan_enabled |= (1 << i);
631 }
632
633 if (!data->fan_enabled) {
4e7d99e1
JD
634 dev_dbg(dev, "Enabling monitoring of all fans\n");
635 for (i = 0; i < 8; i++) {
636 if (!(sio_data->has_fanin & (1 << i))) /* Not wired */
637 continue;
ba224e2c
JD
638 pc87427_write8_bank(data, LD_FAN, BANK_FM(i),
639 PC87427_REG_FAN_STATUS,
640 FAN_STATUS_MONEN);
4e7d99e1
JD
641 }
642 data->fan_enabled = sio_data->has_fanin;
ba224e2c 643 }
328716bc
JD
644
645 /* Check which PWM outputs are enabled */
646 for (i = 0; i < 4; i++) {
647 if (!(sio_data->has_fanout & (1 << i))) /* Not wired */
648 continue;
649 reg = pc87427_read8_bank(data, LD_FAN, BANK_FC(i),
650 PC87427_REG_PWM_ENABLE);
651 if (reg & PWM_ENABLE_CTLEN)
652 data->pwm_enabled |= (1 << i);
653
654 /* We don't expose an interface to reconfigure the automatic
655 fan control mode, so only allow to return to this mode if
656 it was originally set. */
657 if ((reg & PWM_ENABLE_MODE_MASK) == PWM_MODE_AUTO) {
658 dev_dbg(dev, "PWM%d is in automatic control mode\n",
659 i + 1);
660 data->pwm_auto_ok |= (1 << i);
661 }
662 }
ba224e2c
JD
663}
664
665static int __devinit pc87427_probe(struct platform_device *pdev)
666{
667 struct pc87427_data *data;
668 struct resource *res;
669 int i, err;
670
0d22d583
JD
671 data = kzalloc(sizeof(struct pc87427_data), GFP_KERNEL);
672 if (!data) {
ba224e2c
JD
673 err = -ENOMEM;
674 printk(KERN_ERR DRVNAME ": Out of memory\n");
675 goto exit;
676 }
677
678 /* This will need to be revisited when we add support for
679 temperature and voltage monitoring. */
680 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
86855b0c 681 if (!request_region(res->start, resource_size(res), DRVNAME)) {
ce7ee4e8
JD
682 err = -EBUSY;
683 dev_err(&pdev->dev, "Failed to request region 0x%lx-0x%lx\n",
684 (unsigned long)res->start, (unsigned long)res->end);
685 goto exit_kfree;
686 }
ba224e2c
JD
687 data->address[0] = res->start;
688
689 mutex_init(&data->lock);
690 data->name = "pc87427";
691 platform_set_drvdata(pdev, data);
692 pc87427_init_device(&pdev->dev);
693
694 /* Register sysfs hooks */
0d22d583
JD
695 err = device_create_file(&pdev->dev, &dev_attr_name);
696 if (err)
ce7ee4e8 697 goto exit_release_region;
ba224e2c
JD
698 for (i = 0; i < 8; i++) {
699 if (!(data->fan_enabled & (1 << i)))
700 continue;
0d22d583
JD
701 err = sysfs_create_group(&pdev->dev.kobj,
702 &pc87427_group_fan[i]);
703 if (err)
ba224e2c
JD
704 goto exit_remove_files;
705 }
328716bc
JD
706 for (i = 0; i < 4; i++) {
707 if (!(data->pwm_enabled & (1 << i)))
708 continue;
709 err = sysfs_create_group(&pdev->dev.kobj,
710 &pc87427_group_pwm[i]);
711 if (err)
712 goto exit_remove_files;
713 }
ba224e2c 714
1beeffe4
TJ
715 data->hwmon_dev = hwmon_device_register(&pdev->dev);
716 if (IS_ERR(data->hwmon_dev)) {
717 err = PTR_ERR(data->hwmon_dev);
ba224e2c
JD
718 dev_err(&pdev->dev, "Class registration failed (%d)\n", err);
719 goto exit_remove_files;
720 }
721
722 return 0;
723
724exit_remove_files:
725 for (i = 0; i < 8; i++) {
726 if (!(data->fan_enabled & (1 << i)))
727 continue;
728 sysfs_remove_group(&pdev->dev.kobj, &pc87427_group_fan[i]);
729 }
328716bc
JD
730 for (i = 0; i < 4; i++) {
731 if (!(data->pwm_enabled & (1 << i)))
732 continue;
733 sysfs_remove_group(&pdev->dev.kobj, &pc87427_group_pwm[i]);
734 }
ce7ee4e8 735exit_release_region:
86855b0c 736 release_region(res->start, resource_size(res));
ba224e2c
JD
737exit_kfree:
738 platform_set_drvdata(pdev, NULL);
739 kfree(data);
740exit:
741 return err;
742}
743
744static int __devexit pc87427_remove(struct platform_device *pdev)
745{
746 struct pc87427_data *data = platform_get_drvdata(pdev);
ce7ee4e8 747 struct resource *res;
ba224e2c
JD
748 int i;
749
1beeffe4 750 hwmon_device_unregister(data->hwmon_dev);
ba224e2c
JD
751 device_remove_file(&pdev->dev, &dev_attr_name);
752 for (i = 0; i < 8; i++) {
753 if (!(data->fan_enabled & (1 << i)))
754 continue;
755 sysfs_remove_group(&pdev->dev.kobj, &pc87427_group_fan[i]);
756 }
328716bc
JD
757 for (i = 0; i < 4; i++) {
758 if (!(data->pwm_enabled & (1 << i)))
759 continue;
760 sysfs_remove_group(&pdev->dev.kobj, &pc87427_group_pwm[i]);
761 }
04a6217d 762 platform_set_drvdata(pdev, NULL);
ba224e2c
JD
763 kfree(data);
764
ce7ee4e8 765 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
86855b0c 766 release_region(res->start, resource_size(res));
ce7ee4e8 767
ba224e2c
JD
768 return 0;
769}
770
771
772static struct platform_driver pc87427_driver = {
773 .driver = {
774 .owner = THIS_MODULE,
775 .name = DRVNAME,
776 },
777 .probe = pc87427_probe,
778 .remove = __devexit_p(pc87427_remove),
779};
780
4e7d99e1
JD
781static int __init pc87427_device_add(unsigned short address,
782 const struct pc87427_sio_data *sio_data)
ba224e2c
JD
783{
784 struct resource res = {
785 .start = address,
786 .end = address + REGION_LENGTH - 1,
787 .name = logdev_str[0],
788 .flags = IORESOURCE_IO,
789 };
790 int err;
791
b9acb64a
JD
792 err = acpi_check_resource_conflict(&res);
793 if (err)
794 goto exit;
795
ba224e2c
JD
796 pdev = platform_device_alloc(DRVNAME, address);
797 if (!pdev) {
798 err = -ENOMEM;
799 printk(KERN_ERR DRVNAME ": Device allocation failed\n");
800 goto exit;
801 }
802
803 err = platform_device_add_resources(pdev, &res, 1);
804 if (err) {
805 printk(KERN_ERR DRVNAME ": Device resource addition failed "
806 "(%d)\n", err);
807 goto exit_device_put;
808 }
809
4e7d99e1
JD
810 err = platform_device_add_data(pdev, sio_data,
811 sizeof(struct pc87427_sio_data));
812 if (err) {
813 printk(KERN_ERR DRVNAME ": Platform data allocation failed\n");
814 goto exit_device_put;
815 }
816
ba224e2c
JD
817 err = platform_device_add(pdev);
818 if (err) {
819 printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n",
820 err);
821 goto exit_device_put;
822 }
823
824 return 0;
825
826exit_device_put:
827 platform_device_put(pdev);
828exit:
829 return err;
830}
831
4e7d99e1
JD
832static int __init pc87427_find(int sioaddr, unsigned short *address,
833 struct pc87427_sio_data *sio_data)
ba224e2c
JD
834{
835 u16 val;
4e7d99e1 836 u8 cfg, cfg_b;
ba224e2c
JD
837 int i, err = 0;
838
839 /* Identify device */
67b671bc 840 val = force_id ? force_id : superio_inb(sioaddr, SIOREG_DEVID);
ba224e2c
JD
841 if (val != 0xf2) { /* PC87427 */
842 err = -ENODEV;
843 goto exit;
844 }
845
846 for (i = 0; i < 2; i++) {
847 address[i] = 0;
848 /* Select logical device */
849 superio_outb(sioaddr, SIOREG_LDSEL, logdev[i]);
850
851 val = superio_inb(sioaddr, SIOREG_ACT);
852 if (!(val & 0x01)) {
853 printk(KERN_INFO DRVNAME ": Logical device 0x%02x "
854 "not activated\n", logdev[i]);
855 continue;
856 }
857
858 val = superio_inb(sioaddr, SIOREG_MAP);
859 if (val & 0x01) {
860 printk(KERN_WARNING DRVNAME ": Logical device 0x%02x "
861 "is memory-mapped, can't use\n", logdev[i]);
862 continue;
863 }
864
865 val = (superio_inb(sioaddr, SIOREG_IOBASE) << 8)
866 | superio_inb(sioaddr, SIOREG_IOBASE + 1);
867 if (!val) {
868 printk(KERN_INFO DRVNAME ": I/O base address not set "
869 "for logical device 0x%02x\n", logdev[i]);
870 continue;
871 }
872 address[i] = val;
873 }
874
4e7d99e1
JD
875 /* Check which fan inputs are wired */
876 sio_data->has_fanin = (1 << 2) | (1 << 3); /* FANIN2, FANIN3 */
877
878 cfg = superio_inb(sioaddr, SIOREG_CF2);
879 if (!(cfg & (1 << 3)))
880 sio_data->has_fanin |= (1 << 0); /* FANIN0 */
881 if (!(cfg & (1 << 2)))
882 sio_data->has_fanin |= (1 << 4); /* FANIN4 */
883
884 cfg = superio_inb(sioaddr, SIOREG_CFD);
885 if (!(cfg & (1 << 0)))
886 sio_data->has_fanin |= (1 << 1); /* FANIN1 */
887
888 cfg = superio_inb(sioaddr, SIOREG_CF4);
889 if (!(cfg & (1 << 0)))
890 sio_data->has_fanin |= (1 << 7); /* FANIN7 */
891 cfg_b = superio_inb(sioaddr, SIOREG_CFB);
892 if (!(cfg & (1 << 1)) && (cfg_b & (1 << 3)))
893 sio_data->has_fanin |= (1 << 5); /* FANIN5 */
894 cfg = superio_inb(sioaddr, SIOREG_CF3);
895 if ((cfg & (1 << 3)) && !(cfg_b & (1 << 5)))
896 sio_data->has_fanin |= (1 << 6); /* FANIN6 */
897
328716bc
JD
898 /* Check which fan outputs are wired */
899 sio_data->has_fanout = (1 << 0); /* FANOUT0 */
900 if (cfg_b & (1 << 0))
901 sio_data->has_fanout |= (1 << 3); /* FANOUT3 */
902
903 cfg = superio_inb(sioaddr, SIOREG_CFC);
904 if (!(cfg & (1 << 4))) {
905 if (cfg_b & (1 << 1))
906 sio_data->has_fanout |= (1 << 1); /* FANOUT1 */
907 if (cfg_b & (1 << 2))
908 sio_data->has_fanout |= (1 << 2); /* FANOUT2 */
909 }
910
911 /* FANOUT1 and FANOUT2 can each be routed to 2 different pins */
912 cfg = superio_inb(sioaddr, SIOREG_CF5);
913 if (cfg & (1 << 6))
914 sio_data->has_fanout |= (1 << 1); /* FANOUT1 */
915 if (cfg & (1 << 5))
916 sio_data->has_fanout |= (1 << 2); /* FANOUT2 */
917
ba224e2c
JD
918exit:
919 superio_exit(sioaddr);
920 return err;
921}
922
923static int __init pc87427_init(void)
924{
925 int err;
926 unsigned short address[2];
4e7d99e1 927 struct pc87427_sio_data sio_data;
ba224e2c 928
4e7d99e1
JD
929 if (pc87427_find(0x2e, address, &sio_data)
930 && pc87427_find(0x4e, address, &sio_data))
ba224e2c
JD
931 return -ENODEV;
932
933 /* For now the driver only handles fans so we only care about the
934 first address. */
935 if (!address[0])
936 return -ENODEV;
937
938 err = platform_driver_register(&pc87427_driver);
939 if (err)
940 goto exit;
941
942 /* Sets global pdev as a side effect */
4e7d99e1 943 err = pc87427_device_add(address[0], &sio_data);
ba224e2c
JD
944 if (err)
945 goto exit_driver;
946
947 return 0;
948
949exit_driver:
950 platform_driver_unregister(&pc87427_driver);
951exit:
952 return err;
953}
954
955static void __exit pc87427_exit(void)
956{
957 platform_device_unregister(pdev);
958 platform_driver_unregister(&pc87427_driver);
959}
960
961MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
962MODULE_DESCRIPTION("PC87427 hardware monitoring driver");
963MODULE_LICENSE("GPL");
964
965module_init(pc87427_init);
966module_exit(pc87427_exit);