All of lore.kernel.org
 help / color / mirror / Atom feed
From: Przemyslaw Marczak <p.marczak@samsung.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH v2 05/12] dm: pmic: new commands: pmic and regulator
Date: Tue, 03 Mar 2015 17:24:36 +0100	[thread overview]
Message-ID: <1425399883-14053-6-git-send-email-p.marczak@samsung.com> (raw)
In-Reply-To: <1425399883-14053-1-git-send-email-p.marczak@samsung.com>

This introduces new commands:
- pmic (new) - CONFIG_DM_PMIC_CMD
- regulator - CONFIG_DM_REGULATOR_CMD
Both uses a common code and dm pmic api.

To avoid code mess the old pmic command is kept without changes.

Command pmic
The new pmic command uses driver model pmic api. The previous pmic
I/O functionality is keept. And now read/write is the main pmic command
feature. This command can be used only for UCLASS_PMIC devices,
since this uclass is designed for pmic I/O operations only and provides
pmic platform data.

Command options (pmic [option]):
- list                     - list available PMICs
- dev <id>                 - set id to current pmic device
- pmic dump                - dump registers
- pmic read <reg>          - read register
- pmic write <reg> <value> - write register

The user interface is changed. Before any operation, first the device
should be chosen.

Command regulator
It uses the same code, but provides user interface for regulator devices.

This was designed to access the regulator device without it's documentation.
It is possible, if driver implements uclass features, e.g. output descriptors.

Available commands:
- list     - list UCLASS regulator devices
- dev [id] - show or set current regulator device
- dump     - dump registers of current regulator device
- [ldo/buck/dvs][N] [name/state/desc]- print regulator(s) info
- [ldoN/buckN/dvsN] [setval/setmode] [mV/modeN] [-f] - set val (mV)
   or mode - only if descriptor exists

The regulator descriptor 'min' and 'max' limits prevents setting
unsafe value. But sometimes it is useful to change the regulator
value for some test - so the force option (-f) is available.
This option is not available for change the mode, since this depends
on pmic device design.

Signed-off-by: Przemyslaw Marczak <p.marczak@samsung.com>
---
Changes v2:
- remove errno_str() call
- pmic command: move some code to pmic uclass
- pmic command: code cleanup
- fix data types
- add command line, regulator on/off setting feature
- adjust to new pmic api
- cleanup
---
 drivers/power/Makefile   |   2 +
 drivers/power/cmd_pmic.c | 820 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 822 insertions(+)
 create mode 100644 drivers/power/cmd_pmic.c

diff --git a/drivers/power/Makefile b/drivers/power/Makefile
index a6b7012..943b38f 100644
--- a/drivers/power/Makefile
+++ b/drivers/power/Makefile
@@ -22,4 +22,6 @@ obj-$(CONFIG_POWER_FSL) += power_fsl.o
 obj-$(CONFIG_POWER_I2C) += power_i2c.o
 obj-$(CONFIG_POWER_SPI) += power_spi.o
 obj-$(CONFIG_DM_PMIC) += pmic-uclass.o
+obj-$(CONFIG_DM_PMIC_CMD) += cmd_pmic.o
 obj-$(CONFIG_DM_REGULATOR) += regulator-uclass.o
