2 * pc87427.c - hardware monitoring driver for the
3 * National Semiconductor PC87427 Super-I/O chip
4 * Copyright (C) 2006, 2008 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>
35 #include <linux/acpi.h>
38 static unsigned short force_id;
39 module_param(force_id, ushort, 0);
40 MODULE_PARM_DESC(force_id, "Override the detected device ID");
42 static struct platform_device *pdev;
44 #define DRVNAME "pc87427"
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). */
50 struct device *hwmon_dev;
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 */
62 struct pc87427_sio_data {
67 * Super-I/O registers and operations
70 #define SIOREG_LDSEL 0x07 /* Logical device select */
71 #define SIOREG_DEVID 0x20 /* Device ID */
72 #define SIOREG_CF2 0x22 /* Configuration 2 */
73 #define SIOREG_CF3 0x23 /* Configuration 3 */
74 #define SIOREG_CF4 0x24 /* Configuration 4 */
75 #define SIOREG_CFB 0x2B /* Configuration B */
76 #define SIOREG_CFD 0x2D /* Configuration D */
77 #define SIOREG_ACT 0x30 /* Device activation */
78 #define SIOREG_MAP 0x50 /* I/O or memory mapping */
79 #define SIOREG_IOBASE 0x60 /* I/O base address */
81 static const u8 logdev[2] = { 0x09, 0x14 };
82 static const char *logdev_str[2] = { DRVNAME " FMC", DRVNAME " HMC" };
87 static inline void superio_outb(int sioaddr, int reg, int val)
90 outb(val, sioaddr + 1);
93 static inline int superio_inb(int sioaddr, int reg)
96 return inb(sioaddr + 1);
99 static inline void superio_exit(int sioaddr)
102 outb(0x02, sioaddr + 1);
109 #define REGION_LENGTH 32
110 #define PC87427_REG_BANK 0x0f
111 #define BANK_FM(nr) (nr)
112 #define BANK_FT(nr) (0x08 + (nr))
113 #define BANK_FC(nr) (0x10 + (nr) * 2)
116 * I/O access functions
119 /* ldi is the logical device index */
120 static inline int pc87427_read8(struct pc87427_data *data, u8 ldi, u8 reg)
122 return inb(data->address[ldi] + reg);
125 /* Must be called with data->lock held, except during init */
126 static inline int pc87427_read8_bank(struct pc87427_data *data, u8 ldi,
129 outb(bank, data->address[ldi] + PC87427_REG_BANK);
130 return inb(data->address[ldi] + reg);
133 /* Must be called with data->lock held, except during init */
134 static inline void pc87427_write8_bank(struct pc87427_data *data, u8 ldi,
135 u8 bank, u8 reg, u8 value)
137 outb(bank, data->address[ldi] + PC87427_REG_BANK);
138 outb(value, data->address[ldi] + reg);
142 * Fan registers and conversions
145 /* fan data registers are 16-bit wide */
146 #define PC87427_REG_FAN 0x12
147 #define PC87427_REG_FAN_MIN 0x14
148 #define PC87427_REG_FAN_STATUS 0x10
150 #define FAN_STATUS_STALL (1 << 3)
151 #define FAN_STATUS_LOSPD (1 << 1)
152 #define FAN_STATUS_MONEN (1 << 0)
154 /* Dedicated function to read all registers related to a given fan input.
155 This saves us quite a few locks and bank selections.
156 Must be called with data->lock held.
158 static void pc87427_readall_fan(struct pc87427_data *data, u8 nr)
160 int iobase = data->address[LD_FAN];
162 outb(BANK_FM(nr), iobase + PC87427_REG_BANK);
163 data->fan[nr] = inw(iobase + PC87427_REG_FAN);
164 data->fan_min[nr] = inw(iobase + PC87427_REG_FAN_MIN);
165 data->fan_status[nr] = inb(iobase + PC87427_REG_FAN_STATUS);
166 /* Clear fan alarm bits */
167 outb(data->fan_status[nr], iobase + PC87427_REG_FAN_STATUS);
170 /* The 2 LSB of fan speed registers are used for something different.
171 The actual 2 LSB of the measurements are not available. */
172 static inline unsigned long fan_from_reg(u16 reg)
175 if (reg == 0x0000 || reg == 0xfffc)
177 return 5400000UL / reg;
180 /* The 2 LSB of the fan speed limit registers are not significant. */
181 static inline u16 fan_to_reg(unsigned long val)
185 if (val >= 1350000UL)
187 return ((1350000UL + val / 2) / val) << 2;
194 static struct pc87427_data *pc87427_update_device(struct device *dev)
196 struct pc87427_data *data = dev_get_drvdata(dev);
199 mutex_lock(&data->lock);
200 if (!time_after(jiffies, data->last_updated + HZ)
201 && data->last_updated)
205 for (i = 0; i < 8; i++) {
206 if (!(data->fan_enabled & (1 << i)))
208 pc87427_readall_fan(data, i);
210 data->last_updated = jiffies;
213 mutex_unlock(&data->lock);
217 static ssize_t show_fan_input(struct device *dev, struct device_attribute
220 struct pc87427_data *data = pc87427_update_device(dev);
221 int nr = to_sensor_dev_attr(devattr)->index;
223 return sprintf(buf, "%lu\n", fan_from_reg(data->fan[nr]));
226 static ssize_t show_fan_min(struct device *dev, struct device_attribute
229 struct pc87427_data *data = pc87427_update_device(dev);
230 int nr = to_sensor_dev_attr(devattr)->index;
232 return sprintf(buf, "%lu\n", fan_from_reg(data->fan_min[nr]));
235 static ssize_t show_fan_alarm(struct device *dev, struct device_attribute
238 struct pc87427_data *data = pc87427_update_device(dev);
239 int nr = to_sensor_dev_attr(devattr)->index;
241 return sprintf(buf, "%d\n", !!(data->fan_status[nr]
242 & FAN_STATUS_LOSPD));
245 static ssize_t show_fan_fault(struct device *dev, struct device_attribute
248 struct pc87427_data *data = pc87427_update_device(dev);
249 int nr = to_sensor_dev_attr(devattr)->index;
251 return sprintf(buf, "%d\n", !!(data->fan_status[nr]
252 & FAN_STATUS_STALL));
255 static ssize_t set_fan_min(struct device *dev, struct device_attribute
256 *devattr, const char *buf, size_t count)
258 struct pc87427_data *data = dev_get_drvdata(dev);
259 int nr = to_sensor_dev_attr(devattr)->index;
261 int iobase = data->address[LD_FAN];
263 if (strict_strtoul(buf, 10, &val) < 0)
266 mutex_lock(&data->lock);
267 outb(BANK_FM(nr), iobase + PC87427_REG_BANK);
268 /* The low speed limit registers are read-only while monitoring
269 is enabled, so we have to disable monitoring, then change the
270 limit, and finally enable monitoring again. */
271 outb(0, iobase + PC87427_REG_FAN_STATUS);
272 data->fan_min[nr] = fan_to_reg(val);
273 outw(data->fan_min[nr], iobase + PC87427_REG_FAN_MIN);
274 outb(FAN_STATUS_MONEN, iobase + PC87427_REG_FAN_STATUS);
275 mutex_unlock(&data->lock);
280 static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan_input, NULL, 0);
281 static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan_input, NULL, 1);
282 static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, show_fan_input, NULL, 2);
283 static SENSOR_DEVICE_ATTR(fan4_input, S_IRUGO, show_fan_input, NULL, 3);
284 static SENSOR_DEVICE_ATTR(fan5_input, S_IRUGO, show_fan_input, NULL, 4);
285 static SENSOR_DEVICE_ATTR(fan6_input, S_IRUGO, show_fan_input, NULL, 5);
286 static SENSOR_DEVICE_ATTR(fan7_input, S_IRUGO, show_fan_input, NULL, 6);
287 static SENSOR_DEVICE_ATTR(fan8_input, S_IRUGO, show_fan_input, NULL, 7);
289 static SENSOR_DEVICE_ATTR(fan1_min, S_IWUSR | S_IRUGO,
290 show_fan_min, set_fan_min, 0);
291 static SENSOR_DEVICE_ATTR(fan2_min, S_IWUSR | S_IRUGO,
292 show_fan_min, set_fan_min, 1);
293 static SENSOR_DEVICE_ATTR(fan3_min, S_IWUSR | S_IRUGO,
294 show_fan_min, set_fan_min, 2);
295 static SENSOR_DEVICE_ATTR(fan4_min, S_IWUSR | S_IRUGO,
296 show_fan_min, set_fan_min, 3);
297 static SENSOR_DEVICE_ATTR(fan5_min, S_IWUSR | S_IRUGO,
298 show_fan_min, set_fan_min, 4);
299 static SENSOR_DEVICE_ATTR(fan6_min, S_IWUSR | S_IRUGO,
300 show_fan_min, set_fan_min, 5);
301 static SENSOR_DEVICE_ATTR(fan7_min, S_IWUSR | S_IRUGO,
302 show_fan_min, set_fan_min, 6);
303 static SENSOR_DEVICE_ATTR(fan8_min, S_IWUSR | S_IRUGO,
304 show_fan_min, set_fan_min, 7);
306 static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_fan_alarm, NULL, 0);
307 static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_fan_alarm, NULL, 1);
308 static SENSOR_DEVICE_ATTR(fan3_alarm, S_IRUGO, show_fan_alarm, NULL, 2);
309 static SENSOR_DEVICE_ATTR(fan4_alarm, S_IRUGO, show_fan_alarm, NULL, 3);
310 static SENSOR_DEVICE_ATTR(fan5_alarm, S_IRUGO, show_fan_alarm, NULL, 4);
311 static SENSOR_DEVICE_ATTR(fan6_alarm, S_IRUGO, show_fan_alarm, NULL, 5);
312 static SENSOR_DEVICE_ATTR(fan7_alarm, S_IRUGO, show_fan_alarm, NULL, 6);
313 static SENSOR_DEVICE_ATTR(fan8_alarm, S_IRUGO, show_fan_alarm, NULL, 7);
315 static SENSOR_DEVICE_ATTR(fan1_fault, S_IRUGO, show_fan_fault, NULL, 0);
316 static SENSOR_DEVICE_ATTR(fan2_fault, S_IRUGO, show_fan_fault, NULL, 1);
317 static SENSOR_DEVICE_ATTR(fan3_fault, S_IRUGO, show_fan_fault, NULL, 2);
318 static SENSOR_DEVICE_ATTR(fan4_fault, S_IRUGO, show_fan_fault, NULL, 3);
319 static SENSOR_DEVICE_ATTR(fan5_fault, S_IRUGO, show_fan_fault, NULL, 4);
320 static SENSOR_DEVICE_ATTR(fan6_fault, S_IRUGO, show_fan_fault, NULL, 5);
321 static SENSOR_DEVICE_ATTR(fan7_fault, S_IRUGO, show_fan_fault, NULL, 6);
322 static SENSOR_DEVICE_ATTR(fan8_fault, S_IRUGO, show_fan_fault, NULL, 7);
324 static struct attribute *pc87427_attributes_fan[8][5] = {
326 &sensor_dev_attr_fan1_input.dev_attr.attr,
327 &sensor_dev_attr_fan1_min.dev_attr.attr,
328 &sensor_dev_attr_fan1_alarm.dev_attr.attr,
329 &sensor_dev_attr_fan1_fault.dev_attr.attr,
332 &sensor_dev_attr_fan2_input.dev_attr.attr,
333 &sensor_dev_attr_fan2_min.dev_attr.attr,
334 &sensor_dev_attr_fan2_alarm.dev_attr.attr,
335 &sensor_dev_attr_fan2_fault.dev_attr.attr,
338 &sensor_dev_attr_fan3_input.dev_attr.attr,
339 &sensor_dev_attr_fan3_min.dev_attr.attr,
340 &sensor_dev_attr_fan3_alarm.dev_attr.attr,
341 &sensor_dev_attr_fan3_fault.dev_attr.attr,
344 &sensor_dev_attr_fan4_input.dev_attr.attr,
345 &sensor_dev_attr_fan4_min.dev_attr.attr,
346 &sensor_dev_attr_fan4_alarm.dev_attr.attr,
347 &sensor_dev_attr_fan4_fault.dev_attr.attr,
350 &sensor_dev_attr_fan5_input.dev_attr.attr,
351 &sensor_dev_attr_fan5_min.dev_attr.attr,
352 &sensor_dev_attr_fan5_alarm.dev_attr.attr,
353 &sensor_dev_attr_fan5_fault.dev_attr.attr,
356 &sensor_dev_attr_fan6_input.dev_attr.attr,
357 &sensor_dev_attr_fan6_min.dev_attr.attr,
358 &sensor_dev_attr_fan6_alarm.dev_attr.attr,
359 &sensor_dev_attr_fan6_fault.dev_attr.attr,
362 &sensor_dev_attr_fan7_input.dev_attr.attr,
363 &sensor_dev_attr_fan7_min.dev_attr.attr,
364 &sensor_dev_attr_fan7_alarm.dev_attr.attr,
365 &sensor_dev_attr_fan7_fault.dev_attr.attr,
368 &sensor_dev_attr_fan8_input.dev_attr.attr,
369 &sensor_dev_attr_fan8_min.dev_attr.attr,
370 &sensor_dev_attr_fan8_alarm.dev_attr.attr,
371 &sensor_dev_attr_fan8_fault.dev_attr.attr,
376 static const struct attribute_group pc87427_group_fan[8] = {
377 { .attrs = pc87427_attributes_fan[0] },
378 { .attrs = pc87427_attributes_fan[1] },
379 { .attrs = pc87427_attributes_fan[2] },
380 { .attrs = pc87427_attributes_fan[3] },
381 { .attrs = pc87427_attributes_fan[4] },
382 { .attrs = pc87427_attributes_fan[5] },
383 { .attrs = pc87427_attributes_fan[6] },
384 { .attrs = pc87427_attributes_fan[7] },
387 static ssize_t show_name(struct device *dev, struct device_attribute
390 struct pc87427_data *data = dev_get_drvdata(dev);
392 return sprintf(buf, "%s\n", data->name);
394 static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
398 * Device detection, attach and detach
401 static void __devinit pc87427_init_device(struct device *dev)
403 struct pc87427_sio_data *sio_data = dev->platform_data;
404 struct pc87427_data *data = dev_get_drvdata(dev);
408 /* The FMC module should be ready */
409 reg = pc87427_read8(data, LD_FAN, PC87427_REG_BANK);
411 dev_warn(dev, "FMC module not ready!\n");
413 /* Check which fans are enabled */
414 for (i = 0; i < 8; i++) {
415 if (!(sio_data->has_fanin & (1 << i))) /* Not wired */
417 reg = pc87427_read8_bank(data, LD_FAN, BANK_FM(i),
418 PC87427_REG_FAN_STATUS);
419 if (reg & FAN_STATUS_MONEN)
420 data->fan_enabled |= (1 << i);
423 if (!data->fan_enabled) {
424 dev_dbg(dev, "Enabling monitoring of all fans\n");
425 for (i = 0; i < 8; i++) {
426 if (!(sio_data->has_fanin & (1 << i))) /* Not wired */
428 pc87427_write8_bank(data, LD_FAN, BANK_FM(i),
429 PC87427_REG_FAN_STATUS,
432 data->fan_enabled = sio_data->has_fanin;
436 static int __devinit pc87427_probe(struct platform_device *pdev)
438 struct pc87427_data *data;
439 struct resource *res;
442 data = kzalloc(sizeof(struct pc87427_data), GFP_KERNEL);
445 printk(KERN_ERR DRVNAME ": Out of memory\n");
449 /* This will need to be revisited when we add support for
450 temperature and voltage monitoring. */
451 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
452 if (!request_region(res->start, resource_size(res), DRVNAME)) {
454 dev_err(&pdev->dev, "Failed to request region 0x%lx-0x%lx\n",
455 (unsigned long)res->start, (unsigned long)res->end);
458 data->address[0] = res->start;
460 mutex_init(&data->lock);
461 data->name = "pc87427";
462 platform_set_drvdata(pdev, data);
463 pc87427_init_device(&pdev->dev);
465 /* Register sysfs hooks */
466 err = device_create_file(&pdev->dev, &dev_attr_name);
468 goto exit_release_region;
469 for (i = 0; i < 8; i++) {
470 if (!(data->fan_enabled & (1 << i)))
472 err = sysfs_create_group(&pdev->dev.kobj,
473 &pc87427_group_fan[i]);
475 goto exit_remove_files;
478 data->hwmon_dev = hwmon_device_register(&pdev->dev);
479 if (IS_ERR(data->hwmon_dev)) {
480 err = PTR_ERR(data->hwmon_dev);
481 dev_err(&pdev->dev, "Class registration failed (%d)\n", err);
482 goto exit_remove_files;
488 for (i = 0; i < 8; i++) {
489 if (!(data->fan_enabled & (1 << i)))
491 sysfs_remove_group(&pdev->dev.kobj, &pc87427_group_fan[i]);
494 release_region(res->start, resource_size(res));
496 platform_set_drvdata(pdev, NULL);
502 static int __devexit pc87427_remove(struct platform_device *pdev)
504 struct pc87427_data *data = platform_get_drvdata(pdev);
505 struct resource *res;
508 hwmon_device_unregister(data->hwmon_dev);
509 device_remove_file(&pdev->dev, &dev_attr_name);
510 for (i = 0; i < 8; i++) {
511 if (!(data->fan_enabled & (1 << i)))
513 sysfs_remove_group(&pdev->dev.kobj, &pc87427_group_fan[i]);
515 platform_set_drvdata(pdev, NULL);
518 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
519 release_region(res->start, resource_size(res));
525 static struct platform_driver pc87427_driver = {
527 .owner = THIS_MODULE,
530 .probe = pc87427_probe,
531 .remove = __devexit_p(pc87427_remove),
534 static int __init pc87427_device_add(unsigned short address,
535 const struct pc87427_sio_data *sio_data)
537 struct resource res = {
539 .end = address + REGION_LENGTH - 1,
540 .name = logdev_str[0],
541 .flags = IORESOURCE_IO,
545 err = acpi_check_resource_conflict(&res);
549 pdev = platform_device_alloc(DRVNAME, address);
552 printk(KERN_ERR DRVNAME ": Device allocation failed\n");
556 err = platform_device_add_resources(pdev, &res, 1);
558 printk(KERN_ERR DRVNAME ": Device resource addition failed "
560 goto exit_device_put;
563 err = platform_device_add_data(pdev, sio_data,
564 sizeof(struct pc87427_sio_data));
566 printk(KERN_ERR DRVNAME ": Platform data allocation failed\n");
567 goto exit_device_put;
570 err = platform_device_add(pdev);
572 printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n",
574 goto exit_device_put;
580 platform_device_put(pdev);
585 static int __init pc87427_find(int sioaddr, unsigned short *address,
586 struct pc87427_sio_data *sio_data)
592 /* Identify device */
593 val = force_id ? force_id : superio_inb(sioaddr, SIOREG_DEVID);
594 if (val != 0xf2) { /* PC87427 */
599 for (i = 0; i < 2; i++) {
601 /* Select logical device */
602 superio_outb(sioaddr, SIOREG_LDSEL, logdev[i]);
604 val = superio_inb(sioaddr, SIOREG_ACT);
606 printk(KERN_INFO DRVNAME ": Logical device 0x%02x "
607 "not activated\n", logdev[i]);
611 val = superio_inb(sioaddr, SIOREG_MAP);
613 printk(KERN_WARNING DRVNAME ": Logical device 0x%02x "
614 "is memory-mapped, can't use\n", logdev[i]);
618 val = (superio_inb(sioaddr, SIOREG_IOBASE) << 8)
619 | superio_inb(sioaddr, SIOREG_IOBASE + 1);
621 printk(KERN_INFO DRVNAME ": I/O base address not set "
622 "for logical device 0x%02x\n", logdev[i]);
628 /* Check which fan inputs are wired */
629 sio_data->has_fanin = (1 << 2) | (1 << 3); /* FANIN2, FANIN3 */
631 cfg = superio_inb(sioaddr, SIOREG_CF2);
632 if (!(cfg & (1 << 3)))
633 sio_data->has_fanin |= (1 << 0); /* FANIN0 */
634 if (!(cfg & (1 << 2)))
635 sio_data->has_fanin |= (1 << 4); /* FANIN4 */
637 cfg = superio_inb(sioaddr, SIOREG_CFD);
638 if (!(cfg & (1 << 0)))
639 sio_data->has_fanin |= (1 << 1); /* FANIN1 */
641 cfg = superio_inb(sioaddr, SIOREG_CF4);
642 if (!(cfg & (1 << 0)))
643 sio_data->has_fanin |= (1 << 7); /* FANIN7 */
644 cfg_b = superio_inb(sioaddr, SIOREG_CFB);
645 if (!(cfg & (1 << 1)) && (cfg_b & (1 << 3)))
646 sio_data->has_fanin |= (1 << 5); /* FANIN5 */
647 cfg = superio_inb(sioaddr, SIOREG_CF3);
648 if ((cfg & (1 << 3)) && !(cfg_b & (1 << 5)))
649 sio_data->has_fanin |= (1 << 6); /* FANIN6 */
652 superio_exit(sioaddr);
656 static int __init pc87427_init(void)
659 unsigned short address[2];
660 struct pc87427_sio_data sio_data;
662 if (pc87427_find(0x2e, address, &sio_data)
663 && pc87427_find(0x4e, address, &sio_data))
666 /* For now the driver only handles fans so we only care about the
671 err = platform_driver_register(&pc87427_driver);
675 /* Sets global pdev as a side effect */
676 err = pc87427_device_add(address[0], &sio_data);
683 platform_driver_unregister(&pc87427_driver);
688 static void __exit pc87427_exit(void)
690 platform_device_unregister(pdev);
691 platform_driver_unregister(&pc87427_driver);
694 MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
695 MODULE_DESCRIPTION("PC87427 hardware monitoring driver");
696 MODULE_LICENSE("GPL");
698 module_init(pc87427_init);
699 module_exit(pc87427_exit);