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 14 DECLARE_GLOBAL_DATA_PTR; 15 16 enum periph_id { 17 PERIPH_ID_UART0, 18 PERIPH_ID_SPI0, 19 PERIPH_ID_NONE = -1, 20 }; 21 22 struct ar933x_pinctrl_priv { 23 void __iomem *regs; 24 }; 25 26 static 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 40 static 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 53 static 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 72 static 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 92 static 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 103 static 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 109 static 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 124 static const struct udevice_id ar933x_pinctrl_ids[] = { 125 { .compatible = "qca,ar933x-pinctrl" }, 126 { } 127 }; 128 129 U_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