aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean Delvare <khali@linux-fr.org>2009-12-09 14:35:48 -0500
committerJean Delvare <khali@linux-fr.org>2009-12-09 14:35:48 -0500
commit591ec6509ed888723caf6ac8ced3f6f718625a1f (patch)
treec6b896931d92623084a606442056bbc89eb24354
parent895ff267686663afa894314b749d23ac2867434a (diff)
hwmon: (it87) Check for fan2 and fan3 availability
The fan2 and fan3 input and output pins can be used as GPIOs. Check their function before exposing their sysfs attributes and accessing their registers. Signed-off-by: Jean Delvare <khali@linux-fr.org>
-rw-r--r--drivers/hwmon/it87.c27
1 files changed, 24 insertions, 3 deletions
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 2f782e3f9a2b..0ffe84d190bb 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -125,6 +125,7 @@ superio_exit(void)
125 125
126/* Logical device 7 registers (IT8712F and later) */ 126/* Logical device 7 registers (IT8712F and later) */
127#define IT87_SIO_GPIO3_REG 0x27 127#define IT87_SIO_GPIO3_REG 0x27
128#define IT87_SIO_GPIO5_REG 0x29
128#define IT87_SIO_PINX2_REG 0x2c /* Pin selection */ 129#define IT87_SIO_PINX2_REG 0x2c /* Pin selection */
129#define IT87_SIO_VID_REG 0xfc /* VID value */ 130#define IT87_SIO_VID_REG 0xfc /* VID value */
130 131
@@ -245,8 +246,9 @@ struct it87_sio_data {
245 /* Values read from Super-I/O config space */ 246 /* Values read from Super-I/O config space */
246 u8 revision; 247 u8 revision;
247 u8 vid_value; 248 u8 vid_value;
249 /* Features skipped based on config or DMI */
248 u8 skip_vid; 250 u8 skip_vid;
249 /* Values set based on DMI strings */ 251 u8 skip_fan;
250 u8 skip_pwm; 252 u8 skip_pwm;
251}; 253};
252 254
@@ -1044,6 +1046,19 @@ static int __init it87_find(unsigned short *address,
1044 sio_data->skip_vid = 1; 1046 sio_data->skip_vid = 1;
1045 } 1047 }
1046 1048
1049 /* Check if fan3 is there or not */
1050 if (reg & (1 << 6))
1051 sio_data->skip_pwm |= (1 << 2);
1052 if (reg & (1 << 7))
1053 sio_data->skip_fan |= (1 << 2);
1054
1055 /* Check if fan2 is there or not */
1056 reg = superio_inb(IT87_SIO_GPIO5_REG);
1057 if (reg & (1 << 1))
1058 sio_data->skip_pwm |= (1 << 1);
1059 if (reg & (1 << 2))
1060 sio_data->skip_fan |= (1 << 1);
1061
1047 if ((sio_data->type == it8718 || sio_data->type == it8720) 1062 if ((sio_data->type == it8718 || sio_data->type == it8720)
1048 && !(sio_data->skip_vid)) 1063 && !(sio_data->skip_vid))
1049 sio_data->vid_value = superio_inb(IT87_SIO_VID_REG); 1064 sio_data->vid_value = superio_inb(IT87_SIO_VID_REG);
@@ -1367,8 +1382,10 @@ static int __devinit it87_check_pwm(struct device *dev)
1367/* Called when we have found a new IT87. */ 1382/* Called when we have found a new IT87. */
1368static void __devinit it87_init_device(struct platform_device *pdev) 1383static void __devinit it87_init_device(struct platform_device *pdev)
1369{ 1384{
1385 struct it87_sio_data *sio_data = pdev->dev.platform_data;
1370 struct it87_data *data = platform_get_drvdata(pdev); 1386 struct it87_data *data = platform_get_drvdata(pdev);
1371 int tmp, i; 1387 int tmp, i;
1388 u8 mask;
1372 1389
1373 /* initialize to sane defaults: 1390 /* initialize to sane defaults:
1374 * - if the chip is in manual pwm mode, this will be overwritten with 1391 * - if the chip is in manual pwm mode, this will be overwritten with
@@ -1414,10 +1431,11 @@ static void __devinit it87_init_device(struct platform_device *pdev)
1414 } 1431 }
1415 1432
1416 /* Check if tachometers are reset manually or by some reason */ 1433 /* Check if tachometers are reset manually or by some reason */
1434 mask = 0x70 & ~(sio_data->skip_fan << 4);
1417 data->fan_main_ctrl = it87_read_value(data, IT87_REG_FAN_MAIN_CTRL); 1435 data->fan_main_ctrl = it87_read_value(data, IT87_REG_FAN_MAIN_CTRL);
1418 if ((data->fan_main_ctrl & 0x70) == 0) { 1436 if ((data->fan_main_ctrl & mask) == 0) {
1419 /* Enable all fan tachometers */ 1437 /* Enable all fan tachometers */
1420 data->fan_main_ctrl |= 0x70; 1438 data->fan_main_ctrl |= mask;
1421 it87_write_value(data, IT87_REG_FAN_MAIN_CTRL, data->fan_main_ctrl); 1439 it87_write_value(data, IT87_REG_FAN_MAIN_CTRL, data->fan_main_ctrl);
1422 } 1440 }
1423 data->has_fan = (data->fan_main_ctrl >> 4) & 0x07; 1441 data->has_fan = (data->fan_main_ctrl >> 4) & 0x07;
@@ -1440,6 +1458,9 @@ static void __devinit it87_init_device(struct platform_device *pdev)
1440 } 1458 }
1441 } 1459 }
1442 1460
1461 /* Fan input pins may be used for alternative functions */
1462 data->has_fan &= ~sio_data->skip_fan;
1463
1443 /* Set current fan mode registers and the default settings for the 1464 /* Set current fan mode registers and the default settings for the
1444 * other mode registers */ 1465 * other mode registers */
1445 for (i = 0; i < 3; i++) { 1466 for (i = 0; i < 3; i++) {