[PATCH] hwmon: adm9240 driver update - dynamic sysfs
authorGrant Coady <grant_lkml@dodo.com.au>
Fri, 16 Sep 2005 19:32:57 +0000 (05:32 +1000)
committerGreg Kroah-Hartman <gregkh@suse.de>
Fri, 28 Oct 2005 21:02:05 +0000 (14:02 -0700)
hwmon: adm9240 update 2/2: convert to use dynamic sysfs accessors

This patch converts adm9240 to use Yani Ioannou's dynamic sysfs callbacks,
reducing driver memory footprint from 16312 to 14104 bytes on 2.6.14-rc1,
removing the old driver macro mess.

Run tested on Intel SE440BX-2 mobo.

Signed-off-by: Grant Coady <gcoady@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/hwmon/adm9240.c

index ecef342e5fa3b03cf3f469e3a25ecff32bbbe5d5..8bb6d6e45ed5f43d67654077e0211ff388b08eb4 100644 (file)
@@ -45,6 +45,7 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/i2c.h>
+#include <linux/hwmon-sysfs.h>
 #include <linux/hwmon.h>
 #include <linux/hwmon-vid.h>
 #include <linux/err.h>
@@ -69,8 +70,7 @@ I2C_CLIENT_INSMOD_3(adm9240, ds1780, lm81);
 #define ADM9240_REG_INT(nr)            (0x41 + (nr))
 #define ADM9240_REG_INT_MASK(nr)       (0x43 + (nr))
 #define ADM9240_REG_TEMP               0x27
-#define ADM9240_REG_TEMP_HIGH          0x39
-#define ADM9240_REG_TEMP_HYST          0x3a
+#define ADM9240_REG_TEMP_MAX(nr)       (0x39 + (nr)) /* 0, 1 = high, hyst */
 #define ADM9240_REG_ANALOG_OUT         0x19
 #define ADM9240_REG_CHASSIS_CLEAR      0x46
 #define ADM9240_REG_VID_FAN_DIV                0x47
@@ -162,8 +162,7 @@ struct adm9240_data {
        u8 fan_min[2];          /* rw   fan1_min */
        u8 fan_div[2];          /* rw   fan1_div, read-only accessor */
        s16 temp;               /* ro   temp1_input, 9-bit sign-extended */
-       s8 temp_high;           /* rw   temp1_max */
-       s8 temp_hyst;           /* rw   temp1_max_hyst */
+       s8 temp_max[2];         /* rw   0 -> temp_max, 1 -> temp_max_hyst */
        u16 alarms;             /* ro   alarms */
        u8 aout;                /* rw   aout_output */
        u8 vid;                 /* ro   vid */
@@ -173,157 +172,143 @@ struct adm9240_data {
 /*** sysfs accessors ***/
 
 /* temperature */
-#define show_temp(value, scale)                                        \
-static ssize_t show_##value(struct device *dev,                        \
-                           struct device_attribute *attr,      \
-                           char *buf)                          \
-{                                                              \
-       struct adm9240_data *data = adm9240_update_device(dev); \
-       return sprintf(buf, "%d\n", data->value * scale);       \
-}
-show_temp(temp_high, 1000);
-show_temp(temp_hyst, 1000);
-show_temp(temp, 500); /* 0.5'C per bit */
-
-#define set_temp(value, reg)                                   \
-static ssize_t set_##value(struct device *dev,                         \
-                          struct device_attribute *attr,       \
-                          const char *buf, size_t count)       \
-{                                                              \
-       struct i2c_client *client = to_i2c_client(dev);         \
-       struct adm9240_data *data = adm9240_update_device(dev); \
-       long temp = simple_strtoul(buf, NULL, 10);              \
-                                                               \
-       down(&data->update_lock);                               \
-       data->value = TEMP_TO_REG(temp);                        \
-       i2c_smbus_write_byte_data(client, reg, data->value);    \
-       up(&data->update_lock);                                 \
-       return count;                                           \
-}
-
-set_temp(temp_high, ADM9240_REG_TEMP_HIGH);
-set_temp(temp_hyst, ADM9240_REG_TEMP_HYST);
-
-static DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO,
-               show_temp_high, set_temp_high);
-static DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO,
-               show_temp_hyst, set_temp_hyst);
+static ssize_t show_temp(struct device *dev, struct device_attribute *dummy,
+               char *buf)
+{
+       struct adm9240_data *data = adm9240_update_device(dev);
+       return sprintf(buf, "%d\n", data->temp * 500); /* 9-bit value */
+}
+
+static ssize_t show_max(struct device *dev, struct device_attribute *devattr,
+               char *buf)
+{
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+       struct adm9240_data *data = adm9240_update_device(dev);
+       return sprintf(buf, "%d\n", data->temp_max[attr->index] * 1000);
+}
+
+static ssize_t set_max(struct device *dev, struct device_attribute *devattr,
+               const char *buf, size_t count)
+{
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+       struct i2c_client *client = to_i2c_client(dev);
+       struct adm9240_data *data = i2c_get_clientdata(client);
+       long val = simple_strtol(buf, NULL, 10);
+
+       down(&data->update_lock);
+       data->temp_max[attr->index] = TEMP_TO_REG(val);
+       i2c_smbus_write_byte_data(client, ADM9240_REG_TEMP_MAX(attr->index),
+                       data->temp_max[attr->index]);
+       up(&data->update_lock);
+       return count;
+}
+
 static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL);
