hwmon: (ads7828) Accept optional parameters from device tree
authorSam Povilus <kernel.development@povil.us>
Thu, 30 Mar 2017 03:46:37 +0000 (21:46 -0600)
committerGuenter Roeck <linux@roeck-us.net>
Sun, 2 Apr 2017 14:01:53 +0000 (07:01 -0700)
Adding the ability for the ads7828 and ads7830 to use device tree to
get optional parameters instead of using platform devices. This allows
people using custom boards to also use the ads7828 in a non-default manner.

Signed-off-by: Sam Povilus <kernel.development@povil.us>
[groeck: Fixed whitespace errors in ads7828.txt]
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Documentation/devicetree/bindings/hwmon/ads7828.txt [new file with mode: 0644]
drivers/hwmon/ads7828.c

diff --git a/Documentation/devicetree/bindings/hwmon/ads7828.txt b/Documentation/devicetree/bindings/hwmon/ads7828.txt
new file mode 100644 (file)
index 0000000..fe0cc4a
--- /dev/null
@@ -0,0 +1,25 @@
+ads7828 properties
+
+Required properties:
+- compatible: Should be one of
+              ti,ads7828
+              ti,ads7830
+- reg: I2C address
+
+Optional properties:
+
+- ti,differential-input
+  Set to use the device in differential mode.
+- vref-supply
+  The external reference on the device is set to this regulators output. If it
+  does not exists the internal reference will be used and output by the ads78xx
+  on the "external vref" pin.
+
+  Example ADS7828 node:
+
+  ads7828: ads@48 {
+          comatible = "ti,ads7828";
+          reg = <0x48>;
+          vref-supply = <&vref>;
+          ti,differential-input;
+  };
index b0ef66687816b3084b1b41c70965afc59a3a28a1..898607bf682b73637a8818e6959c419a5e1acafa 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/platform_data/ads7828.h>
 #include <linux/regmap.h>
 #include <linux/slab.h>
+#include <linux/regulator/consumer.h>
 
 /* The ADS7828 registers */
 #define ADS7828_CMD_SD_SE      0x80    /* Single ended inputs */
@@ -119,10 +120,12 @@ static int ads7828_probe(struct i2c_client *client,
        struct ads7828_data *data;
        struct device *hwmon_dev;
        unsigned int vref_mv = ADS7828_INT_VREF_MV;
+       unsigned int vref_uv;
        bool diff_input = false;
        bool ext_vref = false;
        unsigned int regval;
        enum ads7828_chips chip;
+       struct regulator *reg;
 
        data = devm_kzalloc(dev, sizeof(struct ads7828_data), GFP_KERNEL);
        if (!data)
@@ -133,6 +136,18 @@ static int ads7828_probe(struct i2c_client *client,
                ext_vref = pdata->ext_vref;
                if (ext_vref && pdata->vref_mv)
                        vref_mv = pdata->vref_mv;
+       } else if (dev->of_node) {
+               diff_input = of_property_read_bool(dev->of_node,
+                                                  "ti,differential-input");
+               reg = devm_regulator_get_optional(dev, "vref");
+               if (!IS_ERR(reg)) {
+                       vref_uv = regulator_get_voltage(reg);
+                       vref_mv = DIV_ROUND_CLOSEST(vref_uv, 1000);
+                       if (vref_mv < ADS7828_EXT_VREF_MV_MIN ||
+                           vref_mv > ADS7828_EXT_VREF_MV_MAX)
+                               return -EINVAL;
+                       ext_vref = true;
+               }
        }
 
        if (client->dev.of_node)