diff options
Diffstat (limited to 'drivers/pinctrl/rockchip/pinctrl-rk322x.c')
-rw-r--r-- | drivers/pinctrl/rockchip/pinctrl-rk322x.c | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/drivers/pinctrl/rockchip/pinctrl-rk322x.c b/drivers/pinctrl/rockchip/pinctrl-rk322x.c index d67b48a06a..442c40ce0b 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rk322x.c +++ b/drivers/pinctrl/rockchip/pinctrl-rk322x.c @@ -141,6 +141,39 @@ static struct rockchip_mux_route_data rk3228_mux_route_data[] = { }, }; +static int rk3228_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) +{ + struct rockchip_pinctrl_priv *priv = bank->priv; + int iomux_num = (pin / 8); + struct regmap *regmap; + int reg, ret, mask, mux_type; + u8 bit; + u32 data, route_reg, route_val; + + regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU) + ? priv->regmap_pmu : priv->regmap_base; + + /* get basic quadrupel of mux registers and the correct reg inside */ + mux_type = bank->iomux[iomux_num].type; + reg = bank->iomux[iomux_num].offset; + reg += rockchip_get_mux_data(mux_type, pin, &bit, &mask); + + if (bank->route_mask & BIT(pin)) { + if (rockchip_get_mux_route(bank, pin, mux, &route_reg, + &route_val)) { + ret = regmap_write(regmap, route_reg, route_val); + if (ret) + return ret; + } + } + + data = (mask << (bit + 16)); + data |= (mux & mask) << bit; + ret = regmap_write(regmap, reg, data); + + return ret; +} + #define RK3228_PULL_OFFSET 0x100 static void rk3228_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, @@ -190,6 +223,7 @@ static struct rockchip_pin_ctrl rk3228_pin_ctrl = { .grf_mux_offset = 0x0, .iomux_routes = rk3228_mux_route_data, .niomux_routes = ARRAY_SIZE(rk3228_mux_route_data), + .set_mux = rk3228_set_mux, .pull_calc_reg = rk3228_calc_pull_reg_and_bit, .drv_calc_reg = rk3228_calc_drv_reg_and_bit, }; |