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