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 505decbf53SPrzemyslaw Marczak static int adc_supply_enable(struct udevice *dev) 515decbf53SPrzemyslaw Marczak { 525decbf53SPrzemyslaw Marczak struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev); 535decbf53SPrzemyslaw Marczak const char *supply_type; 545decbf53SPrzemyslaw Marczak int ret = 0; 555decbf53SPrzemyslaw Marczak 565decbf53SPrzemyslaw Marczak if (uc_pdata->vdd_supply) { 575decbf53SPrzemyslaw Marczak supply_type = "vdd"; 585decbf53SPrzemyslaw Marczak ret = regulator_set_enable(uc_pdata->vdd_supply, true); 595decbf53SPrzemyslaw Marczak } 605decbf53SPrzemyslaw Marczak 615decbf53SPrzemyslaw Marczak if (!ret && uc_pdata->vss_supply) { 625decbf53SPrzemyslaw Marczak supply_type = "vss"; 635decbf53SPrzemyslaw Marczak ret = regulator_set_enable(uc_pdata->vss_supply, true); 645decbf53SPrzemyslaw Marczak } 655decbf53SPrzemyslaw Marczak 665decbf53SPrzemyslaw Marczak if (ret) 675decbf53SPrzemyslaw Marczak error("%s: can't enable %s-supply!", dev->name, supply_type); 685decbf53SPrzemyslaw Marczak 695decbf53SPrzemyslaw Marczak return ret; 705decbf53SPrzemyslaw Marczak } 715decbf53SPrzemyslaw Marczak 725decbf53SPrzemyslaw Marczak int adc_data_mask(struct udevice *dev, unsigned int *data_mask) 735decbf53SPrzemyslaw Marczak { 745decbf53SPrzemyslaw Marczak struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev); 755decbf53SPrzemyslaw Marczak 765decbf53SPrzemyslaw Marczak if (!uc_pdata) 775decbf53SPrzemyslaw Marczak return -ENOSYS; 785decbf53SPrzemyslaw Marczak 795decbf53SPrzemyslaw Marczak *data_mask = uc_pdata->data_mask; 805decbf53SPrzemyslaw Marczak return 0; 815decbf53SPrzemyslaw Marczak } 825decbf53SPrzemyslaw Marczak 835decbf53SPrzemyslaw Marczak int adc_stop(struct udevice *dev) 845decbf53SPrzemyslaw Marczak { 855decbf53SPrzemyslaw Marczak const struct adc_ops *ops = dev_get_driver_ops(dev); 865decbf53SPrzemyslaw Marczak 875decbf53SPrzemyslaw Marczak if (!ops->stop) 885decbf53SPrzemyslaw Marczak return -ENOSYS; 895decbf53SPrzemyslaw Marczak 905decbf53SPrzemyslaw Marczak return ops->stop(dev); 915decbf53SPrzemyslaw Marczak } 925decbf53SPrzemyslaw Marczak 935decbf53SPrzemyslaw Marczak int adc_start_channel(struct udevice *dev, int channel) 945decbf53SPrzemyslaw Marczak { 955decbf53SPrzemyslaw Marczak const struct adc_ops *ops = dev_get_driver_ops(dev); 965decbf53SPrzemyslaw Marczak int ret; 975decbf53SPrzemyslaw Marczak 985decbf53SPrzemyslaw Marczak if (!ops->start_channel) 995decbf53SPrzemyslaw Marczak return -ENOSYS; 1005decbf53SPrzemyslaw Marczak 1015decbf53SPrzemyslaw Marczak ret = check_channel(dev, channel, CHECK_NUMBER, __func__); 1025decbf53SPrzemyslaw Marczak if (ret) 1035decbf53SPrzemyslaw Marczak return ret; 1045decbf53SPrzemyslaw Marczak 1055decbf53SPrzemyslaw Marczak ret = adc_supply_enable(dev); 1065decbf53SPrzemyslaw Marczak if (ret) 1075decbf53SPrzemyslaw Marczak return ret; 1085decbf53SPrzemyslaw Marczak 1095decbf53SPrzemyslaw Marczak return ops->start_channel(dev, channel); 1105decbf53SPrzemyslaw Marczak } 1115decbf53SPrzemyslaw Marczak 1125decbf53SPrzemyslaw Marczak int adc_start_channels(struct udevice *dev, unsigned int channel_mask) 1135decbf53SPrzemyslaw Marczak { 1145decbf53SPrzemyslaw Marczak const struct adc_ops *ops = dev_get_driver_ops(dev); 1155decbf53SPrzemyslaw Marczak int ret; 1165decbf53SPrzemyslaw Marczak 1175decbf53SPrzemyslaw Marczak if (!ops->start_channels) 1185decbf53SPrzemyslaw Marczak return -ENOSYS; 1195decbf53SPrzemyslaw Marczak 1205decbf53SPrzemyslaw Marczak ret = check_channel(dev, channel_mask, CHECK_MASK, __func__); 1215decbf53SPrzemyslaw Marczak if (ret) 1225decbf53SPrzemyslaw Marczak return ret; 1235decbf53SPrzemyslaw Marczak 1245decbf53SPrzemyslaw Marczak ret = adc_supply_enable(dev); 1255decbf53SPrzemyslaw Marczak if (ret) 1265decbf53SPrzemyslaw Marczak return ret; 1275decbf53SPrzemyslaw Marczak 1285decbf53SPrzemyslaw Marczak return ops->start_channels(dev, channel_mask); 1295decbf53SPrzemyslaw Marczak } 1305decbf53SPrzemyslaw Marczak 1315decbf53SPrzemyslaw Marczak int adc_channel_data(struct udevice *dev, int channel, unsigned int *data) 1325decbf53SPrzemyslaw Marczak { 1335decbf53SPrzemyslaw Marczak struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev); 1345decbf53SPrzemyslaw Marczak const struct adc_ops *ops = dev_get_driver_ops(dev); 1355decbf53SPrzemyslaw Marczak unsigned int timeout_us = uc_pdata->data_timeout_us; 1365decbf53SPrzemyslaw Marczak int ret; 1375decbf53SPrzemyslaw Marczak 1385decbf53SPrzemyslaw Marczak if (!ops->channel_data) 1395decbf53SPrzemyslaw Marczak return -ENOSYS; 1405decbf53SPrzemyslaw Marczak 1415decbf53SPrzemyslaw Marczak ret = check_channel(dev, channel, CHECK_NUMBER, __func__); 1425decbf53SPrzemyslaw Marczak if (ret) 1435decbf53SPrzemyslaw Marczak return ret; 1445decbf53SPrzemyslaw Marczak 1455decbf53SPrzemyslaw Marczak do { 1465decbf53SPrzemyslaw Marczak ret = ops->channel_data(dev, channel, data); 1475decbf53SPrzemyslaw Marczak if (!ret || ret != -EBUSY) 1485decbf53SPrzemyslaw Marczak break; 1495decbf53SPrzemyslaw Marczak 1505decbf53SPrzemyslaw Marczak /* TODO: use timer uclass (for early calls). */ 1515decbf53SPrzemyslaw Marczak sdelay(5); 1525decbf53SPrzemyslaw Marczak } while (timeout_us--); 1535decbf53SPrzemyslaw Marczak 1545decbf53SPrzemyslaw Marczak return ret; 1555decbf53SPrzemyslaw Marczak } 1565decbf53SPrzemyslaw Marczak 1575decbf53SPrzemyslaw Marczak int adc_channels_data(struct udevice *dev, unsigned int channel_mask, 1585decbf53SPrzemyslaw Marczak struct adc_channel *channels) 1595decbf53SPrzemyslaw Marczak { 1605decbf53SPrzemyslaw Marczak struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev); 1615decbf53SPrzemyslaw Marczak unsigned int timeout_us = uc_pdata->multidata_timeout_us; 1625decbf53SPrzemyslaw Marczak const struct adc_ops *ops = dev_get_driver_ops(dev); 1635decbf53SPrzemyslaw Marczak int ret; 1645decbf53SPrzemyslaw Marczak 1655decbf53SPrzemyslaw Marczak if (!ops->channels_data) 1665decbf53SPrzemyslaw Marczak return -ENOSYS; 1675decbf53SPrzemyslaw Marczak 1685decbf53SPrzemyslaw Marczak ret = check_channel(dev, channel_mask, CHECK_MASK, __func__); 1695decbf53SPrzemyslaw Marczak if (ret) 1705decbf53SPrzemyslaw Marczak return ret; 1715decbf53SPrzemyslaw Marczak 1725decbf53SPrzemyslaw Marczak do { 1735decbf53SPrzemyslaw Marczak ret = ops->channels_data(dev, channel_mask, channels); 1745decbf53SPrzemyslaw Marczak if (!ret || ret != -EBUSY) 1755decbf53SPrzemyslaw Marczak break; 1765decbf53SPrzemyslaw Marczak 1775decbf53SPrzemyslaw Marczak /* TODO: use timer uclass (for early calls). */ 1785decbf53SPrzemyslaw Marczak sdelay(5); 1795decbf53SPrzemyslaw Marczak } while (timeout_us--); 1805decbf53SPrzemyslaw Marczak 1815decbf53SPrzemyslaw Marczak return ret; 1825decbf53SPrzemyslaw Marczak } 1835decbf53SPrzemyslaw Marczak 1845decbf53SPrzemyslaw Marczak int adc_channel_single_shot(const char *name, int channel, unsigned int *data) 1855decbf53SPrzemyslaw Marczak { 1865decbf53SPrzemyslaw Marczak struct udevice *dev; 1875decbf53SPrzemyslaw Marczak int ret; 1885decbf53SPrzemyslaw Marczak 1895decbf53SPrzemyslaw Marczak ret = uclass_get_device_by_name(UCLASS_ADC, name, &dev); 1905decbf53SPrzemyslaw Marczak if (ret) 1915decbf53SPrzemyslaw Marczak return ret; 1925decbf53SPrzemyslaw Marczak 1935decbf53SPrzemyslaw Marczak ret = adc_start_channel(dev, channel); 1945decbf53SPrzemyslaw Marczak if (ret) 1955decbf53SPrzemyslaw Marczak return ret; 1965decbf53SPrzemyslaw Marczak 1975decbf53SPrzemyslaw Marczak ret = adc_channel_data(dev, channel, data); 1985decbf53SPrzemyslaw Marczak if (ret) 1995decbf53SPrzemyslaw Marczak return ret; 2005decbf53SPrzemyslaw Marczak 2015decbf53SPrzemyslaw Marczak return 0; 2025decbf53SPrzemyslaw Marczak } 2035decbf53SPrzemyslaw Marczak 2045decbf53SPrzemyslaw Marczak static int _adc_channels_single_shot(struct udevice *dev, 2055decbf53SPrzemyslaw Marczak unsigned int channel_mask, 2065decbf53SPrzemyslaw Marczak struct adc_channel *channels) 2075decbf53SPrzemyslaw Marczak { 2085decbf53SPrzemyslaw Marczak unsigned int data; 2095decbf53SPrzemyslaw Marczak int channel, ret; 2105decbf53SPrzemyslaw Marczak 2115decbf53SPrzemyslaw Marczak for (channel = 0; channel <= ADC_MAX_CHANNEL; channel++) { 2125decbf53SPrzemyslaw Marczak /* Check channel bit. */ 2135decbf53SPrzemyslaw Marczak if (!((channel_mask >> channel) & 0x1)) 2145decbf53SPrzemyslaw Marczak continue; 2155decbf53SPrzemyslaw Marczak 2165decbf53SPrzemyslaw Marczak ret = adc_start_channel(dev, channel); 2175decbf53SPrzemyslaw Marczak if (ret) 2185decbf53SPrzemyslaw Marczak return ret; 2195decbf53SPrzemyslaw Marczak 2205decbf53SPrzemyslaw Marczak ret = adc_channel_data(dev, channel, &data); 2215decbf53SPrzemyslaw Marczak if (ret) 2225decbf53SPrzemyslaw Marczak return ret; 2235decbf53SPrzemyslaw Marczak 2245decbf53SPrzemyslaw Marczak channels->id = channel; 2255decbf53SPrzemyslaw Marczak channels->data = data; 2265decbf53SPrzemyslaw Marczak channels++; 2275decbf53SPrzemyslaw Marczak } 2285decbf53SPrzemyslaw Marczak 2295decbf53SPrzemyslaw Marczak return 0; 2305decbf53SPrzemyslaw Marczak } 2315decbf53SPrzemyslaw Marczak 2325decbf53SPrzemyslaw Marczak int adc_channels_single_shot(const char *name, unsigned int channel_mask, 2335decbf53SPrzemyslaw Marczak struct adc_channel *channels) 2345decbf53SPrzemyslaw Marczak { 2355decbf53SPrzemyslaw Marczak struct udevice *dev; 2365decbf53SPrzemyslaw Marczak int ret; 2375decbf53SPrzemyslaw Marczak 2385decbf53SPrzemyslaw Marczak ret = uclass_get_device_by_name(UCLASS_ADC, name, &dev); 2395decbf53SPrzemyslaw Marczak if (ret) 2405decbf53SPrzemyslaw Marczak return ret; 2415decbf53SPrzemyslaw Marczak 2425decbf53SPrzemyslaw Marczak ret = adc_start_channels(dev, channel_mask); 2435decbf53SPrzemyslaw Marczak if (ret) 2445decbf53SPrzemyslaw Marczak goto try_manual; 2455decbf53SPrzemyslaw Marczak 2465decbf53SPrzemyslaw Marczak ret = adc_channels_data(dev, channel_mask, channels); 2475decbf53SPrzemyslaw Marczak if (ret) 2485decbf53SPrzemyslaw Marczak return ret; 2495decbf53SPrzemyslaw Marczak 2505decbf53SPrzemyslaw Marczak return 0; 2515decbf53SPrzemyslaw Marczak 2525decbf53SPrzemyslaw Marczak try_manual: 2535decbf53SPrzemyslaw Marczak if (ret != -ENOSYS) 2545decbf53SPrzemyslaw Marczak return ret; 2555decbf53SPrzemyslaw Marczak 2565decbf53SPrzemyslaw Marczak return _adc_channels_single_shot(dev, channel_mask, channels); 2575decbf53SPrzemyslaw Marczak } 2585decbf53SPrzemyslaw Marczak 2595decbf53SPrzemyslaw Marczak static int adc_vdd_platdata_update(struct udevice *dev) 2605decbf53SPrzemyslaw Marczak { 2615decbf53SPrzemyslaw Marczak struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev); 2625decbf53SPrzemyslaw Marczak int ret; 2635decbf53SPrzemyslaw Marczak 2645decbf53SPrzemyslaw Marczak /* Warning! 2655decbf53SPrzemyslaw Marczak * This function can't return supply device before its bind. 2665decbf53SPrzemyslaw Marczak * Please pay attention to proper fdt scan sequence. If ADC device 2675decbf53SPrzemyslaw Marczak * will bind before its supply regulator device, then the below 'get' 2685decbf53SPrzemyslaw Marczak * will return an error. 2695decbf53SPrzemyslaw Marczak */ 2705decbf53SPrzemyslaw Marczak ret = device_get_supply_regulator(dev, "vdd-supply", 2715decbf53SPrzemyslaw Marczak &uc_pdata->vdd_supply); 2725decbf53SPrzemyslaw Marczak if (ret) 2735decbf53SPrzemyslaw Marczak return ret; 2745decbf53SPrzemyslaw Marczak 2755decbf53SPrzemyslaw Marczak ret = regulator_get_value(uc_pdata->vdd_supply); 2765decbf53SPrzemyslaw Marczak if (ret < 0) 2775decbf53SPrzemyslaw Marczak return ret; 2785decbf53SPrzemyslaw Marczak 2795decbf53SPrzemyslaw Marczak uc_pdata->vdd_microvolts = ret; 2805decbf53SPrzemyslaw Marczak 2815decbf53SPrzemyslaw Marczak return 0; 2825decbf53SPrzemyslaw Marczak } 2835decbf53SPrzemyslaw Marczak 2845decbf53SPrzemyslaw Marczak static int adc_vss_platdata_update(struct udevice *dev) 2855decbf53SPrzemyslaw Marczak { 2865decbf53SPrzemyslaw Marczak struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev); 2875decbf53SPrzemyslaw Marczak int ret; 2885decbf53SPrzemyslaw Marczak 2895decbf53SPrzemyslaw Marczak ret = device_get_supply_regulator(dev, "vss-supply", 2905decbf53SPrzemyslaw Marczak &uc_pdata->vss_supply); 2915decbf53SPrzemyslaw Marczak if (ret) 2925decbf53SPrzemyslaw Marczak return ret; 2935decbf53SPrzemyslaw Marczak 2945decbf53SPrzemyslaw Marczak ret = regulator_get_value(uc_pdata->vss_supply); 2955decbf53SPrzemyslaw Marczak if (ret < 0) 2965decbf53SPrzemyslaw Marczak return ret; 2975decbf53SPrzemyslaw Marczak 2985decbf53SPrzemyslaw Marczak uc_pdata->vss_microvolts = ret; 2995decbf53SPrzemyslaw Marczak 3005decbf53SPrzemyslaw Marczak return 0; 3015decbf53SPrzemyslaw Marczak } 3025decbf53SPrzemyslaw Marczak 3035decbf53SPrzemyslaw Marczak int adc_vdd_value(struct udevice *dev, int *uV) 3045decbf53SPrzemyslaw Marczak { 3055decbf53SPrzemyslaw Marczak struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev); 3065decbf53SPrzemyslaw Marczak int ret, value_sign = uc_pdata->vdd_polarity_negative ? -1 : 1; 3075decbf53SPrzemyslaw Marczak 3085decbf53SPrzemyslaw Marczak if (!uc_pdata->vdd_supply) 3095decbf53SPrzemyslaw Marczak goto nodev; 3105decbf53SPrzemyslaw Marczak 3115decbf53SPrzemyslaw Marczak /* Update the regulator Value. */ 3125decbf53SPrzemyslaw Marczak ret = adc_vdd_platdata_update(dev); 3135decbf53SPrzemyslaw Marczak if (ret) 3145decbf53SPrzemyslaw Marczak return ret; 3155decbf53SPrzemyslaw Marczak nodev: 3165decbf53SPrzemyslaw Marczak if (uc_pdata->vdd_microvolts == -ENODATA) 3175decbf53SPrzemyslaw Marczak return -ENODATA; 3185decbf53SPrzemyslaw Marczak 3195decbf53SPrzemyslaw Marczak *uV = uc_pdata->vdd_microvolts * value_sign; 3205decbf53SPrzemyslaw Marczak 3215decbf53SPrzemyslaw Marczak return 0; 3225decbf53SPrzemyslaw Marczak } 3235decbf53SPrzemyslaw Marczak 3245decbf53SPrzemyslaw Marczak int adc_vss_value(struct udevice *dev, int *uV) 3255decbf53SPrzemyslaw Marczak { 3265decbf53SPrzemyslaw Marczak struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev); 3275decbf53SPrzemyslaw Marczak int ret, value_sign = uc_pdata->vss_polarity_negative ? -1 : 1; 3285decbf53SPrzemyslaw Marczak 3295decbf53SPrzemyslaw Marczak if (!uc_pdata->vss_supply) 3305decbf53SPrzemyslaw Marczak goto nodev; 3315decbf53SPrzemyslaw Marczak 3325decbf53SPrzemyslaw Marczak /* Update the regulator Value. */ 3335decbf53SPrzemyslaw Marczak ret = adc_vss_platdata_update(dev); 3345decbf53SPrzemyslaw Marczak if (ret) 3355decbf53SPrzemyslaw Marczak return ret; 3365decbf53SPrzemyslaw Marczak nodev: 3375decbf53SPrzemyslaw Marczak if (uc_pdata->vss_microvolts == -ENODATA) 3385decbf53SPrzemyslaw Marczak return -ENODATA; 3395decbf53SPrzemyslaw Marczak 3405decbf53SPrzemyslaw Marczak *uV = uc_pdata->vss_microvolts * value_sign; 3415decbf53SPrzemyslaw Marczak 3425decbf53SPrzemyslaw Marczak return 0; 3435decbf53SPrzemyslaw Marczak } 3445decbf53SPrzemyslaw Marczak 3455decbf53SPrzemyslaw Marczak static int adc_vdd_platdata_set(struct udevice *dev) 3465decbf53SPrzemyslaw Marczak { 3475decbf53SPrzemyslaw Marczak struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev); 348*53d788d8SSimon Glass int ret; 3495decbf53SPrzemyslaw Marczak char *prop; 3505decbf53SPrzemyslaw Marczak 3515decbf53SPrzemyslaw Marczak prop = "vdd-polarity-negative"; 352*53d788d8SSimon Glass uc_pdata->vdd_polarity_negative = dev_read_bool(dev, prop); 3535decbf53SPrzemyslaw Marczak 3545decbf53SPrzemyslaw Marczak ret = adc_vdd_platdata_update(dev); 3555decbf53SPrzemyslaw Marczak if (ret != -ENOENT) 3565decbf53SPrzemyslaw Marczak return ret; 3575decbf53SPrzemyslaw Marczak 3585decbf53SPrzemyslaw Marczak /* No vdd-supply phandle. */ 3595decbf53SPrzemyslaw Marczak prop = "vdd-microvolts"; 360*53d788d8SSimon Glass uc_pdata->vdd_microvolts = dev_read_u32_default(dev, prop, -ENODATA); 3615decbf53SPrzemyslaw Marczak 3625decbf53SPrzemyslaw Marczak return 0; 3635decbf53SPrzemyslaw Marczak } 3645decbf53SPrzemyslaw Marczak 3655decbf53SPrzemyslaw Marczak static int adc_vss_platdata_set(struct udevice *dev) 3665decbf53SPrzemyslaw Marczak { 3675decbf53SPrzemyslaw Marczak struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev); 368*53d788d8SSimon Glass int ret; 3695decbf53SPrzemyslaw Marczak char *prop; 3705decbf53SPrzemyslaw Marczak 3715decbf53SPrzemyslaw Marczak prop = "vss-polarity-negative"; 372*53d788d8SSimon Glass uc_pdata->vss_polarity_negative = dev_read_bool(dev, prop); 3735decbf53SPrzemyslaw Marczak 3745decbf53SPrzemyslaw Marczak ret = adc_vss_platdata_update(dev); 3755decbf53SPrzemyslaw Marczak if (ret != -ENOENT) 3765decbf53SPrzemyslaw Marczak return ret; 3775decbf53SPrzemyslaw Marczak 3785decbf53SPrzemyslaw Marczak /* No vss-supply phandle. */ 3795decbf53SPrzemyslaw Marczak prop = "vss-microvolts"; 380*53d788d8SSimon Glass uc_pdata->vss_microvolts = dev_read_u32_default(dev, prop, -ENODATA); 3815decbf53SPrzemyslaw Marczak 3825decbf53SPrzemyslaw Marczak return 0; 3835decbf53SPrzemyslaw Marczak } 3845decbf53SPrzemyslaw Marczak 3855decbf53SPrzemyslaw Marczak static int adc_pre_probe(struct udevice *dev) 3865decbf53SPrzemyslaw Marczak { 3875decbf53SPrzemyslaw Marczak int ret; 3885decbf53SPrzemyslaw Marczak 3895decbf53SPrzemyslaw Marczak /* Set ADC VDD platdata: polarity, uV, regulator (phandle). */ 3905decbf53SPrzemyslaw Marczak ret = adc_vdd_platdata_set(dev); 3915decbf53SPrzemyslaw Marczak if (ret) 3925decbf53SPrzemyslaw Marczak error("%s: Can't update Vdd. Error: %d", dev->name, ret); 3935decbf53SPrzemyslaw Marczak 3945decbf53SPrzemyslaw Marczak /* Set ADC VSS platdata: polarity, uV, regulator (phandle). */ 3955decbf53SPrzemyslaw Marczak ret = adc_vss_platdata_set(dev); 3965decbf53SPrzemyslaw Marczak if (ret) 3975decbf53SPrzemyslaw Marczak error("%s: Can't update Vss. Error: %d", dev->name, ret); 3985decbf53SPrzemyslaw Marczak 3995decbf53SPrzemyslaw Marczak return 0; 4005decbf53SPrzemyslaw Marczak } 4015decbf53SPrzemyslaw Marczak 4025decbf53SPrzemyslaw Marczak UCLASS_DRIVER(adc) = { 4035decbf53SPrzemyslaw Marczak .id = UCLASS_ADC, 4045decbf53SPrzemyslaw Marczak .name = "adc", 4055decbf53SPrzemyslaw Marczak .pre_probe = adc_pre_probe, 4065decbf53SPrzemyslaw Marczak .per_device_platdata_auto_alloc_size = ADC_UCLASS_PLATDATA_SIZE, 4075decbf53SPrzemyslaw Marczak }; 408