diff options
Diffstat (limited to 'drivers/pinctrl/meson')
-rw-r--r-- | drivers/pinctrl/meson/pinctrl-amlogic-a4.c | 118 | ||||
-rw-r--r-- | drivers/pinctrl/meson/pinctrl-meson-g12a.c | 22 |
2 files changed, 113 insertions, 27 deletions
diff --git a/drivers/pinctrl/meson/pinctrl-amlogic-a4.c b/drivers/pinctrl/meson/pinctrl-amlogic-a4.c index 385cc619df13c..c8958222df8c7 100644 --- a/drivers/pinctrl/meson/pinctrl-amlogic-a4.c +++ b/drivers/pinctrl/meson/pinctrl-amlogic-a4.c @@ -50,15 +50,23 @@ struct aml_pio_control { u32 bit_offset[AML_NUM_REG]; }; -struct aml_reg_bit { - u32 bank_id; - u32 reg_offs[AML_NUM_REG]; - u32 bit_offs[AML_NUM_REG]; +/* + * partial bank(subordinate) pins mux config use other bank(main) mux registgers + * m_bank_id: the main bank which pin_id from 0, but register bit not from bit 0 + * m_bit_offs: bit offset the main bank mux register + * sid: start pin_id of subordinate bank + * eid: end pin_id of subordinate bank + */ +struct multi_mux { + unsigned int m_bank_id; + unsigned int m_bit_offs; + unsigned int sid; + unsigned int eid; }; struct aml_pctl_data { unsigned int number; - struct aml_reg_bit rb_offs[]; + const struct multi_mux *p_mux; }; struct aml_pmx_func { @@ -78,10 +86,12 @@ struct aml_gpio_bank { struct gpio_chip gpio_chip; struct aml_pio_control pc; u32 bank_id; + u32 mux_bit_offs; unsigned int pin_base; struct regmap *reg_mux; struct regmap *reg_gpio; struct regmap *reg_ds; + const struct multi_mux *p_mux; }; struct aml_pinctrl { @@ -113,13 +123,46 @@ static const char *aml_bank_name[31] = { "GPIOCC", "TEST_N", "ANALOG" }; +static const struct multi_mux multi_mux_s7[] = { + { + .m_bank_id = AMLOGIC_GPIO_CC, + .m_bit_offs = 24, + .sid = (AMLOGIC_GPIO_X << 8) + 16, + .eid = (AMLOGIC_GPIO_X << 8) + 19, + }, +}; + +static const struct aml_pctl_data s7_priv_data = { + .number = ARRAY_SIZE(multi_mux_s7), + .p_mux = multi_mux_s7, +}; + +static const struct multi_mux multi_mux_s6[] = { + { + .m_bank_id = AMLOGIC_GPIO_CC, + .m_bit_offs = 24, + .sid = (AMLOGIC_GPIO_X << 8) + 16, + .eid = (AMLOGIC_GPIO_X << 8) + 19, + }, { + .m_bank_id = AMLOGIC_GPIO_F, + .m_bit_offs = 4, + .sid = (AMLOGIC_GPIO_D << 8) + 6, + .eid = (AMLOGIC_GPIO_D << 8) + 6, + }, +}; + +static const struct aml_pctl_data s6_priv_data = { + .number = ARRAY_SIZE(multi_mux_s6), + .p_mux = multi_mux_s6, +}; + static int aml_pmx_calc_reg_and_offset(struct pinctrl_gpio_range *range, unsigned int pin, unsigned int *reg, unsigned int *offset) { unsigned int shift; - shift = (pin - range->pin_base) << 2; + shift = ((pin - range->pin_base) << 2) + *offset; *reg = (shift / 32) * 4; *offset = shift % 32; @@ -131,9 +174,36 @@ static int aml_pctl_set_function(struct aml_pinctrl *info, int pin_id, int func) { struct aml_gpio_bank *bank = gpio_chip_to_bank(range->gc); + unsigned int shift; int reg; - int offset; + int i; + unsigned int offset = bank->mux_bit_offs; + const struct multi_mux *p_mux; + + /* peculiar mux reg set */ + if (bank->p_mux) { + p_mux = bank->p_mux; + if (pin_id >= p_mux->sid && pin_id <= p_mux->eid) { + bank = NULL; + for (i = 0; i < info->nbanks; i++) { + if (info->banks[i].bank_id == p_mux->m_bank_id) { + bank = &info->banks[i]; + break; + } + } + if (!bank || !bank->reg_mux) + return -EINVAL; + + shift = (pin_id - p_mux->sid) << 2; + reg = (shift / 32) * 4; + offset = shift % 32; + return regmap_update_bits(bank->reg_mux, reg, + 0xf << offset, (func & 0xf) << offset); + } + } + + /* normal mux reg set */ if (!bank->reg_mux) return 0; @@ -830,29 +900,27 @@ static void init_bank_register_bit(struct aml_pinctrl *info, struct aml_gpio_bank *bank) { const struct aml_pctl_data *data = info->data; - const struct aml_reg_bit *aml_rb; - bool def_offs = true; + const struct multi_mux *p_mux; int i; + for (i = 0; i < AML_NUM_REG; i++) { + bank->pc.reg_offset[i] = aml_def_regoffs[i]; + bank->pc.bit_offset[i] = 0; + } + + bank->mux_bit_offs = 0; + if (data) { for (i = 0; i < data->number; i++) { - aml_rb = &data->rb_offs[i]; - if (bank->bank_id == aml_rb->bank_id) { - def_offs = false; + p_mux = &data->p_mux[i]; + if (bank->bank_id == p_mux->m_bank_id) { + bank->mux_bit_offs = p_mux->m_bit_offs; + break; + } + if (p_mux->sid >> 8 == bank->bank_id) { + bank->p_mux = p_mux; break; } - } - } - - if (def_offs) { - for (i = 0; i < AML_NUM_REG; i++) { - bank->pc.reg_offset[i] = aml_def_regoffs[i]; - bank->pc.bit_offset[i] = 0; - } - } else { - for (i = 0; i < AML_NUM_REG; i++) { - bank->pc.reg_offset[i] = aml_rb->reg_offs[i]; - bank->pc.bit_offset[i] = aml_rb->bit_offs[i]; } } } @@ -1021,6 +1089,8 @@ static int aml_pctl_probe(struct platform_device *pdev) static const struct of_device_id aml_pctl_of_match[] = { { .compatible = "amlogic,pinctrl-a4", }, + { .compatible = "amlogic,pinctrl-s7", .data = &s7_priv_data, }, + { .compatible = "amlogic,pinctrl-s6", .data = &s6_priv_data, }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, aml_pctl_dt_match); diff --git a/drivers/pinctrl/meson/pinctrl-meson-g12a.c b/drivers/pinctrl/meson/pinctrl-meson-g12a.c index e2788bfc5874e..8b9130c6e170b 100644 --- a/drivers/pinctrl/meson/pinctrl-meson-g12a.c +++ b/drivers/pinctrl/meson/pinctrl-meson-g12a.c @@ -270,15 +270,21 @@ static const unsigned int pwm_a_pins[] = { GPIOX_6 }; /* pwm_b */ static const unsigned int pwm_b_x7_pins[] = { GPIOX_7 }; static const unsigned int pwm_b_x19_pins[] = { GPIOX_19 }; +static const unsigned int pwm_b_z0_pins[] = { GPIOZ_0 }; +static const unsigned int pwm_b_z13_pins[] = { GPIOZ_13 }; +static const unsigned int pwm_b_h_pins[] = { GPIOH_7 }; /* pwm_c */ static const unsigned int pwm_c_c_pins[] = { GPIOC_4 }; static const unsigned int pwm_c_x5_pins[] = { GPIOX_5 }; static const unsigned int pwm_c_x8_pins[] = { GPIOX_8 }; +static const unsigned int pwm_c_z_pins[] = { GPIOZ_1 }; /* pwm_d */ static const unsigned int pwm_d_x3_pins[] = { GPIOX_3 }; static const unsigned int pwm_d_x6_pins[] = { GPIOX_6 }; +static const unsigned int pwm_d_z_pins[] = { GPIOZ_2 }; +static const unsigned int pwm_d_a_pins[] = { GPIOA_4 }; /* pwm_e */ static const unsigned int pwm_e_pins[] = { GPIOX_16 }; @@ -649,12 +655,22 @@ static const struct meson_pmx_group meson_g12a_periphs_groups[] = { GROUP(pwm_a, 1), GROUP(pwm_b_x7, 4), GROUP(pwm_b_x19, 1), + GROUP(pwm_b_z0, 5), + GROUP(pwm_b_z13, 5), + GROUP(pwm_b_h, 5), GROUP(pwm_c_x5, 4), GROUP(pwm_c_x8, 5), + GROUP(pwm_c_c, 5), + GROUP(pwm_c_z, 5), + GROUP(pwm_d_z, 4), + GROUP(pwm_d_a, 3), GROUP(pwm_d_x3, 4), GROUP(pwm_d_x6, 4), GROUP(pwm_e, 1), + GROUP(pwm_f_a, 3), + GROUP(pwm_f_h, 4), GROUP(pwm_f_x, 1), + GROUP(pwm_f_z, 5), GROUP(tsin_a_valid, 3), GROUP(tsin_a_sop, 3), GROUP(tsin_a_din0, 3), @@ -1058,15 +1074,15 @@ static const char * const pwm_a_groups[] = { }; static const char * const pwm_b_groups[] = { - "pwm_b_x7", "pwm_b_x19", + "pwm_b_h", "pwm_b_x7", "pwm_b_x19", "pwm_b_z0", "pwm_b_z13" }; static const char * const pwm_c_groups[] = { - "pwm_c_c", "pwm_c_x5", "pwm_c_x8", + "pwm_c_c", "pwm_c_x5", "pwm_c_x8", "pwm_c_z", }; static const char * const pwm_d_groups[] = { - "pwm_d_x3", "pwm_d_x6", + "pwm_d_a", "pwm_d_x3", "pwm_d_x6", "pwm_d_z", }; static const char * const pwm_e_groups[] = { |