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 struct platform_device *pdev;
39 #define DRVNAME "pc87427"
41 /* The lock mutex protects both the I/O accesses (needed because the
42 device is using banked registers) and the register cache (needed to keep
43 the data in the registers and the cache in sync at any time). */
45 struct device *hwmon_dev;
50 unsigned long last_updated; /* in jiffies */
51 u8 fan_enabled; /* bit vector */
52 u16 fan[8]; /* register values */
53 u16 fan_min[8]; /* register values */
54 u8 fan_status[8]; /* register values */
58 * Super-I/O registers and operations
61 #define SIOREG_LDSEL 0x07 /* Logical device select */
62 #define SIOREG_DEVID 0x20 /* Device ID */
63 #define SIOREG_ACT 0x30 /* Device activation */
64 #define SIOREG_MAP 0x50 /* I/O or memory mapping */
65 #define SIOREG_IOBASE 0x60 /* I/O base address */
67 static const u8 logdev[2] = { 0x09, 0x14 };
68 static const char *logdev_str[2] = { DRVNAME " FMC", DRVNAME " HMC" };
73 static inline void superio_outb(int sioaddr, int reg, int val)
76 outb(val, sioaddr + 1);
79 static inline int superio_inb(int sioaddr, int reg)
82 return inb(sioaddr + 1);
85 static inline void superio_exit(int sioaddr)
88 outb(0x02, sioaddr + 1);
95 #define REGION_LENGTH 32
96 #define PC87427_REG_BANK 0x0f
97 #define BANK_FM(nr) (nr)
98 #define BANK_FT(nr) (0x08 + (nr))
99 #define BANK_FC(nr) (0x10 + (nr) * 2)
102 * I/O access functions
105 /* ldi is the logical device index */
106 static inline int pc87427_read8(struct pc87427_data *data, u8 ldi, u8 reg)
108 return inb(data->address[ldi] + reg);
111 /* Must be called with data->lock held, except during init */
112 static inline int pc87427_read8_bank(struct pc87427_data *data, u8 ldi,
115 outb(bank, data->address[ldi] + PC87427_REG_BANK);
116 return inb(data->address[ldi] + reg);
119 /* Must be called with data->lock held, except during init */
120 static inline void pc87427_write8_bank(struct pc87427_data *data, u8 ldi,
121 u8 bank, u8 reg, u8 value)
123 outb(bank, data->address[ldi] + PC87427_REG_BANK);
124 outb(value, data->address[ldi] + reg);
128 * Fan registers and conversions
131 /* fan data registers are 16-bit wide */
132 #define PC87427_REG_FAN 0x12
133 #define PC87427_REG_FAN_MIN 0x14
134 #define PC87427_REG_FAN_STATUS 0x10
136 #define FAN_STATUS_STALL (1 << 3)
137 #define FAN_STATUS_LOSPD (1 << 1)
138 #define FAN_STATUS_MONEN (1 << 0)
140 /* Dedicated function to read all registers related to a given fan input.
141 This saves us quite a few locks and bank selections.
142 Must be called with data->lock held.
144 static void pc87427_readall_fan(struct pc87427_data *data, u8 nr)
146 int iobase = data->address[LD_FAN];
148 outb(BANK_FM(nr), iobase + PC87427_REG_BANK);
149 data->fan[nr] = inw(iobase + PC87427_REG_FAN);
150 data->fan_min[nr] = inw(iobase + PC87427_REG_FAN_MIN);
151 data->fan_status[nr] = inb(iobase + PC87427_REG_FAN_STATUS);
152 /* Clear fan alarm bits */
153 outb(data->fan_status[nr], iobase + PC87427_REG_FAN_STATUS);
156 /* The 2 LSB of fan speed registers are used for something different.
157 The actual 2 LSB of the measurements are not available. */
158 static inline unsigned long fan_from_reg(u16 reg)
161 if (reg == 0x0000 || reg == 0xfffc)
163 return 5400000UL / reg;
166 /* The 2 LSB of the fan speed limit registers are not significant. */
167 static inline u16 fan_to_reg(unsigned long val)
171 if (val >= 1350000UL)
173 return ((1350000UL + val / 2) / val) << 2;
180 static struct pc87427_data *pc87427_update_device(struct device *dev)
182 struct pc87427_data *data = dev_get_drvdata(dev);
185 mutex_lock(&data->lock);
186 if (!time_after(jiffies, data->last_updated + HZ)
187 && data->last_updated)
191 for (i = 0; i < 8; i++) {
192 if (!(data->fan_enabled & (1 << i)))
194 pc87427_readall_fan(data, i);
196 data->last_updated = jiffies;
199 mutex_unlock(&data->lock);
203 static ssize_t show_fan_input(struct device *dev, struct device_attribute
206 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
207 struct pc87427_data *data = pc87427_update_device(dev);
208 int nr = attr->index;
210 return sprintf(buf, "%lu\n", fan_from_reg(data->fan[nr]));
213 static ssize_t show_fan_min(struct device *dev, struct device_attribute
216 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
217 struct pc87427_data *data = pc87427_update_device(dev);
218 int nr = attr->index;
220 return sprintf(buf, "%lu\n", fan_from_reg(data->fan_min[nr]));
223 static ssize_t show_fan_alarm(struct device *dev, struct device_attribute
226 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
227 struct pc87427_data *data = pc87427_update_device(dev);
228 int nr = attr->index;
230 return sprintf(buf, "%d\n", !!(data->fan_status[nr]
231 & FAN_STATUS_LOSPD));
234 static ssize_t show_fan_fault(struct device *dev, struct device_attribute
237 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
238 struct pc87427_data *data = pc87427_update_device(dev);
239 int nr = attr->index;
241 return sprintf(buf, "%d\n", !!(data->fan_status[nr]
242 & FAN_STATUS_STALL));
245 static ssize_t set_fan_min(struct device *dev, struct device_attribute
246 *devattr, const char *buf, size_t count)
248 struct pc87427_data *data = dev_get_drvdata(dev);
249 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
250 int nr = attr->index;
251 unsigned long val = simple_strtoul(buf, NULL, 10);
252 int iobase = data->address[LD_FAN];
254 mutex_lock(&data->lock);
255 outb(BANK_FM(nr), iobase + PC87427_REG_BANK);
256 /* The low speed limit registers are read-only while monitoring
257 is enabled, so we have to disable monitoring, then change the
258 limit, and finally enable monitoring again. */
259 outb(0, iobase + PC87427_REG_FAN_STATUS);
260 data->fan_min[nr] = fan_to_reg(val);
261 outw(data->fan_min[nr], iobase + PC87427_REG_FAN_MIN);
262 outb(FAN_STATUS_MONEN, iobase + PC87427_REG_FAN_STATUS);
263 mutex_unlock(&data->lock);
268 static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan_input, NULL, 0);
269 static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan_input, NULL, 1);
270 static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, show_fan_input, NULL, 2);
271 static SENSOR_DEVICE_ATTR(fan4_input, S_IRUGO, show_fan_input, NULL, 3);
272 static SENSOR_DEVICE_ATTR(fan5_input, S_IRUGO, show_fan_input, NULL, 4);
273 static SENSOR_DEVICE_ATTR(fan6_input, S_IRUGO, show_fan_input, NULL, 5);
274 static SENSOR_DEVICE_ATTR(fan7_input, S_IRUGO, show_fan_input, NULL, 6);
275 static SENSOR_DEVICE_ATTR(fan8_input, S_IRUGO, show_fan_input, NULL, 7);
277 static SENSOR_DEVICE_ATTR(fan1_min, S_IWUSR | S_IRUGO,
278 show_fan_min, set_fan_min, 0);
279 static SENSOR_DEVICE_ATTR(fan2_min, S_IWUSR | S_IRUGO,
280 show_fan_min, set_fan_min, 1);
281 static SENSOR_DEVICE_ATTR(fan3_min, S_IWUSR | S_IRUGO,
282 show_fan_min, set_fan_min, 2);
283 static SENSOR_DEVICE_ATTR(fan4_min, S_IWUSR | S_IRUGO,
284 show_fan_min, set_fan_min, 3);
285 static SENSOR_DEVICE_ATTR(fan5_min, S_IWUSR | S_IRUGO,
286 show_fan_min, set_fan_min, 4);
287 static SENSOR_DEVICE_ATTR(fan6_min, S_IWUSR | S_IRUGO,
288 show_fan_min, set_fan_min, 5);
289 static SENSOR_DEVICE_ATTR(fan7_min, S_IWUSR | S_IRUGO,
290 show_fan_min, set_fan_min, 6);
291 static SENSOR_DEVICE_ATTR(fan8_min, S_IWUSR | S_IRUGO,
292 show_fan_min, set_fan_min, 7);
294 static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_fan_alarm, NULL, 0);
295 static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_fan_alarm, NULL, 1);
296 static SENSOR_DEVICE_ATTR(fan3_alarm, S_IRUGO, show_fan_alarm, NULL, 2);
297 static SENSOR_DEVICE_ATTR(fan4_alarm, S_IRUGO, show_fan_alarm, NULL, 3);
298 static SENSOR_DEVICE_ATTR(fan5_alarm, S_IRUGO, show_fan_alarm, NULL, 4);
299 static SENSOR_DEVICE_ATTR(fan6_alarm, S_IRUGO, show_fan_alarm, NULL, 5);
300 static SENSOR_DEVICE_ATTR(fan7_alarm, S_IRUGO, show_fan_alarm, NULL, 6);
301 static SENSOR_DEVICE_ATTR(fan8_alarm, S_IRUGO, show_fan_alarm, NULL, 7);
303 static SENSOR_DEVICE_ATTR(fan1_fault, S_IRUGO, show_fan_fault, NULL, 0);
304 static SENSOR_DEVICE_ATTR(fan2_fault, S_IRUGO, show_fan_fault, NULL, 1);
305 static SENSOR_DEVICE_ATTR(fan3_fault, S_IRUGO, show_fan_fault, NULL, 2);
306 static SENSOR_DEVICE_ATTR(fan4_fault, S_IRUGO, show_fan_fault, NULL, 3);
307 static SENSOR_DEVICE_ATTR(fan5_fault, S_IRUGO, show_fan_fault, NULL, 4);
308 static SENSOR_DEVICE_ATTR(fan6_fault, S_IRUGO, show_fan_fault, NULL, 5);
309 static SENSOR_DEVICE_ATTR(fan7_fault, S_IRUGO, show_fan_fault, NULL, 6);
310 static SENSOR_DEVICE_ATTR(fan8_fault, S_IRUGO, show_fan_fault, NULL, 7);
312 static struct attribute *pc87427_attributes_fan[8][5] = {
314 &sensor_dev_attr_fan1_input.dev_attr.attr,
315 &sensor_dev_attr_fan1_min.dev_attr.attr,
316 &sensor_dev_attr_fan1_alarm.dev_attr.attr,
317 &sensor_dev_attr_fan1_fault.dev_attr.attr,
320 &sensor_dev_attr_fan2_input.dev_attr.attr,
321 &sensor_dev_attr_fan2_min.dev_attr.attr,
322 &sensor_dev_attr_fan2_alarm.dev_attr.attr,
323 &sensor_dev_attr_fan2_fault.dev_attr.attr,
326 &sensor_dev_attr_fan3_input.dev_attr.attr,
327 &sensor_dev_attr_fan3_min.dev_attr.attr,
328 &sensor_dev_attr_fan3_alarm.dev_attr.attr,
329 &sensor_dev_attr_fan3_fault.dev_attr.attr,
332 &sensor_dev_attr_fan4_input.dev_attr.attr,
333 &sensor_dev_attr_fan4_min.dev_attr.attr,
334 &sensor_dev_attr_fan4_alarm.dev_attr.attr,
335 &sensor_dev_attr_fan4_fault.dev_attr.attr,
338 &sensor_dev_attr_fan5_input.dev_attr.attr,
339 &sensor_dev_attr_fan5_min.dev_attr.attr,
340 &sensor_dev_attr_fan5_alarm.dev_attr.attr,
341 &sensor_dev_attr_fan5_fault.dev_attr.attr,
344 &sensor_dev_attr_fan6_input.dev_attr.attr,
345 &sensor_dev_attr_fan6_min.dev_attr.attr,
346 &sensor_dev_attr_fan6_alarm.dev_attr.attr,
347 &sensor_dev_attr_fan6_fault.dev_attr.attr,
350 &sensor_dev_attr_fan7_input.dev_attr.attr,
351 &sensor_dev_attr_fan7_min.dev_attr.attr,
352 &sensor_dev_attr_fan7_alarm.dev_attr.attr,
353 &sensor_dev_attr_fan7_fault.dev_attr.attr,
356 &sensor_dev_attr_fan8_input.dev_attr.attr,
357 &sensor_dev_attr_fan8_min.dev_attr.attr,
358 &sensor_dev_attr_fan8_alarm.dev_attr.attr,
359 &sensor_dev_attr_fan8_fault.dev_attr.attr,
364 static const struct attribute_group pc87427_group_fan[8] = {
365 { .attrs = pc87427_attributes_fan[0] },
366 { .attrs = pc87427_attributes_fan[1] },
367 { .attrs = pc87427_attributes_fan[2] },
368 { .attrs = pc87427_attributes_fan[3] },
369 { .attrs = pc87427_attributes_fan[4] },
370 { .attrs = pc87427_attributes_fan[5] },
371 { .attrs = pc87427_attributes_fan[6] },
372 { .attrs = pc87427_attributes_fan[7] },
375 static ssize_t show_name(struct device *dev, struct device_attribute
378 struct pc87427_data *data = dev_get_drvdata(dev);
380 return sprintf(buf, "%s\n", data->name);
382 static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
386 * Device detection, attach and detach
389 static void __devinit pc87427_init_device(struct device *dev)
391 struct pc87427_data *data = dev_get_drvdata(dev);
395 /* The FMC module should be ready */
396 reg = pc87427_read8(data, LD_FAN, PC87427_REG_BANK);
398 dev_warn(dev, "FMC module not ready!\n");
400 /* Check which fans are enabled */
401 for (i = 0; i < 8; i++) {
402 reg = pc87427_read8_bank(data, LD_FAN, BANK_FM(i),
403 PC87427_REG_FAN_STATUS);
404 if (reg & FAN_STATUS_MONEN)
405 data->fan_enabled |= (1 << i);
408 if (!data->fan_enabled) {
409 dev_dbg(dev, "Enabling all fan inputs\n");
410 for (i = 0; i < 8; i++)
411 pc87427_write8_bank(data, LD_FAN, BANK_FM(i),
412 PC87427_REG_FAN_STATUS,
414 data->fan_enabled = 0xff;
418 static int __devinit pc87427_probe(struct platform_device *pdev)
420 struct pc87427_data *data;
421 struct resource *res;
424 if (!(data = kzalloc(sizeof(struct pc87427_data), GFP_KERNEL))) {
426 printk(KERN_ERR DRVNAME ": Out of memory\n");
430 /* This will need to be revisited when we add support for
431 temperature and voltage monitoring. */
432 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
433 if (!request_region(res->start, res->end - res->start + 1, DRVNAME)) {
435 dev_err(&pdev->dev, "Failed to request region 0x%lx-0x%lx\n",
436 (unsigned long)res->start, (unsigned long)res->end);
439 data->address[0] = res->start;
441 mutex_init(&data->lock);
442 data->name = "pc87427";
443 platform_set_drvdata(pdev, data);
444 pc87427_init_device(&pdev->dev);
446 /* Register sysfs hooks */
447 if ((err = device_create_file(&pdev->dev, &dev_attr_name)))
448 goto exit_release_region;
449 for (i = 0; i < 8; i++) {
450 if (!(data->fan_enabled & (1 << i)))
452 if ((err = sysfs_create_group(&pdev->dev.kobj,
453 &pc87427_group_fan[i])))
454 goto exit_remove_files;
457 data->hwmon_dev = hwmon_device_register(&pdev->dev);
458 if (IS_ERR(data->hwmon_dev)) {
459 err = PTR_ERR(data->hwmon_dev);
460 dev_err(&pdev->dev, "Class registration failed (%d)\n", err);
461 goto exit_remove_files;
467 for (i = 0; i < 8; i++) {
468 if (!(data->fan_enabled & (1 << i)))
470 sysfs_remove_group(&pdev->dev.kobj, &pc87427_group_fan[i]);
473 release_region(res->start, res->end - res->start + 1);
475 platform_set_drvdata(pdev, NULL);
481 static int __devexit pc87427_remove(struct platform_device *pdev)
483 struct pc87427_data *data = platform_get_drvdata(pdev);
484 struct resource *res;
487 hwmon_device_unregister(data->hwmon_dev);
488 device_remove_file(&pdev->dev, &dev_attr_name);
489 for (i = 0; i < 8; i++) {
490 if (!(data->fan_enabled & (1 << i)))
492 sysfs_remove_group(&pdev->dev.kobj, &pc87427_group_fan[i]);
494 platform_set_drvdata(pdev, NULL);
497 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
498 release_region(res->start, res->end - res->start + 1);
504 static struct platform_driver pc87427_driver = {
506 .owner = THIS_MODULE,
509 .probe = pc87427_probe,
510 .remove = __devexit_p(pc87427_remove),
513 static int __init pc87427_device_add(unsigned short address)
515 struct resource res = {
517 .end = address + REGION_LENGTH - 1,
518 .name = logdev_str[0],
519 .flags = IORESOURCE_IO,
523 pdev = platform_device_alloc(DRVNAME, address);
526 printk(KERN_ERR DRVNAME ": Device allocation failed\n");
530 err = platform_device_add_resources(pdev, &res, 1);
532 printk(KERN_ERR DRVNAME ": Device resource addition failed "
534 goto exit_device_put;
537 err = platform_device_add(pdev);
539 printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n",
541 goto exit_device_put;
547 platform_device_put(pdev);
552 static int __init pc87427_find(int sioaddr, unsigned short *address)
557 /* Identify device */
558 val = superio_inb(sioaddr, SIOREG_DEVID);
559 if (val != 0xf2) { /* PC87427 */
564 for (i = 0; i < 2; i++) {
566 /* Select logical device */
567 superio_outb(sioaddr, SIOREG_LDSEL, logdev[i]);
569 val = superio_inb(sioaddr, SIOREG_ACT);
571 printk(KERN_INFO DRVNAME ": Logical device 0x%02x "
572 "not activated\n", logdev[i]);
576 val = superio_inb(sioaddr, SIOREG_MAP);
578 printk(KERN_WARNING DRVNAME ": Logical device 0x%02x "
579 "is memory-mapped, can't use\n", logdev[i]);
583 val = (superio_inb(sioaddr, SIOREG_IOBASE) << 8)
584 | superio_inb(sioaddr, SIOREG_IOBASE + 1);
586 printk(KERN_INFO DRVNAME ": I/O base address not set "
587 "for logical device 0x%02x\n", logdev[i]);
594 superio_exit(sioaddr);
598 static int __init pc87427_init(void)
601 unsigned short address[2];
603 if (pc87427_find(0x2e, address)
604 && pc87427_find(0x4e, address))
607 /* For now the driver only handles fans so we only care about the
612 err = platform_driver_register(&pc87427_driver);
616 /* Sets global pdev as a side effect */
617 err = pc87427_device_add(address[0]);
624 platform_driver_unregister(&pc87427_driver);
629 static void __exit pc87427_exit(void)
631 platform_device_unregister(pdev);
632 platform_driver_unregister(&pc87427_driver);
635 MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
636 MODULE_DESCRIPTION("PC87427 hardware monitoring driver");
637 MODULE_LICENSE("GPL");
639 module_init(pc87427_init);
640 module_exit(pc87427_exit);