hwmon: (core) Add support for string attributes to new API
authorGuenter Roeck <linux@roeck-us.net>
Mon, 8 Aug 2016 03:51:25 +0000 (20:51 -0700)
committerGuenter Roeck <linux@roeck-us.net>
Sat, 10 Dec 2016 05:54:16 +0000 (21:54 -0800)
The new API is so far only suited for data attributes and does not work
well for string attributes, specifically for the 'label' attributes.
Provide a separate callback function for those.

Signed-off-by: Guenter Roeck <linux@roeck-us.net>
drivers/hwmon/hwmon.c
include/linux/hwmon.h

index a74c075a30ec49608308ddd45715f1addc104c84..491231fa0580d248ebe234b3ff8b0df2fde3c09b 100644 (file)
@@ -178,6 +178,22 @@ static ssize_t hwmon_attr_show(struct device *dev,
        return sprintf(buf, "%ld\n", val);
 }
 
+static ssize_t hwmon_attr_show_string(struct device *dev,
+                                     struct device_attribute *devattr,
+                                     char *buf)
+{
+       struct hwmon_device_attribute *hattr = to_hwmon_attr(devattr);
+       char *s;
+       int ret;
+
+       ret = hattr->ops->read_string(dev, hattr->type, hattr->attr,
+                                     hattr->index, &s);
+       if (ret < 0)
+               return ret;
+
+       return sprintf(buf, "%s\n", s);
+}
+
 static ssize_t hwmon_attr_store(struct device *dev,
                                struct device_attribute *devattr,
                                const char *buf, size_t count)
@@ -205,6 +221,17 @@ static int hwmon_attr_base(enum hwmon_sensor_types type)
        return 1;
 }
 
+static bool is_string_attr(enum hwmon_sensor_types type, u32 attr)
+{
+       return (type == hwmon_temp && attr == hwmon_temp_label) ||
+              (type == hwmon_in && attr == hwmon_in_label) ||
+              (type == hwmon_curr && attr == hwmon_curr_label) ||
+              (type == hwmon_power && attr == hwmon_power_label) ||
+              (type == hwmon_energy && attr == hwmon_energy_label) ||
+              (type == hwmon_humidity && attr == hwmon_humidity_label) ||
+              (type == hwmon_fan && attr == hwmon_fan_label);
+}
+
 static struct attribute *hwmon_genattr(struct device *dev,
                                       const void *drvdata,
                                       enum hwmon_sensor_types type,
@@ -218,6 +245,7 @@ static struct attribute *hwmon_genattr(struct device *dev,
        struct attribute *a;
        umode_t mode;
        char *name;
+       bool is_string = is_string_attr(type, attr);
 
        /* The attribute is invisible if there is no template string */
        if (!template)
@@ -227,7 +255,8 @@ static struct attribute *hwmon_genattr(struct device *dev,
        if (!mode)
                return ERR_PTR(-ENOENT);
 
-       if ((mode & S_IRUGO) && !ops->read)
+       if ((mode & S_IRUGO) && ((is_string && !ops->read_string) ||
+                                (!is_string && !ops->read)))
                return ERR_PTR(-EINVAL);
        if ((mode & S_IWUGO) && !ops->write)
                return ERR_PTR(-EINVAL);
@@ -252,7 +281,7 @@ static struct attribute *hwmon_genattr(struct device *dev,
        hattr->ops = ops;
 
        dattr = &hattr->dev_attr;
-       dattr->show = hwmon_attr_show;
+       dattr->show = is_string ? hwmon_attr_show_string : hwmon_attr_show;
        dattr->store = hwmon_attr_store;
 
        a = &dattr->attr;
index b6a86aa4a9e2881db80adfb2a26cc3a11a26d624..e68334aede4cdae2cd9480c02277b932b13a238f 100644 (file)
@@ -298,7 +298,8 @@ enum hwmon_pwm_attributes {
  *                     Channel number
  *             The function returns the file permissions.
  *             If the return value is 0, no attribute will be created.
- * @read:      Read callback. Mandatory if readable attributes are present.
+ * @read:      Read callback for data attributes. Mandatory if readable
+ *             data attributes are present.
  *             Parameters are:
  *             @dev:   Pointer to hardware monitoring device
  *             @type:  Sensor type
@@ -307,7 +308,19 @@ enum hwmon_pwm_attributes {
  *                     Channel number
  *             @val:   Pointer to returned value
  *             The function returns 0 on success or a negative error number.
- * @write:     Write callback. Mandatory if writeable attributes are present.
+ * @read_string:
+ *             Read callback for string attributes. Mandatory if string
+ *             attributes are present.
+ *             Parameters are:
+ *             @dev:   Pointer to hardware monitoring device
+ *             @type:  Sensor type
+ *             @attr:  Sensor attribute
+ *             @channel:
+ *                     Channel number
+ *             @str:   Pointer to returned string
+ *             The function returns 0 on success or a negative error number.
+ * @write:     Write callback for data attributes. Mandatory if writeable
+ *             data attributes are present.
  *             Parameters are:
  *             @dev:   Pointer to hardware monitoring device
  *             @type:  Sensor type
@@ -322,6 +335,8 @@ struct hwmon_ops {
                              u32 attr, int channel);
        int (*read)(struct device *dev, enum hwmon_sensor_types type,
                    u32 attr, int channel, long *val);
+       int (*read_string)(struct device *dev, enum hwmon_sensor_types type,
+                   u32 attr, int channel, char **str);
        int (*write)(struct device *dev, enum hwmon_sensor_types type,
                     u32 attr, int channel, long val);
 };