diff options
Diffstat (limited to 'drivers/i2c/sun8i_rsb.c')
-rw-r--r-- | drivers/i2c/sun8i_rsb.c | 61 |
1 files changed, 33 insertions, 28 deletions
diff --git a/drivers/i2c/sun8i_rsb.c b/drivers/i2c/sun8i_rsb.c index 716b245a00..47fa05b6d1 100644 --- a/drivers/i2c/sun8i_rsb.c +++ b/drivers/i2c/sun8i_rsb.c @@ -9,10 +9,12 @@ */ #include <axp_pmic.h> +#include <clk.h> #include <common.h> #include <dm.h> #include <errno.h> #include <i2c.h> +#include <reset.h> #include <time.h> #include <asm/arch/cpu.h> #include <asm/arch/gpio.h> @@ -95,27 +97,6 @@ static int sun8i_rsb_set_device_address(struct sunxi_rsb_reg *base, 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; @@ -147,12 +128,6 @@ static int sun8i_rsb_set_device_mode(struct sunxi_rsb_reg *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); @@ -185,6 +160,25 @@ int rsb_init(void) { struct sunxi_rsb_reg *base = (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); + + if (IS_ENABLED(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 { + 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); + } + return sun8i_rsb_init(base); } #endif @@ -243,20 +237,31 @@ static int sun8i_rsb_probe_chip(struct udevice *bus, uint chip_addr, static int sun8i_rsb_probe(struct udevice *bus) { struct sun8i_rsb_priv *priv = dev_get_priv(bus); + struct reset_ctl *reset; + struct clk *clk; priv->base = dev_read_addr_ptr(bus); + reset = devm_reset_control_get(bus, NULL); + if (!IS_ERR(reset)) + reset_deassert(reset); + + clk = devm_clk_get(bus, NULL); + if (!IS_ERR(clk)) + clk_enable(clk); + 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); + struct udevice *bus = child->parent; /* Ensure each transfer is for a single register. */ chip->flags |= DM_I2C_CHIP_RD_ADDRESS | DM_I2C_CHIP_WR_ADDRESS; - return 0; + return sun8i_rsb_probe_chip(bus, chip->chip_addr, 0); } static const struct dm_i2c_ops sun8i_rsb_ops = { |