uboot/drivers/pinctrl/ath79/pinctrl_qca953x.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
   4 */
   5
   6#include <common.h>
   7#include <dm.h>
   8#include <errno.h>
   9#include <asm/io.h>
  10#include <dm/pinctrl.h>
  11#include <mach/ar71xx_regs.h>
  12
  13DECLARE_GLOBAL_DATA_PTR;
  14
  15enum periph_id {
  16        PERIPH_ID_UART0,
  17        PERIPH_ID_SPI0,
  18        PERIPH_ID_NONE = -1,
  19};
  20
  21struct qca953x_pinctrl_priv {
  22        void __iomem *regs;
  23};
  24
  25static void pinctrl_qca953x_spi_config(struct qca953x_pinctrl_priv *priv, int cs)
  26{
  27        switch (cs) {
  28        case 0:
  29                clrsetbits_be32(priv->regs + AR71XX_GPIO_REG_OE,
  30                                QCA953X_GPIO(5) | QCA953X_GPIO(6) |
  31                                QCA953X_GPIO(7), QCA953X_GPIO(8));
  32
  33                clrsetbits_be32(priv->regs + QCA953X_GPIO_REG_OUT_FUNC1,
  34                                QCA953X_GPIO_MUX_MASK(8) |
  35                                QCA953X_GPIO_MUX_MASK(16) |
  36                                QCA953X_GPIO_MUX_MASK(24),
  37                                (QCA953X_GPIO_OUT_MUX_SPI_CS0 << 8) |
  38                                (QCA953X_GPIO_OUT_MUX_SPI_CLK << 16) |
  39                                (QCA953X_GPIO_OUT_MUX_SPI_MOSI << 24));
  40
  41                clrsetbits_be32(priv->regs + QCA953X_GPIO_REG_IN_ENABLE0,
  42                                QCA953X_GPIO_MUX_MASK(0),
  43                                QCA953X_GPIO_IN_MUX_SPI_DATA_IN);
  44
  45                setbits_be32(priv->regs + AR71XX_GPIO_REG_OUT,
  46                             QCA953X_GPIO(8));
  47                break;
  48        }
  49}
  50
  51static void pinctrl_qca953x_uart_config(struct qca953x_pinctrl_priv *priv, int uart_id)
  52{
  53        switch (uart_id) {
  54        case PERIPH_ID_UART0:
  55                clrsetbits_be32(priv->regs + AR71XX_GPIO_REG_OE,
  56                                QCA953X_GPIO(9), QCA953X_GPIO(10));
  57
  58                clrsetbits_be32(priv->regs + QCA953X_GPIO_REG_OUT_FUNC2,
  59                                QCA953X_GPIO_MUX_MASK(16),
  60                                QCA953X_GPIO_OUT_MUX_UART0_SOUT << 16);
  61
  62                clrsetbits_be32(priv->regs + QCA953X_GPIO_REG_IN_ENABLE0,
  63                                QCA953X_GPIO_MUX_MASK(8),
  64                                QCA953X_GPIO_IN_MUX_UART0_SIN << 8);
  65
  66                setbits_be32(priv->regs + AR71XX_GPIO_REG_OUT,
  67                             QCA953X_GPIO(10));
  68                break;
  69        }
  70}
  71
  72static int qca953x_pinctrl_request(struct udevice *dev, int func, int flags)
  73{
  74        struct qca953x_pinctrl_priv *priv = dev_get_priv(dev);
  75
  76        debug("%s: func=%x, flags=%x\n", __func__, func, flags);
  77        switch (func) {
  78        case PERIPH_ID_SPI0:
  79                pinctrl_qca953x_spi_config(priv, flags);
  80                break;
  81        case PERIPH_ID_UART0:
  82                pinctrl_qca953x_uart_config(priv, func);
  83                break;
  84        default:
  85                return -EINVAL;
  86        }
  87
  88        return 0;
  89}
  90
  91static int qca953x_pinctrl_get_periph_id(struct udevice *dev,
  92                                        struct udevice *periph)
  93{
  94        u32 cell[2];
  95        int ret;
  96
  97        ret = fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(periph),
  98                                   "interrupts", cell, ARRAY_SIZE(cell));
  99        if (ret < 0)
 100                return -EINVAL;
 101
 102        switch (cell[0]) {
 103        case 128:
 104                return PERIPH_ID_UART0;
 105        case 129:
 106                return PERIPH_ID_SPI0;
 107        }
 108        return -ENOENT;
 109}
 110
 111static int qca953x_pinctrl_set_state_simple(struct udevice *dev,
 112                                           struct udevice *periph)
 113{
 114        int func;
 115
 116        func = qca953x_pinctrl_get_periph_id(dev, periph);
 117        if (func < 0)
 118                return func;
 119        return qca953x_pinctrl_request(dev, func, 0);
 120}
 121
 122static struct pinctrl_ops qca953x_pinctrl_ops = {
 123        .set_state_simple       = qca953x_pinctrl_set_state_simple,
 124        .request        = qca953x_pinctrl_request,
 125        .get_periph_id  = qca953x_pinctrl_get_periph_id,
 126};
 127
 128static int qca953x_pinctrl_probe(struct udevice *dev)
 129{
 130        struct qca953x_pinctrl_priv *priv = dev_get_priv(dev);
 131        fdt_addr_t addr;
 132
 133        addr = devfdt_get_addr(dev);
 134        if (addr == FDT_ADDR_T_NONE)
 135                return -EINVAL;
 136
 137        priv->regs = map_physmem(addr,
 138                                 AR71XX_GPIO_SIZE,
 139                                 MAP_NOCACHE);
 140        return 0;
 141}
 142
 143static const struct udevice_id qca953x_pinctrl_ids[] = {
 144        { .compatible = "qca,qca953x-pinctrl" },
 145        { }
 146};
 147
 148U_BOOT_DRIVER(pinctrl_qca953x) = {
 149        .name           = "pinctrl_qca953x",
 150        .id             = UCLASS_PINCTRL,
 151        .of_match       = qca953x_pinctrl_ids,
 152        .priv_auto_alloc_size = sizeof(struct qca953x_pinctrl_priv),
 153        .ops            = &qca953x_pinctrl_ops,
 154        .probe          = qca953x_pinctrl_probe,
 155};
 156