Power(full) framework based on Driver Model
Subsystems (4)
PATCH v3 13/17 doc: driver-model: pmic and regulator uclass documentation
In reply to Simon GlassHello Simon,
Quoted 411 lines · Simon Glass
Hi Przemyslaw,
Quoted 81 lines · Przemyslaw Marczak
Signed-off-by Przemyslaw Marczak <[email protected]>---
Changes v2, V3:
- update documentation with the framework api changes
- remove doc file name 'dm' prefix--- doc/driver-model/pmic-framework.txt | 350 ++++++++++++++++++++++++++++++++++++ 1 file changed, 350 insertions(+)create mode 100644
doc/driver-model/pmic-framework.txtdoc/driver-model/pmic-framework.txt new file +65
-0@@ -0,0 +1,350 @@ +# +# (C) Copyright 2014-2015 Samsung Electronics +# Przemyslaw Marczak <[email protected]> +# +# SPDX-License-Identifier: GPL-2.0+ +# + +PMIC framework based on Driver Model +==================================== +TOC: +1. Introduction +2. How does it work +3. Pmic driver api +4. Pmic driver +5. Pmic command +6. Regulator driver api +7. Regulator driver +8. Regulator command + +1. Introduction +=============== +This is an introduction to driver-model multi uclass PMIC devices support. +At present it is based on two uclass types: + +- UCLASS_PMIC - basic uclass type for PMIC I/O, which provides common + read/write interface. +- UCLASS_REGULATOR - additional uclass type for specific PMIC features, which + are various voltage regulators. + +New files: +UCLASS_PMIC: +- drivers/power/pmic-uclass.c +- include/power/pmic.h +UCLASS_REGULATOR: +- drivers/power/regulator-uclass.c +- include/power/regulator.h + +Commands: +- lib/cmd_pmic.c +- lib/cmd_regulator.c + +2. How doees it work +==================== +The Power Management Integrated Circuits (PMIC) are used in embedded systems +to provide stable, precise and specific voltage power source with over-voltage +and thermal protection circuits. + +The single PMIC can provide various functionalities with single or multiple +interfaces, like in the example below. + +-- SoC + | + | ______________________________________ + | BUS 0 | Multi interface PMIC IC |--> LDO out 1 + | e.g.I2C0 | |--> LDO out N + |-----------|---- PMIC device 0 (READ/WRITE ops) | + | or SPI0 | |_ REGULATOR device (ldo/... ops) |--> BUCK out 1 + | | |_ CHARGER device (charger ops) |--> BUCK out M + | | |_ MUIC device (microUSB con ops) | + | BUS 1 | |_ ... |---> BATTERY + | e.g.I2C1 | | + |-----------|---- PMIC device 1 (READ/WRITE ops) |---> USB in 1 + . or SPI1 | |_ RTC device (rtc ops) |---> USB in 2 + . |______________________________________|---> USB out + .doc/driver-model/pmic-framework.txt line 75
Quoted 10 lines
doc/driver-model/pmic-framework.txt new file +10
-0+ +Since U-Boot provides driver model features for I2C and SPI bus drivers, +the PMIC devices should also support this. With the new basic uclass types +for PMIC I/O and regulator features, PMIC drivers can simply provide common +features, with multiple interface and instance support. + +Basic design assumptions: + +- Common I/O api - UCLASS_PMIC +The main assumption is to use UCLASS_PMIC device to provide I/O interface,an I/O interface
doc/driver-model/pmic-framework.txt line 77
Quoted 2 lines
doc/driver-model/pmic-framework.txt new file +2
-0+for devices other uclass types. It is no matter what is the type of device +physical I/O interface.devices of other uclass types. It doesn't matter what type of physical I/O interface is used.
Usually PMIC devices are using SPI or I2C interface,
s/are using/use/
doc/driver-model/pmic-framework.txt line 82
Quoted 5 lines
doc/driver-model/pmic-framework.txt new file +5
-0+but use of any other interface (e.g. when PMIC is not directly connected +to the SoC) - is now possible. Drivers can use the same read/write api. + +- Common regulator api - UCLASS_REGULATOR +For setting the attributes of verious types of regulators with common api,various
with a common
doc/driver-model/pmic-framework.txt line 83
Quoted 1 line
doc/driver-model/pmic-framework.txt new file +1
-0+this uclass can be implemented. This allows to drive the each regulator outputallows driving each regulator's output
doc/driver-model/pmic-framework.txt line 84
Quoted 1 line
doc/driver-model/pmic-framework.txt new file +1
-0+value, on/off state and custom defined operation modes. It also provides thecustom-defined
or perhaps just 'particular'
doc/driver-model/pmic-framework.txt line 86
Quoted 2 lines
doc/driver-model/pmic-framework.txt new file +2
-0+user interface for all operations. +For the very simple implementation, the regulator drivers are not required,For simple implementations, regulator drivers are not required, so the code can use pmic read/write directly.
Quoted 100 lines
doc/driver-model/pmic-framework.txt new file +100
-0+so the code could base on pmic read/write only. + +When board device-tree file includes pmic subnode and the U_Boot compatible +driver exists, then the pmic device bind should looks like this: + +|_ root - will bind the device for I2C/SPI bus node + |_ i2c/spi - should bind a device for pmic node + |_ pmic (parent) - should bind child devices for its features + |_ regulator (child) + |_ charger (child) + |_ other (child) + +Usually PMIC design provides: + - single I/O interface (single UCLASS_PMIC driver) + Then UCLASS_PMIC device should be a parent of all pmic devices, where each + is usually different uclass type, but need to access the same interface + + - multiple I/O interfaces (UCLASS_PMIC driver for each) + For each interface the UCLASS_PMIC device should be a parent of only those + devices (different uclass types), which needs to access the specified + interface. + +3. Pmic driver api +=================== +To use the pmic API, config: CONFIG_DM_PMIC is required. +The new driver API is very simple and is based on 'struct dm_pmic_ops', +which define two basic operations: device read and write. + +The platform data is introduced as 'struct pmic_platdata', to keep an info +about the device interface. + +The api is described in file: 'include/power/pmic.h' +Getting the device: +- by name - int pmic_get(char *name, struct udevice **pmic); + +Device I/O interface +Can be used with UCLASS_PMIC devices: +- Read from the device 'len' bytes at 'reg' into the buffer: + int pmic_read(struct udevice *dev, uint reg, uint8_t *buffer, int len); + +- Write to the device 'len' bytes at 'reg' from the buffer: + int pmic_write(struct udevice *dev, uint reg, uint8_t *buffer, int len); + +4. Pmic driver +============================ +As an example of the pmic driver, please take a look into the MAX77686 driver +'drivers/power/pmic/max77686.c' and the description in 'include/power/pmic.h' + +The pmic driver can be defined by U_BOOT_DRIVER() macro: + +U_BOOT_DRIVER(pmic_max77686) = { + .name = "max77686 pmic", + .id = UCLASS_PMIC, + .of_match = max77686_ids, - Allows to bind by compatible + .bind = max77686_bind, - Function called at device bind + .ops = &max77686_ops, - Pmic api function calls + .platdata_auto_alloc_size = sizeof(struct pmic_platdata), +}; + +To bind the pmic device, field '.of_match' is required with proper compatible. + +Driver ops: +.reg_count = MAX77686_NUM_OF_REGS - number of pmic registers +.read = max77686_read() - allows to use pmic_read() +.write = max77686_write() - allows to use pmic_write() + +Driver bind: +- max77686_bind(): called on bind and calls pmic_child_node_scan() to bind the + childs which are int "voltage-regulators" subnode. The bind is done using + "voltage-regulators" property name. + +5. Pmic command +=============== +To use the pmic command, config: CONFIG_DM_PMIC_CMD is required. +The new pmic command allows to: +- list pmic devices +- choose the current device (like the mmc command) +- read or write the pmic register +- dump all pmic registers + +This command can use only UCLASS_PMIC devices, since this uclass is designed +for pmic I/O operations only. + +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 + +Example of usage: +# pmic list - chose one dev Id, e.g. 3 +# pmic dev 0 - set dev seq 0 as current device +# pmic dump - dump the registers of the current pmic dev +# pmic read 0x0 - read the register at address 0x0 +# pmic write 0x0 0x1 - write 0x1 to the register at addres 0x0 + +6. Regulator driver API +=================================== +To use the regulator API, config: CONFIG_DM_REGULATOR is required.doc/driver-model/pmic-framework.txt line 196
Quoted 10 lines
doc/driver-model/pmic-framework.txt new file +10
-0+The api is described in file: 'include/power/regulator.h' +The api is based on structure types: +- 'dm_regulator_info' - dev->uc_priv (auto-allocated) +- 'dm_regulator_mode' - included in regualtor info + +Regulator info keeps the constraints taken from the device-tree and also device +modes set by the driver (single or array). + +The fixed-regulator common driver keeps provides private structure type, to keep +its gpio attributes. The structure type 'fixed_regulator_priv' is keept in fieldkept
Quoted 137 lines
doc/driver-model/pmic-framework.txt new file +137
-0+'dev->priv' and is allocated by the driver. + +6.1 Regulator device-tree node: +The regulator node should looks like in the example: +ldo1 { + regulator-compatible = "LDO1"; (not used here, but required for bind) + regulator-name = "VDD_MMC_1.8V"; (mandatory) * + regulator-min-microvolt = <1000000>; (mandatory) * + regulator-max-microvolt = <1000000>; (mandatory) * + regulator-min-microamp = <1000>; (optional) * + regulator-max-microamp = <1000>; (optional) * + regulator-always-on; (optional) * + regulator-boot-on; (optional) * +}; + +For the fixed-voltage regulator, voltage min and max must be equal: +VDD_MMC: regulator at 0 { + compatible = "regulator-fixed"; + regulator-name = "VDD_MMC"; (mandatory) * + regulator-min-microvolt = <2800000>; (mandatory) * + regulator-max-microvolt = <2800000>; (mandatory) * + regulator-always-on; (optional) + regulator-boot-on; (optional) + gpio = <&gpc 1 GPIO_ACTIVE_HIGH>; (optional) + gpio-open-drain; (optional) + enable-active-high; (optional) + startup-delay-us +}; + +The attributes signed with '*' can be taken by the common function which is +regulator_ofdata_to_platdata(). The rest attributes for fixed-regulator, are +taken by the driver. + +6.2 Getting the device: +- by name - int regulator_get(char *name, struct udevice **regulator); + +6.3 Device I/O interface +According to the framework assumptions, where uclass pmic device is a parent +of pmic devices other uclass types, the regulator devices should use uclass +pmic interface, with the parent as the device, like this: +- pmic_read(regulator->parent, some_reg, &some_buff, count); +- pmic_write(regulator->parent, some_reg, &some_buff, count); + +6.4 Device regulator operations +The regulator function calls are based on few data types: +- enum regulator_type {...} - standard types: LDO, BUCK, DVS, FIXED +- struct dm_regulator_info {...} - output name and value limits +- struct dm_regulator_mode {...} - output operation mode value and name +- struct dm_regulator_ops {...} - regulator driver function calls + +The first argument is always device. And the device uclass id must be always: +- 'UCLASS_REGULATOR' + +Function details are described in regulator header. The basic features are: +- regulator_info() - get the regulator info structure +- regulator_mode() - get the regulator mode info structure +- regulator_get/set_value() - get/set the regulator output voltage +- regulator_get/set_current() - get/set the regulator output current +- regulator_get/set_enable() - get/set the regulator output enable state +- regulator_get/set_mode() - get/set the regulator output operation mode + +7. Regulator driver +====================================== +As an example of the regulator driver, please take a look into the MAX77686 +regulator driver (drivers/power/regulator/max77686.c). It implements two drivers +for the buck and ldo regulators. The buck driver structure: + +U_BOOT_DRIVER(max77686_buck) = { + .name = "max77686 buck", + .id = UCLASS_REGULATOR, + .ops = &max77686_buck_ops, + .of_match = max77686_buck_ids, + .ofdata_to_platdata = max77686_buck_ofdata_to_platdata, +}; + +The device-tree buck compatibles: +static const struct udevice_id max77686_buck_ids[] = { + { .compatible = "BUCK1", .data = 1 }, + { .compatible = "BUCK2", .data = 2 }, + ... + { }, (need always put null at the end) +}; + +For each compatible, the data is set as a number of buck. This allows to get +the device number without parsing the compatible. + +The buck driver '.ofdata_to_platdata' call implementation: +static int max77686_buck_ofdata_to_platdata(struct udevice *dev) +{ + struct dm_regulator_info *info = dev->uclass_priv; + int ret; + + /* Get the regulation constraints by the common function */ + ret = regulator_ofdata_to_platdata(dev); + if (ret) + return ret; + + info->type = REGULATOR_TYPE_BUCK; + /** + * The device mode array is filled by internal driver function with + * the proper name for each mode id. + */ + info->mode_count = max77686_buck_modes(dev2num(dev), &info->mode); + + return 0; +} + +And the call to regulator_ofdata_to_platdata() is responsible for filling the +regulator output constraints, which are keepts in device-tree regulator nodes, +e.g. 'arch/arm/dts/exynos4412-odroid.dts' + +For the I/O, this driver uses pmic_read/write calls, with the parent device +as the first argument, e.g.: pmic_read(dev->parent, adr, &val, 1); + +8. Regulator command +==================== +To use the pmic command, config: CONFIG_DM_REGULATOR_CMD is required. + +This command is based on driver model regulator api. +User interface features: +- list - list UCLASS regulator devices +- regulator dev [id] - show or [set] operating regulator device +- regulator [info] - print constraints info +- regulator [status] - print operating status +- regulator [value] [-f] - print/[set] voltage value [uV] (force) +- regulator [current] - print/[set] current value [uA] +- regulator [mode_id] - print/[set] operating mode id +- regulator [enable] - enable the regulator output +- regulator [disable] - disable the regulator output + +If pmic device driver provides support to this another pmic uclass, then this +command provides useful user interface. It was designed to allow safe I/O access +to the pmic device, without the pmic documentation. If driver provide regulator +output - value and mode info - then user can operate on it. + +Example of usage: +regulator list - look after regulator 'seq' numberdoc/driver-model/pmic-framework.txt line 343
Quoted 10 lines
doc/driver-model/pmic-framework.txt new file +10
-0+regulator dev 'seq' - set current device +regulator status - show device status +regulator info - list device available regulation constraints +regulator value - prints device voltage value +regulator value 1000000 - set device voltage value to 1000000 uV +regulator value 1200000 -f - if value exceeds limits - set force +regulator mode - print device operation mode id +regulator mode 5 - set devices operation mode to '5' (mode id) + +The -f option (forcibly) or mode - only if descriptor is availableI think something like this would be clearer:
The -f option (forcibly) and 'mode' sub-command are only available if the regulator descriptor is available
doc/driver-model/pmic-framework.txt line 350
Quoted 7 lines
doc/driver-model/pmic-framework.txt new file +7
-0+ +Note: +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 a pmic device design, but the required voltage value can +change, e.g. if some hardware uses pins header.changed.
Quoted 3 lines
What does "e..g. if some hardware uses pins header" mean? Can you reword that to be clearer?
Right, this was unclear.
I meant the hardware connected by I/O expansion header, which can be replaced by other. And each could be supplied by a different voltage value.
Quoted 7 lines
Quoted 3 lines
--
1.9.1Regards,
Simon
I didn't clean this file too much, last time. Will fix in next version. Thanks for help!
Signature · 4 lines
Przemyslaw Marczak Samsung R&D Institute Poland Samsung Electronics p.marczak at samsung.com
PATCH v3 14/17 dm: board:samsung: power_init_board: add requirement of CONFIG_DM_PMIC
In reply to Przemyslaw MarczakIn the power_init_board function call, regulator driver init is called, so before compile, make sure that any power framework is defined.
--- board/samsung/common/board.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
board/samsung/common/board.c +2 -2
@@ -21,9 +21,9 @@#include <asm/arch/pinmux.h> #include <asm/arch/power.h> #include <asm/arch/system.h> -#include <power/pmic.h> #include <asm/arch/sromc.h> #include <lcd.h> +#include <i2c.h> #include <samsung/misc.h> DECLARE_GLOBAL_DATA_PTR ;
@@ -168,7 +168,7 @@ int board_early_init_f(void) }#endif -#if defined(CONFIG_POWER ) +#if defined(CONFIG_POWER ) || defined(CONFIG_DM_PMIC )int power_init_board (void ) {set_ps_hold_ctrl ();
Signature · 1 line
1.9.1
PATCH v3 14/17 dm: board:samsung: power_init_board: add requirement of CONFIG_DM_PMIC
Quoted 7 lines · Przemyslaw Marczak
In the
power_init_boardfunction call, regulator driver init is called, so before compile, make sure that any power framework is defined.Signed-off-by Przemyslaw Marczak <[email protected]>--- board/samsung/common/board.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
Quoted 28 lines
board/samsung/common/board.c +2
-3@@ -21,9 +21,9 @@#include <asm/arch/pinmux.h> #include <asm/arch/power.h> #include <asm/arch/system.h> -#include <power/pmic.h> #include <asm/arch/sromc.h> #include <lcd.h> +#include <i2c.h> #include <samsung/misc.h> DECLARE_GLOBAL_DATA_PTR ;@@ -168,7 +168,7 @@ int board_early_init_f(void) }#endif -#if defined(CONFIG_POWER ) +#if defined(CONFIG_POWER ) || defined(CONFIG_DM_PMIC )int power_init_board (void ) {set_ps_hold_ctrl (); --1.9.1
PATCH v3 15/17 odroid: board: add support to dm pmic api
In reply to Przemyslaw MarczakThis commit change the old pmic framework calls with the new ones.
---
Changes v2:
- remove board_init_i2c() call
- update regulator calls
- update headers
- samsung/misc.c: include required header
Changes v3:
- adjust regulator calls to new api
--- board/samsung/common/misc.c | 1 + board/samsung/odroid/odroid.c | 113 +++++++++++++++++++++++++++++++++--------- 2 files changed, 91 insertions(+), 23 deletions(-)
board/samsung/common/misc.c +1 -0
@@ -16,6 +16,7 @@#include <asm/arch/cpu.h> #include <asm/gpio.h> #include <linux/input.h> +#include <dm.h> #include <power/pmic.h> #include <mmc.h>
board/samsung/odroid/odroid.c +90 -23
159 lines not on this page · raw message
Signature · 1 line
1.9.1
PATCH v3 15/17 odroid: board: add support to dm pmic api
Hi Przemyslaw,
Quoted 60 lines · Przemyslaw Marczak
This commit change the old pmic framework calls with the new ones.
Signed-off-by Przemyslaw Marczak <[email protected]>---
Changes v2:
- removeboard_init_i2c()call
- update regulator calls
- update headers
-samsung/misc.c: include required headerChanges v3:
- adjust regulator calls to new api--- board/samsung/common/misc.c | 1 + board/samsung/odroid/odroid.c | 113 +++++++++++++++++++++++++++++++++--------- 2 files changed, 91 insertions(+), 23 deletions(-)board/samsung/common/misc.c +1
-0@@ -16,6 +16,7 @@#include <asm/arch/cpu.h> #include <asm/gpio.h> #include <linux/input.h> +#include <dm.h> #include <power/pmic.h> #include <mmc.h> board/samsung/odroid/odroid.c +11
-3@@ -12,7 +12,9 @@#include <asm/arch/gpio.h> #include <asm/gpio.h> #include <asm/arch/cpu.h> +#include <dm.h> #include <power/pmic.h> +#include <power/regulator.h> #include <power/max77686_pmic.h> #include <errno.h> #include <mmc.h> @@ -405,15 +407,62 @@ static void board_gpio_init(void)static int pmic_init_max77686 (void ) { -struct pmic *p =pmic_get ("MAX77686_PMIC" ); +struct udevice *dev; +int ret; -if (pmic_probe (p)) -return -ENODEV ; + ret =regulator_get ("VDDQ_EMMC_1.8V" , &dev); +if (ret) { +error ("Regulator get error: %d" , ret); +return ret; + } + + ret =regulator_set_value (dev,1800000 );
board/samsung/odroid/odroid.c static void board_gpio_init(void) · line 429
Quoted 10 lines
board/samsung/odroid/odroid.c +10
-0+if (ret) { +error ("Regulator %s value setting error: %d" , dev->name, ret); +return ret; + } + + ret =regulator_set_enable (dev, true); +if (ret) { +error ("Regulator %s enable error: %d" , dev->name, ret); +return ret; + }
How about adding a function that finds a regulator, sets its voltage and enables it? Then you can avoid duplicating the same code 3 times.
Quoted 129 lines
board/samsung/odroid/odroid.c +69
-21+ + ret =regulator_get ("TFLASH_2.8V" , &dev); +if (ret) { +error ("Regulator get error: %d" , ret); +return ret; + } + + ret =regulator_set_value (dev,2800000 ); +if (ret) { +error ("Regulator %s value setting error: %d" , dev->name, ret); +return ret; + } + + ret =regulator_set_enable (dev, true); +if (ret) { +error ("Regulator %s enable error: %d" , dev->name, ret); +return ret; + } + + ret =regulator_get ("VDDQ_EMMC_2.8V" , &dev); +if (ret) { +error ("Regulator get error: %d" , ret); +return ret; + } -/* Set LDO Voltage */ -max77686_set_ldo_voltage (p,20 ,1800000 );/* LDO20 eMMC */ -max77686_set_ldo_voltage (p,21 ,2800000 );/* LDO21 SD */ -max77686_set_ldo_voltage (p,22 ,2800000 );/* LDO22 eMMC */ + ret =regulator_set_value (dev,2800000 ); +if (ret) { +error ("Regulator %s value setting error: %d" , dev->name, ret); +return ret; + } + + ret =regulator_set_enable (dev, true); +if (ret) { +error ("Regulator %s enable error: %d" , dev->name, ret); +return ret; + }return 0 ; }@@ -434,7 +483,6 @@ int exynos_init(void)int exynos_power_init (void ) { -pmic_init (0 );pmic_init_max77686 ();return 0 ;@@ -443,19 +491,20 @@ int exynos_power_init(void)#ifdef CONFIG_USB_GADGET static int s5pc210_phy_control (int on) { -struct pmic *p_pmic; - - p_pmic =pmic_get ("MAX77686_PMIC" ); -if (!p_pmic) -return -ENODEV ; +struct udevice *dev; +int ret; -if (pmic_probe (p_pmic)) -return -1 ; + ret =regulator_get ("VDD_UOTG_3.0V" , &dev); +if (ret) { +error ("Regulator get error: %d" , ret); +return ret; + }if (on) -return max77686_set_ldo_mode (p_pmic,12 ,OPMODE_ON ); +return regulator_set_mode (dev,OPMODE_ON );else -return max77686_set_ldo_mode (p_pmic,12 ,OPMODE_LPM ); +return regulator_set_mode (dev,OPMODE_LPM ); + } struct s3c_plat_otg_data s5pc210_otg_data = {@@ -472,7 +521,8 @@ struct s3c_plat_otg_data s5pc210_otg_data = {int board_usb_init (int index,enum usb_init_type init) {#ifdef CONFIG_CMD_USB -struct pmic *p_pmic; +struct udevice *dev; +int ret;/* Set Ref freq 0 => 24MHz, 1 => 26MHz*/ /* Odroid Us have it at 24MHz, Odroid Xs at 26MHz */ @@ -490,14 +540,31 @@ int board_usb_init(int index, enum usb_init_type init)/* Power off and on BUCK8 for LAN9730 */ debug ("LAN9730 - Turning power buck 8 OFF and ON.\n" ); - p_pmic =pmic_get ("MAX77686_PMIC" ); -if (p_pmic && !pmic_probe (p_pmic)) { -max77686_set_buck_voltage (p_pmic,8 ,750000 ); -max77686_set_buck_voltage (p_pmic,8 ,3300000 ); + ret =regulator_get ("VCC_P3V3_2.85V" , &dev); +if (ret) { +error ("Regulator get error: %d" , ret); +return ret; } -#endif + ret =regulator_set_enable (dev, true); +if (ret) { +error ("Regulator %s enable setting error: %d" , dev->name, ret); +return ret; + } + + ret =regulator_set_value (dev,750000 ); +if (ret) { +error ("Regulator %s value setting error: %d" , dev->name, ret); +return ret; + } + ret =regulator_set_value (dev,3300000 ); +if (ret) { +error ("Regulator %s value setting error: %d" , dev->name, ret); +return ret; + } + +#endif debug ("USB_udc_probe\n" );return s3c_udc_probe (&s5pc210_otg_data); } --
Quoted 2 lines
1.9.1
Regards,
Simon
PATCH v3 15/17 odroid: board: add support to dm pmic api
Hello Simon,
Quoted 68 lines · Simon Glass
Hi Przemyslaw,
Quoted 65 lines · Przemyslaw Marczak
This commit change the old pmic framework calls with the new ones.
Signed-off-by Przemyslaw Marczak <[email protected]>---
Changes v2:
- removeboard_init_i2c()call
- update regulator calls
- update headers
-samsung/misc.c: include required headerChanges v3:
- adjust regulator calls to new api--- board/samsung/common/misc.c | 1 + board/samsung/odroid/odroid.c | 113 +++++++++++++++++++++++++++++++++--------- 2 files changed, 91 insertions(+), 23 deletions(-)board/samsung/common/misc.c +1
-0@@ -16,6 +16,7 @@#include <asm/arch/cpu.h> #include <asm/gpio.h> #include <linux/input.h> +#include <dm.h> #include <power/pmic.h> #include <mmc.h> board/samsung/odroid/odroid.c +16
-3@@ -12,7 +12,9 @@#include <asm/arch/gpio.h> #include <asm/gpio.h> #include <asm/arch/cpu.h> +#include <dm.h> #include <power/pmic.h> +#include <power/regulator.h> #include <power/max77686_pmic.h> #include <errno.h> #include <mmc.h> @@ -405,15 +407,62 @@ static void board_gpio_init(void)static int pmic_init_max77686 (void ) { -struct pmic *p =pmic_get ("MAX77686_PMIC" ); +struct udevice *dev; +int ret; -if (pmic_probe (p)) -return -ENODEV ; + ret =regulator_get ("VDDQ_EMMC_1.8V" , &dev); +if (ret) { +error ("Regulator get error: %d" , ret); +return ret; + } + + ret =regulator_set_value (dev,1800000 ); +if (ret) { +error ("Regulator %s value setting error: %d" , dev->name, ret); +return ret; + } +
Quoted 9 lines
board/samsung/odroid/odroid.c static void board_gpio_init(void) · line 429
Quoted 5 lines
board/samsung/odroid/odroid.c +5
-0+ ret =regulator_set_enable (dev, true); +if (ret) { +error ("Regulator %s enable error: %d" , dev->name, ret); +return ret; + }How about adding a function that finds a regulator, sets its voltage and enables it? Then you can avoid duplicating the same code 3 times.
Yes, will add something like this.
Quoted 118 lines
Quoted 118 lines
board/samsung/odroid/odroid.c +62
-20+ + ret =regulator_get ("TFLASH_2.8V" , &dev); +if (ret) { +error ("Regulator get error: %d" , ret); +return ret; + } + + ret =regulator_set_value (dev,2800000 ); +if (ret) { +error ("Regulator %s value setting error: %d" , dev->name, ret); +return ret; + } + + ret =regulator_set_enable (dev, true); +if (ret) { +error ("Regulator %s enable error: %d" , dev->name, ret); +return ret; + } + + ret =regulator_get ("VDDQ_EMMC_2.8V" , &dev); +if (ret) { +error ("Regulator get error: %d" , ret); +return ret; + } -/* Set LDO Voltage */ -max77686_set_ldo_voltage (p,20 ,1800000 );/* LDO20 eMMC */ -max77686_set_ldo_voltage (p,21 ,2800000 );/* LDO21 SD */ -max77686_set_ldo_voltage (p,22 ,2800000 );/* LDO22 eMMC */ + ret =regulator_set_value (dev,2800000 ); +if (ret) { +error ("Regulator %s value setting error: %d" , dev->name, ret); +return ret; + } + + ret =regulator_set_enable (dev, true); +if (ret) { +error ("Regulator %s enable error: %d" , dev->name, ret); +return ret; + }return 0 ; }@@ -434,7 +483,6 @@ int exynos_init(void)int exynos_power_init (void ) { -pmic_init (0 );pmic_init_max77686 ();return 0 ;@@ -443,19 +491,20 @@ int exynos_power_init(void)#ifdef CONFIG_USB_GADGET static int s5pc210_phy_control (int on) { -struct pmic *p_pmic; - - p_pmic =pmic_get ("MAX77686_PMIC" ); -if (!p_pmic) -return -ENODEV ; +struct udevice *dev; +int ret; -if (pmic_probe (p_pmic)) -return -1 ; + ret =regulator_get ("VDD_UOTG_3.0V" , &dev); +if (ret) { +error ("Regulator get error: %d" , ret); +return ret; + }if (on) -return max77686_set_ldo_mode (p_pmic,12 ,OPMODE_ON ); +return regulator_set_mode (dev,OPMODE_ON );else -return max77686_set_ldo_mode (p_pmic,12 ,OPMODE_LPM ); +return regulator_set_mode (dev,OPMODE_LPM ); + } struct s3c_plat_otg_data s5pc210_otg_data = {@@ -472,7 +521,8 @@ struct s3c_plat_otg_data s5pc210_otg_data = {int board_usb_init (int index,enum usb_init_type init) {#ifdef CONFIG_CMD_USB -struct pmic *p_pmic; +struct udevice *dev; +int ret;/* Set Ref freq 0 => 24MHz, 1 => 26MHz*/ /* Odroid Us have it at 24MHz, Odroid Xs at 26MHz */ @@ -490,14 +540,31 @@ int board_usb_init(int index, enum usb_init_type init)/* Power off and on BUCK8 for LAN9730 */ debug ("LAN9730 - Turning power buck 8 OFF and ON.\n" ); - p_pmic =pmic_get ("MAX77686_PMIC" ); -if (p_pmic && !pmic_probe (p_pmic)) { -max77686_set_buck_voltage (p_pmic,8 ,750000 ); -max77686_set_buck_voltage (p_pmic,8 ,3300000 ); + ret =regulator_get ("VCC_P3V3_2.85V" , &dev); +if (ret) { +error ("Regulator get error: %d" , ret); +return ret; } -#endif + ret =regulator_set_enable (dev, true); +if (ret) { +error ("Regulator %s enable setting error: %d" , dev->name, ret); +return ret; + } + + ret =regulator_set_value (dev,750000 ); +if (ret) { +error ("Regulator %s value setting error: %d" , dev->name, ret); +return ret; + }
Quoted 17 lines
Quoted 11 lines
board/samsung/odroid/odroid.c +7
-1+ ret =regulator_set_value (dev,3300000 ); +if (ret) { +error ("Regulator %s value setting error: %d" , dev->name, ret); +return ret; + } + +#endif debug ("USB_udc_probe\n" );return s3c_udc_probe (&s5pc210_otg_data); } --Quoted 2 lines
1.9.1
Regards,
Simon
Thanks,
Signature · 4 lines
Przemyslaw Marczak Samsung R&D Institute Poland Samsung Electronics p.marczak at samsung.com
PATCH v3 16/17 odroid: dts: add 'voltage-regulators' description to max77686 node
In reply to Przemyslaw MarczakAdding regulators subnode to fdt max77686 node, allows properly init regulators by the max77686 regulator driver. This enables the complete functionality of the regulator command.
---
Changes V2:
- odroid: dts: remove pmic alias
Changes V3:
- none
--- arch/arm/dts/exynos4412-odroid.dts | 247 +++++++++++++++++++++++++++++++++++++ 1 file changed, 247 insertions(+)
arch/arm/dts/exynos4412-odroid.dts +247 -0
@@ -40,6 +40,253 @@ interrupts = <7 0>; reg = <0x09 0 0>; #clock-cells = <1>; + + voltage-regulators { + ldo1_reg: ldo1 { + regulator-compatible = "LDO1"; + regulator-name = "VDD_ALIVE_1.0V"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + }; + + ldo2_reg: ldo2 { + regulator-compatible = "LDO2"; + regulator-name = "VDDQ_VM1M2_1.2V"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + }; + + ldo3_reg: ldo3 { + regulator-compatible = "LDO3"; + regulator-name = "VCC_1.8V_AP"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + ldo4_reg: ldo4 { + regulator-compatible = "LDO4"; + regulator-name = "VDDQ_MMC2_2.8V"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + }; + + ldo5_reg: ldo5 { + regulator-compatible = "LDO5"; + regulator-name = "VDDQ_MMC0/1/3_1.8V"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + ldo6_reg: ldo6 { + regulator-compatible = "LDO6"; + regulator-name = "VMPLL_1.0V"; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + }; + + ldo7_reg: ldo7 { + regulator-compatible = "LDO7"; + regulator-name = "VPLL_1.1V"; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + }; + + ldo8_reg: ldo8 { + regulator-compatible = "LDO8"; + regulator-name = "VDD_MIPI/HDMI_1.0V"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + }; + + ldo9_reg: ldo9 { + regulator-compatible = "LDO9"; + regulator-name = "nc"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + ldo10_reg: ldo10 { + regulator-compatible = "LDO10"; + regulator-name = "VDD_MIPI/HDMI_1.8V"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + ldo11_reg: ldo11 { + regulator-compatible = "LDO11"; + regulator-name = "VDD_ABB1_1.8V"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + ldo12_reg: ldo12 { + regulator-compatible = "LDO12"; + regulator-name = "VDD_UOTG_3.0V"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + }; + + ldo13_reg: ldo13 { + regulator-compatible = "LDO13"; + regulator-name = "VDD_C2C_1.8V"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + ldo14_reg: ldo14 { + regulator-compatible = "LDO14"; + regulator-name = "VDD_ABB02_1.8V"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + ldo15_reg: ldo15 { + regulator-compatible = "LDO15"; + regulator-name = "VDD_HSIC/OTG_1.0V"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + }; + + ldo16_reg: ldo16 { + regulator-compatible = "LDO16"; + regulator-name = "VDD_HSIC_1.8V"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + ldo17_reg: ldo17 { + regulator-compatible = "LDO17"; + regulator-name = "VDDQ_CAM_1.2V"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + }; + + ldo18_reg: ldo18 { + regulator-compatible = "LDO18"; + regulator-name = "nc"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + ldo19_reg: ldo19 { + regulator-compatible = "LDO19"; + regulator-name = "nc"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + ldo20_reg: ldo20 { + regulator-compatible = "LDO20"; + regulator-name = "VDDQ_EMMC_1.8V"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + ldo21_reg: ldo21 { + regulator-compatible = "LDO21"; + regulator-name = "TFLASH_2.8V"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + }; + + ldo22_reg: ldo22 { + regulator-compatible = "LDO22"; + regulator-name = "VDDQ_EMMC_2.8V"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + }; + + ldo23_reg: ldo23 { + regulator-compatible = "LDO23"; + regulator-name = "nc"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + + ldo24_reg: ldo24 { + regulator-compatible = "LDO24"; + regulator-name = "nc"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + }; + + ldo25_reg: ldo25 { + regulator-compatible = "LDO25"; + regulator-name = "VDDQ_LCD_3.0V"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + }; + + ldo26_reg: ldo26 { + regulator-compatible = "LDO26"; + regulator-name = "nc"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + }; + + buck1_reg: buck1 { + regulator-compatible = "BUCK1"; + regulator-name = "VDD_MIF_1.0V"; + regulator-min-microvolt = <8500000>; + regulator-max-microvolt = <1100000>; + }; + + buck2_reg: buck2 { + regulator-compatible = "BUCK2"; + regulator-name = "VDD_ARM_1.0V"; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <1500000>; + }; + + buck3_reg: buck3 { + regulator-compatible = "BUCK3"; + regulator-name = "VDD_INT_1.1V"; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <1150000>; + }; + + buck4_reg: buck4 { + regulator-compatible = "BUCK4"; + regulator-name = "VDD_G3D_1.0V"; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <1150000>; + }; + + buck5_reg: buck5 { + regulator-compatible = "BUCK5"; + regulator-name = "VDDQ_AP_1.2V"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + }; + + buck6_reg: buck6 { + regulator-compatible = "BUCK6"; + regulator-name = "VCC_INL1/7_1.35V"; + regulator-min-microvolt = <1350000>; + regulator-max-microvolt = <1350000>; + }; + + buck7_reg: buck7 { + regulator-compatible = "BUCK7"; + regulator-name = "VCC_INL2/3/5_2.0V"; + regulator-min-microvolt = <2000000>; + regulator-max-microvolt = <2000000>; + }; + + buck8_reg: buck8 { + regulator-compatible = "BUCK8"; + regulator-name = "VCC_P3V3_2.85V"; + regulator-min-microvolt = <2850000>; + regulator-max-microvolt = <3300000>; + }; + + buck9_reg: buck9 { + regulator-compatible = "BUCK9"; + regulator-name = "nc"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + }; + }; }; };
Signature · 1 line
1.9.1
PATCH v3 16/17 odroid: dts: add 'voltage-regulators' description to max77686 node
Quoted 9 lines · Przemyslaw Marczak
Adding regulators subnode to fdt max77686 node, allows properly init regulators by the max77686 regulator driver. This enables the complete functionality of the regulator command.
Signed-off-by Przemyslaw Marczak <[email protected]>---
Changes V2:
- odroid: dts: remove pmic alias
Quoted 5 lines
Changes V3:
- none--- arch/arm/dts/exynos4412-odroid.dts | 247 +++++++++++++++++++++++++++++++++++++ 1 file changed, 247 insertions(+)
PATCH v3 17/17 odroid: config: enable dm pmic, dm regulator and max77686 driver
In reply to Przemyslaw MarczakThis change enables the configs required to init and setup max77686 regulator driver, using the new driver model pmic and regulator API.
This commits enables:
- CONFIG_ERRNO_STR
- CONFIG_DM_PMIC
- CONFIG_DM_PMIC_CMD
- CONFIG_DM_PMIC_MAX77686
- CONFIG_DM_REGULATOR
- CONFIG_DM_REGULATOR_CMD
- CONFIG_DM_REGULATOR_MAX77686
And removes the unused:
- CONFIG_DM_I2C_COMPAT
- CONFIG_POWER
- CONFIG_POWER_I2C
- CONFIG_POWER_MAX77686
---
Changes V2:
- config: enable dm i2c; cleanup
- remove CONFIG_DM_I2C_COMPAT
- enable regulator command
Changes V3:
- move options to defconfig
--- configs/odroid_defconfig | 8 +++++++- include/configs/odroid.h | 5 ----- 2 files changed, 7 insertions(+), 6 deletions(-)
configs/odroid_defconfig +7 -1
@@ -4,5 +4,11 @@ CONFIG_TARGET_ODROID=y CONFIG_OF_CONTROL=y CONFIG_DEFAULT_DEVICE_TREE="exynos4412-odroid" CONFIG_DM_I2C=y -CONFIG_DM_I2C_COMPAT=y # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set +CONFIG_ERRNO_STR=y +CONFIG_DM_PMIC=y +CONFIG_DM_PMIC_CMD=y +CONFIG_DM_PMIC_MAX77686=y +CONFIG_DM_REGULATOR=y +CONFIG_DM_REGULATOR_CMD=y +CONFIG_DM_REGULATOR_MAX77686=y
include/configs/odroid.h +0 -5
@@ -182,11 +182,6 @@#define CONFIG_SYS_I2C_S3C24X0_SPEED 100000#define CONFIG_SYS_I2C_S3C24X0_SLAVE 0 -/* POWER */ -#define CONFIG_POWER -#define CONFIG_POWER_I2C -#define CONFIG_POWER_MAX77686 -/* GPT */ #define CONFIG_RANDOM_UUID
Signature · 1 line
1.9.1
PATCH v3 17/17 odroid: config: enable dm pmic, dm regulator and max77686 driver
Quoted 12 lines · Przemyslaw Marczak
This change enables the configs required to init and setup max77686 regulator driver, using the new driver model pmic and regulator API.
This commits enables:
-CONFIG_ERRNO_STR
-CONFIG_DM_PMIC
-CONFIG_DM_PMIC_CMD
-CONFIG_DM_PMIC_MAX77686
-CONFIG_DM_REGULATOR
-CONFIG_DM_REGULATOR_CMD
-CONFIG_DM_REGULATOR_MAX77686
Quoted 7 lines
And removes the unused:
-CONFIG_DM_I2C_COMPAT
-CONFIG_POWER
-CONFIG_POWER_I2C
-CONFIG_POWER_MAX77686Signed-off-by Przemyslaw Marczak <[email protected]>
(but pelase rename the commands so that they are CONFIG_CMD_DM_PCI and CONFIG_CMD_DM_REGULATOR)
Quoted 49 lines
---
Changes V2:
- config: enable dm i2c; cleanup
- removeCONFIG_DM_I2C_COMPAT
- enable regulator commandChanges V3:
- move options to defconfig--- configs/odroid_defconfig | 8 +++++++- include/configs/odroid.h | 5 ----- 2 files changed, 7 insertions(+), 6 deletions(-)configs/odroid_defconfig +7
-1@@ -4,5 +4,11 @@ CONFIG_TARGET_ODROID=y CONFIG_OF_CONTROL=y CONFIG_DEFAULT_DEVICE_TREE="exynos4412-odroid" CONFIG_DM_I2C=y -CONFIG_DM_I2C_COMPAT=y # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set +CONFIG_ERRNO_STR=y +CONFIG_DM_PMIC=y +CONFIG_DM_PMIC_CMD=y +CONFIG_DM_PMIC_MAX77686=y +CONFIG_DM_REGULATOR=y +CONFIG_DM_REGULATOR_CMD=y +CONFIG_DM_REGULATOR_MAX77686=yinclude/configs/odroid.h +0
-6@@ -182,11 +182,6 @@#define CONFIG_SYS_I2C_S3C24X0_SPEED 100000#define CONFIG_SYS_I2C_S3C24X0_SLAVE 0 -/* POWER */ -#define CONFIG_POWER -#define CONFIG_POWER_I2C -#define CONFIG_POWER_MAX77686 -/* GPT */ #define CONFIG_RANDOM_UUID --1.9.1
PATCH v3 17/17 odroid: config: enable dm pmic, dm regulator and max77686 driver
Hello Simon,
Quoted 19 lines · Simon Glass
Quoted 18 lines · Przemyslaw Marczak
This change enables the configs required to init and setup max77686 regulator driver, using the new driver model pmic and regulator API.
This commits enables:
-CONFIG_ERRNO_STR
-CONFIG_DM_PMIC
-CONFIG_DM_PMIC_CMD
-CONFIG_DM_PMIC_MAX77686
-CONFIG_DM_REGULATOR
-CONFIG_DM_REGULATOR_CMD
-CONFIG_DM_REGULATOR_MAX77686And removes the unused:
-CONFIG_DM_I2C_COMPAT
-CONFIG_POWER
-CONFIG_POWER_I2C
-CONFIG_POWER_MAX77686
Quoted 7 lines
Quoted 1 line
Signed-off-by Przemyslaw Marczak <[email protected]>Acked-by Simon Glass <[email protected]>(but pelase rename the commands so that they are
CONFIG_CMD_DM_PCIandCONFIG_CMD_DM_REGULATOR)
Yes, will do this.
Quoted 46 lines
Quoted 46 lines
---
Changes V2:
- config: enable dm i2c; cleanup
- removeCONFIG_DM_I2C_COMPAT
- enable regulator commandChanges V3:
- move options to defconfig--- configs/odroid_defconfig | 8 +++++++- include/configs/odroid.h | 5 ----- 2 files changed, 7 insertions(+), 6 deletions(-)configs/odroid_defconfig +7
-1@@ -4,5 +4,11 @@ CONFIG_TARGET_ODROID=y CONFIG_OF_CONTROL=y CONFIG_DEFAULT_DEVICE_TREE="exynos4412-odroid" CONFIG_DM_I2C=y -CONFIG_DM_I2C_COMPAT=y # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set +CONFIG_ERRNO_STR=y +CONFIG_DM_PMIC=y +CONFIG_DM_PMIC_CMD=y +CONFIG_DM_PMIC_MAX77686=y +CONFIG_DM_REGULATOR=y +CONFIG_DM_REGULATOR_CMD=y +CONFIG_DM_REGULATOR_MAX77686=yinclude/configs/odroid.h +0
-5@@ -182,11 +182,6 @@#define CONFIG_SYS_I2C_S3C24X0_SPEED 100000#define CONFIG_SYS_I2C_S3C24X0_SLAVE 0 -/* POWER */ -#define CONFIG_POWER -#define CONFIG_POWER_I2C -#define CONFIG_POWER_MAX77686 -/* GPT */ #define CONFIG_RANDOM_UUID
Quoted 4 lines
Quoted 3 lines
--
1.9.1
Thanks,
Signature · 4 lines
Przemyslaw Marczak Samsung R&D Institute Poland Samsung Electronics p.marczak at samsung.com
v3 cover Power(full) framework based on Driver Model
In reply to Przemyslaw MarczakHello,
Quoted 65 lines · Przemyslaw Marczak
Hello,
Here is the third RFC version of the new PMIC framework.Big thanks to Simon Glass, your comments were really helpful, and I think, that this version is much more better to discuss, than the previous. The changes made in this version are described below each commit. Sorry that I didn't reply to each patch, I agreed with most and just started the work.Best regards
Przemyslaw Marczak (17):
exynos5: fix build break by addingCONFIG_POWER
fdt_ro.c: add new function:fdt_node_check_prop_compatible()
dm: core:lists.c: add new functionlists_bind_fdt_by_prop()
lib:Kconfig: add entry forerrno_str()function
dm: pmic: add implementation of driver model pmic uclass
dm: regulator: add implementation of driver model regulator uclass
dm: pmic: add pmic command
dm: regulator: add regulator command
pmic: max77686 set the same compatible as in the kernel
dm: pmic: add max77686 pmic driver
dm: regulator: add max77686 regulator driver
dm: regulator: add fixed voltage regulator driver
doc: driver-model: pmic and regulator uclass documentation
dm: board:samsung:power_init_board: add requirement ofCONFIG_DM_PMIC
odroid: board: add support to dm pmic api
odroid: dts: add 'voltage-regulators' description to max77686 node
odroid: config: enable dm pmic, dm regulator and max77686 driverMakefile | 1 + arch/arm/dts/exynos4412-odroid.dts | 249 +++++++++- arch/arm/dts/exynos4412-trats2.dts | 2 +- arch/arm/dts/exynos5250-smdk5250.dts | 2 +- arch/arm/dts/exynos5250-snow.dts | 2 +- board/samsung/common/board.c | 4 +- board/samsung/common/misc.c | 1 + board/samsung/odroid/odroid.c | 113 ++++- common/Kconfig | 36 ++ common/Makefile | 4 + common/cmd_pmic.c | 210 +++++++++ common/cmd_regulator.c | 385 +++++++++++++++ configs/odroid_defconfig | 8 +- doc/driver-model/pmic-framework.txt | 350 ++++++++++++++ drivers/core/lists.c | 28 +- drivers/power/Kconfig | 124 ++++- drivers/power/Makefile | 3 +- drivers/power/pmic-uclass.c | 130 ++++++ drivers/power/pmic/Makefile | 1 + drivers/power/pmic/max77686.c | 76 +++ drivers/power/pmic/pmic_max77686.c | 2 +- drivers/power/regulator-uclass.c | 219 +++++++++ drivers/power/regulator/Makefile | 9 + drivers/power/regulator/fixed.c | 124 +++++ drivers/power/regulator/max77686.c | 876 +++++++++++++++++++++++++++++++++++ include/configs/exynos5-common.h | 4 + include/configs/odroid.h | 5 - include/dm/lists.h | 18 + include/dm/uclass-id.h | 4 + include/libfdt.h | 27 ++ include/power/max77686_pmic.h | 26 +- include/power/pmic.h | 210 +++++++++ include/power/regulator.h | 259 +++++++++++ lib/Kconfig | 8 + lib/fdtdec.c | 2 +- lib/libfdt/fdt_ro.c | 14 +- 36 files changed, 3481 insertions(+), 55 deletions(-)
Quoted 11 lines
create mode 100644
common/cmd_pmic.c
create mode 100644common/cmd_regulator.ccreate mode 100644doc/driver-model/pmic-framework.txtcreate mode 100644drivers/power/pmic-uclass.ccreate mode 100644drivers/power/pmic/max77686.ccreate mode 100644drivers/power/regulator-uclass.ccreate mode 100644drivers/power/regulator/Makefilecreate mode 100644drivers/power/regulator/fixed.ccreate mode 100644drivers/power/regulator/max77686.ccreate mode 100644include/power/regulator.h
This patchset is available at:
https://github.com/bobenstein/u-boot
branch: dm-pmic-v3
Best regards,
Signature · 4 lines
Przemyslaw Marczak Samsung R&D Institute Poland Samsung Electronics p.marczak at samsung.com
v3 cover Power(full) framework based on Driver Model
In reply to Przemyslaw MarczakHi Przemyslaw,
Quoted 6 lines · Przemyslaw Marczak
Hello,
Here is the third RFC version of the new PMIC framework.Big thanks to Simon Glass, your comments were really helpful, and I think, that this version is much more better to discuss, than the previous. The changes made in this version are described below each commit. Sorry that I didn't reply to each patch, I agreed with most and just started the work.
This is looking really good. Here are a few overall comments.
1. There is one oddity that I'd like to address before merging.
I don't think the fdt_node_check_prop_compatible() is a good idea, nor necessary. I don't think we should consider the regulator-compatible property to be a compatible string. It has values like LDO8, LDO9 and these don't look like compatible strings, which are normally unique and point to a driver. Here they point to a particular device.
A similar problem is faced in pinctrl and if you look at gpio_exynos_bind() you will see that it works through the sub-nodes, creating devices as needed.
I don't think using udevice_id is right here either.
Here is my suggestion:
a. Create a new structure like this:
struct pmic_child_info {
const char *prefix; // "LDO" or "BUCK"
const char *driver_name; // "max77686_ldo" or "max77686_buck"
};
b. Pass a list of these to pmic_child_node_scan(). In your case there will be three entries, one for LDO, one for BUCK, plus a NULL termination entry,
c. It can work through the subnodes looking for the given prefixes. It then calls device_bind_driver() on each. Then it changes the returned device's of_data to hold the correct value (obtained with strtol() on the part of the name that follows the prefix - e.g. 17 for "LDO17"). This will be easier if you rebase on u-boot-dm/usb-working, where the data is just a long, not a device tree pointer.
d. Now you have the same effect as before, but you can drop the tables like max77686_ldo_ids[] and avoid misappropriating driver model's device lookup.
2. Should we put the regulator stuff in drivers/regulator, as with Linux?
3. Can you please bring in the regulator and pmic device tree binding files, plus max77686?
4. We really do need tests! I suspect that you could create a sandbox I2C pmic that has a few registers and regulators. See i2c_eeprom_emul.c for a basic example. Then you can write some tests that find the pmi,c find the regulator, read and write a few registers, and read and write a few regulators. That would be enough test coverage to get us started. I know this is different from previous U-Boot policy, but tests are a big win during development and also for years to come (as people can change the framework and have some confidence that they did not break anything).
It can be a follow-on patch separate from your series but I'm really not keen on bringing in a major new driver model framework with no tests. If you are struggling for time, let me know and I can try to help by writing a sandbox I2C PMIC for example.
Regards,
Simon
Quoted 73 lines
Best regards
Przemyslaw Marczak (17):
exynos5: fix build break by addingCONFIG_POWER
fdt_ro.c: add new function:fdt_node_check_prop_compatible()
dm: core:lists.c: add new functionlists_bind_fdt_by_prop()
lib:Kconfig: add entry forerrno_str()function
dm: pmic: add implementation of driver model pmic uclass
dm: regulator: add implementation of driver model regulator uclass
dm: pmic: add pmic command
dm: regulator: add regulator command
pmic: max77686 set the same compatible as in the kernel
dm: pmic: add max77686 pmic driver
dm: regulator: add max77686 regulator driver
dm: regulator: add fixed voltage regulator driver
doc: driver-model: pmic and regulator uclass documentation
dm: board:samsung:power_init_board: add requirement ofCONFIG_DM_PMIC
odroid: board: add support to dm pmic api
odroid: dts: add 'voltage-regulators' description to max77686 node
odroid: config: enable dm pmic, dm regulator and max77686 driverMakefile | 1 + arch/arm/dts/exynos4412-odroid.dts | 249 +++++++++- arch/arm/dts/exynos4412-trats2.dts | 2 +- arch/arm/dts/exynos5250-smdk5250.dts | 2 +- arch/arm/dts/exynos5250-snow.dts | 2 +- board/samsung/common/board.c | 4 +- board/samsung/common/misc.c | 1 + board/samsung/odroid/odroid.c | 113 ++++- common/Kconfig | 36 ++ common/Makefile | 4 + common/cmd_pmic.c | 210 +++++++++ common/cmd_regulator.c | 385 +++++++++++++++ configs/odroid_defconfig | 8 +- doc/driver-model/pmic-framework.txt | 350 ++++++++++++++ drivers/core/lists.c | 28 +- drivers/power/Kconfig | 124 ++++- drivers/power/Makefile | 3 +- drivers/power/pmic-uclass.c | 130 ++++++ drivers/power/pmic/Makefile | 1 + drivers/power/pmic/max77686.c | 76 +++ drivers/power/pmic/pmic_max77686.c | 2 +- drivers/power/regulator-uclass.c | 219 +++++++++ drivers/power/regulator/Makefile | 9 + drivers/power/regulator/fixed.c | 124 +++++ drivers/power/regulator/max77686.c | 876 +++++++++++++++++++++++++++++++++++ include/configs/exynos5-common.h | 4 + include/configs/odroid.h | 5 - include/dm/lists.h | 18 + include/dm/uclass-id.h | 4 + include/libfdt.h | 27 ++ include/power/max77686_pmic.h | 26 +- include/power/pmic.h | 210 +++++++++ include/power/regulator.h | 259 +++++++++++ lib/Kconfig | 8 + lib/fdtdec.c | 2 +- lib/libfdt/fdt_ro.c | 14 +- 36 files changed, 3481 insertions(+), 55 deletions(-) create mode 100644 common/cmd_pmic.c create mode 100644 common/cmd_regulator.c create mode 100644 doc/driver-model/pmic-framework.txt create mode 100644 drivers/power/pmic-uclass.c create mode 100644 drivers/power/pmic/max77686.c create mode 100644 drivers/power/regulator-uclass.c create mode 100644 drivers/power/regulator/Makefile create mode 100644 drivers/power/regulator/fixed.c create mode 100644 drivers/power/regulator/max77686.c create mode 100644 include/power/regulator.h--
1.9.1
v3 cover Power(full) framework based on Driver Model
Hello Simon,
Quoted 12 lines · Simon Glass
Hi Przemyslaw,
Quoted 6 lines · Przemyslaw Marczak
Hello,
Here is the third RFC version of the new PMIC framework.Big thanks to Simon Glass, your comments were really helpful, and I think, that this version is much more better to discuss, than the previous. The changes made in this version are described below each commit. Sorry that I didn't reply to each patch, I agreed with most and just started the work.This is looking really good. Here are a few overall comments.
Quoted 8 lines
1. There is one oddity that I'd like to address before merging.
I don't think the
fdt_node_check_prop_compatible()is a good idea, nor necessary. I don't think we should consider the regulator-compatible property to be a compatible string. It has values like LDO8, LDO9 and these don't look like compatible strings, which are normally unique and point to a driver. Here they point to a particular device.
Right, those compatibles don't point to a driver. This is a specific case of use from the kernel.
Quoted 6 lines
A similar problem is faced in pinctrl and if you look at
gpio_exynos_bind()you will see that it works through the sub-nodes, creating devices as needed.I don't think using
udevice_idis right here either.
Yes, I know how it's done. But we haven't the compatibles for each GPIO as for the regulators, and each GPIO driver, bind the childs by its own implementation.
I tried to reuse the existing code. It was nice, but I missed one thing...if there are more, than one driver with the same e.g. "LDO1" compatible, then the first one will bind - and it could be the wrong one...
But, it could be tune-up, to get the right drivers list by arg.
Quoted 4 lines
Here is my suggestion:
a. Create a new structure like this:
Quoted 9 lines
struct
pmic_child_info{
const char *prefix; // "LDO" or "BUCK"
const char*driver_name; // "max77686_ldo" or "max77686_buck"
};b. Pass a list of these to
pmic_child_node_scan(). In your case there will be three entries, one for LDO, one for BUCK, plus a NULL termination entry,
Ok, this could be good.
Quoted 6 lines
c. It can work through the subnodes looking for the given prefixes. It then calls
device_bind_driver()on each. Then it changes the returned device'sof_datato hold the correct value (obtained withstrtol()on the part of the name that follows the prefix - e.g. 17 for "LDO17"). This will be easier if you rebase on u-boot-dm/usb-working, where the data is just a long, not a device tree pointer.
Yes, it's easy. I made something like this in the first version of this patchset, to parse the nodes and fill the max77686 regulator descriptors in function get_desc_for_compat(), from this patch:
http://lists.denx.de/pipermail/u-boot/2014-October/191024.html
Quoted 4 lines
d. Now you have the same effect as before, but you can drop the tables like max77686_ldo_ids[] and avoid misappropriating driver model's device lookup.
Yes, this is an advantage.
I wonder about the usage of "struct udevice_id", which should contain the data, defined only by the driver, right?
In the method you mentioned, we bind the pmic childs and then we modify the "dev->of_id->data" by putting the regulator number from matched prefix in it.
This is ok, but I think, that the second part of this idea should be done by the driver. I think, that the external function shouldn't modify this driver data on bind.
This could be solved by leave this job for the device driver. For example on max77686, we could leave the dev->of_id as null and use dev->priv for the node prefix id.
So, it's not a big problem.
Here, I would like mention the problem with the regulator_get() by name, for which we want use the "regulator-name" constraint.
For this version, it requires probing of all regulator devices, since it uses the dev->uclass_priv, which I think, is a good place to provide the framework-specific structure type for regulator constraints and mode descriptors.
What about moving it back to dev->platdata? Then:
- the structure type: "dm_regulator_info", will move to "dm_regulator_platdata"
- only its .name field could be assigned at regulator bind stage from the "regulator-name" constraint
- the bind could fail, when the constraint name not found
- the rest of constraints will assign in .ofdata_to_platdata() function call as it is at the present version
Then, we also don't need probe each regulator device, when using regulator_get() function.
Quoted 2 lines
2. Should we put the regulator stuff in
drivers/regulator, as with Linux?
I will do this in the next version.
Quoted 3 lines
3. Can you please bring in the regulator and pmic device tree binding files, plus max77686?
Right, I forgot about this.
Quoted 11 lines
4. We really do need tests! I suspect that you could create a sandbox I2C pmic that has a few registers and regulators. See
i2c_eeprom_emul.cfor a basic example. Then you can write some tests that find the pmi,c find the regulator, read and write a few registers, and read and write a few regulators. That would be enough test coverage to get us started. I know this is different from previous U-Boot policy, but tests are a big win during development and also for years to come (as people can change the framework and have some confidence that they did not break anything).
Quoted 8 lines
It can be a follow-on patch separate from your series but I'm really not keen on bringing in a major new driver model framework with no tests. If you are struggling for time, let me know and I can try to help by writing a sandbox I2C PMIC for example.
Regards,
Simon
Ok, I will add sandbox drivers for this all, but first let's prepare the final patchset version of this framework, and then I will send a separate patchset for sandbox before merge of this part.
Quoted 70 lines
Quoted 70 lines
Best regards
Przemyslaw Marczak (17):
exynos5: fix build break by addingCONFIG_POWER
fdt_ro.c: add new function:fdt_node_check_prop_compatible()
dm: core:lists.c: add new functionlists_bind_fdt_by_prop()
lib:Kconfig: add entry forerrno_str()function
dm: pmic: add implementation of driver model pmic uclass
dm: regulator: add implementation of driver model regulator uclass
dm: pmic: add pmic command
dm: regulator: add regulator command
pmic: max77686 set the same compatible as in the kernel
dm: pmic: add max77686 pmic driver
dm: regulator: add max77686 regulator driver
dm: regulator: add fixed voltage regulator driver
doc: driver-model: pmic and regulator uclass documentation
dm: board:samsung:power_init_board: add requirement ofCONFIG_DM_PMIC
odroid: board: add support to dm pmic api
odroid: dts: add 'voltage-regulators' description to max77686 node
odroid: config: enable dm pmic, dm regulator and max77686 driverMakefile | 1 + arch/arm/dts/exynos4412-odroid.dts | 249 +++++++++- arch/arm/dts/exynos4412-trats2.dts | 2 +- arch/arm/dts/exynos5250-smdk5250.dts | 2 +- arch/arm/dts/exynos5250-snow.dts | 2 +- board/samsung/common/board.c | 4 +- board/samsung/common/misc.c | 1 + board/samsung/odroid/odroid.c | 113 ++++- common/Kconfig | 36 ++ common/Makefile | 4 + common/cmd_pmic.c | 210 +++++++++ common/cmd_regulator.c | 385 +++++++++++++++ configs/odroid_defconfig | 8 +- doc/driver-model/pmic-framework.txt | 350 ++++++++++++++ drivers/core/lists.c | 28 +- drivers/power/Kconfig | 124 ++++- drivers/power/Makefile | 3 +- drivers/power/pmic-uclass.c | 130 ++++++ drivers/power/pmic/Makefile | 1 + drivers/power/pmic/max77686.c | 76 +++ drivers/power/pmic/pmic_max77686.c | 2 +- drivers/power/regulator-uclass.c | 219 +++++++++ drivers/power/regulator/Makefile | 9 + drivers/power/regulator/fixed.c | 124 +++++ drivers/power/regulator/max77686.c | 876 +++++++++++++++++++++++++++++++++++ include/configs/exynos5-common.h | 4 + include/configs/odroid.h | 5 - include/dm/lists.h | 18 + include/dm/uclass-id.h | 4 + include/libfdt.h | 27 ++ include/power/max77686_pmic.h | 26 +- include/power/pmic.h | 210 +++++++++ include/power/regulator.h | 259 +++++++++++ lib/Kconfig | 8 + lib/fdtdec.c | 2 +- lib/libfdt/fdt_ro.c | 14 +- 36 files changed, 3481 insertions(+), 55 deletions(-)create mode 100644
common/cmd_pmic.c
create mode 100644common/cmd_regulator.ccreate mode 100644doc/driver-model/pmic-framework.txtcreate mode 100644drivers/power/pmic-uclass.ccreate mode 100644drivers/power/pmic/max77686.ccreate mode 100644drivers/power/regulator-uclass.ccreate mode 100644drivers/power/regulator/Makefilecreate mode 100644drivers/power/regulator/fixed.ccreate mode 100644drivers/power/regulator/max77686.ccreate mode 100644include/power/regulator.h
Quoted 4 lines
Quoted 3 lines
--
1.9.1
Thank you again for the review!
I will send the next version probably on 7-8-th April.
Best regards,
Signature · 4 lines
Przemyslaw Marczak Samsung R&D Institute Poland Samsung Electronics p.marczak at samsung.com
v3 cover Power(full) framework based on Driver Model
Hi Przemyslaw,
Quoted 72 lines · Przemyslaw Marczak
Hello Simon,
Quoted 16 lines · Simon Glass
Hi Przemyslaw,
Quoted 7 lines · Przemyslaw Marczak
Hello,
Here is the third RFC version of the new PMIC framework.Big thanks to Simon Glass, your comments were really helpful, and I think, that this version is much more better to discuss, than the previous. The changes made in this version are described below each commit. Sorry that I didn't reply to each patch, I agreed with most and just started the work.This is looking really good. Here are a few overall comments.
Quoted 8 lines
1. There is one oddity that I'd like to address before merging.
I don't think the
fdt_node_check_prop_compatible()is a good idea, nor necessary. I don't think we should consider the regulator-compatible property to be a compatible string. It has values like LDO8, LDO9 and these don't look like compatible strings, which are normally unique and point to a driver. Here they point to a particular device.Right, those compatibles don't point to a driver. This is a specific case of use from the kernel.
Quoted 6 lines
A similar problem is faced in pinctrl and if you look at
gpio_exynos_bind()you will see that it works through the sub-nodes, creating devices as needed.I don't think using
udevice_idis right here either.Yes, I know how it's done. But we haven't the compatibles for each GPIO as for the regulators, and each GPIO driver, bind the childs by its own implementation.
I tried to reuse the existing code. It was nice, but I missed one thing...if there are more, than one driver with the same e.g. "LDO1" compatible, then the first one will bind - and it could be the wrong one...
But, it could be tune-up, to get the right drivers list by arg.
Quoted 4 lines
Here is my suggestion:
a. Create a new structure like this:
Quoted 9 lines
struct
pmic_child_info{
const char *prefix; // "LDO" or "BUCK"
const char*driver_name; // "max77686_ldo" or "max77686_buck"
};b. Pass a list of these to
pmic_child_node_scan(). In your case there will be three entries, one for LDO, one for BUCK, plus a NULL termination entry,Ok, this could be good.
Quoted 6 lines
c. It can work through the subnodes looking for the given prefixes. It then calls
device_bind_driver()on each. Then it changes the returned device'sof_datato hold the correct value (obtained withstrtol()on the part of the name that follows the prefix - e.g. 17 for "LDO17"). This will be easier if you rebase on u-boot-dm/usb-working, where the data is just a long, not a device tree pointer.
Quoted 5 lines
Yes, it's easy. I made something like this in the first version of this patchset, to parse the nodes and fill the max77686 regulator descriptors in function
get_desc_for_compat(), from this patch:
http://lists.denx.de/pipermail/u-boot/2014-October/191024.html
Yes I see.
Quoted 19 lines
Quoted 4 lines
d. Now you have the same effect as before, but you can drop the tables like max77686_ldo_ids[] and avoid misappropriating driver model's device lookup.
Yes, this is an advantage.
I wonder about the usage of "struct
udevice_id", which should contain the data, defined only by the driver, right?In the method you mentioned, we bind the pmic childs and then we modify the "
dev->of_id->data" by putting the regulator number from matched prefix in it.This is ok, but I think, that the second part of this idea should be done by the driver. I think, that the external function shouldn't modify this driver data on bind.
Quoted 5 lines
This could be solved by leave this job for the device driver. For example on max77686, we could leave the
dev->of_idas null and usedev->privfor the node prefix id.So, it's not a big problem.
As I see it the regulator number (e.g. 1 for LDO1, 3 for BUCK3) is picked up from the name string, so it feels like this is common code. You would be calling a helper function from the driver, so yes you can always have it return the regulator number, and then store it in driver_data in the driver.
But you should rebase on dm/usb-working to get the new driver_data member of struct udevice.
My only concern with using driver_data is that this is normally used to specify the device type where the driver supports multiple hardware variants. The regulator number is more correctly considered to be platform data. This leads on to your point below.
Quoted 17 lines
Here, I would like mention the problem with the
regulator_get()by name, for which we want use the "regulator-name" constraint.For this version, it requires probing of all regulator devices, since it uses the
dev->uclass_priv, which I think, is a good place to provide the framework-specific structure type for regulator constraints and mode descriptors.What about moving it back to
dev->platdata? Then:
- the structure type: "dm_regulator_info", will move to "dm_regulator_platdata"- only its .name field could be assigned at regulator bind stage from the "regulator-name" constraint
Quoted 7 lines
- the bind could fail, when the constraint name not found
- the rest of constraints will assign in .ofdata_to_platdata() function call as it is at the present version
Then, we also don't need probe each regulator device, when using
regulator_get()function.
Here is my understanding on this one:
The regulator name is the device name, so looking up by name should be easy. It just involves scanning through the regulator uclass comparing device names.
Based on what you said above, the regulator number should go in platform data for the regulator as you say. It can be worked out when the PMIC is bound (perhaps in the PMIC uclass' post_bind method).
The idea is that the PMIC is responsible for binding its children so that at start-up we know about all the regulators and can find them, even through none is probed yet.
Quoted 30 lines
Quoted 3 lines
2. Should we put the regulator stuff in
drivers/regulator, as with Linux?I will do this in the next version.
Quoted 3 lines
3. Can you please bring in the regulator and pmic device tree binding files, plus max77686?
Right, I forgot about this.
Quoted 16 lines
4. We really do need tests! I suspect that you could create a sandbox I2C pmic that has a few registers and regulators. See
i2c_eeprom_emul.cfor a basic example. Then you can write some tests that find the pmi,c find the regulator, read and write a few registers, and read and write a few regulators. That would be enough test coverage to get us started. I know this is different from previous U-Boot policy, but tests are a big win during development and also for years to come (as people can change the framework and have some confidence that they did not break anything).It can be a follow-on patch separate from your series but I'm really not keen on bringing in a major new driver model framework with no tests. If you are struggling for time, let me know and I can try to help by writing a sandbox I2C PMIC for example.
Quoted 7 lines
Quoted 3 lines
Regards,
SimonOk, I will add sandbox drivers for this all, but first let's prepare the final patchset version of this framework, and then I will send a separate patchset for sandbox before merge of this part.
OK sounds good.
Quoted 73 lines
Quoted 73 lines
Quoted 73 lines
Best regards
Przemyslaw Marczak (17):
exynos5: fix build break by addingCONFIG_POWER
fdt_ro.c: add new function:fdt_node_check_prop_compatible()
dm: core:lists.c: add new functionlists_bind_fdt_by_prop()
lib:Kconfig: add entry forerrno_str()function
dm: pmic: add implementation of driver model pmic uclass
dm: regulator: add implementation of driver model regulator uclass
dm: pmic: add pmic command
dm: regulator: add regulator command
pmic: max77686 set the same compatible as in the kernel
dm: pmic: add max77686 pmic driver
dm: regulator: add max77686 regulator driver
dm: regulator: add fixed voltage regulator driver
doc: driver-model: pmic and regulator uclass documentation
dm: board:samsung:power_init_board: add requirement ofCONFIG_DM_PMIC
odroid: board: add support to dm pmic api
odroid: dts: add 'voltage-regulators' description to max77686 node
odroid: config: enable dm pmic, dm regulator and max77686 driverMakefile | 1 + arch/arm/dts/exynos4412-odroid.dts | 249 +++++++++- arch/arm/dts/exynos4412-trats2.dts | 2 +- arch/arm/dts/exynos5250-smdk5250.dts | 2 +- arch/arm/dts/exynos5250-snow.dts | 2 +- board/samsung/common/board.c | 4 +- board/samsung/common/misc.c | 1 + board/samsung/odroid/odroid.c | 113 ++++- common/Kconfig | 36 ++ common/Makefile | 4 + common/cmd_pmic.c | 210 +++++++++ common/cmd_regulator.c | 385 +++++++++++++++ configs/odroid_defconfig | 8 +- doc/driver-model/pmic-framework.txt | 350 ++++++++++++++ drivers/core/lists.c | 28 +- drivers/power/Kconfig | 124 ++++- drivers/power/Makefile | 3 +- drivers/power/pmic-uclass.c | 130 ++++++ drivers/power/pmic/Makefile | 1 + drivers/power/pmic/max77686.c | 76 +++ drivers/power/pmic/pmic_max77686.c | 2 +- drivers/power/regulator-uclass.c | 219 +++++++++ drivers/power/regulator/Makefile | 9 + drivers/power/regulator/fixed.c | 124 +++++ drivers/power/regulator/max77686.c | 876 +++++++++++++++++++++++++++++++++++ include/configs/exynos5-common.h | 4 + include/configs/odroid.h | 5 - include/dm/lists.h | 18 + include/dm/uclass-id.h | 4 + include/libfdt.h | 27 ++ include/power/max77686_pmic.h | 26 +- include/power/pmic.h | 210 +++++++++ include/power/regulator.h | 259 +++++++++++ lib/Kconfig | 8 + lib/fdtdec.c | 2 +- lib/libfdt/fdt_ro.c | 14 +- 36 files changed, 3481 insertions(+), 55 deletions(-)create mode 100644
common/cmd_pmic.c
create mode 100644common/cmd_regulator.ccreate mode 100644doc/driver-model/pmic-framework.txtcreate mode 100644drivers/power/pmic-uclass.ccreate mode 100644drivers/power/pmic/max77686.ccreate mode 100644drivers/power/regulator-uclass.ccreate mode 100644drivers/power/regulator/Makefilecreate mode 100644drivers/power/regulator/fixed.ccreate mode 100644drivers/power/regulator/max77686.ccreate mode 100644include/power/regulator.h
Quoted 7 lines
Quoted 4 lines
Quoted 3 lines
--
1.9.1Thank you again for the review!
I will send the next version probably on 7-8-th April.
Regards,
Simon
v4 cover Power(full) framework based on Driver Model
In reply to Przemyslaw MarczakHello,
Again the next version. The changes are described below each commit message. This is rebased on last u-boot-dm/master after apply this patchset:
https://patchwork.ozlabs.org/patch/462775/
https://patchwork.ozlabs.org/patch/462777/
https://patchwork.ozlabs.org/patch/462776/
This all can be found in here:
https://github.com/bobenstein/u-boot/tree/dm-pmic-v4
Best regards,
Przemyslaw Marczak (16):
exynos5: fix build break by adding CONFIG_POWER
exynos4-common: remove the unsued CONFIG_CMD_PMIC
lib: Kconfig: add entry for errno_str() function
dm: pmic: add implementation of driver model pmic uclass
dm: regulator: add implementation of driver model regulator uclass
dm: pmic: add pmic command
dm: regulator: add regulator command
pmic: max77686 set the same compatible as in the kernel
dm: pmic: add max77686 pmic driver
dm: regulator: add max77686 regulator driver
dm: regulator: add fixed voltage regulator driver
doc: driver-model: pmic and regulator uclass documentation
dm: board:samsung: power_init_board: add requirement of CONFIG_DM_PMIC
odroid: board: add support to dm pmic api
odroid: dts: add 'voltage-regulators' description to max77686 node
odroid: config: enable dm pmic, dm regulator and max77686 driver
Makefile | 3 +- arch/arm/dts/exynos4412-odroid.dts | 255 ++++++- arch/arm/dts/exynos4412-trats2.dts | 2 +- arch/arm/dts/exynos5250-smdk5250.dts | 2 +- arch/arm/dts/exynos5250-snow.dts | 2 +- board/samsung/common/board.c | 4 +- board/samsung/common/misc.c | 1 + board/samsung/odroid/odroid.c | 77 ++- common/Kconfig | 36 + common/Makefile | 4 + common/cmd_pmic.c | 231 +++++++ common/cmd_regulator.c | 403 +++++++++++ configs/odroid_defconfig | 8 +- doc/device-tree-bindings/pmic/max77686.txt | 36 + doc/device-tree-bindings/regulator/fixed.txt | 38 ++ doc/device-tree-bindings/regulator/max77686.txt | 70 ++ doc/device-tree-bindings/regulator/regulator.txt | 55 ++ doc/driver-model/pmic-framework.txt | 142 ++++ drivers/power/Kconfig | 8 + drivers/power/Makefile | 1 - drivers/power/pmic/Kconfig | 18 + drivers/power/pmic/Makefile | 2 + drivers/power/pmic/max77686.c | 87 +++ drivers/power/pmic/pmic-uclass.c | 158 +++++ drivers/power/pmic/pmic_max77686.c | 2 +- drivers/power/regulator/Kconfig | 33 + drivers/power/regulator/Makefile | 10 + drivers/power/regulator/fixed.c | 126 ++++ drivers/power/regulator/max77686.c | 825 +++++++++++++++++++++++ drivers/power/regulator/regulator-uclass.c | 300 +++++++++ include/configs/exynos4-common.h | 1 - include/configs/exynos5-common.h | 4 + include/configs/odroid.h | 5 - include/dm/uclass-id.h | 4 + include/power/max77686_pmic.h | 29 +- include/power/pmic.h | 189 ++++++ include/power/regulator.h | 384 +++++++++++ lib/Kconfig | 8 + lib/fdtdec.c | 2 +- 39 files changed, 3512 insertions(+), 53 deletions(-) create mode 100644 common/cmd_pmic.c create mode 100644 common/cmd_regulator.c create mode 100644 doc/device-tree-bindings/pmic/max77686.txt create mode 100644 doc/device-tree-bindings/regulator/fixed.txt create mode 100644 doc/device-tree-bindings/regulator/max77686.txt create mode 100644 doc/device-tree-bindings/regulator/regulator.txt create mode 100644 doc/driver-model/pmic-framework.txt create mode 100644 drivers/power/pmic/Kconfig create mode 100644 drivers/power/pmic/max77686.c create mode 100644 drivers/power/pmic/pmic-uclass.c create mode 100644 drivers/power/regulator/Kconfig create mode 100644 drivers/power/regulator/Makefile create mode 100644 drivers/power/regulator/fixed.c create mode 100644 drivers/power/regulator/max77686.c create mode 100644 drivers/power/regulator/regulator-uclass.c create mode 100644 include/power/regulator.h
Signature · 1 line
1.9.1
PATCH v4 1/16 exynos5: fix build break by adding CONFIG_POWER
Move the configs listed below from exynos5-dt-common.h to exynos5-common.h:
- CONFIG_POWER
- CONFIG_POWER_I2C
fixes build break for Arndale and Smdk5250 boards.
--- include/configs/exynos5-common.h | 4 ++++ 1 file changed, 4 insertions(+)
include/configs/exynos5-common.h +4 -0
@@ -149,6 +149,10 @@#define CONFIG_OF_SPI #endif +/* Power */ +#define CONFIG_POWER +#define CONFIG_POWER_I2C +#ifdef CONFIG_ENV_IS_IN_SPI_FLASH #define CONFIG_ENV_SPI_MODE SPI_MODE_0#define CONFIG_ENV_SECT_SIZE CONFIG_ENV_SIZE
Signature · 1 line
1.9.1
PATCH v4 1/16 exynos5: fix build break by adding CONFIG_POWER
Quoted 10 lines · Przemyslaw Marczak
Move the configs listed below from
exynos5-dt-common.htoexynos5-common.h:
-CONFIG_POWER
-CONFIG_POWER_I2C
fixes build break for Arndale and Smdk5250 boards.Signed-off-by Przemyslaw Marczak <[email protected]>--- include/configs/exynos5-common.h | 4 ++++ 1 file changed, 4 insertions(+)
PATCH v4 1/16 exynos5: fix build break by adding CONFIG_POWER
Quoted 7 lines · Simon Glass
Quoted 6 lines · Przemyslaw Marczak
Move the configs listed below from
exynos5-dt-common.htoexynos5-common.h:
-CONFIG_POWER
-CONFIG_POWER_I2C
fixes build break for Arndale and Smdk5250 boards.
Quoted 6 lines
Quoted 4 lines
Signed-off-by Przemyslaw Marczak <[email protected]>--- include/configs/exynos5-common.h | 4 ++++ 1 file changed, 4 insertions(+)Acked-by Simon Glass <[email protected]>
Applied to u-boot-dm/next, thanks!
PATCH v4 2/16 exynos4-common: remove the unsued CONFIG_CMD_PMIC
In reply to Przemyslaw MarczakThis config name was never used, because the present pmic command was precompiled for the CONFIG_POWER.
--- include/configs/exynos4-common.h | 1 - 1 file changed, 1 deletion(-)
include/configs/exynos4-common.h +0 -1
@@ -31,7 +31,6 @@#undef CONFIG_CMD_MTDPARTS#define CONFIG_CMD_DFU #define CONFIG_CMD_GPT -#define CONFIG_CMD_PMIC #define CONFIG_CMD_SETEXPR /* USB Composite download gadget - g_dnl */
Signature · 1 line
1.9.1
PATCH v4 2/16 exynos4-common: remove the unsued CONFIG_CMD_PMIC
Quoted 7 lines · Przemyslaw Marczak
This config name was never used, because the present pmic command was precompiled for the
CONFIG_POWER.Signed-off-by Przemyslaw Marczak <[email protected]>--- include/configs/exynos4-common.h | 1 - 1 file changed, 1 deletion(-)
PATCH v4 2/16 exynos4-common: remove the unsued CONFIG_CMD_PMIC
Quoted 10 lines · Simon Glass
Quoted 7 lines · Przemyslaw Marczak
This config name was never used, because the present pmic command was precompiled for the
CONFIG_POWER.Signed-off-by Przemyslaw Marczak <[email protected]>--- include/configs/exynos4-common.h | 1 - 1 file changed, 1 deletion(-)Acked-by Simon Glass <[email protected]>
Applied to u-boot-dm/next, thanks!
PATCH v4 3/16 lib: Kconfig: add entry for errno_str() function
In reply to Przemyslaw Marczak--- lib/Kconfig | 8 ++++++++ 1 file changed, 8 insertions(+)
lib/Kconfig +8 -0
@@ -74,4 +74,12 @@ config SHA_PROG_HW_ACCEL is performed in hardware. endmenu +config ERRNO_STR + bool "Enable function for getting errno-related string message" + help + The function errno_str(int errno), returns a pointer to the errno + corresponding text message: + - if errno is null or positive number - a pointer to "Success" message + - if errno is negative - a pointer to errno related message + endmenu
Signature · 1 line
1.9.1
PATCH v4 3/16 lib: Kconfig: add entry for errno_str() function
Quoted 4 lines · Przemyslaw Marczak
Signed-off-by Przemyslaw Marczak <[email protected]>--- lib/Kconfig | 8 ++++++++ 1 file changed, 8 insertions(+)
(please make sure to always add a commit message)
PATCH v4 3/16 lib: Kconfig: add entry for errno_str() function
Quoted 9 lines · Simon Glass
Quoted 4 lines · Przemyslaw Marczak
Signed-off-by Przemyslaw Marczak <[email protected]>--- lib/Kconfig | 8 ++++++++ 1 file changed, 8 insertions(+)(please make sure to always add a commit message)
Acked-by Simon Glass <[email protected]>
Applied to u-boot-dm/next, thanks!
PATCH v4 4/16 dm: pmic: add implementation of driver model pmic uclass
In reply to Przemyslaw MarczakThis commit introduces the PMIC uclass implementation. It allows providing the basic I/O interface for PMIC devices. For the multi-function PMIC devices, this can be used as I/O parent device, for each IC's interface. Then, each PMIC particular function can be provided by the child device's operations, and the child devices will use its parent for read/write by the common API.
Core files:
- 'include/power/pmic.h'
- 'drivers/power/pmic/pmic-uclass.c'
The old pmic framework is still kept and is independent.
For more detailed informations, please look into the header file.
Changes:
- new uclass-id: UCLASS_PMIC
- new config: CONFIG_DM_PMIC
---
Changes V2:
- pmic uclass: adjust uclass code to the mainline changes
- pmic uclass: remove pmic_i2c and pmic_spi
- pmic uclass: modify pmic_platdata
- pmic uclass: add pmic_if_* functions
- pmic uclass: remove pmic_init_dm()
- pmic uclass: cleanup
- pmic.h: define pmic ops structure (read/write operations)
- pmic.h: add comments to functions
Changes V3:
- pmic-uclass.c and pmic.h:
-- remove pmic_if_* functions
-- add new function pmic_child_node_scan()
- add Kconfig entry
Changes V4:
- move drivers/power/pmic-uclass.c to drivers/power/pmic/pmic-uclass.c
- move DM_PMIC Kconfig entry: drivers/power/Kconfig to drivers/power/pmic/Kconfig
- drivers/power/Kconfig: Add menu "Power" and include pmic Kconfig
- Kconfig: provide only the general information about the PMIC
- pmic-uclass.c: add pmic_bind_childs()
- pmic-uclass.c: add debug
- pmic-uclass.c: cleanup includes
- pmic-uclass.c: remove pmic_get_uclass_ops() and use of dev_get_driver_ops()
- pmic-uclass.c: use of uclass_get_device_by_name()
- pmic-uclass.c: add str_get_num() - for get number from string
- include/power/pmic.h - start comments rewording
- power/pmic.h: comments update
--- drivers/power/Kconfig | 6 ++ drivers/power/pmic/Kconfig | 11 +++ drivers/power/pmic/Makefile | 1 + drivers/power/pmic/pmic-uclass.c | 158 ++++++++++++++++++++++++++++++++ include/dm/uclass-id.h | 3 + include/power/pmic.h | 189 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 368 insertions(+) create mode 100644 drivers/power/pmic/Kconfig create mode 100644 drivers/power/pmic/pmic-uclass.c
drivers/power/Kconfig +6 -0
@@ -1,3 +1,7 @@ +menu "Power" + +source "drivers/power/pmic/Kconfig" + config AXP221_POWER boolean "axp221 / axp223 pmic support" depends on MACH_SUN6I || MACH_SUN8I
@@ -73,3 +77,5 @@ config AXP221_ELDO3_VOLT disable eldo3. On some A31(s) tablets it might be used to supply 1.2V for the SSD2828 chip (converter of parallel LCD interface into MIPI DSI). + +endmenu
drivers/power/pmic/Kconfig new file +11 -0
@@ -0,0 +1,11 @@ +config DM_PMIC + bool "Enable Driver Model for PMIC drivers (UCLASS_PMIC)" + depends on DM + ---help--- + This config enables the driver-model PMIC support. + UCLASS_PMIC - designed to provide an I/O interface for PMIC devices. + For the multi-function PMIC devices, this can be used as parent I/O + device for each IC's interface. Then, each children uses its parent + for read/write. For detailed description, please refer to the files: + - 'drivers/power/pmic/pmic-uclass.c' + - 'include/power/pmic.h'
drivers/power/pmic/Makefile +1 -0
@@ -5,6 +5,7 @@ # SPDX-License-Identifier: GPL-2.0+ # +obj-$(CONFIG_DM_PMIC) += pmic-uclass.o obj-$(CONFIG_POWER_LTC3676) += pmic_ltc3676.o obj-$(CONFIG_POWER_MAX8998) += pmic_max8998.o obj-$(CONFIG_POWER_MAX8997) += pmic_max8997.o
drivers/power/pmic/pmic-uclass.c new file +158 -0
158 lines not on this page · raw message
include/dm/uclass-id.h +3 -0
@@ -46,6 +46,9 @@ enum uclass_id {UCLASS_USB_DEV_GENERIC ,/* USB generic device */ UCLASS_MASS_STORAGE ,/* Mass storage device */ +/* Power Management */ +UCLASS_PMIC ,/* PMIC I/O device */ +UCLASS_COUNT , UCLASS_INVALID = -1, };
include/power/pmic.h +189 -0
216 lines not on this page · raw message
Signature · 1 line
1.9.1
PATCH v4 4/16 dm: pmic: add implementation of driver model pmic uclass
Hi Przemyslaw,
Quoted 50 lines · Przemyslaw Marczak
This commit introduces the PMIC uclass implementation. It allows providing the basic I/O interface for PMIC devices. For the multi-function PMIC devices, this can be used as I/O parent device, for each IC's interface. Then, each PMIC particular function can be provided by the child device's operations, and the child devices will use its parent for read/write by the common API.
Core files:
- 'include/power/pmic.h'
- 'drivers/power/pmic/pmic-uclass.c'The old pmic framework is still kept and is independent.
For more detailed informations, please look into the header file.
Changes:
- new uclass-id:UCLASS_PMIC
- new config:CONFIG_DM_PMICSigned-off-by Przemyslaw Marczak <[email protected]>---
Changes V2:
- pmic uclass: adjust uclass code to the mainline changes
- pmic uclass: removepmic_i2candpmic_spi
- pmic uclass: modifypmic_platdata
- pmic uclass: add pmic_if_* functions
- pmic uclass: removepmic_init_dm()
- pmic uclass: cleanup
-pmic.h: define pmic ops structure (read/write operations)
-pmic.h: add comments to functionsChanges V3:
-pmic-uclass.candpmic.h:
-- remove pmic_if_* functions
-- add new functionpmic_child_node_scan()
- addKconfigentryChanges V4:
- movedrivers/power/pmic-uclass.ctodrivers/power/pmic/pmic-uclass.c
- moveDM_PMICKconfigentry:drivers/power/Kconfigtodrivers/power/pmic/Kconfig
-drivers/power/Kconfig: Add menu "Power" and include pmicKconfig
-Kconfig: provide only the general information about the PMIC
-pmic-uclass.c: addpmic_bind_childs()
-pmic-uclass.c: add debug
-pmic-uclass.c: cleanup includes
-pmic-uclass.c: removepmic_get_uclass_ops()and use ofdev_get_driver_ops()
-pmic-uclass.c: use ofuclass_get_device_by_name()
-pmic-uclass.c: addstr_get_num()- for get number from string
-include/power/pmic.h- start comments rewording
-power/pmic.h: comments update
Quoted 10 lines
--- drivers/power/Kconfig | 6 ++ drivers/power/pmic/Kconfig | 11 +++ drivers/power/pmic/Makefile | 1 + drivers/power/pmic/pmic-uclass.c | 158 ++++++++++++++++++++++++++++++++ include/dm/uclass-id.h | 3 + include/power/pmic.h | 189 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 368 insertions(+) create mode 100644 drivers/power/pmic/Kconfig create mode 100644 drivers/power/pmic/pmic-uclass.c
I have a few nits below - perhaps they can be targeted in a follow-up patch or two? I'd like to merge this soon and it is not worth holding up the series for nits.
Quoted 156 lines
drivers/power/Kconfig +6
-0@@ -1,3 +1,7 @@ +menu "Power" + +source "drivers/power/pmic/Kconfig" + config AXP221_POWER boolean "axp221 / axp223 pmic support" depends on MACH_SUN6I || MACH_SUN8I@@ -73,3 +77,5 @@ config AXP221_ELDO3_VOLT disable eldo3. On some A31(s) tablets it might be used to supply 1.2V for the SSD2828 chip (converter of parallel LCD interface into MIPI DSI). + +endmenudrivers/power/pmic/Kconfig new file +11
-0@@ -0,0 +1,11 @@ +config DM_PMIC + bool "Enable Driver Model for PMIC drivers (UCLASS_PMIC)" + depends on DM + ---help--- + This config enables the driver-model PMIC support. + UCLASS_PMIC - designed to provide an I/O interface for PMIC devices. + For the multi-function PMIC devices, this can be used as parent I/O + device for each IC's interface. Then, each children uses its parent + for read/write. For detailed description, please refer to the files: + - 'drivers/power/pmic/pmic-uclass.c' + - 'include/power/pmic.h'drivers/power/pmic/Makefile +1
-0@@ -5,6 +5,7 @@ # SPDX-License-Identifier: GPL-2.0+ # +obj-$(CONFIG_DM_PMIC) += pmic-uclass.o obj-$(CONFIG_POWER_LTC3676) += pmic_ltc3676.o obj-$(CONFIG_POWER_MAX8998) += pmic_max8998.o obj-$(CONFIG_POWER_MAX8997) += pmic_max8997.odrivers/power/pmic/pmic-uclass.c new file +102
-0@@ -0,0 +1,158 @@ +/* +* Copyright (C) 2014-2015 Samsung Electronics +* Przemyslaw Marczak <[email protected]> +* +* SPDX-License-Identifier: GPL-2.0+ +*/ + +#include <common.h> +#include <fdtdec.h> +#include <errno.h> +#include <dm.h> +#include <dm/lists.h> +#include <dm/device-internal.h> +#include <dm/uclass-internal.h> +#include <power/pmic.h> +#include <linux/ctype.h> + +DECLARE_GLOBAL_DATA_PTR ; + +static ulong str_get_num (const char *ptr,const char *maxptr) +{ +if (!ptr || !maxptr) +return 0 ; + +while (!isdigit (*ptr) && ptr++ < maxptr); + +return simple_strtoul (ptr,NULL ,0 ); +} + +int pmic_bind_childs (struct udevice *pmic,int offset, +const struct pmic_child_info *child_info) +{ +const struct pmic_child_info *info; +const void *blob = gd->fdt_blob; +struct driver *drv; +struct udevice *child; +const char *node_name; +int node_name_len; +int bind_count =0 ; +int node; +int prefix_len; +int ret; + +debug ("%s for '%s' at node offset: %d\n" , __func__, pmic->name, + pmic->of_offset); + +for (node =fdt_first_subnode (blob, offset); + node >0 ; + node =fdt_next_subnode (blob, node)) { + node_name =fdt_get_name (blob, node, &node_name_len); + +debug ("* Found child node: '%s' at offset:%d\n" , node_name, + node); + + child =NULL ; + info = child_info; +while (info->prefix) { + prefix_len =strlen (info->prefix); +if (strncasecmp (info->prefix, node_name, prefix_len) || + !info->driver) { + info++; +continue ; + } + +debug (" - compatible prefix: '%s'\n" , info->prefix); + + drv =lists_driver_lookup_name (info->driver); +if (!drv) { +debug (" - driver: '%s' not found!\n" , + info->driver); +continue ; + } + +debug (" - found child driver: '%s'\n" , drv->name); + + ret =device_bind (pmic, drv, node_name,NULL , + node, &child); +if (ret) { +debug (" - child binding error: %d\n" , ret); +continue ; + } + +debug (" - bound child device: '%s'\n" , child->name); + + child->driver_data =str_get_num (node_name + + prefix_len, + node_name + + node_name_len); + +debug (" - set 'child->driver_data': %lu\n" , + child->driver_data); +break ; + } + +if (child) + bind_count++; +else +debug (" - compatible prefix not found\n" ); + } + +debug ("Bound: %d childs for PMIC: '%s'\n" , bind_count, pmic->name); +return bind_count;
drivers/power/pmic/pmic-uclass.c line 112
Quoted 10 lines
drivers/power/pmic/pmic-uclass.c new file +10
-0+} + +int pmic_get (const char *name,struct udevice **devp) +{ +return uclass_get_device_by_name (UCLASS_PMIC , name, devp); +} + +int pmic_reg_count (struct udevice *dev) +{ +const struct dm_pmic_ops *ops =dev_get_driver_ops (dev);
blank line here
Quoted 73 lines
drivers/power/pmic/pmic-uclass.c new file +46
-0+if (!ops) +return -ENOSYS ; + +return ops->reg_count; +} + +int pmic_read (struct udevice *dev,uint reg,uint8_t *buffer,int len) +{ +const struct dm_pmic_ops *ops =dev_get_driver_ops (dev); +int ret; + +if (!buffer) +return -EFAULT ; + +if (!ops || !ops->read) +return -ENOSYS ; + + ret = ops->read (dev, reg, buffer, len); +if (ret) +return ret; + +return 0 ; +} + +int pmic_write (struct udevice *dev,uint reg,const uint8_t *buffer,int len) +{ +const struct dm_pmic_ops *ops =dev_get_driver_ops (dev); +int ret; + +if (!buffer) +return -EFAULT ; + +if (!ops || !ops->write) +return -ENOSYS ; + + ret = ops->write (dev, reg, buffer, len); +if (ret) +return ret; + +return 0 ; +} + +UCLASS_DRIVER (pmic) = { + .id =UCLASS_PMIC , + .name ="pmic" , +};include/dm/uclass-id.h +3
-0@@ -46,6 +46,9 @@ enum uclass_id {UCLASS_USB_DEV_GENERIC ,/* USB generic device */ UCLASS_MASS_STORAGE ,/* Mass storage device */ +/* Power Management */ +UCLASS_PMIC ,/* PMIC I/O device */ +UCLASS_COUNT , UCLASS_INVALID = -1, };include/power/pmic.h +3
-0@@ -1,4 +1,7 @@/* +* Copyright (C) 2014-2015 Samsung Electronics +* Przemyslaw Marczak <[email protected]> +* * Copyright (C) 2011-2012 Samsung Electronics * Lukasz Majewski <[email protected]> *
include/power/pmic.h line 17
Quoted 6 lines
include/power/pmic.h +1
-0@@ -9,10 +12,13 @@#define __CORE_PMIC_H_#include <linux/list.h> +#include <spi.h> #include <i2c.h> #include <power/power_chrg.h>
At some point can you update the ordering of this lot? I think it should be:
i2c.gspi.h
linux/
power/
Quoted 9 lines
include/power/pmic.h +2
-0enum {PMIC_I2C ,PMIC_SPI ,PMIC_NONE }; + +#ifdef CONFIG_POWER enum {I2C_PMIC ,I2C_NUM , };enum {PMIC_READ ,PMIC_WRITE , };enum {PMIC_SENSOR_BYTE_ORDER_LITTLE ,PMIC_SENSOR_BYTE_ORDER_BIG , };@@ -77,7 +83,189 @@ struct pmic {struct pmic *parent;
include/power/pmic.h struct pmic { · line 93
Quoted 10 lines
include/power/pmic.h +8
-0struct list_head list; }; +#endif /* CONFIG_POWER */ + +#ifdef CONFIG_DM_PMIC +/** +* U-Boot PMIC Framework +* ===================== +* +* UCLASS_PMIC - The is designed to provide an I/O interface for PMIC devices.
This is designed
include/power/pmic.h struct pmic { · line 96
Quoted 3 lines
include/power/pmic.h +3
-0+* +* For the multi-function PMIC devices, this can be used as parent I/O device +* for each IC's interface. Then, each children uses its parent for read/write.
each child
Quoted 9 lines
include/power/pmic.h +9
-0+* +* The driver model tree could look like this: +* +*_ root device +* |_ BUS 0 device (e.g. I2C0) - UCLASS_I2C/SPI/... +* | |_ PMIC device (READ/WRITE ops) - UCLASS_PMIC +* | |_ REGULATOR device (ldo/buck/... ops) - UCLASS_REGULATOR +* | |_ CHARGER device (charger ops) - UCLASS_CHARGER (in the future) +* | |_ MUIC device (microUSB connector ops) - UCLASS_MUIC (in the future)
include/power/pmic.h struct pmic { · line 115
Quoted 10 lines
include/power/pmic.h +10
-0+* | |_ ... +* | +* |_ BUS 1 device (e.g. I2C1) - UCLASS_I2C/SPI/... +* |_ PMIC device (READ/WRITE ops) - UCLASS_PMIC +* |_ RTC device (rtc ops) - UCLASS_RTC (in the future) +* +* We can find two PMIC cases in boards design: +* - single I/O interface +* - multiple I/O interfaces +* We bind single PMIC device for each interface, to provide an I/O as a parent,
a single
Quoted 9 lines
include/power/pmic.h +9
-0+* of proper child devices. Each child usually implements a different function, +* controlled by the same interface. +* +* The binding should be done automatically. If device tree nodes/subnodes are +* proper defined, then: +* +* |_ the ROOT driver will bind the device for I2C/SPI node: +* |_ the I2C/SPI driver should bind a device for pmic node: +* |_ the PMIC driver should bind devices for its childs:
include/power/pmic.h struct pmic { · line 134
Quoted 10 lines
include/power/pmic.h +10
-0+* |_ regulator (child) +* |_ charger (child) +* |_ other (child) +* +* The same for other device nodes, for multi-interface PMIC. +* +* Note: +* Each PMIC interface driver should use a different compatible string. +* +* If each pmic child device driver need access the PMIC-specific registers,
If a pmic child device driver needs
include/power/pmic.h struct pmic { · line 144
Quoted 10 lines
include/power/pmic.h +10
-0+* it need know only the register address and the access can be done through +* the parent pmic driver. Like in the example: +* +*_ root driver +* |_ dev: bus I2C0 - UCLASS_I2C +* | |_ dev: my_pmic (read/write) (is parent) - UCLASS_PMIC +* | |_ dev: my_regulator (set value/etc..) (is child) - UCLASS_REGULATOR +* +* To ensure such device relationship, the pmic device driver should also bind +* all its child devices, like in the example below. It should be done by call
by calling pmic_bind_childs()
(which you should rename to pmic_bind_children() I think)
Quoted 10 lines
include/power/pmic.h +10
-0+* the 'pmic_bind_childs()' - please refer to the description of this function +* in this header file. This function, should be called in the driver's '.bind' +* method. +* +* For the example driver, please refer the MAX77686 driver: +* - 'drivers/power/pmic/max77686.c' +*/ + +/** +* struct dm_pmic_ops - PMIC device I/O interface
include/power/pmic.h struct pmic { · line 164
Quoted 10 lines
include/power/pmic.h +10
-0+* +* Should be implemented by UCLASS_PMIC device drivers. The standard +* device operations provides the I/O interface for it's childs. +* +* @reg_count: devices register count +* @read: read 'len' bytes at "reg" and store it into the 'buffer' +* @write: write 'len' bytes from the 'buffer' to the register at 'reg' address +*/ +struct dm_pmic_ops { +int reg_count;
This should not be in ops as it is not an operation. Perhaps add a function for it, or put it in the uclass platform data?
include/power/pmic.h struct pmic { · line 170
Quoted 6 lines
include/power/pmic.h +6
-0+int (*read)(struct udevice *dev,uint reg,uint8_t *buffer,int len); +int (*write)(struct udevice *dev,uint reg,const uint8_t *buffer, +int len); +}; + +/* enum pmic_op_type - used for various pmic devices operation calls,
/**
* enum pmic_op_type -
Quoted 50 lines
include/power/pmic.h +50
-0+* for reduce a number of lines with the same code for read/write or get/set. +* +* @PMIC_OP_GET - get operation +* @PMIC_OP_SET - set operation +*/ +enum pmic_op_type { +PMIC_OP_GET , +PMIC_OP_SET , +}; + +/** +* struct pmic_child_info - basic device's child info for bind child nodes with +* the driver by the node name prefix and driver name. This is a helper struct +* for function: pmic_bind_childs(). +* +* @prefix - child node name prefix (or its name if is unique or single) +* @driver - driver name for the sub-node with prefix +*/ +struct pmic_child_info { +const char *prefix; +const char *driver; +}; + +/* drivers/power/pmic-uclass.c */ + +/** +* pmic_bind_childs() - bind drivers for given parent pmic, using child info +* found in 'child_info' array. +* +* @pmic - pmic device - the parent of found child's +* @child_info - N-childs info array +* @return a positive number of childs, or 0 if no child found (error) +* +* Note: For N-childs the child_info array should have N+1 entries and the last +* entry prefix should be NULL - the same as for drivers compatible. +* +* For example, a single prefix info (N=1): +* static const struct pmic_child_info bind_info[] = { +* { .prefix = "ldo", .driver = "ldo_driver" }, +* { }, +* }; +* +* This function is useful for regulator sub-nodes: +* my_regulator at 0xa { +* reg = <0xa>; +* (pmic - bind automatically by compatible) +* compatible = "my_pmic"; +* ... +* (pmic's childs - bind by pmic_bind_childs()) +* (nodes prefix: "ldo", driver: "my_regulator_ldo")
include/power/pmic.h struct pmic { · line 230
Quoted 10 lines
include/power/pmic.h +10
-0+* ldo1 { ... }; +* ldo2 { ... }; +* +* (nodes prefix: "buck", driver: "my_regulator_buck") +* buck1 { ... }; +* buck2 { ... }; +* }; +*/ +int pmic_bind_childs (struct udevice *pmic,int offset, +const struct pmic_child_info *child_info);
pmic_bind_children
Quoted 50 lines
include/power/pmic.h +38
-1+ +/** +* pmic_get: get the pmic device using its name +* +* @name - device name +* @devp - returned pointer to the pmic device +* @return 0 on success or negative value of errno. +* +* The returned devp device can be used with pmic_read/write calls +*/ +int pmic_get (const char *name,struct udevice **devp); + +/** +* pmic_reg_count: get the pmic register count +* +* The required pmic device can be obtained by 'pmic_get()' +* +* @dev - pointer to the UCLASS_PMIC device +* @return register count value on success or negative value of errno. +*/ +int pmic_reg_count (struct udevice *dev); + +/** +* pmic_read/write: read/write to the UCLASS_PMIC device +* +* The required pmic device can be obtained by 'pmic_get()' +* +* @pmic - pointer to the UCLASS_PMIC device +* @reg - device register offset +* @buffer - pointer to read/write buffer +* @len - byte count for read/write +* @return 0 on success or negative value of errno. +*/ +int pmic_read (struct udevice *dev,uint reg,uint8_t *buffer,int len); +int pmic_write (struct udevice *dev,uint reg,const uint8_t *buffer,int len); +#endif /* CONFIG_DM_PMIC */ +#ifdef CONFIG_POWER int pmic_init (unsigned char bus);int power_init_board (void );int pmic_dialog_init (unsigned char bus);@@ -88,6 +276,7 @@ int pmic_probe(struct pmic *p);int pmic_reg_read (struct pmic *p,u32 reg,u32 *val);int pmic_reg_write (struct pmic *p,u32 reg,u32 val);int pmic_set_output (struct pmic *p,u32 reg,int ldo,int on); +#endif #define pmic_i2c_addr (p->hw.i2c.addr)#define pmic_i2c_tx_num (p->hw.i2c.tx_num) --
Quoted 2 lines
1.9.1
Regards,
Simon
PATCH v4 4/16 dm: pmic: add implementation of driver model pmic uclass
Quoted 64 lines · Simon Glass
Hi Przemyslaw,
Quoted 50 lines · Przemyslaw Marczak
This commit introduces the PMIC uclass implementation. It allows providing the basic I/O interface for PMIC devices. For the multi-function PMIC devices, this can be used as I/O parent device, for each IC's interface. Then, each PMIC particular function can be provided by the child device's operations, and the child devices will use its parent for read/write by the common API.
Core files:
- 'include/power/pmic.h'
- 'drivers/power/pmic/pmic-uclass.c'The old pmic framework is still kept and is independent.
For more detailed informations, please look into the header file.
Changes:
- new uclass-id:UCLASS_PMIC
- new config:CONFIG_DM_PMICSigned-off-by Przemyslaw Marczak <[email protected]>---
Changes V2:
- pmic uclass: adjust uclass code to the mainline changes
- pmic uclass: removepmic_i2candpmic_spi
- pmic uclass: modifypmic_platdata
- pmic uclass: add pmic_if_* functions
- pmic uclass: removepmic_init_dm()
- pmic uclass: cleanup
-pmic.h: define pmic ops structure (read/write operations)
-pmic.h: add comments to functionsChanges V3:
-pmic-uclass.candpmic.h:
-- remove pmic_if_* functions
-- add new functionpmic_child_node_scan()
- addKconfigentryChanges V4:
- movedrivers/power/pmic-uclass.ctodrivers/power/pmic/pmic-uclass.c
- moveDM_PMICKconfigentry:drivers/power/Kconfigtodrivers/power/pmic/Kconfig
-drivers/power/Kconfig: Add menu "Power" and include pmicKconfig
-Kconfig: provide only the general information about the PMIC
-pmic-uclass.c: addpmic_bind_childs()
-pmic-uclass.c: add debug
-pmic-uclass.c: cleanup includes
-pmic-uclass.c: removepmic_get_uclass_ops()and use ofdev_get_driver_ops()
-pmic-uclass.c: use ofuclass_get_device_by_name()
-pmic-uclass.c: addstr_get_num()- for get number from string
-include/power/pmic.h- start comments rewording
-power/pmic.h: comments updateQuoted 10 lines
--- drivers/power/Kconfig | 6 ++ drivers/power/pmic/Kconfig | 11 +++ drivers/power/pmic/Makefile | 1 + drivers/power/pmic/pmic-uclass.c | 158 ++++++++++++++++++++++++++++++++ include/dm/uclass-id.h | 3 + include/power/pmic.h | 189 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 368 insertions(+) create mode 100644 drivers/power/pmic/Kconfig create mode 100644 drivers/power/pmic/pmic-uclass.c
Quoted 5 lines
Acked-by Simon Glass <[email protected]>I have a few nits below - perhaps they can be targeted in a follow-up patch or two? I'd like to merge this soon and it is not worth holding up the series for nits.
Applied to u-boot-dm/next, thanks!
PATCH v4 4/16 dm: pmic: add implementation of driver model pmic uclass
In reply to Simon GlassHello Simon,
Quoted 64 lines · Simon Glass
Hi Przemyslaw,
Quoted 58 lines · Przemyslaw Marczak
This commit introduces the PMIC uclass implementation. It allows providing the basic I/O interface for PMIC devices. For the multi-function PMIC devices, this can be used as I/O parent device, for each IC's interface. Then, each PMIC particular function can be provided by the child device's operations, and the child devices will use its parent for read/write by the common API.
Core files:
- 'include/power/pmic.h'
- 'drivers/power/pmic/pmic-uclass.c'The old pmic framework is still kept and is independent.
For more detailed informations, please look into the header file.
Changes:
- new uclass-id:UCLASS_PMIC
- new config:CONFIG_DM_PMICSigned-off-by Przemyslaw Marczak <[email protected]>---
Changes V2:
- pmic uclass: adjust uclass code to the mainline changes
- pmic uclass: removepmic_i2candpmic_spi
- pmic uclass: modifypmic_platdata
- pmic uclass: add pmic_if_* functions
- pmic uclass: removepmic_init_dm()
- pmic uclass: cleanup
-pmic.h: define pmic ops structure (read/write operations)
-pmic.h: add comments to functionsChanges V3:
-pmic-uclass.candpmic.h:
-- remove pmic_if_* functions
-- add new functionpmic_child_node_scan()
- addKconfigentryChanges V4:
- movedrivers/power/pmic-uclass.ctodrivers/power/pmic/pmic-uclass.c
- moveDM_PMICKconfigentry:drivers/power/Kconfigtodrivers/power/pmic/Kconfig
-drivers/power/Kconfig: Add menu "Power" and include pmicKconfig
-Kconfig: provide only the general information about the PMIC
-pmic-uclass.c: addpmic_bind_childs()
-pmic-uclass.c: add debug
-pmic-uclass.c: cleanup includes
-pmic-uclass.c: removepmic_get_uclass_ops()and use ofdev_get_driver_ops()
-pmic-uclass.c: use ofuclass_get_device_by_name()
-pmic-uclass.c: addstr_get_num()- for get number from string
-include/power/pmic.h- start comments rewording
-power/pmic.h: comments update--- drivers/power/Kconfig | 6 ++ drivers/power/pmic/Kconfig | 11 +++ drivers/power/pmic/Makefile | 1 + drivers/power/pmic/pmic-uclass.c | 158 ++++++++++++++++++++++++++++++++ include/dm/uclass-id.h | 3 + include/power/pmic.h | 189 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 368 insertions(+)Quoted 2 lines
create mode 100644
drivers/power/pmic/Kconfigcreate mode 100644drivers/power/pmic/pmic-uclass.c
Quoted 6 lines
Acked-by Simon Glass <[email protected]>I have a few nits below - perhaps they can be targeted in a follow-up patch or two? I'd like to merge this soon and it is not worth holding up the series for nits.
That's good information. I will fix it all and resend ASAP.
Quoted 358 lines
Quoted 156 lines
drivers/power/Kconfig +6
-0@@ -1,3 +1,7 @@ +menu "Power" + +source "drivers/power/pmic/Kconfig" + config AXP221_POWER boolean "axp221 / axp223 pmic support" depends on MACH_SUN6I || MACH_SUN8I@@ -73,3 +77,5 @@ config AXP221_ELDO3_VOLT disable eldo3. On some A31(s) tablets it might be used to supply 1.2V for the SSD2828 chip (converter of parallel LCD interface into MIPI DSI). + +endmenudrivers/power/pmic/Kconfig new file +11
-0@@ -0,0 +1,11 @@ +config DM_PMIC + bool "Enable Driver Model for PMIC drivers (UCLASS_PMIC)" + depends on DM + ---help--- + This config enables the driver-model PMIC support. + UCLASS_PMIC - designed to provide an I/O interface for PMIC devices. + For the multi-function PMIC devices, this can be used as parent I/O + device for each IC's interface. Then, each children uses its parent + for read/write. For detailed description, please refer to the files: + - 'drivers/power/pmic/pmic-uclass.c' + - 'include/power/pmic.h'drivers/power/pmic/Makefile +1
-0@@ -5,6 +5,7 @@ # SPDX-License-Identifier: GPL-2.0+ # +obj-$(CONFIG_DM_PMIC) += pmic-uclass.o obj-$(CONFIG_POWER_LTC3676) += pmic_ltc3676.o obj-$(CONFIG_POWER_MAX8998) += pmic_max8998.o obj-$(CONFIG_POWER_MAX8997) += pmic_max8997.odrivers/power/pmic/pmic-uclass.c new file +102
-0@@ -0,0 +1,158 @@ +/* +* Copyright (C) 2014-2015 Samsung Electronics +* Przemyslaw Marczak <[email protected]> +* +* SPDX-License-Identifier: GPL-2.0+ +*/ + +#include <common.h> +#include <fdtdec.h> +#include <errno.h> +#include <dm.h> +#include <dm/lists.h> +#include <dm/device-internal.h> +#include <dm/uclass-internal.h> +#include <power/pmic.h> +#include <linux/ctype.h> + +DECLARE_GLOBAL_DATA_PTR ; + +static ulong str_get_num (const char *ptr,const char *maxptr) +{ +if (!ptr || !maxptr) +return 0 ; + +while (!isdigit (*ptr) && ptr++ < maxptr); + +return simple_strtoul (ptr,NULL ,0 ); +} + +int pmic_bind_childs (struct udevice *pmic,int offset, +const struct pmic_child_info *child_info) +{ +const struct pmic_child_info *info; +const void *blob = gd->fdt_blob; +struct driver *drv; +struct udevice *child; +const char *node_name; +int node_name_len; +int bind_count =0 ; +int node; +int prefix_len; +int ret; + +debug ("%s for '%s' at node offset: %d\n" , __func__, pmic->name, + pmic->of_offset); + +for (node =fdt_first_subnode (blob, offset); + node >0 ; + node =fdt_next_subnode (blob, node)) { + node_name =fdt_get_name (blob, node, &node_name_len); + +debug ("* Found child node: '%s' at offset:%d\n" , node_name, + node); + + child =NULL ; + info = child_info; +while (info->prefix) { + prefix_len =strlen (info->prefix); +if (strncasecmp (info->prefix, node_name, prefix_len) || + !info->driver) { + info++; +continue ; + } + +debug (" - compatible prefix: '%s'\n" , info->prefix); + + drv =lists_driver_lookup_name (info->driver); +if (!drv) { +debug (" - driver: '%s' not found!\n" , + info->driver); +continue ; + } + +debug (" - found child driver: '%s'\n" , drv->name); + + ret =device_bind (pmic, drv, node_name,NULL , + node, &child); +if (ret) { +debug (" - child binding error: %d\n" , ret); +continue ; + } + +debug (" - bound child device: '%s'\n" , child->name); + + child->driver_data =str_get_num (node_name + + prefix_len, + node_name + + node_name_len); + +debug (" - set 'child->driver_data': %lu\n" , + child->driver_data); +break ; + } + +if (child) + bind_count++; +else +debug (" - compatible prefix not found\n" ); + } + +debug ("Bound: %d childs for PMIC: '%s'\n" , bind_count, pmic->name); +return bind_count;drivers/power/pmic/pmic-uclass.c line 112
Quoted 10 lines
drivers/power/pmic/pmic-uclass.c new file +10
-0+} + +int pmic_get (const char *name,struct udevice **devp) +{ +return uclass_get_device_by_name (UCLASS_PMIC , name, devp); +} + +int pmic_reg_count (struct udevice *dev) +{ +const struct dm_pmic_ops *ops =dev_get_driver_ops (dev);blank line here
Quoted 73 lines
drivers/power/pmic/pmic-uclass.c new file +46
-0+if (!ops) +return -ENOSYS ; + +return ops->reg_count; +} + +int pmic_read (struct udevice *dev,uint reg,uint8_t *buffer,int len) +{ +const struct dm_pmic_ops *ops =dev_get_driver_ops (dev); +int ret; + +if (!buffer) +return -EFAULT ; + +if (!ops || !ops->read) +return -ENOSYS ; + + ret = ops->read (dev, reg, buffer, len); +if (ret) +return ret; + +return 0 ; +} + +int pmic_write (struct udevice *dev,uint reg,const uint8_t *buffer,int len) +{ +const struct dm_pmic_ops *ops =dev_get_driver_ops (dev); +int ret; + +if (!buffer) +return -EFAULT ; + +if (!ops || !ops->write) +return -ENOSYS ; + + ret = ops->write (dev, reg, buffer, len); +if (ret) +return ret; + +return 0 ; +} + +UCLASS_DRIVER (pmic) = { + .id =UCLASS_PMIC , + .name ="pmic" , +};include/dm/uclass-id.h +3
-0@@ -46,6 +46,9 @@ enum uclass_id {UCLASS_USB_DEV_GENERIC ,/* USB generic device */ UCLASS_MASS_STORAGE ,/* Mass storage device */ +/* Power Management */ +UCLASS_PMIC ,/* PMIC I/O device */ +UCLASS_COUNT , UCLASS_INVALID = -1, };include/power/pmic.h +3
-0@@ -1,4 +1,7 @@/* +* Copyright (C) 2014-2015 Samsung Electronics +* Przemyslaw Marczak <[email protected]> +* * Copyright (C) 2011-2012 Samsung Electronics * Lukasz Majewski <[email protected]> * include/power/pmic.h line 17
Quoted 6 lines
include/power/pmic.h +1
-0@@ -9,10 +12,13 @@#define __CORE_PMIC_H_#include <linux/list.h> +#include <spi.h> #include <i2c.h> #include <power/power_chrg.h> At some point can you update the ordering of this lot? I think it should be:
i2c.g
spi.h
linux/
power/Quoted 9 lines
include/power/pmic.h +2
-0enum {PMIC_I2C ,PMIC_SPI ,PMIC_NONE }; + +#ifdef CONFIG_POWER enum {I2C_PMIC ,I2C_NUM , };enum {PMIC_READ ,PMIC_WRITE , };enum {PMIC_SENSOR_BYTE_ORDER_LITTLE ,PMIC_SENSOR_BYTE_ORDER_BIG , };@@ -77,7 +83,189 @@ struct pmic {struct pmic *parent;include/power/pmic.h struct pmic { · line 93
Quoted 10 lines
include/power/pmic.h +8
-0struct list_head list; }; +#endif /* CONFIG_POWER */ + +#ifdef CONFIG_DM_PMIC +/** +* U-Boot PMIC Framework +* ===================== +* +* UCLASS_PMIC - The is designed to provide an I/O interface for PMIC devices. This is designed
include/power/pmic.h struct pmic { · line 96
Quoted 3 lines
include/power/pmic.h +3
-0+* +* For the multi-function PMIC devices, this can be used as parent I/O device +* for each IC's interface. Then, each children uses its parent for read/write. each child
Quoted 9 lines
include/power/pmic.h +9
-0+* +* The driver model tree could look like this: +* +*_ root device +* |_ BUS 0 device (e.g. I2C0) - UCLASS_I2C/SPI/... +* | |_ PMIC device (READ/WRITE ops) - UCLASS_PMIC +* | |_ REGULATOR device (ldo/buck/... ops) - UCLASS_REGULATOR +* | |_ CHARGER device (charger ops) - UCLASS_CHARGER (in the future) +* | |_ MUIC device (microUSB connector ops) - UCLASS_MUIC (in the future) include/power/pmic.h struct pmic { · line 115
Quoted 10 lines
include/power/pmic.h +10
-0+* | |_ ... +* | +* |_ BUS 1 device (e.g. I2C1) - UCLASS_I2C/SPI/... +* |_ PMIC device (READ/WRITE ops) - UCLASS_PMIC +* |_ RTC device (rtc ops) - UCLASS_RTC (in the future) +* +* We can find two PMIC cases in boards design: +* - single I/O interface +* - multiple I/O interfaces +* We bind single PMIC device for each interface, to provide an I/O as a parent, a single
Quoted 9 lines
include/power/pmic.h +9
-0+* of proper child devices. Each child usually implements a different function, +* controlled by the same interface. +* +* The binding should be done automatically. If device tree nodes/subnodes are +* proper defined, then: +* +* |_ the ROOT driver will bind the device for I2C/SPI node: +* |_ the I2C/SPI driver should bind a device for pmic node: +* |_ the PMIC driver should bind devices for its childs: include/power/pmic.h struct pmic { · line 134
Quoted 10 lines
include/power/pmic.h +10
-0+* |_ regulator (child) +* |_ charger (child) +* |_ other (child) +* +* The same for other device nodes, for multi-interface PMIC. +* +* Note: +* Each PMIC interface driver should use a different compatible string. +* +* If each pmic child device driver need access the PMIC-specific registers, If a pmic child device driver needs
include/power/pmic.h struct pmic { · line 144
Quoted 10 lines
include/power/pmic.h +10
-0+* it need know only the register address and the access can be done through +* the parent pmic driver. Like in the example: +* +*_ root driver +* |_ dev: bus I2C0 - UCLASS_I2C +* | |_ dev: my_pmic (read/write) (is parent) - UCLASS_PMIC +* | |_ dev: my_regulator (set value/etc..) (is child) - UCLASS_REGULATOR +* +* To ensure such device relationship, the pmic device driver should also bind +* all its child devices, like in the example below. It should be done by call by calling
pmic_bind_childs()(which you should rename to
pmic_bind_children()I think)Quoted 15 lines
include/power/pmic.h +15
-0+* the 'pmic_bind_childs()' - please refer to the description of this function +* in this header file. This function, should be called in the driver's '.bind' +* method. +* +* For the example driver, please refer the MAX77686 driver: +* - 'drivers/power/pmic/max77686.c' +*/ + +/** +* struct dm_pmic_ops - PMIC device I/O interface +* +* Should be implemented by UCLASS_PMIC device drivers. The standard +* device operations provides the I/O interface for it's childs. +* +* @reg_count: devices register count
Quoted 9 lines
include/power/pmic.h struct pmic { · line 164
Quoted 5 lines
include/power/pmic.h +5
-0+* @read: read 'len' bytes at "reg" and store it into the 'buffer' +* @write: write 'len' bytes from the 'buffer' to the register at 'reg' address +*/ +struct dm_pmic_ops { +int reg_count;This should not be in ops as it is not an operation. Perhaps add a function for it, or put it in the uclass platform data?
Adding this to uclass platform data will add another problem - choosing the right place for setting this value, because it's usually not given in dts, however the device node "reg" property could also provide the address length as it is for the memory.
But probably you will agree, that this is a job for I2C/SPI subsystem, and moreover has no sense, since usually the dts files don't provide the "reg" property as "<reg length>" for i2c/spi devices.
So maybe putting here an 'ops' function is better idea. int (*get_reg_count)(struct udevice *dev);
This is used only for the PMIC command, so if return -ENOSYS, then just "dump" command will no available for the device.
Quoted 120 lines
include/power/pmic.h struct pmic { · line 170
Quoted 6 lines
include/power/pmic.h +6
-0+int (*read)(struct udevice *dev,uint reg,uint8_t *buffer,int len); +int (*write)(struct udevice *dev,uint reg,const uint8_t *buffer, +int len); +}; + +/* enum pmic_op_type - used for various pmic devices operation calls, /**
* enumpmic_op_type-Quoted 50 lines
include/power/pmic.h +50
-0+* for reduce a number of lines with the same code for read/write or get/set. +* +* @PMIC_OP_GET - get operation +* @PMIC_OP_SET - set operation +*/ +enum pmic_op_type { +PMIC_OP_GET , +PMIC_OP_SET , +}; + +/** +* struct pmic_child_info - basic device's child info for bind child nodes with +* the driver by the node name prefix and driver name. This is a helper struct +* for function: pmic_bind_childs(). +* +* @prefix - child node name prefix (or its name if is unique or single) +* @driver - driver name for the sub-node with prefix +*/ +struct pmic_child_info { +const char *prefix; +const char *driver; +}; + +/* drivers/power/pmic-uclass.c */ + +/** +* pmic_bind_childs() - bind drivers for given parent pmic, using child info +* found in 'child_info' array. +* +* @pmic - pmic device - the parent of found child's +* @child_info - N-childs info array +* @return a positive number of childs, or 0 if no child found (error) +* +* Note: For N-childs the child_info array should have N+1 entries and the last +* entry prefix should be NULL - the same as for drivers compatible. +* +* For example, a single prefix info (N=1): +* static const struct pmic_child_info bind_info[] = { +* { .prefix = "ldo", .driver = "ldo_driver" }, +* { }, +* }; +* +* This function is useful for regulator sub-nodes: +* my_regulator at 0xa { +* reg = <0xa>; +* (pmic - bind automatically by compatible) +* compatible = "my_pmic"; +* ... +* (pmic's childs - bind by pmic_bind_childs()) +* (nodes prefix: "ldo", driver: "my_regulator_ldo") include/power/pmic.h struct pmic { · line 230
Quoted 10 lines
include/power/pmic.h +10
-0+* ldo1 { ... }; +* ldo2 { ... }; +* +* (nodes prefix: "buck", driver: "my_regulator_buck") +* buck1 { ... }; +* buck2 { ... }; +* }; +*/ +int pmic_bind_childs (struct udevice *pmic,int offset, +const struct pmic_child_info *child_info);
pmic_bind_childrenQuoted 47 lines
include/power/pmic.h +38
-0+ +/** +* pmic_get: get the pmic device using its name +* +* @name - device name +* @devp - returned pointer to the pmic device +* @return 0 on success or negative value of errno. +* +* The returned devp device can be used with pmic_read/write calls +*/ +int pmic_get (const char *name,struct udevice **devp); + +/** +* pmic_reg_count: get the pmic register count +* +* The required pmic device can be obtained by 'pmic_get()' +* +* @dev - pointer to the UCLASS_PMIC device +* @return register count value on success or negative value of errno. +*/ +int pmic_reg_count (struct udevice *dev); + +/** +* pmic_read/write: read/write to the UCLASS_PMIC device +* +* The required pmic device can be obtained by 'pmic_get()' +* +* @pmic - pointer to the UCLASS_PMIC device +* @reg - device register offset +* @buffer - pointer to read/write buffer +* @len - byte count for read/write +* @return 0 on success or negative value of errno. +*/ +int pmic_read (struct udevice *dev,uint reg,uint8_t *buffer,int len); +int pmic_write (struct udevice *dev,uint reg,const uint8_t *buffer,int len); +#endif /* CONFIG_DM_PMIC */ +#ifdef CONFIG_POWER int pmic_init (unsigned char bus);int power_init_board (void );int pmic_dialog_init (unsigned char bus);@@ -88,6 +276,7 @@ int pmic_probe(struct pmic *p);int pmic_reg_read (struct pmic *p,u32 reg,u32 *val);int pmic_reg_write (struct pmic *p,u32 reg,u32 val);int pmic_set_output (struct pmic *p,u32 reg,int ldo,int on); +#endif
Quoted 9 lines
Quoted 5 lines
include/power/pmic.h +0
-1#define pmic_i2c_addr (p->hw.i2c.addr)#define pmic_i2c_tx_num (p->hw.i2c.tx_num) --1.9.1
Regards,
Simon
Thanks for the review.
Best regards,
Signature · 4 lines
Przemyslaw Marczak Samsung R&D Institute Poland Samsung Electronics p.marczak at samsung.com
PATCH v4 4/16 dm: pmic: add implementation of driver model pmic uclass
Hi Przemyslaw,
Quoted 501 lines · Przemyslaw Marczak
Hello Simon,
Quoted 71 lines · Simon Glass
Hi Przemyslaw,
Quoted 62 lines · Przemyslaw Marczak
This commit introduces the PMIC uclass implementation. It allows providing the basic I/O interface for PMIC devices. For the multi-function PMIC devices, this can be used as I/O parent device, for each IC's interface. Then, each PMIC particular function can be provided by the child device's operations, and the child devices will use its parent for read/write by the common API.
Core files:
- 'include/power/pmic.h'
- 'drivers/power/pmic/pmic-uclass.c'The old pmic framework is still kept and is independent.
For more detailed informations, please look into the header file.
Changes:
- new uclass-id:UCLASS_PMIC
- new config:CONFIG_DM_PMICSigned-off-by Przemyslaw Marczak <[email protected]>---
Changes V2:
- pmic uclass: adjust uclass code to the mainline changes
- pmic uclass: removepmic_i2candpmic_spi
- pmic uclass: modifypmic_platdata
- pmic uclass: add pmic_if_* functions
- pmic uclass: removepmic_init_dm()
- pmic uclass: cleanup
-pmic.h: define pmic ops structure (read/write operations)
-pmic.h: add comments to functionsChanges V3:
-pmic-uclass.candpmic.h:
-- remove pmic_if_* functions
-- add new functionpmic_child_node_scan()
- addKconfigentryChanges V4:
- movedrivers/power/pmic-uclass.ctodrivers/power/pmic/pmic-uclass.c
- moveDM_PMICKconfigentry:drivers/power/Kconfigtodrivers/power/pmic/Kconfig
-drivers/power/Kconfig: Add menu "Power" and include pmicKconfig
-Kconfig: provide only the general information about the PMIC
-pmic-uclass.c: addpmic_bind_childs()
-pmic-uclass.c: add debug
-pmic-uclass.c: cleanup includes
-pmic-uclass.c: removepmic_get_uclass_ops()and use ofdev_get_driver_ops()
-pmic-uclass.c: use ofuclass_get_device_by_name()
-pmic-uclass.c: addstr_get_num()- for get number from string
-include/power/pmic.h- start comments rewording
-power/pmic.h: comments update--- drivers/power/Kconfig | 6 ++ drivers/power/pmic/Kconfig | 11 +++ drivers/power/pmic/Makefile | 1 + drivers/power/pmic/pmic-uclass.c | 158 ++++++++++++++++++++++++++++++++ include/dm/uclass-id.h | 3 + include/power/pmic.h | 189 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 368 insertions(+)Quoted 2 lines
create mode 100644
drivers/power/pmic/Kconfigcreate mode 100644drivers/power/pmic/pmic-uclass.cQuoted 6 lines
Acked-by Simon Glass <[email protected]>I have a few nits below - perhaps they can be targeted in a follow-up patch or two? I'd like to merge this soon and it is not worth holding up the series for nits.
That's good information. I will fix it all and resend ASAP.
Quoted 398 lines
Quoted 168 lines
drivers/power/Kconfig +6
-0@@ -1,3 +1,7 @@ +menu "Power" + +source "drivers/power/pmic/Kconfig" + config AXP221_POWER boolean "axp221 / axp223 pmic support" depends on MACH_SUN6I || MACH_SUN8I@@ -73,3 +77,5 @@ config AXP221_ELDO3_VOLT disable eldo3. On some A31(s) tablets it might be used to supply 1.2V for the SSD2828 chip (converter of parallel LCD interface into MIPI DSI). + +endmenudrivers/power/pmic/Kconfig new file +6
-0@@ -0,0 +1,11 @@ +config DM_PMIC + bool "Enable Driver Model for PMIC drivers (UCLASS_PMIC)" + depends on DM + ---help--- + This config enables the driver-model PMIC support. + UCLASS_PMIC - designed to provide an I/O interface for PMICdevices.
+ For the multi-function PMIC devices, this can be used as parent
I/O
+ device for each IC's interface. Then, each children uses its
parent
+ for read/write. For detailed description, please refer to the
files:drivers/power/pmic/Kconfig new file +2
-0+ - 'drivers/power/pmic/pmic-uclass.c' + - 'include/power/pmic.h'drivers/power/pmic/Makefile +1
-0@@ -5,6 +5,7 @@ # SPDX-License-Identifier: GPL-2.0+ # +obj-$(CONFIG_DM_PMIC) += pmic-uclass.o obj-$(CONFIG_POWER_LTC3676) += pmic_ltc3676.o obj-$(CONFIG_POWER_MAX8998) += pmic_max8998.o obj-$(CONFIG_POWER_MAX8997) += pmic_max8997.odrivers/power/pmic/pmic-uclass.c new file +52
-0@@ -0,0 +1,158 @@ +/* +* Copyright (C) 2014-2015 Samsung Electronics +* Przemyslaw Marczak <[email protected]> +* +* SPDX-License-Identifier: GPL-2.0+ +*/ + +#include <common.h> +#include <fdtdec.h> +#include <errno.h> +#include <dm.h> +#include <dm/lists.h> +#include <dm/device-internal.h> +#include <dm/uclass-internal.h> +#include <power/pmic.h> +#include <linux/ctype.h> + +DECLARE_GLOBAL_DATA_PTR ; + +static ulong str_get_num (const char *ptr,const char *maxptr) +{ +if (!ptr || !maxptr) +return 0 ; + +while (!isdigit (*ptr) && ptr++ < maxptr); + +return simple_strtoul (ptr,NULL ,0 ); +} + +int pmic_bind_childs (struct udevice *pmic,int offset, +const struct pmic_child_info *child_info) +{ +const struct pmic_child_info *info; +const void *blob = gd->fdt_blob; +struct driver *drv; +struct udevice *child; +const char *node_name; +int node_name_len; +int bind_count =0 ; +int node; +int prefix_len; +int ret; + +debug ("%s for '%s' at node offset: %d\n" , __func__, pmic->name, + pmic->of_offset); + +for (node =fdt_first_subnode (blob, offset); + node >0 ; + node =fdt_next_subnode (blob, node)) { + node_name =fdt_get_name (blob, node, &node_name_len); + + debug("* Found child node: '%s' at offset:%d\n",
node_name,drivers/power/pmic/pmic-uclass.c new file +7
-0+ node); + + child =NULL ; + info = child_info; +while (info->prefix) { + prefix_len =strlen (info->prefix); + if (strncasecmp(info->prefix, node_name,
prefix_len) ||drivers/power/pmic/pmic-uclass.c new file +6
-0+ !info->driver) { + info++; +continue ; + } + + debug(" - compatible prefix: '%s'\n",
info->prefix);drivers/power/pmic/pmic-uclass.c new file +9
-0+ + drv =lists_driver_lookup_name (info->driver); +if (!drv) { +debug (" - driver: '%s' not found!\n" , + info->driver); +continue ; + } + + debug(" - found child driver: '%s'\n",
drv->name);drivers/power/pmic/pmic-uclass.c new file +5
-0+ + ret =device_bind (pmic, drv, node_name,NULL , + node, &child); +if (ret) { + debug(" - child binding error: %d\n",ret);
drivers/power/pmic/pmic-uclass.c new file +4
-0+continue ; + } + + debug(" - bound child device: '%s'\n",
child->name);drivers/power/pmic/pmic-uclass.c new file +18
-0+ + child->driver_data =str_get_num (node_name + + prefix_len, + node_name + + node_name_len); + +debug (" - set 'child->driver_data': %lu\n" , + child->driver_data); +break ; + } + +if (child) + bind_count++; +else +debug (" - compatible prefix not found\n" ); + } + + debug("Bound: %d childs for PMIC: '%s'\n", bind_count,
pmic->name);drivers/power/pmic/pmic-uclass.c new file +1
-0+return bind_count;drivers/power/pmic/pmic-uclass.c line 112
Quoted 10 lines
drivers/power/pmic/pmic-uclass.c new file +10
-0+} + +int pmic_get (const char *name,struct udevice **devp) +{ +return uclass_get_device_by_name (UCLASS_PMIC , name, devp); +} + +int pmic_reg_count (struct udevice *dev) +{ +const struct dm_pmic_ops *ops =dev_get_driver_ops (dev);blank line here
Quoted 74 lines
drivers/power/pmic/pmic-uclass.c new file +25
-0+if (!ops) +return -ENOSYS ; + +return ops->reg_count; +} + +int pmic_read (struct udevice *dev,uint reg,uint8_t *buffer,int len) +{ +const struct dm_pmic_ops *ops =dev_get_driver_ops (dev); +int ret; + +if (!buffer) +return -EFAULT ; + +if (!ops || !ops->read) +return -ENOSYS ; + + ret = ops->read (dev, reg, buffer, len); +if (ret) +return ret; + +return 0 ; +} + +int pmic_write(struct udevice *dev, uint reg, const uint8_t *buffer, intlen)
drivers/power/pmic/pmic-uclass.c new file +21
-0+{ +const struct dm_pmic_ops *ops =dev_get_driver_ops (dev); +int ret; + +if (!buffer) +return -EFAULT ; + +if (!ops || !ops->write) +return -ENOSYS ; + + ret = ops->write (dev, reg, buffer, len); +if (ret) +return ret; + +return 0 ; +} + +UCLASS_DRIVER (pmic) = { + .id =UCLASS_PMIC , + .name ="pmic" , +};include/dm/uclass-id.h +3
-0@@ -46,6 +46,9 @@ enum uclass_id {UCLASS_USB_DEV_GENERIC ,/* USB generic device */ UCLASS_MASS_STORAGE ,/* Mass storage device */ +/* Power Management */ +UCLASS_PMIC ,/* PMIC I/O device */ +UCLASS_COUNT , UCLASS_INVALID = -1, };include/power/pmic.h +3
-0@@ -1,4 +1,7 @@/* +* Copyright (C) 2014-2015 Samsung Electronics +* Przemyslaw Marczak <[email protected]> +* * Copyright (C) 2011-2012 Samsung Electronics * Lukasz Majewski <[email protected]> * include/power/pmic.h line 17
Quoted 6 lines
include/power/pmic.h +1
-0@@ -9,10 +12,13 @@#define __CORE_PMIC_H_#include <linux/list.h> +#include <spi.h> #include <i2c.h> #include <power/power_chrg.h> At some point can you update the ordering of this lot? I think it should be:
i2c.g
spi.h
linux/
power/Quoted 19 lines
include/power/pmic.h +10
-0enum {PMIC_I2C ,PMIC_SPI ,PMIC_NONE }; + +#ifdef CONFIG_POWER enum {I2C_PMIC ,I2C_NUM , };enum {PMIC_READ ,PMIC_WRITE , };enum {PMIC_SENSOR_BYTE_ORDER_LITTLE ,PMIC_SENSOR_BYTE_ORDER_BIG , };@@ -77,7 +83,189 @@ struct pmic {struct pmic *parent; struct list_head list; }; +#endif /* CONFIG_POWER */ + +#ifdef CONFIG_DM_PMIC +/** +* U-Boot PMIC Framework +* ===================== +* +* UCLASS_PMIC - The is designed to provide an I/O interface for PMIC Quoted 1 line
devices.
This is designed
Quoted 5 lines
+ *
+ * For the multi-function PMIC devices, this can be used as parent I/O device
+ * for each IC's interface. Then, each children uses its parent for read/write.each child
Quoted 14 lines
+ *
+ * The driver model tree could look like this:
+ *
+ *_ root device+ * |_ BUS 0 device (e.g. I2C0) - UCLASS_I2C/SPI/... + * | |_ PMIC device (READ/WRITE ops) - UCLASS_PMIC + * | |_ REGULATOR device (ldo/buck/... ops) - UCLASS_REGULATOR + * | |_ CHARGER device (charger ops) - UCLASS_CHARGER (in the future) + * | |_ MUIC device (microUSB connector ops) - UCLASS_MUIC (in the future) + * | |_ ... + * | + * |_ BUS 1 device (e.g. I2C1) - UCLASS_I2C/SPI/...Quoted 9 lines
+ * |_ PMIC device (READ/WRITE ops) -
UCLASS_PMIC
+ * |_ RTC device (rtc ops) -UCLASS_RTC(in the
future)
+ *
+ * We can find two PMIC cases in boards design:
+ * - single I/O interface
+ * - multiple I/O interfaces
+ * We bind single PMIC device for each interface, to provide an I/O as a parent,a single
Quoted 14 lines
+ * of proper child devices. Each child usually implements a different function,
+ * controlled by the same interface.
+ *
+ * The binding should be done automatically. If device tree nodes/subnodes are
+ * proper defined, then:
+ *
+ * |_ the ROOT driver will bind the device for I2C/SPI node:
+ * |_ the I2C/SPI driver should bind a device for pmic node:
+ * |_ the PMIC driver should bind devices for its childs:+ * |_ regulator (child) + * |_ charger (child) + * |_ other (child)Quoted 8 lines
+ *
+ * The same for other device nodes, for multi-interface PMIC.
+ *
+ * Note:
+ * Each PMIC interface driver should use a different compatible string.
+ *
+ * If each pmic child device driver need access the PMIC-specific registers,If a pmic child device driver needs
Quoted 7 lines
+ * it need know only the register address and the access can be done through
+ * the parent pmic driver. Like in the example:
+ *
+ *_ root driver+ * |_ dev: bus I2C0 - UCLASS_I2C + * | |_ dev: my_pmic (read/write) (is parent) -Quoted 8 lines
UCLASS_PMIC
+ * | |_ dev:my_regulator(set value/etc..) (is child) -UCLASS_REGULATOR
+ *
+ * To ensure such device relationship, the pmic device driver should also bind
+ * all its child devices, like in the example below. It should be done by callby calling
pmic_bind_childs()(which you should rename to
pmic_bind_children()I think)Quoted 19 lines
+ * the '
pmic_bind_childs()' - please refer to the description of this function
+ * in this header file. This function, should be called in the driver's '.bind'
+ * method.
+ *
+ * For the example driver, please refer the MAX77686 driver:
+ * - 'drivers/power/pmic/max77686.c'
+ */include/power/pmic.h +10
-0+ +/** +* struct dm_pmic_ops - PMIC device I/O interface +* +* Should be implemented by UCLASS_PMIC device drivers. The standard +* device operations provides the I/O interface for it's childs. +* +* @reg_count: devices register count +* @read: read 'len' bytes at "reg" and store it into the 'buffer' +* @write: write 'len' bytes from the 'buffer' to the register at Quoted 9 lines
include/power/pmic.h struct pmic { · line 164
Quoted 4 lines
'reg' address
+ */include/power/pmic.h +2
-0+struct dm_pmic_ops { +int reg_count;This should not be in ops as it is not an operation. Perhaps add a function for it, or put it in the uclass platform data?
Adding this to uclass platform data will add another problem - choosing the right place for setting this value, because it's usually not given in dts, however the device node "reg" property could also provide the address length as it is for the memory.
But probably you will agree, that this is a job for I2C/SPI subsystem, and moreover has no sense, since usually the dts files don't provide the "reg" property as "<reg length>" for i2c/spi devices.
Quoted 5 lines
So maybe putting here an 'ops' function is better idea. int (*get_reg_count)(struct udevice *dev);
This is used only for the PMIC command, so if return
-ENOSYS, then just "dump" command will no available for the device.
Yes I think turning this value into a function is fine. I just don't think we should have values in the operations struct.
Quoted 132 lines
Quoted 132 lines
include/power/pmic.h struct pmic { · line 170
Quoted 10 lines
+ int (*read)(struct udevice *dev, uint reg,
uint8_t*buffer, int
len);
+ int (*write)(struct udevice *dev, uint reg, constuint8_t
*buffer,include/power/pmic.h +4
-0+ int len); +}; + +/* enum pmic_op_type - used for various pmic devices operation calls, /**
* enumpmic_op_type-Quoted 63 lines
+ * for reduce a number of lines with the same code for read/write or get/set.
+ *
+ * @PMIC_OP_GET - get operation
+ * @PMIC_OP_SET - set operationinclude/power/pmic.h +8
-0+*/ +enum pmic_op_type { +PMIC_OP_GET , +PMIC_OP_SET , +}; + +/** +* struct pmic_child_info - basic device's child info for bind child nodes with
+ * the driver by the node name prefix and driver name. This is a helper struct
+ * for function:pmic_bind_childs().
+ *
+ * @prefix - child node name prefix (or its name if is unique or single)
+ * @driver - driver name for the sub-node with prefix
+ */include/power/pmic.h +9
-0+struct pmic_child_info { +const char *prefix; +const char *driver; +}; + +/* drivers/power/pmic-uclass.c */ + +/** +* pmic_bind_childs() - bind drivers for given parent pmic, using child info
+ * found in 'child_info' array.
+ *
+ * @pmic - pmic device - the parent of found child's
+ * @child_info - N-childs info array
+ * @return a positive number of childs, or 0 if no child found (error)
+ *
+ * Note: For N-childs thechild_infoarray should have N+1 entries and the last
+ * entry prefix should be NULL - the same as for drivers compatible.
+ *
+ * For example, a single prefix info (N=1):
+ * static const structpmic_child_infobind_info[] = {
+ * { .prefix = "ldo", .driver = "ldo_driver" },
+ * { },
+ * };
+ *
+ * This function is useful for regulator sub-nodes:
+ *my_regulatorat0xa{+ * reg = <0xa>; + * (pmic - bind automatically by compatible) + * compatible = "my_pmic"; + * ... + * (pmic's childs - bind by pmic_bind_childs()) + * (nodes prefix: "ldo", driver: "my_regulator_ldo") + * ldo1 { ... }; + * ldo2 { ... }; + * + * (nodes prefix: "buck", driver: "my_regulator_buck") + * buck1 { ... }; + * buck2 { ... };+ * };
+ */include/power/pmic.h struct pmic { · line 230
Quoted 2 lines
include/power/pmic.h +2
-0+int pmic_bind_childs (struct udevice *pmic,int offset, +const struct pmic_child_info *child_info);
pmic_bind_childrenQuoted 48 lines
include/power/pmic.h +35
-0+ +/** +* pmic_get: get the pmic device using its name +* +* @name - device name +* @devp - returned pointer to the pmic device +* @return 0 on success or negative value of errno. +* +* The returned devp device can be used with pmic_read/write calls +*/ +int pmic_get (const char *name,struct udevice **devp); + +/** +* pmic_reg_count: get the pmic register count +* +* The required pmic device can be obtained by 'pmic_get()' +* +* @dev - pointer to the UCLASS_PMIC device +* @return register count value on success or negative value of errno. +*/ +int pmic_reg_count (struct udevice *dev); + +/** +* pmic_read/write: read/write to the UCLASS_PMIC device +* +* The required pmic device can be obtained by 'pmic_get()' +* +* @pmic - pointer to the UCLASS_PMIC device +* @reg - device register offset +* @buffer - pointer to read/write buffer +* @len - byte count for read/write +* @return 0 on success or negative value of errno. +*/ +int pmic_read (struct udevice *dev,uint reg,uint8_t *buffer,int len); +int pmic_write(struct udevice *dev, uint reg, const uint8_t *buffer, intlen);
include/power/pmic.h +3
-0+#endif /* CONFIG_DM_PMIC */ +#ifdef CONFIG_POWER int pmic_init (unsigned char bus);int power_init_board (void );int pmic_dialog_init (unsigned char bus);@@ -88,6 +276,7 @@ int pmic_probe(struct pmic *p);int pmic_reg_read (struct pmic *p,u32 reg,u32 *val);int pmic_reg_write (struct pmic *p,u32 reg,u32 val);int pmic_set_output (struct pmic *p,u32 reg,int ldo,int on); +#endif
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
include/power/pmic.h +0
-1#define pmic_i2c_addr (p->hw.i2c.addr)#define pmic_i2c_tx_num (p->hw.i2c.tx_num) --1.9.1
Regards,
Simon
PATCH v4 5/16 dm: regulator: add implementation of driver model regulator uclass
In reply to Przemyslaw MarczakThis commit introduces the implementation of dm regulator API. Device tree support allows for auto binding. And by the basic uclass operations, it allows to driving the devices in a common way. For detailed informations, please look into the header file.
Core files:
- drivers/power/regulator-uclass.c - provides regulator common functions api
- include/power/regulator.h - define all structures required by the regulator
Changes:
- new uclass-id: UCLASS_REGULATOR
- new config: CONFIG_DM_REGULATOR
---
Changes V2:
- new operations for regulator uclass:
-- get/set output state - for output on/off setting --- add enum: REGULATOR_OFF, REGULATOR_ON
- regulator uclass code rework and cleanup:
-- change name of:
--- enum 'regulator_desc_type' to 'regulator_type' --- add type DVS
--- struct 'regulator_desc' to 'regulator_value_desc'
-- regulator ops function calls:
--- remove 'ldo/buck' from naming
--- add new argument 'type' for define regulator type
-- regulator.h - update comments
Changes V3:
- regulator-uclass.c and regulator.h:
-- api cleanup
-- new function regulator_ofdata_to_platdata()
-- update of comments
-- add Kconfig
Changes V4:
- move file drivers/power/regulator-uclass.c to drivers/power/regulator/regulator-uclass.c
- move DM_REGULATOR Kconfig entry from: drivers/power/Kconfig to drivers/power/regulator/Kconfig
- drivers/power/Kconfig: include regulator Kconfig path
- Kconfig: provide only general informations
- regulator-uclass.c: cleanup
- regulator-uclass.c: allow init regulator with name only
- regulator-uclass.c: remove pmic_get_uclass_ops and use dev_get_driver_ops
- regulator-uclass.c: add use of uclass_get_device_by_name()
- regulator.h: add 'struct dm_regulator_uclass_platdata'
- regulator.h: API documentation cleanup
- regulator - add binding info
--- Makefile | 3 +- doc/device-tree-bindings/regulator/regulator.txt | 55 ++++ drivers/power/Kconfig | 2 + drivers/power/regulator/Kconfig | 17 + drivers/power/regulator/Makefile | 8 + drivers/power/regulator/regulator-uclass.c | 300 ++++++++++++++++++ include/dm/uclass-id.h | 1 + include/power/regulator.h | 384 +++++++++++++++++++++++ 8 files changed, 769 insertions(+), 1 deletion(-) create mode 100644 doc/device-tree-bindings/regulator/regulator.txt create mode 100644 drivers/power/regulator/Kconfig create mode 100644 drivers/power/regulator/Makefile create mode 100644 drivers/power/regulator/regulator-uclass.c create mode 100644 include/power/regulator.h
Makefile +2 -1
@@ -645,7 +645,8 @@ libs-y += drivers/power/ \ drivers/power/fuel_gauge/ \ drivers/power/mfd/ \ drivers/power/pmic/ \ - drivers/power/battery/ + drivers/power/battery/ \ + drivers/power/regulator/ libs-y += drivers/spi/ libs-$(CONFIG_FMAN_ENET) += drivers/net/fm/ libs-$(CONFIG_SYS_FSL_DDR) += drivers/ddr/fsl/
doc/device-tree-bindings/regulator/regulator.txt new file +55 -0
55 lines not on this page · raw message
drivers/power/Kconfig +2 -0
@@ -2,6 +2,8 @@ menu "Power" source "drivers/power/pmic/Kconfig" +source "drivers/power/regulator/Kconfig" + config AXP221_POWER boolean "axp221 / axp223 pmic support" depends on MACH_SUN6I || MACH_SUN8I
drivers/power/regulator/Kconfig new file +17 -0
@@ -0,0 +1,17 @@ +config DM_REGULATOR + bool "Enable Driver Model for REGULATOR drivers (UCLASS_REGULATOR)" + depends on DM + ---help--- + This config enables the driver model regulator support. + UCLASS_REGULATOR - designed to provide a common API for basic regulator's + functions, like get/set Voltage or Current value, enable state, etc... + Note: + When enabling this, please read the description, found in the files: + - 'include/power/pmic.h' + - 'include/power/regulator.h' + - 'drivers/power/pmic/pmic-uclass.c' + - 'drivers/power/pmic/regulator-uclass.c' + It's important to call the device_bind() with the proper node offset, + when binding the regulator devices. The pmic_bind_childs() can be used + for this purpose if PMIC I/O driver is implemented or dm_scan_fdt_node() + otherwise. Detailed informations can be found in the header file.
drivers/power/regulator/Makefile new file +8 -0
@@ -0,0 +1,8 @@ +# +# Copyright (C) 2015 Samsung Electronics +# Przemyslaw Marczak <[email protected]> +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-$(CONFIG_DM_REGULATOR) += regulator-uclass.o
drivers/power/regulator/regulator-uclass.c new file +300 -0
300 lines not on this page · raw message
include/dm/uclass-id.h +1 -0
@@ -48,6 +48,7 @@ enum uclass_id {/* Power Management */ UCLASS_PMIC ,/* PMIC I/O device */ +UCLASS_REGULATOR ,/* REGULATOR device */ UCLASS_COUNT , UCLASS_INVALID = -1,
include/power/regulator.h new file +384 -0
384 lines not on this page · raw message
Signature · 1 line
1.9.1
PATCH v4 5/16 dm: regulator: add implementation of driver model regulator uclass
Hi Przemyslaw,
Quoted 54 lines · Przemyslaw Marczak
This commit introduces the implementation of dm regulator API. Device tree support allows for auto binding. And by the basic uclass operations, it allows to driving the devices in a common way. For detailed informations, please look into the header file.
Core files:
-drivers/power/regulator-uclass.c- provides regulator common functions api
-include/power/regulator.h- define all structures required by the regulatorChanges:
- new uclass-id:UCLASS_REGULATOR
- new config:CONFIG_DM_REGULATORSigned-off-by Przemyslaw Marczak <[email protected]>---
Changes V2:
- new operations for regulator uclass:
-- get/set output state - for output on/off setting --- add enum:REGULATOR_OFF,REGULATOR_ON- regulator uclass code rework and cleanup:
-- change name of:
--- enum 'regulator_desc_type' to 'regulator_type' --- add type DVS
--- struct 'regulator_desc' to 'regulator_value_desc'-- regulator ops function calls:
--- remove 'ldo/buck' from naming
--- add new argument 'type' for define regulator type--
regulator.h- update commentsChanges V3:
-regulator-uclass.candregulator.h:
-- api cleanup
-- new functionregulator_ofdata_to_platdata()
-- update of comments
-- addKconfigChanges V4:
- move filedrivers/power/regulator-uclass.ctodrivers/power/regulator/regulator-uclass.c
- moveDM_REGULATORKconfigentry from:drivers/power/Kconfigtodrivers/power/regulator/Kconfig
-drivers/power/Kconfig: include regulatorKconfigpath
-Kconfig: provide only general informations
-regulator-uclass.c: cleanup
-regulator-uclass.c: allow init regulator with name only
-regulator-uclass.c: removepmic_get_uclass_opsand usedev_get_driver_ops
-regulator-uclass.c: add use ofuclass_get_device_by_name()
-regulator.h: add 'structdm_regulator_uclass_platdata'
-regulator.h: API documentation cleanup
- regulator - add binding info
Quoted 15 lines
--- Makefile | 3 +- doc/device-tree-bindings/regulator/regulator.txt | 55 ++++ drivers/power/Kconfig | 2 + drivers/power/regulator/Kconfig | 17 + drivers/power/regulator/Makefile | 8 + drivers/power/regulator/regulator-uclass.c | 300 ++++++++++++++++++ include/dm/uclass-id.h | 1 + include/power/regulator.h | 384 +++++++++++++++++++++++ 8 files changed, 769 insertions(+), 1 deletion(-) create mode 100644 doc/device-tree-bindings/regulator/regulator.txt create mode 100644 drivers/power/regulator/Kconfig create mode 100644 drivers/power/regulator/Makefile create mode 100644 drivers/power/regulator/regulator-uclass.c create mode 100644 include/power/regulator.h
A few more nits for later.
Quoted 233 lines
Makefile +2
-1@@ -645,7 +645,8 @@ libs-y += drivers/power/ \ drivers/power/fuel_gauge/ \ drivers/power/mfd/ \ drivers/power/pmic/ \ - drivers/power/battery/ + drivers/power/battery/ \ + drivers/power/regulator/ libs-y += drivers/spi/ libs-$(CONFIG_FMAN_ENET) += drivers/net/fm/ libs-$(CONFIG_SYS_FSL_DDR) += drivers/ddr/fsl/doc/device-tree-bindings/regulator/regulator.txt new file +55
-0@@ -0,0 +1,55 @@ +Voltage/Current regulator + +Binding: +The regulator devices don't use the "compatible" property. The binding is done +by the prefix of regulator node's name. Usually the pmic I/O driver will provide +the array of 'struct pmic_child_info' with the prefixes and compatible drivers. +The bind is done by calling function: pmic_bind_childs(). +Example drivers: +pmic: drivers/power/pmic/max77686.c +regulator: drivers/power/regulator/max77686.c + +For the node name e.g.: "prefix[:alpha:]num { ... }": +- the driver prefix should be: "prefix" or "PREFIX" - case insensitive +- the node name's "num" is set as "dev->driver_data" on bind + +Example the prefix "ldo" will pass for: "ldo1", "ldo at 1", "LDO1", "LDOREG at 1"... + +Required properties: +- regulator-name: a string, required by the regulator uclass + +Note +The "regulator-name" constraint is used for setting the device's uclass +platform data '.name' field. And the regulator device name is set from +it's node name. + +Optional properties: +- regulator-min-microvolt: a minimum allowed Voltage value +- regulator-max-microvolt: a maximum allowed Voltage value +- regulator-min-microamp: a minimum allowed Current value +- regulator-max-microamp: a maximum allowed Current value +- regulator-always-on: regulator should never be disabled +- regulator-boot-on: enabled by bootloader/firmware + +Other kernel-style properties, are currently not used. + +Note: +For the regulator autoset from constraints, the framework expects that: +- regulator-min-microvolt is equal to regulator-max-microvolt +- regulator-min-microamp is equal to regulator-max-microamp +- regulator-always-on or regulator-boot-on is set + +Example: +ldo0 { + /* Mandatory */ + regulator-name = "VDDQ_EMMC_1.8V"; + + /* Optional */ + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-min-microamp = <100000>; + regulator-max-microamp = <100000>; + regulator-always-on; + regulator-boot-on; +}; +drivers/power/Kconfig +2
-0@@ -2,6 +2,8 @@ menu "Power" source "drivers/power/pmic/Kconfig" +source "drivers/power/regulator/Kconfig" + config AXP221_POWER boolean "axp221 / axp223 pmic support" depends on MACH_SUN6I || MACH_SUN8Idrivers/power/regulator/Kconfig new file +17
-0@@ -0,0 +1,17 @@ +config DM_REGULATOR + bool "Enable Driver Model for REGULATOR drivers (UCLASS_REGULATOR)" + depends on DM + ---help--- + This config enables the driver model regulator support. + UCLASS_REGULATOR - designed to provide a common API for basic regulator's + functions, like get/set Voltage or Current value, enable state, etc... + Note: + When enabling this, please read the description, found in the files: + - 'include/power/pmic.h' + - 'include/power/regulator.h' + - 'drivers/power/pmic/pmic-uclass.c' + - 'drivers/power/pmic/regulator-uclass.c' + It's important to call the device_bind() with the proper node offset, + when binding the regulator devices. The pmic_bind_childs() can be used + for this purpose if PMIC I/O driver is implemented or dm_scan_fdt_node() + otherwise. Detailed informations can be found in the header file.drivers/power/regulator/Makefile new file +8
-0@@ -0,0 +1,8 @@ +# +# Copyright (C) 2015 Samsung Electronics +# Przemyslaw Marczak <[email protected]> +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-$(CONFIG_DM_REGULATOR) += regulator-uclass.odrivers/power/regulator/regulator-uclass.c new file +101
-0@@ -0,0 +1,300 @@ +/* +* Copyright (C) 2014-2015 Samsung Electronics +* Przemyslaw Marczak <[email protected]> +* +* SPDX-License-Identifier: GPL-2.0+ +*/ +#include <common.h> +#include <fdtdec.h> +#include <errno.h> +#include <dm.h> +#include <dm/uclass-internal.h> +#include <power/pmic.h> +#include <power/regulator.h> + +DECLARE_GLOBAL_DATA_PTR ; + +int regulator_mode (struct udevice *dev,struct dm_regulator_mode **modep) +{ +struct dm_regulator_uclass_platdata *uc_pdata; + + *modep =NULL ; + + uc_pdata =dev_get_uclass_platdata (dev); +if (!uc_pdata) +return -ENXIO ; + + *modep = uc_pdata->mode; +return uc_pdata->mode_count; +} + +int regulator_get_value (struct udevice *dev) +{ +const struct dm_regulator_ops *ops =dev_get_driver_ops (dev); + +if (!ops || !ops->get_value) +return -ENOSYS ; + +return ops->get_value (dev); +} + +int regulator_set_value (struct udevice *dev,int uV) +{ +const struct dm_regulator_ops *ops =dev_get_driver_ops (dev); + +if (!ops || !ops->set_value) +return -ENOSYS ; + +return ops->set_value (dev, uV); +} + +int regulator_get_current (struct udevice *dev) +{ +const struct dm_regulator_ops *ops =dev_get_driver_ops (dev); + +if (!ops || !ops->get_current) +return -ENOSYS ; + +return ops->get_current (dev); +} + +int regulator_set_current (struct udevice *dev,int uA) +{ +const struct dm_regulator_ops *ops =dev_get_driver_ops (dev); + +if (!ops || !ops->set_current) +return -ENOSYS ; + +return ops->set_current (dev, uA); +} + +bool regulator_get_enable (struct udevice *dev) +{ +const struct dm_regulator_ops *ops =dev_get_driver_ops (dev); + +if (!ops || !ops->get_enable) +return -ENOSYS ; + +return ops->get_enable (dev); +} + +int regulator_set_enable (struct udevice *dev,bool enable) +{ +const struct dm_regulator_ops *ops =dev_get_driver_ops (dev); + +if (!ops || !ops->set_enable) +return -ENOSYS ; + +return ops->set_enable (dev, enable); +} + +int regulator_get_mode (struct udevice *dev) +{ +const struct dm_regulator_ops *ops =dev_get_driver_ops (dev); + +if (!ops || !ops->get_mode) +return -ENOSYS ; + +return ops->get_mode (dev); +} + +int regulator_set_mode (struct udevice *dev,int mode)
drivers/power/regulator/regulator-uclass.c line 111
Quoted 10 lines
drivers/power/regulator/regulator-uclass.c new file +10
-0+{ +const struct dm_regulator_ops *ops =dev_get_driver_ops (dev); + +if (!ops || !ops->set_mode) +return -ENOSYS ; + +return ops->set_mode (dev, mode); +} + +int regulator_by_platname (const char *plat_name,struct udevice **devp)
regulator_get_by_platname()
since it does probe the device
Quoted 12 lines
drivers/power/regulator/regulator-uclass.c new file +12
-0+{ +struct dm_regulator_uclass_platdata *uc_pdata; +struct udevice *dev; + + *devp =NULL ; + +for (uclass_find_first_device (UCLASS_REGULATOR , &dev); + dev; +uclass_find_next_device (&dev)) { + uc_pdata =dev_get_uclass_platdata (dev); +if (!uc_pdata ||strcmp (plat_name, uc_pdata->name)) +continue ;
drivers/power/regulator/regulator-uclass.c line 133
Quoted 10 lines
drivers/power/regulator/regulator-uclass.c new file +10
-0+ +return uclass_get_device_tail (dev,0 , devp); + } + +debug ("%s: can't find: %s\n" , __func__, plat_name); + +return -ENODEV ; +} + +int regulator_by_devname (const char *devname,struct udevice **devp)
regulator_get_by_devname
Quoted 7 lines
drivers/power/regulator/regulator-uclass.c new file +7
-0+{ +return uclass_get_device_by_name (UCLASS_REGULATOR , devname, devp); +} + +static int setting_failed (int ret,bool verbose,const char *fmt, ...) +{ +va_list args;
drivers/power/regulator/regulator-uclass.c line 150
Quoted 10 lines
drivers/power/regulator/regulator-uclass.c new file +10
-0+char buf[64 ]; + +if (verbose == false) +return ret; + +va_start (args, fmt); +vscnprintf (buf,sizeof (buf), fmt, args); +va_end (args); + +printf (buf);
I wonder if we should have a vprintf() in U-Boot?
Quoted 6 lines
drivers/power/regulator/regulator-uclass.c new file +6
-0+ +if (!ret) +return 0 ; + +printf (" (ret: %d)" , ret); +
drivers/power/regulator/regulator-uclass.c line 166
Quoted 10 lines
drivers/power/regulator/regulator-uclass.c new file +10
-0+return ret; +} + +int regulator_by_platname_autoset_and_enable (const char *platname, +struct udevice **devp, +bool verbose) +{ +struct dm_regulator_uclass_platdata *uc_pdata; +struct udevice *dev; +bool v = verbose;
Can we drop this local var and just use 'verbose'
Quoted 48 lines
drivers/power/regulator/regulator-uclass.c new file +48
-0+int ret; + +if (devp) + *devp =NULL ; + + ret =regulator_by_platname (platname, &dev); +if (ret) { +error ("Can get the regulator: %s!" , platname); +return ret; + } + + uc_pdata =dev_get_uclass_platdata (dev); +if (!uc_pdata) { +error ("Can get the regulator %s uclass platdata!" , platname); +return -ENXIO ; + } + +if (v) +printf ("%s@%s: " , dev->name, uc_pdata->name); + +/* Those values are optional (-ENODATA if unset) */ +if ((uc_pdata->min_uV != -ENODATA ) && + (uc_pdata->max_uV != -ENODATA ) && + (uc_pdata->min_uV == uc_pdata->max_uV)) { + ret =regulator_set_value (dev, uc_pdata->min_uV); +if (setting_failed (ret, v,"set %d uV" , uc_pdata->min_uV)) + goto exit; + } + +/* Those values are optional (-ENODATA if unset) */ +if ((uc_pdata->min_uA != -ENODATA ) && + (uc_pdata->max_uA != -ENODATA ) && + (uc_pdata->min_uA == uc_pdata->max_uA)) { + ret =regulator_set_current (dev, uc_pdata->min_uA); +if (setting_failed (ret, v,"; set %d uA" , uc_pdata->min_uA)) + goto exit; + } + +if (!uc_pdata->always_on && !uc_pdata->boot_on) + goto retdev; + + ret =regulator_set_enable (dev, true); +if (setting_failed (ret, v,"; enabling" , uc_pdata->min_uA)) + goto exit; + +retdev: +if (devp) + *devp = dev;
drivers/power/regulator/regulator-uclass.c line 224
Quoted 10 lines
drivers/power/regulator/regulator-uclass.c new file +10
-0+exit: +if (v) +printf ("\n" ); +return ret; +} + +int regulator_by_platname_list_autoset_and_enable (const char *list_platname[], +int list_entries, +struct udevice *list_devp[], +bool verbose)
I wonder if you could shorten this (e.g. to regulator_list_autoset())?
Quoted 6 lines
drivers/power/regulator/regulator-uclass.c new file +6
-0+{ +struct udevice *dev; +int i, ret, success =0 ; + +for (i =0 ; i < list_entries; i++) { + ret =regulator_autoset (list_platname[i], &dev, verbose);
drivers/power/regulator/regulator-uclass.c line 240
Quoted 10 lines
drivers/power/regulator/regulator-uclass.c new file +10
-0+if (!ret) + success++; + +if (!list_devp) +continue ; + +if (ret) + list_devp[i] =NULL ; +else + list_devp[i] = dev;
Shouldn't dev be NULL if ret is non-zero anyway?
drivers/power/regulator/regulator-uclass.c line 243
Quoted 3 lines
drivers/power/regulator/regulator-uclass.c new file +3
-0+ } + +return (success != list_entries);
return success == list_entries ? 0 : -EIO
or something. Better would be to record the first error you get and return that.
Quoted 8 lines
drivers/power/regulator/regulator-uclass.c new file +8
-0+} + +static int regulator_post_bind (struct udevice *dev) +{ +struct dm_regulator_uclass_platdata *uc_pdata; +int offset = dev->of_offset; +const void *blob = gd->fdt_blob; +
drivers/power/regulator/regulator-uclass.c line 261
Quoted 10 lines
drivers/power/regulator/regulator-uclass.c new file +10
-0+ uc_pdata =dev_get_uclass_platdata (dev); +if (!uc_pdata) +return -ENXIO ; + +/* Regulator's mandatory constraint */ + uc_pdata->name =fdt_getprop (blob, offset,"regulator-name" ,NULL ); +if (!uc_pdata->name) { +debug ("%s: dev: %s has no property 'regulator-name'\n" , + __func__, dev->name); +return -ENXIO ;
-EINVAL as it indicates invalid device tree data.
Quoted 93 lines
drivers/power/regulator/regulator-uclass.c new file +39
-0+ } + +return 0 ; +} + +static int regulator_pre_probe (struct udevice *dev) +{ +struct dm_regulator_uclass_platdata *uc_pdata; +int offset = dev->of_offset; + + uc_pdata =dev_get_uclass_platdata (dev); +if (!uc_pdata) +return -ENXIO ; + +/* Regulator's optional constraints */ + uc_pdata->min_uV =fdtdec_get_int (gd->fdt_blob, offset, +"regulator-min-microvolt" , -ENODATA ); + uc_pdata->max_uV =fdtdec_get_int (gd->fdt_blob, offset, +"regulator-max-microvolt" , -ENODATA ); + uc_pdata->min_uA =fdtdec_get_int (gd->fdt_blob, offset, +"regulator-min-microamp" , -ENODATA ); + uc_pdata->max_uA =fdtdec_get_int (gd->fdt_blob, offset, +"regulator-max-microamp" , -ENODATA ); + uc_pdata->always_on =fdtdec_get_bool (gd->fdt_blob, offset, +"regulator-always-on" ); + uc_pdata->boot_on =fdtdec_get_bool (gd->fdt_blob, offset, +"regulator-boot-on" ); + +return 0 ; +} + +UCLASS_DRIVER (regulator) = { + .id =UCLASS_REGULATOR , + .name ="regulator" , + .post_bind = regulator_post_bind, + .pre_probe = regulator_pre_probe, + .per_device_platdata_auto_alloc_size = +sizeof (struct dm_regulator_uclass_platdata ), +};include/dm/uclass-id.h +1
-0@@ -48,6 +48,7 @@ enum uclass_id {/* Power Management */ UCLASS_PMIC ,/* PMIC I/O device */ +UCLASS_REGULATOR ,/* REGULATOR device */ UCLASS_COUNT , UCLASS_INVALID = -1,include/power/regulator.h new file +36
-0@@ -0,0 +1,384 @@ +/* +* Copyright (C) 2014-2015 Samsung Electronics +* Przemyslaw Marczak <[email protected]> +* +* SPDX-License-Identifier: GPL-2.0+ +*/ + +#ifndef _INCLUDE_REGULATOR_H_ +#define _INCLUDE_REGULATOR_H_ + +/** +* U-Boot Voltage/Current Regulator +* ================================ +* +* The regulator API is based on a driver model, with the device tree support. +* And this header describes the functions and data types for the uclass id: +* 'UCLASS_REGULATOR' and the regulator driver API. +* +* The regulator uclass - is based on uclass platform data which is allocated, +* automatically for each regulator device on bind and 'dev->uclass_platdata' +* points to it. The data type is: 'struct dm_regulator_uclass_platdata'. +* The uclass file: 'drivers/power/regulator/regulator-uclass.c' +* +* The regulator device - is based on driver's model 'struct udevice'. +* The API can use regulator name in two meanings: +* - devname - the regulator device's name: 'dev->name' +* - platname - the device's platdata's name. So in the code it looks like: +* 'uc_pdata = dev->uclass_platdata'; 'name = uc_pdata->name'. +* +* The regulator device driver - provide an implementation of uclass operations +* pointed by 'dev->driver->ops' as a struct of type 'struct dm_regulator_ops'. +* +* To proper bind the regulator device, the device tree node should provide +* regulator constraints, like in the example below: +* +* ldo1 {
include/power/regulator.h line 46
Quoted 10 lines
include/power/regulator.h new file +10
-0+* regulator-name = "VDD_MMC_1.8V"; (mandatory for bind) +* regulator-min-microvolt = <1000000>; (optional) +* regulator-max-microvolt = <1000000>; (optional) +* regulator-min-microamp = <1000>; (optional) +* regulator-max-microamp = <1000>; (optional) +* regulator-always-on; (optional) +* regulator-boot-on; (optional) +* }; +* +* Please take a notice, that for the proper operation at least name constraint
Please note that for the proper
or
Note: For the proper
include/power/regulator.h line 52
Quoted 6 lines
include/power/regulator.h new file +6
-0+* is needed, e.g. for call the device_by_platname(...). +* +* Regulator bind: +* For each regulator device, the device_bind() should be called with passed +* device tree offset. This is required for this uclass's '.post_bind' method, +* which do the scan on the device node, for the 'regulator-name' constraint.
s/do/does/
include/power/regulator.h line 58
Quoted 6 lines
include/power/regulator.h new file +6
-0+* If the parent is not a PMIC device, and the child is not bind by function: +* 'pmic_bind_childs()', then it's recommended to bind the device by call to +* dm_scan_fdt_node() - this is usually done automatically for bus devices, +* as a post bind method. +* Having the device's name constraint, we can call regulator_by_platname(), +* to find interesting regulator. Before return, the regulator is probed,
How about:
s/to find interesting regulator/to find the required regulator/
include/power/regulator.h line 67
Quoted 9 lines
include/power/regulator.h new file +9
-0+* and the rest of its constraints are put into the device's uclass platform +* data, by the uclass regulator '.pre_probe' method. +* +* For more info about PMIC bind, please refer to file: 'include/power/pmic.h' +* +* Note: +* Please do not use the device_bind_by_name() function, since it pass '-1' as +* device node offset - and the bind will fail on uclass .post_bind method, +* because of missing 'regulator-name' constraint.
Indeed. BTW I think i'm going to add a similar function which allows the node to be passed.
Quoted 211 lines
include/power/regulator.h new file +211
-0+* +* +* Fixed Voltage/Current Regulator +* =============================== +* +* When fixed voltage regulator is needed, then enable the config: +* - CONFIG_DM_REGULATOR_FIXED +* +* The driver file: 'drivers/power/regulator/fixed.c', provides basic support +* for control the GPIO, and return the device tree constraint values. +* +* To bind the fixed voltage regulator device, we usually use a 'simple-bus' +* node as a parent. And 'regulator-fixed' for the driver compatible. This is +* the same as in the kernel. The example node of fixed regulator: +* +* simple-bus { +* compatible = "simple-bus"; +* #address-cells = <1>; +* #size-cells = <0>; +* +* blue_led { +* compatible = "regulator-fixed"; +* regulator-name = "VDD_LED_3.3V"; +* regulator-min-microvolt = <3300000>; +* regulator-max-microvolt = <3300000>; +* gpio = <&gpc1 0 GPIO_ACTIVE_LOW>; +* }; +* }; +* +* The fixed regulator devices also provide regulator uclass platform data. And +* devices bound from such node, can use the regulator drivers API. +*/ + +/* enum regulator_type - used for regulator_*() variant calls */ +enum regulator_type { +REGULATOR_TYPE_LDO =0 , +REGULATOR_TYPE_BUCK , +REGULATOR_TYPE_DVS , +REGULATOR_TYPE_FIXED , +REGULATOR_TYPE_OTHER , +}; + +/** +* struct dm_regulator_mode - this structure holds an information about +* each regulator operation mode. Probably in most cases - an array. +* This will be probably a driver-static data, since it is device-specific. +* +* @id - a driver-specific mode id +* @register_value - a driver-specific value for its mode id +* @name - the name of mode - used for regulator command +* Note: +* The field 'id', should be always a positive number, since the negative values +* are reserved for the errno numbers when returns the mode id. +*/ +struct dm_regulator_mode { +int id;/* Set only as >= 0 (negative value is reserved for errno) */ +int register_value; +const char *name; +}; + +/** +* struct dm_regulator_uclass_platdata - pointed by dev->uclass_platdata, and +* allocated on each regulator bind. This structure holds an information +* about each regulator's constraints and supported operation modes. +* There is no "step" voltage value - so driver should take care of this. +* +* @type - one of 'enum regulator_type' +* @mode - pointer to the regulator mode (array if more than one) +* @mode_count - number of '.mode' entries +* @min_uV* - minimum voltage (micro Volts) +* @max_uV* - maximum voltage (micro Volts) +* @min_uA* - minimum amperage (micro Amps) +* @max_uA* - maximum amperage (micro Amps) +* @always_on* - bool type, true or false +* @boot_on* - bool type, true or false +* @name** - fdt regulator name - should be taken from the device tree +* +* Note: +* * - set automatically on device probe by the uclass's '.pre_probe' method. +* ** - set automatically on device bind by the uclass's '.post_bind' method. +* The constraints: type, mode, mode_count, can be set by device driver, e.g. +* by the driver '.probe' method. +*/ +struct dm_regulator_uclass_platdata { +enum regulator_type type; +struct dm_regulator_mode *mode; +int mode_count; +int min_uV; +int max_uV; +int min_uA; +int max_uA; +bool always_on; +bool boot_on; +const char *name; +}; + +/* Regulator device operations */ +struct dm_regulator_ops { +/** +* The regulator output value function calls operates on a micro Volts. +* +* get/set_value - get/set output value of the given output number +* @dev - regulator device +* Sets: +* @uV - set the output value [micro Volts] +* Returns: output value [uV] on success or negative errno if fail. +*/ +int (*get_value)(struct udevice *dev); +int (*set_value)(struct udevice *dev,int uV); + +/** +* The regulator output current function calls operates on a micro Amps. +* +* get/set_current - get/set output current of the given output number +* @dev - regulator device +* Sets: +* @uA - set the output current [micro Amps] +* Returns: output value [uA] on success or negative errno if fail. +*/ +int (*get_current)(struct udevice *dev); +int (*set_current)(struct udevice *dev,int uA); + +/** +* The most basic feature of the regulator output is its enable state. +* +* get/set_enable - get/set enable state of the given output number +* @dev - regulator device +* Sets: +* @enable - set true - enable or false - disable +* Returns: true/false for get; or 0 / -errno for set. +*/ +bool (*get_enable)(struct udevice *dev); +int (*set_enable)(struct udevice *dev,bool enable); + +/** +* The 'get/set_mode()' function calls should operate on a driver +* specific mode definitions, which should be found in: +* field 'mode' of struct mode_desc. +* +* get/set_mode - get/set operation mode of the given output number +* @dev - regulator device +* Sets +* @mode_id - set output mode id (struct dm_regulator_mode->id) +* Returns: id/0 for get/set on success or negative errno if fail. +* Note: +* The field 'id' of struct type 'dm_regulator_mode', should be always +* positive number, since the negative is reserved for the error. +*/ +int (*get_mode)(struct udevice *dev); +int (*set_mode)(struct udevice *dev,int mode_id); +}; + +/** +* regulator_mode: returns a pointer to the array of regulator mode info +* +* @dev - pointer to the regulator device +* @modep - pointer to the returned mode info array +* Returns - count of modep entries on success or negative errno if fail. +*/ +int regulator_mode (struct udevice *dev,struct dm_regulator_mode **modep); + +/** +* regulator_get_value: get microvoltage voltage value of a given regulator +* +* @dev - pointer to the regulator device +* Returns - positive output value [uV] on success or negative errno if fail. +*/ +int regulator_get_value (struct udevice *dev); + +/** +* regulator_set_value: set the microvoltage value of a given regulator. +* +* @dev - pointer to the regulator device +* @uV - the output value to set [micro Volts] +* Returns - 0 on success or -errno val if fails +*/ +int regulator_set_value (struct udevice *dev,int uV); + +/** +* regulator_get_current: get microampere value of a given regulator +* +* @dev - pointer to the regulator device +* Returns - positive output current [uA] on success or negative errno if fail. +*/ +int regulator_get_current (struct udevice *dev); + +/** +* regulator_set_current: set the microampere value of a given regulator. +* +* @dev - pointer to the regulator device +* @uA - set the output current [micro Amps] +* Returns - 0 on success or -errno val if fails +*/ +int regulator_set_current (struct udevice *dev,int uA); + +/** +* regulator_get_enable: get regulator device enable state. +* +* @dev - pointer to the regulator device +* Returns - true/false of enable state +*/ +bool regulator_get_enable (struct udevice *dev); + +/** +* regulator_set_enable: set regulator enable state +* +* @dev - pointer to the regulator device +* @enable - set true or false +* Returns - 0 on success or -errno val if fails +*/ +int regulator_set_enable (struct udevice *dev,bool enable);
include/power/regulator.h line 288
Quoted 10 lines
include/power/regulator.h new file +10
-0+ +/** +* regulator_get_mode: get mode of a given device regulator +* +* @dev - pointer to the regulator device +* Returns - positive mode number on success or -errno val if fails +* Note: +* The regulator driver should return one of defined, mode number rather, than +* the raw register value. The struct type 'mode_desc' provides a field 'mode' +* for this purpose and register_value for a raw register value.
Can you please reword the first sentence? I don't understand what it is trying to say. Similar below.
Quoted 32 lines
include/power/regulator.h new file +32
-0+*/ +int regulator_get_mode (struct udevice *dev); + +/** +* regulator_set_mode: set given regulator mode +* +* @dev - pointer to the regulator device +* @mode - mode type (field 'mode' of struct mode_desc) +* Returns - 0 on success or -errno value if fails +* Note: +* The regulator driver should take one of defined, mode number rather +* than a raw register value. The struct type 'regulator_mode_desc' has +* a mode field for this purpose and register_value for a raw register value. +*/ +int regulator_set_mode (struct udevice *dev,int mode); + +/** +* regulator_by_platname_autoset_and_enable: setup the regulator given by +* its uclass's platform data '.name'. The setup depends on constraints found +* in device's uclass's platform data (struct dm_regulator_uclass_platdata): +* - Voltage value - will set - if '.min_uV' and '.max_uV' values are equal +* - Current limit - will set - if '.min_uA' and '.max_uA' values are equal +* - Enable - will set - if '.always_on' or '.boot_on' are set to true +* +* The function returns on first encountered error. +* +* @platname - expected string for dm_regulator_uclass_platdata .name field +* @devp - returned pointer to the regulator device - if non-NULL passed +* @verbose - (true/false) print regulator setup info, or be quiet +* Returns: 0 on success or negative value of errno. +* +* The returned 'regulator' device can be used with:
include/power/regulator.h line 330
Quoted 10 lines
include/power/regulator.h new file +10
-0+* - regulator_get/set_* +* For shorter call name, the below macro regulator_autoset() can be used. +*/ +int regulator_by_platname_autoset_and_enable (const char *platname, +struct udevice **devp, +bool verbose); + +#define regulator_autoset (platname, devp, verbose) \ + regulator_by_platname_autoset_and_enable(platname, devp, verbose) +
Can we just use the shorter name for the function and avoid this #ifdef?
include/power/regulator.h line 343
Quoted 13 lines
include/power/regulator.h new file +13
-0+/** +* regulator_by_platname_list_autoset_and_enable: setup the regulators given by +* list of its uclass's platform data '.name'. The setup depends on constraints +* found in device's uclass's platform data. The function loops with calls to: +* regulator_by_platname_autoset_and_enable() for each name of list. +* +* @list_platname - an array of expected strings for .name field of each +* regulator's uclass platdata +* @list_entries - number of regulator's name list entries +* @list_devp - an array of returned pointers to the successfully setup +* regulator devices if non-NULL passed +* @verbose - (true/false) print each regulator setup info, or be quiet +* Returns: 0 on successfully setup of all list entries or 1 otwerwise.
otherwise
include/power/regulator.h line 356
Quoted 13 lines
include/power/regulator.h new file +13
-0+* +* The returned 'regulator' devices can be used with: +* - regulator_get/set_* +* For shorter call name, the below macro regulator_list_autoset() can be used. +*/ +int regulator_by_platname_list_autoset_and_enable (const char *list_platname[], +int list_entries, +struct udevice *list_devp[], +bool verbose); + +#define regulator_list_autoset (namelist, entries, devlist, verbose) \ + regulator_by_platname_list_autoset_and_enable(namelist, entries, \ + devlist, verbose)
As above. With #defines it changes the name in the map output or debugger, which confuses people. An inline function is better, but in this case it may be better to just rename the function.
include/power/regulator.h line 369
Quoted 13 lines
include/power/regulator.h new file +13
-0+ +/** +* regulator_by_devname: returns the pointer to the pmic regulator device. +* Search by name, found in regulator device's name. +* +* @devname - expected string for 'dev->name' of regulator device +* @devp - returned pointer to the regulator device +* Returns: 0 on success or negative value of errno. +* +* The returned 'regulator' device can be used with: +* - regulator_get/set_* +*/ +int regulator_by_devname (const char *devname,struct udevice **devp);
regulator_get_by_devname
include/power/regulator.h line 382
Quoted 13 lines
include/power/regulator.h new file +13
-0+ +/** +* regulator_by_platname: returns the pointer to the pmic regulator device. +* Search by name, found in regulator uclass platdata. +* +* @platname - expected string for dm_regulator_uclass_platdata .name field +* @devp - returned pointer to the regulator device +* Returns: 0 on success or negative value of errno. +* +* The returned 'regulator' device can be used with: +* - regulator_get/set_* +*/ +int regulator_by_platname (const char *platname,struct udevice **devp);
regulator_get_by_platname
Quoted 5 lines
include/power/regulator.h new file +2
-1+ +#endif /* _INCLUDE_REGULATOR_H_ */ --1.9.1
Regards,
Simon
PATCH v4 5/16 dm: regulator: add implementation of driver model regulator uclass
Quoted 57 lines · Simon Glass
Hi Przemyslaw,
Quoted 54 lines · Przemyslaw Marczak
This commit introduces the implementation of dm regulator API. Device tree support allows for auto binding. And by the basic uclass operations, it allows to driving the devices in a common way. For detailed informations, please look into the header file.
Core files:
-drivers/power/regulator-uclass.c- provides regulator common functions api
-include/power/regulator.h- define all structures required by the regulatorChanges:
- new uclass-id:UCLASS_REGULATOR
- new config:CONFIG_DM_REGULATORSigned-off-by Przemyslaw Marczak <[email protected]>---
Changes V2:
- new operations for regulator uclass:
-- get/set output state - for output on/off setting --- add enum:REGULATOR_OFF,REGULATOR_ON- regulator uclass code rework and cleanup:
-- change name of:
--- enum 'regulator_desc_type' to 'regulator_type' --- add type DVS
--- struct 'regulator_desc' to 'regulator_value_desc'-- regulator ops function calls:
--- remove 'ldo/buck' from naming
--- add new argument 'type' for define regulator type--
regulator.h- update commentsChanges V3:
-regulator-uclass.candregulator.h:
-- api cleanup
-- new functionregulator_ofdata_to_platdata()
-- update of comments
-- addKconfigChanges V4:
- move filedrivers/power/regulator-uclass.ctodrivers/power/regulator/regulator-uclass.c
- moveDM_REGULATORKconfigentry from:drivers/power/Kconfigtodrivers/power/regulator/Kconfig
-drivers/power/Kconfig: include regulatorKconfigpath
-Kconfig: provide only general informations
-regulator-uclass.c: cleanup
-regulator-uclass.c: allow init regulator with name only
-regulator-uclass.c: removepmic_get_uclass_opsand usedev_get_driver_ops
-regulator-uclass.c: add use ofuclass_get_device_by_name()
-regulator.h: add 'structdm_regulator_uclass_platdata'
-regulator.h: API documentation cleanup
- regulator - add binding info
Quoted 15 lines
Quoted 15 lines
--- Makefile | 3 +- doc/device-tree-bindings/regulator/regulator.txt | 55 ++++ drivers/power/Kconfig | 2 + drivers/power/regulator/Kconfig | 17 + drivers/power/regulator/Makefile | 8 + drivers/power/regulator/regulator-uclass.c | 300 ++++++++++++++++++ include/dm/uclass-id.h | 1 + include/power/regulator.h | 384 +++++++++++++++++++++++ 8 files changed, 769 insertions(+), 1 deletion(-) create mode 100644 doc/device-tree-bindings/regulator/regulator.txt create mode 100644 drivers/power/regulator/Kconfig create mode 100644 drivers/power/regulator/Makefile create mode 100644 drivers/power/regulator/regulator-uclass.c create mode 100644 include/power/regulator.h
PATCH v4 5/16 dm: regulator: add implementation of driver model regulator uclass
Quoted 59 lines · Simon Glass
Quoted 57 lines · Simon Glass
Hi Przemyslaw,
Quoted 54 lines · Przemyslaw Marczak
This commit introduces the implementation of dm regulator API. Device tree support allows for auto binding. And by the basic uclass operations, it allows to driving the devices in a common way. For detailed informations, please look into the header file.
Core files:
-drivers/power/regulator-uclass.c- provides regulator common functions api
-include/power/regulator.h- define all structures required by the regulatorChanges:
- new uclass-id:UCLASS_REGULATOR
- new config:CONFIG_DM_REGULATORSigned-off-by Przemyslaw Marczak <[email protected]>---
Changes V2:
- new operations for regulator uclass:
-- get/set output state - for output on/off setting --- add enum:REGULATOR_OFF,REGULATOR_ON- regulator uclass code rework and cleanup:
-- change name of:
--- enum 'regulator_desc_type' to 'regulator_type' --- add type DVS
--- struct 'regulator_desc' to 'regulator_value_desc'-- regulator ops function calls:
--- remove 'ldo/buck' from naming
--- add new argument 'type' for define regulator type--
regulator.h- update commentsChanges V3:
-regulator-uclass.candregulator.h:
-- api cleanup
-- new functionregulator_ofdata_to_platdata()
-- update of comments
-- addKconfigChanges V4:
- move filedrivers/power/regulator-uclass.ctodrivers/power/regulator/regulator-uclass.c
- moveDM_REGULATORKconfigentry from:drivers/power/Kconfigtodrivers/power/regulator/Kconfig
-drivers/power/Kconfig: include regulatorKconfigpath
-Kconfig: provide only general informations
-regulator-uclass.c: cleanup
-regulator-uclass.c: allow init regulator with name only
-regulator-uclass.c: removepmic_get_uclass_opsand usedev_get_driver_ops
-regulator-uclass.c: add use ofuclass_get_device_by_name()
-regulator.h: add 'structdm_regulator_uclass_platdata'
-regulator.h: API documentation cleanup
- regulator - add binding info
Quoted 1 line
Acked-by Simon Glass <[email protected]>
Applied to u-boot-dm/next, thanks!
PATCH v4 5/16 dm: regulator: add implementation of driver model regulator uclass
In reply to Simon GlassHello Simon,
Quoted 321 lines · Simon Glass
Hi Przemyslaw,
Quoted 64 lines · Przemyslaw Marczak
This commit introduces the implementation of dm regulator API. Device tree support allows for auto binding. And by the basic uclass operations, it allows to driving the devices in a common way. For detailed informations, please look into the header file.
Core files:
-drivers/power/regulator-uclass.c- provides regulator common functions api
-include/power/regulator.h- define all structures required by the regulatorChanges:
- new uclass-id:UCLASS_REGULATOR
- new config:CONFIG_DM_REGULATORSigned-off-by Przemyslaw Marczak <[email protected]>---
Changes V2:
- new operations for regulator uclass:
-- get/set output state - for output on/off setting --- add enum:REGULATOR_OFF,REGULATOR_ON- regulator uclass code rework and cleanup:
-- change name of:
--- enum 'regulator_desc_type' to 'regulator_type' --- add type DVS
--- struct 'regulator_desc' to 'regulator_value_desc'-- regulator ops function calls:
--- remove 'ldo/buck' from naming
--- add new argument 'type' for define regulator type--
regulator.h- update commentsChanges V3:
-regulator-uclass.candregulator.h:
-- api cleanup
-- new functionregulator_ofdata_to_platdata()
-- update of comments
-- addKconfigChanges V4:
- move filedrivers/power/regulator-uclass.ctodrivers/power/regulator/regulator-uclass.c
- moveDM_REGULATORKconfigentry from:drivers/power/Kconfigtodrivers/power/regulator/Kconfig
-drivers/power/Kconfig: include regulatorKconfigpath
-Kconfig: provide only general informations
-regulator-uclass.c: cleanup
-regulator-uclass.c: allow init regulator with name only
-regulator-uclass.c: removepmic_get_uclass_opsand usedev_get_driver_ops
-regulator-uclass.c: add use ofuclass_get_device_by_name()
-regulator.h: add 'structdm_regulator_uclass_platdata'
-regulator.h: API documentation cleanup
- regulator - add binding info--- Makefile | 3 +- doc/device-tree-bindings/regulator/regulator.txt | 55 ++++ drivers/power/Kconfig | 2 + drivers/power/regulator/Kconfig | 17 + drivers/power/regulator/Makefile | 8 + drivers/power/regulator/regulator-uclass.c | 300 ++++++++++++++++++ include/dm/uclass-id.h | 1 + include/power/regulator.h | 384 +++++++++++++++++++++++ 8 files changed, 769 insertions(+), 1 deletion(-)Quoted 5 lines
create mode 100644
doc/device-tree-bindings/regulator/regulator.txtcreate mode 100644drivers/power/regulator/Kconfigcreate mode 100644drivers/power/regulator/Makefilecreate mode 100644drivers/power/regulator/regulator-uclass.ccreate mode 100644include/power/regulator.hA few more nits for later.
Quoted 233 lines
Makefile +2
-1@@ -645,7 +645,8 @@ libs-y += drivers/power/ \ drivers/power/fuel_gauge/ \ drivers/power/mfd/ \ drivers/power/pmic/ \ - drivers/power/battery/ + drivers/power/battery/ \ + drivers/power/regulator/ libs-y += drivers/spi/ libs-$(CONFIG_FMAN_ENET) += drivers/net/fm/ libs-$(CONFIG_SYS_FSL_DDR) += drivers/ddr/fsl/doc/device-tree-bindings/regulator/regulator.txt new file +55
-0@@ -0,0 +1,55 @@ +Voltage/Current regulator + +Binding: +The regulator devices don't use the "compatible" property. The binding is done +by the prefix of regulator node's name. Usually the pmic I/O driver will provide +the array of 'struct pmic_child_info' with the prefixes and compatible drivers. +The bind is done by calling function: pmic_bind_childs(). +Example drivers: +pmic: drivers/power/pmic/max77686.c +regulator: drivers/power/regulator/max77686.c + +For the node name e.g.: "prefix[:alpha:]num { ... }": +- the driver prefix should be: "prefix" or "PREFIX" - case insensitive +- the node name's "num" is set as "dev->driver_data" on bind + +Example the prefix "ldo" will pass for: "ldo1", "ldo at 1", "LDO1", "LDOREG at 1"... + +Required properties: +- regulator-name: a string, required by the regulator uclass + +Note +The "regulator-name" constraint is used for setting the device's uclass +platform data '.name' field. And the regulator device name is set from +it's node name. + +Optional properties: +- regulator-min-microvolt: a minimum allowed Voltage value +- regulator-max-microvolt: a maximum allowed Voltage value +- regulator-min-microamp: a minimum allowed Current value +- regulator-max-microamp: a maximum allowed Current value +- regulator-always-on: regulator should never be disabled +- regulator-boot-on: enabled by bootloader/firmware + +Other kernel-style properties, are currently not used. + +Note: +For the regulator autoset from constraints, the framework expects that: +- regulator-min-microvolt is equal to regulator-max-microvolt +- regulator-min-microamp is equal to regulator-max-microamp +- regulator-always-on or regulator-boot-on is set + +Example: +ldo0 { + /* Mandatory */ + regulator-name = "VDDQ_EMMC_1.8V"; + + /* Optional */ + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-min-microamp = <100000>; + regulator-max-microamp = <100000>; + regulator-always-on; + regulator-boot-on; +}; +drivers/power/Kconfig +2
-0@@ -2,6 +2,8 @@ menu "Power" source "drivers/power/pmic/Kconfig" +source "drivers/power/regulator/Kconfig" + config AXP221_POWER boolean "axp221 / axp223 pmic support" depends on MACH_SUN6I || MACH_SUN8Idrivers/power/regulator/Kconfig new file +17
-0@@ -0,0 +1,17 @@ +config DM_REGULATOR + bool "Enable Driver Model for REGULATOR drivers (UCLASS_REGULATOR)" + depends on DM + ---help--- + This config enables the driver model regulator support. + UCLASS_REGULATOR - designed to provide a common API for basic regulator's + functions, like get/set Voltage or Current value, enable state, etc... + Note: + When enabling this, please read the description, found in the files: + - 'include/power/pmic.h' + - 'include/power/regulator.h' + - 'drivers/power/pmic/pmic-uclass.c' + - 'drivers/power/pmic/regulator-uclass.c' + It's important to call the device_bind() with the proper node offset, + when binding the regulator devices. The pmic_bind_childs() can be used + for this purpose if PMIC I/O driver is implemented or dm_scan_fdt_node() + otherwise. Detailed informations can be found in the header file.drivers/power/regulator/Makefile new file +8
-0@@ -0,0 +1,8 @@ +# +# Copyright (C) 2015 Samsung Electronics +# Przemyslaw Marczak <[email protected]> +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-$(CONFIG_DM_REGULATOR) += regulator-uclass.odrivers/power/regulator/regulator-uclass.c new file +101
-0@@ -0,0 +1,300 @@ +/* +* Copyright (C) 2014-2015 Samsung Electronics +* Przemyslaw Marczak <[email protected]> +* +* SPDX-License-Identifier: GPL-2.0+ +*/ +#include <common.h> +#include <fdtdec.h> +#include <errno.h> +#include <dm.h> +#include <dm/uclass-internal.h> +#include <power/pmic.h> +#include <power/regulator.h> + +DECLARE_GLOBAL_DATA_PTR ; + +int regulator_mode (struct udevice *dev,struct dm_regulator_mode **modep) +{ +struct dm_regulator_uclass_platdata *uc_pdata; + + *modep =NULL ; + + uc_pdata =dev_get_uclass_platdata (dev); +if (!uc_pdata) +return -ENXIO ; + + *modep = uc_pdata->mode; +return uc_pdata->mode_count; +} + +int regulator_get_value (struct udevice *dev) +{ +const struct dm_regulator_ops *ops =dev_get_driver_ops (dev); + +if (!ops || !ops->get_value) +return -ENOSYS ; + +return ops->get_value (dev); +} + +int regulator_set_value (struct udevice *dev,int uV) +{ +const struct dm_regulator_ops *ops =dev_get_driver_ops (dev); + +if (!ops || !ops->set_value) +return -ENOSYS ; + +return ops->set_value (dev, uV); +} + +int regulator_get_current (struct udevice *dev) +{ +const struct dm_regulator_ops *ops =dev_get_driver_ops (dev); + +if (!ops || !ops->get_current) +return -ENOSYS ; + +return ops->get_current (dev); +} + +int regulator_set_current (struct udevice *dev,int uA) +{ +const struct dm_regulator_ops *ops =dev_get_driver_ops (dev); + +if (!ops || !ops->set_current) +return -ENOSYS ; + +return ops->set_current (dev, uA); +} + +bool regulator_get_enable (struct udevice *dev) +{ +const struct dm_regulator_ops *ops =dev_get_driver_ops (dev); + +if (!ops || !ops->get_enable) +return -ENOSYS ; + +return ops->get_enable (dev); +} + +int regulator_set_enable (struct udevice *dev,bool enable) +{ +const struct dm_regulator_ops *ops =dev_get_driver_ops (dev); + +if (!ops || !ops->set_enable) +return -ENOSYS ; + +return ops->set_enable (dev, enable); +} + +int regulator_get_mode (struct udevice *dev) +{ +const struct dm_regulator_ops *ops =dev_get_driver_ops (dev); + +if (!ops || !ops->get_mode) +return -ENOSYS ; + +return ops->get_mode (dev); +} + +int regulator_set_mode (struct udevice *dev,int mode)drivers/power/regulator/regulator-uclass.c line 111
Quoted 10 lines
drivers/power/regulator/regulator-uclass.c new file +10
-0+{ +const struct dm_regulator_ops *ops =dev_get_driver_ops (dev); + +if (!ops || !ops->set_mode) +return -ENOSYS ; + +return ops->set_mode (dev, mode); +} + +int regulator_by_platname (const char *plat_name,struct udevice **devp)
regulator_get_by_platname()
Quoted 2 lines
since it does probe the device
Ok.
Quoted 16 lines
Quoted 16 lines
drivers/power/regulator/regulator-uclass.c new file +16
-0+{ +struct dm_regulator_uclass_platdata *uc_pdata; +struct udevice *dev; + + *devp =NULL ; + +for (uclass_find_first_device (UCLASS_REGULATOR , &dev); + dev; +uclass_find_next_device (&dev)) { + uc_pdata =dev_get_uclass_platdata (dev); +if (!uc_pdata ||strcmp (plat_name, uc_pdata->name)) +continue ; + +return uclass_get_device_tail (dev,0 , devp); + } +
Quoted 9 lines
drivers/power/regulator/regulator-uclass.c line 133
Quoted 6 lines
drivers/power/regulator/regulator-uclass.c new file +6
-0+debug ("%s: can't find: %s\n" , __func__, plat_name); + +return -ENODEV ; +} + +int regulator_by_devname (const char *devname,struct udevice **devp)
regulator_get_by_devname
Ok.
Quoted 11 lines
Quoted 11 lines
drivers/power/regulator/regulator-uclass.c new file +11
-0+{ +return uclass_get_device_by_name (UCLASS_REGULATOR , devname, devp); +} + +static int setting_failed (int ret,bool verbose,const char *fmt, ...) +{ +va_list args; +char buf[64 ]; + +if (verbose == false) +return ret;
Quoted 9 lines
drivers/power/regulator/regulator-uclass.c line 150
Quoted 6 lines
drivers/power/regulator/regulator-uclass.c new file +6
-0+ +va_start (args, fmt); +vscnprintf (buf,sizeof (buf), fmt, args); +va_end (args); + +printf (buf);I wonder if we should have a
vprintf()in U-Boot?
Yes, it could be useful.
Quoted 10 lines
Quoted 10 lines
drivers/power/regulator/regulator-uclass.c new file +10
-0+ +if (!ret) +return 0 ; + +printf (" (ret: %d)" , ret); + +return ret; +} + +int regulator_by_platname_autoset_and_enable(const char *platname,
Quoted 9 lines
drivers/power/regulator/regulator-uclass.c line 166
Quoted 6 lines
drivers/power/regulator/regulator-uclass.c new file +6
-0+ struct udevice **devp, + bool verbose) +{ +struct dm_regulator_uclass_platdata *uc_pdata; +struct udevice *dev; +bool v = verbose;Can we drop this local var and just use 'verbose'
I added this to avoid breaking the line of call to setting_failed(). So I will use just failed(), and then can put the verbose with no line breaking inside 'if' brackets.
Quoted 52 lines
Quoted 52 lines
drivers/power/regulator/regulator-uclass.c new file +52
-0+int ret; + +if (devp) + *devp =NULL ; + + ret =regulator_by_platname (platname, &dev); +if (ret) { +error ("Can get the regulator: %s!" , platname); +return ret; + } + + uc_pdata =dev_get_uclass_platdata (dev); +if (!uc_pdata) { +error ("Can get the regulator %s uclass platdata!" , platname); +return -ENXIO ; + } + +if (v) +printf ("%s@%s: " , dev->name, uc_pdata->name); + +/* Those values are optional (-ENODATA if unset) */ +if ((uc_pdata->min_uV != -ENODATA ) && + (uc_pdata->max_uV != -ENODATA ) && + (uc_pdata->min_uV == uc_pdata->max_uV)) { + ret =regulator_set_value (dev, uc_pdata->min_uV); +if (setting_failed (ret, v,"set %d uV" , uc_pdata->min_uV)) + goto exit; + } + +/* Those values are optional (-ENODATA if unset) */ +if ((uc_pdata->min_uA != -ENODATA ) && + (uc_pdata->max_uA != -ENODATA ) && + (uc_pdata->min_uA == uc_pdata->max_uA)) { + ret =regulator_set_current (dev, uc_pdata->min_uA); +if (setting_failed (ret, v,"; set %d uA" , uc_pdata->min_uA)) + goto exit; + } + +if (!uc_pdata->always_on && !uc_pdata->boot_on) + goto retdev; + + ret =regulator_set_enable (dev, true); +if (setting_failed (ret, v,"; enabling" , uc_pdata->min_uA)) + goto exit; + +retdev: +if (devp) + *devp = dev; +exit: +if (v) +printf ("\n" ); +return ret;
Quoted 9 lines
drivers/power/regulator/regulator-uclass.c line 224
Quoted 6 lines
drivers/power/regulator/regulator-uclass.c new file +6
-0+} + +int regulator_by_platname_list_autoset_and_enable (const char *list_platname[], +int list_entries, +struct udevice *list_devp[], +bool verbose)I wonder if you could shorten this (e.g. to
regulator_list_autoset())?
I introduced macro: "regulator_list_autoset()" ininclude/power/regulator.h. Is it good?
Quoted 10 lines
Quoted 10 lines
drivers/power/regulator/regulator-uclass.c new file +10
-0+{ +struct udevice *dev; +int i, ret, success =0 ; + +for (i =0 ; i < list_entries; i++) { + ret =regulator_autoset (list_platname[i], &dev, verbose); +if (!ret) + success++; + +if (!list_devp)
Quoted 9 lines
drivers/power/regulator/regulator-uclass.c line 240
Quoted 6 lines
drivers/power/regulator/regulator-uclass.c new file +6
-0+continue ; + +if (ret) + list_devp[i] =NULL ; +else + list_devp[i] = dev;Shouldn't dev be NULL if ret is non-zero anyway?
Right, it always be if given. Will fix.
Quoted 8 lines
drivers/power/regulator/regulator-uclass.c line 243
Quoted 3 lines
drivers/power/regulator/regulator-uclass.c new file +3
-0+ } + +return (success != list_entries);return success ==
list_entries? 0 :-EIOor something. Better would be to record the first error you get and return that.
Ok, I will tune it.
Quoted 12 lines
Quoted 12 lines
drivers/power/regulator/regulator-uclass.c new file +12
-0+} + +static int regulator_post_bind (struct udevice *dev) +{ +struct dm_regulator_uclass_platdata *uc_pdata; +int offset = dev->of_offset; +const void *blob = gd->fdt_blob; + + uc_pdata =dev_get_uclass_platdata (dev); +if (!uc_pdata) +return -ENXIO ; +
Quoted 9 lines
drivers/power/regulator/regulator-uclass.c line 261
Quoted 6 lines
drivers/power/regulator/regulator-uclass.c new file +6
-0+/* Regulator's mandatory constraint */ + uc_pdata->name =fdt_getprop (blob, offset,"regulator-name" ,NULL ); +if (!uc_pdata->name) { +debug ("%s: dev: %s has no property 'regulator-name'\n" , + __func__, dev->name); +return -ENXIO ;
-EINVALas it indicates invalid device tree data.
Ok.
Quoted 106 lines
Quoted 93 lines
drivers/power/regulator/regulator-uclass.c new file +39
-0+ } + +return 0 ; +} + +static int regulator_pre_probe (struct udevice *dev) +{ +struct dm_regulator_uclass_platdata *uc_pdata; +int offset = dev->of_offset; + + uc_pdata =dev_get_uclass_platdata (dev); +if (!uc_pdata) +return -ENXIO ; + +/* Regulator's optional constraints */ + uc_pdata->min_uV =fdtdec_get_int (gd->fdt_blob, offset, +"regulator-min-microvolt" , -ENODATA ); + uc_pdata->max_uV =fdtdec_get_int (gd->fdt_blob, offset, +"regulator-max-microvolt" , -ENODATA ); + uc_pdata->min_uA =fdtdec_get_int (gd->fdt_blob, offset, +"regulator-min-microamp" , -ENODATA ); + uc_pdata->max_uA =fdtdec_get_int (gd->fdt_blob, offset, +"regulator-max-microamp" , -ENODATA ); + uc_pdata->always_on =fdtdec_get_bool (gd->fdt_blob, offset, +"regulator-always-on" ); + uc_pdata->boot_on =fdtdec_get_bool (gd->fdt_blob, offset, +"regulator-boot-on" ); + +return 0 ; +} + +UCLASS_DRIVER (regulator) = { + .id =UCLASS_REGULATOR , + .name ="regulator" , + .post_bind = regulator_post_bind, + .pre_probe = regulator_pre_probe, + .per_device_platdata_auto_alloc_size = +sizeof (struct dm_regulator_uclass_platdata ), +};include/dm/uclass-id.h +1
-0@@ -48,6 +48,7 @@ enum uclass_id {/* Power Management */ UCLASS_PMIC ,/* PMIC I/O device */ +UCLASS_REGULATOR ,/* REGULATOR device */ UCLASS_COUNT , UCLASS_INVALID = -1,include/power/regulator.h new file +36
-0@@ -0,0 +1,384 @@ +/* +* Copyright (C) 2014-2015 Samsung Electronics +* Przemyslaw Marczak <[email protected]> +* +* SPDX-License-Identifier: GPL-2.0+ +*/ + +#ifndef _INCLUDE_REGULATOR_H_ +#define _INCLUDE_REGULATOR_H_ + +/** +* U-Boot Voltage/Current Regulator +* ================================ +* +* The regulator API is based on a driver model, with the device tree support. +* And this header describes the functions and data types for the uclass id: +* 'UCLASS_REGULATOR' and the regulator driver API. +* +* The regulator uclass - is based on uclass platform data which is allocated, +* automatically for each regulator device on bind and 'dev->uclass_platdata' +* points to it. The data type is: 'struct dm_regulator_uclass_platdata'. +* The uclass file: 'drivers/power/regulator/regulator-uclass.c' +* +* The regulator device - is based on driver's model 'struct udevice'. +* The API can use regulator name in two meanings: +* - devname - the regulator device's name: 'dev->name' +* - platname - the device's platdata's name. So in the code it looks like: +* 'uc_pdata = dev->uclass_platdata'; 'name = uc_pdata->name'. +* +* The regulator device driver - provide an implementation of uclass operations +* pointed by 'dev->driver->ops' as a struct of type 'struct dm_regulator_ops'. +* +* To proper bind the regulator device, the device tree node should provide +* regulator constraints, like in the example below: +* +* ldo1 { include/power/regulator.h line 46
Quoted 10 lines
include/power/regulator.h new file +10
-0+* regulator-name = "VDD_MMC_1.8V"; (mandatory for bind) +* regulator-min-microvolt = <1000000>; (optional) +* regulator-max-microvolt = <1000000>; (optional) +* regulator-min-microamp = <1000>; (optional) +* regulator-max-microamp = <1000>; (optional) +* regulator-always-on; (optional) +* regulator-boot-on; (optional) +* }; +* +* Please take a notice, that for the proper operation at least name constraint Please note that for the proper
Quoted 4 lines
or
Note: For the proper
Ok.
Quoted 9 lines
include/power/regulator.h line 52
Quoted 6 lines
include/power/regulator.h new file +6
-0+* is needed, e.g. for call the device_by_platname(...). +* +* Regulator bind: +* For each regulator device, the device_bind() should be called with passed +* device tree offset. This is required for this uclass's '.post_bind' method, +* which do the scan on the device node, for the 'regulator-name' constraint. s/do/does/
Ok.
Quoted 11 lines
include/power/regulator.h line 58
Quoted 6 lines
include/power/regulator.h new file +6
-0+* If the parent is not a PMIC device, and the child is not bind by function: +* 'pmic_bind_childs()', then it's recommended to bind the device by call to +* dm_scan_fdt_node() - this is usually done automatically for bus devices, +* as a post bind method. +* Having the device's name constraint, we can call regulator_by_platname(), +* to find interesting regulator. Before return, the regulator is probed, How about:
s/to find interesting regulator/to find the required regulator/
Ok.
Quoted 10 lines
include/power/regulator.h line 67
Quoted 9 lines
include/power/regulator.h new file +9
-0+* and the rest of its constraints are put into the device's uclass platform +* data, by the uclass regulator '.pre_probe' method. +* +* For more info about PMIC bind, please refer to file: 'include/power/pmic.h' +* +* Note: +* Please do not use the device_bind_by_name() function, since it pass '-1' as +* device node offset - and the bind will fail on uclass .post_bind method, +* because of missing 'regulator-name' constraint.
Quoted 3 lines
Indeed. BTW I think i'm going to add a similar function which allows the node to be passed.
That's great, would be usefull.
Quoted 216 lines
Quoted 216 lines
include/power/regulator.h new file +216
-0+* +* +* Fixed Voltage/Current Regulator +* =============================== +* +* When fixed voltage regulator is needed, then enable the config: +* - CONFIG_DM_REGULATOR_FIXED +* +* The driver file: 'drivers/power/regulator/fixed.c', provides basic support +* for control the GPIO, and return the device tree constraint values. +* +* To bind the fixed voltage regulator device, we usually use a 'simple-bus' +* node as a parent. And 'regulator-fixed' for the driver compatible. This is +* the same as in the kernel. The example node of fixed regulator: +* +* simple-bus { +* compatible = "simple-bus"; +* #address-cells = <1>; +* #size-cells = <0>; +* +* blue_led { +* compatible = "regulator-fixed"; +* regulator-name = "VDD_LED_3.3V"; +* regulator-min-microvolt = <3300000>; +* regulator-max-microvolt = <3300000>; +* gpio = <&gpc1 0 GPIO_ACTIVE_LOW>; +* }; +* }; +* +* The fixed regulator devices also provide regulator uclass platform data. And +* devices bound from such node, can use the regulator drivers API. +*/ + +/* enum regulator_type - used for regulator_*() variant calls */ +enum regulator_type { +REGULATOR_TYPE_LDO =0 , +REGULATOR_TYPE_BUCK , +REGULATOR_TYPE_DVS , +REGULATOR_TYPE_FIXED , +REGULATOR_TYPE_OTHER , +}; + +/** +* struct dm_regulator_mode - this structure holds an information about +* each regulator operation mode. Probably in most cases - an array. +* This will be probably a driver-static data, since it is device-specific. +* +* @id - a driver-specific mode id +* @register_value - a driver-specific value for its mode id +* @name - the name of mode - used for regulator command +* Note: +* The field 'id', should be always a positive number, since the negative values +* are reserved for the errno numbers when returns the mode id. +*/ +struct dm_regulator_mode { +int id;/* Set only as >= 0 (negative value is reserved for errno) */ +int register_value; +const char *name; +}; + +/** +* struct dm_regulator_uclass_platdata - pointed by dev->uclass_platdata, and +* allocated on each regulator bind. This structure holds an information +* about each regulator's constraints and supported operation modes. +* There is no "step" voltage value - so driver should take care of this. +* +* @type - one of 'enum regulator_type' +* @mode - pointer to the regulator mode (array if more than one) +* @mode_count - number of '.mode' entries +* @min_uV* - minimum voltage (micro Volts) +* @max_uV* - maximum voltage (micro Volts) +* @min_uA* - minimum amperage (micro Amps) +* @max_uA* - maximum amperage (micro Amps) +* @always_on* - bool type, true or false +* @boot_on* - bool type, true or false +* @name** - fdt regulator name - should be taken from the device tree +* +* Note: +* * - set automatically on device probe by the uclass's '.pre_probe' method. +* ** - set automatically on device bind by the uclass's '.post_bind' method. +* The constraints: type, mode, mode_count, can be set by device driver, e.g. +* by the driver '.probe' method. +*/ +struct dm_regulator_uclass_platdata { +enum regulator_type type; +struct dm_regulator_mode *mode; +int mode_count; +int min_uV; +int max_uV; +int min_uA; +int max_uA; +bool always_on; +bool boot_on; +const char *name; +}; + +/* Regulator device operations */ +struct dm_regulator_ops { +/** +* The regulator output value function calls operates on a micro Volts. +* +* get/set_value - get/set output value of the given output number +* @dev - regulator device +* Sets: +* @uV - set the output value [micro Volts] +* Returns: output value [uV] on success or negative errno if fail. +*/ +int (*get_value)(struct udevice *dev); +int (*set_value)(struct udevice *dev,int uV); + +/** +* The regulator output current function calls operates on a micro Amps. +* +* get/set_current - get/set output current of the given output number +* @dev - regulator device +* Sets: +* @uA - set the output current [micro Amps] +* Returns: output value [uA] on success or negative errno if fail. +*/ +int (*get_current)(struct udevice *dev); +int (*set_current)(struct udevice *dev,int uA); + +/** +* The most basic feature of the regulator output is its enable state. +* +* get/set_enable - get/set enable state of the given output number +* @dev - regulator device +* Sets: +* @enable - set true - enable or false - disable +* Returns: true/false for get; or 0 / -errno for set. +*/ +bool (*get_enable)(struct udevice *dev); +int (*set_enable)(struct udevice *dev,bool enable); + +/** +* The 'get/set_mode()' function calls should operate on a driver +* specific mode definitions, which should be found in: +* field 'mode' of struct mode_desc. +* +* get/set_mode - get/set operation mode of the given output number +* @dev - regulator device +* Sets +* @mode_id - set output mode id (struct dm_regulator_mode->id) +* Returns: id/0 for get/set on success or negative errno if fail. +* Note: +* The field 'id' of struct type 'dm_regulator_mode', should be always +* positive number, since the negative is reserved for the error. +*/ +int (*get_mode)(struct udevice *dev); +int (*set_mode)(struct udevice *dev,int mode_id); +}; + +/** +* regulator_mode: returns a pointer to the array of regulator mode info +* +* @dev - pointer to the regulator device +* @modep - pointer to the returned mode info array +* Returns - count of modep entries on success or negative errno if fail. +*/ +int regulator_mode (struct udevice *dev,struct dm_regulator_mode **modep); + +/** +* regulator_get_value: get microvoltage voltage value of a given regulator +* +* @dev - pointer to the regulator device +* Returns - positive output value [uV] on success or negative errno if fail. +*/ +int regulator_get_value (struct udevice *dev); + +/** +* regulator_set_value: set the microvoltage value of a given regulator. +* +* @dev - pointer to the regulator device +* @uV - the output value to set [micro Volts] +* Returns - 0 on success or -errno val if fails +*/ +int regulator_set_value (struct udevice *dev,int uV); + +/** +* regulator_get_current: get microampere value of a given regulator +* +* @dev - pointer to the regulator device +* Returns - positive output current [uA] on success or negative errno if fail. +*/ +int regulator_get_current (struct udevice *dev); + +/** +* regulator_set_current: set the microampere value of a given regulator. +* +* @dev - pointer to the regulator device +* @uA - set the output current [micro Amps] +* Returns - 0 on success or -errno val if fails +*/ +int regulator_set_current (struct udevice *dev,int uA); + +/** +* regulator_get_enable: get regulator device enable state. +* +* @dev - pointer to the regulator device +* Returns - true/false of enable state +*/ +bool regulator_get_enable (struct udevice *dev); + +/** +* regulator_set_enable: set regulator enable state +* +* @dev - pointer to the regulator device +* @enable - set true or false +* Returns - 0 on success or -errno val if fails +*/ +int regulator_set_enable (struct udevice *dev,bool enable); + +/** +* regulator_get_mode: get mode of a given device regulator +* +* @dev - pointer to the regulator device
Quoted 9 lines
include/power/regulator.h line 288
Quoted 5 lines
include/power/regulator.h new file +5
-0+* Returns - positive mode number on success or -errno val if fails +* Note: +* The regulator driver should return one of defined, mode number rather, than +* the raw register value. The struct type 'mode_desc' provides a field 'mode' +* for this purpose and register_value for a raw register value. Can you please reword the first sentence? I don't understand what it is trying to say. Similar below.
Ok, will fix this.
Quoted 36 lines
Quoted 36 lines
include/power/regulator.h new file +36
-0+*/ +int regulator_get_mode (struct udevice *dev); + +/** +* regulator_set_mode: set given regulator mode +* +* @dev - pointer to the regulator device +* @mode - mode type (field 'mode' of struct mode_desc) +* Returns - 0 on success or -errno value if fails +* Note: +* The regulator driver should take one of defined, mode number rather +* than a raw register value. The struct type 'regulator_mode_desc' has +* a mode field for this purpose and register_value for a raw register value. +*/ +int regulator_set_mode (struct udevice *dev,int mode); + +/** +* regulator_by_platname_autoset_and_enable: setup the regulator given by +* its uclass's platform data '.name'. The setup depends on constraints found +* in device's uclass's platform data (struct dm_regulator_uclass_platdata): +* - Voltage value - will set - if '.min_uV' and '.max_uV' values are equal +* - Current limit - will set - if '.min_uA' and '.max_uA' values are equal +* - Enable - will set - if '.always_on' or '.boot_on' are set to true +* +* The function returns on first encountered error. +* +* @platname - expected string for dm_regulator_uclass_platdata .name field +* @devp - returned pointer to the regulator device - if non-NULL passed +* @verbose - (true/false) print regulator setup info, or be quiet +* Returns: 0 on success or negative value of errno. +* +* The returned 'regulator' device can be used with: +* - regulator_get/set_* +* For shorter call name, the below macro regulator_autoset() can be used. +*/ +int regulator_by_platname_autoset_and_enable(const char *platname,
Quoted 9 lines
include/power/regulator.h line 330
Quoted 6 lines
include/power/regulator.h new file +6
-0+struct udevice **devp, + bool verbose); + +#define regulator_autoset (platname, devp, verbose) \ + regulator_by_platname_autoset_and_enable(platname, devp, verbose) +Can we just use the shorter name for the function and avoid this #ifdef?
Ok.
Quoted 25 lines
include/power/regulator.h line 343
Quoted 13 lines
include/power/regulator.h new file +13
-0+/** +* regulator_by_platname_list_autoset_and_enable: setup the regulators given by +* list of its uclass's platform data '.name'. The setup depends on constraints +* found in device's uclass's platform data. The function loops with calls to: +* regulator_by_platname_autoset_and_enable() for each name of list. +* +* @list_platname - an array of expected strings for .name field of each +* regulator's uclass platdata +* @list_entries - number of regulator's name list entries +* @list_devp - an array of returned pointers to the successfully setup +* regulator devices if non-NULL passed +* @verbose - (true/false) print each regulator setup info, or be quiet +* Returns: 0 on successfully setup of all list entries or 1 otwerwise. otherwise
Quoted 9 lines
include/power/regulator.h new file +9
-0+* +* The returned 'regulator' devices can be used with: +* - regulator_get/set_* +* For shorter call name, the below macro regulator_list_autoset() can be used. +*/ +int regulator_by_platname_list_autoset_and_enable (const char *list_platname[], +int list_entries, +struct udevice *list_devp[], +bool verbose);
Quoted 9 lines
include/power/regulator.h line 356
Quoted 4 lines
include/power/regulator.h new file +4
-0+ +#define regulator_list_autoset (namelist, entries, devlist, verbose) \ + regulator_by_platname_list_autoset_and_enable(namelist, entries, \ + devlist, verbose)As above. With #defines it changes the name in the map output or debugger, which confuses people. An inline function is better, but in this case it may be better to just rename the function.
Okay, will fix both.
Quoted 16 lines
include/power/regulator.h line 369
Quoted 13 lines
include/power/regulator.h new file +13
-0+ +/** +* regulator_by_devname: returns the pointer to the pmic regulator device. +* Search by name, found in regulator device's name. +* +* @devname - expected string for 'dev->name' of regulator device +* @devp - returned pointer to the regulator device +* Returns: 0 on success or negative value of errno. +* +* The returned 'regulator' device can be used with: +* - regulator_get/set_* +*/ +int regulator_by_devname (const char *devname,struct udevice **devp);
regulator_get_by_devname
Quoted 16 lines
include/power/regulator.h line 382
Quoted 13 lines
include/power/regulator.h new file +13
-0+ +/** +* regulator_by_platname: returns the pointer to the pmic regulator device. +* Search by name, found in regulator uclass platdata. +* +* @platname - expected string for dm_regulator_uclass_platdata .name field +* @devp - returned pointer to the regulator device +* Returns: 0 on success or negative value of errno. +* +* The returned 'regulator' device can be used with: +* - regulator_get/set_* +*/ +int regulator_by_platname (const char *platname,struct udevice **devp);
regulator_get_by_platname
Also, will fix both.
Quoted 9 lines
Quoted 5 lines
include/power/regulator.h new file +2
-1+ +#endif /* _INCLUDE_REGULATOR_H_ */ --1.9.1
Regards,
Simon
Thank you again, will resend ASAP.
Best regards,
Signature · 4 lines
Przemyslaw Marczak Samsung R&D Institute Poland Samsung Electronics p.marczak at samsung.com
PATCH v4 6/16 dm: pmic: add pmic command
In reply to Przemyslaw MarczakThis is new command for the PMIC devices based on driver model PMIC API. Command features are unchanged:
- list UCLASS pmic devices
- show or [set] operating pmic device (NEW)
- dump registers
- read byte of register at address
- write byte to register at address
The only one change for this command is 'dev' subcommand.
---
Changes v3:
- new file
- add Kconfig
Changes V4:
- common/cmd_pmic.c: cleanup
- move config name: CONFIG_DM_PMIC_CMD to CONFIG_CMD_PMIC
--- common/Kconfig | 14 ++++ common/Makefile | 3 + common/cmd_pmic.c | 231 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 248 insertions(+) create mode 100644 common/cmd_pmic.c
common/Kconfig +14 -0
@@ -457,4 +457,18 @@ config BOOTSTAGE_STASH_SIZE endmenu +menu "Power commands" +config CMD_PMIC + bool "Enable Driver Model PMIC command" + depends on DM_PMIC + help + This is the pmic command, based on a driver model pmic's API. + Command features are unchanged: + - list - list pmic devices + - pmic dev <id> - show or [set] operating pmic device (NEW) + - pmic dump - dump registers + - pmic read address - read byte of register at address + - pmic write address - write byte to register at address + The only one change for this command is 'dev' subcommand. +endmenu endmenu
common/Makefile +3 -0
@@ -209,6 +209,9 @@ obj-$(CONFIG_UPDATE_TFTP) += update.o obj-$(CONFIG_USB_KEYBOARD) += usb_kbd.o obj-$(CONFIG_CMD_DFU) += cmd_dfu.o obj-$(CONFIG_CMD_GPT) += cmd_gpt.o + +# Power +obj-$(CONFIG_CMD_PMIC) += cmd_pmic.o endif ifdef CONFIG_SPL_BUILD
common/cmd_pmic.c new file +231 -0
231 lines not on this page · raw message
Signature · 1 line
1.9.1
PATCH v4 6/16 dm: pmic: add pmic command
Quoted 19 lines · Przemyslaw Marczak
This is new command for the PMIC devices based on driver model PMIC API. Command features are unchanged:
- list UCLASS pmic devices
- show or [set] operating pmic device (NEW)
- dump registers
- read byte of register at address
- write byte to register at addressThe only one change for this command is 'dev' subcommand.
Signed-off-by Przemyslaw Marczak <[email protected]>---
Changes v3:
- new file
- addKconfigChanges V4:
-common/cmd_pmic.c: cleanup
- move config name:CONFIG_DM_PMIC_CMDtoCONFIG_CMD_PMIC
Quoted 6 lines
--- common/Kconfig | 14 ++++ common/Makefile | 3 + common/cmd_pmic.c | 231 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 248 insertions(+) create mode 100644 common/cmd_pmic.c
PATCH v4 6/16 dm: pmic: add pmic command
Quoted 27 lines · Simon Glass
Quoted 19 lines · Przemyslaw Marczak
This is new command for the PMIC devices based on driver model PMIC API. Command features are unchanged:
- list UCLASS pmic devices
- show or [set] operating pmic device (NEW)
- dump registers
- read byte of register at address
- write byte to register at addressThe only one change for this command is 'dev' subcommand.
Signed-off-by Przemyslaw Marczak <[email protected]>---
Changes v3:
- new file
- addKconfigChanges V4:
-common/cmd_pmic.c: cleanup
- move config name:CONFIG_DM_PMIC_CMDtoCONFIG_CMD_PMICQuoted 6 lines
--- common/Kconfig | 14 ++++ common/Makefile | 3 + common/cmd_pmic.c | 231 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 248 insertions(+) create mode 100644 common/cmd_pmic.c
Quoted 1 line
Acked-by Simon Glass <[email protected]>
Applied to u-boot-dm/next, thanks!
PATCH v4 7/16 dm: regulator: add regulator command
In reply to Przemyslaw MarczakThis command is based on driver model regulator's API. The user interface provides:
- list UCLASS regulator devices
- show or [set] operating regulator device
- print constraints info
- print operating status
- print/[set] voltage value [uV] (force)
- print/[set] current value [uA]
- print/[set] operating mode id
- enable the regulator output
- disable the regulator output
The 'force' option can be used for setting the value which exceeds the constraints min/max limits.
---
Changes v3:
- new file
- Kconfig entry
Changes V4:
- cmd regulator: move platdata to uc pdata
- cmd_regulator: includes cleanup
- cmd_regulator: add get_curr_dev_and_pl() check type
- move config name: CONFIG_DM_REGULATOR_CMD to CONFIG_CMD_REGULATOR
- common/Kconfig - cleanup
--- common/Kconfig | 22 +++ common/Makefile | 1 + common/cmd_regulator.c | 403 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 426 insertions(+) create mode 100644 common/cmd_regulator.c
common/Kconfig +22 -0
@@ -470,5 +470,27 @@ config CMD_PMIC - pmic read address - read byte of register at address - pmic write address - write byte to register at address The only one change for this command is 'dev' subcommand. + +config CMD_REGULATOR + bool "Enable Driver Model REGULATOR command" + depends on DM_REGULATOR + help + This command is based on driver model regulator's API. + User interface features: + - list - list regulator devices + - regulator dev <id> - show or [set] operating regulator device + - regulator info - print constraints info + - regulator status - print operating status + - regulator value <val] <-f> - print/[set] voltage value [uV] + - regulator current <val> - print/[set] current value [uA] + - regulator mode <id> - print/[set] operating mode id + - regulator enable - enable the regulator output + - regulator disable - disable the regulator output + + The '-f' (force) option can be used for set the value which exceeds + the limits, which are found in device-tree and are kept in regulator's + uclass platdata structure. + endmenu + endmenu
common/Makefile +1 -0
@@ -212,6 +212,7 @@ obj-$(CONFIG_CMD_GPT) += cmd_gpt.o # Power obj-$(CONFIG_CMD_PMIC) += cmd_pmic.o +obj-$(CONFIG_CMD_REGULATOR) += cmd_regulator.o endif ifdef CONFIG_SPL_BUILD
common/cmd_regulator.c new file +403 -0
403 lines not on this page · raw message
Signature · 1 line
1.9.1
PATCH v4 7/16 dm: regulator: add regulator command
Hi Przemyslaw,
Quoted 27 lines · Przemyslaw Marczak
This command is based on driver model regulator's API. The user interface provides:
- list UCLASS regulator devices
- show or [set] operating regulator device
- print constraints info
- print operating status
- print/[set] voltage value [uV] (force)
- print/[set] current value [uA]
- print/[set] operating mode id
- enable the regulator output
- disable the regulator outputThe 'force' option can be used for setting the value which exceeds the constraints min/max limits.
Signed-off-by Przemyslaw Marczak <[email protected]>---
Changes v3:
- new file
-KconfigentryChanges V4:
- cmd regulator: move platdata to uc pdata
-cmd_regulator: includes cleanup
-cmd_regulator: addget_curr_dev_and_pl()check type
- move config name:CONFIG_DM_REGULATOR_CMDtoCONFIG_CMD_REGULATOR
- common/Kconfig - cleanup
Quoted 6 lines
--- common/Kconfig | 22 +++ common/Makefile | 1 + common/cmd_regulator.c | 403 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 426 insertions(+) create mode 100644 common/cmd_regulator.c
I have a few nits that could be dealt with by a follow-on patch.
Quoted 65 lines
common/Kconfig +22
-0@@ -470,5 +470,27 @@ config CMD_PMIC - pmic read address - read byte of register at address - pmic write address - write byte to register at address The only one change for this command is 'dev' subcommand. + +config CMD_REGULATOR + bool "Enable Driver Model REGULATOR command" + depends on DM_REGULATOR + help + This command is based on driver model regulator's API. + User interface features: + - list - list regulator devices + - regulator dev <id> - show or [set] operating regulator device + - regulator info - print constraints info + - regulator status - print operating status + - regulator value <val] <-f> - print/[set] voltage value [uV] + - regulator current <val> - print/[set] current value [uA] + - regulator mode <id> - print/[set] operating mode id + - regulator enable - enable the regulator output + - regulator disable - disable the regulator output + + The '-f' (force) option can be used for set the value which exceeds + the limits, which are found in device-tree and are kept in regulator's + uclass platdata structure. + endmenu + endmenucommon/Makefile +1
-0@@ -212,6 +212,7 @@ obj-$(CONFIG_CMD_GPT) += cmd_gpt.o # Power obj-$(CONFIG_CMD_PMIC) += cmd_pmic.o +obj-$(CONFIG_CMD_REGULATOR) += cmd_regulator.o endif ifdef CONFIG_SPL_BUILDcommon/cmd_regulator.c new file +14
-0@@ -0,0 +1,403 @@ +/* +* Copyright (C) 2014-2015 Samsung Electronics +* Przemyslaw Marczak <[email protected]> +* +* SPDX-License-Identifier: GPL-2.0+ +*/ +#include <common.h> +#include <errno.h> +#include <dm.h> +#include <dm/uclass-internal.h> +#include <power/regulator.h> + +#define LIMIT_SEQ 3 +#define LIMIT_DEVNAME 20
common/cmd_regulator.c line 24
Quoted 10 lines
common/cmd_regulator.c new file +10
-0+#define LIMIT_OFNAME 20 +#define LIMIT_INFO 16 + +static struct udevice *currdev; + +static int failed (const char *getset,const char *thing, +const char *for_dev,int ret) +{ +printf ("Can't %s %s %s.\nError: %d (%s)\n" , getset, thing, for_dev, + ret,errno_str (ret));
blank line here.
I worry that if someone gets one of these messages they will not be able to find it in the source code. How about passing in the full printf() string in each case, or just using printf() in situ? I don't think the code space saving is significant.
common/cmd_regulator.c line 28
Quoted 4 lines
common/cmd_regulator.c new file +4
-0+return CMD_RET_FAILURE ; +} + +static int regulator_get (bool list_only,int get_seq,struct udevice **devp)
This function seems to do multiple things (find and list). Should we split it into two?
common/cmd_regulator.c line 38
Quoted 10 lines
common/cmd_regulator.c new file +10
-0+{ +struct dm_regulator_uclass_platdata *uc_pdata; +struct udevice *dev; +int ret; + +if (devp) + *devp =NULL ; + +for (ret =uclass_first_device (UCLASS_REGULATOR , &dev); dev; + ret =uclass_next_device (&dev)) {
This will probe all regulators that it checks. I think it should avoid that. Do you mean to use
Quoted 42 lines
common/cmd_regulator.c new file +42
-0+if (list_only) { + uc_pdata =dev_get_uclass_platdata (dev); +printf ("|%*d | %*.*s @ %-*.*s| %s @ %s\n" , +LIMIT_SEQ , dev->seq, +LIMIT_DEVNAME ,LIMIT_DEVNAME , dev->name, +LIMIT_OFNAME ,LIMIT_OFNAME , uc_pdata->name, + dev->parent->name, +dev_get_uclass_name (dev->parent)); +continue ; + } + +if (dev->seq == get_seq) { +if (devp) + *devp = dev; +else +return -EINVAL ; + +return 0 ; + } + } + +if (list_only) +return ret; + +return -ENODEV ; +} + +static int do_dev (cmd_tbl_t *cmdtp,int flag,int argc,char *const argv[]) +{ +struct dm_regulator_uclass_platdata *uc_pdata; +int seq, ret = -ENXIO ; + +switch (argc) { +case 2 : + seq =simple_strtoul (argv[1 ],NULL ,0 ); + ret =uclass_get_device_by_seq (UCLASS_REGULATOR , seq, &currdev); +if (ret && (ret =regulator_get (false, seq, &currdev))) + goto failed; +case 1 : + uc_pdata =dev_get_uclass_platdata (currdev); +if (!uc_pdata) + goto failed;
common/cmd_regulator.c line 90
Quoted 10 lines
common/cmd_regulator.c new file +10
-0+ +printf ("dev: %d @ %s\n" , currdev->seq, uc_pdata->name); + } + +return CMD_RET_SUCCESS ; +failed: +return failed ("get" ,"the" ,"device" , ret); +} + +static int get_curr_dev_and_pl(struct udevice **devp,
What is pl? The name does not seem very meaningful to me.
Quoted 314 lines
common/cmd_regulator.c new file +313
-1+struct dm_regulator_uclass_platdata **uc_pdata, + bool allow_type_fixed) +{ + *devp =NULL ; + *uc_pdata =NULL ; + +if (!currdev) +return failed ("get" ,"current" ,"device" , -ENODEV ); + + *devp = currdev; + + *uc_pdata =dev_get_uclass_platdata (*devp); +if (!*uc_pdata) +return failed ("get" ,"regulator" ,"platdata" , -ENXIO ); + +if (!allow_type_fixed && (*uc_pdata)->type ==REGULATOR_TYPE_FIXED ) { +printf ("Operation not allowed for fixed regulator!\n" ); +return CMD_RET_FAILURE ; + } + +return CMD_RET_SUCCESS ; +} + +static int do_list (cmd_tbl_t *cmdtp,int flag,int argc,char *const argv[]) +{ +int ret; + +printf ("|%*s | %*.*s @ %-*.*s| %s @ %s\n" , +LIMIT_SEQ ,"Seq" , +LIMIT_DEVNAME ,LIMIT_DEVNAME ,"Name" , +LIMIT_OFNAME ,LIMIT_OFNAME ,"fdtname" , +"Parent" ,"uclass" ); + + ret =regulator_get (true,0 ,NULL ); +if (ret) +return CMD_RET_FAILURE ; + +return CMD_RET_SUCCESS ; +} + +static int constraint (const char *name,int val,const char *val_name) +{ +printf ("%-*s" ,LIMIT_INFO , name); +if (val <0 ) { +printf (" %s (err: %d)\n" ,errno_str (val), val); +return val; + } + +if (val_name) +printf (" %d (%s)\n" , val, val_name); +else +printf (" %d\n" , val); + +return 0 ; +} + +static const char *get_mode_name (struct dm_regulator_mode *mode, +int mode_count, +int mode_id) +{ +while (mode_count--) { +if (mode->id == mode_id) +return mode->name; + mode++; + } + +return NULL ; +} + +static int do_info (cmd_tbl_t *cmdtp,int flag,int argc,char *const argv[]) +{ +struct udevice *dev; +struct dm_regulator_uclass_platdata *uc_pdata; +struct dm_regulator_mode *modes; +const char *parent_uc; +int mode_count; +int ret; +int i; + + ret =get_curr_dev_and_pl (&dev, &uc_pdata, true); +if (ret) +return ret; + + parent_uc =dev_get_uclass_name (dev->parent); + +printf ("Uclass regulator dev %d info:\n" , dev->seq); +printf ("%-*s %s @ %s\n%-*s %s\n%-*s %s\n%-*s\n" , +LIMIT_INFO ,"* parent:" , dev->parent->name, parent_uc, +LIMIT_INFO ,"* dev name:" , dev->name, +LIMIT_INFO ,"* fdt name:" , uc_pdata->name, +LIMIT_INFO ,"* constraints:" ); + +constraint (" - min uV:" , uc_pdata->min_uV,NULL ); +constraint (" - max uV:" , uc_pdata->max_uV,NULL ); +constraint (" - min uA:" , uc_pdata->min_uA,NULL ); +constraint (" - max uA:" , uc_pdata->max_uA,NULL ); +constraint (" - always on:" , uc_pdata->always_on, + uc_pdata->always_on ?"true" :"false" ); +constraint (" - boot on:" , uc_pdata->boot_on, + uc_pdata->boot_on ?"true" :"false" ); + + mode_count =regulator_mode (dev, &modes); +constraint ("* op modes:" , mode_count,NULL ); + +for (i =0 ; i < mode_count; i++, modes++) +constraint (" - mode id:" , modes->id, modes->name); + +return CMD_RET_SUCCESS ; +} + +static int do_status (cmd_tbl_t *cmdtp,int flag,int argc,char *const argv[]) +{ +struct dm_regulator_uclass_platdata *uc_pdata; +int current, value, mode, ret; +const char *mode_name =NULL ; +struct udevice *dev; +bool enabled; + + ret =get_curr_dev_and_pl (&dev, &uc_pdata, true); +if (ret) +return ret; + + enabled =regulator_get_enable (dev); +constraint (" * enable:" , enabled, enabled ?"true" :"false" ); + + value =regulator_get_value (dev); +constraint (" * value uV:" , value,NULL ); + + current =regulator_get_current (dev); +constraint (" * current uA:" , current,NULL ); + + mode =regulator_get_mode (dev); + mode_name =get_mode_name (uc_pdata->mode, uc_pdata->mode_count, mode); +constraint (" * mode id:" , mode, mode_name); + +return CMD_RET_SUCCESS ; +} + +static int do_value (cmd_tbl_t *cmdtp,int flag,int argc,char *const argv[]) +{ +struct udevice *dev; +struct dm_regulator_uclass_platdata *uc_pdata; +int value; +int force; +int ret; + + ret =get_curr_dev_and_pl (&dev, &uc_pdata, argc ==1 ); +if (ret) +return ret; + +if (argc ==1 ) { + value =regulator_get_value (dev); +if (value <0 ) +return failed ("get" , uc_pdata->name,"voltage" , value); + +printf ("%d uV\n" , value); +return CMD_RET_SUCCESS ; + } + +if (argc ==3 ) + force = !strcmp ("-f" , argv[2 ]); +else + force =0 ; + + value =simple_strtoul (argv[1 ],NULL ,0 ); +if ((value < uc_pdata->min_uV || value > uc_pdata->max_uV) && !force) { +printf ("Value exceeds regulator constraint limits\n" ); +return CMD_RET_FAILURE ; + } + + ret =regulator_set_value (dev, value); +if (ret) +return failed ("set" , uc_pdata->name,"voltage value" , ret); + +return CMD_RET_SUCCESS ; +} + +static int do_current (cmd_tbl_t *cmdtp,int flag,int argc,char *const argv[]) +{ +struct udevice *dev; +struct dm_regulator_uclass_platdata *uc_pdata; +int current; +int ret; + + ret =get_curr_dev_and_pl (&dev, &uc_pdata, argc ==1 ); +if (ret) +return ret; + +if (argc ==1 ) { + current =regulator_get_current (dev); +if (current <0 ) +return failed ("get" , uc_pdata->name,"current" , current); + +printf ("%d uA\n" , current); +return CMD_RET_SUCCESS ; + } + + current =simple_strtoul (argv[1 ],NULL ,0 ); +if (current < uc_pdata->min_uA || current > uc_pdata->max_uA) { +printf ("Current exceeds regulator constraint limits\n" ); +return CMD_RET_FAILURE ; + } + + ret =regulator_set_current (dev, current); +if (ret) +return failed ("set" , uc_pdata->name,"current value" , ret); + +return CMD_RET_SUCCESS ; +} + +static int do_mode (cmd_tbl_t *cmdtp,int flag,int argc,char *const argv[]) +{ +struct udevice *dev; +struct dm_regulator_uclass_platdata *uc_pdata; +int new_mode; +int mode; +int ret; + + ret =get_curr_dev_and_pl (&dev, &uc_pdata, false); +if (ret) +return ret; + +if (argc ==1 ) { + mode =regulator_get_mode (dev); +if (mode <0 ) +return failed ("get" , uc_pdata->name,"mode" , mode); + +printf ("mode id: %d\n" , mode); +return CMD_RET_SUCCESS ; + } + + new_mode =simple_strtoul (argv[1 ],NULL ,0 ); + + ret =regulator_set_mode (dev, new_mode); +if (ret) +return failed ("set" , uc_pdata->name,"mode" , ret); + +return CMD_RET_SUCCESS ; +} + +static int do_enable (cmd_tbl_t *cmdtp,int flag,int argc,char *const argv[]) +{ +struct udevice *dev; +struct dm_regulator_uclass_platdata *uc_pdata; +int ret; + + ret =get_curr_dev_and_pl (&dev, &uc_pdata, true); +if (ret) +return ret; + + ret =regulator_set_enable (dev, true); +if (ret) +return failed ("enable" ,"regulator" , uc_pdata->name, ret); + +return CMD_RET_SUCCESS ; +} + +static int do_disable (cmd_tbl_t *cmdtp,int flag,int argc,char *const argv[]) +{ +struct udevice *dev; +struct dm_regulator_uclass_platdata *uc_pdata; +int ret; + + ret =get_curr_dev_and_pl (&dev, &uc_pdata, true); +if (ret) +return ret; + + ret =regulator_set_enable (dev, false); +if (ret) +return failed ("disable" ,"regulator" , uc_pdata->name, ret); + +return CMD_RET_SUCCESS ; +} + +static cmd_tbl_t subcmd[] = { +U_BOOT_CMD_MKENT (dev,2 ,1 , do_dev,"" ,"" ), +U_BOOT_CMD_MKENT (list,1 ,1 , do_list,"" ,"" ), +U_BOOT_CMD_MKENT (info,2 ,1 , do_info,"" ,"" ), +U_BOOT_CMD_MKENT (status,2 ,1 , do_status,"" ,"" ), +U_BOOT_CMD_MKENT (value,3 ,1 , do_value,"" ,"" ), +U_BOOT_CMD_MKENT (current,3 ,1 , do_current,"" ,"" ), +U_BOOT_CMD_MKENT (mode,2 ,1 , do_mode,"" ,"" ), +U_BOOT_CMD_MKENT (enable,1 ,1 , do_enable,"" ,"" ), +U_BOOT_CMD_MKENT (disable,1 ,1 , do_disable,"" ,"" ), +}; + +static int do_regulator (cmd_tbl_t *cmdtp,int flag,int argc, +char *const argv[]) +{ +cmd_tbl_t *cmd; + + argc--; + argv++; + + cmd =find_cmd_tbl (argv[0 ], subcmd,ARRAY_SIZE (subcmd)); +if (cmd ==NULL || argc > cmd->maxargs) +return CMD_RET_USAGE ; + +return cmd->cmd (cmdtp, flag, argc, argv); +} + +U_BOOT_CMD (regulator,CONFIG_SYS_MAXARGS ,1 , do_regulator, +"uclass operations" , +"list - list UCLASS regulator devices\n" +"regulator dev [id] - show or [set] operating regulator device\n" +"regulator [info] - print constraints info\n" +"regulator [status] - print operating status\n" +"regulator [value] [-f] - print/[set] voltage value [uV] (force)\n" +"regulator [current] - print/[set] current value [uA]\n" +"regulator [mode_id] - print/[set] operating mode id\n" +"regulator [enable] - enable the regulator output\n" +"regulator [disable] - disable the regulator output\n" +); --
Quoted 2 lines
1.9.1
Regards,
Simon
PATCH v4 7/16 dm: regulator: add regulator command
Quoted 37 lines · Simon Glass
Hi Przemyslaw,
Quoted 27 lines · Przemyslaw Marczak
This command is based on driver model regulator's API. The user interface provides:
- list UCLASS regulator devices
- show or [set] operating regulator device
- print constraints info
- print operating status
- print/[set] voltage value [uV] (force)
- print/[set] current value [uA]
- print/[set] operating mode id
- enable the regulator output
- disable the regulator outputThe 'force' option can be used for setting the value which exceeds the constraints min/max limits.
Signed-off-by Przemyslaw Marczak <[email protected]>---
Changes v3:
- new file
-KconfigentryChanges V4:
- cmd regulator: move platdata to uc pdata
-cmd_regulator: includes cleanup
-cmd_regulator: addget_curr_dev_and_pl()check type
- move config name:CONFIG_DM_REGULATOR_CMDtoCONFIG_CMD_REGULATOR
- common/Kconfig - cleanupQuoted 6 lines
--- common/Kconfig | 22 +++ common/Makefile | 1 + common/cmd_regulator.c | 403 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 426 insertions(+) create mode 100644 common/cmd_regulator.c
Quoted 3 lines
Acked-by Simon Glass <[email protected]>I have a few nits that could be dealt with by a follow-on patch.
Applied to u-boot-dm/next, thanks!
PATCH v4 7/16 dm: regulator: add regulator command
In reply to Simon GlassHello Simon,
Quoted 37 lines · Simon Glass
Hi Przemyslaw,
Quoted 27 lines · Przemyslaw Marczak
This command is based on driver model regulator's API. The user interface provides:
- list UCLASS regulator devices
- show or [set] operating regulator device
- print constraints info
- print operating status
- print/[set] voltage value [uV] (force)
- print/[set] current value [uA]
- print/[set] operating mode id
- enable the regulator output
- disable the regulator outputThe 'force' option can be used for setting the value which exceeds the constraints min/max limits.
Signed-off-by Przemyslaw Marczak <[email protected]>---
Changes v3:
- new file
-KconfigentryChanges V4:
- cmd regulator: move platdata to uc pdata
-cmd_regulator: includes cleanup
-cmd_regulator: addget_curr_dev_and_pl()check type
- move config name:CONFIG_DM_REGULATOR_CMDtoCONFIG_CMD_REGULATOR
- common/Kconfig - cleanupQuoted 6 lines
--- common/Kconfig | 22 +++ common/Makefile | 1 + common/cmd_regulator.c | 403 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 426 insertions(+)create mode 100644
common/cmd_regulator.c
Quoted 4 lines
Acked-by Simon Glass <[email protected]>I have a few nits that could be dealt with by a follow-on patch.
Ok.
Quoted 69 lines
Quoted 69 lines
common/Kconfig +22
-0@@ -470,5 +470,27 @@ config CMD_PMIC - pmic read address - read byte of register at address - pmic write address - write byte to register at address The only one change for this command is 'dev' subcommand. + +config CMD_REGULATOR + bool "Enable Driver Model REGULATOR command" + depends on DM_REGULATOR + help + This command is based on driver model regulator's API. + User interface features: + - list - list regulator devices + - regulator dev <id> - show or [set] operating regulator device + - regulator info - print constraints info + - regulator status - print operating status + - regulator value <val] <-f> - print/[set] voltage value [uV] + - regulator current <val> - print/[set] current value [uA] + - regulator mode <id> - print/[set] operating mode id + - regulator enable - enable the regulator output + - regulator disable - disable the regulator output + + The '-f' (force) option can be used for set the value which exceeds + the limits, which are found in device-tree and are kept in regulator's + uclass platdata structure. + endmenu + endmenucommon/Makefile +1
-0@@ -212,6 +212,7 @@ obj-$(CONFIG_CMD_GPT) += cmd_gpt.o # Power obj-$(CONFIG_CMD_PMIC) += cmd_pmic.o +obj-$(CONFIG_CMD_REGULATOR) += cmd_regulator.o endif ifdef CONFIG_SPL_BUILDcommon/cmd_regulator.c new file +18
-0@@ -0,0 +1,403 @@ +/* +* Copyright (C) 2014-2015 Samsung Electronics +* Przemyslaw Marczak <[email protected]> +* +* SPDX-License-Identifier: GPL-2.0+ +*/ +#include <common.h> +#include <errno.h> +#include <dm.h> +#include <dm/uclass-internal.h> +#include <power/regulator.h> + +#define LIMIT_SEQ 3 +#define LIMIT_DEVNAME 20 +#define LIMIT_OFNAME 20 +#define LIMIT_INFO 16 + +static struct udevice *currdev;
Quoted 8 lines
common/cmd_regulator.c line 24
Quoted 6 lines
common/cmd_regulator.c new file +6
-0+ +static int failed (const char *getset,const char *thing, +const char *for_dev,int ret) +{ +printf ("Can't %s %s %s.\nError: %d (%s)\n" , getset, thing, for_dev, + ret,errno_str (ret));blank line here.
I don't see the blank line here in the patch, which I send.
Quoted 6 lines
I worry that if someone gets one of these messages they will not be able to find it in the source code. How about passing in the full
printf()string in each case, or just usingprintf()in situ? I don't think the code space saving is significant.
It's not a debug message. And each one is different, and easy to grep "failed". The code is a little cleaner with this. Also the command code is not complicated.
Quoted 8 lines
common/cmd_regulator.c line 28
Quoted 4 lines
common/cmd_regulator.c new file +4
-0+return CMD_RET_FAILURE ; +} + +static int regulator_get (bool list_only,int get_seq,struct udevice **devp)This function seems to do multiple things (find and list). Should we split it into two?
Quoted 14 lines
common/cmd_regulator.c line 38
Quoted 10 lines
common/cmd_regulator.c new file +10
-0+{ +struct dm_regulator_uclass_platdata *uc_pdata; +struct udevice *dev; +int ret; + +if (devp) + *devp =NULL ; + +for (ret =uclass_first_device (UCLASS_REGULATOR , &dev); dev; + ret =uclass_next_device (&dev)) {This will probe all regulators that it checks. I think it should avoid that. Do you mean to use
Regarding the two above comments, we have two problems:
1. Getting the regulator by sequencial number (dev->seq). I think it's required, because only this method returns the right device. Disadvantage: need to probe all devices.
2. Getting the regulator by "regulator-name" (regulator_uclass_platdata->name).
This would be clean, but unreliable if we have few regulators with the same name - I think we should keep this in mind. Advantage: can use for non-probed devices.
And about the doing multiple things by the regulator_get(). Following your comments about avoiding the code duplication, I put those things into one function, since both actually do the same - loops over the uclass's devices.
So we can threat it as a subcommands:
- regulator_get list
- regulator_get dev
Maybe the enum { GET_LIST, GET_DEV } would be better, than the bool.
Is that really bad?
Quoted 46 lines
Quoted 46 lines
common/cmd_regulator.c new file +46
-0+if (list_only) { + uc_pdata =dev_get_uclass_platdata (dev); +printf ("|%*d | %*.*s @ %-*.*s| %s @ %s\n" , +LIMIT_SEQ , dev->seq, +LIMIT_DEVNAME ,LIMIT_DEVNAME , dev->name, +LIMIT_OFNAME ,LIMIT_OFNAME , uc_pdata->name, + dev->parent->name, +dev_get_uclass_name (dev->parent)); +continue ; + } + +if (dev->seq == get_seq) { +if (devp) + *devp = dev; +else +return -EINVAL ; + +return 0 ; + } + } + +if (list_only) +return ret; + +return -ENODEV ; +} + +static int do_dev (cmd_tbl_t *cmdtp,int flag,int argc,char *const argv[]) +{ +struct dm_regulator_uclass_platdata *uc_pdata; +int seq, ret = -ENXIO ; + +switch (argc) { +case 2 : + seq =simple_strtoul (argv[1 ],NULL ,0 ); + ret =uclass_get_device_by_seq (UCLASS_REGULATOR , seq, &currdev); +if (ret && (ret =regulator_get (false, seq, &currdev))) + goto failed; +case 1 : + uc_pdata =dev_get_uclass_platdata (currdev); +if (!uc_pdata) + goto failed; + +printf ("dev: %d @ %s\n" , currdev->seq, uc_pdata->name); + } +
Quoted 9 lines
common/cmd_regulator.c line 90
Quoted 6 lines
common/cmd_regulator.c new file +6
-0+return CMD_RET_SUCCESS ; +failed: +return failed ("get" ,"the" ,"device" , ret); +} + +static int get_curr_dev_and_pl(struct udevice **devp,What is pl? The name does not seem very meaningful to me.
The platdata, ok I will tune it.
Quoted 311 lines
Quoted 311 lines
common/cmd_regulator.c new file +311
-0+struct dm_regulator_uclass_platdata **uc_pdata, + bool allow_type_fixed) +{ + *devp =NULL ; + *uc_pdata =NULL ; + +if (!currdev) +return failed ("get" ,"current" ,"device" , -ENODEV ); + + *devp = currdev; + + *uc_pdata =dev_get_uclass_platdata (*devp); +if (!*uc_pdata) +return failed ("get" ,"regulator" ,"platdata" , -ENXIO ); + +if (!allow_type_fixed && (*uc_pdata)->type ==REGULATOR_TYPE_FIXED ) { +printf ("Operation not allowed for fixed regulator!\n" ); +return CMD_RET_FAILURE ; + } + +return CMD_RET_SUCCESS ; +} + +static int do_list (cmd_tbl_t *cmdtp,int flag,int argc,char *const argv[]) +{ +int ret; + +printf ("|%*s | %*.*s @ %-*.*s| %s @ %s\n" , +LIMIT_SEQ ,"Seq" , +LIMIT_DEVNAME ,LIMIT_DEVNAME ,"Name" , +LIMIT_OFNAME ,LIMIT_OFNAME ,"fdtname" , +"Parent" ,"uclass" ); + + ret =regulator_get (true,0 ,NULL ); +if (ret) +return CMD_RET_FAILURE ; + +return CMD_RET_SUCCESS ; +} + +static int constraint (const char *name,int val,const char *val_name) +{ +printf ("%-*s" ,LIMIT_INFO , name); +if (val <0 ) { +printf (" %s (err: %d)\n" ,errno_str (val), val); +return val; + } + +if (val_name) +printf (" %d (%s)\n" , val, val_name); +else +printf (" %d\n" , val); + +return 0 ; +} + +static const char *get_mode_name (struct dm_regulator_mode *mode, +int mode_count, +int mode_id) +{ +while (mode_count--) { +if (mode->id == mode_id) +return mode->name; + mode++; + } + +return NULL ; +} + +static int do_info (cmd_tbl_t *cmdtp,int flag,int argc,char *const argv[]) +{ +struct udevice *dev; +struct dm_regulator_uclass_platdata *uc_pdata; +struct dm_regulator_mode *modes; +const char *parent_uc; +int mode_count; +int ret; +int i; + + ret =get_curr_dev_and_pl (&dev, &uc_pdata, true); +if (ret) +return ret; + + parent_uc =dev_get_uclass_name (dev->parent); + +printf ("Uclass regulator dev %d info:\n" , dev->seq); +printf ("%-*s %s @ %s\n%-*s %s\n%-*s %s\n%-*s\n" , +LIMIT_INFO ,"* parent:" , dev->parent->name, parent_uc, +LIMIT_INFO ,"* dev name:" , dev->name, +LIMIT_INFO ,"* fdt name:" , uc_pdata->name, +LIMIT_INFO ,"* constraints:" ); + +constraint (" - min uV:" , uc_pdata->min_uV,NULL ); +constraint (" - max uV:" , uc_pdata->max_uV,NULL ); +constraint (" - min uA:" , uc_pdata->min_uA,NULL ); +constraint (" - max uA:" , uc_pdata->max_uA,NULL ); +constraint (" - always on:" , uc_pdata->always_on, + uc_pdata->always_on ?"true" :"false" ); +constraint (" - boot on:" , uc_pdata->boot_on, + uc_pdata->boot_on ?"true" :"false" ); + + mode_count =regulator_mode (dev, &modes); +constraint ("* op modes:" , mode_count,NULL ); + +for (i =0 ; i < mode_count; i++, modes++) +constraint (" - mode id:" , modes->id, modes->name); + +return CMD_RET_SUCCESS ; +} + +static int do_status (cmd_tbl_t *cmdtp,int flag,int argc,char *const argv[]) +{ +struct dm_regulator_uclass_platdata *uc_pdata; +int current, value, mode, ret; +const char *mode_name =NULL ; +struct udevice *dev; +bool enabled; + + ret =get_curr_dev_and_pl (&dev, &uc_pdata, true); +if (ret) +return ret; + + enabled =regulator_get_enable (dev); +constraint (" * enable:" , enabled, enabled ?"true" :"false" ); + + value =regulator_get_value (dev); +constraint (" * value uV:" , value,NULL ); + + current =regulator_get_current (dev); +constraint (" * current uA:" , current,NULL ); + + mode =regulator_get_mode (dev); + mode_name =get_mode_name (uc_pdata->mode, uc_pdata->mode_count, mode); +constraint (" * mode id:" , mode, mode_name); + +return CMD_RET_SUCCESS ; +} + +static int do_value (cmd_tbl_t *cmdtp,int flag,int argc,char *const argv[]) +{ +struct udevice *dev; +struct dm_regulator_uclass_platdata *uc_pdata; +int value; +int force; +int ret; + + ret =get_curr_dev_and_pl (&dev, &uc_pdata, argc ==1 ); +if (ret) +return ret; + +if (argc ==1 ) { + value =regulator_get_value (dev); +if (value <0 ) +return failed ("get" , uc_pdata->name,"voltage" , value); + +printf ("%d uV\n" , value); +return CMD_RET_SUCCESS ; + } + +if (argc ==3 ) + force = !strcmp ("-f" , argv[2 ]); +else + force =0 ; + + value =simple_strtoul (argv[1 ],NULL ,0 ); +if ((value < uc_pdata->min_uV || value > uc_pdata->max_uV) && !force) { +printf ("Value exceeds regulator constraint limits\n" ); +return CMD_RET_FAILURE ; + } + + ret =regulator_set_value (dev, value); +if (ret) +return failed ("set" , uc_pdata->name,"voltage value" , ret); + +return CMD_RET_SUCCESS ; +} + +static int do_current (cmd_tbl_t *cmdtp,int flag,int argc,char *const argv[]) +{ +struct udevice *dev; +struct dm_regulator_uclass_platdata *uc_pdata; +int current; +int ret; + + ret =get_curr_dev_and_pl (&dev, &uc_pdata, argc ==1 ); +if (ret) +return ret; + +if (argc ==1 ) { + current =regulator_get_current (dev); +if (current <0 ) +return failed ("get" , uc_pdata->name,"current" , current); + +printf ("%d uA\n" , current); +return CMD_RET_SUCCESS ; + } + + current =simple_strtoul (argv[1 ],NULL ,0 ); +if (current < uc_pdata->min_uA || current > uc_pdata->max_uA) { +printf ("Current exceeds regulator constraint limits\n" ); +return CMD_RET_FAILURE ; + } + + ret =regulator_set_current (dev, current); +if (ret) +return failed ("set" , uc_pdata->name,"current value" , ret); + +return CMD_RET_SUCCESS ; +} + +static int do_mode (cmd_tbl_t *cmdtp,int flag,int argc,char *const argv[]) +{ +struct udevice *dev; +struct dm_regulator_uclass_platdata *uc_pdata; +int new_mode; +int mode; +int ret; + + ret =get_curr_dev_and_pl (&dev, &uc_pdata, false); +if (ret) +return ret; + +if (argc ==1 ) { + mode =regulator_get_mode (dev); +if (mode <0 ) +return failed ("get" , uc_pdata->name,"mode" , mode); + +printf ("mode id: %d\n" , mode); +return CMD_RET_SUCCESS ; + } + + new_mode =simple_strtoul (argv[1 ],NULL ,0 ); + + ret =regulator_set_mode (dev, new_mode); +if (ret) +return failed ("set" , uc_pdata->name,"mode" , ret); + +return CMD_RET_SUCCESS ; +} + +static int do_enable (cmd_tbl_t *cmdtp,int flag,int argc,char *const argv[]) +{ +struct udevice *dev; +struct dm_regulator_uclass_platdata *uc_pdata; +int ret; + + ret =get_curr_dev_and_pl (&dev, &uc_pdata, true); +if (ret) +return ret; + + ret =regulator_set_enable (dev, true); +if (ret) +return failed ("enable" ,"regulator" , uc_pdata->name, ret); + +return CMD_RET_SUCCESS ; +} + +static int do_disable (cmd_tbl_t *cmdtp,int flag,int argc,char *const argv[]) +{ +struct udevice *dev; +struct dm_regulator_uclass_platdata *uc_pdata; +int ret; + + ret =get_curr_dev_and_pl (&dev, &uc_pdata, true); +if (ret) +return ret; + + ret =regulator_set_enable (dev, false); +if (ret) +return failed ("disable" ,"regulator" , uc_pdata->name, ret); + +return CMD_RET_SUCCESS ; +} + +static cmd_tbl_t subcmd[] = { +U_BOOT_CMD_MKENT (dev,2 ,1 , do_dev,"" ,"" ), +U_BOOT_CMD_MKENT (list,1 ,1 , do_list,"" ,"" ), +U_BOOT_CMD_MKENT (info,2 ,1 , do_info,"" ,"" ), +U_BOOT_CMD_MKENT (status,2 ,1 , do_status,"" ,"" ), +U_BOOT_CMD_MKENT (value,3 ,1 , do_value,"" ,"" ), +U_BOOT_CMD_MKENT (current,3 ,1 , do_current,"" ,"" ), +U_BOOT_CMD_MKENT (mode,2 ,1 , do_mode,"" ,"" ), +U_BOOT_CMD_MKENT (enable,1 ,1 , do_enable,"" ,"" ), +U_BOOT_CMD_MKENT (disable,1 ,1 , do_disable,"" ,"" ), +}; + +static int do_regulator (cmd_tbl_t *cmdtp,int flag,int argc, +char *const argv[]) +{ +cmd_tbl_t *cmd; + + argc--; + argv++; + + cmd =find_cmd_tbl (argv[0 ], subcmd,ARRAY_SIZE (subcmd)); +if (cmd ==NULL || argc > cmd->maxargs) +return CMD_RET_USAGE ; + +return cmd->cmd (cmdtp, flag, argc, argv); +} + +U_BOOT_CMD (regulator,CONFIG_SYS_MAXARGS ,1 , do_regulator, +"uclass operations" , +"list - list UCLASS regulator devices\n" +"regulator dev [id] - show or [set] operating regulator device\n" +"regulator [info] - print constraints info\n" +"regulator [status] - print operating status\n" +"regulator [value] [-f] - print/[set] voltage value [uV] (force)\n" +"regulator [current] - print/[set] current value [uA]\n" +"regulator [mode_id] - print/[set] operating mode id\n" + "regulator [enable] - enable the regulator output\n"
Quoted 9 lines
Quoted 5 lines
common/cmd_regulator.c new file +2
-1+"regulator [disable] - disable the regulator output\n" +); --1.9.1
Regards,
Simon
Best regards,
Signature · 4 lines
Przemyslaw Marczak Samsung R&D Institute Poland Samsung Electronics p.marczak at samsung.com
PATCH v4 7/16 dm: regulator: add regulator command
Hi Przemyslaw,
Quoted 137 lines · Przemyslaw Marczak
Hello Simon,
Quoted 42 lines · Simon Glass
Hi Przemyslaw,
Quoted 28 lines · Przemyslaw Marczak
This command is based on driver model regulator's API. The user interface provides:
- list UCLASS regulator devices
- show or [set] operating regulator device
- print constraints info
- print operating status
- print/[set] voltage value [uV] (force)
- print/[set] current value [uA]
- print/[set] operating mode id
- enable the regulator output
- disable the regulator outputThe 'force' option can be used for setting the value which exceeds the constraints min/max limits.
Signed-off-by Przemyslaw Marczak <[email protected]>---
Changes v3:
- new file
-KconfigentryChanges V4:
- cmd regulator: move platdata to uc pdata
-cmd_regulator: includes cleanup
-cmd_regulator: addget_curr_dev_and_pl()check type
- move config name:CONFIG_DM_REGULATOR_CMDtoCONFIG_CMD_REGULATOR
- common/Kconfig - cleanupQuoted 7 lines
--- common/Kconfig | 22 +++ common/Makefile | 1 + common/cmd_regulator.c | 403 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 426 insertions(+)create mode 100644
common/cmd_regulator.cQuoted 4 lines
Acked-by Simon Glass <[email protected]>I have a few nits that could be dealt with by a follow-on patch.
Ok.
Quoted 73 lines
Quoted 73 lines
common/Kconfig +18
-0@@ -470,5 +470,27 @@ config CMD_PMIC - pmic read address - read byte of register at address - pmic write address - write byte to register at address The only one change for this command is 'dev' subcommand. + +config CMD_REGULATOR + bool "Enable Driver Model REGULATOR command" + depends on DM_REGULATOR + help + This command is based on driver model regulator's API. + User interface features: + - list - list regulator devices + - regulator dev <id> - show or [set] operating regulator device + - regulator info - print constraints info + - regulator status - print operating status + - regulator value <val] <-f> - print/[set] voltage value [uV] + - regulator current <val> - print/[set] current value [uA] + - regulator mode <id> - print/[set] operating mode id + - regulator enable - enable the regulator output + - regulator disable - disable the regulator output + + The '-f' (force) option can be used for set the value whichexceeds
+ the limits, which are found in device-tree and are kept in
regulator'scommon/Kconfig +3
-0+ uclass platdata structure. + endmenu + endmenucommon/Makefile +1
-0@@ -212,6 +212,7 @@ obj-$(CONFIG_CMD_GPT) += cmd_gpt.o # Power obj-$(CONFIG_CMD_PMIC) += cmd_pmic.o +obj-$(CONFIG_CMD_REGULATOR) += cmd_regulator.o endif ifdef CONFIG_SPL_BUILDcommon/cmd_regulator.c new file +20
-0@@ -0,0 +1,403 @@ +/* +* Copyright (C) 2014-2015 Samsung Electronics +* Przemyslaw Marczak <[email protected]> +* +* SPDX-License-Identifier: GPL-2.0+ +*/ +#include <common.h> +#include <errno.h> +#include <dm.h> +#include <dm/uclass-internal.h> +#include <power/regulator.h> + +#define LIMIT_SEQ 3 +#define LIMIT_DEVNAME 20 +#define LIMIT_OFNAME 20 +#define LIMIT_INFO 16 + +static struct udevice *currdev; + +static int failed(const char *getset, const char *thing,Quoted 8 lines
Quoted 5 lines
common/cmd_regulator.c new file +3
-0+ const char *for_dev, int ret) +{ + printf("Can't %s %s %s.\nError: %d (%s)\n", getset, thing,
for_dev,
+ ret,errno_str(ret));blank line here.
Quoted 1 line
I don't see the blank line here in the patch, which I send.
Odd, there seem to be two blank lines there, and we only need one.
Quoted 11 lines
Quoted 7 lines
I worry that if someone gets one of these messages they will not be able to find it in the source code. How about passing in the full
printf()string in each case, or just usingprintf()in situ? I don't think the code space saving is significant.It's not a debug message. And each one is different, and easy to grep "failed". The code is a little cleaner with this. Also the command code is not complicated.
git grep -i failed |wc -l
2089
Is there some way to know it is a PMIC error message, and find it that way?
Quoted 27 lines
Quoted 11 lines
Quoted 6 lines
common/cmd_regulator.c new file +4
-0+return CMD_RET_FAILURE ; +} + +static int regulator_get(bool list_only, int get_seq, struct udevice**devp)
This function seems to do multiple things (find and list). Should we split it into two?
Quoted 15 lines
common/cmd_regulator.c line 38
Quoted 10 lines
common/cmd_regulator.c new file +10
-0+{ +struct dm_regulator_uclass_platdata *uc_pdata; +struct udevice *dev; +int ret; + +if (devp) + *devp =NULL ; + +for (ret =uclass_first_device (UCLASS_REGULATOR , &dev); dev; + ret =uclass_next_device (&dev)) {This will probe all regulators that it checks. I think it should avoid that. Do you mean to use
Quoted 5 lines
Regarding the two above comments, we have two problems:
1. Getting the regulator by sequencial number (
dev->seq).
I think it's required, because only this method returns the right device.
Disadvantage: need to probe all devices.
But you can use req_seq, or if you have platform data, check that.
Quoted 6 lines
2. Getting the regulator by "regulator-name" (
regulator_uclass_platdata->name).
This would be clean, but unreliable if we have few regulators with the same name - I think we should keep this in mind. Advantage: can use for non-probed devices.
We could probably refuse to bind regulators with the same name. That's just going to lead to confusion.
Quoted 6 lines
And about the doing multiple things by the
regulator_get(). Following your comments about avoiding the code duplication, I put those things into one function, since both actually do the same - loops over the uclass's devices.
Quoted 6 lines
So we can threat it as a subcommands:
-regulator_getlist
-regulator_getdev
Maybe the enum {GET_LIST,GET_DEV} would be better, than the bool.Is that really bad?
I suspect it would be better as two completely separate functions, and probably not much more code size.
Quoted 394 lines
Quoted 52 lines
Quoted 52 lines
common/cmd_regulator.c new file +6
-0+if (list_only) { + uc_pdata =dev_get_uclass_platdata (dev); + printf("|%*d | %*.*s @ %-*.*s| %s @ %s\n", + LIMIT_SEQ, dev->seq, + LIMIT_DEVNAME, LIMIT_DEVNAME, dev->name, + LIMIT_OFNAME, LIMIT_OFNAME,
uc_pdata->name,common/cmd_regulator.c new file +22
-0+ dev->parent->name, + dev_get_uclass_name(dev->parent)); +continue ; + } + +if (dev->seq == get_seq) { +if (devp) + *devp = dev; +else +return -EINVAL ; + +return 0 ; + } + } + +if (list_only) +return ret; + +return -ENODEV ; +} + +static int do_dev(cmd_tbl_t *cmdtp, int flag, int argc, char * constargv[])
common/cmd_regulator.c new file +8
-0+{ +struct dm_regulator_uclass_platdata *uc_pdata; +int seq, ret = -ENXIO ; + +switch (argc) { +case 2 : + seq =simple_strtoul (argv[1 ],NULL ,0 ); + ret = uclass_get_device_by_seq(UCLASS_REGULATOR, seq,&currdev);
common/cmd_regulator.c new file +11
-0+if (ret && (ret =regulator_get (false, seq, &currdev))) + goto failed; +case 1 : + uc_pdata =dev_get_uclass_platdata (currdev); +if (!uc_pdata) + goto failed; + +printf ("dev: %d @ %s\n" , currdev->seq, uc_pdata->name); + } + +return CMD_RET_SUCCESS ;Quoted 9 lines
common/cmd_regulator.c line 90
Quoted 5 lines
common/cmd_regulator.c new file +5
-0+failed: +return failed ("get" ,"the" ,"device" , ret); +} + +static int get_curr_dev_and_pl(struct udevice **devp,What is pl? The name does not seem very meaningful to me.
The platdata, ok I will tune it.
Quoted 329 lines
Quoted 329 lines
+ struct
dm_regulator_uclass_platdata
**uc_pdata,common/cmd_regulator.c new file +15
-0+ bool allow_type_fixed) +{ + *devp = NULL; + *uc_pdata = NULL; + + if (!currdev) + return failed("get", "current", "device", -ENODEV); + + *devp = currdev; + + *uc_pdata = dev_get_uclass_platdata(*devp); + if (!*uc_pdata) + return failed("get", "regulator", "platdata", -ENXIO); + + if (!allow_type_fixed && (*uc_pdata)->type ==
REGULATOR_TYPE_FIXED) {common/cmd_regulator.c new file +8
-0+printf ("Operation not allowed for fixed regulator!\n" ); +return CMD_RET_FAILURE ; + } + +return CMD_RET_SUCCESS ; +} + +static int do_list(cmd_tbl_t *cmdtp, int flag, int argc, char * constargv[])
common/cmd_regulator.c new file +46
-0+{ +int ret; + +printf ("|%*s | %*.*s @ %-*.*s| %s @ %s\n" , +LIMIT_SEQ ,"Seq" , +LIMIT_DEVNAME ,LIMIT_DEVNAME ,"Name" , +LIMIT_OFNAME ,LIMIT_OFNAME ,"fdtname" , +"Parent" ,"uclass" ); + + ret =regulator_get (true,0 ,NULL ); +if (ret) +return CMD_RET_FAILURE ; + +return CMD_RET_SUCCESS ; +} + +static int constraint (const char *name,int val,const char *val_name) +{ +printf ("%-*s" ,LIMIT_INFO , name); +if (val <0 ) { +printf (" %s (err: %d)\n" ,errno_str (val), val); +return val; + } + +if (val_name) +printf (" %d (%s)\n" , val, val_name); +else +printf (" %d\n" , val); + +return 0 ; +} + +static const char *get_mode_name (struct dm_regulator_mode *mode, +int mode_count, +int mode_id) +{ +while (mode_count--) { +if (mode->id == mode_id) +return mode->name; + mode++; + } + +return NULL ; +} + +static int do_info(cmd_tbl_t *cmdtp, int flag, int argc, char * constargv[])
common/cmd_regulator.c new file +41
-0+{ +struct udevice *dev; +struct dm_regulator_uclass_platdata *uc_pdata; +struct dm_regulator_mode *modes; +const char *parent_uc; +int mode_count; +int ret; +int i; + + ret =get_curr_dev_and_pl (&dev, &uc_pdata, true); +if (ret) +return ret; + + parent_uc =dev_get_uclass_name (dev->parent); + +printf ("Uclass regulator dev %d info:\n" , dev->seq); +printf ("%-*s %s @ %s\n%-*s %s\n%-*s %s\n%-*s\n" , +LIMIT_INFO ,"* parent:" , dev->parent->name, parent_uc, +LIMIT_INFO ,"* dev name:" , dev->name, +LIMIT_INFO ,"* fdt name:" , uc_pdata->name, +LIMIT_INFO ,"* constraints:" ); + +constraint (" - min uV:" , uc_pdata->min_uV,NULL ); +constraint (" - max uV:" , uc_pdata->max_uV,NULL ); +constraint (" - min uA:" , uc_pdata->min_uA,NULL ); +constraint (" - max uA:" , uc_pdata->max_uA,NULL ); +constraint (" - always on:" , uc_pdata->always_on, + uc_pdata->always_on ?"true" :"false" ); +constraint (" - boot on:" , uc_pdata->boot_on, + uc_pdata->boot_on ?"true" :"false" ); + + mode_count =regulator_mode (dev, &modes); +constraint ("* op modes:" , mode_count,NULL ); + +for (i =0 ; i < mode_count; i++, modes++) +constraint (" - mode id:" , modes->id, modes->name); + +return CMD_RET_SUCCESS ; +} + +static int do_status(cmd_tbl_t *cmdtp, int flag, int argc, char * constargv[])
common/cmd_regulator.c new file +22
-0+{ +struct dm_regulator_uclass_platdata *uc_pdata; +int current, value, mode, ret; +const char *mode_name =NULL ; +struct udevice *dev; +bool enabled; + + ret =get_curr_dev_and_pl (&dev, &uc_pdata, true); +if (ret) +return ret; + + enabled =regulator_get_enable (dev); +constraint (" * enable:" , enabled, enabled ?"true" :"false" ); + + value =regulator_get_value (dev); +constraint (" * value uV:" , value,NULL ); + + current =regulator_get_current (dev); +constraint (" * current uA:" , current,NULL ); + + mode =regulator_get_mode (dev); + mode_name = get_mode_name(uc_pdata->mode, uc_pdata->mode_count,mode);
common/cmd_regulator.c new file +6
-0+constraint (" * mode id:" , mode, mode_name); + +return CMD_RET_SUCCESS ; +} + +static int do_value(cmd_tbl_t *cmdtp, int flag, int argc, char * constargv[])
common/cmd_regulator.c new file +15
-0+{ +struct udevice *dev; +struct dm_regulator_uclass_platdata *uc_pdata; +int value; +int force; +int ret; + + ret =get_curr_dev_and_pl (&dev, &uc_pdata, argc ==1 ); +if (ret) +return ret; + +if (argc ==1 ) { + value =regulator_get_value (dev); +if (value <0 ) + return failed("get", uc_pdata->name, "voltage",value);
common/cmd_regulator.c new file +12
-0+ +printf ("%d uV\n" , value); +return CMD_RET_SUCCESS ; + } + +if (argc ==3 ) + force = !strcmp ("-f" , argv[2 ]); +else + force =0 ; + + value =simple_strtoul (argv[1 ],NULL ,0 ); + if ((value < uc_pdata->min_uV || value > uc_pdata->max_uV) &&!force) {
common/cmd_regulator.c new file +7
-0+printf ("Value exceeds regulator constraint limits\n" ); +return CMD_RET_FAILURE ; + } + + ret =regulator_set_value (dev, value); +if (ret) + return failed("set", uc_pdata->name, "voltage value",ret);
common/cmd_regulator.c new file +5
-0+ +return CMD_RET_SUCCESS ; +} + +static int do_current(cmd_tbl_t *cmdtp, int flag, int argc, char * constargv[])
common/cmd_regulator.c new file +14
-0+{ +struct udevice *dev; +struct dm_regulator_uclass_platdata *uc_pdata; +int current; +int ret; + + ret =get_curr_dev_and_pl (&dev, &uc_pdata, argc ==1 ); +if (ret) +return ret; + +if (argc ==1 ) { + current =regulator_get_current (dev); +if (current <0 ) + return failed("get", uc_pdata->name, "current",current);
common/cmd_regulator.c new file +14
-0+ +printf ("%d uA\n" , current); +return CMD_RET_SUCCESS ; + } + + current =simple_strtoul (argv[1 ],NULL ,0 ); +if (current < uc_pdata->min_uA || current > uc_pdata->max_uA) { +printf ("Current exceeds regulator constraint limits\n" ); +return CMD_RET_FAILURE ; + } + + ret =regulator_set_current (dev, current); +if (ret) + return failed("set", uc_pdata->name, "current value",ret);
common/cmd_regulator.c new file +5
-0+ +return CMD_RET_SUCCESS ; +} + +static int do_mode(cmd_tbl_t *cmdtp, int flag, int argc, char * constargv[])
common/cmd_regulator.c new file +15
-0+{ +struct udevice *dev; +struct dm_regulator_uclass_platdata *uc_pdata; +int new_mode; +int mode; +int ret; + + ret =get_curr_dev_and_pl (&dev, &uc_pdata, false); +if (ret) +return ret; + +if (argc ==1 ) { + mode =regulator_get_mode (dev); +if (mode <0 ) + return failed("get", uc_pdata->name, "mode",mode);
common/cmd_regulator.c new file +15
-0+ +printf ("mode id: %d\n" , mode); +return CMD_RET_SUCCESS ; + } + + new_mode =simple_strtoul (argv[1 ],NULL ,0 ); + + ret =regulator_set_mode (dev, new_mode); +if (ret) +return failed ("set" , uc_pdata->name,"mode" , ret); + +return CMD_RET_SUCCESS ; +} + +static int do_enable(cmd_tbl_t *cmdtp, int flag, int argc, char * constargv[])
common/cmd_regulator.c new file +12
-0+{ +struct udevice *dev; +struct dm_regulator_uclass_platdata *uc_pdata; +int ret; + + ret =get_curr_dev_and_pl (&dev, &uc_pdata, true); +if (ret) +return ret; + + ret =regulator_set_enable (dev, true); +if (ret) + return failed("enable", "regulator", uc_pdata->name,ret);
common/cmd_regulator.c new file +5
-0+ +return CMD_RET_SUCCESS ; +} + +static int do_disable(cmd_tbl_t *cmdtp, int flag, int argc, char * constargv[])
common/cmd_regulator.c new file +12
-0+{ +struct udevice *dev; +struct dm_regulator_uclass_platdata *uc_pdata; +int ret; + + ret =get_curr_dev_and_pl (&dev, &uc_pdata, true); +if (ret) +return ret; + + ret =regulator_set_enable (dev, false); +if (ret) + return failed("disable", "regulator", uc_pdata->name,ret);
common/cmd_regulator.c new file +35
-0+ +return CMD_RET_SUCCESS ; +} + +static cmd_tbl_t subcmd[] = { +U_BOOT_CMD_MKENT (dev,2 ,1 , do_dev,"" ,"" ), +U_BOOT_CMD_MKENT (list,1 ,1 , do_list,"" ,"" ), +U_BOOT_CMD_MKENT (info,2 ,1 , do_info,"" ,"" ), +U_BOOT_CMD_MKENT (status,2 ,1 , do_status,"" ,"" ), +U_BOOT_CMD_MKENT (value,3 ,1 , do_value,"" ,"" ), +U_BOOT_CMD_MKENT (current,3 ,1 , do_current,"" ,"" ), +U_BOOT_CMD_MKENT (mode,2 ,1 , do_mode,"" ,"" ), +U_BOOT_CMD_MKENT (enable,1 ,1 , do_enable,"" ,"" ), +U_BOOT_CMD_MKENT (disable,1 ,1 , do_disable,"" ,"" ), +}; + +static int do_regulator (cmd_tbl_t *cmdtp,int flag,int argc, +char *const argv[]) +{ +cmd_tbl_t *cmd; + + argc--; + argv++; + + cmd =find_cmd_tbl (argv[0 ], subcmd,ARRAY_SIZE (subcmd)); +if (cmd ==NULL || argc > cmd->maxargs) +return CMD_RET_USAGE ; + +return cmd->cmd (cmdtp, flag, argc, argv); +} + +U_BOOT_CMD (regulator,CONFIG_SYS_MAXARGS ,1 , do_regulator, +"uclass operations" , +"list - list UCLASS regulator devices\n" + "regulator dev [id] - show or [set] operating regulatordevice\n"
common/cmd_regulator.c new file +3
-0+"regulator [info] - print constraints info\n" +"regulator [status] - print operating status\n" + "regulator [value] [-f] - print/[set] voltage value [uV](force)\n"
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
common/cmd_regulator.c new file +5
-1+"regulator [current] - print/[set] current value [uA]\n" +"regulator [mode_id] - print/[set] operating mode id\n" +"regulator [enable] - enable the regulator output\n" +"regulator [disable] - disable the regulator output\n" +); --1.9.1
Regards,
Simon
PATCH v4 7/16 dm: regulator: add regulator command
Hello Simon,
Quoted 140 lines · Simon Glass
Hi Przemyslaw,
Quoted 137 lines · Przemyslaw Marczak
Hello Simon,
Quoted 42 lines · Simon Glass
Hi Przemyslaw,
Quoted 28 lines · Przemyslaw Marczak
This command is based on driver model regulator's API. The user interface provides:
- list UCLASS regulator devices
- show or [set] operating regulator device
- print constraints info
- print operating status
- print/[set] voltage value [uV] (force)
- print/[set] current value [uA]
- print/[set] operating mode id
- enable the regulator output
- disable the regulator outputThe 'force' option can be used for setting the value which exceeds the constraints min/max limits.
Signed-off-by Przemyslaw Marczak <[email protected]>---
Changes v3:
- new file
-KconfigentryChanges V4:
- cmd regulator: move platdata to uc pdata
-cmd_regulator: includes cleanup
-cmd_regulator: addget_curr_dev_and_pl()check type
- move config name:CONFIG_DM_REGULATOR_CMDtoCONFIG_CMD_REGULATOR
- common/Kconfig - cleanupQuoted 7 lines
--- common/Kconfig | 22 +++ common/Makefile | 1 + common/cmd_regulator.c | 403 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 426 insertions(+)create mode 100644
common/cmd_regulator.cQuoted 4 lines
Acked-by Simon Glass <[email protected]>I have a few nits that could be dealt with by a follow-on patch.
Ok.
Quoted 81 lines
Quoted 76 lines
common/Kconfig +18
-0@@ -470,5 +470,27 @@ config CMD_PMIC - pmic read address - read byte of register at address - pmic write address - write byte to register at address The only one change for this command is 'dev' subcommand. + +config CMD_REGULATOR + bool "Enable Driver Model REGULATOR command" + depends on DM_REGULATOR + help + This command is based on driver model regulator's API. + User interface features: + - list - list regulator devices + - regulator dev <id> - show or [set] operating regulator device + - regulator info - print constraints info + - regulator status - print operating status + - regulator value <val] <-f> - print/[set] voltage value [uV] + - regulator current <val> - print/[set] current value [uA] + - regulator mode <id> - print/[set] operating mode id + - regulator enable - enable the regulator output + - regulator disable - disable the regulator output + + The '-f' (force) option can be used for set the value whichexceeds
+ the limits, which are found in device-tree and are kept in
regulator'scommon/Kconfig +3
-0+ uclass platdata structure. + endmenu + endmenucommon/Makefile +1
-0@@ -212,6 +212,7 @@ obj-$(CONFIG_CMD_GPT) += cmd_gpt.o # Power obj-$(CONFIG_CMD_PMIC) += cmd_pmic.o +obj-$(CONFIG_CMD_REGULATOR) += cmd_regulator.o endif ifdef CONFIG_SPL_BUILDcommon/cmd_regulator.c new file +23
-0@@ -0,0 +1,403 @@ +/* +* Copyright (C) 2014-2015 Samsung Electronics +* Przemyslaw Marczak <[email protected]> +* +* SPDX-License-Identifier: GPL-2.0+ +*/ +#include <common.h> +#include <errno.h> +#include <dm.h> +#include <dm/uclass-internal.h> +#include <power/regulator.h> + +#define LIMIT_SEQ 3 +#define LIMIT_DEVNAME 20 +#define LIMIT_OFNAME 20 +#define LIMIT_INFO 16 + +static struct udevice *currdev; + +static int failed (const char *getset,const char *thing, +const char *for_dev,int ret) +{ + printf("Can't %s %s %s.\nError: %d (%s)\n", getset, thing,Quoted 2 lines
for_dev,
+ ret,errno_str(ret));blank line here.
Quoted 4 lines
Quoted 1 line
I don't see the blank line here in the patch, which I send.
Odd, there seem to be two blank lines there, and we only need one.
Ah, sorry. You mean, that there should be added a blank line. Ok, will add one.
Quoted 8 lines
Quoted 8 lines
Quoted 7 lines
I worry that if someone gets one of these messages they will not be able to find it in the source code. How about passing in the full
printf()string in each case, or just usingprintf()in situ? I don't think the code space saving is significant.
Quoted 9 lines
Quoted 3 lines
It's not a debug message. And each one is different, and easy to grep "failed". The code is a little cleaner with this. Also the command code is not complicated.
git grep -i failed |wc -l
2089Is there some way to know it is a PMIC error message, and find it that way?
Ok, I assumed that you know which command you called, and where to find it, so you could use:
grep -i "failed" common/cmd_regulator.c | wc -l
15
But this was only the function name, not a useful text for grep. Now I see that this should use the printf instead of the helper funcion.
Quoted 27 lines
Quoted 27 lines
Quoted 26 lines
Quoted 6 lines
common/cmd_regulator.c new file +4
-0+return CMD_RET_FAILURE ; +} + +static int regulator_get(bool list_only, int get_seq, struct udevice**devp)
This function seems to do multiple things (find and list). Should we split it into two?
common/cmd_regulator.c line 38
Quoted 10 lines
common/cmd_regulator.c new file +10
-0+{ +struct dm_regulator_uclass_platdata *uc_pdata; +struct udevice *dev; +int ret; + +if (devp) + *devp =NULL ; + +for (ret =uclass_first_device (UCLASS_REGULATOR , &dev); dev; + ret =uclass_next_device (&dev)) {This will probe all regulators that it checks. I think it should avoid that. Do you mean to use
Quoted 8 lines
Quoted 5 lines
Regarding the two above comments, we have two problems:
1. Getting the regulator by sequencial number (
dev->seq).
I think it's required, because only this method returns the right device.
Disadvantage: need to probe all devices.But you can use
req_seq, or if you have platform data, check that.
Ok, we could use the req_seq for the PMIC uclass, it's natural that interface, has its address and <reg> property - but this can repeat, if we have two PMICs on a different busses. This is probably possible.
We also shouldn't set the req_seq as the number found in node name, because those numbers can repeat: ldo1 {}; buck1 {}; regulator1 { }.
I think that, using the req_seq is bad idea, since we can't be sure that those values are unique.
I understand that, the probe is not ideal here? But from the other side, if we call "pmic list", then we are sure, that listed devices are ready to use. Shouldn't we expect this?
Quoted 10 lines
Quoted 6 lines
2. Getting the regulator by "regulator-name" (
regulator_uclass_platdata->name).
This would be clean, but unreliable if we have few regulators with the same name - I think we should keep this in mind. Advantage: can use for non-probed devices.We could probably refuse to bind regulators with the same name. That's just going to lead to confusion.
This could be good, because at present we can get only the first matching device, for the given "regulator-name" constraint. Ok, I need add the checking routine to regulator's post_bind() method. And then refuse the bind of the repeated one.
Quoted 11 lines
Quoted 11 lines
And about the doing multiple things by the
regulator_get(). Following your comments about avoiding the code duplication, I put those things into one function, since both actually do the same - loops over the uclass's devices.So we can threat it as a subcommands:
-regulator_getlist
-regulator_getdev
Maybe the enum {GET_LIST,GET_DEV} would be better, than the bool.
Quoted 5 lines
Quoted 1 line
Is that really bad?
I suspect it would be better as two completely separate functions, and probably not much more code size.
Ok.
Quoted 397 lines
Quoted 397 lines
Quoted 52 lines
Quoted 52 lines
common/cmd_regulator.c new file +6
-0+if (list_only) { + uc_pdata =dev_get_uclass_platdata (dev); + printf("|%*d | %*.*s @ %-*.*s| %s @ %s\n", + LIMIT_SEQ, dev->seq, + LIMIT_DEVNAME, LIMIT_DEVNAME, dev->name, + LIMIT_OFNAME, LIMIT_OFNAME,
uc_pdata->name,common/cmd_regulator.c new file +22
-0+ dev->parent->name, + dev_get_uclass_name(dev->parent)); +continue ; + } + +if (dev->seq == get_seq) { +if (devp) + *devp = dev; +else +return -EINVAL ; + +return 0 ; + } + } + +if (list_only) +return ret; + +return -ENODEV ; +} + +static int do_dev(cmd_tbl_t *cmdtp, int flag, int argc, char * constargv[])
common/cmd_regulator.c new file +8
-0+{ +struct dm_regulator_uclass_platdata *uc_pdata; +int seq, ret = -ENXIO ; + +switch (argc) { +case 2 : + seq =simple_strtoul (argv[1 ],NULL ,0 ); + ret = uclass_get_device_by_seq(UCLASS_REGULATOR, seq,&currdev);
common/cmd_regulator.c new file +11
-0+if (ret && (ret =regulator_get (false, seq, &currdev))) + goto failed; +case 1 : + uc_pdata =dev_get_uclass_platdata (currdev); +if (!uc_pdata) + goto failed; + +printf ("dev: %d @ %s\n" , currdev->seq, uc_pdata->name); + } + +return CMD_RET_SUCCESS ;Quoted 9 lines
common/cmd_regulator.c line 90
Quoted 5 lines
common/cmd_regulator.c new file +5
-0+failed: +return failed ("get" ,"the" ,"device" , ret); +} + +static int get_curr_dev_and_pl(struct udevice **devp,What is pl? The name does not seem very meaningful to me.
The platdata, ok I will tune it.
Quoted 332 lines
Quoted 332 lines
+ struct
dm_regulator_uclass_platdata
**uc_pdata,common/cmd_regulator.c new file +15
-0+ bool allow_type_fixed) +{ + *devp = NULL; + *uc_pdata = NULL; + + if (!currdev) + return failed("get", "current", "device", -ENODEV); + + *devp = currdev; + + *uc_pdata = dev_get_uclass_platdata(*devp); + if (!*uc_pdata) + return failed("get", "regulator", "platdata", -ENXIO); + + if (!allow_type_fixed && (*uc_pdata)->type ==
REGULATOR_TYPE_FIXED) {common/cmd_regulator.c new file +8
-0+printf ("Operation not allowed for fixed regulator!\n" ); +return CMD_RET_FAILURE ; + } + +return CMD_RET_SUCCESS ; +} + +static int do_list(cmd_tbl_t *cmdtp, int flag, int argc, char * constargv[])
common/cmd_regulator.c new file +46
-0+{ +int ret; + +printf ("|%*s | %*.*s @ %-*.*s| %s @ %s\n" , +LIMIT_SEQ ,"Seq" , +LIMIT_DEVNAME ,LIMIT_DEVNAME ,"Name" , +LIMIT_OFNAME ,LIMIT_OFNAME ,"fdtname" , +"Parent" ,"uclass" ); + + ret =regulator_get (true,0 ,NULL ); +if (ret) +return CMD_RET_FAILURE ; + +return CMD_RET_SUCCESS ; +} + +static int constraint (const char *name,int val,const char *val_name) +{ +printf ("%-*s" ,LIMIT_INFO , name); +if (val <0 ) { +printf (" %s (err: %d)\n" ,errno_str (val), val); +return val; + } + +if (val_name) +printf (" %d (%s)\n" , val, val_name); +else +printf (" %d\n" , val); + +return 0 ; +} + +static const char *get_mode_name (struct dm_regulator_mode *mode, +int mode_count, +int mode_id) +{ +while (mode_count--) { +if (mode->id == mode_id) +return mode->name; + mode++; + } + +return NULL ; +} + +static int do_info(cmd_tbl_t *cmdtp, int flag, int argc, char * constargv[])
common/cmd_regulator.c new file +41
-0+{ +struct udevice *dev; +struct dm_regulator_uclass_platdata *uc_pdata; +struct dm_regulator_mode *modes; +const char *parent_uc; +int mode_count; +int ret; +int i; + + ret =get_curr_dev_and_pl (&dev, &uc_pdata, true); +if (ret) +return ret; + + parent_uc =dev_get_uclass_name (dev->parent); + +printf ("Uclass regulator dev %d info:\n" , dev->seq); +printf ("%-*s %s @ %s\n%-*s %s\n%-*s %s\n%-*s\n" , +LIMIT_INFO ,"* parent:" , dev->parent->name, parent_uc, +LIMIT_INFO ,"* dev name:" , dev->name, +LIMIT_INFO ,"* fdt name:" , uc_pdata->name, +LIMIT_INFO ,"* constraints:" ); + +constraint (" - min uV:" , uc_pdata->min_uV,NULL ); +constraint (" - max uV:" , uc_pdata->max_uV,NULL ); +constraint (" - min uA:" , uc_pdata->min_uA,NULL ); +constraint (" - max uA:" , uc_pdata->max_uA,NULL ); +constraint (" - always on:" , uc_pdata->always_on, + uc_pdata->always_on ?"true" :"false" ); +constraint (" - boot on:" , uc_pdata->boot_on, + uc_pdata->boot_on ?"true" :"false" ); + + mode_count =regulator_mode (dev, &modes); +constraint ("* op modes:" , mode_count,NULL ); + +for (i =0 ; i < mode_count; i++, modes++) +constraint (" - mode id:" , modes->id, modes->name); + +return CMD_RET_SUCCESS ; +} + +static int do_status(cmd_tbl_t *cmdtp, int flag, int argc, char * constargv[])
common/cmd_regulator.c new file +22
-0+{ +struct dm_regulator_uclass_platdata *uc_pdata; +int current, value, mode, ret; +const char *mode_name =NULL ; +struct udevice *dev; +bool enabled; + + ret =get_curr_dev_and_pl (&dev, &uc_pdata, true); +if (ret) +return ret; + + enabled =regulator_get_enable (dev); +constraint (" * enable:" , enabled, enabled ?"true" :"false" ); + + value =regulator_get_value (dev); +constraint (" * value uV:" , value,NULL ); + + current =regulator_get_current (dev); +constraint (" * current uA:" , current,NULL ); + + mode =regulator_get_mode (dev); + mode_name = get_mode_name(uc_pdata->mode, uc_pdata->mode_count,mode);
common/cmd_regulator.c new file +6
-0+constraint (" * mode id:" , mode, mode_name); + +return CMD_RET_SUCCESS ; +} + +static int do_value(cmd_tbl_t *cmdtp, int flag, int argc, char * constargv[])
common/cmd_regulator.c new file +15
-0+{ +struct udevice *dev; +struct dm_regulator_uclass_platdata *uc_pdata; +int value; +int force; +int ret; + + ret =get_curr_dev_and_pl (&dev, &uc_pdata, argc ==1 ); +if (ret) +return ret; + +if (argc ==1 ) { + value =regulator_get_value (dev); +if (value <0 ) + return failed("get", uc_pdata->name, "voltage",value);
common/cmd_regulator.c new file +12
-0+ +printf ("%d uV\n" , value); +return CMD_RET_SUCCESS ; + } + +if (argc ==3 ) + force = !strcmp ("-f" , argv[2 ]); +else + force =0 ; + + value =simple_strtoul (argv[1 ],NULL ,0 ); + if ((value < uc_pdata->min_uV || value > uc_pdata->max_uV) &&!force) {
common/cmd_regulator.c new file +7
-0+printf ("Value exceeds regulator constraint limits\n" ); +return CMD_RET_FAILURE ; + } + + ret =regulator_set_value (dev, value); +if (ret) + return failed("set", uc_pdata->name, "voltage value",ret);
common/cmd_regulator.c new file +5
-0+ +return CMD_RET_SUCCESS ; +} + +static int do_current(cmd_tbl_t *cmdtp, int flag, int argc, char * constargv[])
common/cmd_regulator.c new file +14
-0+{ +struct udevice *dev; +struct dm_regulator_uclass_platdata *uc_pdata; +int current; +int ret; + + ret =get_curr_dev_and_pl (&dev, &uc_pdata, argc ==1 ); +if (ret) +return ret; + +if (argc ==1 ) { + current =regulator_get_current (dev); +if (current <0 ) + return failed("get", uc_pdata->name, "current",current);
common/cmd_regulator.c new file +14
-0+ +printf ("%d uA\n" , current); +return CMD_RET_SUCCESS ; + } + + current =simple_strtoul (argv[1 ],NULL ,0 ); +if (current < uc_pdata->min_uA || current > uc_pdata->max_uA) { +printf ("Current exceeds regulator constraint limits\n" ); +return CMD_RET_FAILURE ; + } + + ret =regulator_set_current (dev, current); +if (ret) + return failed("set", uc_pdata->name, "current value",ret);
common/cmd_regulator.c new file +5
-0+ +return CMD_RET_SUCCESS ; +} + +static int do_mode(cmd_tbl_t *cmdtp, int flag, int argc, char * constargv[])
common/cmd_regulator.c new file +15
-0+{ +struct udevice *dev; +struct dm_regulator_uclass_platdata *uc_pdata; +int new_mode; +int mode; +int ret; + + ret =get_curr_dev_and_pl (&dev, &uc_pdata, false); +if (ret) +return ret; + +if (argc ==1 ) { + mode =regulator_get_mode (dev); +if (mode <0 ) + return failed("get", uc_pdata->name, "mode",mode);
common/cmd_regulator.c new file +15
-0+ +printf ("mode id: %d\n" , mode); +return CMD_RET_SUCCESS ; + } + + new_mode =simple_strtoul (argv[1 ],NULL ,0 ); + + ret =regulator_set_mode (dev, new_mode); +if (ret) +return failed ("set" , uc_pdata->name,"mode" , ret); + +return CMD_RET_SUCCESS ; +} + +static int do_enable(cmd_tbl_t *cmdtp, int flag, int argc, char * constargv[])
common/cmd_regulator.c new file +12
-0+{ +struct udevice *dev; +struct dm_regulator_uclass_platdata *uc_pdata; +int ret; + + ret =get_curr_dev_and_pl (&dev, &uc_pdata, true); +if (ret) +return ret; + + ret =regulator_set_enable (dev, true); +if (ret) + return failed("enable", "regulator", uc_pdata->name,ret);
common/cmd_regulator.c new file +5
-0+ +return CMD_RET_SUCCESS ; +} + +static int do_disable(cmd_tbl_t *cmdtp, int flag, int argc, char * constargv[])
common/cmd_regulator.c new file +12
-0+{ +struct udevice *dev; +struct dm_regulator_uclass_platdata *uc_pdata; +int ret; + + ret =get_curr_dev_and_pl (&dev, &uc_pdata, true); +if (ret) +return ret; + + ret =regulator_set_enable (dev, false); +if (ret) + return failed("disable", "regulator", uc_pdata->name,ret);
common/cmd_regulator.c new file +35
-0+ +return CMD_RET_SUCCESS ; +} + +static cmd_tbl_t subcmd[] = { +U_BOOT_CMD_MKENT (dev,2 ,1 , do_dev,"" ,"" ), +U_BOOT_CMD_MKENT (list,1 ,1 , do_list,"" ,"" ), +U_BOOT_CMD_MKENT (info,2 ,1 , do_info,"" ,"" ), +U_BOOT_CMD_MKENT (status,2 ,1 , do_status,"" ,"" ), +U_BOOT_CMD_MKENT (value,3 ,1 , do_value,"" ,"" ), +U_BOOT_CMD_MKENT (current,3 ,1 , do_current,"" ,"" ), +U_BOOT_CMD_MKENT (mode,2 ,1 , do_mode,"" ,"" ), +U_BOOT_CMD_MKENT (enable,1 ,1 , do_enable,"" ,"" ), +U_BOOT_CMD_MKENT (disable,1 ,1 , do_disable,"" ,"" ), +}; + +static int do_regulator (cmd_tbl_t *cmdtp,int flag,int argc, +char *const argv[]) +{ +cmd_tbl_t *cmd; + + argc--; + argv++; + + cmd =find_cmd_tbl (argv[0 ], subcmd,ARRAY_SIZE (subcmd)); +if (cmd ==NULL || argc > cmd->maxargs) +return CMD_RET_USAGE ; + +return cmd->cmd (cmdtp, flag, argc, argv); +} + +U_BOOT_CMD (regulator,CONFIG_SYS_MAXARGS ,1 , do_regulator, +"uclass operations" , +"list - list UCLASS regulator devices\n" + "regulator dev [id] - show or [set] operating regulatordevice\n"
common/cmd_regulator.c new file +3
-0+"regulator [info] - print constraints info\n" +"regulator [status] - print operating status\n" + "regulator [value] [-f] - print/[set] voltage value [uV](force)\n"
common/cmd_regulator.c new file +3
-0+"regulator [current] - print/[set] current value [uA]\n" +"regulator [mode_id] - print/[set] operating mode id\n" +"regulator [enable] - enable the regulator output\n"
Quoted 9 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
common/cmd_regulator.c new file +2
-1+"regulator [disable] - disable the regulator output\n" +); --1.9.1
Regards,
Simon
Best regards,
Signature · 4 lines
Przemyslaw Marczak Samsung R&D Institute Poland Samsung Electronics p.marczak at samsung.com
PATCH v4 7/16 dm: regulator: add regulator command
Hi Przemyslaw,
Quoted 238 lines · Przemyslaw Marczak
Hello Simon,
Quoted 150 lines · Simon Glass
Hi Przemyslaw,
Quoted 145 lines · Przemyslaw Marczak
Hello Simon,
Quoted 45 lines · Simon Glass
Hi Przemyslaw,
Quoted 29 lines · Przemyslaw Marczak
This command is based on driver model regulator's API. The user interface provides:
- list UCLASS regulator devices
- show or [set] operating regulator device
- print constraints info
- print operating status
- print/[set] voltage value [uV] (force)
- print/[set] current value [uA]
- print/[set] operating mode id
- enable the regulator output
- disable the regulator outputThe 'force' option can be used for setting the value which exceeds the constraints min/max limits.
Signed-off-by Przemyslaw Marczak <[email protected]>---
Changes v3:
- new file
-KconfigentryChanges V4:
- cmd regulator: move platdata to uc pdata
-cmd_regulator: includes cleanup
-cmd_regulator: addget_curr_dev_and_pl()check type
- move config name:CONFIG_DM_REGULATOR_CMDtoCONFIG_CMD_REGULATOR
- common/Kconfig - cleanupQuoted 7 lines
--- common/Kconfig | 22 +++ common/Makefile | 1 + common/cmd_regulator.c | 403 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 426 insertions(+)create mode 100644
common/cmd_regulator.cQuoted 4 lines
Acked-by Simon Glass <[email protected]>I have a few nits that could be dealt with by a follow-on patch.
Ok.
Quoted 84 lines
Quoted 77 lines
common/Kconfig +9
-0@@ -470,5 +470,27 @@ config CMD_PMIC - pmic read address - read byte of register at address - pmic write address - write byte to register at address The only one change for this command is 'dev' subcommand. + +config CMD_REGULATOR + bool "Enable Driver Model REGULATOR command" + depends on DM_REGULATOR + help + This command is based on driver model regulator's API. + User interface features: + - list - list regulator devices + - regulator dev <id> - show or [set] operating regulatordevice
common/Kconfig +9
-0+ - regulator info - print constraints info + - regulator status - print operating status + - regulator value <val] <-f> - print/[set] voltage value [uV] + - regulator current <val> - print/[set] current value [uA] + - regulator mode <id> - print/[set] operating mode id + - regulator enable - enable the regulator output + - regulator disable - disable the regulator output + + The '-f' (force) option can be used for set the value whichexceeds
+ the limits, which are found in device-tree and are kept in
regulator'scommon/Kconfig +3
-0+ uclass platdata structure. + endmenu + endmenucommon/Makefile +1
-0@@ -212,6 +212,7 @@ obj-$(CONFIG_CMD_GPT) += cmd_gpt.o # Power obj-$(CONFIG_CMD_PMIC) += cmd_pmic.o +obj-$(CONFIG_CMD_REGULATOR) += cmd_regulator.o endif ifdef CONFIG_SPL_BUILDcommon/cmd_regulator.c new file +23
-0@@ -0,0 +1,403 @@ +/* +* Copyright (C) 2014-2015 Samsung Electronics +* Przemyslaw Marczak <[email protected]> +* +* SPDX-License-Identifier: GPL-2.0+ +*/ +#include <common.h> +#include <errno.h> +#include <dm.h> +#include <dm/uclass-internal.h> +#include <power/regulator.h> + +#define LIMIT_SEQ 3 +#define LIMIT_DEVNAME 20 +#define LIMIT_OFNAME 20 +#define LIMIT_INFO 16 + +static struct udevice *currdev; + +static int failed (const char *getset,const char *thing, +const char *for_dev,int ret) +{ + printf("Can't %s %s %s.\nError: %d (%s)\n", getset, thing,Quoted 3 lines
for_dev,
+ ret,errno_str(ret));blank line here.
Quoted 5 lines
Quoted 1 line
I don't see the blank line here in the patch, which I send.
Odd, there seem to be two blank lines there, and we only need one.
Ah, sorry. You mean, that there should be added a blank line. Ok, will add one.
Quoted 14 lines
Quoted 8 lines
Quoted 7 lines
I worry that if someone gets one of these messages they will not be able to find it in the source code. How about passing in the full
printf()string in each case, or just usingprintf()in situ? I don't think the code space saving is significant.Quoted 4 lines
It's not a debug message. And each one is different, and easy to grep "failed". The code is a little cleaner with this. Also the command code is
not complicated.Quoted 6 lines
git grep -i failed |wc -l
2089Is there some way to know it is a PMIC error message, and find it that way?
Ok, I assumed that you know which command you called, and where to find it, so you could use:
grep -i "failed"common/cmd_regulator.c| wc -l
15But this was only the function name, not a useful text for grep. Now I see that this should use the printf instead of the helper funcion.
Quoted 29 lines
Quoted 29 lines
Quoted 28 lines
Quoted 6 lines
common/cmd_regulator.c new file +4
-0+return CMD_RET_FAILURE ; +} + +static int regulator_get(bool list_only, int get_seq, struct udevice**devp)
This function seems to do multiple things (find and list). Should we split it into two?
common/cmd_regulator.c line 38
Quoted 10 lines
common/cmd_regulator.c new file +10
-0+{ +struct dm_regulator_uclass_platdata *uc_pdata; +struct udevice *dev; +int ret; + +if (devp) + *devp =NULL ; + +for (ret =uclass_first_device (UCLASS_REGULATOR , &dev); dev; + ret =uclass_next_device (&dev)) {This will probe all regulators that it checks. I think it should avoid that. Do you mean to use
Quoted 9 lines
Quoted 5 lines
Regarding the two above comments, we have two problems:
1. Getting the regulator by sequencial number (
dev->seq).
I think it's required, because only this method returns the right device.
Disadvantage: need to probe all devices.But you can use
req_seq, or if you have platform data, check that.Ok, we could use the
req_seqfor the PMIC uclass, it's natural that interface, has its address and <reg> property - but this can repeat, if we have two PMICs on a different busses. This is probably possible.We also shouldn't set the
req_seqas the number found in node name, because those numbers can repeat: ldo1 {}; buck1 {}; regulator1 { }.
Quoted 6 lines
I think that, using the
req_seqis bad idea, since we can't be sure that those values are unique.I understand that, the probe is not ideal here? But from the other side, if we call "pmic list", then we are sure, that listed devices are ready to use. Shouldn't we expect this?
I was hoping that we would not probe devices until they are actually used, and that listing them would not constitute 'use'.
In the case of listing, you should not need to worry about ->seq or ->req_seq. If you avoid 'getting' the device you will not probe it.
In the case of getting a device ready for use, yes, it must be probed. But I am only commenting on your 'list' function.
Quoted 31 lines
Quoted 10 lines
Quoted 8 lines
2. Getting the regulator by "regulator-name" (
regulator_uclass_platdata->name).
This would be clean, but unreliable if we have few regulators with the same
name - I think we should keep this in mind. Advantage: can use for non-probed devices.Quoted 3 lines
We could probably refuse to bind regulators with the same name. That's just going to lead to confusion.
This could be good, because at present we can get only the first matching device, for the given "regulator-name" constraint.
Ok, I need add the checking routine to regulator'spost_bind()method. And then refuse the bind of the repeated one.Quoted 12 lines
Quoted 12 lines
And about the doing multiple things by the
regulator_get(). Following your comments about avoiding the code duplication, I put those things into one function, since both actually do the same - loops over the
uclass's devices.So we can threat it as a subcommands:
-regulator_getlist
-regulator_getdev
Maybe the enum {GET_LIST,GET_DEV} would be better, than the bool.
Quoted 421 lines
Quoted 6 lines
Quoted 1 line
Is that really bad?
I suspect it would be better as two completely separate functions, and probably not much more code size.
Ok.
Quoted 411 lines
Quoted 400 lines
Quoted 53 lines
Quoted 53 lines
common/cmd_regulator.c new file +6
-0+if (list_only) { + uc_pdata =dev_get_uclass_platdata (dev); + printf("|%*d | %*.*s @ %-*.*s| %s @ %s\n", + LIMIT_SEQ, dev->seq, + LIMIT_DEVNAME, LIMIT_DEVNAME, dev->name, + LIMIT_OFNAME, LIMIT_OFNAME,
uc_pdata->name,common/cmd_regulator.c new file +22
-0+ dev->parent->name, + dev_get_uclass_name(dev->parent)); +continue ; + } + +if (dev->seq == get_seq) { +if (devp) + *devp = dev; +else +return -EINVAL ; + +return 0 ; + } + } + +if (list_only) +return ret; + +return -ENODEV ; +} + +static int do_dev(cmd_tbl_t *cmdtp, int flag, int argc, char * constargv[])
common/cmd_regulator.c new file +8
-0+{ +struct dm_regulator_uclass_platdata *uc_pdata; +int seq, ret = -ENXIO ; + +switch (argc) { +case 2 : + seq =simple_strtoul (argv[1 ],NULL ,0 ); + ret = uclass_get_device_by_seq(UCLASS_REGULATOR, seq,&currdev);
common/cmd_regulator.c new file +12
-0+if (ret && (ret =regulator_get (false, seq, &currdev))) + goto failed; +case 1 : + uc_pdata =dev_get_uclass_platdata (currdev); +if (!uc_pdata) + goto failed; + +printf ("dev: %d @ %s\n" , currdev->seq, uc_pdata->name); + } + +return CMD_RET_SUCCESS ; +failed:Quoted 9 lines
common/cmd_regulator.c line 90
Quoted 4 lines
common/cmd_regulator.c new file +4
-0+return failed ("get" ,"the" ,"device" , ret); +} + +static int get_curr_dev_and_pl(struct udevice **devp,What is pl? The name does not seem very meaningful to me.
The platdata, ok I will tune it.
Quoted 334 lines
Quoted 334 lines
+ struct
dm_regulator_uclass_platdata
**uc_pdata,common/cmd_regulator.c new file +15
-0+ bool allow_type_fixed) +{ + *devp = NULL; + *uc_pdata = NULL; + + if (!currdev) + return failed("get", "current", "device", -ENODEV); + + *devp = currdev; + + *uc_pdata = dev_get_uclass_platdata(*devp); + if (!*uc_pdata) + return failed("get", "regulator", "platdata", -ENXIO); + + if (!allow_type_fixed && (*uc_pdata)->type ==
REGULATOR_TYPE_FIXED) {common/cmd_regulator.c new file +8
-0+printf ("Operation not allowed for fixed regulator!\n" ); +return CMD_RET_FAILURE ; + } + +return CMD_RET_SUCCESS ; +} + +static int do_list(cmd_tbl_t *cmdtp, int flag, int argc, char * constargv[])
common/cmd_regulator.c new file +46
-0+{ +int ret; + +printf ("|%*s | %*.*s @ %-*.*s| %s @ %s\n" , +LIMIT_SEQ ,"Seq" , +LIMIT_DEVNAME ,LIMIT_DEVNAME ,"Name" , +LIMIT_OFNAME ,LIMIT_OFNAME ,"fdtname" , +"Parent" ,"uclass" ); + + ret =regulator_get (true,0 ,NULL ); +if (ret) +return CMD_RET_FAILURE ; + +return CMD_RET_SUCCESS ; +} + +static int constraint (const char *name,int val,const char *val_name) +{ +printf ("%-*s" ,LIMIT_INFO , name); +if (val <0 ) { +printf (" %s (err: %d)\n" ,errno_str (val), val); +return val; + } + +if (val_name) +printf (" %d (%s)\n" , val, val_name); +else +printf (" %d\n" , val); + +return 0 ; +} + +static const char *get_mode_name (struct dm_regulator_mode *mode, +int mode_count, +int mode_id) +{ +while (mode_count--) { +if (mode->id == mode_id) +return mode->name; + mode++; + } + +return NULL ; +} + +static int do_info(cmd_tbl_t *cmdtp, int flag, int argc, char * constargv[])
common/cmd_regulator.c new file +41
-0+{ +struct udevice *dev; +struct dm_regulator_uclass_platdata *uc_pdata; +struct dm_regulator_mode *modes; +const char *parent_uc; +int mode_count; +int ret; +int i; + + ret =get_curr_dev_and_pl (&dev, &uc_pdata, true); +if (ret) +return ret; + + parent_uc =dev_get_uclass_name (dev->parent); + +printf ("Uclass regulator dev %d info:\n" , dev->seq); +printf ("%-*s %s @ %s\n%-*s %s\n%-*s %s\n%-*s\n" , +LIMIT_INFO ,"* parent:" , dev->parent->name, parent_uc, +LIMIT_INFO ,"* dev name:" , dev->name, +LIMIT_INFO ,"* fdt name:" , uc_pdata->name, +LIMIT_INFO ,"* constraints:" ); + +constraint (" - min uV:" , uc_pdata->min_uV,NULL ); +constraint (" - max uV:" , uc_pdata->max_uV,NULL ); +constraint (" - min uA:" , uc_pdata->min_uA,NULL ); +constraint (" - max uA:" , uc_pdata->max_uA,NULL ); +constraint (" - always on:" , uc_pdata->always_on, + uc_pdata->always_on ?"true" :"false" ); +constraint (" - boot on:" , uc_pdata->boot_on, + uc_pdata->boot_on ?"true" :"false" ); + + mode_count =regulator_mode (dev, &modes); +constraint ("* op modes:" , mode_count,NULL ); + +for (i =0 ; i < mode_count; i++, modes++) +constraint (" - mode id:" , modes->id, modes->name); + +return CMD_RET_SUCCESS ; +} + +static int do_status(cmd_tbl_t *cmdtp, int flag, int argc, char *const
argv[])common/cmd_regulator.c new file +22
-0+{ +struct dm_regulator_uclass_platdata *uc_pdata; +int current, value, mode, ret; +const char *mode_name =NULL ; +struct udevice *dev; +bool enabled; + + ret =get_curr_dev_and_pl (&dev, &uc_pdata, true); +if (ret) +return ret; + + enabled =regulator_get_enable (dev); +constraint (" * enable:" , enabled, enabled ?"true" :"false" ); + + value =regulator_get_value (dev); +constraint (" * value uV:" , value,NULL ); + + current =regulator_get_current (dev); +constraint (" * current uA:" , current,NULL ); + + mode =regulator_get_mode (dev); + mode_name = get_mode_name(uc_pdata->mode, uc_pdata->mode_count,mode);
common/cmd_regulator.c new file +6
-0+constraint (" * mode id:" , mode, mode_name); + +return CMD_RET_SUCCESS ; +} + +static int do_value(cmd_tbl_t *cmdtp, int flag, int argc, char * constargv[])
common/cmd_regulator.c new file +15
-0+{ +struct udevice *dev; +struct dm_regulator_uclass_platdata *uc_pdata; +int value; +int force; +int ret; + + ret =get_curr_dev_and_pl (&dev, &uc_pdata, argc ==1 ); +if (ret) +return ret; + +if (argc ==1 ) { + value =regulator_get_value (dev); +if (value <0 ) + return failed("get", uc_pdata->name, "voltage",value);
common/cmd_regulator.c new file +12
-0+ +printf ("%d uV\n" , value); +return CMD_RET_SUCCESS ; + } + +if (argc ==3 ) + force = !strcmp ("-f" , argv[2 ]); +else + force =0 ; + + value =simple_strtoul (argv[1 ],NULL ,0 ); + if ((value < uc_pdata->min_uV || value > uc_pdata->max_uV) &&!force) {
common/cmd_regulator.c new file +7
-0+printf ("Value exceeds regulator constraint limits\n" ); +return CMD_RET_FAILURE ; + } + + ret =regulator_set_value (dev, value); +if (ret) + return failed("set", uc_pdata->name, "voltage value",ret);
common/cmd_regulator.c new file +5
-0+ +return CMD_RET_SUCCESS ; +} + +static int do_current(cmd_tbl_t *cmdtp, int flag, int argc, char *const
argv[])common/cmd_regulator.c new file +14
-0+{ +struct udevice *dev; +struct dm_regulator_uclass_platdata *uc_pdata; +int current; +int ret; + + ret =get_curr_dev_and_pl (&dev, &uc_pdata, argc ==1 ); +if (ret) +return ret; + +if (argc ==1 ) { + current =regulator_get_current (dev); +if (current <0 ) + return failed("get", uc_pdata->name, "current",current);
common/cmd_regulator.c new file +8
-0+ +printf ("%d uA\n" , current); +return CMD_RET_SUCCESS ; + } + + current =simple_strtoul (argv[1 ],NULL ,0 ); +if (current < uc_pdata->min_uA || current > uc_pdata->max_uA) { + printf("Current exceeds regulator constraintlimits\n");
common/cmd_regulator.c new file +6
-0+return CMD_RET_FAILURE ; + } + + ret =regulator_set_current (dev, current); +if (ret) + return failed("set", uc_pdata->name, "current value",ret);
common/cmd_regulator.c new file +5
-0+ +return CMD_RET_SUCCESS ; +} + +static int do_mode(cmd_tbl_t *cmdtp, int flag, int argc, char * constargv[])
common/cmd_regulator.c new file +15
-0+{ +struct udevice *dev; +struct dm_regulator_uclass_platdata *uc_pdata; +int new_mode; +int mode; +int ret; + + ret =get_curr_dev_and_pl (&dev, &uc_pdata, false); +if (ret) +return ret; + +if (argc ==1 ) { + mode =regulator_get_mode (dev); +if (mode <0 ) + return failed("get", uc_pdata->name, "mode",mode);
common/cmd_regulator.c new file +15
-0+ +printf ("mode id: %d\n" , mode); +return CMD_RET_SUCCESS ; + } + + new_mode =simple_strtoul (argv[1 ],NULL ,0 ); + + ret =regulator_set_mode (dev, new_mode); +if (ret) +return failed ("set" , uc_pdata->name,"mode" , ret); + +return CMD_RET_SUCCESS ; +} + +static int do_enable(cmd_tbl_t *cmdtp, int flag, int argc, char *const
argv[])common/cmd_regulator.c new file +12
-0+{ +struct udevice *dev; +struct dm_regulator_uclass_platdata *uc_pdata; +int ret; + + ret =get_curr_dev_and_pl (&dev, &uc_pdata, true); +if (ret) +return ret; + + ret =regulator_set_enable (dev, true); +if (ret) + return failed("enable", "regulator", uc_pdata->name,ret);
common/cmd_regulator.c new file +5
-0+ +return CMD_RET_SUCCESS ; +} + +static int do_disable(cmd_tbl_t *cmdtp, int flag, int argc, char *const
argv[])common/cmd_regulator.c new file +12
-0+{ +struct udevice *dev; +struct dm_regulator_uclass_platdata *uc_pdata; +int ret; + + ret =get_curr_dev_and_pl (&dev, &uc_pdata, true); +if (ret) +return ret; + + ret =regulator_set_enable (dev, false); +if (ret) + return failed("disable", "regulator", uc_pdata->name,ret);
common/cmd_regulator.c new file +35
-0+ +return CMD_RET_SUCCESS ; +} + +static cmd_tbl_t subcmd[] = { +U_BOOT_CMD_MKENT (dev,2 ,1 , do_dev,"" ,"" ), +U_BOOT_CMD_MKENT (list,1 ,1 , do_list,"" ,"" ), +U_BOOT_CMD_MKENT (info,2 ,1 , do_info,"" ,"" ), +U_BOOT_CMD_MKENT (status,2 ,1 , do_status,"" ,"" ), +U_BOOT_CMD_MKENT (value,3 ,1 , do_value,"" ,"" ), +U_BOOT_CMD_MKENT (current,3 ,1 , do_current,"" ,"" ), +U_BOOT_CMD_MKENT (mode,2 ,1 , do_mode,"" ,"" ), +U_BOOT_CMD_MKENT (enable,1 ,1 , do_enable,"" ,"" ), +U_BOOT_CMD_MKENT (disable,1 ,1 , do_disable,"" ,"" ), +}; + +static int do_regulator (cmd_tbl_t *cmdtp,int flag,int argc, +char *const argv[]) +{ +cmd_tbl_t *cmd; + + argc--; + argv++; + + cmd =find_cmd_tbl (argv[0 ], subcmd,ARRAY_SIZE (subcmd)); +if (cmd ==NULL || argc > cmd->maxargs) +return CMD_RET_USAGE ; + +return cmd->cmd (cmdtp, flag, argc, argv); +} + +U_BOOT_CMD (regulator,CONFIG_SYS_MAXARGS ,1 , do_regulator, +"uclass operations" , +"list - list UCLASS regulator devices\n" + "regulator dev [id] - show or [set] operating regulatordevice\n"
common/cmd_regulator.c new file +3
-0+"regulator [info] - print constraints info\n" +"regulator [status] - print operating status\n" + "regulator [value] [-f] - print/[set] voltage value [uV](force)\n"
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
common/cmd_regulator.c new file +5
-1+"regulator [current] - print/[set] current value [uA]\n" +"regulator [mode_id] - print/[set] operating mode id\n" +"regulator [enable] - enable the regulator output\n" +"regulator [disable] - disable the regulator output\n" +); --1.9.1
Regards,
Simon
Regards,
Simon
PATCH v4 7/16 dm: regulator: add regulator command
Hello Simon,
Quoted 248 lines · Simon Glass
Hi Przemyslaw,
Quoted 238 lines · Przemyslaw Marczak
Hello Simon,
Quoted 150 lines · Simon Glass
Hi Przemyslaw,
Quoted 145 lines · Przemyslaw Marczak
Hello Simon,
Quoted 45 lines · Simon Glass
Hi Przemyslaw,
Quoted 29 lines · Przemyslaw Marczak
This command is based on driver model regulator's API. The user interface provides:
- list UCLASS regulator devices
- show or [set] operating regulator device
- print constraints info
- print operating status
- print/[set] voltage value [uV] (force)
- print/[set] current value [uA]
- print/[set] operating mode id
- enable the regulator output
- disable the regulator outputThe 'force' option can be used for setting the value which exceeds the constraints min/max limits.
Signed-off-by Przemyslaw Marczak <[email protected]>---
Changes v3:
- new file
-KconfigentryChanges V4:
- cmd regulator: move platdata to uc pdata
-cmd_regulator: includes cleanup
-cmd_regulator: addget_curr_dev_and_pl()check type
- move config name:CONFIG_DM_REGULATOR_CMDtoCONFIG_CMD_REGULATOR
- common/Kconfig - cleanupQuoted 7 lines
--- common/Kconfig | 22 +++ common/Makefile | 1 + common/cmd_regulator.c | 403 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 426 insertions(+)create mode 100644
common/cmd_regulator.cQuoted 4 lines
Acked-by Simon Glass <[email protected]>I have a few nits that could be dealt with by a follow-on patch.
Ok.
Quoted 84 lines
Quoted 77 lines
common/Kconfig +9
-0@@ -470,5 +470,27 @@ config CMD_PMIC - pmic read address - read byte of register at address - pmic write address - write byte to register at address The only one change for this command is 'dev' subcommand. + +config CMD_REGULATOR + bool "Enable Driver Model REGULATOR command" + depends on DM_REGULATOR + help + This command is based on driver model regulator's API. + User interface features: + - list - list regulator devices + - regulator dev <id> - show or [set] operating regulatordevice
common/Kconfig +9
-0+ - regulator info - print constraints info + - regulator status - print operating status + - regulator value <val] <-f> - print/[set] voltage value [uV] + - regulator current <val> - print/[set] current value [uA] + - regulator mode <id> - print/[set] operating mode id + - regulator enable - enable the regulator output + - regulator disable - disable the regulator output + + The '-f' (force) option can be used for set the value whichexceeds
+ the limits, which are found in device-tree and are kept in
regulator'scommon/Kconfig +3
-0+ uclass platdata structure. + endmenu + endmenucommon/Makefile +1
-0@@ -212,6 +212,7 @@ obj-$(CONFIG_CMD_GPT) += cmd_gpt.o # Power obj-$(CONFIG_CMD_PMIC) += cmd_pmic.o +obj-$(CONFIG_CMD_REGULATOR) += cmd_regulator.o endif ifdef CONFIG_SPL_BUILDcommon/cmd_regulator.c new file +23
-0@@ -0,0 +1,403 @@ +/* +* Copyright (C) 2014-2015 Samsung Electronics +* Przemyslaw Marczak <[email protected]> +* +* SPDX-License-Identifier: GPL-2.0+ +*/ +#include <common.h> +#include <errno.h> +#include <dm.h> +#include <dm/uclass-internal.h> +#include <power/regulator.h> + +#define LIMIT_SEQ 3 +#define LIMIT_DEVNAME 20 +#define LIMIT_OFNAME 20 +#define LIMIT_INFO 16 + +static struct udevice *currdev; + +static int failed (const char *getset,const char *thing, +const char *for_dev,int ret) +{ + printf("Can't %s %s %s.\nError: %d (%s)\n", getset, thing,Quoted 3 lines
for_dev,
+ ret,errno_str(ret));blank line here.
Quoted 5 lines
Quoted 1 line
I don't see the blank line here in the patch, which I send.
Odd, there seem to be two blank lines there, and we only need one.
Ah, sorry. You mean, that there should be added a blank line. Ok, will add one.
Quoted 14 lines
Quoted 8 lines
Quoted 7 lines
I worry that if someone gets one of these messages they will not be able to find it in the source code. How about passing in the full
printf()string in each case, or just usingprintf()in situ? I don't think the code space saving is significant.Quoted 4 lines
It's not a debug message. And each one is different, and easy to grep "failed". The code is a little cleaner with this. Also the command code is
not complicated.Quoted 6 lines
git grep -i failed |wc -l
2089Is there some way to know it is a PMIC error message, and find it that way?
Ok, I assumed that you know which command you called, and where to find it, so you could use:
grep -i "failed"common/cmd_regulator.c| wc -l
15But this was only the function name, not a useful text for grep. Now I see that this should use the printf instead of the helper funcion.
Quoted 29 lines
Quoted 29 lines
Quoted 28 lines
Quoted 6 lines
common/cmd_regulator.c new file +4
-0+return CMD_RET_FAILURE ; +} + +static int regulator_get(bool list_only, int get_seq, struct udevice**devp)
This function seems to do multiple things (find and list). Should we split it into two?
common/cmd_regulator.c line 38
Quoted 10 lines
common/cmd_regulator.c new file +10
-0+{ +struct dm_regulator_uclass_platdata *uc_pdata; +struct udevice *dev; +int ret; + +if (devp) + *devp =NULL ; + +for (ret =uclass_first_device (UCLASS_REGULATOR , &dev); dev; + ret =uclass_next_device (&dev)) {This will probe all regulators that it checks. I think it should avoid that. Do you mean to use
Quoted 9 lines
Quoted 5 lines
Regarding the two above comments, we have two problems:
1. Getting the regulator by sequencial number (
dev->seq).
I think it's required, because only this method returns the right device.
Disadvantage: need to probe all devices.But you can use
req_seq, or if you have platform data, check that.Ok, we could use the
req_seqfor the PMIC uclass, it's natural that interface, has its address and <reg> property - but this can repeat, if we have two PMICs on a different busses. This is probably possible.We also shouldn't set the
req_seqas the number found in node name, because those numbers can repeat: ldo1 {}; buck1 {}; regulator1 { }.Quoted 6 lines
I think that, using the
req_seqis bad idea, since we can't be sure that those values are unique.I understand that, the probe is not ideal here? But from the other side, if we call "pmic list", then we are sure, that listed devices are ready to use. Shouldn't we expect this?
Quoted 5 lines
I was hoping that we would not probe devices until they are actually used, and that listing them would not constitute 'use'.
In the case of listing, you should not need to worry about ->seq or ->req_seq. If you avoid 'getting' the device you will not probe it.
Yes I know, that I can use the uclass_find_first/next_device() functions here. But only after moving the "regulator dev" command to getting the regulator by it's "name" constraint as will do in the fixup patches.
Quoted 4 lines
In the case of getting a device ready for use, yes, it must be probed. But I am only commenting on your 'list' function.
Yes this is clean for me.
I'm only wonder now, what to do with the "pmic list/dev" commands.
Actually, for the multi interface PMIC IC, we can be sure, that for each interface device will have a different name (dev->name).
But even if the nodes are inside a different parent bus nodes, and have the same names, we probably could assume, that each PMIC's interface has a different address.
To be sure we could put some note into the documentation, that for the PMICs, each node name should be unique.
Then I can use:
- uclass_find_first/next_device() for listing PMIC devices
- uclass_get_device_by_name() for getting the required PMIC
Is that correct, for you?
[snip]
Best regards,
Signature · 4 lines
Przemyslaw Marczak Samsung R&D Institute Poland Samsung Electronics p.marczak at samsung.com
PATCH v4 7/16 dm: regulator: add regulator command
Hi Przemyslaw,
Quoted 305 lines · Przemyslaw Marczak
Hello Simon,
Quoted 272 lines · Simon Glass
Hi Przemyslaw,
Quoted 258 lines · Przemyslaw Marczak
Hello Simon,
Quoted 161 lines · Simon Glass
Hi Przemyslaw,
Quoted 155 lines · Przemyslaw Marczak
Hello Simon,
Quoted 48 lines · Simon Glass
Hi Przemyslaw,
Quoted 30 lines · Przemyslaw Marczak
This command is based on driver model regulator's API. The user interface provides:
- list UCLASS regulator devices
- show or [set] operating regulator device
- print constraints info
- print operating status
- print/[set] voltage value [uV] (force)
- print/[set] current value [uA]
- print/[set] operating mode id
- enable the regulator output
- disable the regulator outputThe 'force' option can be used for setting the value which exceeds the constraints min/max limits.
Signed-off-by Przemyslaw Marczak <[email protected]>---
Changes v3:
- new file
-KconfigentryChanges V4:
- cmd regulator: move platdata to uc pdata
-cmd_regulator: includes cleanup
-cmd_regulator: addget_curr_dev_and_pl()check type
- move config name:CONFIG_DM_REGULATOR_CMDtoCONFIG_CMD_REGULATOR
- common/Kconfig - cleanupQuoted 7 lines
--- common/Kconfig | 22 +++ common/Makefile | 1 + common/cmd_regulator.c | 403 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 426 insertions(+)create mode 100644
common/cmd_regulator.cQuoted 4 lines
Acked-by Simon Glass <[email protected]>I have a few nits that could be dealt with by a follow-on patch.
Ok.
Quoted 89 lines
Quoted 81 lines
common/Kconfig +0
-0@@ -470,5 +470,27 @@ config CMD_PMIC - pmic read address - read byte of register at address - pmic write address - write byte to register at address The only one change for this command is 'dev'subcommand.
common/Kconfig +9
-0+ +config CMD_REGULATOR + bool "Enable Driver Model REGULATOR command" + depends on DM_REGULATOR + help + This command is based on driver model regulator's API. + User interface features: + - list - list regulator devices + - regulator dev <id> - show or [set] operating regulatordevice
common/Kconfig +3
-0+ - regulator info - print constraints info + - regulator status - print operating status + - regulator value <val] <-f> - print/[set] voltage value[uV]
+ - regulator current <val> - print/[set] current value
[uA]
+ - regulator mode <id> - print/[set] operating mode
idcommon/Kconfig +4
-0+ - regulator enable - enable the regulator output + - regulator disable - disable the regulator output + + The '-f' (force) option can be used for set the value whichexceeds
+ the limits, which are found in device-tree and are kept in
regulator'scommon/Kconfig +3
-0+ uclass platdata structure. + endmenu + endmenucommon/Makefile +1
-0@@ -212,6 +212,7 @@ obj-$(CONFIG_CMD_GPT) += cmd_gpt.o # Power obj-$(CONFIG_CMD_PMIC) += cmd_pmic.o +obj-$(CONFIG_CMD_REGULATOR) += cmd_regulator.o endif ifdef CONFIG_SPL_BUILDcommon/cmd_regulator.c new file +23
-0@@ -0,0 +1,403 @@ +/* +* Copyright (C) 2014-2015 Samsung Electronics +* Przemyslaw Marczak <[email protected]> +* +* SPDX-License-Identifier: GPL-2.0+ +*/ +#include <common.h> +#include <errno.h> +#include <dm.h> +#include <dm/uclass-internal.h> +#include <power/regulator.h> + +#define LIMIT_SEQ 3 +#define LIMIT_DEVNAME 20 +#define LIMIT_OFNAME 20 +#define LIMIT_INFO 16 + +static struct udevice *currdev; + +static int failed (const char *getset,const char *thing, +const char *for_dev,int ret) +{ + printf("Can't %s %s %s.\nError: %d (%s)\n", getset, thing,Quoted 3 lines
for_dev,
+ ret,errno_str(ret));blank line here.
Quoted 6 lines
Quoted 1 line
I don't see the blank line here in the patch, which I send.
Odd, there seem to be two blank lines there, and we only need one.
Ah, sorry. You mean, that there should be added a blank line. Ok, will add one.
Quoted 15 lines
Quoted 8 lines
Quoted 7 lines
I worry that if someone gets one of these messages they will not be able to find it in the source code. How about passing in the full
printf()string in each case, or just usingprintf()in situ? I don't think the code space saving is significant.Quoted 4 lines
It's not a debug message. And each one is different, and easy to grep "failed". The code is a little cleaner with this. Also the command code is
not complicated.Quoted 6 lines
git grep -i failed |wc -l
2089Is there some way to know it is a PMIC error message, and find it that way?
Ok, I assumed that you know which command you called, and where to find it,
so you could use:
grep -i "failed"common/cmd_regulator.c| wc -l
15But this was only the function name, not a useful text for grep. Now I see that this should use the printf instead of the helper funcion.
Quoted 33 lines
Quoted 33 lines
Quoted 13 lines
Quoted 6 lines
common/cmd_regulator.c new file +4
-0+return CMD_RET_FAILURE ; +} + +static int regulator_get(bool list_only, int get_seq, struct udevice**devp)
This function seems to do multiple things (find and list). Should we split it into two?
Quoted 17 lines
common/cmd_regulator.c
Quoted 10 lines
common/cmd_regulator.c new file +10
-0+{ +struct dm_regulator_uclass_platdata *uc_pdata; +struct udevice *dev; +int ret; + +if (devp) + *devp =NULL ; + +for (ret =uclass_first_device (UCLASS_REGULATOR , &dev); dev; + ret =uclass_next_device (&dev)) {This will probe all regulators that it checks. I think it should avoid that. Do you mean to use
Regarding the two above comments, we have two problems:
Quoted 9 lines
Quoted 4 lines
1. Getting the regulator by sequencial number (
dev->seq). I think it's required, because only this method returns the right device.
Disadvantage: need to probe all devices.But you can use
req_seq, or if you have platform data, check that.Ok, we could use the
req_seqfor the PMIC uclass, it's natural that interface, has its address and <reg> property - but this can repeat, if we have two PMICs on a different busses. This is probably possible.We also shouldn't set the
req_seqas the number found in node name, because
those numbers can repeat: ldo1 {}; buck1 {}; regulator1 { }.Quoted 7 lines
I think that, using the
req_seqis bad idea, since we can't be sure that those values are unique.I understand that, the probe is not ideal here? But from the other side, if we call "pmic list", then we are sure, that listed devices are ready to
use. Shouldn't we expect this?Quoted 5 lines
I was hoping that we would not probe devices until they are actually used, and that listing them would not constitute 'use'.
In the case of listing, you should not need to worry about ->seq or ->req_seq. If you avoid 'getting' the device you will not probe it.
Yes I know, that I can use the uclass_find_first/next_device() functions here. But only after moving the "regulator dev" command to getting the regulator by it's "name" constraint as will do in the fixup patches.
Quoted 4 lines
In the case of getting a device ready for use, yes, it must be probed. But I am only commenting on your 'list' function.
Yes this is clean for me.
I'm only wonder now, what to do with the "pmic list/dev" commands.
Actually, for the multi interface PMIC IC, we can be sure, that for each interface device will have a different name (
dev->name).But even if the nodes are inside a different parent bus nodes, and have the same names, we probably could assume, that each PMIC's interface has a different address.
To be sure we could put some note into the documentation, that for the PMICs, each node name should be unique.
Quoted 5 lines
Then I can use:
- uclass_find_first/next_device() for listing PMIC devices
-uclass_get_device_by_name()for getting the required PMICIs that correct, for you?
Yes, I think that is good. It will just confuse everyone if we try to handle two PMICs with the same name (or two regulators for that matter). Adding a note to the doc sounds good.
Regards,
Simon
PATCH v4 8/16 pmic: max77686 set the same compatible as in the kernel
In reply to Przemyslaw MarczakThis commit also updates the proper dts files.
--- arch/arm/dts/exynos4412-odroid.dts | 2 +- arch/arm/dts/exynos4412-trats2.dts | 2 +- arch/arm/dts/exynos5250-smdk5250.dts | 2 +- arch/arm/dts/exynos5250-snow.dts | 2 +- lib/fdtdec.c | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-)
arch/arm/dts/exynos4412-odroid.dts +1 -1
@@ -36,7 +36,7 @@ status = "okay"; max77686_pmic at 09 { - compatible = "maxim,max77686_pmic"; + compatible = "maxim,max77686"; interrupts = <7 0>; reg = <0x09 0 0>; #clock-cells = <1>;
arch/arm/dts/exynos4412-trats2.dts +1 -1
@@ -41,7 +41,7 @@ status = "okay"; max77686_pmic at 09 { - compatible = "maxim,max77686_pmic"; + compatible = "maxim,max77686"; interrupts = <7 0>; reg = <0x09 0 0>; #clock-cells = <1>;
arch/arm/dts/exynos5250-smdk5250.dts +1 -1
@@ -68,7 +68,7 @@ i2c at 12c60000 { pmic at 9 { reg = <0x9>; - compatible = "maxim,max77686_pmic"; + compatible = "maxim,max77686"; }; };
arch/arm/dts/exynos5250-snow.dts +1 -1
@@ -108,7 +108,7 @@ i2c at 12c60000 { pmic at 9 { reg = <0x9>; - compatible = "maxim,max77686_pmic"; + compatible = "maxim,max77686"; }; };
lib/fdtdec.c +1 -1
@@ -54,7 +54,7 @@ static const char * const compat_names[COMPAT_COUNT] = {COMPAT (SAMSUNG_EXYNOS_DWMMC ,"samsung,exynos-dwmmc" ),COMPAT (SAMSUNG_EXYNOS_MMC ,"samsung,exynos-mmc" ),COMPAT (SAMSUNG_EXYNOS_SERIAL ,"samsung,exynos4210-uart" ), -COMPAT (MAXIM_MAX77686_PMIC ,"maxim,max77686_pmic" ), +COMPAT (MAXIM_MAX77686_PMIC ,"maxim,max77686" ),COMPAT (GENERIC_SPI_FLASH ,"spi-flash" ),COMPAT (MAXIM_98095_CODEC ,"maxim,max98095-codec" ), COMPAT(INFINEON_SLB9635_TPM, "infineon,slb9635-tpm"),
Signature · 1 line
1.9.1
PATCH v4 8/16 pmic: max77686 set the same compatible as in the kernel
Quoted 10 lines · Przemyslaw Marczak
This commit also updates the proper dts files.
Signed-off-by Przemyslaw Marczak <[email protected]>--- arch/arm/dts/exynos4412-odroid.dts | 2 +- arch/arm/dts/exynos4412-trats2.dts | 2 +- arch/arm/dts/exynos5250-smdk5250.dts | 2 +- arch/arm/dts/exynos5250-snow.dts | 2 +- lib/fdtdec.c | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-)
PATCH v4 8/16 pmic: max77686 set the same compatible as in the kernel
Quoted 12 lines · Simon Glass
Quoted 10 lines · Przemyslaw Marczak
This commit also updates the proper dts files.
Signed-off-by Przemyslaw Marczak <[email protected]>--- arch/arm/dts/exynos4412-odroid.dts | 2 +- arch/arm/dts/exynos4412-trats2.dts | 2 +- arch/arm/dts/exynos5250-smdk5250.dts | 2 +- arch/arm/dts/exynos5250-snow.dts | 2 +- lib/fdtdec.c | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-)
Quoted 1 line
Acked-by Simon Glass <[email protected]>
Applied to u-boot-dm/next, thanks!
PATCH v4 9/16 dm: pmic: add max77686 pmic driver
In reply to Przemyslaw MarczakThis is the implementation of driver model PMIC driver. The max77686 PMIC driver implements read/write operations and driver bind method - to bind its childs.
This driver will try to bind the regulator devices by using it's child info array with regulator prefixes and driver names. This should succeed when compatible regulator driver is compiled. If no regulator driver found, then the pmic can still provide read/write operations, and can be used with PMIC function calls.
---
Changes V2:
- add implementation of pmic read/write
- max77686: add new operations
- max77686: header: change PMIC_NUM_OF_REGS to MAX77686_NUM_OF_REGS
Changes V3:
- pmic/max77686.c: call pmic_child_node_scan() to bind regulator device
- remove use of pmic platdata
- remove unused endian conversions
- Kconfig: add max77686 pmic entry
Changes V4:
- move DM_PMIC_MAX77686 Kconfig entry from: drivers/power/Kconfig to drivers/power/pmic/Kconfig
- pmic/max77686.c: cleanup
- pmic/max77686.c: includes cleanup
- max77686_pmic.h: define ldo and buck driver names
- power/Kconfig: cleanup
- add binding info
--- doc/device-tree-bindings/pmic/max77686.txt | 36 +++++++++++++ drivers/power/pmic/Kconfig | 7 +++ drivers/power/pmic/Makefile | 1 + drivers/power/pmic/max77686.c | 87 ++++++++++++++++++++++++++++++ drivers/power/pmic/pmic_max77686.c | 2 +- include/power/max77686_pmic.h | 10 +++- 6 files changed, 140 insertions(+), 3 deletions(-) create mode 100644 doc/device-tree-bindings/pmic/max77686.txt create mode 100644 drivers/power/pmic/max77686.c
doc/device-tree-bindings/pmic/max77686.txt new file +36 -0
@@ -0,0 +1,36 @@ +MAXIM, MAX77686 pmic + +This device uses two drivers: +- drivers/power/pmic/max77686.c (for parent device) +- drivers/power/regulator/max77686.c (for child regulators) + +This file describes the binding info for the PMIC driver. + +To bind the regulators, please read the additional binding info: +- doc/device-tree-bindings/regulator/max77686.txt + +Required properties: +- compatible: "maxim,max77686" +- reg = 0x9 + +With those two properties, the pmic device can be used for read/write only. +To bind each regulator, the optional regulators subnode should exists. + +Optional subnode: +- voltage-regulators: subnode list of each device's regulator + (see max77686.txt - regulator binding info) + +Example: + +max77686 at 09 { + compatible = "maxim,max77686"; + reg = <0x09>; + + voltage-regulators { + ldo1 { + ... + }; + ... + }; +}; +
drivers/power/pmic/Kconfig +7 -0
@@ -9,3 +9,10 @@ config DM_PMIC for read/write. For detailed description, please refer to the files: - 'drivers/power/pmic/pmic-uclass.c' - 'include/power/pmic.h' + +config DM_PMIC_MAX77686 + bool "Enable Driver Model for PMIC MAX77686" + depends on DM_PMIC + ---help--- + This config enables implementation of driver-model pmic uclass features + for PMIC MAX77686. The driver implements read/write operations.
drivers/power/pmic/Makefile +1 -0
@@ -11,6 +11,7 @@ obj-$(CONFIG_POWER_MAX8998) += pmic_max8998.o obj-$(CONFIG_POWER_MAX8997) += pmic_max8997.o obj-$(CONFIG_POWER_MUIC_MAX8997) += muic_max8997.o obj-$(CONFIG_POWER_MAX77686) += pmic_max77686.o +obj-$(CONFIG_DM_PMIC_MAX77686) += max77686.o obj-$(CONFIG_POWER_PFUZE100) += pmic_pfuze100.o obj-$(CONFIG_POWER_TPS65090_I2C) += pmic_tps65090.o obj-$(CONFIG_POWER_TPS65090_EC) += pmic_tps65090_ec.o
drivers/power/pmic/max77686.c new file +87 -0
87 lines not on this page · raw message
drivers/power/pmic/pmic_max77686.c +1 -1
@@ -295,7 +295,7 @@ int pmic_init(unsigned char bus) p->name = name; p->interface =PMIC_I2C ; - p->number_of_regs =PMIC_NUM_OF_REGS ; + p->number_of_regs =MAX77686_NUM_OF_REGS ; p->hw.i2c.tx_num =1 ;puts ("Board PMIC init\n" );
include/power/max77686_pmic.h +8 -2
@@ -122,11 +122,17 @@ enum {MAX77686_REG_PMIC_BBAT =0x7e ,MAX77686_REG_PMIC_32KHZ , - PMIC_NUM_OF_REGS, + MAX77686_NUM_OF_REGS, };/* I2C device address for pmic max77686 */ -#define MAX77686_I2C_ADDR (0x12 >> 1) +#define MAX77686_I2C_ADDR (0x12 >> 1) +#define MAX77686_LDO_NUM 26 +#define MAX77686_BUCK_NUM 9 + +/* Drivers name */ +#define MAX77686_LDO_DRIVER "max77686_ldo" +#define MAX77686_BUCK_DRIVER "max77686_buck"enum { REG_DISABLE = 0,
Signature · 1 line
1.9.1
PATCH v4 9/16 dm: pmic: add max77686 pmic driver
Quoted 31 lines · Przemyslaw Marczak
This is the implementation of driver model PMIC driver. The max77686 PMIC driver implements read/write operations and driver bind method - to bind its childs.
This driver will try to bind the regulator devices by using it's child info array with regulator prefixes and driver names. This should succeed when compatible regulator driver is compiled. If no regulator driver found, then the pmic can still provide read/write operations, and can be used with PMIC function calls.
Signed-off-by Przemyslaw Marczak <[email protected]>---
Changes V2:
- add implementation of pmic read/write
- max77686: add new operations
- max77686: header: changePMIC_NUM_OF_REGStoMAX77686_NUM_OF_REGSChanges V3:
-pmic/max77686.c: callpmic_child_node_scan()to bind regulator device
- remove use of pmic platdata
- remove unused endian conversions
-Kconfig: add max77686 pmic entryChanges V4:
- moveDM_PMIC_MAX77686Kconfigentry from:drivers/power/Kconfigtodrivers/power/pmic/Kconfig
-pmic/max77686.c: cleanup
-pmic/max77686.c: includes cleanup
-max77686_pmic.h: define ldo and buck driver names
- power/Kconfig: cleanup
- add binding info
Quoted 10 lines
--- doc/device-tree-bindings/pmic/max77686.txt | 36 +++++++++++++ drivers/power/pmic/Kconfig | 7 +++ drivers/power/pmic/Makefile | 1 + drivers/power/pmic/max77686.c | 87 ++++++++++++++++++++++++++++++ drivers/power/pmic/pmic_max77686.c | 2 +- include/power/max77686_pmic.h | 10 +++- 6 files changed, 140 insertions(+), 3 deletions(-) create mode 100644 doc/device-tree-bindings/pmic/max77686.txt create mode 100644 drivers/power/pmic/max77686.c
PATCH v4 9/16 dm: pmic: add max77686 pmic driver
Quoted 43 lines · Simon Glass
Quoted 31 lines · Przemyslaw Marczak
This is the implementation of driver model PMIC driver. The max77686 PMIC driver implements read/write operations and driver bind method - to bind its childs.
This driver will try to bind the regulator devices by using it's child info array with regulator prefixes and driver names. This should succeed when compatible regulator driver is compiled. If no regulator driver found, then the pmic can still provide read/write operations, and can be used with PMIC function calls.
Signed-off-by Przemyslaw Marczak <[email protected]>---
Changes V2:
- add implementation of pmic read/write
- max77686: add new operations
- max77686: header: changePMIC_NUM_OF_REGStoMAX77686_NUM_OF_REGSChanges V3:
-pmic/max77686.c: callpmic_child_node_scan()to bind regulator device
- remove use of pmic platdata
- remove unused endian conversions
-Kconfig: add max77686 pmic entryChanges V4:
- moveDM_PMIC_MAX77686Kconfigentry from:drivers/power/Kconfigtodrivers/power/pmic/Kconfig
-pmic/max77686.c: cleanup
-pmic/max77686.c: includes cleanup
-max77686_pmic.h: define ldo and buck driver names
- power/Kconfig: cleanup
- add binding infoQuoted 10 lines
--- doc/device-tree-bindings/pmic/max77686.txt | 36 +++++++++++++ drivers/power/pmic/Kconfig | 7 +++ drivers/power/pmic/Makefile | 1 + drivers/power/pmic/max77686.c | 87 ++++++++++++++++++++++++++++++ drivers/power/pmic/pmic_max77686.c | 2 +- include/power/max77686_pmic.h | 10 +++- 6 files changed, 140 insertions(+), 3 deletions(-) create mode 100644 doc/device-tree-bindings/pmic/max77686.txt create mode 100644 drivers/power/pmic/max77686.c
Quoted 1 line
Acked-by Simon Glass <[email protected]>
Applied to u-boot-dm/next, thanks!
PATCH v4 10/16 dm: regulator: add max77686 regulator driver
In reply to Przemyslaw MarczakThis commit adds support to MAX77686 regulator driver, based on a driver model regulator's API. It implements almost all regulator operations, beside those for setting and geting the Current value.
For proper bind and operation it requires the MAX77686 PMIC driver.
New file: drivers/power/regulator/max77686.c
New config: CONFIG_DM_REGULATOR_MAX77686
---
Changes V2:
- change debug() to error()
- code cleanup
- fix data types
- ldo/buck state implementation
- adjust to new uclass api
Changes V3:
- regulator/max77686.c:
-- adjust to api changes
-- add separeted drivers for buck and ldo
-- bind regulators by its compatibles
- Kconfig: add regulator max77686 entry
Changes V4:
- move DM_REGULATOR_MAX77686 Kconfig entry from: drivers/power/Kconfig to drivers/power/regulator/Kconfig
- regulator/max77686.c: cleanup
- regulator/max77686.c: add missing break for switch
- regulator/max77686.c: includes cleanup
- regulator.h: comments cleanup
- add binding info
--- doc/device-tree-bindings/regulator/max77686.txt | 70 ++ drivers/power/Makefile | 1 - drivers/power/regulator/Kconfig | 8 + drivers/power/regulator/Makefile | 1 + drivers/power/regulator/max77686.c | 825 ++++++++++++++++++++++++ include/power/max77686_pmic.h | 19 +- include/power/regulator.h | 42 +- 7 files changed, 942 insertions(+), 24 deletions(-) create mode 100644 doc/device-tree-bindings/regulator/max77686.txt create mode 100644 drivers/power/regulator/max77686.c
doc/device-tree-bindings/regulator/max77686.txt new file +70 -0
@@ -0,0 +1,70 @@ +MAXIM, MAX77686 regulators + +This device uses two drivers: +- drivers/power/pmic/max77686.c (as parent I/O device) +- drivers/power/regulator/max77686.c (for child regulators) + +This file describes the binding info for the REGULATOR driver. + +First, please read the binding info for the pmic: +- doc/device-tree-bindings/pmic/max77686.txt + +Required subnode: +- voltage-regulators: required for the PMIC driver + +Required properties: +- regulator-name: used for regulator uclass platform data '.name' + +Optional: +- regulator-min-microvolt: minimum allowed Voltage to set +- regulator-max-microvolt: minimum allowed Voltage to set +- regulator-always-on: regulator should be never disabled +- regulator-boot-on: regulator should be enabled by the bootloader + +Example: +(subnode of max77686 pmic node) +voltage-regulators { + ldo1 { + regulator-name = "VDD_ALIVE_1.0V"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + regulator-always-on; + regulator-boot-on; + }; + + ldo2 { + regulator-name = "VDDQ_VM1M2_1.2V"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-always-on; + regulator-boot-on; + }; + . + . + . + ldo26 { + regulator-name = "nc"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-always-on; + regulator-boot-on; + }; + + buck1 { + regulator-compatible = "BUCK1"; + regulator-name = "VDD_MIF_1.0V"; + regulator-min-microvolt = <8500000>; + regulator-max-microvolt = <1100000>; + regulator-always-on; + regulator-boot-on; + }; + . + . + . + buck9 { + regulator-compatible = "BUCK9"; + regulator-name = "nc"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + }; +};
drivers/power/Makefile +0 -1
@@ -15,7 +15,6 @@ obj-$(CONFIG_TPS6586X_POWER) += tps6586x.o obj-$(CONFIG_TWL4030_POWER) += twl4030.o obj-$(CONFIG_TWL6030_POWER) += twl6030.o obj-$(CONFIG_PALMAS_POWER) += palmas.o - obj-$(CONFIG_POWER) += power_core.o obj-$(CONFIG_DIALOG_POWER) += power_dialog.o obj-$(CONFIG_POWER_FSL) += power_fsl.o
drivers/power/regulator/Kconfig +8 -0
@@ -15,3 +15,11 @@ config DM_REGULATOR when binding the regulator devices. The pmic_bind_childs() can be used for this purpose if PMIC I/O driver is implemented or dm_scan_fdt_node() otherwise. Detailed informations can be found in the header file. + +config DM_REGULATOR_MAX77686 + bool "Enable Driver Model for REGULATOR MAX77686" + depends on DM_REGULATOR && DM_PMIC_MAX77686 + ---help--- + This config enables implementation of driver-model regulator uclass + features for REGULATOR MAX77686. The driver implements get/set api for: + value, enable and mode.
drivers/power/regulator/Makefile +1 -0
@@ -6,3 +6,4 @@ # obj-$(CONFIG_DM_REGULATOR) += regulator-uclass.o +obj-$(CONFIG_DM_REGULATOR_MAX77686) += max77686.o
drivers/power/regulator/max77686.c new file +825 -0
825 lines not on this page · raw message
include/power/max77686_pmic.h +17 -2
@@ -149,23 +149,29 @@ enum {enum {OPMODE_OFF =0 , -OPMODE_STANDBY ,OPMODE_LPM , +OPMODE_STANDBY , +OPMODE_STANDBY_LPM ,OPMODE_ON , }; +#ifdef CONFIG_POWER int max77686_set_ldo_voltage (struct pmic *p,int ldo,ulong uV);int max77686_set_ldo_mode (struct pmic *p,int ldo,char opmode);int max77686_set_buck_voltage (struct pmic *p,int buck,ulong uV);int max77686_set_buck_mode (struct pmic *p,int buck,char opmode); +#endif #define MAX77686_LDO_VOLT_MAX_HEX 0x3f#define MAX77686_LDO_VOLT_MASK 0x3f#define MAX77686_LDO_MODE_MASK 0xc0#define MAX77686_LDO_MODE_OFF (0x00 << 0x06) +#define MAX77686_LDO_MODE_LPM (0x01 << 0x06)#define MAX77686_LDO_MODE_STANDBY (0x01 << 0x06) -#define MAX77686_LDO_MODE_LPM (0x02 << 0x06) +#define MAX77686_LDO_MODE_STANDBY_LPM (0x02 << 0x06)#define MAX77686_LDO_MODE_ON (0x03 << 0x06) +#define MAX77686_BUCK234_VOLT_MAX_HEX 0xff +#define MAX77686_BUCK234_VOLT_MASK 0xff#define MAX77686_BUCK_VOLT_MAX_HEX 0x3f#define MAX77686_BUCK_VOLT_MASK 0x3f#define MAX77686_BUCK_MODE_MASK 0x03
@@ -176,6 +182,15 @@ int max77686_set_buck_mode(struct pmic *p, int buck, char opmode);#define MAX77686_BUCK_MODE_LPM 0x02#define MAX77686_BUCK_MODE_ON 0x03 +/* For regulator hex<->volt conversion */ +#define MAX77686_LDO_UV_MIN 800000/* Minimum LDO uV value */ +#define MAX77686_LDO_UV_LSTEP 25000/* uV lower value step */ +#define MAX77686_LDO_UV_HSTEP 50000/* uV higher value step */ +#define MAX77686_BUCK_UV_LMIN 600000/* Lower minimun BUCK value */ +#define MAX77686_BUCK_UV_HMIN 750000/* Higher minimun BUCK value */ +#define MAX77686_BUCK_UV_LSTEP 12500/* uV lower value step */ +#define MAX77686_BUCK_UV_HSTEP 50000/* uV higher value step */ +/* Buck1 1 volt value */ #define MAX77686_BUCK1OUT_1V 0x5/* Buck1 1.05 volt value */
include/power/regulator.h +21 -21
156 lines not on this page · raw message
Signature · 1 line
1.9.1
PATCH v4 10/16 dm: regulator: add max77686 regulator driver
Quoted 34 lines · Przemyslaw Marczak
This commit adds support to MAX77686 regulator driver, based on a driver model regulator's API. It implements almost all regulator operations, beside those for setting and geting the Current value.
For proper bind and operation it requires the MAX77686 PMIC driver.New file:
drivers/power/regulator/max77686.c
New config:CONFIG_DM_REGULATOR_MAX77686Signed-off-by Przemyslaw Marczak <[email protected]>---
Changes V2:
- changedebug()toerror()
- code cleanup
- fix data types
- ldo/buck state implementation
- adjust to new uclass apiChanges V3:
-regulator/max77686.c:
-- adjust to api changes
-- add separeted drivers for buck and ldo
-- bind regulators by its compatibles
-Kconfig: add regulator max77686 entryChanges V4:
- moveDM_REGULATOR_MAX77686Kconfigentry from:drivers/power/Kconfigtodrivers/power/regulator/Kconfig
-regulator/max77686.c: cleanup
-regulator/max77686.c: add missing break for switch
-regulator/max77686.c: includes cleanup
-regulator.h: comments cleanup
- add binding info
Quoted 11 lines
--- doc/device-tree-bindings/regulator/max77686.txt | 70 ++ drivers/power/Makefile | 1 - drivers/power/regulator/Kconfig | 8 + drivers/power/regulator/Makefile | 1 + drivers/power/regulator/max77686.c | 825 ++++++++++++++++++++++++ include/power/max77686_pmic.h | 19 +- include/power/regulator.h | 42 +- 7 files changed, 942 insertions(+), 24 deletions(-) create mode 100644 doc/device-tree-bindings/regulator/max77686.txt create mode 100644 drivers/power/regulator/max77686.c
PATCH v4 10/16 dm: regulator: add max77686 regulator driver
Quoted 47 lines · Simon Glass
Quoted 34 lines · Przemyslaw Marczak
This commit adds support to MAX77686 regulator driver, based on a driver model regulator's API. It implements almost all regulator operations, beside those for setting and geting the Current value.
For proper bind and operation it requires the MAX77686 PMIC driver.New file:
drivers/power/regulator/max77686.c
New config:CONFIG_DM_REGULATOR_MAX77686Signed-off-by Przemyslaw Marczak <[email protected]>---
Changes V2:
- changedebug()toerror()
- code cleanup
- fix data types
- ldo/buck state implementation
- adjust to new uclass apiChanges V3:
-regulator/max77686.c:
-- adjust to api changes
-- add separeted drivers for buck and ldo
-- bind regulators by its compatibles
-Kconfig: add regulator max77686 entryChanges V4:
- moveDM_REGULATOR_MAX77686Kconfigentry from:drivers/power/Kconfigtodrivers/power/regulator/Kconfig
-regulator/max77686.c: cleanup
-regulator/max77686.c: add missing break for switch
-regulator/max77686.c: includes cleanup
-regulator.h: comments cleanup
- add binding infoQuoted 11 lines
--- doc/device-tree-bindings/regulator/max77686.txt | 70 ++ drivers/power/Makefile | 1 - drivers/power/regulator/Kconfig | 8 + drivers/power/regulator/Makefile | 1 + drivers/power/regulator/max77686.c | 825 ++++++++++++++++++++++++ include/power/max77686_pmic.h | 19 +- include/power/regulator.h | 42 +- 7 files changed, 942 insertions(+), 24 deletions(-) create mode 100644 doc/device-tree-bindings/regulator/max77686.txt create mode 100644 drivers/power/regulator/max77686.c
Quoted 1 line
Acked-by Simon Glass <[email protected]>
Applied to u-boot-dm/next, thanks!
PATCH v4 11/16 dm: regulator: add fixed voltage regulator driver
In reply to Przemyslaw MarczakThis driver implements regulator operations for fixed Voltage/Current value regulators. beside the standard regulator constraints, which are put into the uclass platform data, a typical fixed regulator node provides few additional properties like:
- gpio
- gpio-open-drain
- enable-active-high
- startup-delay-us
The only 'gpio' is used by this driver and is kept in structure of type 'fixed_regulator_platdata', as a device platform data (dev->platdata).
The driver implements:
- get_value
- get_current
- get_enable
- set_enable
The regulator calls and commands can be used for fixed-regulator devices, and the proper error will be returned for prohibited.
Changes v3:
- new file
- Kconfig add fixed-regulator entry
Changes V4:
- move DM_REGULATOR_FIXED Kconfig entry from: drivers/power/Kconfig to drivers/power/regulator/Kconfig
- regulator/fixed.c: adjust to use of uclass platdata and device platdata
- regulator/fixed.c: includes cleanup
- regulator/fixed.c: fix gpio request
- add binding info
--- doc/device-tree-bindings/regulator/fixed.txt | 38 ++++++++ drivers/power/regulator/Kconfig | 8 ++ drivers/power/regulator/Makefile | 1 + drivers/power/regulator/fixed.c | 126 +++++++++++++++++++++++++++ 4 files changed, 173 insertions(+) create mode 100644 doc/device-tree-bindings/regulator/fixed.txt create mode 100644 drivers/power/regulator/fixed.c
doc/device-tree-bindings/regulator/fixed.txt new file +38 -0
@@ -0,0 +1,38 @@ +Fixed Voltage regulator + +Binding: +The binding is done by the property "compatible" - this is different, than for +binding by the node prefix (doc/device-tree-bindings/regulator/regulator.txt). + +Required properties: +- compatible: "regulator-fixed" +- regulator-name: this is required by the regulator uclass + +Optional properties: +- gpio: GPIO to use for enable control +- regulator constraints (binding info: regulator.txt) + +Other kernel-style properties, are currently not used. + +Note: +For the regulator constraints, driver expects that: +- regulator-min-microvolt is equal to regulator-max-microvolt +- regulator-min-microamp is equal to regulator-max-microamp + +Example: +fixed_regulator at 0 { + /* Mandatory */ + compatible = "regulator-fixed"; + regulator-name = "LED_3.3V"; + + /* Optional: */ + gpio = <&gpc1 0 GPIO_ACTIVE_LOW>; + + /* Optional for regulator uclass */ + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-min-microamp = <15000>; + regulator-max-microamp = <15000>; + regulator-always-on; + regulator-boot-on; +};
drivers/power/regulator/Kconfig +8 -0
@@ -23,3 +23,11 @@ config DM_REGULATOR_MAX77686 This config enables implementation of driver-model regulator uclass features for REGULATOR MAX77686. The driver implements get/set api for: value, enable and mode. + +config DM_REGULATOR_FIXED + bool "Enable Driver Model for REGULATOR Fixed value" + depends on DM_REGULATOR + ---help--- + This config enables implementation of driver-model regulator uclass + features for fixed value regulators. The driver implements get/set api + for enable and get only for voltage value.
drivers/power/regulator/Makefile +1 -0
@@ -7,3 +7,4 @@ obj-$(CONFIG_DM_REGULATOR) += regulator-uclass.o obj-$(CONFIG_DM_REGULATOR_MAX77686) += max77686.o +obj-$(CONFIG_DM_REGULATOR_FIXED) += fixed.o
drivers/power/regulator/fixed.c new file +126 -0
126 lines not on this page · raw message
Signature · 1 line
1.9.1
PATCH v4 11/16 dm: regulator: add fixed voltage regulator driver
Quoted 33 lines · Przemyslaw Marczak
This driver implements regulator operations for fixed Voltage/Current value regulators. beside the standard regulator constraints, which are put into the uclass platform data, a typical fixed regulator node provides few additional properties like:
- gpio
- gpio-open-drain
- enable-active-high
- startup-delay-us
The only 'gpio' is used by this driver and is kept in structure of type 'fixed_regulator_platdata', as a device platform data (dev->platdata).The driver implements:
-get_value
-get_current
-get_enable
-set_enableThe regulator calls and commands can be used for fixed-regulator devices, and the proper error will be returned for prohibited.
Signed-off-by Przemyslaw Marczak <[email protected]>Changes v3:
- new file
-Kconfigadd fixed-regulator entryChanges V4:
- moveDM_REGULATOR_FIXEDKconfigentry from:drivers/power/Kconfigtodrivers/power/regulator/Kconfig
-regulator/fixed.c: adjust to use of uclass platdata and device platdata
-regulator/fixed.c: includes cleanup
-regulator/fixed.c: fix gpio request
- add binding info
Quoted 8 lines
--- doc/device-tree-bindings/regulator/fixed.txt | 38 ++++++++ drivers/power/regulator/Kconfig | 8 ++ drivers/power/regulator/Makefile | 1 + drivers/power/regulator/fixed.c | 126 +++++++++++++++++++++++++++ 4 files changed, 173 insertions(+) create mode 100644 doc/device-tree-bindings/regulator/fixed.txt create mode 100644 drivers/power/regulator/fixed.c
PATCH v4 11/16 dm: regulator: add fixed voltage regulator driver
Quoted 43 lines · Simon Glass
Quoted 33 lines · Przemyslaw Marczak
This driver implements regulator operations for fixed Voltage/Current value regulators. beside the standard regulator constraints, which are put into the uclass platform data, a typical fixed regulator node provides few additional properties like:
- gpio
- gpio-open-drain
- enable-active-high
- startup-delay-us
The only 'gpio' is used by this driver and is kept in structure of type 'fixed_regulator_platdata', as a device platform data (dev->platdata).The driver implements:
-get_value
-get_current
-get_enable
-set_enableThe regulator calls and commands can be used for fixed-regulator devices, and the proper error will be returned for prohibited.
Signed-off-by Przemyslaw Marczak <[email protected]>Changes v3:
- new file
-Kconfigadd fixed-regulator entryChanges V4:
- moveDM_REGULATOR_FIXEDKconfigentry from:drivers/power/Kconfigtodrivers/power/regulator/Kconfig
-regulator/fixed.c: adjust to use of uclass platdata and device platdata
-regulator/fixed.c: includes cleanup
-regulator/fixed.c: fix gpio request
- add binding infoQuoted 8 lines
--- doc/device-tree-bindings/regulator/fixed.txt | 38 ++++++++ drivers/power/regulator/Kconfig | 8 ++ drivers/power/regulator/Makefile | 1 + drivers/power/regulator/fixed.c | 126 +++++++++++++++++++++++++++ 4 files changed, 173 insertions(+) create mode 100644 doc/device-tree-bindings/regulator/fixed.txt create mode 100644 drivers/power/regulator/fixed.c
Quoted 1 line
Acked-by Simon Glass <[email protected]>
Applied to u-boot-dm/next, thanks!
PATCH v4 11/16 dm: regulator: add fixed voltage regulator driver
In reply to Przemyslaw MarczakHello Simon,
Quoted 17 lines · Przemyslaw Marczak
This driver implements regulator operations for fixed Voltage/Current value regulators. beside the standard regulator constraints, which are put into the uclass platform data, a typical fixed regulator node provides few additional properties like:
- gpio
- gpio-open-drain
- enable-active-high
- startup-delay-us
The only 'gpio' is used by this driver and is kept in structure of type 'fixed_regulator_platdata', as a device platform data (dev->platdata).The driver implements:
-get_value
-get_current
-get_enable
-set_enable
Quoted 5 lines
The regulator calls and commands can be used for fixed-regulator devices, and the proper error will be returned for prohibited.
Signed-off-by Przemyslaw Marczak <[email protected]>
I missed the separation (---) here and I see that you add ACK below the changes.
Could you remove them from the tree?
Quoted 11 lines
Changes v3:
- new file
-Kconfigadd fixed-regulator entryChanges V4:
- moveDM_REGULATOR_FIXEDKconfigentry from:drivers/power/Kconfigtodrivers/power/regulator/Kconfig
-regulator/fixed.c: adjust to use of uclass platdata and device platdata
-regulator/fixed.c: includes cleanup
-regulator/fixed.c: fix gpio request
- add binding info
Quoted 8 lines
--- doc/device-tree-bindings/regulator/fixed.txt | 38 ++++++++ drivers/power/regulator/Kconfig | 8 ++ drivers/power/regulator/Makefile | 1 + drivers/power/regulator/fixed.c | 126 +++++++++++++++++++++++++++ 4 files changed, 173 insertions(+)create mode 100644
doc/device-tree-bindings/regulator/fixed.txtcreate mode 100644drivers/power/regulator/fixed.c
Best regards,
Signature · 4 lines
Przemyslaw Marczak Samsung R&D Institute Poland Samsung Electronics p.marczak at samsung.com
PATCH v4 11/16 dm: regulator: add fixed voltage regulator driver
+CC Simon
Quoted 24 lines · Przemyslaw Marczak
Hello Simon,
Quoted 21 lines · Przemyslaw Marczak
This driver implements regulator operations for fixed Voltage/Current value regulators. beside the standard regulator constraints, which are put into the uclass platform data, a typical fixed regulator node provides
few additional properties like:
- gpio
- gpio-open-drain
- enable-active-high
- startup-delay-us
The only 'gpio' is used by this driver and is kept in structure of type 'fixed_regulator_platdata', as a device platform data (dev->platdata).The driver implements:
-get_value
-get_current
-get_enable
-set_enableThe regulator calls and commands can be used for fixed-regulator devices, and the proper error will be returned for prohibited.
Quoted 7 lines
Quoted 2 lines
Signed-off-by Przemyslaw Marczak <[email protected]>I missed the separation (---) here and I see that you add ACK below the changes.
Could you remove them from the tree?
[...]
Best regards,
Signature · 4 lines
Przemyslaw Marczak Samsung R&D Institute Poland Samsung Electronics p.marczak at samsung.com
PATCH v4 11/16 dm: regulator: add fixed voltage regulator driver
In reply to Przemyslaw MarczakHi Przemyslaw,
Quoted 24 lines · Przemyslaw Marczak
Hello Simon,
Quoted 21 lines · Przemyslaw Marczak
This driver implements regulator operations for fixed Voltage/Current value regulators. beside the standard regulator constraints, which are put into the uclass platform data, a typical fixed regulator node provides few additional properties like:
- gpio
- gpio-open-drain
- enable-active-high
- startup-delay-us
The only 'gpio' is used by this driver and is kept in structure of type 'fixed_regulator_platdata', as a device platform data (dev->platdata).The driver implements:
-get_value
-get_current
-get_enable
-set_enableThe regulator calls and commands can be used for fixed-regulator devices, and the proper error will be returned for prohibited.
Quoted 6 lines
Quoted 2 lines
Signed-off-by Przemyslaw Marczak <[email protected]>I missed the separation (---) here and I see that you add ACK below the changes.
Could you remove them from the tree?
OK, done. You could try patman which handles this automatically.
Regards,
Simon
PATCH v4 12/16 doc: driver-model: pmic and regulator uclass documentation
In reply to Przemyslaw MarczakSince this framework is still under the construction, the main documentation is kept in the header files.
---
Changes v2, V3:
- update documentation with the framework api changes
- remove doc file name 'dm' prefix
Changes V4:
- move the description to the headers and leave only general info
--- doc/driver-model/pmic-framework.txt | 142 ++++++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 doc/driver-model/pmic-framework.txt
doc/driver-model/pmic-framework.txt new file +142 -0
@@ -0,0 +1,142 @@ +# +# (C) Copyright 2014-2015 Samsung Electronics +# Przemyslaw Marczak <[email protected]> +# +# SPDX-License-Identifier: GPL-2.0+ +# + +PMIC framework based on Driver Model +==================================== +TOC: +1. Introduction +2. How does it work +3. Pmic uclass +4. Regulator uclass + +1. Introduction +=============== +This is an introduction to driver-model multi uclass PMIC IC's support. +At present it's based on two uclass types: +- UCLASS_PMIC - basic uclass type for PMIC I/O, which provides common + read/write interface. +- UCLASS_REGULATOR - additional uclass type for specific PMIC features, + which are Voltage/Current regulators. + +New files: +UCLASS_PMIC: +- drivers/power/pmic/pmic-uclass.c +- include/power/pmic.h +UCLASS_REGULATOR: +- drivers/power/regulator/regulator-uclass.c +- include/power/regulator.h + +Commands: +- common/cmd_pmic.c +- common/cmd_regulator.c + +2. How doees it work +==================== +The Power Management Integrated Circuits (PMIC) are used in embedded systems +to provide stable, precise and specific voltage power source with over-voltage +and thermal protection circuits. + +The single PMIC can provide various functions by single or multiple interfaces, +like in the example below. + +-- SoC + | + | ______________________________________ + | BUS 0 | Multi interface PMIC IC |--> LDO out 1 + | e.g.I2C0 | |--> LDO out N + |-----------|---- PMIC device 0 (READ/WRITE ops) | + | or SPI0 | |_ REGULATOR device (ldo/... ops) |--> BUCK out 1 + | | |_ CHARGER device (charger ops) |--> BUCK out M + | | |_ MUIC device (microUSB con ops) | + | BUS 1 | |_ ... |---> BATTERY + | e.g.I2C1 | | + |-----------|---- PMIC device 1 (READ/WRITE ops) |---> USB in 1 + . or SPI1 | |_ RTC device (rtc ops) |---> USB in 2 + . |______________________________________|---> USB out + . + +Since U-Boot provides driver model features for I2C and SPI bus drivers, +the PMIC devices should also support this. By the pmic and regulator API's, +PMIC drivers can simply provide a common functions, for multi-interface and +and multi-instance device support. + +Basic design assumptions: + +- Common I/O API - UCLASS_PMIC +For the multi-function PMIC devices, this can be used as parent I/O device +for each IC's interface. Then, each children uses the same dev for read/write. + +- Common regulator API - UCLASS_REGULATOR +For driving the regulator attributes, auto setting function or command line +interface, based on kernel-style regulator device tree constraints. + +For simple implementations, regulator drivers are not required, so the code can +use pmic read/write directly. + +3. Pmic uclass +============== +The basic informations: +* Uclass: 'UCLASS_PMIC' +* Header: 'include/power/pmic.h' +* Core: 'drivers/power/pmic/pmic-uclass.c' + config: 'CONFIG_DM_PMIC' +* Command: 'common/cmd_pmic.c' + config: 'CONFIG_CMD_PMIC' +* Example: 'drivers/power/pmic/max77686.c' + +This is still under the construction. So for the API description, please refer +to the header file. + +As an example of the pmic driver, please refer to the MAX77686 driver. + +Please pay attention for the driver's '.bind' method. Exactly the function call: +'pmic_bind_childs()', which is used to bind the regulators by using the array of +regulator's node, compatible prefixes. + +The 'pmic; command also supports the new API. So the pmic command can be enabled +by adding CONFIG_CMD_PMIC. +The new pmic command allows to: +- list pmic devices +- choose the current device (like the mmc command) +- read or write the pmic register +- dump all pmic registers + +This command can use only UCLASS_PMIC devices, since this uclass is designed +for pmic I/O operations only. + +For more informations, please refer to the file: 'common/cmd_pmic.c'. + +4. Regulator uclass +=================== +The basic informations: +* Uclass: 'UCLASS_REGULATOR' +* Header: 'include/power/regulator.h' +* Core: 'drivers/power/regulator/regulator-uclass.c' + config: 'CONFIG_DM_REGULATOR' + binding: 'doc/device-tree-bindings/regulator/regulator.txt' +* Command: 'common/cmd_regulator.c' + config: 'CONFIG_CMD_REGULATOR' +* Example: 'drivers/power/regulator/max77686.c' + 'drivers/power/pmic/max77686.c' (required I/O driver for the above) +* Example: 'drivers/power/regulator/fixed.c' + config" 'CONFIG_DM_REGULATOR_FIXED' + +This is still under the construction. So for the API description, please refer +to the header file. + +For the example regulator driver, please refer to the MAX77686 regulator driver, +but this driver can't operate without pmic's example driver, which provides an +I/O interface for MAX77686 regulator. + +The second example is a fixed Voltage/Current regulator for a common use. + +The 'regulator' command also supports the new API. The command allow: +- list regulator devices +- choose the current device (like the mmc command) +- do all regulator-specific operations + +For more informations, please refer to the file: 'common/cmd_regulator.c'
Signature · 1 line
1.9.1
PATCH v4 12/16 doc: driver-model: pmic and regulator uclass documentation
Hi Przemyslaw,
Quoted 9 lines · Przemyslaw Marczak
Since this framework is still under the construction, the main documentation is kept in the header files.
Signed-off-by Przemyslaw Marczak <[email protected]>---
Changes v2, V3:
- update documentation with the framework api changes
- remove doc file name 'dm' prefix
Quoted 7 lines
Changes V4:
- move the description to the headers and leave only general info--- doc/driver-model/pmic-framework.txt | 142 ++++++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 doc/driver-model/pmic-framework.txt
Quoted 93 lines
doc/driver-model/pmic-framework.txt new file +86
-0@@ -0,0 +1,142 @@ +# +# (C) Copyright 2014-2015 Samsung Electronics +# Przemyslaw Marczak <[email protected]> +# +# SPDX-License-Identifier: GPL-2.0+ +# + +PMIC framework based on Driver Model +==================================== +TOC: +1. Introduction +2. How does it work +3. Pmic uclass +4. Regulator uclass + +1. Introduction +=============== +This is an introduction to driver-model multi uclass PMIC IC's support. +At present it's based on two uclass types: +- UCLASS_PMIC - basic uclass type for PMIC I/O, which provides common + read/write interface. +- UCLASS_REGULATOR - additional uclass type for specific PMIC features, + which are Voltage/Current regulators. + +New files: +UCLASS_PMIC: +- drivers/power/pmic/pmic-uclass.c +- include/power/pmic.h +UCLASS_REGULATOR: +- drivers/power/regulator/regulator-uclass.c +- include/power/regulator.h + +Commands: +- common/cmd_pmic.c +- common/cmd_regulator.c + +2. How doees it work +==================== +The Power Management Integrated Circuits (PMIC) are used in embedded systems +to provide stable, precise and specific voltage power source with over-voltage +and thermal protection circuits. + +The single PMIC can provide various functions by single or multiple interfaces, +like in the example below. + +-- SoC + | + | ______________________________________ + | BUS 0 | Multi interface PMIC IC |--> LDO out 1 + | e.g.I2C0 | |--> LDO out N + |-----------|---- PMIC device 0 (READ/WRITE ops) | + | or SPI0 | |_ REGULATOR device (ldo/... ops) |--> BUCK out 1 + | | |_ CHARGER device (charger ops) |--> BUCK out M + | | |_ MUIC device (microUSB con ops) | + | BUS 1 | |_ ... |---> BATTERY + | e.g.I2C1 | | + |-----------|---- PMIC device 1 (READ/WRITE ops) |---> USB in 1 + . or SPI1 | |_ RTC device (rtc ops) |---> USB in 2 + . |______________________________________|---> USB out + . + +Since U-Boot provides driver model features for I2C and SPI bus drivers, +the PMIC devices should also support this. By the pmic and regulator API's, +PMIC drivers can simply provide a common functions, for multi-interface and +and multi-instance device support. + +Basic design assumptions: + +- Common I/O API - UCLASS_PMIC +For the multi-function PMIC devices, this can be used as parent I/O device +for each IC's interface. Then, each children uses the same dev for read/write. + +- Common regulator API - UCLASS_REGULATOR +For driving the regulator attributes, auto setting function or command line +interface, based on kernel-style regulator device tree constraints. + +For simple implementations, regulator drivers are not required, so the code can +use pmic read/write directly. + +3. Pmic uclass +============== +The basic informations: +* Uclass: 'UCLASS_PMIC' +* Header: 'include/power/pmic.h' +* Core: 'drivers/power/pmic/pmic-uclass.c' + config: 'CONFIG_DM_PMIC'
doc/driver-model/pmic-framework.txt line 96
Quoted 10 lines
doc/driver-model/pmic-framework.txt new file +10
-0+* Command: 'common/cmd_pmic.c' + config: 'CONFIG_CMD_PMIC' +* Example: 'drivers/power/pmic/max77686.c' + +This is still under the construction. So for the API description, please refer +to the header file. + +As an example of the pmic driver, please refer to the MAX77686 driver. + +Please pay attention for the driver's '.bind' method. Exactly the function call:
I think 'driver's bind() method' is better than a quoted '.bind'.
Quoted 5 lines
doc/driver-model/pmic-framework.txt new file +5
-0+'pmic_bind_childs()', which is used to bind the regulators by using the array of +regulator's node, compatible prefixes. + +The 'pmic; command also supports the new API. So the pmic command can be enabled +by adding CONFIG_CMD_PMIC.
doc/driver-model/pmic-framework.txt line 111
Quoted 10 lines
doc/driver-model/pmic-framework.txt new file +10
-0+The new pmic command allows to: +- list pmic devices +- choose the current device (like the mmc command) +- read or write the pmic register +- dump all pmic registers + +This command can use only UCLASS_PMIC devices, since this uclass is designed +for pmic I/O operations only. + +For more informations, please refer to the file: 'common/cmd_pmic.c'.
information
doc/driver-model/pmic-framework.txt line 115
Quoted 4 lines
doc/driver-model/pmic-framework.txt new file +4
-0+ +4. Regulator uclass +=================== +The basic informations:
information
Quoted 4 lines
doc/driver-model/pmic-framework.txt new file +4
-0+* Uclass: 'UCLASS_REGULATOR' +* Header: 'include/power/regulator.h' +* Core: 'drivers/power/regulator/regulator-uclass.c' + config: 'CONFIG_DM_REGULATOR'
doc/driver-model/pmic-framework.txt line 129
Quoted 10 lines
doc/driver-model/pmic-framework.txt new file +10
-0+ binding: 'doc/device-tree-bindings/regulator/regulator.txt' +* Command: 'common/cmd_regulator.c' + config: 'CONFIG_CMD_REGULATOR' +* Example: 'drivers/power/regulator/max77686.c' + 'drivers/power/pmic/max77686.c' (required I/O driver for the above) +* Example: 'drivers/power/regulator/fixed.c' + config" 'CONFIG_DM_REGULATOR_FIXED' + +This is still under the construction. So for the API description, please refer +to the header file.
What is still under construction?
doc/driver-model/pmic-framework.txt line 137
Quoted 8 lines
doc/driver-model/pmic-framework.txt new file +8
-0+ +For the example regulator driver, please refer to the MAX77686 regulator driver, +but this driver can't operate without pmic's example driver, which provides an +I/O interface for MAX77686 regulator. + +The second example is a fixed Voltage/Current regulator for a common use. + +The 'regulator' command also supports the new API. The command allow:
allows, or maybe s/allow/allows you to/
Quoted 8 lines
doc/driver-model/pmic-framework.txt new file +5
-1+- list regulator devices +- choose the current device (like the mmc command) +- do all regulator-specific operations + +For more informations, please refer to the file: 'common/cmd_regulator.c' --1.9.1
Regards,
Simon
PATCH v4 12/16 doc: driver-model: pmic and regulator uclass documentation
Quoted 15 lines · Simon Glass
Hi Przemyslaw,
Quoted 12 lines · Przemyslaw Marczak
Since this framework is still under the construction, the main documentation is kept in the header files.
Signed-off-by Przemyslaw Marczak <[email protected]>---
Changes v2, V3:
- update documentation with the framework api changes
- remove doc file name 'dm' prefixChanges V4:
- move the description to the headers and leave only general info
Quoted 6 lines
Quoted 4 lines
--- doc/driver-model/pmic-framework.txt | 142 ++++++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 doc/driver-model/pmic-framework.txtAcked-by Simon Glass <[email protected]>
Applied to u-boot-dm/next, thanks!
PATCH v4 12/16 doc: driver-model: pmic and regulator uclass documentation
In reply to Simon GlassHello,
Quoted 153 lines · Simon Glass
Hi Przemyslaw,
Quoted 9 lines · Przemyslaw Marczak
Since this framework is still under the construction, the main documentation is kept in the header files.
Signed-off-by Przemyslaw Marczak <[email protected]>---
Changes v2, V3:
- update documentation with the framework api changes
- remove doc file name 'dm' prefixQuoted 7 lines
Changes V4:
- move the description to the headers and leave only general info--- doc/driver-model/pmic-framework.txt | 142 ++++++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+)create mode 100644
doc/driver-model/pmic-framework.txtAcked-by Simon Glass <[email protected]>Quoted 93 lines
doc/driver-model/pmic-framework.txt new file +86
-0@@ -0,0 +1,142 @@ +# +# (C) Copyright 2014-2015 Samsung Electronics +# Przemyslaw Marczak <[email protected]> +# +# SPDX-License-Identifier: GPL-2.0+ +# + +PMIC framework based on Driver Model +==================================== +TOC: +1. Introduction +2. How does it work +3. Pmic uclass +4. Regulator uclass + +1. Introduction +=============== +This is an introduction to driver-model multi uclass PMIC IC's support. +At present it's based on two uclass types: +- UCLASS_PMIC - basic uclass type for PMIC I/O, which provides common + read/write interface. +- UCLASS_REGULATOR - additional uclass type for specific PMIC features, + which are Voltage/Current regulators. + +New files: +UCLASS_PMIC: +- drivers/power/pmic/pmic-uclass.c +- include/power/pmic.h +UCLASS_REGULATOR: +- drivers/power/regulator/regulator-uclass.c +- include/power/regulator.h + +Commands: +- common/cmd_pmic.c +- common/cmd_regulator.c + +2. How doees it work +==================== +The Power Management Integrated Circuits (PMIC) are used in embedded systems +to provide stable, precise and specific voltage power source with over-voltage +and thermal protection circuits. + +The single PMIC can provide various functions by single or multiple interfaces, +like in the example below. + +-- SoC + | + | ______________________________________ + | BUS 0 | Multi interface PMIC IC |--> LDO out 1 + | e.g.I2C0 | |--> LDO out N + |-----------|---- PMIC device 0 (READ/WRITE ops) | + | or SPI0 | |_ REGULATOR device (ldo/... ops) |--> BUCK out 1 + | | |_ CHARGER device (charger ops) |--> BUCK out M + | | |_ MUIC device (microUSB con ops) | + | BUS 1 | |_ ... |---> BATTERY + | e.g.I2C1 | | + |-----------|---- PMIC device 1 (READ/WRITE ops) |---> USB in 1 + . or SPI1 | |_ RTC device (rtc ops) |---> USB in 2 + . |______________________________________|---> USB out + . + +Since U-Boot provides driver model features for I2C and SPI bus drivers, +the PMIC devices should also support this. By the pmic and regulator API's, +PMIC drivers can simply provide a common functions, for multi-interface and +and multi-instance device support. + +Basic design assumptions: + +- Common I/O API - UCLASS_PMIC +For the multi-function PMIC devices, this can be used as parent I/O device +for each IC's interface. Then, each children uses the same dev for read/write. + +- Common regulator API - UCLASS_REGULATOR +For driving the regulator attributes, auto setting function or command line +interface, based on kernel-style regulator device tree constraints. + +For simple implementations, regulator drivers are not required, so the code can +use pmic read/write directly. + +3. Pmic uclass +============== +The basic informations: +* Uclass: 'UCLASS_PMIC' +* Header: 'include/power/pmic.h' +* Core: 'drivers/power/pmic/pmic-uclass.c' + config: 'CONFIG_DM_PMIC'doc/driver-model/pmic-framework.txt line 96
Quoted 10 lines
doc/driver-model/pmic-framework.txt new file +10
-0+* Command: 'common/cmd_pmic.c' + config: 'CONFIG_CMD_PMIC' +* Example: 'drivers/power/pmic/max77686.c' + +This is still under the construction. So for the API description, please refer +to the header file. + +As an example of the pmic driver, please refer to the MAX77686 driver. + +Please pay attention for the driver's '.bind' method. Exactly the function call:I think 'driver's
bind()method' is better than a quoted '.bind'.Quoted 5 lines
doc/driver-model/pmic-framework.txt new file +5
-0+'pmic_bind_childs()', which is used to bind the regulators by using the array of +regulator's node, compatible prefixes. + +The 'pmic; command also supports the new API. So the pmic command can be enabled +by adding CONFIG_CMD_PMIC.doc/driver-model/pmic-framework.txt line 111
Quoted 10 lines
doc/driver-model/pmic-framework.txt new file +10
-0+The new pmic command allows to: +- list pmic devices +- choose the current device (like the mmc command) +- read or write the pmic register +- dump all pmic registers + +This command can use only UCLASS_PMIC devices, since this uclass is designed +for pmic I/O operations only. + +For more informations, please refer to the file: 'common/cmd_pmic.c'.information
doc/driver-model/pmic-framework.txt line 115
Quoted 4 lines
doc/driver-model/pmic-framework.txt new file +4
-0+ +4. Regulator uclass +=================== +The basic informations:information
Quoted 17 lines
Quoted 4 lines
doc/driver-model/pmic-framework.txt new file +4
-0+* Uclass: 'UCLASS_REGULATOR' +* Header: 'include/power/regulator.h' +* Core: 'drivers/power/regulator/regulator-uclass.c' + config: 'CONFIG_DM_REGULATOR'doc/driver-model/pmic-framework.txt line 129
Quoted 10 lines
doc/driver-model/pmic-framework.txt new file +10
-0+ binding: 'doc/device-tree-bindings/regulator/regulator.txt' +* Command: 'common/cmd_regulator.c' + config: 'CONFIG_CMD_REGULATOR' +* Example: 'drivers/power/regulator/max77686.c' + 'drivers/power/pmic/max77686.c' (required I/O driver for the above) +* Example: 'drivers/power/regulator/fixed.c' + config" 'CONFIG_DM_REGULATOR_FIXED' + +This is still under the construction. So for the API description, please refer +to the header file.What is still under construction?
We need add muic, charger, etc., so the whole framework isn't finished yet.
Quoted 11 lines
doc/driver-model/pmic-framework.txt line 137
Quoted 8 lines
doc/driver-model/pmic-framework.txt new file +8
-0+ +For the example regulator driver, please refer to the MAX77686 regulator driver, +but this driver can't operate without pmic's example driver, which provides an +I/O interface for MAX77686 regulator. + +The second example is a fixed Voltage/Current regulator for a common use. + +The 'regulator' command also supports the new API. The command allow:allows, or maybe s/allow/allows you to/
Quoted 12 lines
Quoted 8 lines
doc/driver-model/pmic-framework.txt new file +5
-1+- list regulator devices +- choose the current device (like the mmc command) +- do all regulator-specific operations + +For more informations, please refer to the file: 'common/cmd_regulator.c' --1.9.1
Regards,
Simon
Thank you, I will fix the mistakes.
Best regards,
Signature · 4 lines
Przemyslaw Marczak Samsung R&D Institute Poland Samsung Electronics p.marczak at samsung.com
PATCH v4 13/16 dm: board:samsung: power_init_board: add requirement of CONFIG_DM_PMIC
In reply to Przemyslaw MarczakIn the power_init_board function call, regulator driver init is called, so before compile, make sure that any power framework is defined.
--- board/samsung/common/board.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
board/samsung/common/board.c +2 -2
@@ -21,9 +21,9 @@#include <asm/arch/pinmux.h> #include <asm/arch/power.h> #include <asm/arch/system.h> -#include <power/pmic.h> #include <asm/arch/sromc.h> #include <lcd.h> +#include <i2c.h> #include <samsung/misc.h> #include <usb.h>
@@ -169,7 +169,7 @@ int board_early_init_f(void) }#endif -#if defined(CONFIG_POWER ) +#if defined(CONFIG_POWER ) || defined(CONFIG_DM_PMIC )int power_init_board (void ) {set_ps_hold_ctrl ();
Signature · 1 line
1.9.1
PATCH v4 13/16 dm: board:samsung: power_init_board: add requirement of CONFIG_DM_PMIC
Quoted 7 lines · Przemyslaw Marczak
In the
power_init_boardfunction call, regulator driver init is called, so before compile, make sure that any power framework is defined.Signed-off-by Przemyslaw Marczak <[email protected]>--- board/samsung/common/board.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
Would be good to sort the includes correctly (unrelated to your patch).
PATCH v4 13/16 dm: board:samsung: power_init_board: add requirement of CONFIG_DM_PMIC
Quoted 4 lines · Simon Glass
Quoted 3 lines · Przemyslaw Marczak
In the
power_init_boardfunction call, regulator driver init is called, so before compile, make sure that any power framework is defined.
Quoted 8 lines
Quoted 4 lines
Signed-off-by Przemyslaw Marczak <[email protected]>--- board/samsung/common/board.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)Acked-by Simon Glass <[email protected]>Would be good to sort the includes correctly (unrelated to your patch).
Applied to u-boot-dm/next, thanks!
PATCH v4 13/16 dm: board:samsung: power_init_board: add requirement of CONFIG_DM_PMIC
In reply to Simon GlassHello,
Quoted 4 lines · Simon Glass
Quoted 3 lines · Przemyslaw Marczak
In the
power_init_boardfunction call, regulator driver init is called, so before compile, make sure that any power framework is defined.
Quoted 9 lines
Quoted 4 lines
Signed-off-by Przemyslaw Marczak <[email protected]>--- board/samsung/common/board.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)Acked-by Simon Glass <[email protected]>Would be good to sort the includes correctly (unrelated to your patch).
Ok, will do that.
Best regards,
Signature · 4 lines
Przemyslaw Marczak Samsung R&D Institute Poland Samsung Electronics p.marczak at samsung.com
PATCH v4 14/16 odroid: board: add support to dm pmic api
In reply to Przemyslaw MarczakThis commit change the old pmic framework calls to the new ones.
---
Changes v2:
- remove board_init_i2c() call
- update regulator calls
- update headers
- samsung/misc.c: include required header
Changes v3:
- adjust regulator calls to new api
Changes V4:
- use regulator_list_autoset() for mmc regulators
--- board/samsung/common/misc.c | 1 + board/samsung/odroid/odroid.c | 77 +++++++++++++++++++++++++------------------ 2 files changed, 46 insertions(+), 32 deletions(-)
board/samsung/common/misc.c +1 -0
@@ -16,6 +16,7 @@#include <asm/arch/cpu.h> #include <asm/gpio.h> #include <linux/input.h> +#include <dm.h> #include <power/pmic.h> #include <mmc.h>
board/samsung/odroid/odroid.c +45 -32
127 lines not on this page · raw message
Signature · 1 line
1.9.1
PATCH v4 14/16 odroid: board: add support to dm pmic api
Hi Przemyslaw,
Quoted 13 lines · Przemyslaw Marczak
This commit change the old pmic framework calls to the new ones.
Signed-off-by Przemyslaw Marczak <[email protected]>---
Changes v2:
- removeboard_init_i2c()call
- update regulator calls
- update headers
-samsung/misc.c: include required headerChanges v3:
- adjust regulator calls to new api
Quoted 7 lines
Changes V4:
- useregulator_list_autoset()for mmc regulators--- board/samsung/common/misc.c | 1 + board/samsung/odroid/odroid.c | 77 +++++++++++++++++++++++++------------------ 2 files changed, 46 insertions(+), 32 deletions(-)
Quoted 28 lines
board/samsung/common/misc.c +1
-0@@ -16,6 +16,7 @@#include <asm/arch/cpu.h> #include <asm/gpio.h> #include <linux/input.h> +#include <dm.h> #include <power/pmic.h> #include <mmc.h> board/samsung/odroid/odroid.c +2
-0@@ -12,7 +12,9 @@#include <asm/arch/gpio.h> #include <asm/gpio.h> #include <asm/arch/cpu.h> +#include <dm.h> #include <power/pmic.h> +#include <power/regulator.h> #include <power/max77686_pmic.h> #include <errno.h> #include <mmc.h>
board/samsung/odroid/odroid.c enum { · line 39
Quoted 7 lines
board/samsung/odroid/odroid.c +4
-0@@ -31,6 +33,12 @@ enum { ODROID_TYPES, }; +static const char *mmc_regulators[] = { +"VDDQ_EMMC_1.8V" , +"VDDQ_EMMC_2.8V" , +"TFLASH_2.8V" ,
I wonder if it would be better to terminate with NULL instead of requiring an ARRAY_SIZE?
Quoted 117 lines
board/samsung/odroid/odroid.c +39
-33+}; +void set_board_type (void ) {/* Set GPA1 pin 1 to HI - enable XCL205 output */ @@ -403,21 +411,6 @@ static void board_gpio_init(void)#endif } -static int pmic_init_max77686 (void ) -{ -struct pmic *p =pmic_get ("MAX77686_PMIC" ); - -if (pmic_probe (p)) -return -ENODEV ; - -/* Set LDO Voltage */ -max77686_set_ldo_voltage (p,20 ,1800000 );/* LDO20 eMMC */ -max77686_set_ldo_voltage (p,21 ,2800000 );/* LDO21 SD */ -max77686_set_ldo_voltage (p,22 ,2800000 );/* LDO22 eMMC */ - -return 0 ; -} -int exynos_early_init_f (void ) {board_clock_init ();@@ -434,8 +427,10 @@ int exynos_init(void)int exynos_power_init (void ) { -pmic_init (0 ); -pmic_init_max77686 (); +int list_count =ARRAY_SIZE (mmc_regulators); + +if (regulator_list_autoset (mmc_regulators, list_count,NULL , true)) +error ("Unable to init all mmc regulators" );return 0 ; }@@ -443,19 +438,20 @@ int exynos_power_init(void)#ifdef CONFIG_USB_GADGET static int s5pc210_phy_control (int on) { -struct pmic *p_pmic; +struct udevice *dev; +int ret; - p_pmic =pmic_get ("MAX77686_PMIC" ); -if (!p_pmic) -return -ENODEV ; - -if (pmic_probe (p_pmic)) -return -1 ; + ret =regulator_by_platname ("VDD_UOTG_3.0V" , &dev); +if (ret) { +error ("Regulator get error: %d" , ret); +return ret; + }if (on) -return max77686_set_ldo_mode (p_pmic,12 ,OPMODE_ON ); +return regulator_set_mode (dev,OPMODE_ON );else -return max77686_set_ldo_mode (p_pmic,12 ,OPMODE_LPM ); +return regulator_set_mode (dev,OPMODE_LPM ); + } struct s3c_plat_otg_data s5pc210_otg_data = {@@ -472,7 +468,8 @@ struct s3c_plat_otg_data s5pc210_otg_data = {int board_usb_init (int index,enum usb_init_type init) {#ifdef CONFIG_CMD_USB -struct pmic *p_pmic; +struct udevice *dev; +int ret;/* Set Ref freq 0 => 24MHz, 1 => 26MHz*/ /* Odroid Us have it at 24MHz, Odroid Xs at 26MHz */ @@ -490,14 +487,30 @@ int board_usb_init(int index, enum usb_init_type init)/* Power off and on BUCK8 for LAN9730 */ debug ("LAN9730 - Turning power buck 8 OFF and ON.\n" ); - p_pmic =pmic_get ("MAX77686_PMIC" ); -if (p_pmic && !pmic_probe (p_pmic)) { -max77686_set_buck_voltage (p_pmic,8 ,750000 ); -max77686_set_buck_voltage (p_pmic,8 ,3300000 ); + ret =regulator_by_platname ("VCC_P3V3_2.85V" , &dev); +if (ret) { +error ("Regulator get error: %d" , ret); +return ret; } -#endif + ret =regulator_set_enable (dev, true); +if (ret) { +error ("Regulator %s enable setting error: %d" , dev->name, ret); +return ret; + } + ret =regulator_set_value (dev,750000 ); +if (ret) { +error ("Regulator %s value setting error: %d" , dev->name, ret); +return ret; + } + + ret =regulator_set_value (dev,3300000 ); +if (ret) { +error ("Regulator %s value setting error: %d" , dev->name, ret); +return ret; + } +#endif debug ("USB_udc_probe\n" );return s3c_udc_probe (&s5pc210_otg_data); } --
Quoted 2 lines
1.9.1
Regards,
Simon
PATCH v4 14/16 odroid: board: add support to dm pmic api
Quoted 19 lines · Simon Glass
Hi Przemyslaw,
Quoted 16 lines · Przemyslaw Marczak
This commit change the old pmic framework calls to the new ones.
Signed-off-by Przemyslaw Marczak <[email protected]>---
Changes v2:
- removeboard_init_i2c()call
- update regulator calls
- update headers
-samsung/misc.c: include required headerChanges v3:
- adjust regulator calls to new apiChanges V4:
- useregulator_list_autoset()for mmc regulators
Quoted 6 lines
Quoted 4 lines
--- board/samsung/common/misc.c | 1 + board/samsung/odroid/odroid.c | 77 +++++++++++++++++++++++++------------------ 2 files changed, 46 insertions(+), 32 deletions(-)Acked-by Simon Glass <[email protected]>
Applied to u-boot-dm/next, thanks!
PATCH v4 14/16 odroid: board: add support to dm pmic api
In reply to Simon GlassHello Simon,
Quoted 57 lines · Simon Glass
Hi Przemyslaw,
Quoted 13 lines · Przemyslaw Marczak
This commit change the old pmic framework calls to the new ones.
Signed-off-by Przemyslaw Marczak <[email protected]>---
Changes v2:
- removeboard_init_i2c()call
- update regulator calls
- update headers
-samsung/misc.c: include required headerChanges v3:
- adjust regulator calls to new apiQuoted 7 lines
Changes V4:
- useregulator_list_autoset()for mmc regulators--- board/samsung/common/misc.c | 1 + board/samsung/odroid/odroid.c | 77 +++++++++++++++++++++++++------------------ 2 files changed, 46 insertions(+), 32 deletions(-)Acked-by Simon Glass <[email protected]>Quoted 31 lines
board/samsung/common/misc.c +1
-0@@ -16,6 +16,7 @@#include <asm/arch/cpu.h> #include <asm/gpio.h> #include <linux/input.h> +#include <dm.h> #include <power/pmic.h> #include <mmc.h> board/samsung/odroid/odroid.c +2
-0@@ -12,7 +12,9 @@#include <asm/arch/gpio.h> #include <asm/gpio.h> #include <asm/arch/cpu.h> +#include <dm.h> #include <power/pmic.h> +#include <power/regulator.h> #include <power/max77686_pmic.h> #include <errno.h> #include <mmc.h> @@ -31,6 +33,12 @@ enum { ODROID_TYPES, };
Quoted 8 lines
board/samsung/odroid/odroid.c enum { · line 39
Quoted 4 lines
board/samsung/odroid/odroid.c +4
-0+static const char *mmc_regulators[] = { +"VDDQ_EMMC_1.8V" , +"VDDQ_EMMC_2.8V" , +"TFLASH_2.8V" ,I wonder if it would be better to terminate with NULL instead of requiring an
ARRAY_SIZE?
Yes, I should do this, will fix.
Quoted 114 lines
Quoted 114 lines
board/samsung/odroid/odroid.c +39
-32+}; +void set_board_type (void ) {/* Set GPA1 pin 1 to HI - enable XCL205 output */ @@ -403,21 +411,6 @@ static void board_gpio_init(void)#endif } -static int pmic_init_max77686 (void ) -{ -struct pmic *p =pmic_get ("MAX77686_PMIC" ); - -if (pmic_probe (p)) -return -ENODEV ; - -/* Set LDO Voltage */ -max77686_set_ldo_voltage (p,20 ,1800000 );/* LDO20 eMMC */ -max77686_set_ldo_voltage (p,21 ,2800000 );/* LDO21 SD */ -max77686_set_ldo_voltage (p,22 ,2800000 );/* LDO22 eMMC */ - -return 0 ; -} -int exynos_early_init_f (void ) {board_clock_init ();@@ -434,8 +427,10 @@ int exynos_init(void)int exynos_power_init (void ) { -pmic_init (0 ); -pmic_init_max77686 (); +int list_count =ARRAY_SIZE (mmc_regulators); + +if (regulator_list_autoset (mmc_regulators, list_count,NULL , true)) +error ("Unable to init all mmc regulators" );return 0 ; }@@ -443,19 +438,20 @@ int exynos_power_init(void)#ifdef CONFIG_USB_GADGET static int s5pc210_phy_control (int on) { -struct pmic *p_pmic; +struct udevice *dev; +int ret; - p_pmic =pmic_get ("MAX77686_PMIC" ); -if (!p_pmic) -return -ENODEV ; - -if (pmic_probe (p_pmic)) -return -1 ; + ret =regulator_by_platname ("VDD_UOTG_3.0V" , &dev); +if (ret) { +error ("Regulator get error: %d" , ret); +return ret; + }if (on) -return max77686_set_ldo_mode (p_pmic,12 ,OPMODE_ON ); +return regulator_set_mode (dev,OPMODE_ON );else -return max77686_set_ldo_mode (p_pmic,12 ,OPMODE_LPM ); +return regulator_set_mode (dev,OPMODE_LPM ); + } struct s3c_plat_otg_data s5pc210_otg_data = {@@ -472,7 +468,8 @@ struct s3c_plat_otg_data s5pc210_otg_data = {int board_usb_init (int index,enum usb_init_type init) {#ifdef CONFIG_CMD_USB -struct pmic *p_pmic; +struct udevice *dev; +int ret;/* Set Ref freq 0 => 24MHz, 1 => 26MHz*/ /* Odroid Us have it at 24MHz, Odroid Xs at 26MHz */ @@ -490,14 +487,30 @@ int board_usb_init(int index, enum usb_init_type init)/* Power off and on BUCK8 for LAN9730 */ debug ("LAN9730 - Turning power buck 8 OFF and ON.\n" ); - p_pmic =pmic_get ("MAX77686_PMIC" ); -if (p_pmic && !pmic_probe (p_pmic)) { -max77686_set_buck_voltage (p_pmic,8 ,750000 ); -max77686_set_buck_voltage (p_pmic,8 ,3300000 ); + ret =regulator_by_platname ("VCC_P3V3_2.85V" , &dev); +if (ret) { +error ("Regulator get error: %d" , ret); +return ret; } -#endif + ret =regulator_set_enable (dev, true); +if (ret) { +error ("Regulator %s enable setting error: %d" , dev->name, ret); +return ret; + } + ret =regulator_set_value (dev,750000 ); +if (ret) { +error ("Regulator %s value setting error: %d" , dev->name, ret); +return ret; + } + + ret =regulator_set_value (dev,3300000 ); +if (ret) { +error ("Regulator %s value setting error: %d" , dev->name, ret); +return ret; + } +#endif debug ("USB_udc_probe\n" );
Quoted 9 lines
Quoted 5 lines
board/samsung/odroid/odroid.c +0
-1return s3c_udc_probe (&s5pc210_otg_data); } --1.9.1
Regards,
Simon
Best regards,
Signature · 4 lines
Przemyslaw Marczak Samsung R&D Institute Poland Samsung Electronics p.marczak at samsung.com
PATCH v4 15/16 odroid: dts: add 'voltage-regulators' description to max77686 node
In reply to Przemyslaw MarczakAdding regulators subnode to fdt max77686 node, allows properly init regulators by the max77686 regulator driver. This enables the complete functionality of the regulator command.
---
Changes V2:
- odroid: dts: remove pmic alias
Changes V3:
- none
Changes V4:
- add constraints for mmc regulators auto enable
--- arch/arm/dts/exynos4412-odroid.dts | 253 +++++++++++++++++++++++++++++++++++++ 1 file changed, 253 insertions(+)
arch/arm/dts/exynos4412-odroid.dts +253 -0
@@ -40,6 +40,259 @@ interrupts = <7 0>; reg = <0x09 0 0>; #clock-cells = <1>; + + voltage-regulators { + ldo1_reg: ldo1 { + regulator-compatible = "LDO1"; + regulator-name = "VDD_ALIVE_1.0V"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + }; + + ldo2_reg: ldo2 { + regulator-compatible = "LDO2"; + regulator-name = "VDDQ_VM1M2_1.2V"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + }; + + ldo3_reg: ldo3 { + regulator-compatible = "LDO3"; + regulator-name = "VCC_1.8V_AP"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + ldo4_reg: ldo4 { + regulator-compatible = "LDO4"; + regulator-name = "VDDQ_MMC2_2.8V"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + }; + + ldo5_reg: ldo5 { + regulator-compatible = "LDO5"; + regulator-name = "VDDQ_MMC0/1/3_1.8V"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + ldo6_reg: ldo6 { + regulator-compatible = "LDO6"; + regulator-name = "VMPLL_1.0V"; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + }; + + ldo7_reg: ldo7 { + regulator-compatible = "LDO7"; + regulator-name = "VPLL_1.1V"; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + }; + + ldo8_reg: ldo8 { + regulator-compatible = "LDO8"; + regulator-name = "VDD_MIPI/HDMI_1.0V"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + }; + + ldo9_reg: ldo9 { + regulator-compatible = "LDO9"; + regulator-name = "nc"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + ldo10_reg: ldo10 { + regulator-compatible = "LDO10"; + regulator-name = "VDD_MIPI/HDMI_1.8V"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + ldo11_reg: ldo11 { + regulator-compatible = "LDO11"; + regulator-name = "VDD_ABB1_1.8V"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + ldo12_reg: ldo12 { + regulator-compatible = "LDO12"; + regulator-name = "VDD_UOTG_3.0V"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + }; + + ldo13_reg: ldo13 { + regulator-compatible = "LDO13"; + regulator-name = "VDD_C2C_1.8V"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + ldo14_reg: ldo14 { + regulator-compatible = "LDO14"; + regulator-name = "VDD_ABB02_1.8V"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + ldo15_reg: ldo15 { + regulator-compatible = "LDO15"; + regulator-name = "VDD_HSIC/OTG_1.0V"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + }; + + ldo16_reg: ldo16 { + regulator-compatible = "LDO16"; + regulator-name = "VDD_HSIC_1.8V"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + ldo17_reg: ldo17 { + regulator-compatible = "LDO17"; + regulator-name = "VDDQ_CAM_1.2V"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + }; + + ldo18_reg: ldo18 { + regulator-compatible = "LDO18"; + regulator-name = "nc"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + ldo19_reg: ldo19 { + regulator-compatible = "LDO19"; + regulator-name = "nc"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + ldo20_reg: ldo20 { + regulator-compatible = "LDO20"; + regulator-name = "VDDQ_EMMC_1.8V"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + }; + + ldo21_reg: ldo21 { + regulator-compatible = "LDO21"; + regulator-name = "TFLASH_2.8V"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-always-on; + regulator-boot-on; + }; + + ldo22_reg: ldo22 { + regulator-compatible = "LDO22"; + regulator-name = "VDDQ_EMMC_2.8V"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-always-on; + regulator-boot-on; + }; + + ldo23_reg: ldo23 { + regulator-compatible = "LDO23"; + regulator-name = "nc"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + + ldo24_reg: ldo24 { + regulator-compatible = "LDO24"; + regulator-name = "nc"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + }; + + ldo25_reg: ldo25 { + regulator-compatible = "LDO25"; + regulator-name = "VDDQ_LCD_3.0V"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + }; + + ldo26_reg: ldo26 { + regulator-compatible = "LDO26"; + regulator-name = "nc"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + }; + + buck1_reg: buck at 1 { + regulator-compatible = "BUCK1"; + regulator-name = "VDD_MIF_1.0V"; + regulator-min-microvolt = <8500000>; + regulator-max-microvolt = <1100000>; + }; + + buck2_reg: buck at 2 { + regulator-compatible = "BUCK2"; + regulator-name = "VDD_ARM_1.0V"; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <1500000>; + }; + + buck3_reg: buck3 { + regulator-compatible = "BUCK3"; + regulator-name = "VDD_INT_1.1V"; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <1150000>; + }; + + buck4_reg: buck4 { + regulator-compatible = "BUCK4"; + regulator-name = "VDD_G3D_1.0V"; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <1150000>; + }; + + buck5_reg: buck5 { + regulator-compatible = "BUCK5"; + regulator-name = "VDDQ_AP_1.2V"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + }; + + buck6_reg: buck6 { + regulator-compatible = "BUCK6"; + regulator-name = "VCC_INL1/7_1.35V"; + regulator-min-microvolt = <1350000>; + regulator-max-microvolt = <1350000>; + }; + + buck7_reg: buck7 { + regulator-compatible = "BUCK7"; + regulator-name = "VCC_INL2/3/5_2.0V"; + regulator-min-microvolt = <2000000>; + regulator-max-microvolt = <2000000>; + }; + + buck8_reg: buck8 { + regulator-compatible = "BUCK8"; + regulator-name = "VCC_P3V3_2.85V"; + regulator-min-microvolt = <2850000>; + regulator-max-microvolt = <3300000>; + }; + + buck9_reg: buck9 { + regulator-compatible = "BUCK9"; + regulator-name = "nc"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + }; + }; }; };
Signature · 1 line
1.9.1
PATCH v4 15/16 odroid: dts: add 'voltage-regulators' description to max77686 node
Quoted 12 lines · Przemyslaw Marczak
Adding regulators subnode to fdt max77686 node, allows properly init regulators by the max77686 regulator driver. This enables the complete functionality of the regulator command.
Signed-off-by Przemyslaw Marczak <[email protected]>---
Changes V2:
- odroid: dts: remove pmic aliasChanges V3:
- none
Quoted 7 lines
Changes V4:
- add constraints for mmc regulators auto enable--- arch/arm/dts/exynos4412-odroid.dts | 253 +++++++++++++++++++++++++++++++++++++ 1 file changed, 253 insertions(+)
PATCH v4 15/16 odroid: dts: add 'voltage-regulators' description to max77686 node
Quoted 16 lines · Simon Glass
Quoted 15 lines · Przemyslaw Marczak
Adding regulators subnode to fdt max77686 node, allows properly init regulators by the max77686 regulator driver. This enables the complete functionality of the regulator command.
Signed-off-by Przemyslaw Marczak <[email protected]>---
Changes V2:
- odroid: dts: remove pmic aliasChanges V3:
- noneChanges V4:
- add constraints for mmc regulators auto enable
Quoted 6 lines
Quoted 4 lines
--- arch/arm/dts/exynos4412-odroid.dts | 253 +++++++++++++++++++++++++++++++++++++ 1 file changed, 253 insertions(+)Acked-by Simon Glass <[email protected]>
Applied to u-boot-dm/next, thanks!
PATCH v4 16/16 odroid: config: enable dm pmic, dm regulator and max77686 driver
In reply to Przemyslaw MarczakThis change enables the configs required to init and setup max77686 regulator driver, using the new driver model pmic and regulator API.
This commits enables:
- CONFIG_ERRNO_STR
- CONFIG_DM_PMIC
- CONFIG_DM_PMIC_CMD
- CONFIG_DM_PMIC_MAX77686
- CONFIG_DM_REGULATOR
- CONFIG_DM_REGULATOR_CMD
- CONFIG_DM_REGULATOR_MAX77686
And removes the unused:
- CONFIG_DM_I2C_COMPAT
- CONFIG_POWER
- CONFIG_POWER_I2C
- CONFIG_POWER_MAX77686
---
Changes V2:
- config: enable dm i2c; cleanup
- remove CONFIG_DM_I2C_COMPAT
- enable regulator command
Changes V3:
- move options to defconfig
Changes V4:
- update commands config names
--- configs/odroid_defconfig | 8 +++++++- include/configs/odroid.h | 5 ----- 2 files changed, 7 insertions(+), 6 deletions(-)
configs/odroid_defconfig +7 -1
@@ -4,5 +4,11 @@ CONFIG_TARGET_ODROID=y CONFIG_OF_CONTROL=y CONFIG_DEFAULT_DEVICE_TREE="exynos4412-odroid" CONFIG_DM_I2C=y -CONFIG_DM_I2C_COMPAT=y # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set +CONFIG_ERRNO_STR=y +CONFIG_DM_PMIC=y +CONFIG_CMD_PMIC=y +CONFIG_DM_PMIC_MAX77686=y +CONFIG_DM_REGULATOR=y +CONFIG_CMD_REGULATOR=y +CONFIG_DM_REGULATOR_MAX77686=y
include/configs/odroid.h +0 -5
@@ -182,11 +182,6 @@#define CONFIG_SYS_I2C_S3C24X0_SPEED 100000#define CONFIG_SYS_I2C_S3C24X0_SLAVE 0 -/* POWER */ -#define CONFIG_POWER -#define CONFIG_POWER_I2C -#define CONFIG_POWER_MAX77686 -/* GPT */ #define CONFIG_RANDOM_UUID
Signature · 1 line
1.9.1
PATCH v4 16/16 odroid: config: enable dm pmic, dm regulator and max77686 driver
Quoted 28 lines · Przemyslaw Marczak
This change enables the configs required to init and setup max77686 regulator driver, using the new driver model pmic and regulator API.
This commits enables:
-CONFIG_ERRNO_STR
-CONFIG_DM_PMIC
-CONFIG_DM_PMIC_CMD
-CONFIG_DM_PMIC_MAX77686
-CONFIG_DM_REGULATOR
-CONFIG_DM_REGULATOR_CMD
-CONFIG_DM_REGULATOR_MAX77686And removes the unused:
-CONFIG_DM_I2C_COMPAT
-CONFIG_POWER
-CONFIG_POWER_I2C
-CONFIG_POWER_MAX77686Signed-off-by Przemyslaw Marczak <[email protected]>---
Changes V2:
- config: enable dm i2c; cleanup
- removeCONFIG_DM_I2C_COMPAT
- enable regulator commandChanges V3:
- move options to defconfig
Quoted 7 lines
Changes V4:
- update commands config names--- configs/odroid_defconfig | 8 +++++++- include/configs/odroid.h | 5 ----- 2 files changed, 7 insertions(+), 6 deletions(-)
PATCH v4 16/16 odroid: config: enable dm pmic, dm regulator and max77686 driver
Quoted 32 lines · Simon Glass
Quoted 31 lines · Przemyslaw Marczak
This change enables the configs required to init and setup max77686 regulator driver, using the new driver model pmic and regulator API.
This commits enables:
-CONFIG_ERRNO_STR
-CONFIG_DM_PMIC
-CONFIG_DM_PMIC_CMD
-CONFIG_DM_PMIC_MAX77686
-CONFIG_DM_REGULATOR
-CONFIG_DM_REGULATOR_CMD
-CONFIG_DM_REGULATOR_MAX77686And removes the unused:
-CONFIG_DM_I2C_COMPAT
-CONFIG_POWER
-CONFIG_POWER_I2C
-CONFIG_POWER_MAX77686Signed-off-by Przemyslaw Marczak <[email protected]>---
Changes V2:
- config: enable dm i2c; cleanup
- removeCONFIG_DM_I2C_COMPAT
- enable regulator commandChanges V3:
- move options to defconfigChanges V4:
- update commands config names
Quoted 6 lines
Quoted 4 lines
--- configs/odroid_defconfig | 8 +++++++- include/configs/odroid.h | 5 ----- 2 files changed, 7 insertions(+), 6 deletions(-)Acked-by Simon Glass <[email protected]>
Applied to u-boot-dm/next, thanks!
v4 cover Power(full) framework based on Driver Model
In reply to Przemyslaw MarczakHi Przemyslaw,
Quoted 87 lines · Przemyslaw Marczak
Hello,
Again the next version. The changes are described below each commit message. This is rebased on last u-boot-dm/master after apply this patchset:
https://patchwork.ozlabs.org/patch/462775/
https://patchwork.ozlabs.org/patch/462777/
https://patchwork.ozlabs.org/patch/462776/This all can be found in here:
https://github.com/bobenstein/u-boot/tree/dm-pmic-v4Best regards,
Przemyslaw Marczak (16):
exynos5: fix build break by addingCONFIG_POWER
exynos4-common: remove the unsuedCONFIG_CMD_PMIC
lib:Kconfig: add entry forerrno_str()function
dm: pmic: add implementation of driver model pmic uclass
dm: regulator: add implementation of driver model regulator uclass
dm: pmic: add pmic command
dm: regulator: add regulator command
pmic: max77686 set the same compatible as in the kernel
dm: pmic: add max77686 pmic driver
dm: regulator: add max77686 regulator driver
dm: regulator: add fixed voltage regulator driver
doc: driver-model: pmic and regulator uclass documentation
dm: board:samsung:power_init_board: add requirement ofCONFIG_DM_PMIC
odroid: board: add support to dm pmic api
odroid: dts: add 'voltage-regulators' description to max77686 node
odroid: config: enable dm pmic, dm regulator and max77686 driverMakefile | 3 +- arch/arm/dts/exynos4412-odroid.dts | 255 ++++++- arch/arm/dts/exynos4412-trats2.dts | 2 +- arch/arm/dts/exynos5250-smdk5250.dts | 2 +- arch/arm/dts/exynos5250-snow.dts | 2 +- board/samsung/common/board.c | 4 +- board/samsung/common/misc.c | 1 + board/samsung/odroid/odroid.c | 77 ++- common/Kconfig | 36 + common/Makefile | 4 + common/cmd_pmic.c | 231 +++++++ common/cmd_regulator.c | 403 +++++++++++ configs/odroid_defconfig | 8 +- doc/device-tree-bindings/pmic/max77686.txt | 36 + doc/device-tree-bindings/regulator/fixed.txt | 38 ++ doc/device-tree-bindings/regulator/max77686.txt | 70 ++ doc/device-tree-bindings/regulator/regulator.txt | 55 ++ doc/driver-model/pmic-framework.txt | 142 ++++ drivers/power/Kconfig | 8 + drivers/power/Makefile | 1 - drivers/power/pmic/Kconfig | 18 + drivers/power/pmic/Makefile | 2 + drivers/power/pmic/max77686.c | 87 +++ drivers/power/pmic/pmic-uclass.c | 158 +++++ drivers/power/pmic/pmic_max77686.c | 2 +- drivers/power/regulator/Kconfig | 33 + drivers/power/regulator/Makefile | 10 + drivers/power/regulator/fixed.c | 126 ++++ drivers/power/regulator/max77686.c | 825 +++++++++++++++++++++++ drivers/power/regulator/regulator-uclass.c | 300 +++++++++ include/configs/exynos4-common.h | 1 - include/configs/exynos5-common.h | 4 + include/configs/odroid.h | 5 - include/dm/uclass-id.h | 4 + include/power/max77686_pmic.h | 29 +- include/power/pmic.h | 189 ++++++ include/power/regulator.h | 384 +++++++++++ lib/Kconfig | 8 + lib/fdtdec.c | 2 +- 39 files changed, 3512 insertions(+), 53 deletions(-) create mode 100644 common/cmd_pmic.c create mode 100644 common/cmd_regulator.c create mode 100644 doc/device-tree-bindings/pmic/max77686.txt create mode 100644 doc/device-tree-bindings/regulator/fixed.txt create mode 100644 doc/device-tree-bindings/regulator/max77686.txt create mode 100644 doc/device-tree-bindings/regulator/regulator.txt create mode 100644 doc/driver-model/pmic-framework.txt create mode 100644 drivers/power/pmic/Kconfig create mode 100644 drivers/power/pmic/max77686.c create mode 100644 drivers/power/pmic/pmic-uclass.c create mode 100644 drivers/power/regulator/Kconfig create mode 100644 drivers/power/regulator/Makefile create mode 100644 drivers/power/regulator/fixed.c create mode 100644 drivers/power/regulator/max77686.c create mode 100644 drivers/power/regulator/regulator-uclass.c create mode 100644 include/power/regulator.h
Quoted 3 lines
--
1.9.1
I'm going to test this and apply to u-boot-dm/next while we wait for you to finish the sandbox test code. I've made a few comments on the series. They are minor so I don't want to do another whole spin of the series (it takes time to review!), but you could do a fix-up patch or two if you like. I could perhaps squash them in if you prefer that, but honestly they are nits.
It will be great to get this into mainline soon!
Regards,
Simon
v4 cover Power(full) framework based on Driver Model
Hello Simon,
Quoted 101 lines · Simon Glass
Hi Przemyslaw,
Quoted 87 lines · Przemyslaw Marczak
Hello,
Again the next version. The changes are described below each commit message. This is rebased on last u-boot-dm/master after apply this patchset:
https://patchwork.ozlabs.org/patch/462775/
https://patchwork.ozlabs.org/patch/462777/
https://patchwork.ozlabs.org/patch/462776/This all can be found in here:
https://github.com/bobenstein/u-boot/tree/dm-pmic-v4Best regards,
Przemyslaw Marczak (16):
exynos5: fix build break by addingCONFIG_POWER
exynos4-common: remove the unsuedCONFIG_CMD_PMIC
lib:Kconfig: add entry forerrno_str()function
dm: pmic: add implementation of driver model pmic uclass
dm: regulator: add implementation of driver model regulator uclass
dm: pmic: add pmic command
dm: regulator: add regulator command
pmic: max77686 set the same compatible as in the kernel
dm: pmic: add max77686 pmic driver
dm: regulator: add max77686 regulator driver
dm: regulator: add fixed voltage regulator driver
doc: driver-model: pmic and regulator uclass documentation
dm: board:samsung:power_init_board: add requirement ofCONFIG_DM_PMIC
odroid: board: add support to dm pmic api
odroid: dts: add 'voltage-regulators' description to max77686 node
odroid: config: enable dm pmic, dm regulator and max77686 driverMakefile | 3 +- arch/arm/dts/exynos4412-odroid.dts | 255 ++++++- arch/arm/dts/exynos4412-trats2.dts | 2 +- arch/arm/dts/exynos5250-smdk5250.dts | 2 +- arch/arm/dts/exynos5250-snow.dts | 2 +- board/samsung/common/board.c | 4 +- board/samsung/common/misc.c | 1 + board/samsung/odroid/odroid.c | 77 ++- common/Kconfig | 36 + common/Makefile | 4 + common/cmd_pmic.c | 231 +++++++ common/cmd_regulator.c | 403 +++++++++++ configs/odroid_defconfig | 8 +- doc/device-tree-bindings/pmic/max77686.txt | 36 + doc/device-tree-bindings/regulator/fixed.txt | 38 ++ doc/device-tree-bindings/regulator/max77686.txt | 70 ++ doc/device-tree-bindings/regulator/regulator.txt | 55 ++ doc/driver-model/pmic-framework.txt | 142 ++++ drivers/power/Kconfig | 8 + drivers/power/Makefile | 1 - drivers/power/pmic/Kconfig | 18 + drivers/power/pmic/Makefile | 2 + drivers/power/pmic/max77686.c | 87 +++ drivers/power/pmic/pmic-uclass.c | 158 +++++ drivers/power/pmic/pmic_max77686.c | 2 +- drivers/power/regulator/Kconfig | 33 + drivers/power/regulator/Makefile | 10 + drivers/power/regulator/fixed.c | 126 ++++ drivers/power/regulator/max77686.c | 825 +++++++++++++++++++++++ drivers/power/regulator/regulator-uclass.c | 300 +++++++++ include/configs/exynos4-common.h | 1 - include/configs/exynos5-common.h | 4 + include/configs/odroid.h | 5 - include/dm/uclass-id.h | 4 + include/power/max77686_pmic.h | 29 +- include/power/pmic.h | 189 ++++++ include/power/regulator.h | 384 +++++++++++ lib/Kconfig | 8 + lib/fdtdec.c | 2 +- 39 files changed, 3512 insertions(+), 53 deletions(-)create mode 100644
common/cmd_pmic.c
create mode 100644common/cmd_regulator.c
create mode 100644doc/device-tree-bindings/pmic/max77686.txtcreate mode 100644doc/device-tree-bindings/regulator/fixed.txtcreate mode 100644doc/device-tree-bindings/regulator/max77686.txtcreate mode 100644doc/device-tree-bindings/regulator/regulator.txtcreate mode 100644doc/driver-model/pmic-framework.txtcreate mode 100644drivers/power/pmic/Kconfig
create mode 100644drivers/power/pmic/max77686.c
create mode 100644drivers/power/pmic/pmic-uclass.ccreate mode 100644drivers/power/regulator/Kconfigcreate mode 100644drivers/power/regulator/Makefilecreate mode 100644drivers/power/regulator/fixed.ccreate mode 100644drivers/power/regulator/max77686.ccreate mode 100644drivers/power/regulator/regulator-uclass.ccreate mode 100644include/power/regulator.hQuoted 3 lines
--
1.9.1I'm going to test this and apply to u-boot-dm/next while we wait for you to finish the sandbox test code. I've made a few comments on the series. They are minor so I don't want to do another whole spin of the series (it takes time to review!), but you could do a fix-up patch or two if you like. I could perhaps squash them in if you prefer that, but honestly they are nits.
Quoted 5 lines
It will be great to get this into mainline soon!
Regards,
Simon
Thank you again for the review. I know, that it takes a time, especially when things are fully reworked.
I have some other things to do now. So I think, that the end of the next week is reliable time to have the sandbox tests ready.
I will try to resend the fixes today or tomorrow.
One more question about the sandbox.
What do you think about adding: "drivers/power/pmic/max77686-sandbox.c"? The read/write could be done for the file as in the sandbox SPI driver. Then it's no problem to enable the max77686 regulator for the sandbox. This could probably work without dump the real device, when keep the set -> get I/O order.
Best regards,
Signature · 4 lines
Przemyslaw Marczak Samsung R&D Institute Poland Samsung Electronics p.marczak at samsung.com
v4 cover Power(full) framework based on Driver Model
Hi Przemyslaw,
Quoted 123 lines · Przemyslaw Marczak
Hello Simon,
Quoted 106 lines · Simon Glass
Hi Przemyslaw,
Quoted 90 lines · Przemyslaw Marczak
Hello,
Again the next version. The changes are described below each commit message.
This is rebased on last u-boot-dm/master after apply this patchset:
https://patchwork.ozlabs.org/patch/462775/
https://patchwork.ozlabs.org/patch/462777/
https://patchwork.ozlabs.org/patch/462776/This all can be found in here:
https://github.com/bobenstein/u-boot/tree/dm-pmic-v4Best regards,
Przemyslaw Marczak (16):
exynos5: fix build break by addingCONFIG_POWER
exynos4-common: remove the unsuedCONFIG_CMD_PMIC
lib:Kconfig: add entry forerrno_str()function
dm: pmic: add implementation of driver model pmic uclass
dm: regulator: add implementation of driver model regulator uclass
dm: pmic: add pmic command
dm: regulator: add regulator command
pmic: max77686 set the same compatible as in the kernel
dm: pmic: add max77686 pmic driver
dm: regulator: add max77686 regulator driver
dm: regulator: add fixed voltage regulator driver
doc: driver-model: pmic and regulator uclass documentation
dm: board:samsung:power_init_board: add requirement ofCONFIG_DM_PMIC
odroid: board: add support to dm pmic api
odroid: dts: add 'voltage-regulators' description to max77686 node
odroid: config: enable dm pmic, dm regulator and max77686 driverMakefile | 3 +- arch/arm/dts/exynos4412-odroid.dts | 255 ++++++- arch/arm/dts/exynos4412-trats2.dts | 2 +- arch/arm/dts/exynos5250-smdk5250.dts | 2 +- arch/arm/dts/exynos5250-snow.dts | 2 +- board/samsung/common/board.c | 4 +- board/samsung/common/misc.c | 1 + board/samsung/odroid/odroid.c | 77 ++- common/Kconfig | 36 + common/Makefile | 4 + common/cmd_pmic.c | 231 +++++++ common/cmd_regulator.c | 403 +++++++++++ configs/odroid_defconfig | 8 +- doc/device-tree-bindings/pmic/max77686.txt | 36 + doc/device-tree-bindings/regulator/fixed.txt | 38 ++ doc/device-tree-bindings/regulator/max77686.txt | 70 ++ doc/device-tree-bindings/regulator/regulator.txt | 55 ++ doc/driver-model/pmic-framework.txt | 142 ++++ drivers/power/Kconfig | 8 + drivers/power/Makefile | 1 - drivers/power/pmic/Kconfig | 18 + drivers/power/pmic/Makefile | 2 + drivers/power/pmic/max77686.c | 87 +++ drivers/power/pmic/pmic-uclass.c | 158 +++++ drivers/power/pmic/pmic_max77686.c | 2 +- drivers/power/regulator/Kconfig | 33 + drivers/power/regulator/Makefile | 10 + drivers/power/regulator/fixed.c | 126 ++++ drivers/power/regulator/max77686.c | 825 +++++++++++++++++++++++ drivers/power/regulator/regulator-uclass.c | 300 +++++++++ include/configs/exynos4-common.h | 1 - include/configs/exynos5-common.h | 4 + include/configs/odroid.h | 5 - include/dm/uclass-id.h | 4 + include/power/max77686_pmic.h | 29 +- include/power/pmic.h | 189 ++++++ include/power/regulator.h | 384 +++++++++++ lib/Kconfig | 8 + lib/fdtdec.c | 2 +- 39 files changed, 3512 insertions(+), 53 deletions(-)create mode 100644
common/cmd_pmic.c
create mode 100644common/cmd_regulator.c
create mode 100644doc/device-tree-bindings/pmic/max77686.txtcreate mode 100644doc/device-tree-bindings/regulator/fixed.txtcreate mode 100644doc/device-tree-bindings/regulator/max77686.txtcreate mode 100644doc/device-tree-bindings/regulator/regulator.txtcreate mode 100644doc/driver-model/pmic-framework.txtcreate mode 100644drivers/power/pmic/Kconfig
create mode 100644drivers/power/pmic/max77686.c
create mode 100644drivers/power/pmic/pmic-uclass.ccreate mode 100644drivers/power/regulator/Kconfigcreate mode 100644drivers/power/regulator/Makefilecreate mode 100644drivers/power/regulator/fixed.ccreate mode 100644drivers/power/regulator/max77686.ccreate mode 100644drivers/power/regulator/regulator-uclass.ccreate mode 100644include/power/regulator.hQuoted 3 lines
--
1.9.1I'm going to test this and apply to u-boot-dm/next while we wait for you to finish the sandbox test code. I've made a few comments on the series. They are minor so I don't want to do another whole spin of the series (it takes time to review!), but you could do a fix-up patch or two if you like. I could perhaps squash them in if you prefer that, but honestly they are nits.
Quoted 5 lines
It will be great to get this into mainline soon!
Regards,
SimonThank you again for the review. I know, that it takes a time, especially when things are fully reworked.
I have some other things to do now. So I think, that the end of the next week is reliable time to have the sandbox tests ready.I will try to resend the fixes today or tomorrow.
Quoted 7 lines
One more question about the sandbox.
What do you think about adding: "
drivers/power/pmic/max77686-sandbox.c"? The read/write could be done for the file as in the sandbox SPI driver. Then it's no problem to enable the max77686 regulator for the sandbox. This could probably work without dump the real device, when keep the set -> get I/O order.
I'd be more comfortable with a new pmic, a really simple 'fake' one with just a few LDOs, maybe one BUCK. Enough to support some reasonable tests.
The problem with max77686 is that is it quite complicated, and when writing and expanding tests, we really want things to be simple.
Also for the tests, we really don't need anything elaborate. Try to test the main functions.
Regards,
Simon
v4 cover Power(full) framework based on Driver Model
Hello Simon,
Quoted 138 lines · Simon Glass
Hi Przemyslaw,
Quoted 123 lines · Przemyslaw Marczak
Hello Simon,
Quoted 106 lines · Simon Glass
Hi Przemyslaw,
Quoted 90 lines · Przemyslaw Marczak
Hello,
Again the next version. The changes are described below each commit message.
This is rebased on last u-boot-dm/master after apply this patchset:
https://patchwork.ozlabs.org/patch/462775/
https://patchwork.ozlabs.org/patch/462777/
https://patchwork.ozlabs.org/patch/462776/This all can be found in here:
https://github.com/bobenstein/u-boot/tree/dm-pmic-v4Best regards,
Przemyslaw Marczak (16):
exynos5: fix build break by addingCONFIG_POWER
exynos4-common: remove the unsuedCONFIG_CMD_PMIC
lib:Kconfig: add entry forerrno_str()function
dm: pmic: add implementation of driver model pmic uclass
dm: regulator: add implementation of driver model regulator uclass
dm: pmic: add pmic command
dm: regulator: add regulator command
pmic: max77686 set the same compatible as in the kernel
dm: pmic: add max77686 pmic driver
dm: regulator: add max77686 regulator driver
dm: regulator: add fixed voltage regulator driver
doc: driver-model: pmic and regulator uclass documentation
dm: board:samsung:power_init_board: add requirement ofCONFIG_DM_PMIC
odroid: board: add support to dm pmic api
odroid: dts: add 'voltage-regulators' description to max77686 node
odroid: config: enable dm pmic, dm regulator and max77686 driverMakefile | 3 +- arch/arm/dts/exynos4412-odroid.dts | 255 ++++++- arch/arm/dts/exynos4412-trats2.dts | 2 +- arch/arm/dts/exynos5250-smdk5250.dts | 2 +- arch/arm/dts/exynos5250-snow.dts | 2 +- board/samsung/common/board.c | 4 +- board/samsung/common/misc.c | 1 + board/samsung/odroid/odroid.c | 77 ++- common/Kconfig | 36 + common/Makefile | 4 + common/cmd_pmic.c | 231 +++++++ common/cmd_regulator.c | 403 +++++++++++ configs/odroid_defconfig | 8 +- doc/device-tree-bindings/pmic/max77686.txt | 36 + doc/device-tree-bindings/regulator/fixed.txt | 38 ++ doc/device-tree-bindings/regulator/max77686.txt | 70 ++ doc/device-tree-bindings/regulator/regulator.txt | 55 ++ doc/driver-model/pmic-framework.txt | 142 ++++ drivers/power/Kconfig | 8 + drivers/power/Makefile | 1 - drivers/power/pmic/Kconfig | 18 + drivers/power/pmic/Makefile | 2 + drivers/power/pmic/max77686.c | 87 +++ drivers/power/pmic/pmic-uclass.c | 158 +++++ drivers/power/pmic/pmic_max77686.c | 2 +- drivers/power/regulator/Kconfig | 33 + drivers/power/regulator/Makefile | 10 + drivers/power/regulator/fixed.c | 126 ++++ drivers/power/regulator/max77686.c | 825 +++++++++++++++++++++++ drivers/power/regulator/regulator-uclass.c | 300 +++++++++ include/configs/exynos4-common.h | 1 - include/configs/exynos5-common.h | 4 + include/configs/odroid.h | 5 - include/dm/uclass-id.h | 4 + include/power/max77686_pmic.h | 29 +- include/power/pmic.h | 189 ++++++ include/power/regulator.h | 384 +++++++++++ lib/Kconfig | 8 + lib/fdtdec.c | 2 +- 39 files changed, 3512 insertions(+), 53 deletions(-)create mode 100644
common/cmd_pmic.c
create mode 100644common/cmd_regulator.c
create mode 100644doc/device-tree-bindings/pmic/max77686.txtcreate mode 100644doc/device-tree-bindings/regulator/fixed.txtcreate mode 100644doc/device-tree-bindings/regulator/max77686.txtcreate mode 100644doc/device-tree-bindings/regulator/regulator.txtcreate mode 100644doc/driver-model/pmic-framework.txtcreate mode 100644drivers/power/pmic/Kconfig
create mode 100644drivers/power/pmic/max77686.c
create mode 100644drivers/power/pmic/pmic-uclass.ccreate mode 100644drivers/power/regulator/Kconfigcreate mode 100644drivers/power/regulator/Makefilecreate mode 100644drivers/power/regulator/fixed.ccreate mode 100644drivers/power/regulator/max77686.ccreate mode 100644drivers/power/regulator/regulator-uclass.ccreate mode 100644include/power/regulator.hQuoted 3 lines
--
1.9.1I'm going to test this and apply to u-boot-dm/next while we wait for you to finish the sandbox test code. I've made a few comments on the series. They are minor so I don't want to do another whole spin of the series (it takes time to review!), but you could do a fix-up patch or two if you like. I could perhaps squash them in if you prefer that, but honestly they are nits.
Quoted 5 lines
It will be great to get this into mainline soon!
Regards,
SimonThank you again for the review. I know, that it takes a time, especially when things are fully reworked.
I have some other things to do now. So I think, that the end of the next week is reliable time to have the sandbox tests ready.I will try to resend the fixes today or tomorrow.
Quoted 7 lines
One more question about the sandbox.
What do you think about adding: "
drivers/power/pmic/max77686-sandbox.c"? The read/write could be done for the file as in the sandbox SPI driver. Then it's no problem to enable the max77686 regulator for the sandbox. This could probably work without dump the real device, when keep the set -> get I/O order.I'd be more comfortable with a new pmic, a really simple 'fake' one with just a few LDOs, maybe one BUCK. Enough to support some reasonable tests.
Quoted 9 lines
The problem with max77686 is that is it quite complicated, and when writing and expanding tests, we really want things to be simple.
Also for the tests, we really don't need anything elaborate. Try to test the main functions.
Regards,
Simon
Ok, I see. This should be easy.
Best regards,
Signature · 4 lines
Przemyslaw Marczak Samsung R&D Institute Poland Samsung Electronics p.marczak at samsung.com