^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * Allwinner A1X SoCs pinctrl driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2012 Maxime Ripard
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Maxime Ripard <maxime.ripard@free-electrons.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * This file is licensed under the terms of the GNU General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * License version 2. This program is licensed "as is" without any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * warranty of any kind, whether express or implied.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #ifndef __PINCTRL_SUNXI_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #define __PINCTRL_SUNXI_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define PA_BASE 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define PB_BASE 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define PC_BASE 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define PD_BASE 96
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define PE_BASE 128
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define PF_BASE 160
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define PG_BASE 192
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define PH_BASE 224
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define PI_BASE 256
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define PL_BASE 352
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define PM_BASE 384
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define PN_BASE 416
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define SUNXI_PINCTRL_PIN(bank, pin) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) PINCTRL_PIN(P ## bank ## _BASE + (pin), "P" #bank #pin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define SUNXI_PIN_NAME_MAX_LEN 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define BANK_MEM_SIZE 0x24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define MUX_REGS_OFFSET 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define DATA_REGS_OFFSET 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define DLEVEL_REGS_OFFSET 0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define PULL_REGS_OFFSET 0x1c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define PINS_PER_BANK 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define MUX_PINS_PER_REG 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define MUX_PINS_BITS 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define MUX_PINS_MASK 0x0f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define DATA_PINS_PER_REG 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define DATA_PINS_BITS 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define DATA_PINS_MASK 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define DLEVEL_PINS_PER_REG 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define DLEVEL_PINS_BITS 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define DLEVEL_PINS_MASK 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define PULL_PINS_PER_REG 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define PULL_PINS_BITS 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define PULL_PINS_MASK 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define IRQ_PER_BANK 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define IRQ_CFG_REG 0x200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define IRQ_CFG_IRQ_PER_REG 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define IRQ_CFG_IRQ_BITS 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define IRQ_CFG_IRQ_MASK ((1 << IRQ_CFG_IRQ_BITS) - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define IRQ_CTRL_REG 0x210
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define IRQ_CTRL_IRQ_PER_REG 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define IRQ_CTRL_IRQ_BITS 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define IRQ_CTRL_IRQ_MASK ((1 << IRQ_CTRL_IRQ_BITS) - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define IRQ_STATUS_REG 0x214
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define IRQ_STATUS_IRQ_PER_REG 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define IRQ_STATUS_IRQ_BITS 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define IRQ_STATUS_IRQ_MASK ((1 << IRQ_STATUS_IRQ_BITS) - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define IRQ_DEBOUNCE_REG 0x218
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define IRQ_MEM_SIZE 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define IRQ_EDGE_RISING 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define IRQ_EDGE_FALLING 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define IRQ_LEVEL_HIGH 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define IRQ_LEVEL_LOW 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define IRQ_EDGE_BOTH 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define GRP_CFG_REG 0x300
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define IO_BIAS_MASK GENMASK(3, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define SUN4I_FUNC_INPUT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define SUN4I_FUNC_IRQ 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define PINCTRL_SUN5I_A10S BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define PINCTRL_SUN5I_A13 BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define PINCTRL_SUN5I_GR8 BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define PINCTRL_SUN6I_A31 BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define PINCTRL_SUN6I_A31S BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define PINCTRL_SUN4I_A10 BIT(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define PINCTRL_SUN7I_A20 BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define PINCTRL_SUN8I_R40 BIT(8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #define PINCTRL_SUN8I_V3 BIT(9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #define PINCTRL_SUN8I_V3S BIT(10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #define PIO_POW_MOD_SEL_REG 0x340
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) enum sunxi_desc_bias_voltage {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) BIAS_VOLTAGE_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * Bias voltage configuration is done through
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * Pn_GRP_CONFIG registers, as seen on A80 SoC.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) BIAS_VOLTAGE_GRP_CONFIG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) * Bias voltage is set through PIO_POW_MOD_SEL_REG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) * register, as seen on H6 SoC, for example.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) BIAS_VOLTAGE_PIO_POW_MODE_SEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) struct sunxi_desc_function {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) unsigned long variant;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) u8 muxval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) u8 irqbank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) u8 irqnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) struct sunxi_desc_pin {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) struct pinctrl_pin_desc pin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) unsigned long variant;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) struct sunxi_desc_function *functions;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) struct sunxi_pinctrl_desc {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) const struct sunxi_desc_pin *pins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) int npins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) unsigned pin_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) unsigned irq_banks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) const unsigned int *irq_bank_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) bool irq_read_needs_mux;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) bool disable_strict_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) enum sunxi_desc_bias_voltage io_bias_cfg_variant;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) struct sunxi_pinctrl_function {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) const char **groups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) unsigned ngroups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) struct sunxi_pinctrl_group {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) unsigned pin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) struct sunxi_pinctrl_regulator {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) struct regulator *regulator;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) refcount_t refcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) struct sunxi_pinctrl {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) void __iomem *membase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) struct gpio_chip *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) const struct sunxi_pinctrl_desc *desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) struct sunxi_pinctrl_regulator regulators[9];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) struct irq_domain *domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) struct sunxi_pinctrl_function *functions;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) unsigned nfunctions;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) struct sunxi_pinctrl_group *groups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) unsigned ngroups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) int *irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) unsigned *irq_array;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) raw_spinlock_t lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) struct pinctrl_dev *pctl_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) unsigned long variant;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) #define SUNXI_PIN(_pin, ...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) .pin = _pin, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) .functions = (struct sunxi_desc_function[]){ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) __VA_ARGS__, { } }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) #define SUNXI_PIN_VARIANT(_pin, _variant, ...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) .pin = _pin, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) .variant = _variant, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) .functions = (struct sunxi_desc_function[]){ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) __VA_ARGS__, { } }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) #define SUNXI_FUNCTION(_val, _name) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) .name = _name, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) .muxval = _val, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) #define SUNXI_FUNCTION_VARIANT(_val, _name, _variant) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) .name = _name, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) .muxval = _val, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) .variant = _variant, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) #define SUNXI_FUNCTION_IRQ(_val, _irq) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) .name = "irq", \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) .muxval = _val, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) .irqnum = _irq, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) #define SUNXI_FUNCTION_IRQ_BANK(_val, _bank, _irq) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) .name = "irq", \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) .muxval = _val, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) .irqbank = _bank, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) .irqnum = _irq, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) * The sunXi PIO registers are organized as is:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) * 0x00 - 0x0c Muxing values.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) * 8 pins per register, each pin having a 4bits value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) * 0x10 Pin values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) * 32 bits per register, each pin corresponding to one bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) * 0x14 - 0x18 Drive level
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) * 16 pins per register, each pin having a 2bits value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) * 0x1c - 0x20 Pull-Up values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) * 16 pins per register, each pin having a 2bits value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) * This is for the first bank. Each bank will have the same layout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) * with an offset being a multiple of 0x24.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) * The following functions calculate from the pin number the register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) * and the bit offset that we should access.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) static inline u32 sunxi_mux_reg(u16 pin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) u8 bank = pin / PINS_PER_BANK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) u32 offset = bank * BANK_MEM_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) offset += MUX_REGS_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) offset += pin % PINS_PER_BANK / MUX_PINS_PER_REG * 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) return round_down(offset, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) static inline u32 sunxi_mux_offset(u16 pin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) u32 pin_num = pin % MUX_PINS_PER_REG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) return pin_num * MUX_PINS_BITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) static inline u32 sunxi_data_reg(u16 pin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) u8 bank = pin / PINS_PER_BANK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) u32 offset = bank * BANK_MEM_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) offset += DATA_REGS_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) offset += pin % PINS_PER_BANK / DATA_PINS_PER_REG * 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) return round_down(offset, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) static inline u32 sunxi_data_offset(u16 pin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) u32 pin_num = pin % DATA_PINS_PER_REG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) return pin_num * DATA_PINS_BITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) static inline u32 sunxi_dlevel_reg(u16 pin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) u8 bank = pin / PINS_PER_BANK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) u32 offset = bank * BANK_MEM_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) offset += DLEVEL_REGS_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) offset += pin % PINS_PER_BANK / DLEVEL_PINS_PER_REG * 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) return round_down(offset, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) static inline u32 sunxi_dlevel_offset(u16 pin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) u32 pin_num = pin % DLEVEL_PINS_PER_REG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) return pin_num * DLEVEL_PINS_BITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) static inline u32 sunxi_pull_reg(u16 pin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) u8 bank = pin / PINS_PER_BANK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) u32 offset = bank * BANK_MEM_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) offset += PULL_REGS_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) offset += pin % PINS_PER_BANK / PULL_PINS_PER_REG * 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) return round_down(offset, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) static inline u32 sunxi_pull_offset(u16 pin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) u32 pin_num = pin % PULL_PINS_PER_REG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) return pin_num * PULL_PINS_BITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) static inline u32 sunxi_irq_hw_bank_num(const struct sunxi_pinctrl_desc *desc, u8 bank)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) if (!desc->irq_bank_map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) return bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) return desc->irq_bank_map[bank];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) static inline u32 sunxi_irq_cfg_reg(const struct sunxi_pinctrl_desc *desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) u16 irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) u8 bank = irq / IRQ_PER_BANK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) u8 reg = (irq % IRQ_PER_BANK) / IRQ_CFG_IRQ_PER_REG * 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) return IRQ_CFG_REG +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) sunxi_irq_hw_bank_num(desc, bank) * IRQ_MEM_SIZE + reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) static inline u32 sunxi_irq_cfg_offset(u16 irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) u32 irq_num = irq % IRQ_CFG_IRQ_PER_REG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) return irq_num * IRQ_CFG_IRQ_BITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) static inline u32 sunxi_irq_ctrl_reg_from_bank(const struct sunxi_pinctrl_desc *desc, u8 bank)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) return IRQ_CTRL_REG + sunxi_irq_hw_bank_num(desc, bank) * IRQ_MEM_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) static inline u32 sunxi_irq_ctrl_reg(const struct sunxi_pinctrl_desc *desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) u16 irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) u8 bank = irq / IRQ_PER_BANK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) return sunxi_irq_ctrl_reg_from_bank(desc, bank);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) static inline u32 sunxi_irq_ctrl_offset(u16 irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) u32 irq_num = irq % IRQ_CTRL_IRQ_PER_REG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) return irq_num * IRQ_CTRL_IRQ_BITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) static inline u32 sunxi_irq_debounce_reg_from_bank(const struct sunxi_pinctrl_desc *desc, u8 bank)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) return IRQ_DEBOUNCE_REG +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) sunxi_irq_hw_bank_num(desc, bank) * IRQ_MEM_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) static inline u32 sunxi_irq_status_reg_from_bank(const struct sunxi_pinctrl_desc *desc, u8 bank)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) return IRQ_STATUS_REG +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) sunxi_irq_hw_bank_num(desc, bank) * IRQ_MEM_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) static inline u32 sunxi_irq_status_reg(const struct sunxi_pinctrl_desc *desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) u16 irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) u8 bank = irq / IRQ_PER_BANK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) return sunxi_irq_status_reg_from_bank(desc, bank);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) static inline u32 sunxi_irq_status_offset(u16 irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) u32 irq_num = irq % IRQ_STATUS_IRQ_PER_REG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) return irq_num * IRQ_STATUS_IRQ_BITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) static inline u32 sunxi_grp_config_reg(u16 pin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) u8 bank = pin / PINS_PER_BANK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) return GRP_CFG_REG + bank * 0x4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) int sunxi_pinctrl_init_with_variant(struct platform_device *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) const struct sunxi_pinctrl_desc *desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) unsigned long variant);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) #define sunxi_pinctrl_init(_dev, _desc) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) sunxi_pinctrl_init_with_variant(_dev, _desc, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) #endif /* __PINCTRL_SUNXI_H */