uboot/drivers/power/pmic/as3722.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (C) 2014 NVIDIA Corporation
   4 */
   5
   6#define pr_fmt(fmt) "as3722: " fmt
   7
   8#include <common.h>
   9#include <dm.h>
  10#include <errno.h>
  11#include <fdtdec.h>
  12#include <i2c.h>
  13#include <log.h>
  14#include <dm/lists.h>
  15#include <power/as3722.h>
  16#include <power/pmic.h>
  17
  18#define AS3722_NUM_OF_REGS      0x92
  19
  20static int as3722_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
  21{
  22        int ret;
  23
  24        ret = dm_i2c_read(dev, reg, buff, len);
  25        if (ret < 0)
  26                return ret;
  27
  28        return 0;
  29}
  30
  31static int as3722_write(struct udevice *dev, uint reg, const uint8_t *buff,
  32                        int len)
  33{
  34        int ret;
  35
  36        ret = dm_i2c_write(dev, reg, buff, len);
  37        if (ret < 0)
  38                return ret;
  39
  40        return 0;
  41}
  42
  43static int as3722_read_id(struct udevice *dev, uint *idp, uint *revisionp)
  44{
  45        int ret;
  46
  47        ret = pmic_reg_read(dev, AS3722_ASIC_ID1);
  48        if (ret < 0) {
  49                pr_err("failed to read ID1 register: %d\n", ret);
  50                return ret;
  51        }
  52        *idp = ret;
  53
  54        ret = pmic_reg_read(dev, AS3722_ASIC_ID2);
  55        if (ret < 0) {
  56                pr_err("failed to read ID2 register: %d\n", ret);
  57                return ret;
  58        }
  59        *revisionp = ret;
  60
  61        return 0;
  62}
  63
  64/* TODO(treding@nvidia.com): Add proper regulator support to avoid this */
  65int as3722_sd_set_voltage(struct udevice *dev, unsigned int sd, u8 value)
  66{
  67        int ret;
  68
  69        if (sd > 6)
  70                return -EINVAL;
  71
  72        ret = pmic_reg_write(dev, AS3722_SD_VOLTAGE(sd), value);
  73        if (ret < 0) {
  74                pr_err("failed to write SD%u voltage register: %d\n", sd, ret);
  75                return ret;
  76        }
  77
  78        return 0;
  79}
  80
  81int as3722_ldo_set_voltage(struct udevice *dev, unsigned int ldo, u8 value)
  82{
  83        int ret;
  84
  85        if (ldo > 11)
  86                return -EINVAL;
  87
  88        ret = pmic_reg_write(dev, AS3722_LDO_VOLTAGE(ldo), value);
  89        if (ret < 0) {
  90                pr_err("failed to write LDO%u voltage register: %d\n", ldo,
  91                       ret);
  92                return ret;
  93        }
  94
  95        return 0;
  96}
  97
  98static int as3722_probe(struct udevice *dev)
  99{
 100        uint id, revision;
 101        int ret;
 102
 103        ret = as3722_read_id(dev, &id, &revision);
 104        if (ret < 0) {
 105                pr_err("failed to read ID: %d\n", ret);
 106                return ret;
 107        }
 108
 109        if (id != AS3722_DEVICE_ID) {
 110                pr_err("unknown device\n");
 111                return -ENOENT;
 112        }
 113
 114        debug("AS3722 revision %#x found on I2C bus %s\n", revision, dev->name);
 115
 116        return 0;
 117}
 118
 119#if CONFIG_IS_ENABLED(PMIC_CHILDREN)
 120static const struct pmic_child_info pmic_children_info[] = {
 121        { .prefix = "sd", .driver = "as3722_stepdown"},
 122        { .prefix = "ldo", .driver = "as3722_ldo"},
 123        { },
 124};
 125
 126static int as3722_bind(struct udevice *dev)
 127{
 128        struct udevice *gpio_dev;
 129        ofnode regulators_node;
 130        int children;
 131        int ret;
 132
 133        regulators_node = dev_read_subnode(dev, "regulators");
 134        if (!ofnode_valid(regulators_node)) {
 135                debug("%s: %s regulators subnode not found\n", __func__,
 136                      dev->name);
 137                return -ENXIO;
 138        }
 139
 140        children = pmic_bind_children(dev, regulators_node, pmic_children_info);
 141        if (!children)
 142                debug("%s: %s - no child found\n", __func__, dev->name);
 143        ret = device_bind_driver(dev, "gpio_as3722", "gpio_as3722", &gpio_dev);
 144        if (ret) {
 145                debug("%s: Cannot bind GPIOs (ret=%d)\n", __func__, ret);
 146                return ret;
 147        }
 148
 149        return 0;
 150}
 151#endif
 152
 153static int as3722_reg_count(struct udevice *dev)
 154{
 155        return AS3722_NUM_OF_REGS;
 156}
 157
 158static struct dm_pmic_ops as3722_ops = {
 159        .reg_count = as3722_reg_count,
 160        .read = as3722_read,
 161        .write = as3722_write,
 162};
 163
 164static const struct udevice_id as3722_ids[] = {
 165        { .compatible = "ams,as3722" },
 166        { }
 167};
 168
 169U_BOOT_DRIVER(pmic_as3722) = {
 170        .name = "as3722_pmic",
 171        .id = UCLASS_PMIC,
 172        .of_match = as3722_ids,
 173#if CONFIG_IS_ENABLED(PMIC_CHILDREN)
 174        .bind = as3722_bind,
 175#endif
 176        .probe = as3722_probe,
 177        .ops = &as3722_ops,
 178};
 179