diff -Naur a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig --- a/drivers/hwmon/Kconfig 2005-07-13 06:46:46.000000000 +0200 +++ b/drivers/hwmon/Kconfig 2005-07-15 15:12:21.464951750 +0200 @@ -369,6 +369,16 @@ This driver can also be built as a module. If so, the module will be called w83781d. +config SENSORS_W83792D + tristate "Winbond W83792D" + depends on HWMON && I2C && EXPERIMENTAL + select I2C_SENSOR + help + If you say yes here you get support for the Winbond W83792D chip. + + This driver can also be built as a module. If so, the module + will be called w83792d. + config SENSORS_W83L785TS tristate "Winbond W83L785TS-S" depends on HWMON && I2C && EXPERIMENTAL diff -Naur a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile --- a/drivers/hwmon/Makefile 2005-07-13 06:46:46.000000000 +0200 +++ b/drivers/hwmon/Makefile 2005-07-15 13:34:01.137434000 +0200 @@ -5,6 +5,7 @@ # asb100, then w83781d go first, as they can override other drivers' addresses. obj-$(CONFIG_SENSORS_ASB100) += asb100.o obj-$(CONFIG_SENSORS_W83627HF) += w83627hf.o +obj-$(CONFIG_SENSORS_W83792D) += w83792d.o obj-$(CONFIG_SENSORS_W83781D) += w83781d.o obj-$(CONFIG_SENSORS_ADM1021) += adm1021.o diff -Naur a/drivers/hwmon/w83792d.c b/drivers/hwmon/w83792d.c --- a/drivers/hwmon/w83792d.c 2005-07-15 12:56:35.969119750 +0200 +++ b/drivers/hwmon/w83792d.c 2005-07-15 12:56:55.018310250 +0200 @@ -2,7 +2,8 @@ w83792d.c - Part of lm_sensors, Linux kernel modules for hardware monitoring Copyright (C) 2004, 2005 Winbond Electronics Corp. - Chunhao Huang + Chunhao Huang , + Rudolf Marek This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -41,6 +42,7 @@ #include #include #include +#include /* Addresses to scan */ static unsigned short normal_i2c[] = { 0x2c, 0x2f, I2C_CLIENT_END }; @@ -356,15 +358,21 @@ } /* following are the sysfs callback functions */ -static ssize_t show_in(struct device *dev, char *buf, int nr) +static ssize_t show_in(struct device *dev, struct device_attribute *attr, + char *buf) { + struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); + int nr = sensor_attr->index; struct w83792d_data *data = w83792d_update_device(dev); return sprintf(buf,"%ld\n", IN_FROM_REG(nr,(in_count_from_reg(nr, data)))); } #define show_in_reg(reg) \ -static ssize_t show_##reg (struct device *dev, char *buf, int nr) \ +static ssize_t show_##reg (struct device *dev, struct device_attribute *attr, \ + char *buf) \ { \ + struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \ + int nr = sensor_attr->index; \ struct w83792d_data *data = w83792d_update_device(dev); \ return sprintf(buf,"%ld\n", (long)(IN_FROM_REG(nr, (data->reg[nr])*4))); \ } @@ -373,8 +381,11 @@ show_in_reg(in_max); #define store_in_reg(REG, reg) \ -static ssize_t store_in_##reg (struct device *dev, const char *buf, size_t count, int nr) \ +static ssize_t store_in_##reg (struct device *dev, struct device_attribute *attr, \ + const char *buf, size_t count) \ { \ + struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \ + int nr = sensor_attr->index; \ struct i2c_client *client = to_i2c_client(dev); \ struct w83792d_data *data = i2c_get_clientdata(client); \ u32 val; \ @@ -388,60 +399,51 @@ store_in_reg(MIN, min); store_in_reg(MAX, max); -#define sysfs_in_offset(offset) \ -static ssize_t \ -show_regs_in_##offset (struct device *dev, char *buf) \ -{ \ - return show_in(dev, buf, offset); \ -} \ -static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_regs_in_##offset, NULL); - -#define sysfs_in_reg_offset(reg, offset) \ -static ssize_t show_regs_in_##reg##offset (struct device *dev, char *buf) \ -{ \ - return show_in_##reg (dev, buf, offset); \ -} \ -static ssize_t store_regs_in_##reg##offset (struct device *dev, const char *buf, size_t count) \ -{ \ - return store_in_##reg (dev, buf, count, offset); \ -} \ -static DEVICE_ATTR(in##offset##_##reg, S_IRUGO| S_IWUSR, show_regs_in_##reg##offset, store_regs_in_##reg##offset); - -#define sysfs_in_offsets(offset) \ -sysfs_in_offset(offset); \ -sysfs_in_reg_offset(min, offset); \ -sysfs_in_reg_offset(max, offset); - -sysfs_in_offsets(0); -sysfs_in_offsets(1); -sysfs_in_offsets(2); -sysfs_in_offsets(3); -sysfs_in_offsets(4); -sysfs_in_offsets(5); -sysfs_in_offsets(6); -sysfs_in_offsets(7); -sysfs_in_offsets(8); +#define sysfs_in_reg(offset) \ +static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO, show_in, \ + NULL, offset); \ +static SENSOR_DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \ + show_in_min, store_in_min, offset); \ +static SENSOR_DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \ + show_in_max, store_in_max, offset); + +sysfs_in_reg(0); +sysfs_in_reg(1); +sysfs_in_reg(2); +sysfs_in_reg(3); +sysfs_in_reg(4); +sysfs_in_reg(5); +sysfs_in_reg(6); +sysfs_in_reg(7); +sysfs_in_reg(8); #define device_create_file_in(client, offset) \ do { \ -device_create_file(&client->dev, &dev_attr_in##offset##_input); \ -device_create_file(&client->dev, &dev_attr_in##offset##_min); \ -device_create_file(&client->dev, &dev_attr_in##offset##_max); \ +device_create_file(&client->dev, &sensor_dev_attr_in##offset##_input.dev_attr); \ +device_create_file(&client->dev, &sensor_dev_attr_in##offset##_max.dev_attr); \ +device_create_file(&client->dev, &sensor_dev_attr_in##offset##_min.dev_attr); \ } while (0) #define show_fan_reg(reg) \ -static ssize_t show_##reg (struct device *dev, char *buf, int nr) \ +static ssize_t show_##reg (struct device *dev, struct device_attribute *attr, \ + char *buf) \ { \ + struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \ + int nr = sensor_attr->index; \ struct w83792d_data *data = w83792d_update_device(dev); \ return sprintf(buf,"%ld\n", \ FAN_FROM_REG(data->reg[nr-1], (long)DIV_FROM_REG(data->fan_div[nr-1]))); \ } + show_fan_reg(fan); show_fan_reg(fan_min); static ssize_t -store_fan_min(struct device *dev, const char *buf, size_t count, int nr) +store_fan_min(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { + struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); + int nr = sensor_attr->index; struct i2c_client *client = to_i2c_client(dev); struct w83792d_data *data = i2c_get_clientdata(client); u32 val; @@ -455,182 +457,181 @@ return count; } -#define sysfs_fan_offset(offset) \ -static ssize_t show_regs_fan_##offset (struct device *dev, char *buf) \ -{ \ - return show_fan(dev, buf, offset); \ -} \ -static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_regs_fan_##offset, NULL); +static ssize_t +show_fan_div(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); + int nr = sensor_attr->index; + struct w83792d_data *data = w83792d_update_device(dev); + return sprintf(buf, "%ld\n", + (long) DIV_FROM_REG(data->fan_div[nr - 1])); +} -#define sysfs_fan_min_offset(offset) \ -static ssize_t show_regs_fan_min##offset (struct device *dev, char *buf) \ -{ \ - return show_fan_min(dev, buf, offset); \ -} \ -static ssize_t store_regs_fan_min##offset (struct device *dev, const char *buf, size_t count) \ -{ \ - return store_fan_min(dev, buf, count, offset); \ -} \ -static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, show_regs_fan_min##offset, store_regs_fan_min##offset); - -sysfs_fan_offset(1); -sysfs_fan_min_offset(1); -sysfs_fan_offset(2); -sysfs_fan_min_offset(2); -sysfs_fan_offset(3); -sysfs_fan_min_offset(3); -sysfs_fan_offset(4); -sysfs_fan_min_offset(4); -sysfs_fan_offset(5); -sysfs_fan_min_offset(5); -sysfs_fan_offset(6); -sysfs_fan_min_offset(6); -sysfs_fan_offset(7); -sysfs_fan_min_offset(7); +/* Note: we save and restore the fan minimum here, because its value is + determined in part by the fan divisor. This follows the principle of + least suprise; the user doesn't expect the fan minimum to change just + because the divisor changed. */ +static ssize_t +store_fan_div(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); + int nr = sensor_attr->index - 1; + struct i2c_client *client = to_i2c_client(dev); + struct w83792d_data *data = i2c_get_clientdata(client); + unsigned long min; + /*u8 reg;*/ + u8 fan_div_reg = 0; + u8 tmp_fan_div; + + /* Save fan_min */ + min = FAN_FROM_REG(data->fan_min[nr], + DIV_FROM_REG(data->fan_div[nr])); + + data->fan_div[nr] = DIV_TO_REG(simple_strtoul(buf, NULL, 10)); + + fan_div_reg = w83792d_read_value(client, W83792D_REG_FAN_DIV[nr >> 1]); + fan_div_reg &= (nr & 0x01) ? 0x8f : 0xf8; + tmp_fan_div = (nr & 0x01) ? (((data->fan_div[nr]) << 4) & 0x70) + : ((data->fan_div[nr]) & 0x07); + w83792d_write_value(client, W83792D_REG_FAN_DIV[nr >> 1], + fan_div_reg | tmp_fan_div); + + /* Restore fan_min */ + data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr])); + w83792d_write_value(client, W83792D_REG_FAN_MIN[nr], data->fan_min[nr]); + + return count; +} + +#define sysfs_fan(offset) \ +static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan, NULL, \ +offset); \ +static SENSOR_DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \ +show_fan_div, store_fan_div, offset); \ +static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \ +show_fan_min, store_fan_min, offset); + +sysfs_fan(1); +sysfs_fan(2); +sysfs_fan(3); +sysfs_fan(4); +sysfs_fan(5); +sysfs_fan(6); +sysfs_fan(7); #define device_create_file_fan(client, offset) \ do { \ -device_create_file(&client->dev, &dev_attr_fan##offset##_input); \ -device_create_file(&client->dev, &dev_attr_fan##offset##_min); \ +device_create_file(&client->dev, &sensor_dev_attr_fan##offset##_input.dev_attr); \ +device_create_file(&client->dev, &sensor_dev_attr_fan##offset##_div.dev_attr); \ +device_create_file(&client->dev, &sensor_dev_attr_fan##offset##_min.dev_attr); \ } while (0) /* read/write the temperature1, includes measured value and limits */ -#define show_temp1_reg(reg, index) \ -static ssize_t show_##reg (struct device *dev, char *buf) \ -{ \ - struct w83792d_data *data = w83792d_update_device(dev); \ - return sprintf(buf,"%ld\n", (long)TEMP1_FROM_REG(data->temp1[index])); \ -} - -show_temp1_reg(temp1, 0); -show_temp1_reg(temp1_max, 1); -show_temp1_reg(temp1_max_hyst, 2); -#define store_temp1_reg(reg, index) \ -static ssize_t store_##reg (struct device *dev, const char *buf, size_t count) \ -{ \ - struct i2c_client *client = to_i2c_client(dev); \ - struct w83792d_data *data = i2c_get_clientdata(client); \ - s32 val; \ - \ - val = simple_strtol(buf, NULL, 10); \ - \ - data->temp1[index] = TEMP1_TO_REG(val); \ - w83792d_write_value(client, W83792D_REG_TEMP1[index], \ - data->temp1[index]); \ - \ - return count; \ +static ssize_t show_temp1(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); + int nr = sensor_attr->index; + struct w83792d_data *data = w83792d_update_device(dev); + return sprintf(buf,"%ld\n", (long)TEMP1_FROM_REG(data->temp1[nr])); } -store_temp1_reg(temp1_max, 1); -store_temp1_reg(temp1_max_hyst, 2); -static ssize_t show_regs_temp1(struct device *dev, char *buf) +static ssize_t store_temp1(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { - return show_temp1(dev, buf); + struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); + int nr = sensor_attr->index; + struct i2c_client *client = to_i2c_client(dev); + struct w83792d_data *data = i2c_get_clientdata(client); + s32 val; + + val = simple_strtol(buf, NULL, 10); + + data->temp1[nr] = TEMP1_TO_REG(val); + w83792d_write_value(client, W83792D_REG_TEMP1[nr], + data->temp1[nr]); + + return count; } -static DEVICE_ATTR(temp1_input, S_IRUGO, show_regs_temp1, NULL); -#define sysfs_temp_offsets(reg) \ -static ssize_t show_regs_##reg(struct device *dev, char *buf) \ -{ \ - return show_##reg(dev, buf); \ -} \ -static ssize_t store_regs_##reg(struct device *dev, const char *buf, size_t count) \ -{ \ - return store_##reg(dev, buf, count); \ -} \ -static DEVICE_ATTR(reg, S_IRUGO|S_IWUSR, show_regs_##reg, store_regs_##reg); - -sysfs_temp_offsets(temp1_max); -sysfs_temp_offsets(temp1_max_hyst); +static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp1, NULL, 0); +static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO | S_IWUSR, show_temp1, + store_temp1, 1); +static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR, show_temp1, + store_temp1, 2); #define device_create_file_temp1(client) \ do { \ -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, &sensor_dev_attr_temp1_input.dev_attr); \ +device_create_file(&client->dev, &sensor_dev_attr_temp1_max.dev_attr); \ +device_create_file(&client->dev, &sensor_dev_attr_temp1_max_hyst.dev_attr); \ } while (0) + /* read/write the temperature2-3, includes measured value and limits */ -#define show_temp_add_reg(reg, offset, index) \ -static ssize_t show_##reg (struct device *dev, char *buf) \ -{ \ - struct w83792d_data *data = w83792d_update_device(dev); \ - return sprintf(buf,"%ld\n", \ - (long)TEMP_ADD_FROM_REG(data->temp_add[offset][index], \ - data->temp_add[offset][index+1])); \ + +static ssize_t show_temp23(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct sensor_device_attribute_2 *sensor_attr = to_sensor_dev_attr_2(attr); + int nr = sensor_attr->nr; + int index = sensor_attr->index; + struct w83792d_data *data = w83792d_update_device(dev); + return sprintf(buf,"%ld\n", + (long)TEMP_ADD_FROM_REG(data->temp_add[nr][index], + data->temp_add[nr][index+1])); } -show_temp_add_reg(temp2, 0, 0); -show_temp_add_reg(temp2_max, 0, 2); -show_temp_add_reg(temp2_max_hyst, 0, 4); -show_temp_add_reg(temp3, 1, 0); -show_temp_add_reg(temp3_max, 1, 2); -show_temp_add_reg(temp3_max_hyst, 1, 4); +static ssize_t store_temp23(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct sensor_device_attribute_2 *sensor_attr = to_sensor_dev_attr_2(attr); + int nr = sensor_attr->nr; + int index = sensor_attr->index; + struct i2c_client *client = to_i2c_client(dev); + struct w83792d_data *data = i2c_get_clientdata(client); + s32 val; -#define store_temp_add_reg(reg, offset, index) \ -static ssize_t store_##reg (struct device *dev, const char *buf, size_t count) \ -{ \ - struct i2c_client *client = to_i2c_client(dev); \ - struct w83792d_data *data = i2c_get_clientdata(client); \ - s32 val; \ - \ - val = simple_strtol(buf, NULL, 10); \ - \ - data->temp_add[offset][index] = TEMP_ADD_TO_REG_HIGH(val); \ - data->temp_add[offset][index+1] = TEMP_ADD_TO_REG_LOW(val); \ - w83792d_write_value(client, W83792D_REG_TEMP_ADD[offset][index], \ - data->temp_add[offset][index]); \ - w83792d_write_value(client, W83792D_REG_TEMP_ADD[offset][index+1], \ - data->temp_add[offset][index+1]); \ - \ - return count; \ -} + val = simple_strtol(buf, NULL, 10); -store_temp_add_reg(temp2_max, 0, 2); -store_temp_add_reg(temp2_max_hyst, 0, 4); -store_temp_add_reg(temp3_max, 1, 2); -store_temp_add_reg(temp3_max_hyst, 1, 4); + data->temp_add[nr][index] = TEMP_ADD_TO_REG_HIGH(val); + data->temp_add[nr][index+1] = TEMP_ADD_TO_REG_LOW(val); + w83792d_write_value(client, W83792D_REG_TEMP_ADD[nr][index], + data->temp_add[nr][index]); + w83792d_write_value(client, W83792D_REG_TEMP_ADD[nr][index+1], + data->temp_add[nr][index+1]); -#define show_regs_temp_add(reg) \ -static ssize_t show_regs_##reg(struct device *dev, char *buf) \ -{ \ - return show_##reg(dev, buf); \ -} \ -static DEVICE_ATTR(reg##_input, S_IRUGO, show_regs_##reg, NULL); + return count; +} -show_regs_temp_add(temp2); -show_regs_temp_add(temp3); +#define sysfs_temp23(name,idx) \ +static SENSOR_DEVICE_ATTR_2(name##_input, S_IRUGO, show_temp23, NULL, \ +idx, 0); \ +static SENSOR_DEVICE_ATTR_2(name##_max, S_IRUGO | S_IWUSR, \ +show_temp23, store_temp23, idx, 2); \ +static SENSOR_DEVICE_ATTR_2(name##_max_hyst, S_IRUGO | S_IWUSR, \ +show_temp23, store_temp23, idx, 4); -#define sysfs_temp_add_offsets(reg) \ -static ssize_t show_regs_##reg(struct device *dev, char *buf) \ -{ \ - return show_##reg(dev, buf); \ -} \ -static ssize_t store_regs_##reg(struct device *dev, const char *buf, size_t count) \ -{ \ - return store_##reg(dev, buf, count); \ -} \ -static DEVICE_ATTR(reg, S_IRUGO|S_IWUSR, show_regs_##reg, store_regs_##reg); - -sysfs_temp_add_offsets(temp2_max); -sysfs_temp_add_offsets(temp2_max_hyst); -sysfs_temp_add_offsets(temp3_max); -sysfs_temp_add_offsets(temp3_max_hyst); +sysfs_temp23(temp2,0) +sysfs_temp23(temp3,1) #define device_create_file_temp_add(client, offset) \ do { \ -device_create_file(&client->dev, &dev_attr_temp##offset##_input); \ -device_create_file(&client->dev, &dev_attr_temp##offset##_max); \ -device_create_file(&client->dev, &dev_attr_temp##offset##_max_hyst); \ +device_create_file(&client->dev, &sensor_dev_attr_temp##offset##_input.dev_attr); \ +device_create_file(&client->dev, &sensor_dev_attr_temp##offset##_max.dev_attr); \ +device_create_file(&client->dev, \ +&sensor_dev_attr_temp##offset##_max_hyst.dev_attr); \ } while (0) /* get reatime status of all sensors items: voltage, temp, fan */ static ssize_t -show_alarms_reg(struct device *dev, char *buf) +show_alarms_reg(struct device *dev, struct device_attribute *attr, char *buf) { struct w83792d_data *data = w83792d_update_device(dev); return sprintf(buf, "%d\n", data->alarms); @@ -642,82 +643,23 @@ device_create_file(&client->dev, &dev_attr_alarms); -static ssize_t -show_fan_div_reg(struct device *dev, char *buf, int nr) -{ - struct w83792d_data *data = w83792d_update_device(dev); - return sprintf(buf, "%ld\n", - (long) DIV_FROM_REG(data->fan_div[nr - 1])); -} -/* Note: we save and restore the fan minimum here, because its value is - determined in part by the fan divisor. This follows the principle of - least suprise; the user doesn't expect the fan minimum to change just - because the divisor changed. */ static ssize_t -store_fan_div_reg(struct device *dev, const char *buf, size_t count, int nr) -{ - struct i2c_client *client = to_i2c_client(dev); - struct w83792d_data *data = i2c_get_clientdata(client); - unsigned long min; - /*u8 reg;*/ - u8 fan_div_reg = 0; - u8 tmp_fan_div; - - /* Save fan_min */ - min = FAN_FROM_REG(data->fan_min[nr], - DIV_FROM_REG(data->fan_div[nr])); - - data->fan_div[nr] = DIV_TO_REG(simple_strtoul(buf, NULL, 10)); - - fan_div_reg = w83792d_read_value(client, W83792D_REG_FAN_DIV[nr >> 1]); - fan_div_reg &= (nr & 0x01) ? 0x8f : 0xf8; - tmp_fan_div = (nr & 0x01) ? (((data->fan_div[nr]) << 4) & 0x70) - : ((data->fan_div[nr]) & 0x07); - w83792d_write_value(client, W83792D_REG_FAN_DIV[nr >> 1], - fan_div_reg | tmp_fan_div); - - /* Restore fan_min */ - data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr])); - w83792d_write_value(client, W83792D_REG_FAN_MIN[nr], data->fan_min[nr]); - - return count; -} - -#define sysfs_fan_div(offset) \ -static ssize_t show_regs_fan_div_##offset (struct device *dev, char *buf) \ -{ \ - return show_fan_div_reg(dev, buf, offset); \ -} \ -static ssize_t store_regs_fan_div_##offset (struct device *dev, const char *buf, size_t count) \ -{ \ - return store_fan_div_reg(dev, buf, count, offset - 1); \ -} \ -static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, show_regs_fan_div_##offset, store_regs_fan_div_##offset); - -sysfs_fan_div(1); -sysfs_fan_div(2); -sysfs_fan_div(3); -sysfs_fan_div(4); -sysfs_fan_div(5); -sysfs_fan_div(6); -sysfs_fan_div(7); - -#define device_create_file_fan_div(client, offset) \ -do { \ -device_create_file(&client->dev, &dev_attr_fan##offset##_div); \ -} while (0) - -static ssize_t -show_pwm_reg(struct device *dev, char *buf, int nr) +show_pwm(struct device *dev, struct device_attribute *attr, + char *buf) { + struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); + int nr = sensor_attr->index; struct w83792d_data *data = w83792d_update_device(dev); return sprintf(buf, "%ld\n", (long) PWM_FROM_REG(data->pwm[nr-1])); } static ssize_t -show_pwmenable_reg(struct device *dev, char *buf, int nr) +show_pwmenable(struct device *dev, struct device_attribute *attr, + char *buf) { + struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); + int nr = sensor_attr->index; struct w83792d_data *data = w83792d_update_device(dev); long pwm_enable_tmp = 1; if (data->pwmenable[nr-1] == 0) { @@ -731,8 +673,11 @@ } static ssize_t -store_pwm_reg(struct device *dev, const char *buf, size_t count, int nr) +store_pwm(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { + struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); + int nr = sensor_attr->index; struct i2c_client *client = to_i2c_client(dev); struct w83792d_data *data = i2c_get_clientdata(client); u32 val; @@ -746,8 +691,11 @@ } static ssize_t -store_pwmenable_reg(struct device *dev, const char *buf, size_t count, int nr) +store_pwmenable(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { + struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); + int nr = sensor_attr->index; struct i2c_client *client = to_i2c_client(dev); struct w83792d_data *data = i2c_get_clientdata(client); u32 val; @@ -779,59 +727,43 @@ } #define sysfs_pwm(offset) \ -static ssize_t show_regs_pwm_##offset (struct device *dev, char *buf) \ -{ \ - return show_pwm_reg(dev, buf, offset); \ -} \ -static ssize_t store_regs_pwm_##offset (struct device *dev, \ - const char *buf, size_t count) \ -{ \ - return store_pwm_reg(dev, buf, count, offset); \ -} \ -static DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, \ - show_regs_pwm_##offset, store_regs_pwm_##offset); - -#define sysfs_pwmenable(offset) \ -static ssize_t show_regs_pwmenable_##offset (struct device *dev, char *buf) \ -{ \ - return show_pwmenable_reg(dev, buf, offset); \ -} \ -static ssize_t store_regs_pwmenable_##offset (struct device *dev, \ - const char *buf, size_t count) \ -{ \ - return store_pwmenable_reg(dev, buf, count, offset); \ -} \ -static DEVICE_ATTR(pwm##offset##_enable, S_IRUGO | S_IWUSR, \ - show_regs_pwmenable_##offset, store_regs_pwmenable_##offset); +static SENSOR_DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, \ +show_pwm, store_pwm, offset); \ +static SENSOR_DEVICE_ATTR(pwm##offset##_enable, S_IRUGO | S_IWUSR, \ +show_pwmenable, store_pwmenable, offset); \ sysfs_pwm(1); sysfs_pwm(2); sysfs_pwm(3); -sysfs_pwmenable(1); -sysfs_pwmenable(2); -sysfs_pwmenable(3); + #define device_create_file_pwm(client, offset) \ do { \ -device_create_file(&client->dev, &dev_attr_pwm##offset); \ +device_create_file(&client->dev, &sensor_dev_attr_pwm##offset.dev_attr); \ } while (0) #define device_create_file_pwmenable(client, offset) \ do { \ -device_create_file(&client->dev, &dev_attr_pwm##offset##_enable); \ +device_create_file(&client->dev, &sensor_dev_attr_pwm##offset##_enable.dev_attr); \ } while (0) static ssize_t -show_pwm_mode_reg(struct device *dev, char *buf, int nr) +show_pwm_mode(struct device *dev, struct device_attribute *attr, + char *buf) { + struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); + int nr = sensor_attr->index; struct w83792d_data *data = w83792d_update_device(dev); return sprintf(buf, "%ld\n", (long)data->pwm_mode[nr-1]); } static ssize_t -store_pwm_mode_reg(struct device *dev, const char *buf, size_t count, int nr) +store_pwm_mode(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { + struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); + int nr = sensor_attr->index; struct i2c_client *client = to_i2c_client(dev); struct w83792d_data *data = i2c_get_clientdata(client); u32 val; @@ -848,17 +780,8 @@ } #define sysfs_pwm_mode(offset) \ -static ssize_t show_regs_pwm_mode_##offset (struct device *dev, char *buf) \ -{ \ - return show_pwm_mode_reg(dev, buf, offset); \ -} \ -static ssize_t store_regs_pwm_mode_##offset (struct device *dev, \ - const char *buf, size_t count) \ -{ \ - return store_pwm_mode_reg(dev, buf, count, offset); \ -} \ -static DEVICE_ATTR(pwm##offset##_mode, S_IRUGO | S_IWUSR, \ - show_regs_pwm_mode_##offset, store_regs_pwm_mode_##offset); +static SENSOR_DEVICE_ATTR(pwm##offset##_mode, S_IRUGO | S_IWUSR, \ +show_pwm_mode, store_pwm_mode, offset); sysfs_pwm_mode(1); sysfs_pwm_mode(2); @@ -866,22 +789,18 @@ #define device_create_file_pwm_mode(client, offset) \ do { \ -device_create_file(&client->dev, &dev_attr_pwm##offset##_mode); \ +device_create_file(&client->dev, &sensor_dev_attr_pwm##offset##_mode.dev_attr); \ } while (0) -static ssize_t -show_chassis_reg(struct device *dev, char *buf) +static ssize_t +show_regs_chassis(struct device *dev, struct device_attribute *attr, + char *buf) { struct w83792d_data *data = w83792d_update_device(dev); return sprintf(buf, "%ld\n", (long)data->chassis); } -static ssize_t show_regs_chassis (struct device *dev, char *buf) -{ - return show_chassis_reg(dev, buf); -} - static DEVICE_ATTR(chassis, S_IRUGO, show_regs_chassis, NULL); #define device_create_file_chassis(client) \ @@ -891,14 +810,15 @@ static ssize_t -show_chassis_clear_reg(struct device *dev, char *buf) +show_chassis_clear(struct device *dev, struct device_attribute *attr, char *buf) { struct w83792d_data *data = w83792d_update_device(dev); return sprintf(buf, "%ld\n", (long)data->chassis_clear); } static ssize_t -store_chassis_clear_reg(struct device *dev, const char *buf, size_t count) +store_chassis_clear(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { struct i2c_client *client = to_i2c_client(dev); struct w83792d_data *data = i2c_get_clientdata(client); @@ -916,19 +836,8 @@ return count; } -static ssize_t show_regs_chassis_clear (struct device *dev, char *buf) -{ - return show_chassis_clear_reg(dev, buf); -} - -static ssize_t store_regs_chassis_clear (struct device *dev, - const char *buf, size_t count) -{ - return store_chassis_clear_reg(dev, buf, count); -} - static DEVICE_ATTR(chassis_clear, S_IRUGO | S_IWUSR, - show_regs_chassis_clear, store_regs_chassis_clear); + show_chassis_clear, store_chassis_clear); #define device_create_file_chassis_clear(client) \ do { \ @@ -939,15 +848,21 @@ /* For Smart Fan I / Thermal Cruise */ static ssize_t -show_thermal_cruise_reg(struct device *dev, char *buf, int nr) +show_thermal_cruise(struct device *dev, struct device_attribute *attr, + char *buf) { + struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); + int nr = sensor_attr->index; struct w83792d_data *data = w83792d_update_device(dev); return sprintf(buf, "%ld\n", (long)data->thermal_cruise[nr-1]); } static ssize_t -store_thermal_cruise_reg(struct device *dev, const char *buf, size_t count, int nr) +store_thermal_cruise(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { + struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); + int nr = sensor_attr->index; struct i2c_client *client = to_i2c_client(dev); struct w83792d_data *data = i2c_get_clientdata(client); u32 val; @@ -966,17 +881,8 @@ } #define sysfs_thermal_cruise(offset) \ -static ssize_t show_regs_thermal_cruise##offset (struct device *dev, char *buf) \ -{ \ - return show_thermal_cruise_reg(dev, buf, offset); \ -} \ -static ssize_t store_regs_thermal_cruise##offset (struct device *dev, \ - const char *buf, size_t count) \ -{ \ - return store_thermal_cruise_reg(dev, buf, count, offset); \ -} \ -static DEVICE_ATTR(thermal_cruise##offset, S_IRUGO | S_IWUSR, \ - show_regs_thermal_cruise##offset, store_regs_thermal_cruise##offset); +static SENSOR_DEVICE_ATTR(thermal_cruise##offset, S_IRUGO | S_IWUSR, \ +show_thermal_cruise, store_thermal_cruise, offset); sysfs_thermal_cruise(1); sysfs_thermal_cruise(2); @@ -984,21 +890,27 @@ #define device_create_file_thermal_cruise(client, offset) \ do { \ -device_create_file(&client->dev, &dev_attr_thermal_cruise##offset); \ +device_create_file(&client->dev, &sensor_dev_attr_thermal_cruise##offset.dev_attr); \ } while (0) /* For Smart Fan I/Thermal Cruise and Smart Fan II */ static ssize_t -show_tolerance_reg(struct device *dev, char *buf, int nr) +show_tolerance(struct device *dev, struct device_attribute *attr, + char *buf) { + struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); + int nr = sensor_attr->index; struct w83792d_data *data = w83792d_update_device(dev); return sprintf(buf, "%ld\n", (long)data->tolerance[nr-1]); } static ssize_t -store_tolerance_reg(struct device *dev, const char *buf, size_t count, int nr) +store_tolerance(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { + struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); + int nr = sensor_attr->index; struct i2c_client *client = to_i2c_client(dev); struct w83792d_data *data = i2c_get_clientdata(client); u32 val; @@ -1021,17 +933,8 @@ } #define sysfs_tolerance(offset) \ -static ssize_t show_regs_tolerance##offset (struct device *dev, char *buf) \ -{ \ - return show_tolerance_reg(dev, buf, offset); \ -} \ -static ssize_t store_regs_tolerance##offset (struct device *dev, \ - const char *buf, size_t count) \ -{ \ - return store_tolerance_reg(dev, buf, count, offset); \ -} \ -static DEVICE_ATTR(tolerance##offset, S_IRUGO | S_IWUSR, \ - show_regs_tolerance##offset, store_regs_tolerance##offset); +static SENSOR_DEVICE_ATTR(tolerance##offset, S_IRUGO | S_IWUSR, \ +show_tolerance, store_tolerance, offset); sysfs_tolerance(1); sysfs_tolerance(2); @@ -1039,21 +942,29 @@ #define device_create_file_tolerance(client, offset) \ do { \ -device_create_file(&client->dev, &dev_attr_tolerance##offset); \ +device_create_file(&client->dev, &sensor_dev_attr_tolerance##offset.dev_attr); \ } while (0) /* For Smart Fan II */ static ssize_t -show_sf2_point_reg(struct device *dev, char *buf, int nr, int index) +show_sf2_point(struct device *dev, struct device_attribute *attr, + char *buf) { + struct sensor_device_attribute_2 *sensor_attr = to_sensor_dev_attr_2(attr); + int nr = sensor_attr->nr; + int index = sensor_attr->index; struct w83792d_data *data = w83792d_update_device(dev); return sprintf(buf, "%ld\n", (long)data->sf2_points[index-1][nr-1]); } static ssize_t -store_sf2_point_reg(struct device *dev, const char *buf, size_t count, int nr, int index) +store_sf2_point(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { + struct sensor_device_attribute_2 *sensor_attr = to_sensor_dev_attr_2(attr); + int nr = sensor_attr->nr; + int index = sensor_attr->index; struct i2c_client *client = to_i2c_client(dev); struct w83792d_data *data = i2c_get_clientdata(client); u32 val; @@ -1071,18 +982,8 @@ } #define sysfs_sf2_point(offset, index) \ -static ssize_t show_regs_sf2_point##offset##_fan##index (struct device *dev, char *buf) \ -{ \ - return show_sf2_point_reg(dev, buf, offset, index); \ -} \ -static ssize_t store_regs_sf2_point##offset##_fan##index (struct device *dev, \ - const char *buf, size_t count) \ -{ \ - return store_sf2_point_reg(dev, buf, count, offset, index); \ -} \ -static DEVICE_ATTR(sf2_point##offset##_fan##index, S_IRUGO | S_IWUSR, \ - show_regs_sf2_point##offset##_fan##index, \ - store_regs_sf2_point##offset##_fan##index); +static SENSOR_DEVICE_ATTR_2(sf2_point##offset##_fan##index, S_IRUGO | S_IWUSR, \ +show_sf2_point, store_sf2_point, offset, index); sysfs_sf2_point(1, 1); /* Fan1 */ sysfs_sf2_point(2, 1); /* Fan1 */ @@ -1099,21 +1000,30 @@ #define device_create_file_sf2_point(client, offset, index) \ do { \ -device_create_file(&client->dev, &dev_attr_sf2_point##offset##_fan##index); \ +device_create_file(&client->dev, \ +&sensor_dev_attr_sf2_point##offset##_fan##index.dev_attr); \ } while (0) static ssize_t -show_sf2_level_reg(struct device *dev, char *buf, int nr, int index) +show_sf2_level(struct device *dev, struct device_attribute *attr, + char *buf) { + struct sensor_device_attribute_2 *sensor_attr = to_sensor_dev_attr_2(attr); + int nr = sensor_attr->nr; + int index = sensor_attr->index; struct w83792d_data *data = w83792d_update_device(dev); return sprintf(buf, "%d\n", (((data->sf2_levels[index-1][nr]) * 100) / 15)); } static ssize_t -store_sf2_level_reg(struct device *dev, const char *buf, size_t count, int nr, int index) +store_sf2_level(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { + struct sensor_device_attribute_2 *sensor_attr = to_sensor_dev_attr_2(attr); + int nr = sensor_attr->nr; + int index = sensor_attr->index; struct i2c_client *client = to_i2c_client(dev); struct w83792d_data *data = i2c_get_clientdata(client); u32 val; @@ -1136,19 +1046,8 @@ } #define sysfs_sf2_level(offset, index) \ -static ssize_t show_regs_sf2_level##offset##_fan##index (struct device *dev, char *buf) \ -{ \ - return show_sf2_level_reg(dev, buf, offset, index); \ -} \ -static ssize_t store_regs_sf2_level##offset##_fan##index (struct device *dev, \ - const char *buf, size_t count) \ -{ \ - return store_sf2_level_reg(dev, buf, count, offset, index); \ -} \ -static DEVICE_ATTR(sf2_level##offset##_fan##index, S_IRUGO | S_IWUSR, \ - show_regs_sf2_level##offset##_fan##index, \ - store_regs_sf2_level##offset##_fan##index); - +static SENSOR_DEVICE_ATTR_2(sf2_level##offset##_fan##index, S_IRUGO | S_IWUSR, \ +show_sf2_level, store_sf2_level, offset, index); sysfs_sf2_level(1, 1); /* Fan1 */ sysfs_sf2_level(2, 1); /* Fan1 */ @@ -1162,7 +1061,8 @@ #define device_create_file_sf2_level(client, offset, index) \ do { \ -device_create_file(&client->dev, &dev_attr_sf2_level##offset##_fan##index); \ +device_create_file(&client->dev, \ +&sensor_dev_attr_sf2_level##offset##_fan##index.dev_attr); \ } while (0) @@ -1411,14 +1311,6 @@ device_create_file_alarms(new_client); - device_create_file_fan_div(new_client, 1); - device_create_file_fan_div(new_client, 2); - device_create_file_fan_div(new_client, 3); - device_create_file_fan_div(new_client, 4); - device_create_file_fan_div(new_client, 5); - device_create_file_fan_div(new_client, 6); - device_create_file_fan_div(new_client, 7); - device_create_file_pwm(new_client, 1); device_create_file_pwm(new_client, 2); device_create_file_pwm(new_client, 3); @@ -1727,7 +1619,7 @@ i2c_del_driver(&w83792d_driver); } -MODULE_AUTHOR("Chunhao Huang @ Winbond "); +MODULE_AUTHOR("Chunhao Huang @ Winbond "); MODULE_DESCRIPTION("W83792AD/D driver for linux-2.6"); MODULE_LICENSE("GPL"); diff -Naur a/include/linux/hwmon-sysfs.h b/include/linux/hwmon-sysfs.h --- a/include/linux/hwmon-sysfs.h 2005-07-13 06:46:46.000000000 +0200 +++ b/include/linux/hwmon-sysfs.h 2005-07-15 12:56:55.018310250 +0200 @@ -33,4 +33,19 @@ .index = _index, \ } +struct sensor_device_attribute_2 { + struct device_attribute dev_attr; + u8 index; + u8 nr; +}; +#define to_sensor_dev_attr_2(_dev_attr) \ + container_of(_dev_attr, struct sensor_device_attribute_2, dev_attr) + +#define SENSOR_DEVICE_ATTR_2(_name,_mode,_show,_store,_nr,_index) \ +struct sensor_device_attribute_2 sensor_dev_attr_##_name = { \ + .dev_attr = __ATTR(_name,_mode,_show,_store), \ + .index = _index, \ + .nr = _nr, \ +} + #endif /* _LINUX_HWMON_SYSFS_H */