diff options
Diffstat (limited to 'drivers/pinctrl/rockchip/pinctrl-rk3328.c')
-rw-r--r-- | drivers/pinctrl/rockchip/pinctrl-rk3328.c | 125 |
1 files changed, 113 insertions, 12 deletions
diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3328.c b/drivers/pinctrl/rockchip/pinctrl-rk3328.c index f1b3d10dbe..8d37a6f945 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rk3328.c +++ b/drivers/pinctrl/rockchip/pinctrl-rk3328.c @@ -121,6 +121,42 @@ static struct rockchip_mux_route_data rk3328_mux_route_data[] = { }, }; +static int rk3328_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->recalced_mask & BIT(pin)) + rockchip_get_recalced_mux(bank, 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 RK3328_PULL_OFFSET 0x100 static void rk3328_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, @@ -138,6 +174,33 @@ static void rk3328_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, *bit *= ROCKCHIP_PULL_BITS_PER_PIN; } +static int rk3328_set_pull(struct rockchip_pin_bank *bank, + int pin_num, int pull) +{ + struct regmap *regmap; + int reg, ret; + u8 bit, type; + u32 data; + + if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT) + return -ENOTSUPP; + + rk3328_calc_pull_reg_and_bit(bank, pin_num, ®map, ®, &bit); + type = bank->pull_type[pin_num / 8]; + ret = rockchip_translate_pull_value(type, pull); + if (ret < 0) { + debug("unsupported pull setting %d\n", pull); + return ret; + } + + /* enable the write to the equivalent lower bits */ + data = ((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << (bit + 16); + data |= (ret << bit); + ret = regmap_write(regmap, reg, data); + + return ret; +} + #define RK3328_DRV_GRF_OFFSET 0x200 static void rk3328_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, @@ -155,6 +218,30 @@ static void rk3328_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, *bit *= ROCKCHIP_DRV_BITS_PER_PIN; } +static int rk3328_set_drive(struct rockchip_pin_bank *bank, + int pin_num, int strength) +{ + struct regmap *regmap; + int reg, ret; + u32 data; + u8 bit; + int type = bank->drv[pin_num / 8].drv_type; + + rk3328_calc_drv_reg_and_bit(bank, pin_num, ®map, ®, &bit); + ret = rockchip_translate_drive_value(type, strength); + if (ret < 0) { + debug("unsupported driver strength %d\n", strength); + return ret; + } + + /* enable the write to the equivalent lower bits */ + data = ((1 << ROCKCHIP_DRV_BITS_PER_PIN) - 1) << (bit + 16); + data |= (ret << bit); + ret = regmap_write(regmap, reg, data); + + return ret; +} + #define RK3328_SCHMITT_BITS_PER_PIN 1 #define RK3328_SCHMITT_PINS_PER_REG 16 #define RK3328_SCHMITT_BANK_STRIDE 8 @@ -177,6 +264,21 @@ static int rk3328_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, return 0; } +static int rk3328_set_schmitt(struct rockchip_pin_bank *bank, + int pin_num, int enable) +{ + struct regmap *regmap; + int reg; + u8 bit; + u32 data; + + rk3328_calc_schmitt_reg_and_bit(bank, pin_num, ®map, ®, &bit); + /* enable the write to the equivalent lower bits */ + data = BIT(bit + 16) | (enable << bit); + + return regmap_write(regmap, reg, data); +} + static struct rockchip_pin_bank rk3328_pin_banks[] = { PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", 0, 0, 0, 0), PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", 0, 0, 0, 0), @@ -192,18 +294,17 @@ static struct rockchip_pin_bank rk3328_pin_banks[] = { }; static struct rockchip_pin_ctrl rk3328_pin_ctrl = { - .pin_banks = rk3328_pin_banks, - .nr_banks = ARRAY_SIZE(rk3328_pin_banks), - .label = "RK3328-GPIO", - .type = RK3288, - .grf_mux_offset = 0x0, - .iomux_recalced = rk3328_mux_recalced_data, - .niomux_recalced = ARRAY_SIZE(rk3328_mux_recalced_data), - .iomux_routes = rk3328_mux_route_data, - .niomux_routes = ARRAY_SIZE(rk3328_mux_route_data), - .pull_calc_reg = rk3328_calc_pull_reg_and_bit, - .drv_calc_reg = rk3328_calc_drv_reg_and_bit, - .schmitt_calc_reg = rk3328_calc_schmitt_reg_and_bit, + .pin_banks = rk3328_pin_banks, + .nr_banks = ARRAY_SIZE(rk3328_pin_banks), + .grf_mux_offset = 0x0, + .iomux_recalced = rk3328_mux_recalced_data, + .niomux_recalced = ARRAY_SIZE(rk3328_mux_recalced_data), + .iomux_routes = rk3328_mux_route_data, + .niomux_routes = ARRAY_SIZE(rk3328_mux_route_data), + .set_mux = rk3328_set_mux, + .set_pull = rk3328_set_pull, + .set_drive = rk3328_set_drive, + .set_schmitt = rk3328_set_schmitt, }; static const struct udevice_id rk3328_pinctrl_ids[] = { |