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