2 * pc87427.c - hardware monitoring driver for the
3 * National Semiconductor PC87427 Super-I/O chip
4 * Copyright (C) 2006 Jean Delvare <khali@linux-fr.org>
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.
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.
15 * Supports the following chips:
17 * Chip #vin #fan #pwm #temp devid
18 * PC87427 - 8 - - 0xF2
20 * This driver assumes that no more than one chip is present.
21 * Only fan inputs are supported so far, although the chip can do much more.
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>
34 #include <linux/ioport.h>
37 static unsigned short force_id
;
38 module_param(force_id
, ushort
, 0);
39 MODULE_PARM_DESC(force_id
, "Override the detected device ID");
41 static struct platform_device
*pdev
;
43 #define DRVNAME "pc87427"
45 /* The lock mutex protects both the I/O accesses (needed because the
46 device is using banked registers) and the register cache (needed to keep
47 the data in the registers and the cache in sync at any time). */
49 struct device
*hwmon_dev
;
54 unsigned long last_updated
; /* in jiffies */
55 u8 fan_enabled
; /* bit vector */
56 u16 fan
[8]; /* register values */
57 u16 fan_min
[8]; /* register values */
58 u8 fan_status
[8]; /* register values */
62 * Super-I/O registers and operations
65 #define SIOREG_LDSEL 0x07 /* Logical device select */
66 #define SIOREG_DEVID 0x20 /* Device ID */
67 #define SIOREG_ACT 0x30 /* Device activation */
68 #define SIOREG_MAP 0x50 /* I/O or memory mapping */
69 #define SIOREG_IOBASE 0x60 /* I/O base address */
71 static const u8 logdev
[2] = { 0x09, 0x14 };
72 static const char *logdev_str
[2] = { DRVNAME
" FMC", DRVNAME
" HMC" };
77 static inline void superio_outb(int sioaddr
, int reg
, int val
)
80 outb(val
, sioaddr
+ 1);
83 static inline int superio_inb(int sioaddr
, int reg
)
86 return inb(sioaddr
+ 1);
89 static inline void superio_exit(int sioaddr
)
92 outb(0x02, sioaddr
+ 1);
99 #define REGION_LENGTH 32
100 #define PC87427_REG_BANK 0x0f
101 #define BANK_FM(nr) (nr)
102 #define BANK_FT(nr) (0x08 + (nr))
103 #define BANK_FC(nr) (0x10 + (nr) * 2)
106 * I/O access functions
109 /* ldi is the logical device index */
110 static inline int pc87427_read8(struct pc87427_data
*data
, u8 ldi
, u8 reg
)
112 return inb(data
->address
[ldi
] + reg
);
115 /* Must be called with data->lock held, except during init */
116 static inline int pc87427_read8_bank(struct pc87427_data
*data
, u8 ldi
,
119 outb(bank
, data
->address
[ldi
] + PC87427_REG_BANK
);
120 return inb(data
->address
[ldi
] + reg
);
123 /* Must be called with data->lock held, except during init */
124 static inline void pc87427_write8_bank(struct pc87427_data
*data
, u8 ldi
,
125 u8 bank
, u8 reg
, u8 value
)
127 outb(bank
, data
->address
[ldi
] + PC87427_REG_BANK
);
128 outb(value
, data
->address
[ldi
] + reg
);
132 * Fan registers and conversions
135 /* fan data registers are 16-bit wide */
136 #define PC87427_REG_FAN 0x12
137 #define PC87427_REG_FAN_MIN 0x14
138 #define PC87427_REG_FAN_STATUS 0x10
140 #define FAN_STATUS_STALL (1 << 3)
141 #define FAN_STATUS_LOSPD (1 << 1)
142 #define FAN_STATUS_MONEN (1 << 0)
144 /* Dedicated function to read all registers related to a given fan input.
145 This saves us quite a few locks and bank selections.
146 Must be called with data->lock held.
148 static void pc87427_readall_fan(struct pc87427_data
*data
, u8 nr
)
150 int iobase
= data
->address
[LD_FAN
];
152 outb(BANK_FM(nr
), iobase
+ PC87427_REG_BANK
);
153 data
->fan
[nr
] = inw(iobase
+ PC87427_REG_FAN
);
154 data
->fan_min
[nr
] = inw(iobase
+ PC87427_REG_FAN_MIN
);
155 data
->fan_status
[nr
] = inb(iobase
+ PC87427_REG_FAN_STATUS
);
156 /* Clear fan alarm bits */
157 outb(data
->fan_status
[nr
], iobase
+ PC87427_REG_FAN_STATUS
);
160 /* The 2 LSB of fan speed registers are used for something different.
161 The actual 2 LSB of the measurements are not available. */
162 static inline unsigned long fan_from_reg(u16 reg
)
165 if (reg
== 0x0000 || reg
== 0xfffc)
167 return 5400000UL / reg
;
170 /* The 2 LSB of the fan speed limit registers are not significant. */
171 static inline u16
fan_to_reg(unsigned long val
)
175 if (val
>= 1350000UL)
177 return ((1350000UL + val
/ 2) / val
) << 2;
184 static struct pc87427_data
*pc87427_update_device(struct device
*dev
)
186 struct pc87427_data
*data
= dev_get_drvdata(dev
);
189 mutex_lock(&data
->lock
);
190 if (!time_after(jiffies
, data
->last_updated
+ HZ
)
191 && data
->last_updated
)
195 for (i
= 0; i
< 8; i
++) {
196 if (!(data
->fan_enabled
& (1 << i
)))
198 pc87427_readall_fan(data
, i
);
200 data
->last_updated
= jiffies
;
203 mutex_unlock(&data
->lock
);
207 static ssize_t
show_fan_input(struct device
*dev
, struct device_attribute
210 struct sensor_device_attribute
*attr
= to_sensor_dev_attr(devattr
);
211 struct pc87427_data
*data
= pc87427_update_device(dev
);
212 int nr
= attr
->index
;
214 return sprintf(buf
, "%lu\n", fan_from_reg(data
->fan
[nr
]));
217 static ssize_t
show_fan_min(struct device
*dev
, struct device_attribute
220 struct sensor_device_attribute
*attr
= to_sensor_dev_attr(devattr
);
221 struct pc87427_data
*data
= pc87427_update_device(dev
);
222 int nr
= attr
->index
;
224 return sprintf(buf
, "%lu\n", fan_from_reg(data
->fan_min
[nr
]));
227 static ssize_t
show_fan_alarm(struct device
*dev
, struct device_attribute
230 struct sensor_device_attribute
*attr
= to_sensor_dev_attr(devattr
);
231 struct pc87427_data
*data
= pc87427_update_device(dev
);
232 int nr
= attr
->index
;
234 return sprintf(buf
, "%d\n", !!(data
->fan_status
[nr
]
235 & FAN_STATUS_LOSPD
));
238 static ssize_t
show_fan_fault(struct device
*dev
, struct device_attribute
241 struct sensor_device_attribute
*attr
= to_sensor_dev_attr(devattr
);
242 struct pc87427_data
*data
= pc87427_update_device(dev
);
243 int nr
= attr
->index
;
245 return sprintf(buf
, "%d\n", !!(data
->fan_status
[nr
]
246 & FAN_STATUS_STALL
));
249 static ssize_t
set_fan_min(struct device
*dev
, struct device_attribute
250 *devattr
, const char *buf
, size_t count
)
252 struct pc87427_data
*data
= dev_get_drvdata(dev
);
253 struct sensor_device_attribute
*attr
= to_sensor_dev_attr(devattr
);
254 int nr
= attr
->index
;
255 unsigned long val
= simple_strtoul(buf
, NULL
, 10);
256 int iobase
= data
->address
[LD_FAN
];
258 mutex_lock(&data
->lock
);
259 outb(BANK_FM(nr
), iobase
+ PC87427_REG_BANK
);
260 /* The low speed limit registers are read-only while monitoring
261 is enabled, so we have to disable monitoring, then change the
262 limit, and finally enable monitoring again. */
263 outb(0, iobase
+ PC87427_REG_FAN_STATUS
);
264 data
->fan_min
[nr
] = fan_to_reg(val
);
265 outw(data
->fan_min
[nr
], iobase
+ PC87427_REG_FAN_MIN
);
266 outb(FAN_STATUS_MONEN
, iobase
+ PC87427_REG_FAN_STATUS
);
267 mutex_unlock(&data
->lock
);
272 static SENSOR_DEVICE_ATTR(fan1_input
, S_IRUGO
, show_fan_input
, NULL
, 0);
273 static SENSOR_DEVICE_ATTR(fan2_input
, S_IRUGO
, show_fan_input
, NULL
, 1);
274 static SENSOR_DEVICE_ATTR(fan3_input
, S_IRUGO
, show_fan_input
, NULL
, 2);
275 static SENSOR_DEVICE_ATTR(fan4_input
, S_IRUGO
, show_fan_input
, NULL
, 3);
276 static SENSOR_DEVICE_ATTR(fan5_input
, S_IRUGO
, show_fan_input
, NULL
, 4);
277 static SENSOR_DEVICE_ATTR(fan6_input
, S_IRUGO
, show_fan_input
, NULL
, 5);
278 static SENSOR_DEVICE_ATTR(fan7_input
, S_IRUGO
, show_fan_input
, NULL
, 6);
279 static SENSOR_DEVICE_ATTR(fan8_input
, S_IRUGO
, show_fan_input
, NULL
, 7);
281 static SENSOR_DEVICE_ATTR(fan1_min
, S_IWUSR
| S_IRUGO
,
282 show_fan_min
, set_fan_min
, 0);
283 static SENSOR_DEVICE_ATTR(fan2_min
, S_IWUSR
| S_IRUGO
,
284 show_fan_min
, set_fan_min
, 1);
285 static SENSOR_DEVICE_ATTR(fan3_min
, S_IWUSR
| S_IRUGO
,
286 show_fan_min
, set_fan_min
, 2);
287 static SENSOR_DEVICE_ATTR(fan4_min
, S_IWUSR
| S_IRUGO
,
288 show_fan_min
, set_fan_min
, 3);
289 static SENSOR_DEVICE_ATTR(fan5_min
, S_IWUSR
| S_IRUGO
,
290 show_fan_min
, set_fan_min
, 4);
291 static SENSOR_DEVICE_ATTR(fan6_min
, S_IWUSR
| S_IRUGO
,
292 show_fan_min
, set_fan_min
, 5);
293 static SENSOR_DEVICE_ATTR(fan7_min
, S_IWUSR
| S_IRUGO
,
294 show_fan_min
, set_fan_min
, 6);
295 static SENSOR_DEVICE_ATTR(fan8_min
, S_IWUSR
| S_IRUGO
,
296 show_fan_min
, set_fan_min
, 7);
298 static SENSOR_DEVICE_ATTR(fan1_alarm
, S_IRUGO
, show_fan_alarm
, NULL
, 0);
299 static SENSOR_DEVICE_ATTR(fan2_alarm
, S_IRUGO
, show_fan_alarm
, NULL
, 1);
300 static SENSOR_DEVICE_ATTR(fan3_alarm
, S_IRUGO
, show_fan_alarm
, NULL
, 2);
301 static SENSOR_DEVICE_ATTR(fan4_alarm
, S_IRUGO
, show_fan_alarm
, NULL
, 3);
302 static SENSOR_DEVICE_ATTR(fan5_alarm
, S_IRUGO
, show_fan_alarm
, NULL
, 4);
303 static SENSOR_DEVICE_ATTR(fan6_alarm
, S_IRUGO
, show_fan_alarm
, NULL
, 5);
304 static SENSOR_DEVICE_ATTR(fan7_alarm
, S_IRUGO
, show_fan_alarm
, NULL
, 6);
305 static SENSOR_DEVICE_ATTR(fan8_alarm
, S_IRUGO
, show_fan_alarm
, NULL
, 7);
307 static SENSOR_DEVICE_ATTR(fan1_fault
, S_IRUGO
, show_fan_fault
, NULL
, 0);
308 static SENSOR_DEVICE_ATTR(fan2_fault
, S_IRUGO
, show_fan_fault
, NULL
, 1);
309 static SENSOR_DEVICE_ATTR(fan3_fault
, S_IRUGO
, show_fan_fault
, NULL
, 2);
310 static SENSOR_DEVICE_ATTR(fan4_fault
, S_IRUGO
, show_fan_fault
, NULL
, 3);
311 static SENSOR_DEVICE_ATTR(fan5_fault
, S_IRUGO
, show_fan_fault
, NULL
, 4);
312 static SENSOR_DEVICE_ATTR(fan6_fault
, S_IRUGO
, show_fan_fault
, NULL
, 5);
313 static SENSOR_DEVICE_ATTR(fan7_fault
, S_IRUGO
, show_fan_fault
, NULL
, 6);
314 static SENSOR_DEVICE_ATTR(fan8_fault
, S_IRUGO
, show_fan_fault
, NULL
, 7);
316 static struct attribute
*pc87427_attributes_fan
[8][5] = {
318 &sensor_dev_attr_fan1_input
.dev_attr
.attr
,
319 &sensor_dev_attr_fan1_min
.dev_attr
.attr
,
320 &sensor_dev_attr_fan1_alarm
.dev_attr
.attr
,
321 &sensor_dev_attr_fan1_fault
.dev_attr
.attr
,
324 &sensor_dev_attr_fan2_input
.dev_attr
.attr
,
325 &sensor_dev_attr_fan2_min
.dev_attr
.attr
,
326 &sensor_dev_attr_fan2_alarm
.dev_attr
.attr
,
327 &sensor_dev_attr_fan2_fault
.dev_attr
.attr
,
330 &sensor_dev_attr_fan3_input
.dev_attr
.attr
,
331 &sensor_dev_attr_fan3_min
.dev_attr
.attr
,
332 &sensor_dev_attr_fan3_alarm
.dev_attr
.attr
,
333 &sensor_dev_attr_fan3_fault
.dev_attr
.attr
,
336 &sensor_dev_attr_fan4_input
.dev_attr
.attr
,
337 &sensor_dev_attr_fan4_min
.dev_attr
.attr
,
338 &sensor_dev_attr_fan4_alarm
.dev_attr
.attr
,
339 &sensor_dev_attr_fan4_fault
.dev_attr
.attr
,
342 &sensor_dev_attr_fan5_input
.dev_attr
.attr
,
343 &sensor_dev_attr_fan5_min
.dev_attr
.attr
,
344 &sensor_dev_attr_fan5_alarm
.dev_attr
.attr
,
345 &sensor_dev_attr_fan5_fault
.dev_attr
.attr
,
348 &sensor_dev_attr_fan6_input
.dev_attr
.attr
,
349 &sensor_dev_attr_fan6_min
.dev_attr
.attr
,
350 &sensor_dev_attr_fan6_alarm
.dev_attr
.attr
,
351 &sensor_dev_attr_fan6_fault
.dev_attr
.attr
,
354 &sensor_dev_attr_fan7_input
.dev_attr
.attr
,
355 &sensor_dev_attr_fan7_min
.dev_attr
.attr
,
356 &sensor_dev_attr_fan7_alarm
.dev_attr
.attr
,
357 &sensor_dev_attr_fan7_fault
.dev_attr
.attr
,
360 &sensor_dev_attr_fan8_input
.dev_attr
.attr
,
361 &sensor_dev_attr_fan8_min
.dev_attr
.attr
,
362 &sensor_dev_attr_fan8_alarm
.dev_attr
.attr
,
363 &sensor_dev_attr_fan8_fault
.dev_attr
.attr
,
368 static const struct attribute_group pc87427_group_fan
[8] = {
369 { .attrs
= pc87427_attributes_fan
[0] },
370 { .attrs
= pc87427_attributes_fan
[1] },
371 { .attrs
= pc87427_attributes_fan
[2] },
372 { .attrs
= pc87427_attributes_fan
[3] },
373 { .attrs
= pc87427_attributes_fan
[4] },
374 { .attrs
= pc87427_attributes_fan
[5] },
375 { .attrs
= pc87427_attributes_fan
[6] },
376 { .attrs
= pc87427_attributes_fan
[7] },
379 static ssize_t
show_name(struct device
*dev
, struct device_attribute
382 struct pc87427_data
*data
= dev_get_drvdata(dev
);
384 return sprintf(buf
, "%s\n", data
->name
);
386 static DEVICE_ATTR(name
, S_IRUGO
, show_name
, NULL
);
390 * Device detection, attach and detach
393 static void __devinit
pc87427_init_device(struct device
*dev
)
395 struct pc87427_data
*data
= dev_get_drvdata(dev
);
399 /* The FMC module should be ready */
400 reg
= pc87427_read8(data
, LD_FAN
, PC87427_REG_BANK
);
402 dev_warn(dev
, "FMC module not ready!\n");
404 /* Check which fans are enabled */
405 for (i
= 0; i
< 8; i
++) {
406 reg
= pc87427_read8_bank(data
, LD_FAN
, BANK_FM(i
),
407 PC87427_REG_FAN_STATUS
);
408 if (reg
& FAN_STATUS_MONEN
)
409 data
->fan_enabled
|= (1 << i
);
412 if (!data
->fan_enabled
) {
413 dev_dbg(dev
, "Enabling all fan inputs\n");
414 for (i
= 0; i
< 8; i
++)
415 pc87427_write8_bank(data
, LD_FAN
, BANK_FM(i
),
416 PC87427_REG_FAN_STATUS
,
418 data
->fan_enabled
= 0xff;
422 static int __devinit
pc87427_probe(struct platform_device
*pdev
)
424 struct pc87427_data
*data
;
425 struct resource
*res
;
428 if (!(data
= kzalloc(sizeof(struct pc87427_data
), GFP_KERNEL
))) {
430 printk(KERN_ERR DRVNAME
": Out of memory\n");
434 /* This will need to be revisited when we add support for
435 temperature and voltage monitoring. */
436 res
= platform_get_resource(pdev
, IORESOURCE_IO
, 0);
437 if (!request_region(res
->start
, res
->end
- res
->start
+ 1, DRVNAME
)) {
439 dev_err(&pdev
->dev
, "Failed to request region 0x%lx-0x%lx\n",
440 (unsigned long)res
->start
, (unsigned long)res
->end
);
443 data
->address
[0] = res
->start
;
445 mutex_init(&data
->lock
);
446 data
->name
= "pc87427";
447 platform_set_drvdata(pdev
, data
);
448 pc87427_init_device(&pdev
->dev
);
450 /* Register sysfs hooks */
451 if ((err
= device_create_file(&pdev
->dev
, &dev_attr_name
)))
452 goto exit_release_region
;
453 for (i
= 0; i
< 8; i
++) {
454 if (!(data
->fan_enabled
& (1 << i
)))
456 if ((err
= sysfs_create_group(&pdev
->dev
.kobj
,
457 &pc87427_group_fan
[i
])))
458 goto exit_remove_files
;
461 data
->hwmon_dev
= hwmon_device_register(&pdev
->dev
);
462 if (IS_ERR(data
->hwmon_dev
)) {
463 err
= PTR_ERR(data
->hwmon_dev
);
464 dev_err(&pdev
->dev
, "Class registration failed (%d)\n", err
);
465 goto exit_remove_files
;
471 for (i
= 0; i
< 8; i
++) {
472 if (!(data
->fan_enabled
& (1 << i
)))
474 sysfs_remove_group(&pdev
->dev
.kobj
, &pc87427_group_fan
[i
]);
477 release_region(res
->start
, res
->end
- res
->start
+ 1);
479 platform_set_drvdata(pdev
, NULL
);
485 static int __devexit
pc87427_remove(struct platform_device
*pdev
)
487 struct pc87427_data
*data
= platform_get_drvdata(pdev
);
488 struct resource
*res
;
491 hwmon_device_unregister(data
->hwmon_dev
);
492 device_remove_file(&pdev
->dev
, &dev_attr_name
);
493 for (i
= 0; i
< 8; i
++) {
494 if (!(data
->fan_enabled
& (1 << i
)))
496 sysfs_remove_group(&pdev
->dev
.kobj
, &pc87427_group_fan
[i
]);
498 platform_set_drvdata(pdev
, NULL
);
501 res
= platform_get_resource(pdev
, IORESOURCE_IO
, 0);
502 release_region(res
->start
, res
->end
- res
->start
+ 1);
508 static struct platform_driver pc87427_driver
= {
510 .owner
= THIS_MODULE
,
513 .probe
= pc87427_probe
,
514 .remove
= __devexit_p(pc87427_remove
),
517 static int __init
pc87427_device_add(unsigned short address
)
519 struct resource res
= {
521 .end
= address
+ REGION_LENGTH
- 1,
522 .name
= logdev_str
[0],
523 .flags
= IORESOURCE_IO
,
527 pdev
= platform_device_alloc(DRVNAME
, address
);
530 printk(KERN_ERR DRVNAME
": Device allocation failed\n");
534 err
= platform_device_add_resources(pdev
, &res
, 1);
536 printk(KERN_ERR DRVNAME
": Device resource addition failed "
538 goto exit_device_put
;
541 err
= platform_device_add(pdev
);
543 printk(KERN_ERR DRVNAME
": Device addition failed (%d)\n",
545 goto exit_device_put
;
551 platform_device_put(pdev
);
556 static int __init
pc87427_find(int sioaddr
, unsigned short *address
)
561 /* Identify device */
562 val
= force_id
? force_id
: superio_inb(sioaddr
, SIOREG_DEVID
);
563 if (val
!= 0xf2) { /* PC87427 */
568 for (i
= 0; i
< 2; i
++) {
570 /* Select logical device */
571 superio_outb(sioaddr
, SIOREG_LDSEL
, logdev
[i
]);
573 val
= superio_inb(sioaddr
, SIOREG_ACT
);
575 printk(KERN_INFO DRVNAME
": Logical device 0x%02x "
576 "not activated\n", logdev
[i
]);
580 val
= superio_inb(sioaddr
, SIOREG_MAP
);
582 printk(KERN_WARNING DRVNAME
": Logical device 0x%02x "
583 "is memory-mapped, can't use\n", logdev
[i
]);
587 val
= (superio_inb(sioaddr
, SIOREG_IOBASE
) << 8)
588 | superio_inb(sioaddr
, SIOREG_IOBASE
+ 1);
590 printk(KERN_INFO DRVNAME
": I/O base address not set "
591 "for logical device 0x%02x\n", logdev
[i
]);
598 superio_exit(sioaddr
);
602 static int __init
pc87427_init(void)
605 unsigned short address
[2];
607 if (pc87427_find(0x2e, address
)
608 && pc87427_find(0x4e, address
))
611 /* For now the driver only handles fans so we only care about the
616 err
= platform_driver_register(&pc87427_driver
);
620 /* Sets global pdev as a side effect */
621 err
= pc87427_device_add(address
[0]);
628 platform_driver_unregister(&pc87427_driver
);
633 static void __exit
pc87427_exit(void)
635 platform_device_unregister(pdev
);
636 platform_driver_unregister(&pc87427_driver
);
639 MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
640 MODULE_DESCRIPTION("PC87427 hardware monitoring driver");
641 MODULE_LICENSE("GPL");
643 module_init(pc87427_init
);
644 module_exit(pc87427_exit
);