1 // SPDX-License-Identifier: (GPL-2.0 OR MIT) 2 /* 3 * Microsemi SoCs pinctrl driver 4 * 5 * Author: <gregory.clement@bootlin.com> 6 * License: Dual MIT/GPL 7 * Copyright (c) 2018 Microsemi Corporation 8 */ 9 10 #include <common.h> 11 #include <config.h> 12 #include <dm.h> 13 #include <dm/device-internal.h> 14 #include <dm/lists.h> 15 #include <dm/pinctrl.h> 16 #include <dm/root.h> 17 #include <errno.h> 18 #include <fdtdec.h> 19 #include <linux/io.h> 20 #include <asm/gpio.h> 21 #include <asm/system.h> 22 #include "mscc-common.h" 23 24 enum { 25 FUNC_NONE, 26 FUNC_GPIO, 27 FUNC_SIO, 28 FUNC_TACHO, 29 FUNC_TWI, 30 FUNC_PHY_LED, 31 FUNC_EXT_IRQ, 32 FUNC_SFP, 33 FUNC_SI, 34 FUNC_PWM, 35 FUNC_UART, 36 FUNC_MAX 37 }; 38 39 static char * const luton_function_names[] = { 40 [FUNC_NONE] = "none", 41 [FUNC_GPIO] = "gpio", 42 [FUNC_SIO] = "sio", 43 [FUNC_TACHO] = "tacho", 44 [FUNC_TWI] = "twi", 45 [FUNC_PHY_LED] = "phy_led", 46 [FUNC_EXT_IRQ] = "ext_irq", 47 [FUNC_SFP] = "sfp", 48 [FUNC_SI] = "si", 49 [FUNC_PWM] = "pwm", 50 [FUNC_UART] = "uart", 51 }; 52 53 MSCC_P(0, SIO, NONE, NONE); 54 MSCC_P(1, SIO, NONE, NONE); 55 MSCC_P(2, SIO, NONE, NONE); 56 MSCC_P(3, SIO, NONE, NONE); 57 MSCC_P(4, TACHO, NONE, NONE); 58 MSCC_P(5, TWI, PHY_LED, NONE); 59 MSCC_P(6, TWI, PHY_LED, NONE); 60 MSCC_P(7, NONE, PHY_LED, NONE); 61 MSCC_P(8, EXT_IRQ, PHY_LED, NONE); 62 MSCC_P(9, EXT_IRQ, PHY_LED, NONE); 63 MSCC_P(10, SFP, PHY_LED, NONE); 64 MSCC_P(11, SFP, PHY_LED, NONE); 65 MSCC_P(12, SFP, PHY_LED, NONE); 66 MSCC_P(13, SFP, PHY_LED, NONE); 67 MSCC_P(14, SI, PHY_LED, NONE); 68 MSCC_P(15, SI, PHY_LED, NONE); 69 MSCC_P(16, SI, PHY_LED, NONE); 70 MSCC_P(17, SFP, PHY_LED, NONE); 71 MSCC_P(18, SFP, PHY_LED, NONE); 72 MSCC_P(19, SFP, PHY_LED, NONE); 73 MSCC_P(20, SFP, PHY_LED, NONE); 74 MSCC_P(21, SFP, PHY_LED, NONE); 75 MSCC_P(22, SFP, PHY_LED, NONE); 76 MSCC_P(23, SFP, PHY_LED, NONE); 77 MSCC_P(24, SFP, PHY_LED, NONE); 78 MSCC_P(25, SFP, PHY_LED, NONE); 79 MSCC_P(26, SFP, PHY_LED, NONE); 80 MSCC_P(27, SFP, PHY_LED, NONE); 81 MSCC_P(28, SFP, PHY_LED, NONE); 82 MSCC_P(29, PWM, NONE, NONE); 83 MSCC_P(30, UART, NONE, NONE); 84 MSCC_P(31, UART, NONE, NONE); 85 86 #define LUTON_PIN(n) { \ 87 .name = "GPIO_"#n, \ 88 .drv_data = &mscc_pin_##n \ 89 } 90 91 static const struct mscc_pin_data luton_pins[] = { 92 LUTON_PIN(0), 93 LUTON_PIN(1), 94 LUTON_PIN(2), 95 LUTON_PIN(3), 96 LUTON_PIN(4), 97 LUTON_PIN(5), 98 LUTON_PIN(6), 99 LUTON_PIN(7), 100 LUTON_PIN(8), 101 LUTON_PIN(9), 102 LUTON_PIN(10), 103 LUTON_PIN(11), 104 LUTON_PIN(12), 105 LUTON_PIN(13), 106 LUTON_PIN(14), 107 LUTON_PIN(15), 108 LUTON_PIN(16), 109 LUTON_PIN(17), 110 LUTON_PIN(18), 111 LUTON_PIN(19), 112 LUTON_PIN(20), 113 LUTON_PIN(21), 114 LUTON_PIN(22), 115 LUTON_PIN(23), 116 LUTON_PIN(24), 117 LUTON_PIN(25), 118 LUTON_PIN(26), 119 LUTON_PIN(27), 120 LUTON_PIN(28), 121 LUTON_PIN(29), 122 LUTON_PIN(30), 123 LUTON_PIN(31), 124 }; 125 126 static const unsigned long luton_gpios[] = { 127 [MSCC_GPIO_OUT_SET] = 0x00, 128 [MSCC_GPIO_OUT_CLR] = 0x04, 129 [MSCC_GPIO_OUT] = 0x08, 130 [MSCC_GPIO_IN] = 0x0c, 131 [MSCC_GPIO_OE] = 0x10, 132 [MSCC_GPIO_INTR] = 0x14, 133 [MSCC_GPIO_INTR_ENA] = 0x18, 134 [MSCC_GPIO_INTR_IDENT] = 0x1c, 135 [MSCC_GPIO_ALT0] = 0x20, 136 [MSCC_GPIO_ALT1] = 0x24, 137 }; 138 139 static int luton_gpio_probe(struct udevice *dev) 140 { 141 struct gpio_dev_priv *uc_priv; 142 143 uc_priv = dev_get_uclass_priv(dev); 144 uc_priv->bank_name = "luton-gpio"; 145 uc_priv->gpio_count = ARRAY_SIZE(luton_pins); 146 147 return 0; 148 } 149 150 static struct driver luton_gpio_driver = { 151 .name = "luton-gpio", 152 .id = UCLASS_GPIO, 153 .probe = luton_gpio_probe, 154 .ops = &mscc_gpio_ops, 155 }; 156 157 int luton_pinctrl_probe(struct udevice *dev) 158 { 159 int ret; 160 161 ret = mscc_pinctrl_probe(dev, FUNC_MAX, luton_pins, 162 ARRAY_SIZE(luton_pins), luton_function_names, 163 luton_gpios); 164 165 if (ret) 166 return ret; 167 168 ret = device_bind(dev, &luton_gpio_driver, "luton-gpio", NULL, 169 dev_of_offset(dev), NULL); 170 171 return 0; 172 } 173 174 static const struct udevice_id luton_pinctrl_of_match[] = { 175 {.compatible = "mscc,luton-pinctrl"}, 176 {}, 177 }; 178 179 U_BOOT_DRIVER(luton_pinctrl) = { 180 .name = "luton-pinctrl", 181 .id = UCLASS_PINCTRL, 182 .of_match = of_match_ptr(luton_pinctrl_of_match), 183 .probe = luton_pinctrl_probe, 184 .priv_auto_alloc_size = sizeof(struct mscc_pinctrl), 185 .ops = &mscc_pinctrl_ops, 186 }; 187