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