summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/pinctrl/sunxi/pinctrl-sunxi.c29
-rw-r--r--drivers/pinctrl/sunxi/pinctrl-sunxi.h4
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,
/*