Merge branch 'hwmon-for-linus' of git://jdelvare.pck.nerim.net/jdelvare-2.6
* 'hwmon-for-linus' of git://jdelvare.pck.nerim.net/jdelvare-2.6: hwmon: (abituguru3) Enable DMI probing feature on Abit AT8 32X hwmon: (abituguru3) Enable reading from AUX3 fan on Abit AT8 32X hwmon: (adt7473) Fix some bogosity in documentation file hwmon: Define sysfs interface for energy consumption register hwmon: (it87) Prevent power-off on Shuttle SN68PT eeepc-laptop: Fix hwmon interface
This commit is contained in:
commit
07f4055418
5 changed files with 83 additions and 36 deletions
|
@ -14,14 +14,14 @@ Description
|
||||||
|
|
||||||
This driver implements support for the Analog Devices ADT7473 chip family.
|
This driver implements support for the Analog Devices ADT7473 chip family.
|
||||||
|
|
||||||
The LM85 uses the 2-wire interface compatible with the SMBUS 2.0
|
The ADT7473 uses the 2-wire interface compatible with the SMBUS 2.0
|
||||||
specification. Using an analog to digital converter it measures three (3)
|
specification. Using an analog to digital converter it measures three (3)
|
||||||
temperatures and two (2) voltages. It has three (3) 16-bit counters for
|
temperatures and two (2) voltages. It has four (4) 16-bit counters for
|
||||||
measuring fan speed. There are three (3) PWM outputs that can be used
|
measuring fan speed. There are three (3) PWM outputs that can be used
|
||||||
to control fan speed.
|
to control fan speed.
|
||||||
|
|
||||||
A sophisticated control system for the PWM outputs is designed into the
|
A sophisticated control system for the PWM outputs is designed into the
|
||||||
LM85 that allows fan speed to be adjusted automatically based on any of the
|
ADT7473 that allows fan speed to be adjusted automatically based on any of the
|
||||||
three temperature sensors. Each PWM output is individually adjustable and
|
three temperature sensors. Each PWM output is individually adjustable and
|
||||||
programmable. Once configured, the ADT7473 will adjust the PWM outputs in
|
programmable. Once configured, the ADT7473 will adjust the PWM outputs in
|
||||||
response to the measured temperatures without further host intervention.
|
response to the measured temperatures without further host intervention.
|
||||||
|
@ -46,14 +46,6 @@ from the raw value to get the temperature value.
|
||||||
The Analog Devices datasheet is very detailed and describes a procedure for
|
The Analog Devices datasheet is very detailed and describes a procedure for
|
||||||
determining an optimal configuration for the automatic PWM control.
|
determining an optimal configuration for the automatic PWM control.
|
||||||
|
|
||||||
Hardware Configurations
|
|
||||||
-----------------------
|
|
||||||
|
|
||||||
The ADT7473 chips have an optional SMBALERT output that can be used to
|
|
||||||
signal the chipset in case a limit is exceeded or the temperature sensors
|
|
||||||
fail. Individual sensor interrupts can be masked so they won't trigger
|
|
||||||
SMBALERT. The SMBALERT output if configured replaces the PWM2 function.
|
|
||||||
|
|
||||||
Configuration Notes
|
Configuration Notes
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
|
@ -61,8 +53,8 @@ Besides standard interfaces driver adds the following:
|
||||||
|
|
||||||
* PWM Control
|
* PWM Control
|
||||||
|
|
||||||
* pwm#_auto_point1_pwm and pwm#_auto_point1_temp and
|
* pwm#_auto_point1_pwm and temp#_auto_point1_temp and
|
||||||
* pwm#_auto_point2_pwm and pwm#_auto_point2_temp -
|
* pwm#_auto_point2_pwm and temp#_auto_point2_temp -
|
||||||
|
|
||||||
point1: Set the pwm speed at a lower temperature bound.
|
point1: Set the pwm speed at a lower temperature bound.
|
||||||
point2: Set the pwm speed at a higher temperature bound.
|
point2: Set the pwm speed at a higher temperature bound.
|
||||||
|
|
|
@ -329,6 +329,10 @@ power[1-*]_average Average power use
|
||||||
Unit: microWatt
|
Unit: microWatt
|
||||||
RO
|
RO
|
||||||
|
|
||||||
|
power[1-*]_average_interval Power use averaging interval
|
||||||
|
Unit: milliseconds
|
||||||
|
RW
|
||||||
|
|
||||||
power[1-*]_average_highest Historical average maximum power use
|
power[1-*]_average_highest Historical average maximum power use
|
||||||
Unit: microWatt
|
Unit: microWatt
|
||||||
RO
|
RO
|
||||||
|
@ -353,6 +357,14 @@ power[1-*]_reset_history Reset input_highest, input_lowest,
|
||||||
average_highest and average_lowest.
|
average_highest and average_lowest.
|
||||||
WO
|
WO
|
||||||
|
|
||||||
|
**********
|
||||||
|
* Energy *
|
||||||
|
**********
|
||||||
|
|
||||||
|
energy[1-*]_input Cumulative energy use
|
||||||
|
Unit: microJoule
|
||||||
|
RO
|
||||||
|
|
||||||
**********
|
**********
|
||||||
* Alarms *
|
* Alarms *
|
||||||
**********
|
**********
|
||||||
|
|
|
@ -279,7 +279,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
|
||||||
{ "OTES1 Fan", 36, 2, 60, 1, 0 },
|
{ "OTES1 Fan", 36, 2, 60, 1, 0 },
|
||||||
{ NULL, 0, 0, 0, 0, 0 } }
|
{ NULL, 0, 0, 0, 0, 0 } }
|
||||||
},
|
},
|
||||||
{ 0x0011, NULL /* Abit AT8 32X, need DMI string */, {
|
{ 0x0011, "AT8 32X(ATI RD580-ULI M1575)", {
|
||||||
{ "CPU Core", 0, 0, 10, 1, 0 },
|
{ "CPU Core", 0, 0, 10, 1, 0 },
|
||||||
{ "DDR", 1, 0, 20, 1, 0 },
|
{ "DDR", 1, 0, 20, 1, 0 },
|
||||||
{ "DDR VTT", 2, 0, 10, 1, 0 },
|
{ "DDR VTT", 2, 0, 10, 1, 0 },
|
||||||
|
@ -303,6 +303,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
|
||||||
{ "SYS Fan", 34, 2, 60, 1, 0 },
|
{ "SYS Fan", 34, 2, 60, 1, 0 },
|
||||||
{ "AUX1 Fan", 35, 2, 60, 1, 0 },
|
{ "AUX1 Fan", 35, 2, 60, 1, 0 },
|
||||||
{ "AUX2 Fan", 36, 2, 60, 1, 0 },
|
{ "AUX2 Fan", 36, 2, 60, 1, 0 },
|
||||||
|
{ "AUX3 Fan", 37, 2, 60, 1, 0 },
|
||||||
{ NULL, 0, 0, 0, 0, 0 } }
|
{ NULL, 0, 0, 0, 0, 0 } }
|
||||||
},
|
},
|
||||||
{ 0x0012, NULL /* Abit AN8 32X, need DMI string */, {
|
{ 0x0012, NULL /* Abit AN8 32X, need DMI string */, {
|
||||||
|
|
|
@ -46,6 +46,8 @@
|
||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
#include <linux/mutex.h>
|
#include <linux/mutex.h>
|
||||||
#include <linux/sysfs.h>
|
#include <linux/sysfs.h>
|
||||||
|
#include <linux/string.h>
|
||||||
|
#include <linux/dmi.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
|
|
||||||
#define DRVNAME "it87"
|
#define DRVNAME "it87"
|
||||||
|
@ -236,6 +238,8 @@ struct it87_sio_data {
|
||||||
/* Values read from Super-I/O config space */
|
/* Values read from Super-I/O config space */
|
||||||
u8 revision;
|
u8 revision;
|
||||||
u8 vid_value;
|
u8 vid_value;
|
||||||
|
/* Values set based on DMI strings */
|
||||||
|
u8 skip_pwm;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* For each registered chip, we need to keep some data in memory.
|
/* For each registered chip, we need to keep some data in memory.
|
||||||
|
@ -964,6 +968,7 @@ static int __init it87_find(unsigned short *address,
|
||||||
{
|
{
|
||||||
int err = -ENODEV;
|
int err = -ENODEV;
|
||||||
u16 chip_type;
|
u16 chip_type;
|
||||||
|
const char *board_vendor, *board_name;
|
||||||
|
|
||||||
superio_enter();
|
superio_enter();
|
||||||
chip_type = force_id ? force_id : superio_inw(DEVID);
|
chip_type = force_id ? force_id : superio_inw(DEVID);
|
||||||
|
@ -1022,6 +1027,24 @@ static int __init it87_find(unsigned short *address,
|
||||||
pr_info("it87: in7 is VCCH (+5V Stand-By)\n");
|
pr_info("it87: in7 is VCCH (+5V Stand-By)\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Disable specific features based on DMI strings */
|
||||||
|
board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR);
|
||||||
|
board_name = dmi_get_system_info(DMI_BOARD_NAME);
|
||||||
|
if (board_vendor && board_name) {
|
||||||
|
if (strcmp(board_vendor, "nVIDIA") == 0
|
||||||
|
&& strcmp(board_name, "FN68PT") == 0) {
|
||||||
|
/* On the Shuttle SN68PT, FAN_CTL2 is apparently not
|
||||||
|
connected to a fan, but to something else. One user
|
||||||
|
has reported instant system power-off when changing
|
||||||
|
the PWM2 duty cycle, so we disable it.
|
||||||
|
I use the board name string as the trigger in case
|
||||||
|
the same board is ever used in other systems. */
|
||||||
|
pr_info("it87: Disabling pwm2 due to "
|
||||||
|
"hardware constraints\n");
|
||||||
|
sio_data->skip_pwm = (1 << 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
superio_exit();
|
superio_exit();
|
||||||
return err;
|
return err;
|
||||||
|
@ -1168,25 +1191,33 @@ static int __devinit it87_probe(struct platform_device *pdev)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (enable_pwm_interface) {
|
if (enable_pwm_interface) {
|
||||||
if ((err = device_create_file(dev,
|
if (!(sio_data->skip_pwm & (1 << 0))) {
|
||||||
&sensor_dev_attr_pwm1_enable.dev_attr))
|
if ((err = device_create_file(dev,
|
||||||
|| (err = device_create_file(dev,
|
&sensor_dev_attr_pwm1_enable.dev_attr))
|
||||||
&sensor_dev_attr_pwm2_enable.dev_attr))
|
|| (err = device_create_file(dev,
|
||||||
|| (err = device_create_file(dev,
|
&sensor_dev_attr_pwm1.dev_attr))
|
||||||
&sensor_dev_attr_pwm3_enable.dev_attr))
|
|| (err = device_create_file(dev,
|
||||||
|| (err = device_create_file(dev,
|
&dev_attr_pwm1_freq)))
|
||||||
&sensor_dev_attr_pwm1.dev_attr))
|
goto ERROR4;
|
||||||
|| (err = device_create_file(dev,
|
}
|
||||||
&sensor_dev_attr_pwm2.dev_attr))
|
if (!(sio_data->skip_pwm & (1 << 1))) {
|
||||||
|| (err = device_create_file(dev,
|
if ((err = device_create_file(dev,
|
||||||
&sensor_dev_attr_pwm3.dev_attr))
|
&sensor_dev_attr_pwm2_enable.dev_attr))
|
||||||
|| (err = device_create_file(dev,
|
|| (err = device_create_file(dev,
|
||||||
&dev_attr_pwm1_freq))
|
&sensor_dev_attr_pwm2.dev_attr))
|
||||||
|| (err = device_create_file(dev,
|
|| (err = device_create_file(dev,
|
||||||
&dev_attr_pwm2_freq))
|
&dev_attr_pwm2_freq)))
|
||||||
|| (err = device_create_file(dev,
|
goto ERROR4;
|
||||||
&dev_attr_pwm3_freq)))
|
}
|
||||||
goto ERROR4;
|
if (!(sio_data->skip_pwm & (1 << 2))) {
|
||||||
|
if ((err = device_create_file(dev,
|
||||||
|
&sensor_dev_attr_pwm3_enable.dev_attr))
|
||||||
|
|| (err = device_create_file(dev,
|
||||||
|
&sensor_dev_attr_pwm3.dev_attr))
|
||||||
|
|| (err = device_create_file(dev,
|
||||||
|
&dev_attr_pwm3_freq)))
|
||||||
|
goto ERROR4;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data->type == it8712 || data->type == it8716
|
if (data->type == it8712 || data->type == it8716
|
||||||
|
@ -1546,6 +1577,7 @@ static int __init sm_it87_init(void)
|
||||||
unsigned short isa_address=0;
|
unsigned short isa_address=0;
|
||||||
struct it87_sio_data sio_data;
|
struct it87_sio_data sio_data;
|
||||||
|
|
||||||
|
memset(&sio_data, 0, sizeof(struct it87_sio_data));
|
||||||
err = it87_find(&isa_address, &sio_data);
|
err = it87_find(&isa_address, &sio_data);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
|
@ -450,12 +450,14 @@ static int eeepc_get_fan_pwm(void)
|
||||||
int value = 0;
|
int value = 0;
|
||||||
|
|
||||||
read_acpi_int(NULL, EEEPC_EC_FAN_PWM, &value);
|
read_acpi_int(NULL, EEEPC_EC_FAN_PWM, &value);
|
||||||
|
value = value * 255 / 100;
|
||||||
return (value);
|
return (value);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void eeepc_set_fan_pwm(int value)
|
static void eeepc_set_fan_pwm(int value)
|
||||||
{
|
{
|
||||||
value = SENSORS_LIMIT(value, 0, 100);
|
value = SENSORS_LIMIT(value, 0, 255);
|
||||||
|
value = value * 100 / 255;
|
||||||
ec_write(EEEPC_EC_SC02, value);
|
ec_write(EEEPC_EC_SC02, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -520,15 +522,23 @@ static ssize_t show_sys_hwmon(int (*get)(void), char *buf)
|
||||||
static SENSOR_DEVICE_ATTR(_name, _mode, show_##_name, store_##_name, 0);
|
static SENSOR_DEVICE_ATTR(_name, _mode, show_##_name, store_##_name, 0);
|
||||||
|
|
||||||
EEEPC_CREATE_SENSOR_ATTR(fan1_input, S_IRUGO, eeepc_get_fan_rpm, NULL);
|
EEEPC_CREATE_SENSOR_ATTR(fan1_input, S_IRUGO, eeepc_get_fan_rpm, NULL);
|
||||||
EEEPC_CREATE_SENSOR_ATTR(fan1_pwm, S_IRUGO | S_IWUSR,
|
EEEPC_CREATE_SENSOR_ATTR(pwm1, S_IRUGO | S_IWUSR,
|
||||||
eeepc_get_fan_pwm, eeepc_set_fan_pwm);
|
eeepc_get_fan_pwm, eeepc_set_fan_pwm);
|
||||||
EEEPC_CREATE_SENSOR_ATTR(pwm1_enable, S_IRUGO | S_IWUSR,
|
EEEPC_CREATE_SENSOR_ATTR(pwm1_enable, S_IRUGO | S_IWUSR,
|
||||||
eeepc_get_fan_ctrl, eeepc_set_fan_ctrl);
|
eeepc_get_fan_ctrl, eeepc_set_fan_ctrl);
|
||||||
|
|
||||||
|
static ssize_t
|
||||||
|
show_name(struct device *dev, struct device_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
return sprintf(buf, "eeepc\n");
|
||||||
|
}
|
||||||
|
static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, 0);
|
||||||
|
|
||||||
static struct attribute *hwmon_attributes[] = {
|
static struct attribute *hwmon_attributes[] = {
|
||||||
&sensor_dev_attr_fan1_pwm.dev_attr.attr,
|
&sensor_dev_attr_pwm1.dev_attr.attr,
|
||||||
&sensor_dev_attr_fan1_input.dev_attr.attr,
|
&sensor_dev_attr_fan1_input.dev_attr.attr,
|
||||||
&sensor_dev_attr_pwm1_enable.dev_attr.attr,
|
&sensor_dev_attr_pwm1_enable.dev_attr.attr,
|
||||||
|
&sensor_dev_attr_name.dev_attr.attr,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue