1*53bdae24SGregory CLEMENT // SPDX-License-Identifier: (GPL-2.0 OR MIT) 2*53bdae24SGregory CLEMENT /* 3*53bdae24SGregory CLEMENT * Microsemi SoCs pinctrl driver 4*53bdae24SGregory CLEMENT * 5*53bdae24SGregory CLEMENT * Author: <alexandre.belloni@free-electrons.com> 6*53bdae24SGregory CLEMENT * Author: <gregory.clement@bootlin.com> 7*53bdae24SGregory CLEMENT * License: Dual MIT/GPL 8*53bdae24SGregory CLEMENT * Copyright (c) 2017 Microsemi Corporation 9*53bdae24SGregory CLEMENT */ 10*53bdae24SGregory CLEMENT 11*53bdae24SGregory CLEMENT #include <asm/gpio.h> 12*53bdae24SGregory CLEMENT #include <asm/system.h> 13*53bdae24SGregory CLEMENT #include <common.h> 14*53bdae24SGregory CLEMENT #include <config.h> 15*53bdae24SGregory CLEMENT #include <dm.h> 16*53bdae24SGregory CLEMENT #include <dm/device-internal.h> 17*53bdae24SGregory CLEMENT #include <dm/lists.h> 18*53bdae24SGregory CLEMENT #include <dm/pinctrl.h> 19*53bdae24SGregory CLEMENT #include <dm/root.h> 20*53bdae24SGregory CLEMENT #include <errno.h> 21*53bdae24SGregory CLEMENT #include <fdtdec.h> 22*53bdae24SGregory CLEMENT #include <linux/io.h> 23*53bdae24SGregory CLEMENT #include "mscc-common.h" 24*53bdae24SGregory CLEMENT 25*53bdae24SGregory CLEMENT enum { 26*53bdae24SGregory CLEMENT FUNC_NONE, 27*53bdae24SGregory CLEMENT FUNC_GPIO, 28*53bdae24SGregory CLEMENT FUNC_IRQ0_IN, 29*53bdae24SGregory CLEMENT FUNC_IRQ0_OUT, 30*53bdae24SGregory CLEMENT FUNC_IRQ1_IN, 31*53bdae24SGregory CLEMENT FUNC_IRQ1_OUT, 32*53bdae24SGregory CLEMENT FUNC_MIIM1, 33*53bdae24SGregory CLEMENT FUNC_PCI_WAKE, 34*53bdae24SGregory CLEMENT FUNC_PTP0, 35*53bdae24SGregory CLEMENT FUNC_PTP1, 36*53bdae24SGregory CLEMENT FUNC_PTP2, 37*53bdae24SGregory CLEMENT FUNC_PTP3, 38*53bdae24SGregory CLEMENT FUNC_PWM, 39*53bdae24SGregory CLEMENT FUNC_RECO_CLK0, 40*53bdae24SGregory CLEMENT FUNC_RECO_CLK1, 41*53bdae24SGregory CLEMENT FUNC_SFP0, 42*53bdae24SGregory CLEMENT FUNC_SFP1, 43*53bdae24SGregory CLEMENT FUNC_SFP2, 44*53bdae24SGregory CLEMENT FUNC_SFP3, 45*53bdae24SGregory CLEMENT FUNC_SFP4, 46*53bdae24SGregory CLEMENT FUNC_SFP5, 47*53bdae24SGregory CLEMENT FUNC_SG0, 48*53bdae24SGregory CLEMENT FUNC_SI, 49*53bdae24SGregory CLEMENT FUNC_TACHO, 50*53bdae24SGregory CLEMENT FUNC_TWI, 51*53bdae24SGregory CLEMENT FUNC_TWI_SCL_M, 52*53bdae24SGregory CLEMENT FUNC_UART, 53*53bdae24SGregory CLEMENT FUNC_UART2, 54*53bdae24SGregory CLEMENT FUNC_MAX 55*53bdae24SGregory CLEMENT }; 56*53bdae24SGregory CLEMENT 57*53bdae24SGregory CLEMENT static char * const ocelot_function_names[] = { 58*53bdae24SGregory CLEMENT [FUNC_NONE] = "none", 59*53bdae24SGregory CLEMENT [FUNC_GPIO] = "gpio", 60*53bdae24SGregory CLEMENT [FUNC_IRQ0_IN] = "irq0_in", 61*53bdae24SGregory CLEMENT [FUNC_IRQ0_OUT] = "irq0_out", 62*53bdae24SGregory CLEMENT [FUNC_IRQ1_IN] = "irq1_in", 63*53bdae24SGregory CLEMENT [FUNC_IRQ1_OUT] = "irq1_out", 64*53bdae24SGregory CLEMENT [FUNC_MIIM1] = "miim1", 65*53bdae24SGregory CLEMENT [FUNC_PCI_WAKE] = "pci_wake", 66*53bdae24SGregory CLEMENT [FUNC_PTP0] = "ptp0", 67*53bdae24SGregory CLEMENT [FUNC_PTP1] = "ptp1", 68*53bdae24SGregory CLEMENT [FUNC_PTP2] = "ptp2", 69*53bdae24SGregory CLEMENT [FUNC_PTP3] = "ptp3", 70*53bdae24SGregory CLEMENT [FUNC_PWM] = "pwm", 71*53bdae24SGregory CLEMENT [FUNC_RECO_CLK0] = "reco_clk0", 72*53bdae24SGregory CLEMENT [FUNC_RECO_CLK1] = "reco_clk1", 73*53bdae24SGregory CLEMENT [FUNC_SFP0] = "sfp0", 74*53bdae24SGregory CLEMENT [FUNC_SFP1] = "sfp1", 75*53bdae24SGregory CLEMENT [FUNC_SFP2] = "sfp2", 76*53bdae24SGregory CLEMENT [FUNC_SFP3] = "sfp3", 77*53bdae24SGregory CLEMENT [FUNC_SFP4] = "sfp4", 78*53bdae24SGregory CLEMENT [FUNC_SFP5] = "sfp5", 79*53bdae24SGregory CLEMENT [FUNC_SG0] = "sg0", 80*53bdae24SGregory CLEMENT [FUNC_SI] = "si", 81*53bdae24SGregory CLEMENT [FUNC_TACHO] = "tacho", 82*53bdae24SGregory CLEMENT [FUNC_TWI] = "twi", 83*53bdae24SGregory CLEMENT [FUNC_TWI_SCL_M] = "twi_scl_m", 84*53bdae24SGregory CLEMENT [FUNC_UART] = "uart", 85*53bdae24SGregory CLEMENT [FUNC_UART2] = "uart2", 86*53bdae24SGregory CLEMENT }; 87*53bdae24SGregory CLEMENT 88*53bdae24SGregory CLEMENT MSCC_P(0, SG0, NONE, NONE); 89*53bdae24SGregory CLEMENT MSCC_P(1, SG0, NONE, NONE); 90*53bdae24SGregory CLEMENT MSCC_P(2, SG0, NONE, NONE); 91*53bdae24SGregory CLEMENT MSCC_P(3, SG0, NONE, NONE); 92*53bdae24SGregory CLEMENT MSCC_P(4, IRQ0_IN, IRQ0_OUT, TWI); 93*53bdae24SGregory CLEMENT MSCC_P(5, IRQ1_IN, IRQ1_OUT, PCI_WAKE); 94*53bdae24SGregory CLEMENT MSCC_P(6, UART, TWI_SCL_M, NONE); 95*53bdae24SGregory CLEMENT MSCC_P(7, UART, TWI_SCL_M, NONE); 96*53bdae24SGregory CLEMENT MSCC_P(8, SI, TWI_SCL_M, IRQ0_OUT); 97*53bdae24SGregory CLEMENT MSCC_P(9, SI, TWI_SCL_M, IRQ1_OUT); 98*53bdae24SGregory CLEMENT MSCC_P(10, PTP2, TWI_SCL_M, SFP0); 99*53bdae24SGregory CLEMENT MSCC_P(11, PTP3, TWI_SCL_M, SFP1); 100*53bdae24SGregory CLEMENT MSCC_P(12, UART2, TWI_SCL_M, SFP2); 101*53bdae24SGregory CLEMENT MSCC_P(13, UART2, TWI_SCL_M, SFP3); 102*53bdae24SGregory CLEMENT MSCC_P(14, MIIM1, TWI_SCL_M, SFP4); 103*53bdae24SGregory CLEMENT MSCC_P(15, MIIM1, TWI_SCL_M, SFP5); 104*53bdae24SGregory CLEMENT MSCC_P(16, TWI, NONE, SI); 105*53bdae24SGregory CLEMENT MSCC_P(17, TWI, TWI_SCL_M, SI); 106*53bdae24SGregory CLEMENT MSCC_P(18, PTP0, TWI_SCL_M, NONE); 107*53bdae24SGregory CLEMENT MSCC_P(19, PTP1, TWI_SCL_M, NONE); 108*53bdae24SGregory CLEMENT MSCC_P(20, RECO_CLK0, TACHO, NONE); 109*53bdae24SGregory CLEMENT MSCC_P(21, RECO_CLK1, PWM, NONE); 110*53bdae24SGregory CLEMENT 111*53bdae24SGregory CLEMENT #define OCELOT_PIN(n) { \ 112*53bdae24SGregory CLEMENT .name = "GPIO_"#n, \ 113*53bdae24SGregory CLEMENT .drv_data = &mscc_pin_##n \ 114*53bdae24SGregory CLEMENT } 115*53bdae24SGregory CLEMENT 116*53bdae24SGregory CLEMENT static const struct mscc_pin_data ocelot_pins[] = { 117*53bdae24SGregory CLEMENT OCELOT_PIN(0), 118*53bdae24SGregory CLEMENT OCELOT_PIN(1), 119*53bdae24SGregory CLEMENT OCELOT_PIN(2), 120*53bdae24SGregory CLEMENT OCELOT_PIN(3), 121*53bdae24SGregory CLEMENT OCELOT_PIN(4), 122*53bdae24SGregory CLEMENT OCELOT_PIN(5), 123*53bdae24SGregory CLEMENT OCELOT_PIN(6), 124*53bdae24SGregory CLEMENT OCELOT_PIN(7), 125*53bdae24SGregory CLEMENT OCELOT_PIN(8), 126*53bdae24SGregory CLEMENT OCELOT_PIN(9), 127*53bdae24SGregory CLEMENT OCELOT_PIN(10), 128*53bdae24SGregory CLEMENT OCELOT_PIN(11), 129*53bdae24SGregory CLEMENT OCELOT_PIN(12), 130*53bdae24SGregory CLEMENT OCELOT_PIN(13), 131*53bdae24SGregory CLEMENT OCELOT_PIN(14), 132*53bdae24SGregory CLEMENT OCELOT_PIN(15), 133*53bdae24SGregory CLEMENT OCELOT_PIN(16), 134*53bdae24SGregory CLEMENT OCELOT_PIN(17), 135*53bdae24SGregory CLEMENT OCELOT_PIN(18), 136*53bdae24SGregory CLEMENT OCELOT_PIN(19), 137*53bdae24SGregory CLEMENT OCELOT_PIN(20), 138*53bdae24SGregory CLEMENT OCELOT_PIN(21), 139*53bdae24SGregory CLEMENT }; 140*53bdae24SGregory CLEMENT 141*53bdae24SGregory CLEMENT static int ocelot_gpio_probe(struct udevice *dev) 142*53bdae24SGregory CLEMENT { 143*53bdae24SGregory CLEMENT struct gpio_dev_priv *uc_priv; 144*53bdae24SGregory CLEMENT 145*53bdae24SGregory CLEMENT uc_priv = dev_get_uclass_priv(dev); 146*53bdae24SGregory CLEMENT uc_priv->bank_name = "ocelot-gpio"; 147*53bdae24SGregory CLEMENT uc_priv->gpio_count = ARRAY_SIZE(ocelot_pins); 148*53bdae24SGregory CLEMENT 149*53bdae24SGregory CLEMENT return 0; 150*53bdae24SGregory CLEMENT } 151*53bdae24SGregory CLEMENT 152*53bdae24SGregory CLEMENT static struct driver ocelot_gpio_driver = { 153*53bdae24SGregory CLEMENT .name = "ocelot-gpio", 154*53bdae24SGregory CLEMENT .id = UCLASS_GPIO, 155*53bdae24SGregory CLEMENT .probe = ocelot_gpio_probe, 156*53bdae24SGregory CLEMENT .ops = &mscc_gpio_ops, 157*53bdae24SGregory CLEMENT }; 158*53bdae24SGregory CLEMENT 159*53bdae24SGregory CLEMENT int ocelot_pinctrl_probe(struct udevice *dev) 160*53bdae24SGregory CLEMENT { 161*53bdae24SGregory CLEMENT int ret; 162*53bdae24SGregory CLEMENT 163*53bdae24SGregory CLEMENT ret = mscc_pinctrl_probe(dev, FUNC_MAX, ocelot_pins, 164*53bdae24SGregory CLEMENT ARRAY_SIZE(ocelot_pins), 165*53bdae24SGregory CLEMENT ocelot_function_names); 166*53bdae24SGregory CLEMENT 167*53bdae24SGregory CLEMENT if (ret) 168*53bdae24SGregory CLEMENT return ret; 169*53bdae24SGregory CLEMENT 170*53bdae24SGregory CLEMENT ret = device_bind(dev, &ocelot_gpio_driver, "ocelot-gpio", NULL, 171*53bdae24SGregory CLEMENT dev_of_offset(dev), NULL); 172*53bdae24SGregory CLEMENT 173*53bdae24SGregory CLEMENT return ret; 174*53bdae24SGregory CLEMENT } 175*53bdae24SGregory CLEMENT 176*53bdae24SGregory CLEMENT static const struct udevice_id ocelot_pinctrl_of_match[] = { 177*53bdae24SGregory CLEMENT {.compatible = "mscc,ocelot-pinctrl"}, 178*53bdae24SGregory CLEMENT {}, 179*53bdae24SGregory CLEMENT }; 180*53bdae24SGregory CLEMENT 181*53bdae24SGregory CLEMENT U_BOOT_DRIVER(ocelot_pinctrl) = { 182*53bdae24SGregory CLEMENT .name = "ocelot-pinctrl", 183*53bdae24SGregory CLEMENT .id = UCLASS_PINCTRL, 184*53bdae24SGregory CLEMENT .of_match = of_match_ptr(ocelot_pinctrl_of_match), 185*53bdae24SGregory CLEMENT .probe = ocelot_pinctrl_probe, 186*53bdae24SGregory CLEMENT .priv_auto_alloc_size = sizeof(struct mscc_pinctrl), 187*53bdae24SGregory CLEMENT .ops = &mscc_pinctrl_ops, 188*53bdae24SGregory CLEMENT }; 189