X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fhwmon%2Fw83627ehf.c;fp=drivers%2Fhwmon%2Fw83627ehf.c;h=12d79f5e4900cf4db5a142d66cd0a9d2fc39ba1b;hb=64ba3f394c830ec48a1c31b53dcae312c56f1604;hp=40301bc6ce186e5a1c92c7a7d9964e945807dac7;hpb=be1e6109ac94a859551f8e1774eb9a8469fe055c;p=linux-2.6.git diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c index 40301bc6c..12d79f5e4 100644 --- a/drivers/hwmon/w83627ehf.c +++ b/drivers/hwmon/w83627ehf.c @@ -30,7 +30,10 @@ Supports the following chips: Chip #vin #fan #pwm #temp chip_id man_id - w83627ehf 10 5 - 3 0x88 0x5ca3 + w83627ehf - 5 - 3 0x88 0x5ca3 + + This is a preliminary version of the driver, only supporting the + fan and temperature inputs. The chip does much more than that. */ #include @@ -39,9 +42,7 @@ #include #include #include -#include #include -#include #include #include "lm75.h" @@ -118,14 +119,6 @@ superio_exit(void) static const u16 W83627EHF_REG_FAN[] = { 0x28, 0x29, 0x2a, 0x3f, 0x553 }; static const u16 W83627EHF_REG_FAN_MIN[] = { 0x3b, 0x3c, 0x3d, 0x3e, 0x55c }; -/* The W83627EHF registers for nr=7,8,9 are in bank 5 */ -#define W83627EHF_REG_IN_MAX(nr) ((nr < 7) ? (0x2b + (nr) * 2) : \ - (0x554 + (((nr) - 7) * 2))) -#define W83627EHF_REG_IN_MIN(nr) ((nr < 7) ? (0x2c + (nr) * 2) : \ - (0x555 + (((nr) - 7) * 2))) -#define W83627EHF_REG_IN(nr) ((nr < 7) ? (0x20 + (nr)) : \ - (0x550 + (nr) - 7)) - #define W83627EHF_REG_TEMP1 0x27 #define W83627EHF_REG_TEMP1_HYST 0x3a #define W83627EHF_REG_TEMP1_OVER 0x39 @@ -141,10 +134,6 @@ static const u16 W83627EHF_REG_TEMP_CONFIG[] = { 0x152, 0x252 }; #define W83627EHF_REG_DIODE 0x59 #define W83627EHF_REG_SMI_OVT 0x4C -#define W83627EHF_REG_ALARM1 0x459 -#define W83627EHF_REG_ALARM2 0x45A -#define W83627EHF_REG_ALARM3 0x45B - /* * Conversions */ @@ -181,20 +170,6 @@ temp1_to_reg(int temp) return (temp + 500) / 1000; } -/* Some of analog inputs have internal scaling (2x), 8mV is ADC LSB */ - -static u8 scale_in[10] = { 8, 8, 16, 16, 8, 8, 8, 16, 16, 8 }; - -static inline long in_from_reg(u8 reg, u8 nr) -{ - return reg * scale_in[nr]; -} - -static inline u8 in_to_reg(u32 val, u8 nr) -{ - return SENSORS_LIMIT(((val + (scale_in[nr] / 2)) / scale_in[nr]), 0, 255); -} - /* * Data structures and manipulation thereof */ @@ -202,16 +177,13 @@ static inline u8 in_to_reg(u32 val, u8 nr) struct w83627ehf_data { struct i2c_client client; struct class_device *class_dev; - struct mutex lock; + struct semaphore lock; - struct mutex update_lock; + struct semaphore update_lock; char valid; /* !=0 if following fields are valid */ unsigned long last_updated; /* In jiffies */ /* Register values */ - u8 in[10]; /* Register value */ - u8 in_max[10]; /* Register value */ - u8 in_min[10]; /* Register value */ u8 fan[5]; u8 fan_min[5]; u8 fan_div[5]; @@ -222,7 +194,6 @@ struct w83627ehf_data { s16 temp[2]; s16 temp_max[2]; s16 temp_max_hyst[2]; - u32 alarms; }; static inline int is_word_sized(u16 reg) @@ -259,7 +230,7 @@ static u16 w83627ehf_read_value(struct i2c_client *client, u16 reg) struct w83627ehf_data *data = i2c_get_clientdata(client); int res, word_sized = is_word_sized(reg); - mutex_lock(&data->lock); + down(&data->lock); w83627ehf_set_bank(client, reg); outb_p(reg & 0xff, client->addr + ADDR_REG_OFFSET); @@ -271,7 +242,7 @@ static u16 w83627ehf_read_value(struct i2c_client *client, u16 reg) } w83627ehf_reset_bank(client, reg); - mutex_unlock(&data->lock); + up(&data->lock); return res; } @@ -281,7 +252,7 @@ static int w83627ehf_write_value(struct i2c_client *client, u16 reg, u16 value) struct w83627ehf_data *data = i2c_get_clientdata(client); int word_sized = is_word_sized(reg); - mutex_lock(&data->lock); + down(&data->lock); w83627ehf_set_bank(client, reg); outb_p(reg & 0xff, client->addr + ADDR_REG_OFFSET); @@ -293,7 +264,7 @@ static int w83627ehf_write_value(struct i2c_client *client, u16 reg, u16 value) outb_p(value & 0xff, client->addr + DATA_REG_OFFSET); w83627ehf_reset_bank(client, reg); - mutex_unlock(&data->lock); + up(&data->lock); return 0; } @@ -351,7 +322,7 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) struct w83627ehf_data *data = i2c_get_clientdata(client); int i; - mutex_lock(&data->update_lock); + down(&data->update_lock); if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { @@ -376,16 +347,6 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) data->fan_div[3] |= (i >> 5) & 0x04; } - /* Measured voltages and limits */ - for (i = 0; i < 10; i++) { - data->in[i] = w83627ehf_read_value(client, - W83627EHF_REG_IN(i)); - data->in_min[i] = w83627ehf_read_value(client, - W83627EHF_REG_IN_MIN(i)); - data->in_max[i] = w83627ehf_read_value(client, - W83627EHF_REG_IN_MAX(i)); - } - /* Measured fan speeds and limits */ for (i = 0; i < 5; i++) { if (!(data->has_fan & (1 << i))) @@ -432,136 +393,23 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) W83627EHF_REG_TEMP_HYST[i]); } - data->alarms = w83627ehf_read_value(client, - W83627EHF_REG_ALARM1) | - (w83627ehf_read_value(client, - W83627EHF_REG_ALARM2) << 8) | - (w83627ehf_read_value(client, - W83627EHF_REG_ALARM3) << 16); - data->last_updated = jiffies; data->valid = 1; } - mutex_unlock(&data->update_lock); + up(&data->update_lock); return data; } /* * Sysfs callback functions */ -#define show_in_reg(reg) \ -static ssize_t \ -show_##reg(struct device *dev, struct device_attribute *attr, \ - char *buf) \ -{ \ - struct w83627ehf_data *data = w83627ehf_update_device(dev); \ - struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \ - int nr = sensor_attr->index; \ - return sprintf(buf, "%ld\n", in_from_reg(data->reg[nr], nr)); \ -} -show_in_reg(in) -show_in_reg(in_min) -show_in_reg(in_max) - -#define store_in_reg(REG, reg) \ -static ssize_t \ -store_in_##reg (struct device *dev, struct device_attribute *attr, \ - const char *buf, size_t count) \ -{ \ - struct i2c_client *client = to_i2c_client(dev); \ - struct w83627ehf_data *data = i2c_get_clientdata(client); \ - struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \ - int nr = sensor_attr->index; \ - u32 val = simple_strtoul(buf, NULL, 10); \ - \ - mutex_lock(&data->update_lock); \ - data->in_##reg[nr] = in_to_reg(val, nr); \ - w83627ehf_write_value(client, W83627EHF_REG_IN_##REG(nr), \ - data->in_##reg[nr]); \ - mutex_unlock(&data->update_lock); \ - return count; \ -} - -store_in_reg(MIN, min) -store_in_reg(MAX, max) - -static ssize_t show_alarm(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct w83627ehf_data *data = w83627ehf_update_device(dev); - struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); - int nr = sensor_attr->index; - return sprintf(buf, "%u\n", (data->alarms >> nr) & 0x01); -} - -static struct sensor_device_attribute sda_in_input[] = { - SENSOR_ATTR(in0_input, S_IRUGO, show_in, NULL, 0), - SENSOR_ATTR(in1_input, S_IRUGO, show_in, NULL, 1), - SENSOR_ATTR(in2_input, S_IRUGO, show_in, NULL, 2), - SENSOR_ATTR(in3_input, S_IRUGO, show_in, NULL, 3), - SENSOR_ATTR(in4_input, S_IRUGO, show_in, NULL, 4), - SENSOR_ATTR(in5_input, S_IRUGO, show_in, NULL, 5), - SENSOR_ATTR(in6_input, S_IRUGO, show_in, NULL, 6), - SENSOR_ATTR(in7_input, S_IRUGO, show_in, NULL, 7), - SENSOR_ATTR(in8_input, S_IRUGO, show_in, NULL, 8), - SENSOR_ATTR(in9_input, S_IRUGO, show_in, NULL, 9), -}; - -static struct sensor_device_attribute sda_in_alarm[] = { - SENSOR_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0), - SENSOR_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1), - SENSOR_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 2), - SENSOR_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, 3), - SENSOR_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, 8), - SENSOR_ATTR(in5_alarm, S_IRUGO, show_alarm, NULL, 21), - SENSOR_ATTR(in6_alarm, S_IRUGO, show_alarm, NULL, 20), - SENSOR_ATTR(in7_alarm, S_IRUGO, show_alarm, NULL, 16), - SENSOR_ATTR(in8_alarm, S_IRUGO, show_alarm, NULL, 17), - SENSOR_ATTR(in9_alarm, S_IRUGO, show_alarm, NULL, 19), -}; - -static struct sensor_device_attribute sda_in_min[] = { - SENSOR_ATTR(in0_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 0), - SENSOR_ATTR(in1_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 1), - SENSOR_ATTR(in2_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 2), - SENSOR_ATTR(in3_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 3), - SENSOR_ATTR(in4_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 4), - SENSOR_ATTR(in5_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 5), - SENSOR_ATTR(in6_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 6), - SENSOR_ATTR(in7_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 7), - SENSOR_ATTR(in8_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 8), - SENSOR_ATTR(in9_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 9), -}; - -static struct sensor_device_attribute sda_in_max[] = { - SENSOR_ATTR(in0_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 0), - SENSOR_ATTR(in1_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 1), - SENSOR_ATTR(in2_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 2), - SENSOR_ATTR(in3_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 3), - SENSOR_ATTR(in4_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 4), - SENSOR_ATTR(in5_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 5), - SENSOR_ATTR(in6_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 6), - SENSOR_ATTR(in7_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 7), - SENSOR_ATTR(in8_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 8), - SENSOR_ATTR(in9_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 9), -}; - -static void device_create_file_in(struct device *dev, int i) -{ - device_create_file(dev, &sda_in_input[i].dev_attr); - device_create_file(dev, &sda_in_alarm[i].dev_attr); - device_create_file(dev, &sda_in_min[i].dev_attr); - device_create_file(dev, &sda_in_max[i].dev_attr); -} #define show_fan_reg(reg) \ static ssize_t \ -show_##reg(struct device *dev, struct device_attribute *attr, \ - char *buf) \ +show_##reg(struct device *dev, char *buf, int nr) \ { \ struct w83627ehf_data *data = w83627ehf_update_device(dev); \ - struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \ - int nr = sensor_attr->index; \ return sprintf(buf, "%d\n", \ fan_from_reg(data->reg[nr], \ div_from_reg(data->fan_div[nr]))); \ @@ -570,28 +418,23 @@ show_fan_reg(fan); show_fan_reg(fan_min); static ssize_t -show_fan_div(struct device *dev, struct device_attribute *attr, - char *buf) +show_fan_div(struct device *dev, char *buf, int nr) { struct w83627ehf_data *data = w83627ehf_update_device(dev); - struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); - int nr = sensor_attr->index; - return sprintf(buf, "%u\n", div_from_reg(data->fan_div[nr])); + return sprintf(buf, "%u\n", + div_from_reg(data->fan_div[nr])); } static ssize_t -store_fan_min(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +store_fan_min(struct device *dev, const char *buf, size_t count, int nr) { struct i2c_client *client = to_i2c_client(dev); struct w83627ehf_data *data = i2c_get_clientdata(client); - struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); - int nr = sensor_attr->index; unsigned int val = simple_strtoul(buf, NULL, 10); unsigned int reg; u8 new_div; - mutex_lock(&data->update_lock); + down(&data->update_lock); if (!val) { /* No min limit, alarm disabled */ data->fan_min[nr] = 255; @@ -639,55 +482,63 @@ store_fan_min(struct device *dev, struct device_attribute *attr, } w83627ehf_write_value(client, W83627EHF_REG_FAN_MIN[nr], data->fan_min[nr]); - mutex_unlock(&data->update_lock); + up(&data->update_lock); return count; } -static struct sensor_device_attribute sda_fan_input[] = { - SENSOR_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0), - SENSOR_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1), - SENSOR_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2), - SENSOR_ATTR(fan4_input, S_IRUGO, show_fan, NULL, 3), - SENSOR_ATTR(fan5_input, S_IRUGO, show_fan, NULL, 4), -}; - -static struct sensor_device_attribute sda_fan_alarm[] = { - SENSOR_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, 6), - SENSOR_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, 7), - SENSOR_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL, 11), - SENSOR_ATTR(fan4_alarm, S_IRUGO, show_alarm, NULL, 10), - SENSOR_ATTR(fan5_alarm, S_IRUGO, show_alarm, NULL, 23), -}; - -static struct sensor_device_attribute sda_fan_min[] = { - SENSOR_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan_min, - store_fan_min, 0), - SENSOR_ATTR(fan2_min, S_IWUSR | S_IRUGO, show_fan_min, - store_fan_min, 1), - SENSOR_ATTR(fan3_min, S_IWUSR | S_IRUGO, show_fan_min, - store_fan_min, 2), - SENSOR_ATTR(fan4_min, S_IWUSR | S_IRUGO, show_fan_min, - store_fan_min, 3), - SENSOR_ATTR(fan5_min, S_IWUSR | S_IRUGO, show_fan_min, - store_fan_min, 4), -}; +#define sysfs_fan_offset(offset) \ +static ssize_t \ +show_reg_fan_##offset(struct device *dev, struct device_attribute *attr, \ + char *buf) \ +{ \ + return show_fan(dev, buf, offset-1); \ +} \ +static DEVICE_ATTR(fan##offset##_input, S_IRUGO, \ + show_reg_fan_##offset, NULL); -static struct sensor_device_attribute sda_fan_div[] = { - SENSOR_ATTR(fan1_div, S_IRUGO, show_fan_div, NULL, 0), - SENSOR_ATTR(fan2_div, S_IRUGO, show_fan_div, NULL, 1), - SENSOR_ATTR(fan3_div, S_IRUGO, show_fan_div, NULL, 2), - SENSOR_ATTR(fan4_div, S_IRUGO, show_fan_div, NULL, 3), - SENSOR_ATTR(fan5_div, S_IRUGO, show_fan_div, NULL, 4), -}; +#define sysfs_fan_min_offset(offset) \ +static ssize_t \ +show_reg_fan##offset##_min(struct device *dev, struct device_attribute *attr, \ + char *buf) \ +{ \ + return show_fan_min(dev, buf, offset-1); \ +} \ +static ssize_t \ +store_reg_fan##offset##_min(struct device *dev, struct device_attribute *attr, \ + const char *buf, size_t count) \ +{ \ + return store_fan_min(dev, buf, count, offset-1); \ +} \ +static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \ + show_reg_fan##offset##_min, \ + store_reg_fan##offset##_min); -static void device_create_file_fan(struct device *dev, int i) -{ - device_create_file(dev, &sda_fan_input[i].dev_attr); - device_create_file(dev, &sda_fan_alarm[i].dev_attr); - device_create_file(dev, &sda_fan_div[i].dev_attr); - device_create_file(dev, &sda_fan_min[i].dev_attr); -} +#define sysfs_fan_div_offset(offset) \ +static ssize_t \ +show_reg_fan##offset##_div(struct device *dev, struct device_attribute *attr, \ + char *buf) \ +{ \ + return show_fan_div(dev, buf, offset - 1); \ +} \ +static DEVICE_ATTR(fan##offset##_div, S_IRUGO, \ + show_reg_fan##offset##_div, NULL); + +sysfs_fan_offset(1); +sysfs_fan_min_offset(1); +sysfs_fan_div_offset(1); +sysfs_fan_offset(2); +sysfs_fan_min_offset(2); +sysfs_fan_div_offset(2); +sysfs_fan_offset(3); +sysfs_fan_min_offset(3); +sysfs_fan_div_offset(3); +sysfs_fan_offset(4); +sysfs_fan_min_offset(4); +sysfs_fan_div_offset(4); +sysfs_fan_offset(5); +sysfs_fan_min_offset(5); +sysfs_fan_div_offset(5); #define show_temp1_reg(reg) \ static ssize_t \ @@ -710,24 +561,27 @@ store_temp1_##reg(struct device *dev, struct device_attribute *attr, \ struct w83627ehf_data *data = i2c_get_clientdata(client); \ u32 val = simple_strtoul(buf, NULL, 10); \ \ - mutex_lock(&data->update_lock); \ + down(&data->update_lock); \ data->temp1_##reg = temp1_to_reg(val); \ w83627ehf_write_value(client, W83627EHF_REG_TEMP1_##REG, \ data->temp1_##reg); \ - mutex_unlock(&data->update_lock); \ + up(&data->update_lock); \ return count; \ } store_temp1_reg(OVER, max); store_temp1_reg(HYST, max_hyst); +static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp1, NULL); +static DEVICE_ATTR(temp1_max, S_IRUGO| S_IWUSR, + show_temp1_max, store_temp1_max); +static DEVICE_ATTR(temp1_max_hyst, S_IRUGO| S_IWUSR, + show_temp1_max_hyst, store_temp1_max_hyst); + #define show_temp_reg(reg) \ static ssize_t \ -show_##reg(struct device *dev, struct device_attribute *attr, \ - char *buf) \ +show_##reg (struct device *dev, char *buf, int nr) \ { \ struct w83627ehf_data *data = w83627ehf_update_device(dev); \ - struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \ - int nr = sensor_attr->index; \ return sprintf(buf, "%d\n", \ LM75_TEMP_FROM_REG(data->reg[nr])); \ } @@ -737,45 +591,55 @@ show_temp_reg(temp_max_hyst); #define store_temp_reg(REG, reg) \ static ssize_t \ -store_##reg(struct device *dev, struct device_attribute *attr, \ - const char *buf, size_t count) \ +store_##reg (struct device *dev, const char *buf, size_t count, int nr) \ { \ struct i2c_client *client = to_i2c_client(dev); \ struct w83627ehf_data *data = i2c_get_clientdata(client); \ - struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \ - int nr = sensor_attr->index; \ u32 val = simple_strtoul(buf, NULL, 10); \ \ - mutex_lock(&data->update_lock); \ + down(&data->update_lock); \ data->reg[nr] = LM75_TEMP_TO_REG(val); \ w83627ehf_write_value(client, W83627EHF_REG_TEMP_##REG[nr], \ data->reg[nr]); \ - mutex_unlock(&data->update_lock); \ + up(&data->update_lock); \ return count; \ } store_temp_reg(OVER, temp_max); store_temp_reg(HYST, temp_max_hyst); -static struct sensor_device_attribute sda_temp[] = { - SENSOR_ATTR(temp1_input, S_IRUGO, show_temp1, NULL, 0), - SENSOR_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 0), - SENSOR_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 1), - SENSOR_ATTR(temp1_max, S_IRUGO | S_IWUSR, show_temp1_max, - store_temp1_max, 0), - SENSOR_ATTR(temp2_max, S_IRUGO | S_IWUSR, show_temp_max, - store_temp_max, 0), - SENSOR_ATTR(temp3_max, S_IRUGO | S_IWUSR, show_temp_max, - store_temp_max, 1), - SENSOR_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR, show_temp1_max_hyst, - store_temp1_max_hyst, 0), - SENSOR_ATTR(temp2_max_hyst, S_IRUGO | S_IWUSR, show_temp_max_hyst, - store_temp_max_hyst, 0), - SENSOR_ATTR(temp3_max_hyst, S_IRUGO | S_IWUSR, show_temp_max_hyst, - store_temp_max_hyst, 1), - SENSOR_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 4), - SENSOR_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 5), - SENSOR_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 13), -}; +#define sysfs_temp_offset(offset) \ +static ssize_t \ +show_reg_temp##offset (struct device *dev, struct device_attribute *attr, \ + char *buf) \ +{ \ + return show_temp(dev, buf, offset - 2); \ +} \ +static DEVICE_ATTR(temp##offset##_input, S_IRUGO, \ + show_reg_temp##offset, NULL); + +#define sysfs_temp_reg_offset(reg, offset) \ +static ssize_t \ +show_reg_temp##offset##_##reg(struct device *dev, struct device_attribute *attr, \ + char *buf) \ +{ \ + return show_temp_##reg(dev, buf, offset - 2); \ +} \ +static ssize_t \ +store_reg_temp##offset##_##reg(struct device *dev, struct device_attribute *attr, \ + const char *buf, size_t count) \ +{ \ + return store_temp_##reg(dev, buf, count, offset - 2); \ +} \ +static DEVICE_ATTR(temp##offset##_##reg, S_IRUGO| S_IWUSR, \ + show_reg_temp##offset##_##reg, \ + store_reg_temp##offset##_##reg); + +sysfs_temp_offset(2); +sysfs_temp_reg_offset(max, 2); +sysfs_temp_reg_offset(max_hyst, 2); +sysfs_temp_offset(3); +sysfs_temp_reg_offset(max, 3); +sysfs_temp_reg_offset(max_hyst, 3); /* * Driver and client management @@ -809,7 +673,6 @@ static int w83627ehf_detect(struct i2c_adapter *adapter) { struct i2c_client *client; struct w83627ehf_data *data; - struct device *dev; int i, err = 0; if (!request_region(address + REGION_OFFSET, REGION_LENGTH, @@ -826,15 +689,14 @@ static int w83627ehf_detect(struct i2c_adapter *adapter) client = &data->client; i2c_set_clientdata(client, data); client->addr = address; - mutex_init(&data->lock); + init_MUTEX(&data->lock); client->adapter = adapter; client->driver = &w83627ehf_driver; client->flags = 0; - dev = &client->dev; strlcpy(client->name, "w83627ehf", I2C_NAME_SIZE); data->valid = 0; - mutex_init(&data->update_lock); + init_MUTEX(&data->update_lock); /* Tell the i2c layer a new client has arrived */ if ((err = i2c_attach_client(client))) @@ -858,21 +720,42 @@ static int w83627ehf_detect(struct i2c_adapter *adapter) data->has_fan |= (1 << 4); /* Register sysfs hooks */ - data->class_dev = hwmon_device_register(dev); + data->class_dev = hwmon_device_register(&client->dev); if (IS_ERR(data->class_dev)) { err = PTR_ERR(data->class_dev); goto exit_detach; } - for (i = 0; i < 10; i++) - device_create_file_in(dev, i); - - for (i = 0; i < 5; i++) { - if (data->has_fan & (1 << i)) - device_create_file_fan(dev, i); + device_create_file(&client->dev, &dev_attr_fan1_input); + device_create_file(&client->dev, &dev_attr_fan1_min); + device_create_file(&client->dev, &dev_attr_fan1_div); + device_create_file(&client->dev, &dev_attr_fan2_input); + device_create_file(&client->dev, &dev_attr_fan2_min); + device_create_file(&client->dev, &dev_attr_fan2_div); + device_create_file(&client->dev, &dev_attr_fan3_input); + device_create_file(&client->dev, &dev_attr_fan3_min); + device_create_file(&client->dev, &dev_attr_fan3_div); + + if (data->has_fan & (1 << 3)) { + device_create_file(&client->dev, &dev_attr_fan4_input); + device_create_file(&client->dev, &dev_attr_fan4_min); + device_create_file(&client->dev, &dev_attr_fan4_div); } - for (i = 0; i < ARRAY_SIZE(sda_temp); i++) - device_create_file(dev, &sda_temp[i].dev_attr); + if (data->has_fan & (1 << 4)) { + device_create_file(&client->dev, &dev_attr_fan5_input); + device_create_file(&client->dev, &dev_attr_fan5_min); + device_create_file(&client->dev, &dev_attr_fan5_div); + } + + device_create_file(&client->dev, &dev_attr_temp1_input); + device_create_file(&client->dev, &dev_attr_temp1_max); + device_create_file(&client->dev, &dev_attr_temp1_max_hyst); + device_create_file(&client->dev, &dev_attr_temp2_input); + device_create_file(&client->dev, &dev_attr_temp2_max); + device_create_file(&client->dev, &dev_attr_temp2_max_hyst); + device_create_file(&client->dev, &dev_attr_temp3_input); + device_create_file(&client->dev, &dev_attr_temp3_max); + device_create_file(&client->dev, &dev_attr_temp3_max_hyst); return 0;