15decbf53SPrzemyslaw Marczak /* 25decbf53SPrzemyslaw Marczak * Copyright (C) 2015 Samsung Electronics 35decbf53SPrzemyslaw Marczak * Przemyslaw Marczak <p.marczak@samsung.com> 45decbf53SPrzemyslaw Marczak * 55decbf53SPrzemyslaw Marczak * SPDX-License-Identifier: GPL-2.0+ 65decbf53SPrzemyslaw Marczak */ 75decbf53SPrzemyslaw Marczak 85decbf53SPrzemyslaw Marczak #include <common.h> 95decbf53SPrzemyslaw Marczak #include <errno.h> 105decbf53SPrzemyslaw Marczak #include <dm.h> 115decbf53SPrzemyslaw Marczak #include <dm/lists.h> 125decbf53SPrzemyslaw Marczak #include <dm/device-internal.h> 135decbf53SPrzemyslaw Marczak #include <dm/uclass-internal.h> 145decbf53SPrzemyslaw Marczak #include <adc.h> 155decbf53SPrzemyslaw Marczak #include <power/regulator.h> 165decbf53SPrzemyslaw Marczak 175decbf53SPrzemyslaw Marczak DECLARE_GLOBAL_DATA_PTR; 185decbf53SPrzemyslaw Marczak 195decbf53SPrzemyslaw Marczak #define ADC_UCLASS_PLATDATA_SIZE sizeof(struct adc_uclass_platdata) 205decbf53SPrzemyslaw Marczak #define CHECK_NUMBER true 215decbf53SPrzemyslaw Marczak #define CHECK_MASK (!CHECK_NUMBER) 225decbf53SPrzemyslaw Marczak 235decbf53SPrzemyslaw Marczak /* TODO: add support for timer uclass (for early calls) */ 245decbf53SPrzemyslaw Marczak #ifdef CONFIG_SANDBOX_ARCH 255decbf53SPrzemyslaw Marczak #define sdelay(x) udelay(x) 265decbf53SPrzemyslaw Marczak #else 275decbf53SPrzemyslaw Marczak extern void sdelay(unsigned long loops); 285decbf53SPrzemyslaw Marczak #endif 295decbf53SPrzemyslaw Marczak 305decbf53SPrzemyslaw Marczak static int check_channel(struct udevice *dev, int value, bool number_or_mask, 315decbf53SPrzemyslaw Marczak const char *caller_function) 325decbf53SPrzemyslaw Marczak { 335decbf53SPrzemyslaw Marczak struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev); 345decbf53SPrzemyslaw Marczak unsigned mask = number_or_mask ? (1 << value) : value; 355decbf53SPrzemyslaw Marczak 365decbf53SPrzemyslaw Marczak /* For the real ADC hardware, some ADC channels can be inactive. 375decbf53SPrzemyslaw Marczak * For example if device has 4 analog channels, and only channels 385decbf53SPrzemyslaw Marczak * 1-st and 3-rd are valid, then channel mask is: 0b1010, so request 395decbf53SPrzemyslaw Marczak * with mask 0b1110 should return an error. 405decbf53SPrzemyslaw Marczak */ 415decbf53SPrzemyslaw Marczak if ((uc_pdata->channel_mask >= mask) && (uc_pdata->channel_mask & mask)) 425decbf53SPrzemyslaw Marczak return 0; 435decbf53SPrzemyslaw Marczak 445decbf53SPrzemyslaw Marczak printf("Error in %s/%s().\nWrong channel selection for device: %s\n", 455decbf53SPrzemyslaw Marczak __FILE__, caller_function, dev->name); 465decbf53SPrzemyslaw Marczak 475decbf53SPrzemyslaw Marczak return -EINVAL; 485decbf53SPrzemyslaw Marczak } 495decbf53SPrzemyslaw Marczak 50*35ef9ac3SJoseph Chen #ifdef CONFIG_ADC_REQ_REGULATOR 515decbf53SPrzemyslaw Marczak static int adc_supply_enable(struct udevice *dev) 525decbf53SPrzemyslaw Marczak { 535decbf53SPrzemyslaw Marczak struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev); 545decbf53SPrzemyslaw Marczak const char *supply_type; 555decbf53SPrzemyslaw Marczak int ret = 0; 565decbf53SPrzemyslaw Marczak 575decbf53SPrzemyslaw Marczak if (uc_pdata->vdd_supply) { 585decbf53SPrzemyslaw Marczak supply_type = "vdd"; 595decbf53SPrzemyslaw Marczak ret = regulator_set_enable(uc_pdata->vdd_supply, true); 605decbf53SPrzemyslaw Marczak } 615decbf53SPrzemyslaw Marczak 625decbf53SPrzemyslaw Marczak if (!ret && uc_pdata->vss_supply) { 635decbf53SPrzemyslaw Marczak supply_type = "vss"; 645decbf53SPrzemyslaw Marczak ret = regulator_set_enable(uc_pdata->vss_supply, true); 655decbf53SPrzemyslaw Marczak } 665decbf53SPrzemyslaw Marczak 675decbf53SPrzemyslaw Marczak if (ret) 6890aa625cSMasahiro Yamada pr_err("%s: can't enable %s-supply!", dev->name, supply_type); 695decbf53SPrzemyslaw Marczak 705decbf53SPrzemyslaw Marczak return ret; 715decbf53SPrzemyslaw Marczak } 72*35ef9ac3SJoseph Chen #else 73*35ef9ac3SJoseph Chen static inline int adc_supply_enable(struct udevice *dev) { return 0; } 74*35ef9ac3SJoseph Chen #endif 755decbf53SPrzemyslaw Marczak 765decbf53SPrzemyslaw Marczak int adc_data_mask(struct udevice *dev, unsigned int *data_mask) 775decbf53SPrzemyslaw Marczak { 785decbf53SPrzemyslaw Marczak struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev); 795decbf53SPrzemyslaw Marczak 805decbf53SPrzemyslaw Marczak if (!uc_pdata) 815decbf53SPrzemyslaw Marczak return -ENOSYS; 825decbf53SPrzemyslaw Marczak 835decbf53SPrzemyslaw Marczak *data_mask = uc_pdata->data_mask; 845decbf53SPrzemyslaw Marczak return 0; 855decbf53SPrzemyslaw Marczak } 865decbf53SPrzemyslaw Marczak 875decbf53SPrzemyslaw Marczak int adc_stop(struct udevice *dev) 885decbf53SPrzemyslaw Marczak { 895decbf53SPrzemyslaw Marczak const struct adc_ops *ops = dev_get_driver_ops(dev); 905decbf53SPrzemyslaw Marczak 915decbf53SPrzemyslaw Marczak if (!ops->stop) 925decbf53SPrzemyslaw Marczak return -ENOSYS; 935decbf53SPrzemyslaw Marczak 945decbf53SPrzemyslaw Marczak return ops->stop(dev); 955decbf53SPrzemyslaw Marczak } 965decbf53SPrzemyslaw Marczak 975decbf53SPrzemyslaw Marczak int adc_start_channel(struct udevice *dev, int channel) 985decbf53SPrzemyslaw Marczak { 995decbf53SPrzemyslaw Marczak const struct adc_ops *ops = dev_get_driver_ops(dev); 1005decbf53SPrzemyslaw Marczak int ret; 1015decbf53SPrzemyslaw Marczak 1025decbf53SPrzemyslaw Marczak if (!ops->start_channel) 1035decbf53SPrzemyslaw Marczak return -ENOSYS; 1045decbf53SPrzemyslaw Marczak 1055decbf53SPrzemyslaw Marczak ret = check_channel(dev, channel, CHECK_NUMBER, __func__); 1065decbf53SPrzemyslaw Marczak if (ret) 1075decbf53SPrzemyslaw Marczak return ret; 1085decbf53SPrzemyslaw Marczak 1095decbf53SPrzemyslaw Marczak ret = adc_supply_enable(dev); 1105decbf53SPrzemyslaw Marczak if (ret) 1115decbf53SPrzemyslaw Marczak return ret; 1125decbf53SPrzemyslaw Marczak 1135decbf53SPrzemyslaw Marczak return ops->start_channel(dev, channel); 1145decbf53SPrzemyslaw Marczak } 1155decbf53SPrzemyslaw Marczak 1165decbf53SPrzemyslaw Marczak int adc_start_channels(struct udevice *dev, unsigned int channel_mask) 1175decbf53SPrzemyslaw Marczak { 1185decbf53SPrzemyslaw Marczak const struct adc_ops *ops = dev_get_driver_ops(dev); 1195decbf53SPrzemyslaw Marczak int ret; 1205decbf53SPrzemyslaw Marczak 1215decbf53SPrzemyslaw Marczak if (!ops->start_channels) 1225decbf53SPrzemyslaw Marczak return -ENOSYS; 1235decbf53SPrzemyslaw Marczak 1245decbf53SPrzemyslaw Marczak ret = check_channel(dev, channel_mask, CHECK_MASK, __func__); 1255decbf53SPrzemyslaw Marczak if (ret) 1265decbf53SPrzemyslaw Marczak return ret; 1275decbf53SPrzemyslaw Marczak 1285decbf53SPrzemyslaw Marczak ret = adc_supply_enable(dev); 1295decbf53SPrzemyslaw Marczak if (ret) 1305decbf53SPrzemyslaw Marczak return ret; 1315decbf53SPrzemyslaw Marczak 1325decbf53SPrzemyslaw Marczak return ops->start_channels(dev, channel_mask); 1335decbf53SPrzemyslaw Marczak } 1345decbf53SPrzemyslaw Marczak 1355decbf53SPrzemyslaw Marczak int adc_channel_data(struct udevice *dev, int channel, unsigned int *data) 1365decbf53SPrzemyslaw Marczak { 1375decbf53SPrzemyslaw Marczak struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev); 1385decbf53SPrzemyslaw Marczak const struct adc_ops *ops = dev_get_driver_ops(dev); 1395decbf53SPrzemyslaw Marczak unsigned int timeout_us = uc_pdata->data_timeout_us; 1405decbf53SPrzemyslaw Marczak int ret; 1415decbf53SPrzemyslaw Marczak 1425decbf53SPrzemyslaw Marczak if (!ops->channel_data) 1435decbf53SPrzemyslaw Marczak return -ENOSYS; 1445decbf53SPrzemyslaw Marczak 1455decbf53SPrzemyslaw Marczak ret = check_channel(dev, channel, CHECK_NUMBER, __func__); 1465decbf53SPrzemyslaw Marczak if (ret) 1475decbf53SPrzemyslaw Marczak return ret; 1485decbf53SPrzemyslaw Marczak 1495decbf53SPrzemyslaw Marczak do { 1505decbf53SPrzemyslaw Marczak ret = ops->channel_data(dev, channel, data); 1515decbf53SPrzemyslaw Marczak if (!ret || ret != -EBUSY) 1525decbf53SPrzemyslaw Marczak break; 1535decbf53SPrzemyslaw Marczak 1545decbf53SPrzemyslaw Marczak /* TODO: use timer uclass (for early calls). */ 1555decbf53SPrzemyslaw Marczak sdelay(5); 1565decbf53SPrzemyslaw Marczak } while (timeout_us--); 1575decbf53SPrzemyslaw Marczak 1585decbf53SPrzemyslaw Marczak return ret; 1595decbf53SPrzemyslaw Marczak } 1605decbf53SPrzemyslaw Marczak 1615decbf53SPrzemyslaw Marczak int adc_channels_data(struct udevice *dev, unsigned int channel_mask, 1625decbf53SPrzemyslaw Marczak struct adc_channel *channels) 1635decbf53SPrzemyslaw Marczak { 1645decbf53SPrzemyslaw Marczak struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev); 1655decbf53SPrzemyslaw Marczak unsigned int timeout_us = uc_pdata->multidata_timeout_us; 1665decbf53SPrzemyslaw Marczak const struct adc_ops *ops = dev_get_driver_ops(dev); 1675decbf53SPrzemyslaw Marczak int ret; 1685decbf53SPrzemyslaw Marczak 1695decbf53SPrzemyslaw Marczak if (!ops->channels_data) 1705decbf53SPrzemyslaw Marczak return -ENOSYS; 1715decbf53SPrzemyslaw Marczak 1725decbf53SPrzemyslaw Marczak ret = check_channel(dev, channel_mask, CHECK_MASK, __func__); 1735decbf53SPrzemyslaw Marczak if (ret) 1745decbf53SPrzemyslaw Marczak return ret; 1755decbf53SPrzemyslaw Marczak 1765decbf53SPrzemyslaw Marczak do { 1775decbf53SPrzemyslaw Marczak ret = ops->channels_data(dev, channel_mask, channels); 1785decbf53SPrzemyslaw Marczak if (!ret || ret != -EBUSY) 1795decbf53SPrzemyslaw Marczak break; 1805decbf53SPrzemyslaw Marczak 1815decbf53SPrzemyslaw Marczak /* TODO: use timer uclass (for early calls). */ 1825decbf53SPrzemyslaw Marczak sdelay(5); 1835decbf53SPrzemyslaw Marczak } while (timeout_us--); 1845decbf53SPrzemyslaw Marczak 1855decbf53SPrzemyslaw Marczak return ret; 1865decbf53SPrzemyslaw Marczak } 1875decbf53SPrzemyslaw Marczak 1885decbf53SPrzemyslaw Marczak int adc_channel_single_shot(const char *name, int channel, unsigned int *data) 1895decbf53SPrzemyslaw Marczak { 1905decbf53SPrzemyslaw Marczak struct udevice *dev; 1915decbf53SPrzemyslaw Marczak int ret; 1925decbf53SPrzemyslaw Marczak 1935decbf53SPrzemyslaw Marczak ret = uclass_get_device_by_name(UCLASS_ADC, name, &dev); 1945decbf53SPrzemyslaw Marczak if (ret) 1955decbf53SPrzemyslaw Marczak return ret; 1965decbf53SPrzemyslaw Marczak 1975decbf53SPrzemyslaw Marczak ret = adc_start_channel(dev, channel); 1985decbf53SPrzemyslaw Marczak if (ret) 1995decbf53SPrzemyslaw Marczak return ret; 2005decbf53SPrzemyslaw Marczak 2015decbf53SPrzemyslaw Marczak ret = adc_channel_data(dev, channel, data); 2025decbf53SPrzemyslaw Marczak if (ret) 2035decbf53SPrzemyslaw Marczak return ret; 2045decbf53SPrzemyslaw Marczak 2055decbf53SPrzemyslaw Marczak return 0; 2065decbf53SPrzemyslaw Marczak } 2075decbf53SPrzemyslaw Marczak 2085decbf53SPrzemyslaw Marczak static int _adc_channels_single_shot(struct udevice *dev, 2095decbf53SPrzemyslaw Marczak unsigned int channel_mask, 2105decbf53SPrzemyslaw Marczak struct adc_channel *channels) 2115decbf53SPrzemyslaw Marczak { 2125decbf53SPrzemyslaw Marczak unsigned int data; 2135decbf53SPrzemyslaw Marczak int channel, ret; 2145decbf53SPrzemyslaw Marczak 2155decbf53SPrzemyslaw Marczak for (channel = 0; channel <= ADC_MAX_CHANNEL; channel++) { 2165decbf53SPrzemyslaw Marczak /* Check channel bit. */ 2175decbf53SPrzemyslaw Marczak if (!((channel_mask >> channel) & 0x1)) 2185decbf53SPrzemyslaw Marczak continue; 2195decbf53SPrzemyslaw Marczak 2205decbf53SPrzemyslaw Marczak ret = adc_start_channel(dev, channel); 2215decbf53SPrzemyslaw Marczak if (ret) 2225decbf53SPrzemyslaw Marczak return ret; 2235decbf53SPrzemyslaw Marczak 2245decbf53SPrzemyslaw Marczak ret = adc_channel_data(dev, channel, &data); 2255decbf53SPrzemyslaw Marczak if (ret) 2265decbf53SPrzemyslaw Marczak return ret; 2275decbf53SPrzemyslaw Marczak 2285decbf53SPrzemyslaw Marczak channels->id = channel; 2295decbf53SPrzemyslaw Marczak channels->data = data; 2305decbf53SPrzemyslaw Marczak channels++; 2315decbf53SPrzemyslaw Marczak } 2325decbf53SPrzemyslaw Marczak 2335decbf53SPrzemyslaw Marczak return 0; 2345decbf53SPrzemyslaw Marczak } 2355decbf53SPrzemyslaw Marczak 2365decbf53SPrzemyslaw Marczak int adc_channels_single_shot(const char *name, unsigned int channel_mask, 2375decbf53SPrzemyslaw Marczak struct adc_channel *channels) 2385decbf53SPrzemyslaw Marczak { 2395decbf53SPrzemyslaw Marczak struct udevice *dev; 2405decbf53SPrzemyslaw Marczak int ret; 2415decbf53SPrzemyslaw Marczak 2425decbf53SPrzemyslaw Marczak ret = uclass_get_device_by_name(UCLASS_ADC, name, &dev); 2435decbf53SPrzemyslaw Marczak if (ret) 2445decbf53SPrzemyslaw Marczak return ret; 2455decbf53SPrzemyslaw Marczak 2465decbf53SPrzemyslaw Marczak ret = adc_start_channels(dev, channel_mask); 2475decbf53SPrzemyslaw Marczak if (ret) 2485decbf53SPrzemyslaw Marczak goto try_manual; 2495decbf53SPrzemyslaw Marczak 2505decbf53SPrzemyslaw Marczak ret = adc_channels_data(dev, channel_mask, channels); 2515decbf53SPrzemyslaw Marczak if (ret) 2525decbf53SPrzemyslaw Marczak return ret; 2535decbf53SPrzemyslaw Marczak 2545decbf53SPrzemyslaw Marczak return 0; 2555decbf53SPrzemyslaw Marczak 2565decbf53SPrzemyslaw Marczak try_manual: 2575decbf53SPrzemyslaw Marczak if (ret != -ENOSYS) 2585decbf53SPrzemyslaw Marczak return ret; 2595decbf53SPrzemyslaw Marczak 2605decbf53SPrzemyslaw Marczak return _adc_channels_single_shot(dev, channel_mask, channels); 2615decbf53SPrzemyslaw Marczak } 2625decbf53SPrzemyslaw Marczak 263*35ef9ac3SJoseph Chen #ifdef CONFIG_ADC_REQ_REGULATOR 2645decbf53SPrzemyslaw Marczak static int adc_vdd_platdata_update(struct udevice *dev) 2655decbf53SPrzemyslaw Marczak { 2665decbf53SPrzemyslaw Marczak struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev); 2675decbf53SPrzemyslaw Marczak int ret; 2685decbf53SPrzemyslaw Marczak 2695decbf53SPrzemyslaw Marczak /* Warning! 2705decbf53SPrzemyslaw Marczak * This function can't return supply device before its bind. 2715decbf53SPrzemyslaw Marczak * Please pay attention to proper fdt scan sequence. If ADC device 2725decbf53SPrzemyslaw Marczak * will bind before its supply regulator device, then the below 'get' 2735decbf53SPrzemyslaw Marczak * will return an error. 2745decbf53SPrzemyslaw Marczak */ 2755decbf53SPrzemyslaw Marczak ret = device_get_supply_regulator(dev, "vdd-supply", 2765decbf53SPrzemyslaw Marczak &uc_pdata->vdd_supply); 2775decbf53SPrzemyslaw Marczak if (ret) 2785decbf53SPrzemyslaw Marczak return ret; 2795decbf53SPrzemyslaw Marczak 2805decbf53SPrzemyslaw Marczak ret = regulator_get_value(uc_pdata->vdd_supply); 2815decbf53SPrzemyslaw Marczak if (ret < 0) 2825decbf53SPrzemyslaw Marczak return ret; 2835decbf53SPrzemyslaw Marczak 2845decbf53SPrzemyslaw Marczak uc_pdata->vdd_microvolts = ret; 2855decbf53SPrzemyslaw Marczak 2865decbf53SPrzemyslaw Marczak return 0; 2875decbf53SPrzemyslaw Marczak } 288*35ef9ac3SJoseph Chen #else 289*35ef9ac3SJoseph Chen static inline int adc_vdd_platdata_update(struct udevice *dev) { return 0; } 290*35ef9ac3SJoseph Chen #endif 2915decbf53SPrzemyslaw Marczak 292*35ef9ac3SJoseph Chen #ifdef CONFIG_ADC_REQ_REGULATOR 2935decbf53SPrzemyslaw Marczak static int adc_vss_platdata_update(struct udevice *dev) 2945decbf53SPrzemyslaw Marczak { 2955decbf53SPrzemyslaw Marczak struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev); 2965decbf53SPrzemyslaw Marczak int ret; 2975decbf53SPrzemyslaw Marczak 2985decbf53SPrzemyslaw Marczak ret = device_get_supply_regulator(dev, "vss-supply", 2995decbf53SPrzemyslaw Marczak &uc_pdata->vss_supply); 3005decbf53SPrzemyslaw Marczak if (ret) 3015decbf53SPrzemyslaw Marczak return ret; 3025decbf53SPrzemyslaw Marczak 3035decbf53SPrzemyslaw Marczak ret = regulator_get_value(uc_pdata->vss_supply); 3045decbf53SPrzemyslaw Marczak if (ret < 0) 3055decbf53SPrzemyslaw Marczak return ret; 3065decbf53SPrzemyslaw Marczak 3075decbf53SPrzemyslaw Marczak uc_pdata->vss_microvolts = ret; 3085decbf53SPrzemyslaw Marczak 3095decbf53SPrzemyslaw Marczak return 0; 3105decbf53SPrzemyslaw Marczak } 311*35ef9ac3SJoseph Chen #else 312*35ef9ac3SJoseph Chen static inline int adc_vss_platdata_update(struct udevice *dev) { return 0; } 313*35ef9ac3SJoseph Chen #endif 3145decbf53SPrzemyslaw Marczak 3155decbf53SPrzemyslaw Marczak int adc_vdd_value(struct udevice *dev, int *uV) 3165decbf53SPrzemyslaw Marczak { 3175decbf53SPrzemyslaw Marczak struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev); 3185decbf53SPrzemyslaw Marczak int ret, value_sign = uc_pdata->vdd_polarity_negative ? -1 : 1; 3195decbf53SPrzemyslaw Marczak 3205decbf53SPrzemyslaw Marczak if (!uc_pdata->vdd_supply) 3215decbf53SPrzemyslaw Marczak goto nodev; 3225decbf53SPrzemyslaw Marczak 3235decbf53SPrzemyslaw Marczak /* Update the regulator Value. */ 3245decbf53SPrzemyslaw Marczak ret = adc_vdd_platdata_update(dev); 3255decbf53SPrzemyslaw Marczak if (ret) 3265decbf53SPrzemyslaw Marczak return ret; 3275decbf53SPrzemyslaw Marczak nodev: 3285decbf53SPrzemyslaw Marczak if (uc_pdata->vdd_microvolts == -ENODATA) 3295decbf53SPrzemyslaw Marczak return -ENODATA; 3305decbf53SPrzemyslaw Marczak 3315decbf53SPrzemyslaw Marczak *uV = uc_pdata->vdd_microvolts * value_sign; 3325decbf53SPrzemyslaw Marczak 3335decbf53SPrzemyslaw Marczak return 0; 3345decbf53SPrzemyslaw Marczak } 3355decbf53SPrzemyslaw Marczak 3365decbf53SPrzemyslaw Marczak int adc_vss_value(struct udevice *dev, int *uV) 3375decbf53SPrzemyslaw Marczak { 3385decbf53SPrzemyslaw Marczak struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev); 3395decbf53SPrzemyslaw Marczak int ret, value_sign = uc_pdata->vss_polarity_negative ? -1 : 1; 3405decbf53SPrzemyslaw Marczak 3415decbf53SPrzemyslaw Marczak if (!uc_pdata->vss_supply) 3425decbf53SPrzemyslaw Marczak goto nodev; 3435decbf53SPrzemyslaw Marczak 3445decbf53SPrzemyslaw Marczak /* Update the regulator Value. */ 3455decbf53SPrzemyslaw Marczak ret = adc_vss_platdata_update(dev); 3465decbf53SPrzemyslaw Marczak if (ret) 3475decbf53SPrzemyslaw Marczak return ret; 3485decbf53SPrzemyslaw Marczak nodev: 3495decbf53SPrzemyslaw Marczak if (uc_pdata->vss_microvolts == -ENODATA) 3505decbf53SPrzemyslaw Marczak return -ENODATA; 3515decbf53SPrzemyslaw Marczak 3525decbf53SPrzemyslaw Marczak *uV = uc_pdata->vss_microvolts * value_sign; 3535decbf53SPrzemyslaw Marczak 3545decbf53SPrzemyslaw Marczak return 0; 3555decbf53SPrzemyslaw Marczak } 3565decbf53SPrzemyslaw Marczak 3575decbf53SPrzemyslaw Marczak static int adc_vdd_platdata_set(struct udevice *dev) 3585decbf53SPrzemyslaw Marczak { 3595decbf53SPrzemyslaw Marczak struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev); 36053d788d8SSimon Glass int ret; 3615decbf53SPrzemyslaw Marczak char *prop; 3625decbf53SPrzemyslaw Marczak 3635decbf53SPrzemyslaw Marczak prop = "vdd-polarity-negative"; 36453d788d8SSimon Glass uc_pdata->vdd_polarity_negative = dev_read_bool(dev, prop); 3655decbf53SPrzemyslaw Marczak 3665decbf53SPrzemyslaw Marczak ret = adc_vdd_platdata_update(dev); 3675decbf53SPrzemyslaw Marczak if (ret != -ENOENT) 3685decbf53SPrzemyslaw Marczak return ret; 3695decbf53SPrzemyslaw Marczak 3705decbf53SPrzemyslaw Marczak /* No vdd-supply phandle. */ 3715decbf53SPrzemyslaw Marczak prop = "vdd-microvolts"; 37253d788d8SSimon Glass uc_pdata->vdd_microvolts = dev_read_u32_default(dev, prop, -ENODATA); 3735decbf53SPrzemyslaw Marczak 3745decbf53SPrzemyslaw Marczak return 0; 3755decbf53SPrzemyslaw Marczak } 3765decbf53SPrzemyslaw Marczak 3775decbf53SPrzemyslaw Marczak static int adc_vss_platdata_set(struct udevice *dev) 3785decbf53SPrzemyslaw Marczak { 3795decbf53SPrzemyslaw Marczak struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev); 38053d788d8SSimon Glass int ret; 3815decbf53SPrzemyslaw Marczak char *prop; 3825decbf53SPrzemyslaw Marczak 3835decbf53SPrzemyslaw Marczak prop = "vss-polarity-negative"; 38453d788d8SSimon Glass uc_pdata->vss_polarity_negative = dev_read_bool(dev, prop); 3855decbf53SPrzemyslaw Marczak 3865decbf53SPrzemyslaw Marczak ret = adc_vss_platdata_update(dev); 3875decbf53SPrzemyslaw Marczak if (ret != -ENOENT) 3885decbf53SPrzemyslaw Marczak return ret; 3895decbf53SPrzemyslaw Marczak 3905decbf53SPrzemyslaw Marczak /* No vss-supply phandle. */ 3915decbf53SPrzemyslaw Marczak prop = "vss-microvolts"; 39253d788d8SSimon Glass uc_pdata->vss_microvolts = dev_read_u32_default(dev, prop, -ENODATA); 3935decbf53SPrzemyslaw Marczak 3945decbf53SPrzemyslaw Marczak return 0; 3955decbf53SPrzemyslaw Marczak } 3965decbf53SPrzemyslaw Marczak 3975decbf53SPrzemyslaw Marczak static int adc_pre_probe(struct udevice *dev) 3985decbf53SPrzemyslaw Marczak { 3995decbf53SPrzemyslaw Marczak int ret; 4005decbf53SPrzemyslaw Marczak 4015decbf53SPrzemyslaw Marczak /* Set ADC VDD platdata: polarity, uV, regulator (phandle). */ 4025decbf53SPrzemyslaw Marczak ret = adc_vdd_platdata_set(dev); 4035decbf53SPrzemyslaw Marczak if (ret) 40490aa625cSMasahiro Yamada pr_err("%s: Can't update Vdd. Error: %d", dev->name, ret); 4055decbf53SPrzemyslaw Marczak 4065decbf53SPrzemyslaw Marczak /* Set ADC VSS platdata: polarity, uV, regulator (phandle). */ 4075decbf53SPrzemyslaw Marczak ret = adc_vss_platdata_set(dev); 4085decbf53SPrzemyslaw Marczak if (ret) 40990aa625cSMasahiro Yamada pr_err("%s: Can't update Vss. Error: %d", dev->name, ret); 4105decbf53SPrzemyslaw Marczak 4115decbf53SPrzemyslaw Marczak return 0; 4125decbf53SPrzemyslaw Marczak } 4135decbf53SPrzemyslaw Marczak 4145decbf53SPrzemyslaw Marczak UCLASS_DRIVER(adc) = { 4155decbf53SPrzemyslaw Marczak .id = UCLASS_ADC, 4165decbf53SPrzemyslaw Marczak .name = "adc", 4175decbf53SPrzemyslaw Marczak .pre_probe = adc_pre_probe, 4185decbf53SPrzemyslaw Marczak .per_device_platdata_auto_alloc_size = ADC_UCLASS_PLATDATA_SIZE, 4195decbf53SPrzemyslaw Marczak }; 420