+static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO,
+               show_max, set_max, 0);
+static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO,
+               show_max, set_max, 1);
 
 /* voltage */
-static ssize_t show_in(struct device *dev, char *buf, int nr)
+static ssize_t show_in(struct device *dev, struct device_attribute *devattr,
+               char *buf)
 {
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
        struct adm9240_data *data = adm9240_update_device(dev);
-       return sprintf(buf, "%d\n", IN_FROM_REG(data->in[nr], nr));
+       return sprintf(buf, "%d\n", IN_FROM_REG(data->in[attr->index],
+                               attr->index));
 }
 
-static ssize_t show_in_min(struct device *dev, char *buf, int nr)
+static ssize_t show_in_min(struct device *dev, struct device_attribute *devattr,
+               char *buf)
 {
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
        struct adm9240_data *data = adm9240_update_device(dev);
-       return sprintf(buf, "%d\n", IN_FROM_REG(data->in_min[nr], nr));
+       return sprintf(buf, "%d\n", IN_FROM_REG(data->in_min[attr->index],
+                               attr->index));
 }
 
-static ssize_t show_in_max(struct device *dev, char *buf, int nr)
+static ssize_t show_in_max(struct device *dev, struct device_attribute *devattr,
+               char *buf)
 {
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
        struct adm9240_data *data = adm9240_update_device(dev);
-       return sprintf(buf, "%d\n", IN_FROM_REG(data->in_max[nr], nr));
+       return sprintf(buf, "%d\n", IN_FROM_REG(data->in_max[attr->index],
+                               attr->index));
 }
 
-static ssize_t set_in_min(struct device *dev, const char *buf,
-               size_t count, int nr)
+static ssize_t set_in_min(struct device *dev, struct device_attribute *devattr,
+               const char *buf, size_t count)
 {
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
        struct i2c_client *client = to_i2c_client(dev);
        struct adm9240_data *data = i2c_get_clientdata(client);
        unsigned long val = simple_strtoul(buf, NULL, 10);
 
        down(&data->update_lock);
-       data->in_min[nr] = IN_TO_REG(val, nr);
-       i2c_smbus_write_byte_data(client, ADM9240_REG_IN_MIN(nr),
-                       data->in_min[nr]);
+       data->in_min[attr->index] = IN_TO_REG(val, attr->index);
+       i2c_smbus_write_byte_data(client, ADM9240_REG_IN_MIN(attr->index),
+                       data->in_min[attr->index]);
        up(&data->update_lock);
        return count;
 }
 
-static ssize_t set_in_max(struct device *dev, const char *buf,
-               size_t count, int nr)
+static ssize_t set_in_max(struct device *dev, struct device_attribute *devattr,
+               const char *buf, size_t count)
 {
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
        struct i2c_client *client = to_i2c_client(dev);
        struct adm9240_data *data = i2c_get_clientdata(client);
        unsigned long val = simple_strtoul(buf, NULL, 10);
 
        down(&data->update_lock);
-       data->in_max[nr] = IN_TO_REG(val, nr);
-       i2c_smbus_write_byte_data(client, ADM9240_REG_IN_MAX(nr),
-                       data->in_max[nr]);
+       data->in_max[attr->index] = IN_TO_REG(val, attr->index);
+       i2c_smbus_write_byte_data(client, ADM9240_REG_IN_MAX(attr->index),
+                       data->in_max[attr->index]);
        up(&data->update_lock);
        return count;
 }
 
