From: Lothar Waßmann Date: Tue, 14 Mar 2017 16:41:35 +0000 (+0100) Subject: cmd: add command for accessing the RPM via SMD protocol X-Git-Tag: KARO-TXSD-2017-03-15~7 X-Git-Url: https://git.karo-electronics.de/?p=karo-tx-uboot.git;a=commitdiff_plain;h=c6c7153d25fb841c22883cb6c86cd3d763a6dbc3 cmd: add command for accessing the RPM via SMD protocol This patch adds a command for accessing PMIC (e.g. PM8916) registers via the Qualcomm Resource Power Manager (RPM) using the SMD protocol. --- diff --git a/cmd/Kconfig b/cmd/Kconfig index 17808de716..b5b5f49110 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -436,6 +436,11 @@ config CMD_SPMI help SPMI bus utility command. +config CMD_SMD + bool "smd-rpm support for Qualcomm PMIC access" + help + Qualcomm PMIC access via SMD-RPM + endmenu diff --git a/cmd/Makefile b/cmd/Makefile index 5d911f50f8..830b3a4943 100644 --- a/cmd/Makefile +++ b/cmd/Makefile @@ -121,6 +121,7 @@ obj-$(CONFIG_CMD_SETEXPR) += setexpr.o obj-$(CONFIG_CMD_SOFTSWITCH) += softswitch.o obj-$(CONFIG_CMD_SPI) += spi.o obj-$(CONFIG_CMD_SPIBOOTLDR) += spibootldr.o +obj-$(CONFIG_CMD_SMD) += smd-rpm.o obj-$(CONFIG_CMD_SPMI) += spmi.o obj-$(CONFIG_CMD_STRINGS) += strings.o obj-$(CONFIG_CMD_TERMINAL) += terminal.o diff --git a/cmd/smd-rpm.c b/cmd/smd-rpm.c new file mode 100644 index 0000000000..d925a04d08 --- /dev/null +++ b/cmd/smd-rpm.c @@ -0,0 +1,232 @@ +/* + * (C) Copyright 2016 Lothar Waßmann + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +static bool smd_inited; + +static uint32_t smd_rpm_msg[] = { + LDOA_RES_TYPE, 0, KEY_SOFTWARE_ENABLE, 4, 0, + KEY_MICRO_VOLT, 4, 0, + KEY_CURRENT, 4, 0, +}; + +#define smd_param_ldo smd_rpm_msg[1] +#define smd_param_enable smd_rpm_msg[4] +#define smd_param_uV smd_rpm_msg[7] +#define smd_param_uA smd_rpm_msg[10] + +static int do_smd_init(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) +{ + if (!smd_inited) { + smd_rpm_init(); + smd_inited = true; + } + return CMD_RET_SUCCESS; +} + +static int do_smd_uninit(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) +{ + if (smd_inited) { + smd_rpm_uninit(); + smd_inited = false; + } + return CMD_RET_SUCCESS; +} + +#ifdef DEBUG +static void dump_rpm_msg(void *_msg, size_t msglen) +{ + uint32_t *msg = _msg; + size_t m; + + printf("MSG:"); + for (m = 0; m < msglen / 4; m++) { + printf(" %08x", msg[m]); + } + printf("\n"); +} +#else +static inline void dump_rpm_msg(void *_msg, size_t msglen) +{ +} +#endif + +static int do_raw_write(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) +{ + int ret; + size_t msglen = argc * sizeof(uint32_t); + static uint32_t *msg; + static size_t msgsize; + int i; + + if (argc < 1) + return CMD_RET_USAGE; + + if (msg == NULL || msgsize < msglen) { + free(msg); + msg = malloc(msglen); + if (msg == NULL) { + msgsize = 0; + return CMD_RET_FAILURE; + } + msgsize = msglen; + } + + for (i = 0; i < argc; i++) + msg[i] = strtoul(argv[i], NULL, 16); + + dump_rpm_msg(msg, msglen); + + if (!smd_inited) + smd_rpm_init(); + + ret = rpm_send_data(msg, msglen, RPM_REQUEST_TYPE); + if (ret) + printf("Failed to configure regulator LDO%u\n", smd_param_ldo); + + if (!smd_inited) + smd_rpm_uninit(); + + return ret ? CMD_RET_FAILURE : CMD_RET_SUCCESS; +} + +static int do_smd_write(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) +{ + uint ldo, uV, uA; + int ret; + size_t msglen; + + if (argv[0][0] == 'w') + return do_raw_write(cmdtp, flag, argc - 1, &argv[1]); + + if (argc < 2 || argc > 4) + return cmd_usage(cmdtp); + + msglen = 5 * sizeof(uint32_t); + smd_param_enable = argv[0][0] == 'e'; + + ldo = simple_strtoul(argv[1], NULL, 10); + if (ldo > 18) + return CMD_RET_USAGE; + + smd_param_ldo = ldo; + + if (argc > 2) { + if (ldo > 3) { + uV = simple_strtoul(argv[2], NULL, 10); + smd_param_uV = uV; + msglen += 3 * sizeof(uint32_t); + } else { + printf("LDO%u has no voltage control\n", ldo); + } + } + if (argc > 3) { + uA = simple_strtoul(argv[3], NULL, 10); + smd_param_uA = uA; + msglen += 3 * sizeof(uint32_t); + } + printf("%sabling LDO%u", smd_param_enable == GENERIC_ENABLE ? "En" : "Dis", + smd_param_ldo); + if (argc > 2) + printf(": %u.%03uV", smd_param_uV / 1000000, + smd_param_uV / 1000 % 1000); + if (argc > 3) + printf(", %u.%03umA", smd_param_uA / 1000, + smd_param_uA % 1000); + printf("\n"); + + if (!smd_inited) + smd_rpm_init(); + + dump_rpm_msg(smd_rpm_msg, msglen); + ret = rpm_send_data(smd_rpm_msg, msglen, RPM_REQUEST_TYPE); + if (ret) + printf("Failed to configure regulator LDO%u\n", smd_param_ldo); + + if (!smd_inited) + smd_rpm_uninit(); + + return ret ? CMD_RET_FAILURE : CMD_RET_SUCCESS; +} + +static cmd_tbl_t cmd_smd_sub[] = { + U_BOOT_CMD_MKENT(init, 0, 1, do_smd_init, "", ""), + U_BOOT_CMD_MKENT(uninit, 0, 1, do_smd_uninit, "", ""), + U_BOOT_CMD_MKENT(enable, 4, 1, do_smd_write, "", ""), + U_BOOT_CMD_MKENT(disable, 5, 0, do_smd_write, "", ""), + U_BOOT_CMD_MKENT(write, 4, 1, do_smd_write, "", ""), +}; + +static inline void smd_reloc(void) +{ + static int relocated; + + if (!relocated) { + fixup_cmdtable(cmd_smd_sub, ARRAY_SIZE(cmd_smd_sub)); + relocated = 1; + }; +} + +/** + * do_smd() - Handle the "smd" command-line command + * @cmdtp: Command data struct pointer + * @flag: Command flag + * @argc: Command-line argument count + * @argv: Array of command-line arguments + * + * Returns zero on success, CMD_RET_USAGE in case of misuse and negative + * on error. + */ +static int do_smd(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) +{ + cmd_tbl_t *c; + +#ifdef CONFIG_NEEDS_MANUAL_RELOC + smd_reloc(); +#endif + + if (argc < 2) + return CMD_RET_USAGE; + + /* Strip off leading 'smd' command argument */ + argc--; + argv++; + + c = find_cmd_tbl(argv[0], cmd_smd_sub, ARRAY_SIZE(cmd_smd_sub)); + + if (c) + return c->cmd(cmdtp, flag, argc, argv); + else + printf("subcommand '%s' not found\n", argv[0]); + return CMD_RET_USAGE; +} + +#ifdef CONFIG_SYS_LONGHELP +static char smd_help_text[] = + "\tsmd init\n" + "\tsmd uninit\n" + "\tsmd enable [] [] - Enable LDO optionally setting voltage and current\n" + "\tsmd disable [] [] - Disable LDO\n" + "\tsmd write [ ] [...]\n" + "\tsmd read \n" + ; +#endif + +U_BOOT_CMD( + smd, 16, 0, do_smd, + "Qualcomm SMD sub-system", + smd_help_text +);