Merge branch 'release' of git://lm-sensors.org/kernel/mhoffman/hwmon-2.6
* 'release' of git://lm-sensors.org/kernel/mhoffman/hwmon-2.6: hwmon: (lm75) sensor reading bugfix hwmon: (abituguru3) update driver detection hwmon: (w83791d) new maintainer hwmon: (abituguru3) Identify Abit AW8D board as such hwmon: Update the sysfs interface documentation hwmon: (adt7473) Initialize max_duty_at_overheat before use hwmon: (lm85) Fix function RANGE_TO_REG()
This commit is contained in:
@@ -2,17 +2,12 @@ Naming and data format standards for sysfs files
|
|||||||
------------------------------------------------
|
------------------------------------------------
|
||||||
|
|
||||||
The libsensors library offers an interface to the raw sensors data
|
The libsensors library offers an interface to the raw sensors data
|
||||||
through the sysfs interface. See libsensors documentation and source for
|
through the sysfs interface. Since lm-sensors 3.0.0, libsensors is
|
||||||
further information. As of writing this document, libsensors
|
completely chip-independent. It assumes that all the kernel drivers
|
||||||
(from lm_sensors 2.8.3) is heavily chip-dependent. Adding or updating
|
implement the standard sysfs interface described in this document.
|
||||||
support for any given chip requires modifying the library's code.
|
This makes adding or updating support for any given chip very easy, as
|
||||||
This is because libsensors was written for the procfs interface
|
libsensors, and applications using it, do not need to be modified.
|
||||||
older kernel modules were using, which wasn't standardized enough.
|
This is a major improvement compared to lm-sensors 2.
|
||||||
Recent versions of libsensors (from lm_sensors 2.8.2 and later) have
|
|
||||||
support for the sysfs interface, though.
|
|
||||||
|
|
||||||
The new sysfs interface was designed to be as chip-independent as
|
|
||||||
possible.
|
|
||||||
|
|
||||||
Note that motherboards vary widely in the connections to sensor chips.
|
Note that motherboards vary widely in the connections to sensor chips.
|
||||||
There is no standard that ensures, for example, that the second
|
There is no standard that ensures, for example, that the second
|
||||||
@@ -35,19 +30,17 @@ access this data in a simple and consistent way. That said, such programs
|
|||||||
will have to implement conversion, labeling and hiding of inputs. For
|
will have to implement conversion, labeling and hiding of inputs. For
|
||||||
this reason, it is still not recommended to bypass the library.
|
this reason, it is still not recommended to bypass the library.
|
||||||
|
|
||||||
If you are developing a userspace application please send us feedback on
|
|
||||||
this standard.
|
|
||||||
|
|
||||||
Note that this standard isn't completely established yet, so it is subject
|
|
||||||
to changes. If you are writing a new hardware monitoring driver those
|
|
||||||
features can't seem to fit in this interface, please contact us with your
|
|
||||||
extension proposal. Keep in mind that backward compatibility must be
|
|
||||||
preserved.
|
|
||||||
|
|
||||||
Each chip gets its own directory in the sysfs /sys/devices tree. To
|
Each chip gets its own directory in the sysfs /sys/devices tree. To
|
||||||
find all sensor chips, it is easier to follow the device symlinks from
|
find all sensor chips, it is easier to follow the device symlinks from
|
||||||
/sys/class/hwmon/hwmon*.
|
/sys/class/hwmon/hwmon*.
|
||||||
|
|
||||||
|
Up to lm-sensors 3.0.0, libsensors looks for hardware monitoring attributes
|
||||||
|
in the "physical" device directory. Since lm-sensors 3.0.1, attributes found
|
||||||
|
in the hwmon "class" device directory are also supported. Complex drivers
|
||||||
|
(e.g. drivers for multifunction chips) may want to use this possibility to
|
||||||
|
avoid namespace pollution. The only drawback will be that older versions of
|
||||||
|
libsensors won't support the driver in question.
|
||||||
|
|
||||||
All sysfs values are fixed point numbers.
|
All sysfs values are fixed point numbers.
|
||||||
|
|
||||||
There is only one value per file, unlike the older /proc specification.
|
There is only one value per file, unlike the older /proc specification.
|
||||||
|
|||||||
@@ -4431,10 +4431,10 @@ M: johnpol@2ka.mipt.ru
|
|||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
||||||
W83791D HARDWARE MONITORING DRIVER
|
W83791D HARDWARE MONITORING DRIVER
|
||||||
P: Charles Spirakis
|
P: Marc Hulsman
|
||||||
M: bezaur@gmail.com
|
M: m.hulsman@tudelft.nl
|
||||||
L: lm-sensors@lm-sensors.org
|
L: lm-sensors@lm-sensors.org
|
||||||
S: Odd Fixes
|
S: Maintained
|
||||||
|
|
||||||
W83793 HARDWARE MONITORING DRIVER
|
W83793 HARDWARE MONITORING DRIVER
|
||||||
P: Rudolf Marek
|
P: Rudolf Marek
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/hwmon.h>
|
#include <linux/hwmon.h>
|
||||||
#include <linux/hwmon-sysfs.h>
|
#include <linux/hwmon-sysfs.h>
|
||||||
|
#include <linux/dmi.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
|
|
||||||
/* uGuru3 bank addresses */
|
/* uGuru3 bank addresses */
|
||||||
@@ -323,7 +324,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
|
|||||||
{ "AUX1 Fan", 36, 2, 60, 1, 0 },
|
{ "AUX1 Fan", 36, 2, 60, 1, 0 },
|
||||||
{ NULL, 0, 0, 0, 0, 0 } }
|
{ NULL, 0, 0, 0, 0, 0 } }
|
||||||
},
|
},
|
||||||
{ 0x0013, "unknown", {
|
{ 0x0013, "Abit AW8D", {
|
||||||
{ "CPU Core", 0, 0, 10, 1, 0 },
|
{ "CPU Core", 0, 0, 10, 1, 0 },
|
||||||
{ "DDR", 1, 0, 10, 1, 0 },
|
{ "DDR", 1, 0, 10, 1, 0 },
|
||||||
{ "DDR VTT", 2, 0, 10, 1, 0 },
|
{ "DDR VTT", 2, 0, 10, 1, 0 },
|
||||||
@@ -349,6 +350,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
|
|||||||
{ "AUX2 Fan", 36, 2, 60, 1, 0 },
|
{ "AUX2 Fan", 36, 2, 60, 1, 0 },
|
||||||
{ "AUX3 Fan", 37, 2, 60, 1, 0 },
|
{ "AUX3 Fan", 37, 2, 60, 1, 0 },
|
||||||
{ "AUX4 Fan", 38, 2, 60, 1, 0 },
|
{ "AUX4 Fan", 38, 2, 60, 1, 0 },
|
||||||
|
{ "AUX5 Fan", 39, 2, 60, 1, 0 },
|
||||||
{ NULL, 0, 0, 0, 0, 0 } }
|
{ NULL, 0, 0, 0, 0, 0 } }
|
||||||
},
|
},
|
||||||
{ 0x0014, "Abit AB9 Pro", {
|
{ 0x0014, "Abit AB9 Pro", {
|
||||||
@@ -1111,11 +1113,12 @@ static int __init abituguru3_detect(void)
|
|||||||
{
|
{
|
||||||
/* See if there is an uguru3 there. An idle uGuru3 will hold 0x00 or
|
/* See if there is an uguru3 there. An idle uGuru3 will hold 0x00 or
|
||||||
0x08 at DATA and 0xAC at CMD. Sometimes the uGuru3 will hold 0x05
|
0x08 at DATA and 0xAC at CMD. Sometimes the uGuru3 will hold 0x05
|
||||||
at CMD instead, why is unknown. So we test for 0x05 too. */
|
or 0x55 at CMD instead, why is unknown. */
|
||||||
u8 data_val = inb_p(ABIT_UGURU3_BASE + ABIT_UGURU3_DATA);
|
u8 data_val = inb_p(ABIT_UGURU3_BASE + ABIT_UGURU3_DATA);
|
||||||
u8 cmd_val = inb_p(ABIT_UGURU3_BASE + ABIT_UGURU3_CMD);
|
u8 cmd_val = inb_p(ABIT_UGURU3_BASE + ABIT_UGURU3_CMD);
|
||||||
if (((data_val == 0x00) || (data_val == 0x08)) &&
|
if (((data_val == 0x00) || (data_val == 0x08)) &&
|
||||||
((cmd_val == 0xAC) || (cmd_val == 0x05)))
|
((cmd_val == 0xAC) || (cmd_val == 0x05) ||
|
||||||
|
(cmd_val == 0x55)))
|
||||||
return ABIT_UGURU3_BASE;
|
return ABIT_UGURU3_BASE;
|
||||||
|
|
||||||
ABIT_UGURU3_DEBUG("no Abit uGuru3 found, data = 0x%02X, cmd = "
|
ABIT_UGURU3_DEBUG("no Abit uGuru3 found, data = 0x%02X, cmd = "
|
||||||
@@ -1138,6 +1141,15 @@ static int __init abituguru3_init(void)
|
|||||||
int address, err;
|
int address, err;
|
||||||
struct resource res = { .flags = IORESOURCE_IO };
|
struct resource res = { .flags = IORESOURCE_IO };
|
||||||
|
|
||||||
|
#ifdef CONFIG_DMI
|
||||||
|
const char *board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR);
|
||||||
|
|
||||||
|
/* safety check, refuse to load on non Abit motherboards */
|
||||||
|
if (!force && (!board_vendor ||
|
||||||
|
strcmp(board_vendor, "http://www.abit.com.tw/")))
|
||||||
|
return -ENODEV;
|
||||||
|
#endif
|
||||||
|
|
||||||
address = abituguru3_detect();
|
address = abituguru3_detect();
|
||||||
if (address < 0)
|
if (address < 0)
|
||||||
return address;
|
return address;
|
||||||
|
|||||||
@@ -309,6 +309,9 @@ no_sensor_update:
|
|||||||
ADT7473_REG_PWM_BHVR(i));
|
ADT7473_REG_PWM_BHVR(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
i = i2c_smbus_read_byte_data(client, ADT7473_REG_CFG4);
|
||||||
|
data->max_duty_at_overheat = !!(i & ADT7473_CFG4_MAX_DUTY_AT_OVT);
|
||||||
|
|
||||||
data->limits_last_updated = local_jiffies;
|
data->limits_last_updated = local_jiffies;
|
||||||
data->limits_valid = 1;
|
data->limits_valid = 1;
|
||||||
|
|
||||||
|
|||||||
@@ -251,10 +251,13 @@ static int lm75_detach_client(struct i2c_client *client)
|
|||||||
the SMBus standard. */
|
the SMBus standard. */
|
||||||
static int lm75_read_value(struct i2c_client *client, u8 reg)
|
static int lm75_read_value(struct i2c_client *client, u8 reg)
|
||||||
{
|
{
|
||||||
|
int value;
|
||||||
|
|
||||||
if (reg == LM75_REG_CONF)
|
if (reg == LM75_REG_CONF)
|
||||||
return i2c_smbus_read_byte_data(client, reg);
|
return i2c_smbus_read_byte_data(client, reg);
|
||||||
else
|
|
||||||
return swab16(i2c_smbus_read_word_data(client, reg));
|
value = i2c_smbus_read_word_data(client, reg);
|
||||||
|
return (value < 0) ? value : swab16(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int lm75_write_value(struct i2c_client *client, u8 reg, u16 value)
|
static int lm75_write_value(struct i2c_client *client, u8 reg, u16 value)
|
||||||
@@ -287,9 +290,16 @@ static struct lm75_data *lm75_update_device(struct device *dev)
|
|||||||
int i;
|
int i;
|
||||||
dev_dbg(&client->dev, "Starting lm75 update\n");
|
dev_dbg(&client->dev, "Starting lm75 update\n");
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(data->temp); i++)
|
for (i = 0; i < ARRAY_SIZE(data->temp); i++) {
|
||||||
data->temp[i] = lm75_read_value(client,
|
int status;
|
||||||
LM75_REG_TEMP[i]);
|
|
||||||
|
status = lm75_read_value(client, LM75_REG_TEMP[i]);
|
||||||
|
if (status < 0)
|
||||||
|
dev_dbg(&client->dev, "reg %d, err %d\n",
|
||||||
|
LM75_REG_TEMP[i], status);
|
||||||
|
else
|
||||||
|
data->temp[i] = status;
|
||||||
|
}
|
||||||
data->last_updated = jiffies;
|
data->last_updated = jiffies;
|
||||||
data->valid = 1;
|
data->valid = 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -192,23 +192,20 @@ static int RANGE_TO_REG( int range )
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if ( range < lm85_range_map[0] ) {
|
if (range >= lm85_range_map[15])
|
||||||
return 0 ;
|
|
||||||
} else if ( range > lm85_range_map[15] ) {
|
|
||||||
return 15 ;
|
return 15 ;
|
||||||
} else { /* find closest match */
|
|
||||||
for ( i = 14 ; i >= 0 ; --i ) {
|
/* Find the closest match */
|
||||||
if ( range > lm85_range_map[i] ) { /* range bracketed */
|
for (i = 14; i >= 0; --i) {
|
||||||
if ((lm85_range_map[i+1] - range) <
|
if (range >= lm85_range_map[i]) {
|
||||||
(range - lm85_range_map[i])) {
|
if ((lm85_range_map[i + 1] - range) <
|
||||||
i++;
|
(range - lm85_range_map[i]))
|
||||||
break;
|
return i + 1;
|
||||||
}
|
return i;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return( i & 0x0f );
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
#define RANGE_FROM_REG(val) (lm85_range_map[(val)&0x0f])
|
#define RANGE_FROM_REG(val) (lm85_range_map[(val)&0x0f])
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user