On Tue, 2017-07-11 at 21:30 -0600, Simon Glass wrote: > Convert this PMIC driver to driver model and fix up other users. The > regulator and GPIO functions are now handled by separate drivers. > > Update nyan-big to work correct. Three boards will need to be updated > by > the maintainers: apalis-tk1, jetson-tk1, cei-tk1-som > > Signed-off-by: Simon Glass <s...@chromium.org> > Reviewed-by: Lukasz Majewski <lu...@denx.de> > --- > > Changes in v4: None > Changes in v3: None > Changes in v2: None > > arch/arm/mach-tegra/board2.c | 6 - > board/cei/cei-tk1-som/cei-tk1-som.c | 2 + > board/nvidia/jetson-tk1/jetson-tk1.c | 2 + > board/nvidia/nyan-big/nyan-big.c | 22 +-- > board/toradex/apalis-tk1/apalis-tk1.c | 6 + > configs/apalis-tk1_defconfig | 3 + > configs/cei-tk1-som_defconfig | 3 + > configs/jetson-tk1_defconfig | 3 + > configs/nyan-big_defconfig | 1 + > drivers/power/pmic/Makefile | 2 +- > drivers/power/pmic/as3722.c | 292 ++++++++++++---------- > ------------ > include/power/as3722.h | 18 +-- > 12 files changed, 133 insertions(+), 227 deletions(-) > > diff --git a/arch/arm/mach-tegra/board2.c b/arch/arm/mach- > tegra/board2.c > index 181dc30a6b..bd137969f0 100644 > --- a/arch/arm/mach-tegra/board2.c > +++ b/arch/arm/mach-tegra/board2.c > @@ -29,7 +29,6 @@ > #ifdef CONFIG_TEGRA_CLOCK_SCALING > #include <asm/arch/emc.h> > #endif > -#include <power/as3722.h> > #include "emc.h" > > DECLARE_GLOBAL_DATA_PTR; > @@ -142,11 +141,6 @@ int board_init(void) > debug("Memory controller init failed: %d\n", err); > # endif > # endif /* CONFIG_TEGRA_PMU */ > -#ifdef CONFIG_PMIC_AS3722 > - err = as3722_init(NULL); > - if (err && err != -ENODEV) > - return err; > -#endif > #endif /* CONFIG_SYS_I2C_TEGRA */ > > #ifdef CONFIG_USB_EHCI_TEGRA > diff --git a/board/cei/cei-tk1-som/cei-tk1-som.c b/board/cei/cei-tk1- > som/cei-tk1-som.c > index 9ba7490c38..7c87bd1eb1 100644 > --- a/board/cei/cei-tk1-som/cei-tk1-som.c > +++ b/board/cei/cei-tk1-som/cei-tk1-som.c > @@ -39,6 +39,7 @@ void pinmux_init(void) > #ifdef CONFIG_PCI_TEGRA > int tegra_pcie_board_init(void) > { > +/* TODO: Convert to driver model > struct udevice *pmic; > int err; > > @@ -59,6 +60,7 @@ int tegra_pcie_board_init(void) > error("failed to set SD4 voltage: %d\n", err); > return err; > } > +*/ > > return 0; > } > diff --git a/board/nvidia/jetson-tk1/jetson-tk1.c > b/board/nvidia/jetson-tk1/jetson-tk1.c > index a66b710cdd..48272d086c 100644 > --- a/board/nvidia/jetson-tk1/jetson-tk1.c > +++ b/board/nvidia/jetson-tk1/jetson-tk1.c > @@ -39,6 +39,7 @@ void pinmux_init(void) > #ifdef CONFIG_PCI_TEGRA > int tegra_pcie_board_init(void) > { > +/* TODO: Convert to driver model
Is that still applicable or how was that one solved at the end? > struct udevice *pmic; > int err; > > @@ -59,6 +60,7 @@ int tegra_pcie_board_init(void) > error("failed to set SD4 voltage: %d\n", err); > return err; > } > +*/ > > return 0; > } > diff --git a/board/nvidia/nyan-big/nyan-big.c b/board/nvidia/nyan- > big/nyan-big.c > index 8f68ae9fbe..54acf5418d 100644 > --- a/board/nvidia/nyan-big/nyan-big.c > +++ b/board/nvidia/nyan-big/nyan-big.c > @@ -6,6 +6,7 @@ > */ > > #include <common.h> > +#include <dm.h> > #include <errno.h> > #include <asm/gpio.h> > #include <asm/io.h> > @@ -46,20 +47,23 @@ int tegra_board_id(void) > > int tegra_lcd_pmic_init(int board_id) > { > - struct udevice *pmic; > + struct udevice *dev; > int ret; > > - ret = as3722_get(&pmic); > - if (ret) > - return -ENOENT; > + ret = uclass_get_device_by_driver(UCLASS_PMIC, > + DM_GET_DRIVER(pmic_as3722) > , &dev); > + if (ret) { > + debug("%s: Failed to find PMIC\n", __func__); > + return ret; > + } > > if (board_id == 0) > - as3722_write(pmic, 0x00, 0x3c); > + pmic_reg_write(dev, 0x00, 0x3c); > else > - as3722_write(pmic, 0x00, 0x50); > - as3722_write(pmic, 0x12, 0x10); > - as3722_write(pmic, 0x0c, 0x07); > - as3722_write(pmic, 0x20, 0x10); > + pmic_reg_write(dev, 0x00, 0x50); > + pmic_reg_write(dev, 0x12, 0x10); > + pmic_reg_write(dev, 0x0c, 0x07); > + pmic_reg_write(dev, 0x20, 0x10); > > return 0; > } > diff --git a/board/toradex/apalis-tk1/apalis-tk1.c > b/board/toradex/apalis-tk1/apalis-tk1.c > index c7e519c19b..5de61e7c2b 100644 > --- a/board/toradex/apalis-tk1/apalis-tk1.c > +++ b/board/toradex/apalis-tk1/apalis-tk1.c > @@ -61,6 +61,7 @@ void pinmux_init(void) > #ifdef CONFIG_PCI_TEGRA > int tegra_pcie_board_init(void) > { > + /* TODO: Convert to driver model > struct udevice *pmic; > int err; > > @@ -94,6 +95,7 @@ int tegra_pcie_board_init(void) > error("failed to set GPIO#2 high: %d\n", err); > return err; > } > + */ > > /* Reset I210 Gigabit Ethernet Controller */ > gpio_request(LAN_RESET_N, "LAN_RESET_N"); > @@ -110,6 +112,7 @@ int tegra_pcie_board_init(void) > gpio_direction_output(TEGRA_GPIO(O, 6), 0); > > /* Make sure LDO9 and LDO10 are initially enabled @ 0V */ > + /* TODO: Convert to driver model > err = as3722_ldo_enable(pmic, 9); > if (err < 0) { > error("failed to enable LDO9: %d\n", err); > @@ -130,6 +133,7 @@ int tegra_pcie_board_init(void) > error("failed to set LDO10 voltage: %d\n", err); > return err; > } > + */ > > mdelay(100); > > @@ -137,6 +141,7 @@ int tegra_pcie_board_init(void) > gpio_set_value(TEGRA_GPIO(O, 6), 1); > > /* Enable LDO9 and LDO10 for +V3.3_ETH on patched prototypes > */ > + /* TODO: Convert to driver model > err = as3722_ldo_set_voltage(pmic, 9, 0xff); > if (err < 0) { > error("failed to set LDO9 voltage: %d\n", err); > @@ -147,6 +152,7 @@ int tegra_pcie_board_init(void) > error("failed to set LDO10 voltage: %d\n", err); > return err; > } > + */ > > mdelay(100); > gpio_set_value(LAN_RESET_N, 1); > diff --git a/configs/apalis-tk1_defconfig b/configs/apalis- > tk1_defconfig > index 9179aaf92f..ccff112392 100644 > --- a/configs/apalis-tk1_defconfig > +++ b/configs/apalis-tk1_defconfig > @@ -32,7 +32,10 @@ CONFIG_PCI=y > CONFIG_DM_PCI=y > CONFIG_DM_PCI_COMPAT=y > CONFIG_PCI_TEGRA=y > +CONFIG_DM_PMIC=y > CONFIG_PMIC_AS3722=y > +CONFIG_DM_REGULATOR=y > +CONFIG_REGULATOR_AS3722=y > CONFIG_SYS_NS16550=y > CONFIG_USB=y > CONFIG_DM_USB=y > diff --git a/configs/cei-tk1-som_defconfig b/configs/cei-tk1- > som_defconfig > index 1a5e47dba5..5623bbfbc6 100644 > --- a/configs/cei-tk1-som_defconfig > +++ b/configs/cei-tk1-som_defconfig > @@ -36,7 +36,10 @@ CONFIG_PCI=y > CONFIG_DM_PCI=y > CONFIG_DM_PCI_COMPAT=y > CONFIG_PCI_TEGRA=y > +CONFIG_DM_PMIC=y > CONFIG_PMIC_AS3722=y > +CONFIG_DM_REGULATOR=y > +CONFIG_REGULATOR_AS3722=y > CONFIG_SYS_NS16550=y > CONFIG_TEGRA114_SPI=y > CONFIG_USB=y > diff --git a/configs/jetson-tk1_defconfig b/configs/jetson- > tk1_defconfig > index 65a5832e44..d086951299 100644 > --- a/configs/jetson-tk1_defconfig > +++ b/configs/jetson-tk1_defconfig > @@ -36,7 +36,10 @@ CONFIG_PCI=y > CONFIG_DM_PCI=y > CONFIG_DM_PCI_COMPAT=y > CONFIG_PCI_TEGRA=y > +CONFIG_DM_PMIC=y > CONFIG_PMIC_AS3722=y > +CONFIG_DM_REGULATOR=y > +CONFIG_REGULATOR_AS3722=y > CONFIG_SYS_NS16550=y > CONFIG_TEGRA114_SPI=y > CONFIG_USB=y > diff --git a/configs/nyan-big_defconfig b/configs/nyan-big_defconfig > index cb3b0a85cf..8e11c2f15c 100644 > --- a/configs/nyan-big_defconfig > +++ b/configs/nyan-big_defconfig > @@ -49,6 +49,7 @@ CONFIG_SPI_FLASH_WINBOND=y > CONFIG_DM_PMIC=y > CONFIG_PMIC_AS3722=y > CONFIG_DM_REGULATOR=y > +CONFIG_REGULATOR_AS3722=y > CONFIG_DM_REGULATOR_FIXED=y > CONFIG_PWM_TEGRA=y > CONFIG_DEBUG_UART=y > diff --git a/drivers/power/pmic/Makefile > b/drivers/power/pmic/Makefile > index f488799a92..f7bdfa5609 100644 > --- a/drivers/power/pmic/Makefile > +++ b/drivers/power/pmic/Makefile > @@ -12,7 +12,7 @@ obj-$(CONFIG_DM_PMIC_PFUZE100) += pfuze100.o > obj-$(CONFIG_PMIC_S2MPS11) += s2mps11.o > obj-$(CONFIG_DM_PMIC_SANDBOX) += sandbox.o i2c_pmic_emul.o > obj-$(CONFIG_PMIC_ACT8846) += act8846.o > -obj-$(CONFIG_PMIC_AS3722) += as3722.o > +obj-$(CONFIG_PMIC_AS3722) += as3722.o as3722_gpio.o > obj-$(CONFIG_PMIC_MAX8997) += max8997.o > obj-$(CONFIG_PMIC_PM8916) += pm8916.o > obj-$(CONFIG_PMIC_RK8XX) += rk8xx.o > diff --git a/drivers/power/pmic/as3722.c > b/drivers/power/pmic/as3722.c > index c09e1de06f..4efe8ee183 100644 > --- a/drivers/power/pmic/as3722.c > +++ b/drivers/power/pmic/as3722.c > @@ -11,264 +11,168 @@ > #include <errno.h> > #include <fdtdec.h> > #include <i2c.h> > - > +#include <dm/lists.h> > #include <power/as3722.h> > +#include <power/pmic.h> > > -#define AS3722_SD_VOLTAGE(n) (0x00 + (n)) > -#define AS3722_GPIO_CONTROL(n) (0x08 + (n)) > -#define AS3722_GPIO_CONTROL_MODE_OUTPUT_VDDH (1 << 0) > -#define AS3722_GPIO_CONTROL_MODE_OUTPUT_VDDL (7 << 0) > -#define AS3722_GPIO_CONTROL_INVERT (1 << 7) > -#define AS3722_LDO_VOLTAGE(n) (0x10 + (n)) > -#define AS3722_GPIO_SIGNAL_OUT 0x20 > -#define AS3722_SD_CONTROL 0x4d > -#define AS3722_LDO_CONTROL 0x4e > -#define AS3722_ASIC_ID1 0x90 > -#define AS3722_DEVICE_ID 0x0c > -#define AS3722_ASIC_ID2 0x91 > - > -int as3722_read(struct udevice *pmic, u8 reg, u8 *value) > -{ > - int err; > - > - err = dm_i2c_read(pmic, reg, value, 1); > - if (err < 0) > - return err; > - > - return 0; > -} > +#define AS3722_NUM_OF_REGS 0x92 > > -int as3722_write(struct udevice *pmic, u8 reg, u8 value) > +static int as3722_read(struct udevice *dev, uint reg, uint8_t *buff, > int len) > { > - int err; > + int ret; > > - err = dm_i2c_write(pmic, reg, &value, 1); > - if (err < 0) > - return err; > + ret = dm_i2c_read(dev, reg, buff, len); > + if (ret < 0) > + return ret; > > return 0; > } > > -static int as3722_read_id(struct udevice *pmic, u8 *id, u8 > *revision) > +static int as3722_write(struct udevice *dev, uint reg, const uint8_t > *buff, > + int len) > { > - int err; > + int ret; > > - err = as3722_read(pmic, AS3722_ASIC_ID1, id); > - if (err) { > - error("failed to read ID1 register: %d", err); > - return err; > - } > - > - err = as3722_read(pmic, AS3722_ASIC_ID2, revision); > - if (err) { > - error("failed to read ID2 register: %d", err); > - return err; > - } > + ret = dm_i2c_write(dev, reg, buff, len); > + if (ret < 0) > + return ret; > > return 0; > } > > -int as3722_sd_enable(struct udevice *pmic, unsigned int sd) > +static int as3722_read_id(struct udevice *dev, uint *idp, uint > *revisionp) > { > - u8 value; > - int err; > - > - if (sd > 6) > - return -EINVAL; > + int ret; > > - err = as3722_read(pmic, AS3722_SD_CONTROL, &value); > - if (err) { > - error("failed to read SD control register: %d", > err); > - return err; > + ret = pmic_reg_read(dev, AS3722_ASIC_ID1); > + if (ret < 0) { > + error("failed to read ID1 register: %d", ret); > + return ret; > } > + *idp = ret; > > - value |= 1 << sd; > - > - err = as3722_write(pmic, AS3722_SD_CONTROL, value); > - if (err < 0) { > - error("failed to write SD control register: %d", > err); > - return err; > + ret = pmic_reg_read(dev, AS3722_ASIC_ID2); > + if (ret < 0) { > + error("failed to read ID2 register: %d", ret); > + return ret; > } > + *revisionp = ret; > > return 0; > } > > -int as3722_sd_set_voltage(struct udevice *pmic, unsigned int sd, u8 > value) > +/* TODO(tred...@nvidia.com): Add proper regulator support to avoid > this */ > +int as3722_sd_set_voltage(struct udevice *dev, unsigned int sd, u8 > value) > { > - int err; > + int ret; > > if (sd > 6) > return -EINVAL; > > - err = as3722_write(pmic, AS3722_SD_VOLTAGE(sd), value); > - if (err < 0) { > - error("failed to write SD%u voltage register: %d", > sd, err); > - return err; > + ret = pmic_reg_write(dev, AS3722_SD_VOLTAGE(sd), value); > + if (ret < 0) { > + error("failed to write SD%u voltage register: %d", > sd, ret); > + return ret; > } > > return 0; > } > > -int as3722_ldo_enable(struct udevice *pmic, unsigned int ldo) > +int as3722_ldo_set_voltage(struct udevice *dev, unsigned int ldo, u8 > value) > { > - u8 value; > - int err; > + int ret; > > if (ldo > 11) > return -EINVAL; > > - err = as3722_read(pmic, AS3722_LDO_CONTROL, &value); > - if (err) { > - error("failed to read LDO control register: %d", > err); > - return err; > - } > - > - value |= 1 << ldo; > - > - err = as3722_write(pmic, AS3722_LDO_CONTROL, value); > - if (err < 0) { > - error("failed to write LDO control register: %d", > err); > - return err; > - } > - > - return 0; > -} > - > -int as3722_ldo_set_voltage(struct udevice *pmic, unsigned int ldo, > u8 value) > -{ > - int err; > - > - if (ldo > 11) > - return -EINVAL; > - > - err = as3722_write(pmic, AS3722_LDO_VOLTAGE(ldo), value); > - if (err < 0) { > + ret = pmic_reg_write(dev, AS3722_LDO_VOLTAGE(ldo), value); > + if (ret < 0) { > error("failed to write LDO%u voltage register: %d", > ldo, > - err); > - return err; > + ret); > + return ret; > } > > return 0; > } > > -int as3722_gpio_configure(struct udevice *pmic, unsigned int gpio, > - unsigned long flags) > +static int as3722_probe(struct udevice *dev) > { > - u8 value = 0; > - int err; > + uint id, revision; > + int ret; > > - if (flags & AS3722_GPIO_OUTPUT_VDDH) > - value |= AS3722_GPIO_CONTROL_MODE_OUTPUT_VDDH; > - > - if (flags & AS3722_GPIO_INVERT) > - value |= AS3722_GPIO_CONTROL_INVERT; > - > - err = as3722_write(pmic, AS3722_GPIO_CONTROL(gpio), value); > - if (err) { > - error("failed to configure GPIO#%u: %d", gpio, err); > - return err; > + ret = as3722_read_id(dev, &id, &revision); > + if (ret < 0) { > + error("failed to read ID: %d", ret); > + return ret; > } > > - return 0; > -} > - > -static int as3722_gpio_set(struct udevice *pmic, unsigned int gpio, > - unsigned int level) > -{ > - const char *l; > - u8 value; > - int err; > - > - if (gpio > 7) > - return -EINVAL; > - > - err = as3722_read(pmic, AS3722_GPIO_SIGNAL_OUT, &value); > - if (err < 0) { > - error("failed to read GPIO signal out register: %d", > err); > - return err; > - } > - > - if (level == 0) { > - value &= ~(1 << gpio); > - l = "low"; > - } else { > - value |= 1 << gpio; > - l = "high"; > + if (id != AS3722_DEVICE_ID) { > + error("unknown device"); > + return -ENOENT; > } > > - err = as3722_write(pmic, AS3722_GPIO_SIGNAL_OUT, value); > - if (err) { > - error("failed to set GPIO#%u %s: %d", gpio, l, err); > - return err; > - } > + debug("AS3722 revision %#x found on I2C bus %s\n", revision, > dev->name); > > return 0; > } > > -int as3722_gpio_direction_output(struct udevice *pmic, unsigned int > gpio, > - unsigned int level) > -{ > - u8 value; > - int err; > - > - if (gpio > 7) > - return -EINVAL; > +#if CONFIG_IS_ENABLED(PMIC_CHILDREN) > +static const struct pmic_child_info pmic_children_info[] = { > + { .prefix = "sd", .driver = "as3722_stepdown"}, > + { .prefix = "ldo", .driver = "as3722_ldo"}, > + { }, > +}; > > - if (level == 0) > - value = AS3722_GPIO_CONTROL_MODE_OUTPUT_VDDL; > - else > - value = AS3722_GPIO_CONTROL_MODE_OUTPUT_VDDH; > +static int as3722_bind(struct udevice *dev) > +{ > + struct udevice *gpio_dev; > + ofnode regulators_node; > + int children; > + int ret; > > - err = as3722_write(pmic, AS3722_GPIO_CONTROL(gpio), value); > - if (err) { > - error("failed to configure GPIO#%u as output: %d", > gpio, err); > - return err; > + regulators_node = dev_read_subnode(dev, "regulators"); > + if (!ofnode_valid(regulators_node)) { > + debug("%s: %s regulators subnode not found\n", > __func__, > + dev->name); > + return -ENXIO; > } > > - err = as3722_gpio_set(pmic, gpio, level); > - if (err < 0) { > - error("failed to set GPIO#%u high: %d", gpio, err); > - return err; > + children = pmic_bind_children(dev, regulators_node, > pmic_children_info); > + if (!children) > + debug("%s: %s - no child found\n", __func__, dev- > >name); > + ret = device_bind_driver(dev, "gpio_as3722", "gpio_as3722", > &gpio_dev); > + if (ret) { > + debug("%s: Cannot bind GPIOs (ret=%d)\n", __func__, > ret); > + return ret; > } > > return 0; > } > +#endif > > -/* Temporary function until we get the pmic framework */ > -int as3722_get(struct udevice **devp) > +static int as3722_reg_count(struct udevice *dev) > { > - int bus = 0; > - int address = 0x40; > - > - return i2c_get_chip_for_busnum(bus, address, 1, devp); > + return AS3722_NUM_OF_REGS; > } > > -int as3722_init(struct udevice **devp) > -{ > - struct udevice *pmic; > - u8 id, revision; > - const unsigned int bus = 0; > - const unsigned int address = 0x40; > - int err; > - > - err = i2c_get_chip_for_busnum(bus, address, 1, &pmic); > - if (err) > - return err; > - err = as3722_read_id(pmic, &id, &revision); > - if (err < 0) { > - error("failed to read ID: %d", err); > - return err; > - } > - > - if (id != AS3722_DEVICE_ID) { > - error("unknown device"); > - return -ENOENT; > - } > - > - debug("AS3722 revision %#x found on I2C bus %u, address > %#x\n", > - revision, bus, address); > - if (devp) > - *devp = pmic; > - > - return 0; > -} > +static struct dm_pmic_ops as3722_ops = { > + .reg_count = as3722_reg_count, > + .read = as3722_read, > + .write = as3722_write, > +}; > + > +static const struct udevice_id as3722_ids[] = { > + { .compatible = "ams,as3722" }, > + { } > +}; > + > +U_BOOT_DRIVER(pmic_as3722) = { > + .name = "as3722_pmic", > + .id = UCLASS_PMIC, > + .of_match = as3722_ids, > +#if CONFIG_IS_ENABLED(PMIC_CHILDREN) > + .bind = as3722_bind, > +#endif > + .probe = as3722_probe, > + .ops = &as3722_ops, > +}; > diff --git a/include/power/as3722.h b/include/power/as3722.h > index 713e79840f..491f1b7ea7 100644 > --- a/include/power/as3722.h > +++ b/include/power/as3722.h > @@ -7,8 +7,6 @@ > #ifndef __POWER_AS3722_H__ > #define __POWER_AS3722_H__ > > -#include <asm/types.h> > - > #define AS3722_GPIO_OUTPUT_VDDH (1 << 0) > #define AS3722_GPIO_INVERT (1 << 1) > > @@ -21,23 +19,9 @@ > #define AS3722_ASIC_ID2 0x91 > > #define AS3722_GPIO_CONTROL(n) (0x08 + (n)) > +#define AS3722_GPIO_SIGNAL_OUT 0x20 > #define AS3722_GPIO_CONTROL_MODE_OUTPUT_VDDH (1 << 0) > #define AS3722_GPIO_CONTROL_MODE_OUTPUT_VDDL (7 << 0) > #define AS3722_GPIO_CONTROL_INVERT (1 << 7) > > -struct udevice; > - > -int as3722_init(struct udevice **devp); > -int as3722_sd_enable(struct udevice *pmic, unsigned int sd); > -int as3722_sd_set_voltage(struct udevice *pmic, unsigned int sd, u8 > value); > -int as3722_ldo_enable(struct udevice *pmic, unsigned int ldo); > -int as3722_ldo_set_voltage(struct udevice *pmic, unsigned int ldo, > u8 value); > -int as3722_gpio_configure(struct udevice *pmic, unsigned int gpio, > - unsigned long flags); > -int as3722_gpio_direction_output(struct udevice *pmic, unsigned int > gpio, > - unsigned int level); > -int as3722_read(struct udevice *pmic, u8 reg, u8 *value); > -int as3722_write(struct udevice *pmic, u8 reg, u8 value); > -int as3722_get(struct udevice **devp); > - > #endif /* __POWER_AS3722_H__ */ _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot