summaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/w83627ehf.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwmon/w83627ehf.c')
-rw-r--r--drivers/hwmon/w83627ehf.c72
1 files changed, 40 insertions, 32 deletions
diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c
index c51ae2e1775..b15c6a998b7 100644
--- a/drivers/hwmon/w83627ehf.c
+++ b/drivers/hwmon/w83627ehf.c
@@ -223,7 +223,7 @@ temp1_from_reg(s8 reg)
}
static inline s8
-temp1_to_reg(int temp, int min, int max)
+temp1_to_reg(long temp, int min, int max)
{
if (temp <= min)
return min / 1000;
@@ -256,7 +256,7 @@ struct w83627ehf_data {
int addr; /* IO base of hw monitor block */
const char *name;
- struct class_device *class_dev;
+ struct device *hwmon_dev;
struct mutex lock;
struct mutex update_lock;
@@ -309,18 +309,16 @@ static inline int is_word_sized(u16 reg)
|| (reg & 0x00ff) == 0x55));
}
-/* We assume that the default bank is 0, thus the following two functions do
- nothing for registers which live in bank 0. For others, they respectively
- set the bank register to the correct value (before the register is
- accessed), and back to 0 (afterwards). */
+/* Registers 0x50-0x5f are banked */
static inline void w83627ehf_set_bank(struct w83627ehf_data *data, u16 reg)
{
- if (reg & 0xff00) {
+ if ((reg & 0x00f0) == 0x50) {
outb_p(W83627EHF_REG_BANK, data->addr + ADDR_REG_OFFSET);
outb_p(reg >> 8, data->addr + DATA_REG_OFFSET);
}
}
+/* Not strictly necessary, but play it safe for now */
static inline void w83627ehf_reset_bank(struct w83627ehf_data *data, u16 reg)
{
if (reg & 0xff00) {
@@ -421,6 +419,31 @@ static void w83627ehf_write_fan_div(struct w83627ehf_data *data, int nr)
}
}
+static void w83627ehf_update_fan_div(struct w83627ehf_data *data)
+{
+ int i;
+
+ i = w83627ehf_read_value(data, W83627EHF_REG_FANDIV1);
+ data->fan_div[0] = (i >> 4) & 0x03;
+ data->fan_div[1] = (i >> 6) & 0x03;
+ i = w83627ehf_read_value(data, W83627EHF_REG_FANDIV2);
+ data->fan_div[2] = (i >> 6) & 0x03;
+ i = w83627ehf_read_value(data, W83627EHF_REG_VBAT);
+ data->fan_div[0] |= (i >> 3) & 0x04;
+ data->fan_div[1] |= (i >> 4) & 0x04;
+ data->fan_div[2] |= (i >> 5) & 0x04;
+ if (data->has_fan & ((1 << 3) | (1 << 4))) {
+ i = w83627ehf_read_value(data, W83627EHF_REG_DIODE);
+ data->fan_div[3] = i & 0x03;
+ data->fan_div[4] = ((i >> 2) & 0x03)
+ | ((i >> 5) & 0x04);
+ }
+ if (data->has_fan & (1 << 3)) {
+ i = w83627ehf_read_value(data, W83627EHF_REG_SMI_OVT);
+ data->fan_div[3] |= (i >> 5) & 0x04;
+ }
+}
+
static struct w83627ehf_data *w83627ehf_update_device(struct device *dev)
{
struct w83627ehf_data *data = dev_get_drvdata(dev);
@@ -432,25 +455,7 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev)
if (time_after(jiffies, data->last_updated + HZ + HZ/2)
|| !data->valid) {
/* Fan clock dividers */
- i = w83627ehf_read_value(data, W83627EHF_REG_FANDIV1);
- data->fan_div[0] = (i >> 4) & 0x03;
- data->fan_div[1] = (i >> 6) & 0x03;
- i = w83627ehf_read_value(data, W83627EHF_REG_FANDIV2);
- data->fan_div[2] = (i >> 6) & 0x03;
- i = w83627ehf_read_value(data, W83627EHF_REG_VBAT);
- data->fan_div[0] |= (i >> 3) & 0x04;
- data->fan_div[1] |= (i >> 4) & 0x04;
- data->fan_div[2] |= (i >> 5) & 0x04;
- if (data->has_fan & ((1 << 3) | (1 << 4))) {
- i = w83627ehf_read_value(data, W83627EHF_REG_DIODE);
- data->fan_div[3] = i & 0x03;
- data->fan_div[4] = ((i >> 2) & 0x03)
- | ((i >> 5) & 0x04);
- }
- if (data->has_fan & (1 << 3)) {
- i = w83627ehf_read_value(data, W83627EHF_REG_SMI_OVT);
- data->fan_div[3] |= (i >> 5) & 0x04;
- }
+ w83627ehf_update_fan_div(data);
/* Measured voltages and limits */
for (i = 0; i < data->in_num; i++) {
@@ -800,7 +805,7 @@ store_temp1_##reg(struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
struct w83627ehf_data *data = dev_get_drvdata(dev); \
- u32 val = simple_strtoul(buf, NULL, 10); \
+ long val = simple_strtol(buf, NULL, 10); \
\
mutex_lock(&data->update_lock); \
data->temp1_##reg = temp1_to_reg(val, -128000, 127000); \
@@ -835,7 +840,7 @@ store_##reg(struct device *dev, struct device_attribute *attr, \
struct w83627ehf_data *data = dev_get_drvdata(dev); \
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \
int nr = sensor_attr->index; \
- u32 val = simple_strtoul(buf, NULL, 10); \
+ long val = simple_strtol(buf, NULL, 10); \
\
mutex_lock(&data->update_lock); \
data->reg[nr] = LM75_TEMP_TO_REG(val); \
@@ -1312,6 +1317,9 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
if (!(i & (1 << 1)) && (!fan5pin))
data->has_fan |= (1 << 4);
+ /* Read fan clock dividers immediately */
+ w83627ehf_update_fan_div(data);
+
/* Register sysfs hooks */
for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays); i++)
if ((err = device_create_file(dev,
@@ -1376,9 +1384,9 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
goto exit_remove;
}
- data->class_dev = hwmon_device_register(dev);
- if (IS_ERR(data->class_dev)) {
- err = PTR_ERR(data->class_dev);
+ data->hwmon_dev = hwmon_device_register(dev);
+ if (IS_ERR(data->hwmon_dev)) {
+ err = PTR_ERR(data->hwmon_dev);
goto exit_remove;
}
@@ -1398,7 +1406,7 @@ static int __devexit w83627ehf_remove(struct platform_device *pdev)
{
struct w83627ehf_data *data = platform_get_drvdata(pdev);
- hwmon_device_unregister(data->class_dev);
+ hwmon_device_unregister(data->hwmon_dev);
w83627ehf_device_remove_files(&pdev->dev);
release_region(data->addr, IOREGION_LENGTH);
platform_set_drvdata(pdev, NULL);