aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/it87.c
diff options
context:
space:
mode:
authorJean Delvare <khali@linux-fr.org>2010-03-05 16:17:15 -0500
committerJean Delvare <khali@linux-fr.org>2010-03-05 16:17:15 -0500
commitb99883dcd565e30299a6c5c3250725a4d48a8253 (patch)
tree98e5353f006b3fe8362d8b8dc4af35b1cb256fb5 /drivers/hwmon/it87.c
parent53de33427fa3d7dd62cc5ec75ce0d4e6c6d602dd (diff)
hwmon: (it87) Display fan outputs in automatic mode as such
The it87 driver doesn't yet support automatic fan control. Let it at least tell the user when a fan output is in automatic mode. Also let the user switch from automatic mode (possibly set by the BIOS) to manual mode and back without losing the settings. Signed-off-by: Jean Delvare <khali@linux-fr.org>
Diffstat (limited to 'drivers/hwmon/it87.c')
-rw-r--r--drivers/hwmon/it87.c99
1 files changed, 61 insertions, 38 deletions
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 0ffe84d190bb..49022bd2a0a5 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -281,7 +281,14 @@ struct it87_data {
281 u32 alarms; /* Register encoding, combined */ 281 u32 alarms; /* Register encoding, combined */
282 u8 fan_main_ctrl; /* Register value */ 282 u8 fan_main_ctrl; /* Register value */
283 u8 fan_ctl; /* Register value */ 283 u8 fan_ctl; /* Register value */
284 u8 manual_pwm_ctl[3]; /* manual PWM value set by user */ 284
285 /* The following 3 arrays correspond to the same registers. The
286 * meaning of bits 6-0 depends on the value of bit 7, and we want
287 * to preserve settings on mode changes, so we have to track all
288 * values separately. */
289 u8 pwm_ctrl[3]; /* Register value */
290 u8 pwm_duty[3]; /* Manual PWM value set by user (bit 6-0) */
291 u8 pwm_temp_map[3]; /* PWM to temp. chan. mapping (bits 1-0) */
285}; 292};
286 293
287static inline int has_16bit_fans(const struct it87_data *data) 294static inline int has_16bit_fans(const struct it87_data *data)
@@ -531,6 +538,19 @@ show_sensor_offset(2);
531show_sensor_offset(3); 538show_sensor_offset(3);
532 539
533/* 3 Fans */ 540/* 3 Fans */
541
542static int pwm_mode(const struct it87_data *data, int nr)
543{
544 int ctrl = data->fan_main_ctrl & (1 << nr);
545
546 if (ctrl == 0) /* Full speed */
547 return 0;
548 if (data->pwm_ctrl[nr] & 0x80) /* Automatic mode */
549 return 2;
550 else /* Manual mode */
551 return 1;
552}
553
534static ssize_t show_fan(struct device *dev, struct device_attribute *attr, 554static ssize_t show_fan(struct device *dev, struct device_attribute *attr,
535 char *buf) 555 char *buf)
536{ 556{
@@ -567,7 +587,7 @@ static ssize_t show_pwm_enable(struct device *dev, struct device_attribute *attr
567 int nr = sensor_attr->index; 587 int nr = sensor_attr->index;
568 588
569 struct it87_data *data = it87_update_device(dev); 589 struct it87_data *data = it87_update_device(dev);
570 return sprintf(buf,"%d\n", (data->fan_main_ctrl & (1 << nr)) ? 1 : 0); 590 return sprintf(buf, "%d\n", pwm_mode(data, nr));
571} 591}
572static ssize_t show_pwm(struct device *dev, struct device_attribute *attr, 592static ssize_t show_pwm(struct device *dev, struct device_attribute *attr,
573 char *buf) 593 char *buf)
@@ -576,7 +596,7 @@ static ssize_t show_pwm(struct device *dev, struct device_attribute *attr,
576 int nr = sensor_attr->index; 596 int nr = sensor_attr->index;
577 597
578 struct it87_data *data = it87_update_device(dev); 598 struct it87_data *data = it87_update_device(dev);
579 return sprintf(buf,"%d\n", data->manual_pwm_ctl[nr]); 599 return sprintf(buf, "%d\n", PWM_FROM_REG(data->pwm_duty[nr]));
580} 600}
581static ssize_t show_pwm_freq(struct device *dev, struct device_attribute *attr, 601static ssize_t show_pwm_freq(struct device *dev, struct device_attribute *attr,
582 char *buf) 602 char *buf)
@@ -660,6 +680,9 @@ static ssize_t set_pwm_enable(struct device *dev,
660 struct it87_data *data = dev_get_drvdata(dev); 680 struct it87_data *data = dev_get_drvdata(dev);
661 int val = simple_strtol(buf, NULL, 10); 681 int val = simple_strtol(buf, NULL, 10);
662 682
683 if (val < 0 || val > 2)
684 return -EINVAL;
685
663 mutex_lock(&data->update_lock); 686 mutex_lock(&data->update_lock);
664 687
665 if (val == 0) { 688 if (val == 0) {
@@ -670,15 +693,15 @@ static ssize_t set_pwm_enable(struct device *dev,
670 /* set on/off mode */ 693 /* set on/off mode */
671 data->fan_main_ctrl &= ~(1 << nr); 694 data->fan_main_ctrl &= ~(1 << nr);
672 it87_write_value(data, IT87_REG_FAN_MAIN_CTRL, data->fan_main_ctrl); 695 it87_write_value(data, IT87_REG_FAN_MAIN_CTRL, data->fan_main_ctrl);
673 } else if (val == 1) { 696 } else {
697 if (val == 1) /* Manual mode */
698 data->pwm_ctrl[nr] = data->pwm_duty[nr];
699 else /* Automatic mode */
700 data->pwm_ctrl[nr] = 0x80 | data->pwm_temp_map[nr];
701 it87_write_value(data, IT87_REG_PWM(nr), data->pwm_ctrl[nr]);
674 /* set SmartGuardian mode */ 702 /* set SmartGuardian mode */
675 data->fan_main_ctrl |= (1 << nr); 703 data->fan_main_ctrl |= (1 << nr);
676 it87_write_value(data, IT87_REG_FAN_MAIN_CTRL, data->fan_main_ctrl); 704 it87_write_value(data, IT87_REG_FAN_MAIN_CTRL, data->fan_main_ctrl);
677 /* set saved pwm value, clear FAN_CTLX PWM mode bit */
678 it87_write_value(data, IT87_REG_PWM(nr), PWM_TO_REG(data->manual_pwm_ctl[nr]));
679 } else {
680 mutex_unlock(&data->update_lock);
681 return -EINVAL;
682 } 705 }
683 706
684 mutex_unlock(&data->update_lock); 707 mutex_unlock(&data->update_lock);
@@ -697,9 +720,13 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
697 return -EINVAL; 720 return -EINVAL;
698 721
699 mutex_lock(&data->update_lock); 722 mutex_lock(&data->update_lock);
700 data->manual_pwm_ctl[nr] = val; 723 data->pwm_duty[nr] = PWM_TO_REG(val);
701 if (data->fan_main_ctrl & (1 << nr)) 724 /* If we are in manual mode, write the duty cycle immediately;
702 it87_write_value(data, IT87_REG_PWM(nr), PWM_TO_REG(data->manual_pwm_ctl[nr])); 725 * otherwise, just store it for later use. */
726 if (!(data->pwm_ctrl[nr] & 0x80)) {
727 data->pwm_ctrl[nr] = data->pwm_duty[nr];
728 it87_write_value(data, IT87_REG_PWM(nr), data->pwm_ctrl[nr]);
729 }
703 mutex_unlock(&data->update_lock); 730 mutex_unlock(&data->update_lock);
704 return count; 731 return count;
705} 732}
@@ -1387,15 +1414,17 @@ static void __devinit it87_init_device(struct platform_device *pdev)
1387 int tmp, i; 1414 int tmp, i;
1388 u8 mask; 1415 u8 mask;
1389 1416
1390 /* initialize to sane defaults: 1417 /* For each PWM channel:
1391 * - if the chip is in manual pwm mode, this will be overwritten with 1418 * - If it is in automatic mode, setting to manual mode should set
1392 * the actual settings on the chip (so in this case, initialization 1419 * the fan to full speed by default.
1393 * is not needed) 1420 * - If it is in manual mode, we need a mapping to temperature
1394 * - if in automatic or on/off mode, we could switch to manual mode, 1421 * channels to use when later setting to automatic mode later.
1395 * read the registers and set manual_pwm_ctl accordingly, but currently 1422 * Use a 1:1 mapping by default (we are clueless.)
1396 * this is not implemented, so we initialize to something sane */ 1423 * In both cases, the value can (and should) be changed by the user
1424 * prior to switching to a different mode. */
1397 for (i = 0; i < 3; i++) { 1425 for (i = 0; i < 3; i++) {
1398 data->manual_pwm_ctl[i] = 0xff; 1426 data->pwm_temp_map[i] = i;
1427 data->pwm_duty[i] = 0x7f; /* Full speed */
1399 } 1428 }
1400 1429
1401 /* Some chips seem to have default value 0xff for all limit 1430 /* Some chips seem to have default value 0xff for all limit
@@ -1461,30 +1490,21 @@ static void __devinit it87_init_device(struct platform_device *pdev)
1461 /* Fan input pins may be used for alternative functions */ 1490 /* Fan input pins may be used for alternative functions */
1462 data->has_fan &= ~sio_data->skip_fan; 1491 data->has_fan &= ~sio_data->skip_fan;
1463 1492
1464 /* Set current fan mode registers and the default settings for the
1465 * other mode registers */
1466 for (i = 0; i < 3; i++) {
1467 if (data->fan_main_ctrl & (1 << i)) {
1468 /* pwm mode */
1469 tmp = it87_read_value(data, IT87_REG_PWM(i));
1470 if (tmp & 0x80) {
1471 /* automatic pwm - not yet implemented, but
1472 * leave the settings made by the BIOS alone
1473 * until a change is requested via the sysfs
1474 * interface */
1475 } else {
1476 /* manual pwm */
1477 data->manual_pwm_ctl[i] = PWM_FROM_REG(tmp);
1478 }
1479 }
1480 }
1481
1482 /* Start monitoring */ 1493 /* Start monitoring */
1483 it87_write_value(data, IT87_REG_CONFIG, 1494 it87_write_value(data, IT87_REG_CONFIG,
1484 (it87_read_value(data, IT87_REG_CONFIG) & 0x36) 1495 (it87_read_value(data, IT87_REG_CONFIG) & 0x36)
1485 | (update_vbat ? 0x41 : 0x01)); 1496 | (update_vbat ? 0x41 : 0x01));
1486} 1497}
1487 1498
1499static void it87_update_pwm_ctrl(struct it87_data *data, int nr)
1500{
1501 data->pwm_ctrl[nr] = it87_read_value(data, IT87_REG_PWM(nr));
1502 if (data->pwm_ctrl[nr] & 0x80) /* Automatic mode */
1503 data->pwm_temp_map[nr] = data->pwm_ctrl[nr] & 0x03;
1504 else /* Manual mode */
1505 data->pwm_duty[nr] = data->pwm_ctrl[nr] & 0x7f;
1506}
1507
1488static struct it87_data *it87_update_device(struct device *dev) 1508static struct it87_data *it87_update_device(struct device *dev)
1489{ 1509{
1490 struct it87_data *data = dev_get_drvdata(dev); 1510 struct it87_data *data = dev_get_drvdata(dev);
@@ -1551,9 +1571,12 @@ static struct it87_data *it87_update_device(struct device *dev)
1551 it87_read_value(data, IT87_REG_ALARM1) | 1571 it87_read_value(data, IT87_REG_ALARM1) |
1552 (it87_read_value(data, IT87_REG_ALARM2) << 8) | 1572 (it87_read_value(data, IT87_REG_ALARM2) << 8) |
1553 (it87_read_value(data, IT87_REG_ALARM3) << 16); 1573 (it87_read_value(data, IT87_REG_ALARM3) << 16);
1574
1554 data->fan_main_ctrl = it87_read_value(data, 1575 data->fan_main_ctrl = it87_read_value(data,
1555 IT87_REG_FAN_MAIN_CTRL); 1576 IT87_REG_FAN_MAIN_CTRL);
1556 data->fan_ctl = it87_read_value(data, IT87_REG_FAN_CTL); 1577 data->fan_ctl = it87_read_value(data, IT87_REG_FAN_CTL);
1578 for (i = 0; i < 3; i++)
1579 it87_update_pwm_ctrl(data, i);
1557 1580
1558 data->sensor = it87_read_value(data, IT87_REG_TEMP_ENABLE); 1581 data->sensor = it87_read_value(data, IT87_REG_TEMP_ENABLE);
1559 /* The 8705 does not have VID capability. 1582 /* The 8705 does not have VID capability.