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