1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) 2014-2015 Samsung Electronics 4 * Przemyslaw Marczak <p.marczak@samsung.com> 5 */ 6 #include <common.h> 7 #include <errno.h> 8 #include <dm.h> 9 #include <dm/uclass-internal.h> 10 #include <power/pmic.h> 11 12 #define LIMIT_DEV 32 13 #define LIMIT_PARENT 20 14 15 static struct udevice *currdev; 16 17 static int failure(int ret) 18 { 19 printf("Error: %d (%s)\n", ret, errno_str(ret)); 20 21 return CMD_RET_FAILURE; 22 } 23 24 static int do_dev(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 25 { 26 char *name; 27 int ret = -ENODEV; 28 29 switch (argc) { 30 case 2: 31 name = argv[1]; 32 ret = pmic_get(name, &currdev); 33 if (ret) { 34 printf("Can't get PMIC: %s!\n", name); 35 return failure(ret); 36 } 37 case 1: 38 if (!currdev) { 39 printf("PMIC device is not set!\n\n"); 40 return CMD_RET_USAGE; 41 } 42 43 printf("dev: %d @ %s\n", currdev->seq, currdev->name); 44 } 45 46 return CMD_RET_SUCCESS; 47 } 48 49 static int do_list(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 50 { 51 struct udevice *dev; 52 int ret; 53 54 printf("| %-*.*s| %-*.*s| %s @ %s\n", 55 LIMIT_DEV, LIMIT_DEV, "Name", 56 LIMIT_PARENT, LIMIT_PARENT, "Parent name", 57 "Parent uclass", "seq"); 58 59 for (ret = uclass_first_device(UCLASS_PMIC, &dev); dev; 60 ret = uclass_next_device(&dev)) { 61 if (ret) 62 continue; 63 64 printf("| %-*.*s| %-*.*s| %s @ %d\n", 65 LIMIT_DEV, LIMIT_DEV, dev->name, 66 LIMIT_PARENT, LIMIT_PARENT, dev->parent->name, 67 dev_get_uclass_name(dev->parent), dev->parent->seq); 68 } 69 70 if (ret) 71 return CMD_RET_FAILURE; 72 73 return CMD_RET_SUCCESS; 74 } 75 76 static int do_dump(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 77 { 78 struct udevice *dev; 79 uint8_t value; 80 uint reg; 81 int ret; 82 83 if (!currdev) { 84 printf("First, set the PMIC device!\n"); 85 return CMD_RET_USAGE; 86 } 87 88 dev = currdev; 89 90 printf("Dump pmic: %s registers\n", dev->name); 91 92 for (reg = 0; reg < pmic_reg_count(dev); reg++) { 93 ret = pmic_read(dev, reg, &value, 1); 94 if (ret) { 95 printf("Can't read register: %d\n", reg); 96 return failure(ret); 97 } 98 99 if (!(reg % 16)) 100 printf("\n0x%02x: ", reg); 101 102 printf("%2.2x ", value); 103 } 104 printf("\n"); 105 106 return CMD_RET_SUCCESS; 107 } 108 109 static int do_read(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 110 { 111 struct udevice *dev; 112 int regs, ret; 113 uint8_t value; 114 uint reg; 115 116 if (!currdev) { 117 printf("First, set the PMIC device!\n"); 118 return CMD_RET_USAGE; 119 } 120 121 dev = currdev; 122 123 if (argc != 2) 124 return CMD_RET_USAGE; 125 126 reg = simple_strtoul(argv[1], NULL, 0); 127 regs = pmic_reg_count(dev); 128 if (reg > regs) { 129 printf("PMIC max reg: %d\n", regs); 130 return failure(-EFAULT); 131 } 132 133 ret = pmic_read(dev, reg, &value, 1); 134 if (ret) { 135 printf("Can't read PMIC register: %d!\n", reg); 136 return failure(ret); 137 } 138 139 printf("0x%02x: 0x%2.2x\n", reg, value); 140 141 return CMD_RET_SUCCESS; 142 } 143 144 static int do_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 145 { 146 struct udevice *dev; 147 int regs, ret; 148 uint8_t value; 149 uint reg; 150 151 if (!currdev) { 152 printf("First, set the PMIC device!\n"); 153 return CMD_RET_USAGE; 154 } 155 156 dev = currdev; 157 158 if (argc != 3) 159 return CMD_RET_USAGE; 160 161 reg = simple_strtoul(argv[1], NULL, 0); 162 regs = pmic_reg_count(dev); 163 if (reg > regs) { 164 printf("PMIC max reg: %d\n", regs); 165 return failure(-EFAULT); 166 } 167 168 value = simple_strtoul(argv[2], NULL, 0); 169 170 ret = pmic_write(dev, reg, &value, 1); 171 if (ret) { 172 printf("Can't write PMIC register: %d!\n", reg); 173 return failure(ret); 174 } 175 176 return CMD_RET_SUCCESS; 177 } 178 179 static cmd_tbl_t subcmd[] = { 180 U_BOOT_CMD_MKENT(dev, 2, 1, do_dev, "", ""), 181 U_BOOT_CMD_MKENT(list, 1, 1, do_list, "", ""), 182 U_BOOT_CMD_MKENT(dump, 1, 1, do_dump, "", ""), 183 U_BOOT_CMD_MKENT(read, 2, 1, do_read, "", ""), 184 U_BOOT_CMD_MKENT(write, 3, 1, do_write, "", ""), 185 }; 186 187 static int do_pmic(cmd_tbl_t *cmdtp, int flag, int argc, 188 char * const argv[]) 189 { 190 cmd_tbl_t *cmd; 191 192 argc--; 193 argv++; 194 195 cmd = find_cmd_tbl(argv[0], subcmd, ARRAY_SIZE(subcmd)); 196 if (cmd == NULL || argc > cmd->maxargs) 197 return CMD_RET_USAGE; 198 199 return cmd->cmd(cmdtp, flag, argc, argv); 200 } 201 202 U_BOOT_CMD(pmic, CONFIG_SYS_MAXARGS, 1, do_pmic, 203 "PMIC sub-system", 204 "list - list pmic devices\n" 205 "pmic dev [name] - show or [set] operating PMIC device\n" 206 "pmic dump - dump registers\n" 207 "pmic read address - read byte of register at address\n" 208 "pmic write address - write byte to register at address\n" 209 ); 210