diff options
-rw-r--r-- | arch/arm/mach-sunxi/Kconfig | 18 | ||||
-rw-r--r-- | arch/arm/mach-sunxi/Makefile | 1 | ||||
-rw-r--r-- | arch/arm/mach-sunxi/pmic_bus.c | 11 | ||||
-rw-r--r-- | arch/arm/mach-sunxi/rsb.c | 175 | ||||
-rw-r--r-- | configs/Cubieboard4_defconfig | 2 | ||||
-rw-r--r-- | configs/Merrii_A80_Optimus_defconfig | 2 | ||||
-rw-r--r-- | drivers/i2c/Kconfig | 8 | ||||
-rw-r--r-- | drivers/i2c/Makefile | 1 | ||||
-rw-r--r-- | drivers/i2c/sun8i_rsb.c | 281 | ||||
-rw-r--r-- | include/axp_pmic.h | 6 |
10 files changed, 309 insertions, 196 deletions
diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig index f4a4528..10401d3 100644 --- a/arch/arm/mach-sunxi/Kconfig +++ b/arch/arm/mach-sunxi/Kconfig @@ -100,14 +100,6 @@ config AXP_PMIC_BUS Select this PMIC bus access helpers for Sunxi platform PRCM or other AXP family PMIC devices. -config SUN8I_RSB - bool "Allwinner sunXi Reduced Serial Bus Driver" - help - Say y here to enable support for Allwinner's Reduced Serial Bus - (RSB) support. This controller is responsible for communicating - with various RSB based devices, such as AXP223, AXP8XX PMICs, - and AC100/AC200 ICs. - config SUNXI_SRAM_ADDRESS hex default 0x10000 if MACH_SUN9I || MACH_SUN50I || MACH_SUN50I_H5 @@ -250,9 +242,10 @@ config MACH_SUN8I_A23 select ARCH_SUPPORT_PSCI select DRAM_SUN8I_A23 select PHY_SUN4I_USB - select SUN8I_RSB + select SPL_I2C select SUNXI_GEN_SUN6I select SUPPORT_SPL + select SYS_I2C_SUN8I_RSB select ARMV7_BOOT_SEC_DEFAULT if OLD_SUNXI_KERNEL_COMPAT imply CONS_INDEX_5 if !DM_SERIAL @@ -264,9 +257,10 @@ config MACH_SUN8I_A33 select ARCH_SUPPORT_PSCI select DRAM_SUN8I_A33 select PHY_SUN4I_USB - select SUN8I_RSB + select SPL_I2C select SUNXI_GEN_SUN6I select SUPPORT_SPL + select SYS_I2C_SUN8I_RSB select ARMV7_BOOT_SEC_DEFAULT if OLD_SUNXI_KERNEL_COMPAT imply CONS_INDEX_5 if !DM_SERIAL @@ -275,11 +269,12 @@ config MACH_SUN8I_A83T select CPU_V7A select DRAM_SUN8I_A83T select PHY_SUN4I_USB - select SUN8I_RSB + select SPL_I2C select SUNXI_GEN_SUN6I select MMC_SUNXI_HAS_NEW_MODE select MMC_SUNXI_HAS_MODE_SWITCH select SUPPORT_SPL + select SYS_I2C_SUN8I_RSB config MACH_SUN8I_H3 bool "sun8i (Allwinner H3)" @@ -320,6 +315,7 @@ config MACH_SUN9I bool "sun9i (Allwinner A80)" select CPU_V7A select DRAM_SUN9I + select SPL_I2C select SUN6I_PRCM select SUNXI_GEN_SUN6I select SUPPORT_SPL diff --git a/arch/arm/mach-sunxi/Makefile b/arch/arm/mach-sunxi/Makefile index c9312bb..5d3fd70 100644 --- a/arch/arm/mach-sunxi/Makefile +++ b/arch/arm/mach-sunxi/Makefile @@ -13,7 +13,6 @@ obj-y += dram_helpers.o obj-y += pinmux.o obj-$(CONFIG_SUN6I_PRCM) += prcm.o obj-$(CONFIG_AXP_PMIC_BUS) += pmic_bus.o -obj-$(CONFIG_SUN8I_RSB) += rsb.o obj-$(CONFIG_MACH_SUN4I) += clock_sun4i.o obj-$(CONFIG_MACH_SUN5I) += clock_sun4i.o obj-$(CONFIG_MACH_SUN6I) += clock_sun6i.o diff --git a/arch/arm/mach-sunxi/pmic_bus.c b/arch/arm/mach-sunxi/pmic_bus.c index 673a05f..8277972 100644 --- a/arch/arm/mach-sunxi/pmic_bus.c +++ b/arch/arm/mach-sunxi/pmic_bus.c @@ -23,10 +23,6 @@ #define AXP221_CHIP_ADDR 0x68 -/* AXP818 device and runtime addresses are same as AXP223 */ -#define AXP223_DEVICE_ADDR 0x3a3 -#define AXP223_RUNTIME_ADDR 0x2d - int pmic_bus_init(void) { /* This cannot be 0 because it is used in SPL before BSS is ready */ @@ -49,7 +45,8 @@ int pmic_bus_init(void) if (ret) return ret; - ret = rsb_set_device_address(AXP223_DEVICE_ADDR, AXP223_RUNTIME_ADDR); + ret = rsb_set_device_address(AXP_PMIC_PRI_DEVICE_ADDR, + AXP_PMIC_PRI_RUNTIME_ADDR); # endif if (ret) return ret; @@ -73,7 +70,7 @@ int pmic_bus_read(u8 reg, u8 *data) # elif defined CONFIG_MACH_SUN8I_R40 return i2c_read(AXP209_I2C_ADDR, reg, 1, data, 1); # else - return rsb_read(AXP223_RUNTIME_ADDR, reg, data); + return rsb_read(AXP_PMIC_PRI_RUNTIME_ADDR, reg, data); # endif #endif } @@ -92,7 +89,7 @@ int pmic_bus_write(u8 reg, u8 data) # elif defined CONFIG_MACH_SUN8I_R40 return i2c_write(AXP209_I2C_ADDR, reg, 1, &data, 1); # else - return rsb_write(AXP223_RUNTIME_ADDR, reg, data); + return rsb_write(AXP_PMIC_PRI_RUNTIME_ADDR, reg, data); # endif #endif } diff --git a/arch/arm/mach-sunxi/rsb.c b/arch/arm/mach-sunxi/rsb.c deleted file mode 100644 index 01bb09b..0000000 --- a/arch/arm/mach-sunxi/rsb.c +++ /dev/null @@ -1,175 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * (C) Copyright 2014 Hans de Goede <hdegoede@redhat.com> - * - * Based on allwinner u-boot sources rsb code which is: - * (C) Copyright 2007-2013 - * Allwinner Technology Co., Ltd. <www.allwinnertech.com> - * lixiang <lixiang@allwinnertech.com> - */ - -#include <common.h> -#include <errno.h> -#include <time.h> -#include <asm/arch/cpu.h> -#include <asm/arch/gpio.h> -#include <asm/arch/prcm.h> -#include <asm/arch/rsb.h> - -static int rsb_set_device_mode(void); - -static void rsb_cfg_io(void) -{ -#ifdef CONFIG_MACH_SUN8I - sunxi_gpio_set_cfgpin(SUNXI_GPL(0), SUN8I_GPL_R_RSB); - sunxi_gpio_set_cfgpin(SUNXI_GPL(1), SUN8I_GPL_R_RSB); - sunxi_gpio_set_pull(SUNXI_GPL(0), 1); - sunxi_gpio_set_pull(SUNXI_GPL(1), 1); - sunxi_gpio_set_drv(SUNXI_GPL(0), 2); - sunxi_gpio_set_drv(SUNXI_GPL(1), 2); -#elif defined CONFIG_MACH_SUN9I - sunxi_gpio_set_cfgpin(SUNXI_GPN(0), SUN9I_GPN_R_RSB); - sunxi_gpio_set_cfgpin(SUNXI_GPN(1), SUN9I_GPN_R_RSB); - sunxi_gpio_set_pull(SUNXI_GPN(0), 1); - sunxi_gpio_set_pull(SUNXI_GPN(1), 1); - sunxi_gpio_set_drv(SUNXI_GPN(0), 2); - sunxi_gpio_set_drv(SUNXI_GPN(1), 2); -#else -#error unsupported MACH_SUNXI -#endif -} - -static void rsb_set_clk(void) -{ - struct sunxi_rsb_reg * const rsb = - (struct sunxi_rsb_reg *)SUNXI_RSB_BASE; - u32 div = 0; - u32 cd_odly = 0; - - /* Source is Hosc24M, set RSB clk to 3Mhz */ - div = 24000000 / 3000000 / 2 - 1; - cd_odly = div >> 1; - if (!cd_odly) - cd_odly = 1; - - writel((cd_odly << 8) | div, &rsb->ccr); -} - -int rsb_init(void) -{ - struct sunxi_rsb_reg * const rsb = - (struct sunxi_rsb_reg *)SUNXI_RSB_BASE; - - /* Enable RSB and PIO clk, and de-assert their resets */ - prcm_apb0_enable(PRCM_APB0_GATE_PIO | PRCM_APB0_GATE_RSB); - - /* Setup external pins */ - rsb_cfg_io(); - - writel(RSB_CTRL_SOFT_RST, &rsb->ctrl); - rsb_set_clk(); - - return rsb_set_device_mode(); -} - -static int rsb_await_trans(void) -{ - struct sunxi_rsb_reg * const rsb = - (struct sunxi_rsb_reg *)SUNXI_RSB_BASE; - unsigned long tmo = timer_get_us() + 1000000; - u32 stat; - int ret; - - while (1) { - stat = readl(&rsb->stat); - if (stat & RSB_STAT_LBSY_INT) { - ret = -EBUSY; - break; - } - if (stat & RSB_STAT_TERR_INT) { - ret = -EIO; - break; - } - if (stat & RSB_STAT_TOVER_INT) { - ret = 0; - break; - } - if (timer_get_us() > tmo) { - ret = -ETIME; - break; - } - } - writel(stat, &rsb->stat); /* Clear status bits */ - - return ret; -} - -static int rsb_set_device_mode(void) -{ - struct sunxi_rsb_reg * const rsb = - (struct sunxi_rsb_reg *)SUNXI_RSB_BASE; - unsigned long tmo = timer_get_us() + 1000000; - - writel(RSB_DMCR_DEVICE_MODE_START | RSB_DMCR_DEVICE_MODE_DATA, - &rsb->dmcr); - - while (readl(&rsb->dmcr) & RSB_DMCR_DEVICE_MODE_START) { - if (timer_get_us() > tmo) - return -ETIME; - } - - return rsb_await_trans(); -} - -static int rsb_do_trans(void) -{ - struct sunxi_rsb_reg * const rsb = - (struct sunxi_rsb_reg *)SUNXI_RSB_BASE; - - setbits_le32(&rsb->ctrl, RSB_CTRL_START_TRANS); - return rsb_await_trans(); -} - -int rsb_set_device_address(u16 device_addr, u16 runtime_addr) -{ - struct sunxi_rsb_reg * const rsb = - (struct sunxi_rsb_reg *)SUNXI_RSB_BASE; - - writel(RSB_DEVADDR_RUNTIME_ADDR(runtime_addr) | - RSB_DEVADDR_DEVICE_ADDR(device_addr), &rsb->devaddr); - writel(RSB_CMD_SET_RTSADDR, &rsb->cmd); - - return rsb_do_trans(); -} - -int rsb_write(const u16 runtime_device_addr, const u8 reg_addr, u8 data) -{ - struct sunxi_rsb_reg * const rsb = - (struct sunxi_rsb_reg *)SUNXI_RSB_BASE; - - writel(RSB_DEVADDR_RUNTIME_ADDR(runtime_device_addr), &rsb->devaddr); - writel(reg_addr, &rsb->addr); - writel(data, &rsb->data); - writel(RSB_CMD_BYTE_WRITE, &rsb->cmd); - - return rsb_do_trans(); -} - -int rsb_read(const u16 runtime_device_addr, const u8 reg_addr, u8 *data) -{ - struct sunxi_rsb_reg * const rsb = - (struct sunxi_rsb_reg *)SUNXI_RSB_BASE; - int ret; - - writel(RSB_DEVADDR_RUNTIME_ADDR(runtime_device_addr), &rsb->devaddr); - writel(reg_addr, &rsb->addr); - writel(RSB_CMD_BYTE_READ, &rsb->cmd); - - ret = rsb_do_trans(); - if (ret) - return ret; - - *data = readl(&rsb->data) & 0xff; - - return 0; -} diff --git a/configs/Cubieboard4_defconfig b/configs/Cubieboard4_defconfig index 0377bb8..3848cab 100644 --- a/configs/Cubieboard4_defconfig +++ b/configs/Cubieboard4_defconfig @@ -11,6 +11,6 @@ CONFIG_USB0_VBUS_DET="AXP0-VBUS-DETECT" CONFIG_USB0_ID_DET="PH16" CONFIG_USB1_VBUS_PIN="PH14" CONFIG_USB3_VBUS_PIN="PH15" -CONFIG_SUN8I_RSB=y +CONFIG_SYS_I2C_SUN8I_RSB=y CONFIG_AXP_GPIO=y CONFIG_AXP809_POWER=y diff --git a/configs/Merrii_A80_Optimus_defconfig b/configs/Merrii_A80_Optimus_defconfig index 8fb6504..35e5753 100644 --- a/configs/Merrii_A80_Optimus_defconfig +++ b/configs/Merrii_A80_Optimus_defconfig @@ -11,6 +11,6 @@ CONFIG_USB0_VBUS_DET="AXP0-VBUS-DETECT" CONFIG_USB0_ID_DET="PH3" CONFIG_USB1_VBUS_PIN="PH4" CONFIG_USB3_VBUS_PIN="PH5" -CONFIG_SUN8I_RSB=y +CONFIG_SYS_I2C_SUN8I_RSB=y CONFIG_AXP_GPIO=y CONFIG_AXP809_POWER=y diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig index 0adf143..66bd6fe 100644 --- a/drivers/i2c/Kconfig +++ b/drivers/i2c/Kconfig @@ -583,6 +583,14 @@ config SYS_I2C_SUN6I_P2WI in the Allwinner A31 and A31s SOCs. This interface is used to connect to specific devices like the X-Powers AXP221 PMIC. +config SYS_I2C_SUN8I_RSB + bool "Allwinner sun8i Reduced Serial Bus controller" + depends on ARCH_SUNXI + help + Support for Allwinner's Reduced Serial Bus (RSB) controller. This + controller is responsible for communicating with various RSB based + devices, such as X-Powers AXPxxx PMICs and AC100/AC200 CODEC ICs. + config SYS_I2C_SYNQUACER bool "Socionext SynQuacer I2C controller" depends on ARCH_SYNQUACER && DM_I2C diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile index 0a2cc64..9164274 100644 --- a/drivers/i2c/Makefile +++ b/drivers/i2c/Makefile @@ -44,6 +44,7 @@ obj-$(CONFIG_SYS_I2C_SH) += sh_i2c.o obj-$(CONFIG_SYS_I2C_SOFT) += soft_i2c.o obj-$(CONFIG_SYS_I2C_STM32F7) += stm32f7_i2c.o obj-$(CONFIG_SYS_I2C_SUN6I_P2WI) += sun6i_p2wi.o +obj-$(CONFIG_SYS_I2C_SUN8I_RSB) += sun8i_rsb.o obj-$(CONFIG_SYS_I2C_SYNQUACER) += synquacer_i2c.o obj-$(CONFIG_SYS_I2C_TEGRA) += tegra_i2c.o obj-$(CONFIG_SYS_I2C_UNIPHIER) += i2c-uniphier.o diff --git a/drivers/i2c/sun8i_rsb.c b/drivers/i2c/sun8i_rsb.c new file mode 100644 index 0000000..716b245 --- /dev/null +++ b/drivers/i2c/sun8i_rsb.c @@ -0,0 +1,281 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2014 Hans de Goede <hdegoede@redhat.com> + * + * Based on allwinner u-boot sources rsb code which is: + * (C) Copyright 2007-2013 + * Allwinner Technology Co., Ltd. <www.allwinnertech.com> + * lixiang <lixiang@allwinnertech.com> + */ + +#include <axp_pmic.h> +#include <common.h> +#include <dm.h> +#include <errno.h> +#include <i2c.h> +#include <time.h> +#include <asm/arch/cpu.h> +#include <asm/arch/gpio.h> +#include <asm/arch/prcm.h> +#include <asm/arch/rsb.h> + +static int sun8i_rsb_await_trans(struct sunxi_rsb_reg *base) +{ + unsigned long tmo = timer_get_us() + 1000000; + u32 stat; + int ret; + + while (1) { + stat = readl(&base->stat); + if (stat & RSB_STAT_LBSY_INT) { + ret = -EBUSY; + break; + } + if (stat & RSB_STAT_TERR_INT) { + ret = -EIO; + break; + } + if (stat & RSB_STAT_TOVER_INT) { + ret = 0; + break; + } + if (timer_get_us() > tmo) { + ret = -ETIME; + break; + } + } + writel(stat, &base->stat); /* Clear status bits */ + + return ret; +} + +static int sun8i_rsb_do_trans(struct sunxi_rsb_reg *base) +{ + setbits_le32(&base->ctrl, RSB_CTRL_START_TRANS); + + return sun8i_rsb_await_trans(base); +} + +static int sun8i_rsb_read(struct sunxi_rsb_reg *base, u16 runtime_addr, + u8 reg_addr, u8 *data) +{ + int ret; + + writel(RSB_DEVADDR_RUNTIME_ADDR(runtime_addr), &base->devaddr); + writel(reg_addr, &base->addr); + writel(RSB_CMD_BYTE_READ, &base->cmd); + + ret = sun8i_rsb_do_trans(base); + if (ret) + return ret; + + *data = readl(&base->data) & 0xff; + + return 0; +} + +static int sun8i_rsb_write(struct sunxi_rsb_reg *base, u16 runtime_addr, + u8 reg_addr, u8 data) +{ + writel(RSB_DEVADDR_RUNTIME_ADDR(runtime_addr), &base->devaddr); + writel(reg_addr, &base->addr); + writel(data, &base->data); + writel(RSB_CMD_BYTE_WRITE, &base->cmd); + + return sun8i_rsb_do_trans(base); +} + +static int sun8i_rsb_set_device_address(struct sunxi_rsb_reg *base, + u16 device_addr, u16 runtime_addr) +{ + writel(RSB_DEVADDR_RUNTIME_ADDR(runtime_addr) | + RSB_DEVADDR_DEVICE_ADDR(device_addr), &base->devaddr); + writel(RSB_CMD_SET_RTSADDR, &base->cmd); + + return sun8i_rsb_do_trans(base); +} + +static void sun8i_rsb_cfg_io(void) +{ +#ifdef CONFIG_MACH_SUN8I + sunxi_gpio_set_cfgpin(SUNXI_GPL(0), SUN8I_GPL_R_RSB); + sunxi_gpio_set_cfgpin(SUNXI_GPL(1), SUN8I_GPL_R_RSB); + sunxi_gpio_set_pull(SUNXI_GPL(0), 1); + sunxi_gpio_set_pull(SUNXI_GPL(1), 1); + sunxi_gpio_set_drv(SUNXI_GPL(0), 2); + sunxi_gpio_set_drv(SUNXI_GPL(1), 2); +#elif defined CONFIG_MACH_SUN9I + sunxi_gpio_set_cfgpin(SUNXI_GPN(0), SUN9I_GPN_R_RSB); + sunxi_gpio_set_cfgpin(SUNXI_GPN(1), SUN9I_GPN_R_RSB); + sunxi_gpio_set_pull(SUNXI_GPN(0), 1); + sunxi_gpio_set_pull(SUNXI_GPN(1), 1); + sunxi_gpio_set_drv(SUNXI_GPN(0), 2); + sunxi_gpio_set_drv(SUNXI_GPN(1), 2); +#else +#error unsupported MACH_SUNXI +#endif +} + +static void sun8i_rsb_set_clk(struct sunxi_rsb_reg *base) +{ + u32 div = 0; + u32 cd_odly = 0; + + /* Source is Hosc24M, set RSB clk to 3Mhz */ + div = 24000000 / 3000000 / 2 - 1; + cd_odly = div >> 1; + if (!cd_odly) + cd_odly = 1; + + writel((cd_odly << 8) | div, &base->ccr); +} + +static int sun8i_rsb_set_device_mode(struct sunxi_rsb_reg *base) +{ + unsigned long tmo = timer_get_us() + 1000000; + + writel(RSB_DMCR_DEVICE_MODE_START | RSB_DMCR_DEVICE_MODE_DATA, + &base->dmcr); + + while (readl(&base->dmcr) & RSB_DMCR_DEVICE_MODE_START) { + if (timer_get_us() > tmo) + return -ETIME; + } + + return sun8i_rsb_await_trans(base); +} + +static int sun8i_rsb_init(struct sunxi_rsb_reg *base) +{ + /* Enable RSB and PIO clk, and de-assert their resets */ + prcm_apb0_enable(PRCM_APB0_GATE_PIO | PRCM_APB0_GATE_RSB); + + /* Setup external pins */ + sun8i_rsb_cfg_io(); + + writel(RSB_CTRL_SOFT_RST, &base->ctrl); + sun8i_rsb_set_clk(base); + + return sun8i_rsb_set_device_mode(base); +} + +#if IS_ENABLED(CONFIG_AXP_PMIC_BUS) +int rsb_read(const u16 runtime_addr, const u8 reg_addr, u8 *data) +{ + struct sunxi_rsb_reg *base = (struct sunxi_rsb_reg *)SUNXI_RSB_BASE; + + return sun8i_rsb_read(base, runtime_addr, reg_addr, data); +} + +int rsb_write(const u16 runtime_addr, const u8 reg_addr, u8 data) +{ + struct sunxi_rsb_reg *base = (struct sunxi_rsb_reg *)SUNXI_RSB_BASE; + + return sun8i_rsb_write(base, runtime_addr, reg_addr, data); +} + +int rsb_set_device_address(u16 device_addr, u16 runtime_addr) +{ + struct sunxi_rsb_reg *base = (struct sunxi_rsb_reg *)SUNXI_RSB_BASE; + + return sun8i_rsb_set_device_address(base, device_addr, runtime_addr); +} + +int rsb_init(void) +{ + struct sunxi_rsb_reg *base = (struct sunxi_rsb_reg *)SUNXI_RSB_BASE; + + return sun8i_rsb_init(base); +} +#endif + +#if CONFIG_IS_ENABLED(DM_I2C) +struct sun8i_rsb_priv { + struct sunxi_rsb_reg *base; +}; + +/* + * The mapping from hardware address to runtime address is fixed, and shared + * among all RSB drivers. See the comment in drivers/bus/sunxi-rsb.c in Linux. + */ +static int sun8i_rsb_get_runtime_address(u16 device_addr) +{ + if (device_addr == AXP_PMIC_PRI_DEVICE_ADDR) + return AXP_PMIC_PRI_RUNTIME_ADDR; + if (device_addr == AXP_PMIC_SEC_DEVICE_ADDR) + return AXP_PMIC_SEC_RUNTIME_ADDR; + + return -ENXIO; +} + +static int sun8i_rsb_xfer(struct udevice *bus, struct i2c_msg *msg, int nmsgs) +{ + int runtime_addr = sun8i_rsb_get_runtime_address(msg->addr); + struct sun8i_rsb_priv *priv = dev_get_priv(bus); + + if (runtime_addr < 0) + return runtime_addr; + + /* The hardware only supports SMBus-style transfers. */ + if (nmsgs == 2 && msg[1].flags == I2C_M_RD && msg[1].len == 1) + return sun8i_rsb_read(priv->base, runtime_addr, + msg[0].buf[0], &msg[1].buf[0]); + + if (nmsgs == 1 && msg[0].len == 2) + return sun8i_rsb_write(priv->base, runtime_addr, + msg[0].buf[0], msg[0].buf[1]); + + return -EINVAL; +} + +static int sun8i_rsb_probe_chip(struct udevice *bus, uint chip_addr, + uint chip_flags) +{ + int runtime_addr = sun8i_rsb_get_runtime_address(chip_addr); + struct sun8i_rsb_priv *priv = dev_get_priv(bus); + + if (runtime_addr < 0) + return runtime_addr; + + return sun8i_rsb_set_device_address(priv->base, chip_addr, runtime_addr); +} + +static int sun8i_rsb_probe(struct udevice *bus) +{ + struct sun8i_rsb_priv *priv = dev_get_priv(bus); + + priv->base = dev_read_addr_ptr(bus); + + return sun8i_rsb_init(priv->base); +} + +static int sun8i_rsb_child_pre_probe(struct udevice *child) +{ + struct dm_i2c_chip *chip = dev_get_parent_plat(child); + + /* Ensure each transfer is for a single register. */ + chip->flags |= DM_I2C_CHIP_RD_ADDRESS | DM_I2C_CHIP_WR_ADDRESS; + + return 0; +} + +static const struct dm_i2c_ops sun8i_rsb_ops = { + .xfer = sun8i_rsb_xfer, + .probe_chip = sun8i_rsb_probe_chip, +}; + +static const struct udevice_id sun8i_rsb_ids[] = { + { .compatible = "allwinner,sun8i-a23-rsb" }, + { /* sentinel */ } +}; + +U_BOOT_DRIVER(sun8i_rsb) = { + .name = "sun8i_rsb", + .id = UCLASS_I2C, + .of_match = sun8i_rsb_ids, + .probe = sun8i_rsb_probe, + .child_pre_probe = sun8i_rsb_child_pre_probe, + .priv_auto = sizeof(struct sun8i_rsb_priv), + .ops = &sun8i_rsb_ops, +}; +#endif /* CONFIG_IS_ENABLED(DM_I2C) */ diff --git a/include/axp_pmic.h b/include/axp_pmic.h index 0db3e14..46a017d 100644 --- a/include/axp_pmic.h +++ b/include/axp_pmic.h @@ -30,6 +30,12 @@ #define AXP_PMIC_MODE_REG 0x3e #define AXP_PMIC_MODE_I2C 0x00 #define AXP_PMIC_MODE_P2WI 0x3e +#define AXP_PMIC_MODE_RSB 0x7c + +#define AXP_PMIC_PRI_DEVICE_ADDR 0x3a3 +#define AXP_PMIC_PRI_RUNTIME_ADDR 0x2d +#define AXP_PMIC_SEC_DEVICE_ADDR 0x745 +#define AXP_PMIC_SEC_RUNTIME_ADDR 0x3a int axp_set_dcdc1(unsigned int mvolt); int axp_set_dcdc2(unsigned int mvolt); |