uboot/drivers/power/regulator/regulator-uclass.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (C) 2014-2015 Samsung Electronics
   4 * Przemyslaw Marczak <p.marczak@samsung.com>
   5 */
   6
   7#include <common.h>
   8#include <errno.h>
   9#include <dm.h>
  10#include <dm/uclass-internal.h>
  11#include <power/pmic.h>
  12#include <power/regulator.h>
  13
  14int regulator_mode(struct udevice *dev, struct dm_regulator_mode **modep)
  15{
  16        struct dm_regulator_uclass_platdata *uc_pdata;
  17
  18        *modep = NULL;
  19
  20        uc_pdata = dev_get_uclass_platdata(dev);
  21        if (!uc_pdata)
  22                return -ENXIO;
  23
  24        *modep = uc_pdata->mode;
  25        return uc_pdata->mode_count;
  26}
  27
  28int regulator_get_value(struct udevice *dev)
  29{
  30        const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
  31
  32        if (!ops || !ops->get_value)
  33                return -ENOSYS;
  34
  35        return ops->get_value(dev);
  36}
  37
  38static void regulator_set_value_ramp_delay(struct udevice *dev, int old_uV,
  39                                           int new_uV, unsigned int ramp_delay)
  40{
  41        int delay = DIV_ROUND_UP(abs(new_uV - old_uV), ramp_delay);
  42
  43        debug("regulator %s: delay %u us (%d uV -> %d uV)\n", dev->name, delay,
  44              old_uV, new_uV);
  45
  46        udelay(delay);
  47}
  48
  49int regulator_set_value(struct udevice *dev, int uV)
  50{
  51        const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
  52        struct dm_regulator_uclass_platdata *uc_pdata;
  53        int ret, old_uV = uV, is_enabled = 0;
  54
  55        uc_pdata = dev_get_uclass_platdata(dev);
  56        if (uc_pdata->min_uV != -ENODATA && uV < uc_pdata->min_uV)
  57                return -EINVAL;
  58        if (uc_pdata->max_uV != -ENODATA && uV > uc_pdata->max_uV)
  59                return -EINVAL;
  60
  61        if (!ops || !ops->set_value)
  62                return -ENOSYS;
  63
  64        if (uc_pdata->ramp_delay) {
  65                is_enabled = regulator_get_enable(dev);
  66                old_uV = regulator_get_value(dev);
  67        }
  68
  69        ret = ops->set_value(dev, uV);
  70
  71        if (!ret) {
  72                if (uc_pdata->ramp_delay && old_uV > 0 && is_enabled)
  73                        regulator_set_value_ramp_delay(dev, old_uV, uV,
  74                                                       uc_pdata->ramp_delay);
  75        }
  76
  77        return ret;
  78}
  79
  80int regulator_set_suspend_value(struct udevice *dev, int uV)
  81{
  82        const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
  83        struct dm_regulator_uclass_platdata *uc_pdata;
  84
  85        uc_pdata = dev_get_uclass_platdata(dev);
  86        if (uc_pdata->min_uV != -ENODATA && uV < uc_pdata->min_uV)
  87                return -EINVAL;
  88        if (uc_pdata->max_uV != -ENODATA && uV > uc_pdata->max_uV)
  89                return -EINVAL;
  90
  91        if (!ops->set_suspend_value)
  92                return -ENOSYS;
  93
  94        return ops->set_suspend_value(dev, uV);
  95}
  96
  97int regulator_get_suspend_value(struct udevice *dev)
  98{
  99        const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
 100
 101        if (!ops->get_suspend_value)
 102                return -ENOSYS;
 103
 104        return ops->get_suspend_value(dev);
 105}
 106
 107/*
 108 * To be called with at most caution as there is no check
 109 * before setting the actual voltage value.
 110 */
 111int regulator_set_value_force(struct udevice *dev, int uV)
 112{
 113        const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
 114
 115        if (!ops || !ops->set_value)
 116                return -ENOSYS;
 117
 118        return ops->set_value(dev, uV);
 119}
 120
 121int regulator_get_current(struct udevice *dev)
 122{
 123        const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
 124
 125        if (!ops || !ops->get_current)
 126                return -ENOSYS;
 127
 128        return ops->get_current(dev);
 129}
 130
 131int regulator_set_current(struct udevice *dev, int uA)
 132{
 133        const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
 134        struct dm_regulator_uclass_platdata *uc_pdata;
 135
 136        uc_pdata = dev_get_uclass_platdata(dev);
 137        if (uc_pdata->min_uA != -ENODATA && uA < uc_pdata->min_uA)
 138                return -EINVAL;
 139        if (uc_pdata->max_uA != -ENODATA && uA > uc_pdata->max_uA)
 140                return -EINVAL;
 141
 142        if (!ops || !ops->set_current)
 143                return -ENOSYS;
 144
 145        return ops->set_current(dev, uA);
 146}
 147
 148int regulator_get_enable(struct udevice *dev)
 149{
 150        const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
 151
 152        if (!ops || !ops->get_enable)
 153                return -ENOSYS;
 154
 155        return ops->get_enable(dev);
 156}
 157
 158int regulator_set_enable(struct udevice *dev, bool enable)
 159{
 160        const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
 161        struct dm_regulator_uclass_platdata *uc_pdata;
 162        int ret, old_enable = 0;
 163
 164        if (!ops || !ops->set_enable)
 165                return -ENOSYS;
 166
 167        uc_pdata = dev_get_uclass_platdata(dev);
 168        if (!enable && uc_pdata->always_on)
 169                return -EACCES;
 170
 171        if (uc_pdata->ramp_delay)
 172                old_enable = regulator_get_enable(dev);
 173
 174        ret = ops->set_enable(dev, enable);
 175        if (!ret) {
 176                if (uc_pdata->ramp_delay && !old_enable && enable) {
 177                        int uV = regulator_get_value(dev);
 178
 179                        if (uV > 0) {
 180                                regulator_set_value_ramp_delay(dev, 0, uV,
 181                                                               uc_pdata->ramp_delay);
 182                        }
 183                }
 184        }
 185
 186        return ret;
 187}
 188
 189int regulator_set_enable_if_allowed(struct udevice *dev, bool enable)
 190{
 191        int ret;
 192
 193        ret = regulator_set_enable(dev, enable);
 194        if (ret == -ENOSYS || ret == -EACCES)
 195                return 0;
 196
 197        return ret;
 198}
 199
 200int regulator_set_suspend_enable(struct udevice *dev, bool enable)
 201{
 202        const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
 203
 204        if (!ops->set_suspend_enable)
 205                return -ENOSYS;
 206
 207        return ops->set_suspend_enable(dev, enable);
 208}
 209
 210int regulator_get_suspend_enable(struct udevice *dev)
 211{
 212        const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
 213
 214        if (!ops->get_suspend_enable)
 215                return -ENOSYS;
 216
 217        return ops->get_suspend_enable(dev);
 218}
 219
 220int regulator_get_mode(struct udevice *dev)
 221{
 222        const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
 223
 224        if (!ops || !ops->get_mode)
 225                return -ENOSYS;
 226
 227        return ops->get_mode(dev);
 228}
 229
 230int regulator_set_mode(struct udevice *dev, int mode)
 231{
 232        const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
 233
 234        if (!ops || !ops->set_mode)
 235                return -ENOSYS;
 236
 237        return ops->set_mode(dev, mode);
 238}
 239
 240int regulator_get_by_platname(const char *plat_name, struct udevice **devp)
 241{
 242        struct dm_regulator_uclass_platdata *uc_pdata;
 243        struct udevice *dev;
 244        int ret;
 245
 246        *devp = NULL;
 247
 248        for (ret = uclass_find_first_device(UCLASS_REGULATOR, &dev); dev;
 249             ret = uclass_find_next_device(&dev)) {
 250                if (ret) {
 251                        debug("regulator %s, ret=%d\n", dev->name, ret);
 252                        continue;
 253                }
 254
 255                uc_pdata = dev_get_uclass_platdata(dev);
 256                if (!uc_pdata || strcmp(plat_name, uc_pdata->name))
 257                        continue;
 258
 259                return uclass_get_device_tail(dev, 0, devp);
 260        }
 261
 262        debug("%s: can't find: %s, ret=%d\n", __func__, plat_name, ret);
 263
 264        return -ENODEV;
 265}
 266
 267int regulator_get_by_devname(const char *devname, struct udevice **devp)
 268{
 269        return uclass_get_device_by_name(UCLASS_REGULATOR, devname, devp);
 270}
 271
 272int device_get_supply_regulator(struct udevice *dev, const char *supply_name,
 273                                struct udevice **devp)
 274{
 275        return uclass_get_device_by_phandle(UCLASS_REGULATOR, dev,
 276                                            supply_name, devp);
 277}
 278
 279int regulator_autoset(struct udevice *dev)
 280{
 281        struct dm_regulator_uclass_platdata *uc_pdata;
 282        int ret = 0;
 283
 284        uc_pdata = dev_get_uclass_platdata(dev);
 285
 286        ret = regulator_set_suspend_enable(dev, uc_pdata->suspend_on);
 287        if (!ret && uc_pdata->suspend_on) {
 288                ret = regulator_set_suspend_value(dev, uc_pdata->suspend_uV);
 289                if (!ret)
 290                        return ret;
 291        }
 292
 293        if (!uc_pdata->always_on && !uc_pdata->boot_on)
 294                return -EMEDIUMTYPE;
 295
 296        if (uc_pdata->type == REGULATOR_TYPE_FIXED)
 297                return regulator_set_enable(dev, true);
 298
 299        if (uc_pdata->flags & REGULATOR_FLAG_AUTOSET_UV)
 300                ret = regulator_set_value(dev, uc_pdata->min_uV);
 301        if (uc_pdata->init_uV > 0)
 302                ret = regulator_set_value(dev, uc_pdata->init_uV);
 303        if (!ret && (uc_pdata->flags & REGULATOR_FLAG_AUTOSET_UA))
 304                ret = regulator_set_current(dev, uc_pdata->min_uA);
 305
 306        if (!ret)
 307                ret = regulator_set_enable(dev, true);
 308
 309        return ret;
 310}
 311
 312static void regulator_show(struct udevice *dev, int ret)
 313{
 314        struct dm_regulator_uclass_platdata *uc_pdata;
 315
 316        uc_pdata = dev_get_uclass_platdata(dev);
 317
 318        printf("%s@%s: ", dev->name, uc_pdata->name);
 319        if (uc_pdata->flags & REGULATOR_FLAG_AUTOSET_UV)
 320                printf("set %d uV", uc_pdata->min_uV);
 321        if (uc_pdata->flags & REGULATOR_FLAG_AUTOSET_UA)
 322                printf("; set %d uA", uc_pdata->min_uA);
 323        printf("; enabling");
 324        if (ret)
 325                printf(" (ret: %d)", ret);
 326        printf("\n");
 327}
 328
 329int regulator_autoset_by_name(const char *platname, struct udevice **devp)
 330{
 331        struct udevice *dev;
 332        int ret;
 333
 334        ret = regulator_get_by_platname(platname, &dev);
 335        if (devp)
 336                *devp = dev;
 337        if (ret) {
 338                debug("Can get the regulator: %s (err=%d)\n", platname, ret);
 339                return ret;
 340        }
 341
 342        return regulator_autoset(dev);
 343}
 344
 345int regulator_list_autoset(const char *list_platname[],
 346                           struct udevice *list_devp[],
 347                           bool verbose)
 348{
 349        struct udevice *dev;
 350        int error = 0, i = 0, ret;
 351
 352        while (list_platname[i]) {
 353                ret = regulator_autoset_by_name(list_platname[i], &dev);
 354                if (ret != -EMEDIUMTYPE && verbose)
 355                        regulator_show(dev, ret);
 356                if (ret & !error)
 357                        error = ret;
 358
 359                if (list_devp)
 360                        list_devp[i] = dev;
 361
 362                i++;
 363        }
 364
 365        return error;
 366}
 367
 368static bool regulator_name_is_unique(struct udevice *check_dev,
 369                                     const char *check_name)
 370{
 371        struct dm_regulator_uclass_platdata *uc_pdata;
 372        struct udevice *dev;
 373        int check_len = strlen(check_name);
 374        int ret;
 375        int len;
 376
 377        for (ret = uclass_find_first_device(UCLASS_REGULATOR, &dev); dev;
 378             ret = uclass_find_next_device(&dev)) {
 379                if (ret || dev == check_dev)
 380                        continue;
 381
 382                uc_pdata = dev_get_uclass_platdata(dev);
 383                len = strlen(uc_pdata->name);
 384                if (len != check_len)
 385                        continue;
 386
 387                if (!strcmp(uc_pdata->name, check_name))
 388                        return false;
 389        }
 390
 391        return true;
 392}
 393
 394static int regulator_post_bind(struct udevice *dev)
 395{
 396        struct dm_regulator_uclass_platdata *uc_pdata;
 397        const char *property = "regulator-name";
 398
 399        uc_pdata = dev_get_uclass_platdata(dev);
 400
 401        /* Regulator's mandatory constraint */
 402        uc_pdata->name = dev_read_string(dev, property);
 403        if (!uc_pdata->name) {
 404                debug("%s: dev '%s' has no property '%s'\n",
 405                      __func__, dev->name, property);
 406                uc_pdata->name = dev_read_name(dev);
 407                if (!uc_pdata->name)
 408                        return -EINVAL;
 409        }
 410
 411        if (regulator_name_is_unique(dev, uc_pdata->name))
 412                return 0;
 413
 414        debug("'%s' of dev: '%s', has nonunique value: '%s\n",
 415              property, dev->name, uc_pdata->name);
 416
 417        return -EINVAL;
 418}
 419
 420static int regulator_pre_probe(struct udevice *dev)
 421{
 422        struct dm_regulator_uclass_platdata *uc_pdata;
 423        ofnode node;
 424
 425        uc_pdata = dev_get_uclass_platdata(dev);
 426        if (!uc_pdata)
 427                return -ENXIO;
 428
 429        /* Regulator's optional constraints */
 430        uc_pdata->min_uV = dev_read_u32_default(dev, "regulator-min-microvolt",
 431                                                -ENODATA);
 432        uc_pdata->max_uV = dev_read_u32_default(dev, "regulator-max-microvolt",
 433                                                -ENODATA);
 434        uc_pdata->init_uV = dev_read_u32_default(dev, "regulator-init-microvolt",
 435                                                 -ENODATA);
 436        uc_pdata->min_uA = dev_read_u32_default(dev, "regulator-min-microamp",
 437                                                -ENODATA);
 438        uc_pdata->max_uA = dev_read_u32_default(dev, "regulator-max-microamp",
 439                                                -ENODATA);
 440        uc_pdata->always_on = dev_read_bool(dev, "regulator-always-on");
 441        uc_pdata->boot_on = dev_read_bool(dev, "regulator-boot-on");
 442        uc_pdata->ramp_delay = dev_read_u32_default(dev, "regulator-ramp-delay",
 443                                                    0);
 444
 445        node = dev_read_subnode(dev, "regulator-state-mem");
 446        if (ofnode_valid(node)) {
 447                uc_pdata->suspend_on = !ofnode_read_bool(node, "regulator-off-in-suspend");
 448                if (ofnode_read_u32(node, "regulator-suspend-microvolt", &uc_pdata->suspend_uV))
 449                        uc_pdata->suspend_uV = uc_pdata->max_uV;
 450        } else {
 451                uc_pdata->suspend_on = true;
 452                uc_pdata->suspend_uV = uc_pdata->max_uV;
 453        }
 454
 455        /* Those values are optional (-ENODATA if unset) */
 456        if ((uc_pdata->min_uV != -ENODATA) &&
 457            (uc_pdata->max_uV != -ENODATA) &&
 458            (uc_pdata->min_uV == uc_pdata->max_uV))
 459                uc_pdata->flags |= REGULATOR_FLAG_AUTOSET_UV;
 460
 461        /* Those values are optional (-ENODATA if unset) */
 462        if ((uc_pdata->min_uA != -ENODATA) &&
 463            (uc_pdata->max_uA != -ENODATA) &&
 464            (uc_pdata->min_uA == uc_pdata->max_uA))
 465                uc_pdata->flags |= REGULATOR_FLAG_AUTOSET_UA;
 466
 467        if (uc_pdata->boot_on)
 468                regulator_set_enable(dev, uc_pdata->boot_on);
 469
 470        return 0;
 471}
 472
 473int regulators_enable_boot_on(bool verbose)
 474{
 475        struct udevice *dev;
 476        struct uclass *uc;
 477        int ret;
 478
 479        ret = uclass_get(UCLASS_REGULATOR, &uc);
 480        if (ret)
 481                return ret;
 482        for (uclass_first_device(UCLASS_REGULATOR, &dev);
 483             dev;
 484             uclass_next_device(&dev)) {
 485                ret = regulator_autoset(dev);
 486                if (ret == -EMEDIUMTYPE) {
 487                        ret = 0;
 488                        continue;
 489                }
 490                if (verbose)
 491                        regulator_show(dev, ret);
 492                if (ret == -ENOSYS)
 493                        ret = 0;
 494        }
 495
 496        return ret;
 497}
 498
 499UCLASS_DRIVER(regulator) = {
 500        .id             = UCLASS_REGULATOR,
 501        .name           = "regulator",
 502        .post_bind      = regulator_post_bind,
 503        .pre_probe      = regulator_pre_probe,
 504        .per_device_platdata_auto_alloc_size =
 505                                sizeof(struct dm_regulator_uclass_platdata),
 506};
 507