-#define show_in_offset(offset)                                         \
-static ssize_t show_in##offset(struct device *dev,                     \
-                              struct device_attribute *attr,           \
-                              char *buf)                               \
-{                                                                      \
-       return show_in(dev, buf, offset);                               \
-}                                                                      \
-static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_in##offset, NULL);        \
-static ssize_t show_in##offset##_min(struct device *dev,               \
-                                    struct device_attribute *attr,     \
-                                    char *buf)                         \
-{                                                                      \
-       return show_in_min(dev, buf, offset);                           \
-}                                                                      \
-static ssize_t show_in##offset##_max(struct device *dev,               \
-                                    struct device_attribute *attr,     \
-                                    char *buf)                         \
-{                                                                      \
-       return show_in_max(dev, buf, offset);                           \
-}                                                                      \
-static ssize_t                                                         \
-set_in##offset##_min(struct device *dev,                               \
-                    struct device_attribute *attr, const char *buf,    \
-                    size_t count)                                      \
-{                                                                      \
-       return set_in_min(dev, buf, count, offset);                     \
-}                                                                      \
-static ssize_t                                                         \
-set_in##offset##_max(struct device *dev,                               \
-                    struct device_attribute *attr, const char *buf,    \
-                    size_t count)                                      \
-{                                                                      \
-       return set_in_max(dev, buf, count, offset);                     \
-}                                                                      \
-static DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR,                        \
-               show_in##offset##_min, set_in##offset##_min);           \
-static DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR,                        \
-               show_in##offset##_max, set_in##offset##_max);
-
-show_in_offset(0);
-show_in_offset(1);
-show_in_offset(2);
-show_in_offset(3);
-show_in_offset(4);
-show_in_offset(5);
+#define vin(nr)                                                        \
+static SENSOR_DEVICE_ATTR(in##nr##_input, S_IRUGO,             \
+               show_in, NULL, nr);                             \
+static SENSOR_DEVICE_ATTR(in##nr##_min, S_IRUGO | S_IWUSR,     \
+               show_in_min, set_in_min, nr);                   \
+static SENSOR_DEVICE_ATTR(in##nr##_max, S_IRUGO | S_IWUSR,     \
+               show_in_max, set_in_max, nr);
+
+vin(0);
+vin(1);
+vin(2);
+vin(3);
+vin(4);
+vin(5);
 
 /* fans */
-static ssize_t show_fan(struct device *dev, char *buf, int nr)
+static ssize_t show_fan(struct device *dev,
+               struct device_attribute *devattr, char *buf)
 {
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
        struct adm9240_data *data = adm9240_update_device(dev);
-       return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr],
-                               1 << data->fan_div[nr]));
+       return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[attr->index],
+                               1 << data->fan_div[attr->index]));
 }
 
-static ssize_t show_fan_min(struct device *dev, char *buf, int nr)
+static ssize_t show_fan_min(struct device *dev,
+               struct device_attribute *devattr, char *buf)
 {
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
        struct adm9240_data *data = adm9240_update_device(dev);
-       return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan_min[nr],
-                               1 << data->fan_div[nr]));
+       return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan_min[attr->index],
+                               1 << data->fan_div[attr->index]));
 }
 
-static ssize_t show_fan_div(struct device *dev, char *buf, int nr)
+static ssize_t show_fan_div(struct device *dev,
+               struct device_attribute *devattr, char *buf)
 {
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
        struct adm9240_data *data = adm9240_update_device(dev);
-       return sprintf(buf, "%d\n", 1 << data->fan_div[nr]);
+       return sprintf(buf, "%d\n", 1 << data->fan_div[attr->index]);
 }
 
 /* write new fan div, callers must hold data->update_lock */
