uboot/drivers/power/axp809.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * AXP809 driver based on AXP221 driver
   4 *
   5 *
   6 * (C) Copyright 2016 Chen-Yu Tsai <wens@csie.org>
   7 *
   8 * Based on axp221.c
   9 * (C) Copyright 2014 Hans de Goede <hdegoede@redhat.com>
  10 * (C) Copyright 2013 Oliver Schinagl <oliver@schinagl.nl>
  11 */
  12
  13#include <common.h>
  14#include <errno.h>
  15#include <asm/arch/gpio.h>
  16#include <asm/arch/pmic_bus.h>
  17#include <axp_pmic.h>
  18
  19static u8 axp809_mvolt_to_cfg(int mvolt, int min, int max, int div)
  20{
  21        if (mvolt < min)
  22                mvolt = min;
  23        else if (mvolt > max)
  24                mvolt = max;
  25
  26        return (mvolt - min) / div;
  27}
  28
  29int axp_set_dcdc1(unsigned int mvolt)
  30{
  31        int ret;
  32        u8 cfg = axp809_mvolt_to_cfg(mvolt, 1600, 3400, 100);
  33
  34        if (mvolt == 0)
  35                return pmic_bus_clrbits(AXP809_OUTPUT_CTRL1,
  36                                        AXP809_OUTPUT_CTRL1_DCDC1_EN);
  37
  38        ret = pmic_bus_write(AXP809_DCDC1_CTRL, cfg);
  39        if (ret)
  40                return ret;
  41
  42        ret = pmic_bus_setbits(AXP809_OUTPUT_CTRL2,
  43                               AXP809_OUTPUT_CTRL2_DC1SW_EN);
  44        if (ret)
  45                return ret;
  46
  47        return pmic_bus_setbits(AXP809_OUTPUT_CTRL1,
  48                                AXP809_OUTPUT_CTRL1_DCDC1_EN);
  49}
  50
  51int axp_set_dcdc2(unsigned int mvolt)
  52{
  53        int ret;
  54        u8 cfg = axp809_mvolt_to_cfg(mvolt, 600, 1540, 20);
  55
  56        if (mvolt == 0)
  57                return pmic_bus_clrbits(AXP809_OUTPUT_CTRL1,
  58                                        AXP809_OUTPUT_CTRL1_DCDC2_EN);
  59
  60        ret = pmic_bus_write(AXP809_DCDC2_CTRL, cfg);
  61        if (ret)
  62                return ret;
  63
  64        return pmic_bus_setbits(AXP809_OUTPUT_CTRL1,
  65                                AXP809_OUTPUT_CTRL1_DCDC2_EN);
  66}
  67
  68int axp_set_dcdc3(unsigned int mvolt)
  69{
  70        int ret;
  71        u8 cfg = axp809_mvolt_to_cfg(mvolt, 600, 1860, 20);
  72
  73        if (mvolt == 0)
  74                return pmic_bus_clrbits(AXP809_OUTPUT_CTRL1,
  75                                        AXP809_OUTPUT_CTRL1_DCDC3_EN);
  76
  77        ret = pmic_bus_write(AXP809_DCDC3_CTRL, cfg);
  78        if (ret)
  79                return ret;
  80
  81        return pmic_bus_setbits(AXP809_OUTPUT_CTRL1,
  82                                AXP809_OUTPUT_CTRL1_DCDC3_EN);
  83}
  84
  85int axp_set_dcdc4(unsigned int mvolt)
  86{
  87        int ret;
  88        u8 cfg = axp809_mvolt_to_cfg(mvolt, 600, 1540, 20);
  89
  90        if (mvolt >= 1540)
  91                cfg = 0x30 + axp809_mvolt_to_cfg(mvolt, 1800, 2600, 100);
  92
  93        if (mvolt == 0)
  94                return pmic_bus_clrbits(AXP809_OUTPUT_CTRL1,
  95                                        AXP809_OUTPUT_CTRL1_DCDC4_EN);
  96
  97        ret = pmic_bus_write(AXP809_DCDC5_CTRL, cfg);
  98        if (ret)
  99                return ret;
 100
 101        return pmic_bus_setbits(AXP809_OUTPUT_CTRL1,
 102                                AXP809_OUTPUT_CTRL1_DCDC4_EN);
 103}
 104
 105int axp_set_dcdc5(unsigned int mvolt)
 106{
 107        int ret;
 108        u8 cfg = axp809_mvolt_to_cfg(mvolt, 1000, 2550, 50);
 109
 110        if (mvolt == 0)
 111                return pmic_bus_clrbits(AXP809_OUTPUT_CTRL1,
 112                                        AXP809_OUTPUT_CTRL1_DCDC5_EN);
 113
 114        ret = pmic_bus_write(AXP809_DCDC5_CTRL, cfg);
 115        if (ret)
 116                return ret;
 117
 118        return pmic_bus_setbits(AXP809_OUTPUT_CTRL1,
 119                                AXP809_OUTPUT_CTRL1_DCDC5_EN);
 120}
 121
 122int axp_set_aldo(int aldo_num, unsigned int mvolt)
 123{
 124        int ret;
 125        u8 cfg;
 126
 127        if (aldo_num < 1 || aldo_num > 3)
 128                return -EINVAL;
 129
 130        if (mvolt == 0 && aldo_num == 3)
 131                return pmic_bus_clrbits(AXP809_OUTPUT_CTRL2,
 132                                        AXP809_OUTPUT_CTRL2_ALDO3_EN);
 133        if (mvolt == 0)
 134                return pmic_bus_clrbits(AXP809_OUTPUT_CTRL1,
 135                                AXP809_OUTPUT_CTRL1_ALDO1_EN << (aldo_num - 1));
 136
 137        cfg = axp809_mvolt_to_cfg(mvolt, 700, 3300, 100);
 138        ret = pmic_bus_write(AXP809_ALDO1_CTRL + (aldo_num - 1), cfg);
 139        if (ret)
 140                return ret;
 141
 142        if (aldo_num == 3)
 143                return pmic_bus_setbits(AXP809_OUTPUT_CTRL2,
 144                                        AXP809_OUTPUT_CTRL2_ALDO3_EN);
 145        return pmic_bus_setbits(AXP809_OUTPUT_CTRL1,
 146                                AXP809_OUTPUT_CTRL1_ALDO1_EN << (aldo_num - 1));
 147}
 148
 149/* TODO: re-work other AXP drivers to consolidate ALDO functions. */
 150int axp_set_aldo1(unsigned int mvolt)
 151{
 152        return axp_set_aldo(1, mvolt);
 153}
 154
 155int axp_set_aldo2(unsigned int mvolt)
 156{
 157        return axp_set_aldo(2, mvolt);
 158}
 159
 160int axp_set_aldo3(unsigned int mvolt)
 161{
 162        return axp_set_aldo(3, mvolt);
 163}
 164
 165int axp_set_dldo(int dldo_num, unsigned int mvolt)
 166{
 167        u8 cfg = axp809_mvolt_to_cfg(mvolt, 700, 3300, 100);
 168        int ret;
 169
 170        if (dldo_num < 1 || dldo_num > 2)
 171                return -EINVAL;
 172
 173        if (mvolt == 0)
 174                return pmic_bus_clrbits(AXP809_OUTPUT_CTRL2,
 175                                AXP809_OUTPUT_CTRL2_DLDO1_EN << (dldo_num - 1));
 176
 177        if (dldo_num == 1 && mvolt > 3300)
 178                cfg += 1 + axp809_mvolt_to_cfg(mvolt, 3400, 4200, 200);
 179        ret = pmic_bus_write(AXP809_DLDO1_CTRL + (dldo_num - 1), cfg);
 180        if (ret)
 181                return ret;
 182
 183        return pmic_bus_setbits(AXP809_OUTPUT_CTRL2,
 184                                AXP809_OUTPUT_CTRL2_DLDO1_EN << (dldo_num - 1));
 185}
 186
 187int axp_set_eldo(int eldo_num, unsigned int mvolt)
 188{
 189        int ret;
 190        u8 cfg = axp809_mvolt_to_cfg(mvolt, 700, 3300, 100);
 191
 192        if (eldo_num < 1 || eldo_num > 3)
 193                return -EINVAL;
 194
 195        if (mvolt == 0)
 196                return pmic_bus_clrbits(AXP809_OUTPUT_CTRL2,
 197                                AXP809_OUTPUT_CTRL2_ELDO1_EN << (eldo_num - 1));
 198
 199        ret = pmic_bus_write(AXP809_ELDO1_CTRL + (eldo_num - 1), cfg);
 200        if (ret)
 201                return ret;
 202
 203        return pmic_bus_setbits(AXP809_OUTPUT_CTRL2,
 204                                AXP809_OUTPUT_CTRL2_ELDO1_EN << (eldo_num - 1));
 205}
 206
 207int axp_set_sw(bool on)
 208{
 209        if (on)
 210                return pmic_bus_setbits(AXP809_OUTPUT_CTRL2,
 211                                        AXP809_OUTPUT_CTRL2_SWOUT_EN);
 212
 213        return pmic_bus_clrbits(AXP809_OUTPUT_CTRL2,
 214                                AXP809_OUTPUT_CTRL2_SWOUT_EN);
 215}
 216
 217int axp_init(void)
 218{
 219        return pmic_bus_init();
 220}
 221
 222int do_poweroff(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 223{
 224        pmic_bus_write(AXP809_SHUTDOWN, AXP809_SHUTDOWN_POWEROFF);
 225
 226        /* infinite loop during shutdown */
 227        while (1) {}
 228
 229        /* not reached */
 230        return 0;
 231}
 232