mtd: gpmi: change the BCH layout setting for large oob NAND
[oweals/u-boot.git] / drivers / adc / adc-uclass.c
index 7e9ad85c3c09912ea87820eecdee2f2dbce1ea09..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>
@@ -78,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);
@@ -265,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)
@@ -284,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)
@@ -303,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;
 
@@ -324,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;
 
@@ -340,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);
@@ -349,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;
 
@@ -369,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;