@@ -352,12 +337,15 @@ static void adm9240_write_fan_div(struct i2c_client *client, int nr,
  * - otherwise: select fan clock divider to suit fan speed low limit,
  *   measurement code may adjust registers to ensure fan speed reading
  */
-static ssize_t set_fan_min(struct device *dev, const char *buf,
-               size_t count, int nr)
+static ssize_t set_fan_min(struct device *dev,
+               struct device_attribute *devattr,
+               const char *buf, size_t count)
 {
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
        struct i2c_client *client = to_i2c_client(dev);
        struct adm9240_data *data = i2c_get_clientdata(client);
        unsigned long val = simple_strtoul(buf, NULL, 10);
+       int nr = attr->index;
        u8 new_div;
 
        down(&data->update_lock);
@@ -404,40 +392,16 @@ static ssize_t set_fan_min(struct device *dev, const char *buf,
        return count;
 }
 
-#define show_fan_offset(offset)                                                \
-static ssize_t show_fan_##offset (struct device *dev,                  \
-                                 struct device_attribute *attr,        \
-                                 char *buf)                            \
-{                                                                      \
-return show_fan(dev, buf, offset - 1);                                 \
-}                                                                      \
-static ssize_t show_fan_##offset##_div (struct device *dev,            \
-                                       struct device_attribute *attr,  \
-                                       char *buf)                      \
-{                                                                      \
-return show_fan_div(dev, buf, offset - 1);                             \
-}                                                                      \
-static ssize_t show_fan_##offset##_min (struct device *dev,            \
-                                       struct device_attribute *attr,  \
-                                       char *buf)                      \
-{                                                                      \
-return show_fan_min(dev, buf, offset - 1);                             \
-}                                                                      \
-static ssize_t set_fan_##offset##_min (struct device *dev,             \
-                                      struct device_attribute *attr,   \
-                                      const char *buf, size_t count)   \
-{                                                                      \
-return set_fan_min(dev, buf, count, offset - 1);                       \
-}                                                                      \
-static DEVICE_ATTR(fan##offset##_input, S_IRUGO,                       \
-               show_fan_##offset, NULL);                               \
-static DEVICE_ATTR(fan##offset##_div, S_IRUGO,                                 \
-               show_fan_##offset##_div, NULL);                         \
-static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR,               \
-               show_fan_##offset##_min, set_fan_##offset##_min);
-
-show_fan_offset(1);
-show_fan_offset(2);
+#define fan(nr)                                                        \
+static SENSOR_DEVICE_ATTR(fan##nr##_input, S_IRUGO,            \
+               show_fan, NULL, nr - 1);                        \
+static SENSOR_DEVICE_ATTR(fan##nr##_div, S_IRUGO,              \
+               show_fan_div, NULL, nr - 1);                    \
+static SENSOR_DEVICE_ATTR(fan##nr##_min, S_IRUGO | S_IWUSR,    \
+               show_fan_min, set_fan_min, nr - 1);
+
+fan(1);
+fan(2);
 
 /* alarms */
 static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf)
@@ -580,33 +544,59 @@ static int adm9240_detect(struct i2c_adapter *adapter, int address, int kind)
                goto exit_detach;
        }
 
-       device_create_file(&new_client->dev, &dev_attr_in0_input);
-       device_create_file(&new_client->dev, &dev_attr_in0_min);
-       device_create_file(&new_client->dev, &dev_attr_in0_max);
-       device_create_file(&new_client->dev, &dev_attr_in1_input);
-       device_create_file(&new_client->dev, &dev_attr_in1_min);
-       device_create_file(&new_client->dev, &dev_attr_in1_max);
-       device_create_file(&new_client->dev, &dev_attr_in2_input);
-       device_create_file(&new_client->dev, &dev_attr_in2_min);
-       device_create_file(&new_client->dev, &dev_attr_in2_max);
-       device_create_file(&new_client->dev, &dev_attr_in3_input);
-       device_create_file(&new_client->dev, &dev_attr_in3_min);
-       device_create_file(&new_client->dev, &dev_attr_in3_max);
-       device_create_file(&new_client->dev, &dev_attr_in4_input);
-       device_create_file(&new_client->dev, &dev_attr_in4_min);
-       device_create_file(&new_client->dev, &dev_attr_in4_max);
-       device_create_file(&new_client->dev, &dev_attr_in5_input);
-       device_create_file(&new_client->dev, &dev_attr_in5_min);
-       device_create_file(&new_client->dev, &dev_attr_in5_max);
-       device_create_file(&new_client->dev, &dev_attr_temp1_max);
-       device_create_file(&new_client->dev, &dev_attr_temp1_max_hyst);
+       device_create_file(&new_client->dev,
+                       &sensor_dev_attr_in0_input.dev_attr);
+       device_create_file(&new_client->dev,
+                       &sensor_dev_attr_in0_min.dev_attr);
+       device_create_file(&new_client->dev,
+                       &sensor_dev_attr_in0_max.dev_attr);
+       device_create_file(&new_client->dev,
+                       &sensor_dev_attr_in1_input.dev_attr);
+       device_create_file(&new_client->dev,
+                       &sensor_dev_attr_in1_min.dev_attr);
+       device_create_file(&new_client->dev,
+                       &sensor_dev_attr_in1_max.dev_attr);
+       device_create_file(&new_client->dev,
+                       &sensor_dev_attr_in2_input.dev_attr);
+       device_create_file(&new_client->dev,
+                       &sensor_dev_attr_in2_min.dev_attr);
+       device_create_file(&new_client->dev,
+                       &sensor_dev_attr_in2_max.dev_attr);
+       device_create_file(&new_client->dev,
+                       &sensor_dev_attr_in3_input.dev_attr);
+       device_create_file(&new_client->dev,
+                       &sensor_dev_attr_in3_min.dev_attr);
+       device_create_file(&new_client->dev,
+                       &sensor_dev_attr_in3_max.dev_attr);
+       device_create_file(&new_client->dev,
+                       &sensor_dev_attr_in4_input.dev_attr);
+       device_create_file(&new_client->dev,
+                       &sensor_dev_attr_in4_min.dev_attr);
+       device_create_file(&new_client->dev,
+                       &sensor_dev_attr_in4_max.dev_attr);
+       device_create_file(&new_client->dev,
+                       &sensor_dev_attr_in5_input.dev_attr);
+       device_create_file(&new_client->dev,
+                       &sensor_dev_attr_in5_min.dev_attr);
+       device_create_file(&new_client->dev,
+                       &sensor_dev_attr_in5_max.dev_attr);
        device_create_file(&new_client->dev, &dev_attr_temp1_input);
