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