mtd: gpmi: change the BCH layout setting for large oob NAND
[oweals/u-boot.git] / drivers / adc / adc-uclass.c
index a5ef722d2137d7e089ee69f727035f4df8d6f89f..0a492eba5437c3e0dad9c7c410138ff312ede3d8 100644 (file)
@@ -1,12 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Copyright (C) 2015 Samsung Electronics
  * Przemyslaw Marczak <p.marczak@samsung.com>
- *
- * SPDX-License-Identifier:    GPL-2.0+
  */
 
 #include <common.h>
 #include <errno.h>
+#include <div64.h>
 #include <dm.h>
 #include <dm/lists.h>
 #include <dm/device-internal.h>
@@ -14,8 +14,6 @@
 #include <adc.h>
 #include <power/regulator.h>
 
-DECLARE_GLOBAL_DATA_PTR;
-
 #define ADC_UCLASS_PLATDATA_SIZE       sizeof(struct adc_uclass_platdata)
 #define CHECK_NUMBER                   true
 #define CHECK_MASK                     (!CHECK_NUMBER)
@@ -64,7 +62,7 @@ static int adc_supply_enable(struct udevice *dev)
        }
 
        if (ret)
-               error("%s: can't enable %s-supply!", dev->name, supply_type);
+               pr_err("%s: can't enable %s-supply!", dev->name, supply_type);
 
        return ret;
 }
@@ -80,6 +78,18 @@ int adc_data_mask(struct udevice *dev, unsigned int *data_mask)
        return 0;
 }
 
+int adc_channel_mask(struct udevice *dev, unsigned int *channel_mask)
+{
+       struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev);
+
+       if (!uc_pdata)
+               return -ENOSYS;
+
+       *channel_mask = uc_pdata->channel_mask;
+
+       return 0;
+}
+
 int adc_stop(struct udevice *dev)
 {
        const struct adc_ops *ops = dev_get_driver_ops(dev);
@@ -267,10 +277,8 @@ static int adc_vdd_platdata_update(struct udevice *dev)
         * will bind before its supply regulator device, then the below 'get'
         * will return an error.
         */
-       ret = device_get_supply_regulator(dev, "vdd-supply",
-                                         &uc_pdata->vdd_supply);
-       if (ret)
-               return ret;
+       if (!uc_pdata->vdd_supply)
+               return 0;
 
        ret = regulator_get_value(uc_pdata->vdd_supply);
        if (ret < 0)
@@ -286,10 +294,8 @@ static int adc_vss_platdata_update(struct udevice *dev)
        struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev);
        int ret;
 
-       ret = device_get_supply_regulator(dev, "vss-supply",
-                                         &uc_pdata->vss_supply);
-       if (ret)
-               return ret;
+       if (!uc_pdata->vss_supply)
+               return 0;
 
        ret = regulator_get_value(uc_pdata->vss_supply);
        if (ret < 0)
@@ -305,14 +311,11 @@ int adc_vdd_value(struct udevice *dev, int *uV)
        struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev);
        int ret, value_sign = uc_pdata->vdd_polarity_negative ? -1 : 1;
 
-       if (!uc_pdata->vdd_supply)
-               goto nodev;
-
        /* Update the regulator Value. */
        ret = adc_vdd_platdata_update(dev);
        if (ret)
                return ret;
-nodev:
+
        if (uc_pdata->vdd_microvolts == -ENODATA)
                return -ENODATA;
 
@@ -326,14 +329,11 @@ int adc_vss_value(struct udevice *dev, int *uV)
        struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev);
        int ret, value_sign = uc_pdata->vss_polarity_negative ? -1 : 1;
 
-       if (!uc_pdata->vss_supply)
-               goto nodev;
-
        /* Update the regulator Value. */
        ret = adc_vss_platdata_update(dev);
        if (ret)
                return ret;
-nodev:
+
        if (uc_pdata->vss_microvolts == -ENODATA)
                return -ENODATA;
 
@@ -342,6 +342,30 @@ nodev:
        return 0;
 }
 
+int adc_raw_to_uV(struct udevice *dev, unsigned int raw, int *uV)
+{
+       unsigned int data_mask;
+       int ret, val, vref;
+       u64 raw64 = raw;
+
+       ret = adc_vdd_value(dev, &vref);
+       if (ret)
+               return ret;
+
+       if (!adc_vss_value(dev, &val))
+               vref -= val;
+
+       ret = adc_data_mask(dev, &data_mask);
+       if (ret)
+               return ret;
+
+       raw64 *= vref;
+       do_div(raw64, data_mask);
+       *uV = raw64;
+
+       return 0;
+}
+
 static int adc_vdd_platdata_set(struct udevice *dev)
 {
        struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev);
@@ -351,7 +375,12 @@ static int adc_vdd_platdata_set(struct udevice *dev)
        prop = "vdd-polarity-negative";
        uc_pdata->vdd_polarity_negative = dev_read_bool(dev, prop);
 
-       ret = adc_vdd_platdata_update(dev);
+       /* Optionally get regulators */
+       ret = device_get_supply_regulator(dev, "vdd-supply",
+                                         &uc_pdata->vdd_supply);
+       if (!ret)
+               return adc_vdd_platdata_update(dev);
+
        if (ret != -ENOENT)
                return ret;
 
@@ -371,7 +400,11 @@ static int adc_vss_platdata_set(struct udevice *dev)
        prop = "vss-polarity-negative";
        uc_pdata->vss_polarity_negative = dev_read_bool(dev, prop);
 
-       ret = adc_vss_platdata_update(dev);
+       ret = device_get_supply_regulator(dev, "vss-supply",
+                                         &uc_pdata->vss_supply);
+       if (!ret)
+               return adc_vss_platdata_update(dev);
+
        if (ret != -ENOENT)
                return ret;
 
@@ -389,12 +422,12 @@ static int adc_pre_probe(struct udevice *dev)
        /* Set ADC VDD platdata: polarity, uV, regulator (phandle). */
        ret = adc_vdd_platdata_set(dev);
        if (ret)
-               error("%s: Can't update Vdd. Error: %d", dev->name, ret);
+               pr_err("%s: Can't update Vdd. Error: %d", dev->name, ret);
 
        /* Set ADC VSS platdata: polarity, uV, regulator (phandle). */
        ret = adc_vss_platdata_set(dev);
        if (ret)
-               error("%s: Can't update Vss. Error: %d", dev->name, ret);
+               pr_err("%s: Can't update Vss. Error: %d", dev->name, ret);
 
        return 0;
 }