-       device_create_file(&new_client->dev, &dev_attr_fan1_input);
-       device_create_file(&new_client->dev, &dev_attr_fan1_div);
-       device_create_file(&new_client->dev, &dev_attr_fan1_min);
-       device_create_file(&new_client->dev, &dev_attr_fan2_input);
-       device_create_file(&new_client->dev, &dev_attr_fan2_div);
-       device_create_file(&new_client->dev, &dev_attr_fan2_min);
+       device_create_file(&new_client->dev,
+                       &sensor_dev_attr_temp1_max.dev_attr);
+       device_create_file(&new_client->dev,
+                       &sensor_dev_attr_temp1_max_hyst.dev_attr);
+       device_create_file(&new_client->dev,
+                       &sensor_dev_attr_fan1_input.dev_attr);
+       device_create_file(&new_client->dev,
+                       &sensor_dev_attr_fan1_div.dev_attr);
+       device_create_file(&new_client->dev,
+                       &sensor_dev_attr_fan1_min.dev_attr);
+       device_create_file(&new_client->dev,
+                       &sensor_dev_attr_fan2_input.dev_attr);
+       device_create_file(&new_client->dev,
+                       &sensor_dev_attr_fan2_div.dev_attr);
+       device_create_file(&new_client->dev,
+                       &sensor_dev_attr_fan2_min.dev_attr);
        device_create_file(&new_client->dev, &dev_attr_alarms);
        device_create_file(&new_client->dev, &dev_attr_aout_output);
        device_create_file(&new_client->dev, &dev_attr_chassis_clear);
@@ -674,9 +664,9 @@ static void adm9240_init_client(struct i2c_client *client)
                i2c_smbus_write_byte_data(client,
                                ADM9240_REG_FAN_MIN(1), 255);
                i2c_smbus_write_byte_data(client,
-                               ADM9240_REG_TEMP_HIGH, 127);
+                               ADM9240_REG_TEMP_MAX(0), 127);
                i2c_smbus_write_byte_data(client,
-                               ADM9240_REG_TEMP_HYST, 127);
+                               ADM9240_REG_TEMP_MAX(1), 127);
 
                /* start measurement cycle */
                i2c_smbus_write_byte_data(client, ADM9240_REG_CONFIG, 1);
@@ -753,10 +743,10 @@ static struct adm9240_data *adm9240_update_device(struct device *dev)
                        data->fan_min[i] = i2c_smbus_read_byte_data(client,
                                        ADM9240_REG_FAN_MIN(i));
                }
-               data->temp_high = i2c_smbus_read_byte_data(client,
-                               ADM9240_REG_TEMP_HIGH);
-               data->temp_hyst = i2c_smbus_read_byte_data(client,
-                               ADM9240_REG_TEMP_HYST);
+               data->temp_max[0] = i2c_smbus_read_byte_data(client,
+                               ADM9240_REG_TEMP_MAX(0));
+               data->temp_max[1] = i2c_smbus_read_byte_data(client,
+                               ADM9240_REG_TEMP_MAX(1));
 
                /* read fan divs and 5-bit VID */
                i = i2c_smbus_read_byte_data(client, ADM9240_REG_VID_FAN_DIV);