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