uboot/drivers/power/power_core.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (C) 2011 Samsung Electronics
   4 * Lukasz Majewski <l.majewski@samsung.com>
   5 *
   6 * (C) Copyright 2010
   7 * Stefano Babic, DENX Software Engineering, sbabic@denx.de
   8 *
   9 * (C) Copyright 2008-2009 Freescale Semiconductor, Inc.
  10 */
  11
  12#include <common.h>
  13#include <command.h>
  14#include <log.h>
  15#include <malloc.h>
  16#include <linux/types.h>
  17#include <linux/list.h>
  18#include <power/pmic.h>
  19
  20static LIST_HEAD(pmic_list);
  21
  22int check_reg(struct pmic *p, u32 reg)
  23{
  24        if (reg >= p->number_of_regs) {
  25                printf("<reg num> = %d is invalid. Should be less than %d\n",
  26                       reg, p->number_of_regs);
  27                return -EINVAL;
  28        }
  29
  30        return 0;
  31}
  32
  33int pmic_set_output(struct pmic *p, u32 reg, int out, int on)
  34{
  35        u32 val;
  36
  37        if (pmic_reg_read(p, reg, &val))
  38                return -ENOTSUPP;
  39
  40        if (on)
  41                val |= out;
  42        else
  43                val &= ~out;
  44
  45        if (pmic_reg_write(p, reg, val))
  46                return -ENOTSUPP;
  47
  48        return 0;
  49}
  50
  51struct pmic *pmic_alloc(void)
  52{
  53        struct pmic *p;
  54
  55        p = calloc(sizeof(*p), 1);
  56        if (!p) {
  57                printf("%s: No available memory for allocation!\n", __func__);
  58                return NULL;
  59        }
  60
  61        list_add_tail(&p->list, &pmic_list);
  62
  63        debug("%s: new pmic struct: 0x%p\n", __func__, p);
  64
  65        return p;
  66}
  67
  68struct pmic *pmic_get(const char *s)
  69{
  70        struct pmic *p;
  71
  72        list_for_each_entry(p, &pmic_list, list) {
  73                if (strcmp(p->name, s) == 0) {
  74                        debug("%s: pmic %s -> 0x%p\n", __func__, p->name, p);
  75                        return p;
  76                }
  77        }
  78
  79        return NULL;
  80}
  81
  82#ifndef CONFIG_SPL_BUILD
  83static int pmic_dump(struct pmic *p)
  84{
  85        int i, ret;
  86        u32 val;
  87
  88        if (!p) {
  89                puts("Wrong PMIC name!\n");
  90                return -ENODEV;
  91        }
  92
  93        printf("PMIC: %s\n", p->name);
  94        for (i = 0; i < p->number_of_regs; i++) {
  95                ret = pmic_reg_read(p, i, &val);
  96                if (ret)
  97                        puts("PMIC: Registers dump failed\n");
  98
  99                if (!(i % 8))
 100                        printf("\n0x%02x: ", i);
 101
 102                printf("%08x ", val);
 103        }
 104        puts("\n");
 105        return 0;
 106}
 107
 108static const char *power_get_interface(int interface)
 109{
 110        const char *power_interface[] = {"I2C", "SPI", "|+|-|"};
 111        return power_interface[interface];
 112}
 113
 114static void pmic_list_names(void)
 115{
 116        struct pmic *p;
 117
 118        puts("PMIC devices:\n");
 119        list_for_each_entry(p, &pmic_list, list) {
 120                printf("name: %s bus: %s_%d\n", p->name,
 121                       power_get_interface(p->interface), p->bus);
 122        }
 123}
 124
 125static int do_pmic(struct cmd_tbl *cmdtp, int flag, int argc,
 126                   char *const argv[])
 127{
 128        u32 ret, reg, val;
 129        char *cmd, *name;
 130        struct pmic *p;
 131
 132        /* at least two arguments please */
 133        if (argc < 2)
 134                return CMD_RET_USAGE;
 135
 136        if (strcmp(argv[1], "list") == 0) {
 137                pmic_list_names();
 138                return CMD_RET_SUCCESS;
 139        }
 140
 141        if (argc < 3)
 142                return CMD_RET_USAGE;
 143
 144        name = argv[1];
 145        cmd = argv[2];
 146
 147        debug("%s: name: %s cmd: %s\n", __func__, name, cmd);
 148        p = pmic_get(name);
 149        if (!p)
 150                return CMD_RET_FAILURE;
 151
 152        if (strcmp(cmd, "dump") == 0) {
 153                if (pmic_dump(p))
 154                        return CMD_RET_FAILURE;
 155                return CMD_RET_SUCCESS;
 156        }
 157
 158        if (strcmp(cmd, "read") == 0) {
 159                if (argc < 4)
 160                        return CMD_RET_USAGE;
 161
 162                reg = hextoul(argv[3], NULL);
 163                ret = pmic_reg_read(p, reg, &val);
 164
 165                if (ret)
 166                        puts("PMIC: Register read failed\n");
 167
 168                printf("\n0x%02x: 0x%08x\n", reg, val);
 169
 170                return CMD_RET_SUCCESS;
 171        }
 172
 173        if (strcmp(cmd, "write") == 0) {
 174                if (argc < 5)
 175                        return CMD_RET_USAGE;
 176
 177                reg = hextoul(argv[3], NULL);
 178                val = hextoul(argv[4], NULL);
 179                pmic_reg_write(p, reg, val);
 180
 181                return CMD_RET_SUCCESS;
 182        }
 183
 184        if (strcmp(cmd, "bat") == 0) {
 185                if (argc < 4)
 186                        return CMD_RET_USAGE;
 187
 188                if (!p->pbat) {
 189                        printf("%s is not a battery\n", p->name);
 190                        return CMD_RET_FAILURE;
 191                }
 192
 193                if (strcmp(argv[3], "state") == 0)
 194                        p->fg->fg_battery_check(p->pbat->fg, p);
 195
 196                if (strcmp(argv[3], "charge") == 0) {
 197                        printf("BAT: %s charging (ctrl+c to break)\n",
 198                               p->name);
 199                        if (p->low_power_mode)
 200                                p->low_power_mode();
 201                        if (p->pbat->battery_charge)
 202                                p->pbat->battery_charge(p);
 203                }
 204
 205                return CMD_RET_SUCCESS;
 206        }
 207
 208        /* No subcommand found */
 209        return CMD_RET_SUCCESS;
 210}
 211
 212U_BOOT_CMD(
 213        pmic,   CONFIG_SYS_MAXARGS, 1, do_pmic,
 214        "PMIC",
 215        "list - list available PMICs\n"
 216        "pmic name dump - dump named PMIC registers\n"
 217        "pmic name read <reg> - read register\n"
 218        "pmic name write <reg> <value> - write register\n"
 219        "pmic name bat state - write register\n"
 220        "pmic name bat charge - write register\n"
 221);
 222#endif
 223