diff options
-rw-r--r-- | drivers/pinctrl/sunxi/pinctrl-sunxi.c | 29 | ||||
-rw-r--r-- | drivers/pinctrl/sunxi/pinctrl-sunxi.h | 4 |
2 files changed, 25 insertions, 8 deletions
diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c index ae281a3c2ed3..83a031ceb29f 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c @@ -58,13 +58,29 @@ static struct irq_chip sunxi_pinctrl_level_irq_chip; * The following functions calculate the register and the bit offset to access. * They take a pin number which is relative to the start of the current device. */ + +/* + * When using the extended register layout, Bank K does not fit into the + * space used for the other banks. Instead it lives at offset 0x500. + */ +static u32 sunxi_bank_offset(const struct sunxi_pinctrl *pctl, u32 pin) +{ + u32 offset = 0; + + if (pin >= PK_BASE) { + pin -= PK_BASE; + offset = PIO_BANK_K_OFFSET; + } + + return offset + (pin / PINS_PER_BANK) * pctl->bank_mem_size; +} + static void sunxi_mux_reg(const struct sunxi_pinctrl *pctl, u32 pin, u32 *reg, u32 *shift, u32 *mask) { - u32 bank = pin / PINS_PER_BANK; u32 offset = pin % PINS_PER_BANK * MUX_FIELD_WIDTH; - *reg = bank * pctl->bank_mem_size + MUX_REGS_OFFSET + + *reg = sunxi_bank_offset(pctl, pin) + MUX_REGS_OFFSET + offset / BITS_PER_TYPE(u32) * sizeof(u32); *shift = offset % BITS_PER_TYPE(u32); *mask = (BIT(MUX_FIELD_WIDTH) - 1) << *shift; @@ -73,10 +89,9 @@ static void sunxi_mux_reg(const struct sunxi_pinctrl *pctl, static void sunxi_data_reg(const struct sunxi_pinctrl *pctl, u32 pin, u32 *reg, u32 *shift, u32 *mask) { - u32 bank = pin / PINS_PER_BANK; u32 offset = pin % PINS_PER_BANK * DATA_FIELD_WIDTH; - *reg = bank * pctl->bank_mem_size + DATA_REGS_OFFSET + + *reg = sunxi_bank_offset(pctl, pin) + DATA_REGS_OFFSET + offset / BITS_PER_TYPE(u32) * sizeof(u32); *shift = offset % BITS_PER_TYPE(u32); *mask = (BIT(DATA_FIELD_WIDTH) - 1) << *shift; @@ -85,10 +100,9 @@ static void sunxi_data_reg(const struct sunxi_pinctrl *pctl, static void sunxi_dlevel_reg(const struct sunxi_pinctrl *pctl, u32 pin, u32 *reg, u32 *shift, u32 *mask) { - u32 bank = pin / PINS_PER_BANK; u32 offset = pin % PINS_PER_BANK * pctl->dlevel_field_width; - *reg = bank * pctl->bank_mem_size + DLEVEL_REGS_OFFSET + + *reg = sunxi_bank_offset(pctl, pin) + DLEVEL_REGS_OFFSET + offset / BITS_PER_TYPE(u32) * sizeof(u32); *shift = offset % BITS_PER_TYPE(u32); *mask = (BIT(pctl->dlevel_field_width) - 1) << *shift; @@ -97,10 +111,9 @@ static void sunxi_dlevel_reg(const struct sunxi_pinctrl *pctl, static void sunxi_pull_reg(const struct sunxi_pinctrl *pctl, u32 pin, u32 *reg, u32 *shift, u32 *mask) { - u32 bank = pin / PINS_PER_BANK; u32 offset = pin % PINS_PER_BANK * PULL_FIELD_WIDTH; - *reg = bank * pctl->bank_mem_size + pctl->pull_regs_offset + + *reg = sunxi_bank_offset(pctl, pin) + pctl->pull_regs_offset + offset / BITS_PER_TYPE(u32) * sizeof(u32); *shift = offset % BITS_PER_TYPE(u32); *mask = (BIT(PULL_FIELD_WIDTH) - 1) << *shift; diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.h b/drivers/pinctrl/sunxi/pinctrl-sunxi.h index fbbf070a8754..6cf721876d89 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.h +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.h @@ -25,6 +25,8 @@ #define PG_BASE 192 #define PH_BASE 224 #define PI_BASE 256 +#define PJ_BASE 288 +#define PK_BASE 320 #define PL_BASE 352 #define PM_BASE 384 #define PN_BASE 416 @@ -89,6 +91,8 @@ #define PIO_POW_MOD_SEL_REG 0x340 #define PIO_POW_MOD_CTL_REG 0x344 +#define PIO_BANK_K_OFFSET 0x500 + enum sunxi_desc_bias_voltage { BIAS_VOLTAGE_NONE, /* |