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