+obj-$(CONFIG_DM_REGULATOR_CMD) += cmd_pmic.o
diff --git a/drivers/power/cmd_pmic.c b/drivers/power/cmd_pmic.c
new file mode 100644
index 0000000..996bfe7
--- /dev/null
+++ b/drivers/power/cmd_pmic.c
@@ -0,0 +1,820 @@
+/*
+ * Copyright (C) 2014-2015 Samsung Electronics
+ * Przemyslaw Marczak <p.marczak@samsung.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#include <common.h>
+#include <linux/types.h>
+#include <linux/ctype.h>
+#include <fdtdec.h>
+#include <dm.h>
+#include <power/pmic.h>
+#include <power/regulator.h>
+#include <dm/device-internal.h>
+#include <dm/uclass-internal.h>
+#include <dm/root.h>
+#include <dm/lists.h>
+#include <i2c.h>
+#include <compiler.h>
+#include <errno.h>
+
+#define LINE_BUF_LIMIT	80
+#define STR_BUF_LEN	26
+#define ID_STR_LIMIT	4
+#define UC_STR_LIMIT	16
+#define DRV_STR_LIMIT	26
+#define IF_STR_LIMIT	12
+
+static struct udevice *pmic_curr;
+static struct udevice *reg_curr;
+
+#ifdef CONFIG_DM_REGULATOR_CMD
+#define TYPE_INFO(_id, _name) { \
+	.id = _id, \
+	.len = ARRAY_SIZE(_name) - 1, \
+	.name = _name, \
+}
+
+enum display_info {
+	INFO_NAME,
+	INFO_STATE,
+	INFO_DESC,
+	INFO_DESC_MODE,
+	INFO_DESC_VAL,
+};
+
+struct regulator_type_info {
+	int id;
+	int len;
+	char *name;
+};
+
+static struct regulator_type_info type_info[] = {
+	TYPE_INFO(REGULATOR_TYPE_LDO, "ldo"),
+	TYPE_INFO(REGULATOR_TYPE_BUCK, "buck"),
+	TYPE_INFO(REGULATOR_TYPE_DVS, "dvs"),
+};
+
+char *regulator_type_str(int regulator_type)
+{
+	switch (regulator_type) {
+	case REGULATOR_TYPE_LDO:
+	case REGULATOR_TYPE_BUCK:
+	case REGULATOR_TYPE_DVS:
+		return type_info[regulator_type].name;
+	default:
+		return NULL;
+	}
+}
+#endif /* CONFIG_DM_REGULATOR_CMD */
+
+static int set_curr_dev(struct udevice *dev)
+{
+	if (!dev)
+		return -EINVAL;
+
+	if (!dev->driver)
+		return -EINVAL;
+
+	switch (dev->driver->id) {
+	case UCLASS_PMIC:
+		pmic_curr = dev;
+		break;
+	case UCLASS_PMIC_REGULATOR:
+		reg_curr = dev;
+		break;
+	default:
+		error("Bad driver uclass!\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static struct udevice *get_curr_dev(int uclass_id)
+{
+	switch (uclass_id) {
+	case UCLASS_PMIC:
+		return pmic_curr;
+	case UCLASS_PMIC_REGULATOR:
+		return reg_curr;
+	default:
+		error("Bad uclass ID!\n");
+		return NULL;
+	}
+}
+
+static int curr_dev_name(int uclass_id)
+{
+	struct udevice *dev = get_curr_dev(uclass_id);
+
+	if (dev) {
+		printf("PMIC: %s\n", dev->name);
+		return 0;
+	} else {
+		puts("PMIC dev is not set!\n");
+		return -ENODEV;
+	}
+}
+
+static int pmic_dump(int uclass_id)
+{
+	struct udevice *dev;
+	struct udevice *io_dev;
+	int i, ret, max_offset;
+	unsigned char val;
+
+	dev = get_curr_dev(uclass_id);
+	if (!dev)
+		return -ENODEV;
+
+	if (pmic_io_dev(dev, &io_dev)) {
+		printf("PMIC I/O dev not found\n");
+		return -ENODEV;
+	}
+
+	ret = curr_dev_name(uclass_id);
+	if (ret)
+		return CMD_RET_USAGE;
+
+	max_offset = pmic_if_max_offset(io_dev);
+	printf("Register count: %u\n", max_offset);
+
+	for (i = 0; i < max_offset; i++) {
+		ret = pmic_read(io_dev, i, &val);
+		if (ret) {
+			printf("PMIC: Registers dump failed: %d\n", ret);
+			return -EIO;
+		}
+
+		if (!(i % 16))
+			printf("\n0x%02x: ", i);
+
+		printf("%2.2x ", val);
+	}
+	puts("\n");
+	return 0;
+}
+
+/**
+ * display_column - display a string from buffer limited by the column len.
+ *                  Allows display well aligned string columns.
+ *
+ * @buf: a pointer to the buffer with the string to display as a column
+ * @str_len: len of the string
+ * @column_len: a number of characters to be printed, but it is actually
+ *              decremented by 1 for the ending character: '|'
+*/
+static int display_column(char *buf, unsigned int str_len,
+			  unsigned int column_len)
+{
+	int i = column_len;
+
+	if (str_len < column_len - 1) {
+		for (i = str_len; i < column_len; i++)
+			buf[i] = ' ';
+	}
+
+	buf[column_len - 1] = '|';
+	buf[column_len] = '\0';
+
+	puts(buf);
+
+	return i;
+}
+
+static int pmic_list_uclass_devices(int uclass_id)
+{
+	ALLOC_CACHE_ALIGN_BUFFER(char, buf, LINE_BUF_LIMIT);
+	struct uclass_driver *uc_drv = NULL;
+	struct udevice *dev = NULL;
+	struct driver *drv = NULL;
+	struct uclass *uc = NULL;
+	int len;
+	int ret;
+
+	puts("| Id | Uclass        | Driver                  | Interface |\n");
+
+	ret = uclass_get(uclass_id, &uc);
+	if (ret) {
+		error("PMIC uclass: %d not found!\n", uclass_id);
+		return -EINVAL;
+	}
+
+	uc_drv = uc->uc_drv;
+	uclass_foreach_dev(dev, uc) {
+		if (dev)
+			device_probe(dev);
+		else
+			continue;
+
+		printf("| %2.d |", dev->seq);
+
+		len = snprintf(buf, STR_BUF_LEN, " %2.d@%.10s",
+				uc_drv->id,  uc_drv->name);
+
+		display_column(buf, len, UC_STR_LIMIT);
+
+		drv = dev->driver;
+		if (drv && drv->name)
+			len = snprintf(buf, STR_BUF_LEN, " %.26s", drv->name);
+		else
+			len = snprintf(buf, STR_BUF_LEN, " - ");
+
+		display_column(buf, len, DRV_STR_LIMIT);
+
+		len = snprintf(buf, STR_BUF_LEN, " %s%d at 0x%x",
+			       pmic_if_str(dev),
+			       pmic_if_bus_num(dev),
+			       pmic_if_addr_cs(dev));
+
+		display_column(buf, len, IF_STR_LIMIT);
+
+		puts("\n");
+	}
+
+	return 0;
+}
+
+static int pmic_cmd(char *const argv[], int argc, int uclass_id)
+{
+	const char *cmd = argv[0];
+	struct udevice *dev = NULL;
+	int seq;
+
+	if (strcmp(cmd, "list") == 0)
+		return pmic_list_uclass_devices(uclass_id);
+
+	if (strcmp(cmd, "dev") == 0) {
+		switch (argc) {
+		case 2:
+			seq = simple_strtoul(argv[1], NULL, 0);
+			uclass_get_device_by_seq(uclass_id, seq, &dev);
+			if (dev)
+				set_curr_dev(dev);
+			else
+				printf("Device: %d not found\n", seq);
+		case 1:
+			return curr_dev_name(uclass_id);
+		}
+	}
+
+	if (strcmp(cmd, "dump") == 0)
+		return pmic_dump(uclass_id);
+
+	if (!get_curr_dev(uclass_id))
+		return -ENODEV;
+
+	return 1;
+}
+
+#ifdef CONFIG_DM_REGULATOR_CMD
+static char *get_reg_mode_name(int reg, int mode,
+			       struct regulator_mode_desc *mode_desc,
+			       int desc_cnt)
+{
+	int i;
+	char *mode_name = NULL;
+
+	if (!mode_desc)
+		return NULL;
+
+	for (i = 0; i < desc_cnt; i++) {
+		if (mode_desc[i].mode == mode)
+			mode_name = mode_desc[i].name;
+	}
+
+	return mode_name;
+}
+
+static int set_reg_state(int type, int reg_num, int on_off)
+{
+	struct udevice *dev;
+
+	dev = get_curr_dev(UCLASS_PMIC_REGULATOR);
+	if (!dev)
+		return -ENODEV;
+
+	return regulator_set_state(dev,type, reg_num, on_off);
+}
+
+/**
+ * display_reg_info: list regualtor(s) info
+ * @start_reg; @end_reg - first and last regulator number to list
+ * if start_reg == end_reg - then displays only one regulator info
+ *
+ * @display_info options:
+ *
+ * =?INFO_NAME:
+ * regN: name
+ *
+ * =?INFO_STATE:
+ * regN: name
+ *  - Vout: val mV mode: N (name)
+ *
+ * =?INFO_DESC
+ * regN: name
+ *  - Vout: val mV
+ *  - Vmin: val mV
+ *  - Vmax: val mV
+ *  - mode: 1 (name1) [active]
+ *  - mode: 2 (name2) [active]
+ *  - mode: N (nameN) [active]
+ *
+ * =?INFO_DESC_VAL
+ * regN:
+ *  - Vout: val mV
+ *  - Vmin: val mV
+ *  - Vmax: val mV
+ *
+ * =?INFO_DESC_VAL
+ * regN:
+ *  - mode: 1 (name1) [active]
+ *  - mode: 2 (name2) [active]
+ *  - mode: N (nameN) [active]
+ */
+static int display_reg_info(int type, int start_reg,
+			    int end_reg, int display_info)
+{
+	struct udevice *dev;
+	struct regulator_value_desc *desc;
+	struct regulator_mode_desc *mode_desc;
+	char *mode_name;
+	int mode_cnt;
+	int mode;
+	int ret;
+	int state;
+	int reg_val, i, j;
+	int div = 1000;
+
+	if (start_reg > end_reg)
+		return -EINVAL;
+
+	dev = get_curr_dev(UCLASS_PMIC_REGULATOR);
+	if (!dev)
+		return -ENODEV;
+
+	switch (display_info) {
+	case INFO_STATE:
+		puts(" RegN:  val mV  state  mode");
+		break;
+	case INFO_DESC:
+		puts(" RegN:  @descriptors data");
+		break;
+	case INFO_DESC_VAL:
+	case INFO_DESC_MODE:
+		break;
+	case INFO_NAME:
+		puts(" RegN: name");
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	for (i = start_reg; i <= end_reg; i++) {
+		ret = regulator_get_mode(dev, type, i, &mode);
+		ret |= regulator_get_value(dev, type, i, &reg_val);
+		ret |= regulator_get_value_desc(dev, type, i, &desc);
+		ret |= regulator_get_mode_desc(dev, type, i, &mode_cnt,
+					       &mode_desc);
+
+		/* Probably no such regulator number */
+		if (ret)
+			continue;
+
+		/* Display in mV */
+		reg_val /= div;
+
+		printf("\n%s%.2d:", regulator_type_str(type), i);
+
+		switch (display_info) {
+		case INFO_STATE:
+			printf(" %d mV ",  reg_val);
+
+			regulator_get_state(dev, type, i, &state);
+
+			printf("   %s", state ? "ON " : "OFF");
+
+			mode_name = get_reg_mode_name(i, mode, mode_desc,
+							mode_cnt);
+			if (mode_name)
+				printf("  %d@%s", mode, mode_name);
+
+			continue;
+		case INFO_DESC:
+		case INFO_DESC_VAL:
+			if (desc)
+				printf("\n @name: %s", desc->name);
+
+			/* display voltage range */
+			printf("\n @Vout: %d mV", reg_val);
+
+			if (!desc)
+				puts("\n @no value descriptors");
+			else
+				printf("\n @Vmin: %d mV\n @Vmax: %d mV",
+							(desc->min_uV / div),
+							(desc->max_uV / div));
+
+			if (display_info != INFO_DESC)
+				continue;
+		case INFO_DESC_MODE:
+			if (!mode_desc) {
+				puts("\n @no mode descriptors");
+				continue;
+			}
+
+			/* display operation modes info */
+			for (j = 0; j < mode_cnt; j++) {
+				printf("\n @mode: %d (%s)", mode_desc[j].mode,
+							  mode_desc[j].name);
+				if (mode_desc[j].mode == mode)
+					puts(" (active)");
+			}
+			continue;
+		case INFO_NAME:
+			if (desc)
+				printf(" %s", desc->name);
+			else
+				puts(" -");
+			continue;
+		}
+	}
+
+	puts("\n");
+
+	return 0;
+}
+
+/**
+ * check_reg_mode: check if the given regulator supports the given mode
+ *
+ * @dev: device to check
+ * @reg_num: given devices regulator number
+ * @set_mode: mode to check - a mode value of struct regulator_mode_desc
+ * @type: descriptor type: REGULATOR_TYPE_LDO or REGULATOR_TYPE_BUCK
+ */
+static int check_reg_mode(struct udevice *dev, int reg_num, int set_mode,
+			  int type)
+{
+	struct regulator_mode_desc *mode_desc;
+	int i, mode_cnt;
+
+	regulator_get_mode_desc(dev, type, reg_num, &mode_cnt, &mode_desc);
+	if (!mode_desc)
+		goto nodesc;
+
+	for (i = 0; i < mode_cnt; i++) {
+		if (mode_desc[i].mode == set_mode)
+			return 0;
+	}
+
+	printf("Mode:%d not found in the descriptor:", set_mode);
+
+	display_reg_info(type, reg_num, reg_num, INFO_DESC_MODE);
+
+	return -EINVAL;
+
+nodesc:
+	printf("%s%.2d - no descriptor found\n", regulator_type_str(type),
+						 reg_num);
+	return -ENODEV;
+}
+
+static int set_reg_mode(int type, int reg_num, int set_mode)
+{
+	int ret;
+	struct udevice *dev;
+
+	dev = get_curr_dev(UCLASS_PMIC_REGULATOR);
+	if (!dev)
+		return -ENODEV;
+
+	if (check_reg_mode(dev, reg_num, set_mode, type))
+		return -EPERM;
+
+	printf("Set %s%.2d mode: %d\n", regulator_type_str(type),
+					reg_num, set_mode);
+
+	ret = regulator_set_mode(dev, type, reg_num, set_mode);
+
+	return ret;
+}
+
+/**
+ * check_reg_val: check if the given regulator value meets
+ *                the descriptor min and max values
+ *
+ * @dev: device to check
+ * @reg_num: given devices regulator number
+ * @set_val: value to check - in uV
+ * @type: descriptor type: REGULATOR_TYPE_LDO or REGULATOR_TYPE_BUCK
+ */
+static int check_reg_val(struct udevice *dev, int reg_num, int set_val,
+			 int type)
+{
+	struct regulator_value_desc *desc;
+
+	regulator_get_value_desc(dev, type, reg_num, &desc);
+	if (!desc)
+		goto nodesc;
+
+	if (set_val >= desc->min_uV && set_val <= desc->max_uV)
+		return 0;
+
+	printf("Value: %d mV exceeds descriptor limits:", (set_val / 1000));
+
+	display_reg_info(type, reg_num, reg_num, INFO_DESC_VAL);
+
+	return -EINVAL;
+nodesc:
+	printf("%s%.2d - no descriptor found\n", regulator_type_str(type),
+						 reg_num);
+	return -ENODEV;
+}
+
+static int set_reg_val(int type, int reg_num, int set_val, int set_force)
+{
+	int ret;
+	struct udevice *dev;
+
+	dev = get_curr_dev(UCLASS_PMIC_REGULATOR);
+	if (!dev)
+		return -ENODEV;
+
+	/* get mV and set as uV */
+	set_val *= 1000;
+
+	if (!set_force && check_reg_val(dev, reg_num, set_val, type))
+		return -EPERM;
+
+	printf("Set %s%.2d val: %d mV", regulator_type_str(type),
+					reg_num, (set_val / 1000));
+
+	if (set_force)
+		puts(" (force)\n");
+	else
+		puts("\n");
+
+	ret = regulator_set_value(dev, type, reg_num, set_val);
+	return ret;
+}
+
+static int regulator_subcmd(char * const argv[], int argc, int type,
+		      int reg_num, int reg_cnt)
+{
+	int start_reg, end_reg;
+	int set_val, set_force;
+	const char *cmd;
+
+	/* If reg number is given */
+	if (reg_num >= 0) {
+		start_reg = reg_num;
+		end_reg = reg_num;
+	} else {
+		start_reg = 0;
+		end_reg = reg_cnt;
+	}
+
+	cmd = argv[0];
+	if (!strcmp("name", cmd))
+		return display_reg_info(type, start_reg, end_reg, INFO_NAME);
+	else if (!strcmp("state", cmd))
+		return display_reg_info(type, start_reg, end_reg, INFO_STATE);
+	else if (!strcmp("desc", cmd))
+		return display_reg_info(type, start_reg, end_reg, INFO_DESC);
+
+	/* Check if regulator number is given */
+	if (reg_num < 0) {
+		puts("reg num?\n");
+		return -EINVAL;
+	}
+
+	if (!strcmp("on", cmd))
+		return set_reg_state(type, reg_num, REGULATOR_ON);
+
+	if (!strcmp("off", cmd))
+		return set_reg_state(type, reg_num, REGULATOR_OFF);
+
+	/* Check argument value */
+	if (argc < 2 || !isdigit(*argv[1])) {
+		puts("Expected positive value!\n");
+		return -EINVAL;
+	}
+
+	set_val = simple_strtoul(argv[1], NULL, 0);
+	set_force = 0;
+
+	if (!strcmp("setval", cmd)) {
+		if (argc == 3 && !strcmp("-f", argv[2]))
+			set_force = 1;
+
+		return set_reg_val(type, reg_num, set_val, set_force);
+	}
+
+	if (!strcmp("setmode", cmd))
+		return set_reg_mode(type, reg_num, set_val);
+
+	return -EINVAL;
+}
+
+static int do_regulator(cmd_tbl_t *cmdtp, int flag, int argc,
+			char * const argv[])
+{
+	struct udevice *dev = NULL;
+	int cmd_len;
+	int ret = 0;
+	int reg_num = -1;
+	int reg_cnt;
+	int i;
+	char *cmd;
+
+	if (!argc)
+		return CMD_RET_USAGE;
+
+	/* list, dev, dump */
+	ret = pmic_cmd(argv, argc, UCLASS_PMIC_REGULATOR);
+	if (ret != 1)
+		goto finish;
+
+	cmd = argv[0];
+	cmd_len = strlen(cmd);
+
+	dev = get_curr_dev(UCLASS_PMIC_REGULATOR);
+	if (!dev)
+		return CMD_RET_USAGE;
+
+	for (i = 0; i < ARRAY_SIZE(type_info); i++) {
+		if (!strncmp(cmd, type_info[i].name, type_info[i].len)) {
+			ret = regulator_get_cnt(dev, type_info[i].id, &reg_cnt);
+			break;
+		}
+	}
+
+	if (!reg_cnt) {
+		printf("Bad regulator type!\n");
+		goto finish;
+	}
+
+	/* Get regulator number */
+	reg_num = -1;
+	if (cmd_len > type_info[i].len && isdigit(cmd[type_info[i].len]))
+		reg_num = (int)simple_strtoul(cmd + type_info[i].len , NULL, 0);
+
+	if (reg_num > reg_cnt) {
+		printf("Max dev %s number is: %d\n", type_info[i].name,
+						     reg_cnt);
+		return CMD_RET_SUCCESS;
+	}
+
+	/* Subcommand missed? */
+	if (argc == 1) {
+		printf("name/state/desc/setval/setmode/on/off ?\n");
+		return CMD_RET_SUCCESS;
+	}
+
+	argv++;
+	argc--;
+	ret = regulator_subcmd(argv, argc, type_info[i].id, reg_num, reg_cnt);
+
+finish:
+	if (ret < 0)
+		return CMD_RET_FAILURE;
+
+	return CMD_RET_SUCCESS;
+}
+#endif /* CONFIG_DM_REGULATOR_CMD */
+
+#ifdef CONFIG_DM_PMIC_CMD
+static int do_pmic(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	struct udevice *dev, *io_dev;
+	unsigned reg;
+	unsigned char val;
+	char *cmd;
+	int ret = 0;
+
+	if (!argc)
+		return CMD_RET_USAGE;
+
+	/* list, dev, dump */
+	ret = pmic_cmd(argv, argc, UCLASS_PMIC);
+	if (ret != 1)
+		goto finish;
+
+	dev = get_curr_dev(UCLASS_PMIC);
+	ret = pmic_io_dev(dev, &io_dev);
+	if (ret)
+		goto finish;
+
+	cmd = argv[0];
+	if (strcmp(cmd, "read") == 0) {
+		if (argc != 2) {
+			ret = -EINVAL;
+			goto finish;
+		}
+
+		printf("cur dev: %p name: %s\n", dev, dev->name);
+		reg = simple_strtoul(argv[1], NULL, 0);
+
+		printf("read reg: %#x\n", reg);
+		ret = pmic_read(io_dev, reg, &val);
+		if (ret)
+			puts("PMIC: Register read failed\n");
+		else
+			printf("0x%02x: 0x%2.2x\n", reg, val);
+
+		goto finish;
+	}
+
+	if (strcmp(cmd, "write") == 0) {
+		if (argc != 3) {
+			ret = -EINVAL;
+			goto finish;
+		}
+
+		reg = simple_strtoul(argv[1], NULL, 0);
+		val = simple_strtoul(argv[2], NULL, 0);
+
+		printf("Write reg:%#x  val: %#x\n", reg, val);
+
+		ret = pmic_write(io_dev, reg, val);
+		if (ret)
+			puts("PMIC: Register write failed\n");
+
+		goto finish;
+	}
+
+finish:
+	if (ret < 0) {
+		printf("Error: %d\n", ret);
+		return CMD_RET_FAILURE;
+	}
+
+	return CMD_RET_SUCCESS;
+}
+#endif /* CONFIG_DM_PMIC_CMD */
+
+static cmd_tbl_t cmd_pmic[] = {
+#ifdef CONFIG_DM_PMIC_CMD
+	U_BOOT_CMD_MKENT(pmic, 5, 1, do_pmic, "", ""),
+#endif
+#ifdef CONFIG_DM_REGULATOR_CMD
+	U_BOOT_CMD_MKENT(regulator, 5, 1, do_regulator, "", ""),
+#endif
+};
+
+static int do_pmicops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	cmd_tbl_t *cmd;
+
+	cmd = find_cmd_tbl(argv[0], cmd_pmic, ARRAY_SIZE(cmd_pmic));
+	if (cmd == NULL || argc > cmd->maxargs)
+		return CMD_RET_USAGE;
+
+	argc--;
+	argv++;
+
+	return cmd->cmd(cmdtp, flag, argc, argv);
+}
+
+#ifdef CONFIG_DM_PMIC_CMD
+U_BOOT_CMD(pmic,	CONFIG_SYS_MAXARGS, 1, do_pmicops,
+	"PMIC",
+	"list                - list available PMICs\n"
+	"pmic dev <id>            - set id to current pmic device\n"
+	"pmic dump                - dump registers\n"
+	"pmic read <reg>          - read register\n"
+	"pmic write <reg> <value> - write register\n"
+);
+#endif /* CONFIG_DM_PMIC_CMD */
+#ifdef CONFIG_DM_REGULATOR_CMD
+U_BOOT_CMD(regulator, CONFIG_SYS_MAXARGS, 1, do_pmicops,
+	"PMIC Regulator",
+	"list\n\t- list UCLASS regulator devices\n"
+	"regulator dev [id]\n\t- show or set operating regulator device\n"
+	"regulator dump\n\t- dump registers of current regulator\n"
+	"regulator [ldo/buck/dvs][N] [name/state/desc]"
+	"\n\t- print regulator(s) info\n"
+	"regulator [ldoN/buckN/dvsN] [setval/setmode] [mV/modeN] [-f]"
+	"\n\t- set val (mV) (forcibly) or mode - only if desc available\n\n"
+	"Example of usage:\n"
+	"First get available commands:\n"
+	" # regulator\n"
+	"Look after the regulator device 'Id' number:\n"
+	" # regulator list\n"
+	"Set the operating device:\n"
+	" # regulator dev 'Id'\n"
+	"List state of device ldo's:\n"
+	" # regulator ldo state\n"
+	"List descriptors of device ldo's:\n"
+	" # regulator ldo desc\n"
+	"Set the voltage of ldo number 1 to 1200mV\n"
+	" # regulator ldo1 setval 1200\n"
+	"Use option: '-f', if given value exceeds the limits(be careful!):\n"
+	" # regulator ldo1 setval 1200 -f\n"
+	"Set the mode of ldo number 1 to '5' (force not available):\n"
+	" # regulator ldo1 setmode 5\n"
+);
+#endif /* CONFIG_DM_REGULATOR_CMD */
-- 
1.9.1

  parent reply	other threads:[~2015-03-03 16:24 UTC|newest]

Thread overview: 218+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-10-08 20:48 [U-Boot] [PATCH 00/19] [RFC] Power(full) framework based on Driver Model Przemyslaw Marczak
2014-10-08 20:48 ` [U-Boot] [PATCH 01/19] lib: errno: introduce errno_str(): returns errno related message Przemyslaw Marczak
2014-10-09  6:46   ` Joakim Tjernlund
2014-10-09 16:23     ` Przemyslaw Marczak
2014-10-09 22:53       ` Simon Glass
2014-10-10  5:03       ` Joakim Tjernlund
2014-10-10 11:49         ` Przemyslaw Marczak
2014-10-22 15:31   ` Tom Rini
2014-12-11  3:25     ` Simon Glass
2014-12-11 10:11       ` Przemyslaw Marczak
2014-12-11 13:24         ` Simon Glass
2014-10-08 20:48 ` [U-Boot] [PATCH 02/19] exynos: config-common: enable errno_str() function Przemyslaw Marczak
2014-10-08 20:48 ` [U-Boot] [PATCH 03/19] exynos: config-common: enable generic fs command Przemyslaw Marczak
2014-10-08 20:48 ` [U-Boot] [PATCH 04/19] dm: pmic: add implementation of driver model pmic uclass Przemyslaw Marczak
2014-10-10  3:17   ` Simon Glass
2014-10-10 13:32     ` Przemyslaw Marczak
2014-10-10 23:18       ` Simon Glass
2014-10-20 15:44         ` Przemyslaw Marczak
2014-10-20 15:46           ` Simon Glass
2014-10-20 15:51             ` Przemyslaw Marczak
2014-11-06 22:34               ` Simon Glass
2014-11-12 10:29                 ` Przemyslaw Marczak
2014-11-12 15:26                   ` Simon Glass
2014-10-08 20:48 ` [U-Boot] [PATCH 05/19] dm: pmic: add implementation of driver model regulator uclass Przemyslaw Marczak
2014-10-10  3:10   ` Simon Glass
2014-10-10 13:41     ` Przemyslaw Marczak
2014-10-08 20:48 ` [U-Boot] [PATCH 06/19] dm: common: board_r: add call and weak of power_init_dm() Przemyslaw Marczak
2014-10-10  3:32   ` Simon Glass
2014-10-20 15:45     ` Przemyslaw Marczak
2014-10-08 20:48 ` [U-Boot] [PATCH 07/19] dm: pmic: add max77686 pmic driver Przemyslaw Marczak
2014-10-22 15:31   ` Tom Rini
2014-10-08 20:48 ` [U-Boot] [PATCH 08/19] dm: regulator: add max77686 regulator driver Przemyslaw Marczak
2014-10-22 15:32   ` Tom Rini
2014-10-08 20:48 ` [U-Boot] [PATCH 09/19] dm: pmic: new commands: pmic and regulator Przemyslaw Marczak
2014-10-22 15:32   ` Tom Rini
2014-10-08 20:48 ` [U-Boot] [PATCH 10/19] dm: board:samsung: power_init_board: add requirement of CONFIG_DM_PMIC Przemyslaw Marczak
2014-10-08 20:48 ` [U-Boot] [PATCH 11/19] doc: driver-model: pmic and regulator uclass documentation Przemyslaw Marczak
2014-10-10  3:36   ` Simon Glass
2014-10-10 13:45     ` Przemyslaw Marczak
2014-10-08 20:48 ` [U-Boot] [PATCH 12/19] samsung: board: lcd menu: check if any power framework is enabled Przemyslaw Marczak
2014-10-08 20:48 ` [U-Boot] [PATCH 13/19] samsung: misc: power_key_pressed: add support to dm pmic framework Przemyslaw Marczak
2014-10-10  3:37   ` Simon Glass
2014-10-08 20:48 ` [U-Boot] [PATCH 14/19] trats2: board: add support to dm pmic api Przemyslaw Marczak
2014-10-10  3:39   ` Simon Glass
2014-10-10 13:46     ` Przemyslaw Marczak
2014-10-08 20:48 ` [U-Boot] [PATCH 15/19] trats2: dts: max77686: add pmic alias and names cleanup Przemyslaw Marczak
2014-10-08 20:48 ` [U-Boot] [PATCH 16/19] trats2: config: enable dm pmic, dm regulator api, dm max77686 Przemyslaw Marczak
2014-10-10  3:40   ` Simon Glass
2014-10-10 13:50     ` Przemyslaw Marczak
2014-10-08 20:48 ` [U-Boot] [PATCH 17/19] odroid: board: add support to dm pmic api Przemyslaw Marczak
2014-10-08 20:48 ` [U-Boot] [PATCH 18/19] odroid: dts: add 'voltage-regulators' description to max77686 node Przemyslaw Marczak
2014-10-08 20:48 ` [U-Boot] [PATCH 19/19] odroid: config: enable dm pmic, dm regulator and max77686 driver Przemyslaw Marczak
2014-10-08 20:55 ` [U-Boot] [PATCH 00/19] [RFC] Power(full) framework based on Driver Model Przemyslaw Marczak
2014-10-09  6:05   ` Simon Glass
2014-10-09 15:04     ` Przemyslaw Marczak
2014-10-22 15:31 ` Tom Rini
2014-10-24 15:50   ` Przemyslaw Marczak
2014-10-27 12:41   ` Przemyslaw Marczak
2015-03-03 16:24 ` [U-Boot] [PATCH v2 00/12] " Przemyslaw Marczak
2015-03-03 16:24   ` [U-Boot] [PATCH v2 01/12] exynos5: fix build break by adding CONFIG_POWER Przemyslaw Marczak
2015-03-04 12:19     ` Minkyu Kang
2015-03-03 16:24   ` [U-Boot] [PATCH v2 02/12] dm: device: add function device_get_first_child_by_uclass_id() Przemyslaw Marczak
2015-03-06 14:11     ` Simon Glass
2015-03-25 16:08       ` Przemyslaw Marczak
2015-03-03 16:24   ` [U-Boot] [PATCH v2 03/12] dm: pmic: add implementation of driver model pmic uclass Przemyslaw Marczak
2015-03-06 14:11     ` Simon Glass
2015-03-25 16:08       ` Przemyslaw Marczak
2015-03-03 16:24   ` [U-Boot] [PATCH v2 04/12] dm: pmic: add implementation of driver model regulator uclass Przemyslaw Marczak
2015-03-06 14:12     ` Simon Glass
2015-03-25 16:08       ` Przemyslaw Marczak
2015-03-10 11:41     ` Robert Baldyga
2015-03-25 16:08       ` Przemyslaw Marczak
2015-03-03 16:24   ` Przemyslaw Marczak [this message]
2015-03-06 14:13     ` [U-Boot] [PATCH v2 05/12] dm: pmic: new commands: pmic and regulator Simon Glass
2015-03-25 16:08       ` Przemyslaw Marczak
2015-03-03 16:24   ` [U-Boot] [PATCH v2 06/12] dm: pmic: add max77686 pmic driver Przemyslaw Marczak
2015-03-03 16:24   ` [U-Boot] [PATCH v2 07/12] dm: regulator: add max77686 regulator driver Przemyslaw Marczak
2015-03-06 14:14     ` Simon Glass
2015-03-25 16:08       ` Przemyslaw Marczak
2015-03-03 16:24   ` [U-Boot] [PATCH v2 08/12] doc: driver-model: pmic and regulator uclass documentation Przemyslaw Marczak
2015-03-06 14:14     ` Simon Glass
2015-03-25 16:08       ` Przemyslaw Marczak
2015-03-03 16:24   ` [U-Boot] [PATCH v2 09/12] dm: board:samsung: power_init_board: add requirement of CONFIG_DM_PMIC Przemyslaw Marczak
2015-03-03 16:24   ` [U-Boot] [PATCH v2 10/12] odroid: board: add support to dm pmic api Przemyslaw Marczak
2015-03-06 14:14     ` Simon Glass
2015-03-25 16:09       ` Przemyslaw Marczak
2015-03-03 16:24   ` [U-Boot] [PATCH v2 11/12] odroid: dts: add 'voltage-regulators' description to max77686 node Przemyslaw Marczak
2015-03-03 16:24   ` [U-Boot] [PATCH v2 12/12] odroid: config: enable dm pmic, dm regulator and max77686 driver Przemyslaw Marczak
2015-03-06 14:15     ` Simon Glass
2015-03-03 16:30   ` [U-Boot] [PATCH v2 00/12] Power(full) framework based on Driver Model Przemyslaw Marczak
2015-03-03 16:40   ` Przemyslaw Marczak
2015-03-06 14:10   ` Simon Glass
2015-03-06 15:08     ` Przemyslaw Marczak
2015-03-06 19:58       ` Simon Glass
2015-03-10  2:12     ` Simon Glass
2015-03-25 16:09       ` Przemyslaw Marczak
2015-03-24 20:30   ` [U-Boot] [PATCH v3 00/17] " Przemyslaw Marczak
2015-03-24 20:30     ` [U-Boot] [PATCH v3 01/17] exynos5: fix build break by adding CONFIG_POWER Przemyslaw Marczak
2015-03-29 13:05       ` Simon Glass
2015-03-24 20:30     ` [U-Boot] [PATCH v3 02/17] fdt_ro.c: add new function: fdt_node_check_prop_compatible() Przemyslaw Marczak
2015-03-29 13:07       ` Simon Glass
2015-03-24 20:30     ` [U-Boot] [PATCH v3 03/17] dm: core: lists.c: add new function lists_bind_fdt_by_prop() Przemyslaw Marczak
2015-03-29 13:07       ` Simon Glass
2015-03-24 20:30     ` [U-Boot] [PATCH v3 04/17] lib: Kconfig: add entry for errno_str() function Przemyslaw Marczak
2015-03-29 13:07       ` Simon Glass
2015-03-24 20:30     ` [U-Boot] [PATCH v3 05/17] dm: pmic: add implementation of driver model pmic uclass Przemyslaw Marczak
2015-03-29 13:07       ` Simon Glass
2015-04-03 16:08         ` Przemyslaw Marczak
2015-04-05 18:30           ` Simon Glass
2015-03-24 20:30     ` [U-Boot] [PATCH v3 06/17] dm: regulator: add implementation of driver model regulator uclass Przemyslaw Marczak
2015-03-29 13:07       ` Simon Glass
2015-04-03 16:09         ` Przemyslaw Marczak
2015-04-05 18:30           ` Simon Glass
2015-04-07 15:31             ` Przemyslaw Marczak
2015-04-08  1:47               ` Simon Glass
2015-04-08  7:37                 ` Przemyslaw Marczak
2015-03-24 20:30     ` [U-Boot] [PATCH v3 07/17] dm: pmic: add pmic command Przemyslaw Marczak
2015-03-29 13:07       ` Simon Glass
2015-04-03 16:08         ` Przemyslaw Marczak
2015-03-24 20:30     ` [U-Boot] [PATCH v3 08/17] dm: regulator: add regulator command Przemyslaw Marczak
2015-03-29 13:07       ` Simon Glass
2015-04-03 16:08         ` Przemyslaw Marczak
2015-03-24 20:30     ` [U-Boot] [PATCH v3 09/17] pmic: max77686 set the same compatible as in the kernel Przemyslaw Marczak
2015-03-29 13:08       ` Simon Glass
2015-03-24 20:30     ` [U-Boot] [PATCH v3 10/17] dm: pmic: add max77686 pmic driver Przemyslaw Marczak
2015-03-29 13:08       ` Simon Glass
2015-03-24 20:30     ` [U-Boot] [PATCH v3 11/17] dm: regulator: add max77686 regulator driver Przemyslaw Marczak
2015-03-29 13:08       ` Simon Glass
2015-04-03 16:08         ` Przemyslaw Marczak
2015-03-24 20:30     ` [U-Boot] [PATCH v3 12/17] dm: regulator: add fixed voltage " Przemyslaw Marczak
2015-03-29 13:08       ` Simon Glass
2015-04-03 16:09         ` Przemyslaw Marczak
2015-03-24 20:30     ` [U-Boot] [PATCH v3 13/17] doc: driver-model: pmic and regulator uclass documentation Przemyslaw Marczak
2015-03-29 13:08       ` Simon Glass
2015-04-03 16:09         ` Przemyslaw Marczak
2015-03-24 20:30     ` [U-Boot] [PATCH v3 14/17] dm: board:samsung: power_init_board: add requirement of CONFIG_DM_PMIC Przemyslaw Marczak
2015-03-29 13:09       ` Simon Glass
2015-03-24 20:30     ` [U-Boot] [PATCH v3 15/17] odroid: board: add support to dm pmic api Przemyslaw Marczak
2015-03-29 13:08       ` Simon Glass
2015-04-03 16:09         ` Przemyslaw Marczak
2015-03-24 20:30     ` [U-Boot] [PATCH v3 16/17] odroid: dts: add 'voltage-regulators' description to max77686 node Przemyslaw Marczak
2015-03-29 13:10       ` Simon Glass
2015-03-24 20:30     ` [U-Boot] [PATCH v3 17/17] odroid: config: enable dm pmic, dm regulator and max77686 driver Przemyslaw Marczak
2015-03-29 13:10       ` Simon Glass
2015-04-03 16:10         ` Przemyslaw Marczak
2015-03-25  7:47     ` [U-Boot] [PATCH v3 00/17] Power(full) framework based on Driver Model Przemyslaw Marczak
2015-03-29 13:05     ` Simon Glass
2015-04-03 16:11       ` Przemyslaw Marczak
2015-04-05 18:30         ` Simon Glass
2015-04-20 18:07     ` [U-Boot] [PATCH v4 00/16] " Przemyslaw Marczak
2015-04-20 18:07       ` [U-Boot] [PATCH v4 01/16] exynos5: fix build break by adding CONFIG_POWER Przemyslaw Marczak
2015-04-22 16:29         ` Simon Glass
2015-04-22 17:08           ` Simon Glass
2015-04-20 18:07       ` [U-Boot] [PATCH v4 02/16] exynos4-common: remove the unsued CONFIG_CMD_PMIC Przemyslaw Marczak
2015-04-22 16:29         ` Simon Glass
2015-04-22 17:09           ` Simon Glass
2015-04-20 18:07       ` [U-Boot] [PATCH v4 03/16] lib: Kconfig: add entry for errno_str() function Przemyslaw Marczak
2015-04-22 16:29         ` Simon Glass
2015-04-22 17:09           ` Simon Glass
2015-04-20 18:07       ` [U-Boot] [PATCH v4 04/16] dm: pmic: add implementation of driver model pmic uclass Przemyslaw Marczak
2015-04-22 16:30         ` Simon Glass
2015-04-22 17:09           ` Simon Glass
2015-04-23 11:33           ` Przemyslaw Marczak
2015-04-24  4:51             ` Simon Glass
2015-04-20 18:07       ` [U-Boot] [PATCH v4 05/16] dm: regulator: add implementation of driver model regulator uclass Przemyslaw Marczak
2015-04-22 16:30         ` Simon Glass
2015-04-22 16:54           ` Simon Glass
2015-04-22 17:09             ` Simon Glass
2015-04-23 11:33           ` Przemyslaw Marczak
2015-04-20 18:07       ` [U-Boot] [PATCH v4 06/16] dm: pmic: add pmic command Przemyslaw Marczak
2015-04-22 16:30         ` Simon Glass
2015-04-22 17:09           ` Simon Glass
2015-04-20 18:07       ` [U-Boot] [PATCH v4 07/16] dm: regulator: add regulator command Przemyslaw Marczak
2015-04-22 16:30         ` Simon Glass
2015-04-22 17:09           ` Simon Glass
2015-04-23 11:33           ` Przemyslaw Marczak
2015-04-24  4:51             ` Simon Glass
2015-04-24 12:18               ` Przemyslaw Marczak
2015-04-24 12:34                 ` Simon Glass
2015-04-24 12:53                   ` Przemyslaw Marczak
2015-04-24 13:00                     ` Simon Glass
2015-04-20 18:07       ` [U-Boot] [PATCH v4 08/16] pmic: max77686 set the same compatible as in the kernel Przemyslaw Marczak
2015-04-22 16:30         ` Simon Glass
2015-04-22 17:09           ` Simon Glass
2015-04-20 18:07       ` [U-Boot] [PATCH v4 09/16] dm: pmic: add max77686 pmic driver Przemyslaw Marczak
2015-04-22 16:30         ` Simon Glass
2015-04-22 17:10           ` Simon Glass
2015-04-20 18:07       ` [U-Boot] [PATCH v4 10/16] dm: regulator: add max77686 regulator driver Przemyslaw Marczak
2015-04-22 16:31         ` Simon Glass
2015-04-22 17:10           ` Simon Glass
2015-04-20 18:07       ` [U-Boot] [PATCH v4 11/16] dm: regulator: add fixed voltage " Przemyslaw Marczak
2015-04-22 16:31         ` Simon Glass
2015-04-22 17:10           ` Simon Glass
2015-04-23 12:31         ` Przemyslaw Marczak
2015-04-23 12:36           ` Przemyslaw Marczak
2015-04-24  4:50           ` Simon Glass
2015-04-20 18:07       ` [U-Boot] [PATCH v4 12/16] doc: driver-model: pmic and regulator uclass documentation Przemyslaw Marczak
2015-04-22 16:31         ` Simon Glass
2015-04-22 17:10           ` Simon Glass
2015-04-23 11:33           ` Przemyslaw Marczak
2015-04-20 18:07       ` [U-Boot] [PATCH v4 13/16] dm: board:samsung: power_init_board: add requirement of CONFIG_DM_PMIC Przemyslaw Marczak
2015-04-22 16:31         ` Simon Glass
2015-04-22 17:10           ` Simon Glass
2015-04-23 11:33           ` Przemyslaw Marczak
2015-04-20 18:07       ` [U-Boot] [PATCH v4 14/16] odroid: board: add support to dm pmic api Przemyslaw Marczak
2015-04-22 16:31         ` Simon Glass
2015-04-22 17:11           ` Simon Glass
2015-04-23 11:33           ` Przemyslaw Marczak
2015-04-20 18:07       ` [U-Boot] [PATCH v4 15/16] odroid: dts: add 'voltage-regulators' description to max77686 node Przemyslaw Marczak
2015-04-22 16:31         ` Simon Glass
2015-04-22 17:11           ` Simon Glass
2015-04-20 18:07       ` [U-Boot] [PATCH v4 16/16] odroid: config: enable dm pmic, dm regulator and max77686 driver Przemyslaw Marczak
2015-04-22 16:31         ` Simon Glass
2015-04-22 17:11           ` Simon Glass
2015-04-22 16:29       ` [U-Boot] [PATCH v4 00/16] Power(full) framework based on Driver Model Simon Glass
2015-04-23 11:33         ` Przemyslaw Marczak
2015-04-24  4:48           ` Simon Glass
2015-04-24 12:18             ` Przemyslaw Marczak

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1425399883-14053-6-git-send-email-p.marczak@samsung.com \
    --to=p.marczak@samsung.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.