1*bed5cd6fSEmil Renner Berthing // SPDX-License-Identifier: GPL-2.0 2*bed5cd6fSEmil Renner Berthing /* 3*bed5cd6fSEmil Renner Berthing * Pinctrl driver for the T-Head TH1520 SoC 4*bed5cd6fSEmil Renner Berthing * 5*bed5cd6fSEmil Renner Berthing * Copyright (C) 2023 Emil Renner Berthing <emil.renner.berthing@canonical.com> 6*bed5cd6fSEmil Renner Berthing */ 7*bed5cd6fSEmil Renner Berthing 8*bed5cd6fSEmil Renner Berthing #include <linux/array_size.h> 9*bed5cd6fSEmil Renner Berthing #include <linux/bits.h> 10*bed5cd6fSEmil Renner Berthing #include <linux/cleanup.h> 11*bed5cd6fSEmil Renner Berthing #include <linux/clk.h> 12*bed5cd6fSEmil Renner Berthing #include <linux/device.h> 13*bed5cd6fSEmil Renner Berthing #include <linux/io.h> 14*bed5cd6fSEmil Renner Berthing #include <linux/mod_devicetable.h> 15*bed5cd6fSEmil Renner Berthing #include <linux/module.h> 16*bed5cd6fSEmil Renner Berthing #include <linux/mutex.h> 17*bed5cd6fSEmil Renner Berthing #include <linux/of.h> 18*bed5cd6fSEmil Renner Berthing #include <linux/platform_device.h> 19*bed5cd6fSEmil Renner Berthing #include <linux/seq_file.h> 20*bed5cd6fSEmil Renner Berthing #include <linux/spinlock.h> 21*bed5cd6fSEmil Renner Berthing 22*bed5cd6fSEmil Renner Berthing #include <linux/of_address.h> 23*bed5cd6fSEmil Renner Berthing #include <linux/of_device.h> 24*bed5cd6fSEmil Renner Berthing 25*bed5cd6fSEmil Renner Berthing #include <linux/pinctrl/pinconf.h> 26*bed5cd6fSEmil Renner Berthing #include <linux/pinctrl/pinconf-generic.h> 27*bed5cd6fSEmil Renner Berthing #include <linux/pinctrl/pinctrl.h> 28*bed5cd6fSEmil Renner Berthing #include <linux/pinctrl/pinmux.h> 29*bed5cd6fSEmil Renner Berthing 30*bed5cd6fSEmil Renner Berthing #include "core.h" 31*bed5cd6fSEmil Renner Berthing #include "pinmux.h" 32*bed5cd6fSEmil Renner Berthing #include "pinconf.h" 33*bed5cd6fSEmil Renner Berthing 34*bed5cd6fSEmil Renner Berthing #define TH1520_PADCFG_IE BIT(9) 35*bed5cd6fSEmil Renner Berthing #define TH1520_PADCFG_SL BIT(8) 36*bed5cd6fSEmil Renner Berthing #define TH1520_PADCFG_ST BIT(7) 37*bed5cd6fSEmil Renner Berthing #define TH1520_PADCFG_SPU BIT(6) 38*bed5cd6fSEmil Renner Berthing #define TH1520_PADCFG_PS BIT(5) 39*bed5cd6fSEmil Renner Berthing #define TH1520_PADCFG_PE BIT(4) 40*bed5cd6fSEmil Renner Berthing #define TH1520_PADCFG_BIAS (TH1520_PADCFG_SPU | TH1520_PADCFG_PS | TH1520_PADCFG_PE) 41*bed5cd6fSEmil Renner Berthing #define TH1520_PADCFG_DS GENMASK(3, 0) 42*bed5cd6fSEmil Renner Berthing 43*bed5cd6fSEmil Renner Berthing #define TH1520_PULL_DOWN_OHM 44000 /* typ. 44kOhm */ 44*bed5cd6fSEmil Renner Berthing #define TH1520_PULL_UP_OHM 48000 /* typ. 48kOhm */ 45*bed5cd6fSEmil Renner Berthing #define TH1520_PULL_STRONG_OHM 2100 /* typ. 2.1kOhm */ 46*bed5cd6fSEmil Renner Berthing 47*bed5cd6fSEmil Renner Berthing #define TH1520_PAD_NO_PADCFG BIT(30) 48*bed5cd6fSEmil Renner Berthing #define TH1520_PAD_MUXDATA GENMASK(29, 0) 49*bed5cd6fSEmil Renner Berthing 50*bed5cd6fSEmil Renner Berthing struct th1520_pad_group { 51*bed5cd6fSEmil Renner Berthing const char *name; 52*bed5cd6fSEmil Renner Berthing const struct pinctrl_pin_desc *pins; 53*bed5cd6fSEmil Renner Berthing unsigned int npins; 54*bed5cd6fSEmil Renner Berthing }; 55*bed5cd6fSEmil Renner Berthing 56*bed5cd6fSEmil Renner Berthing struct th1520_pinctrl { 57*bed5cd6fSEmil Renner Berthing struct pinctrl_desc desc; 58*bed5cd6fSEmil Renner Berthing struct mutex mutex; /* serialize adding functions */ 59*bed5cd6fSEmil Renner Berthing raw_spinlock_t lock; /* serialize register access */ 60*bed5cd6fSEmil Renner Berthing void __iomem *base; 61*bed5cd6fSEmil Renner Berthing struct pinctrl_dev *pctl; 62*bed5cd6fSEmil Renner Berthing }; 63*bed5cd6fSEmil Renner Berthing 64*bed5cd6fSEmil Renner Berthing static void __iomem *th1520_padcfg(struct th1520_pinctrl *thp, 65*bed5cd6fSEmil Renner Berthing unsigned int pin) 66*bed5cd6fSEmil Renner Berthing { 67*bed5cd6fSEmil Renner Berthing return thp->base + 4 * (pin / 2); 68*bed5cd6fSEmil Renner Berthing } 69*bed5cd6fSEmil Renner Berthing 70*bed5cd6fSEmil Renner Berthing static unsigned int th1520_padcfg_shift(unsigned int pin) 71*bed5cd6fSEmil Renner Berthing { 72*bed5cd6fSEmil Renner Berthing return 16 * (pin & BIT(0)); 73*bed5cd6fSEmil Renner Berthing } 74*bed5cd6fSEmil Renner Berthing 75*bed5cd6fSEmil Renner Berthing static void __iomem *th1520_muxcfg(struct th1520_pinctrl *thp, 76*bed5cd6fSEmil Renner Berthing unsigned int pin) 77*bed5cd6fSEmil Renner Berthing { 78*bed5cd6fSEmil Renner Berthing return thp->base + 0x400 + 4 * (pin / 8); 79*bed5cd6fSEmil Renner Berthing } 80*bed5cd6fSEmil Renner Berthing 81*bed5cd6fSEmil Renner Berthing static unsigned int th1520_muxcfg_shift(unsigned int pin) 82*bed5cd6fSEmil Renner Berthing { 83*bed5cd6fSEmil Renner Berthing return 4 * (pin & GENMASK(2, 0)); 84*bed5cd6fSEmil Renner Berthing } 85*bed5cd6fSEmil Renner Berthing 86*bed5cd6fSEmil Renner Berthing enum th1520_muxtype { 87*bed5cd6fSEmil Renner Berthing TH1520_MUX_____, 88*bed5cd6fSEmil Renner Berthing TH1520_MUX_GPIO, 89*bed5cd6fSEmil Renner Berthing TH1520_MUX_PWM, 90*bed5cd6fSEmil Renner Berthing TH1520_MUX_UART, 91*bed5cd6fSEmil Renner Berthing TH1520_MUX_IR, 92*bed5cd6fSEmil Renner Berthing TH1520_MUX_I2C, 93*bed5cd6fSEmil Renner Berthing TH1520_MUX_SPI, 94*bed5cd6fSEmil Renner Berthing TH1520_MUX_QSPI, 95*bed5cd6fSEmil Renner Berthing TH1520_MUX_SDIO, 96*bed5cd6fSEmil Renner Berthing TH1520_MUX_AUD, 97*bed5cd6fSEmil Renner Berthing TH1520_MUX_I2S, 98*bed5cd6fSEmil Renner Berthing TH1520_MUX_MAC0, 99*bed5cd6fSEmil Renner Berthing TH1520_MUX_MAC1, 100*bed5cd6fSEmil Renner Berthing TH1520_MUX_DPU0, 101*bed5cd6fSEmil Renner Berthing TH1520_MUX_DPU1, 102*bed5cd6fSEmil Renner Berthing TH1520_MUX_ISP, 103*bed5cd6fSEmil Renner Berthing TH1520_MUX_HDMI, 104*bed5cd6fSEmil Renner Berthing TH1520_MUX_BSEL, 105*bed5cd6fSEmil Renner Berthing TH1520_MUX_DBG, 106*bed5cd6fSEmil Renner Berthing TH1520_MUX_CLK, 107*bed5cd6fSEmil Renner Berthing TH1520_MUX_JTAG, 108*bed5cd6fSEmil Renner Berthing TH1520_MUX_ISO, 109*bed5cd6fSEmil Renner Berthing TH1520_MUX_FUSE, 110*bed5cd6fSEmil Renner Berthing TH1520_MUX_RST, 111*bed5cd6fSEmil Renner Berthing }; 112*bed5cd6fSEmil Renner Berthing 113*bed5cd6fSEmil Renner Berthing static const char *const th1520_muxtype_string[] = { 114*bed5cd6fSEmil Renner Berthing [TH1520_MUX_GPIO] = "gpio", 115*bed5cd6fSEmil Renner Berthing [TH1520_MUX_PWM] = "pwm", 116*bed5cd6fSEmil Renner Berthing [TH1520_MUX_UART] = "uart", 117*bed5cd6fSEmil Renner Berthing [TH1520_MUX_IR] = "ir", 118*bed5cd6fSEmil Renner Berthing [TH1520_MUX_I2C] = "i2c", 119*bed5cd6fSEmil Renner Berthing [TH1520_MUX_SPI] = "spi", 120*bed5cd6fSEmil Renner Berthing [TH1520_MUX_QSPI] = "qspi", 121*bed5cd6fSEmil Renner Berthing [TH1520_MUX_SDIO] = "sdio", 122*bed5cd6fSEmil Renner Berthing [TH1520_MUX_AUD] = "audio", 123*bed5cd6fSEmil Renner Berthing [TH1520_MUX_I2S] = "i2s", 124*bed5cd6fSEmil Renner Berthing [TH1520_MUX_MAC0] = "gmac0", 125*bed5cd6fSEmil Renner Berthing [TH1520_MUX_MAC1] = "gmac1", 126*bed5cd6fSEmil Renner Berthing [TH1520_MUX_DPU0] = "dpu0", 127*bed5cd6fSEmil Renner Berthing [TH1520_MUX_DPU1] = "dpu1", 128*bed5cd6fSEmil Renner Berthing [TH1520_MUX_ISP] = "isp", 129*bed5cd6fSEmil Renner Berthing [TH1520_MUX_HDMI] = "hdmi", 130*bed5cd6fSEmil Renner Berthing [TH1520_MUX_BSEL] = "bootsel", 131*bed5cd6fSEmil Renner Berthing [TH1520_MUX_DBG] = "debug", 132*bed5cd6fSEmil Renner Berthing [TH1520_MUX_CLK] = "clock", 133*bed5cd6fSEmil Renner Berthing [TH1520_MUX_JTAG] = "jtag", 134*bed5cd6fSEmil Renner Berthing [TH1520_MUX_ISO] = "iso7816", 135*bed5cd6fSEmil Renner Berthing [TH1520_MUX_FUSE] = "efuse", 136*bed5cd6fSEmil Renner Berthing [TH1520_MUX_RST] = "reset", 137*bed5cd6fSEmil Renner Berthing }; 138*bed5cd6fSEmil Renner Berthing 139*bed5cd6fSEmil Renner Berthing static enum th1520_muxtype th1520_muxtype_get(const char *str) 140*bed5cd6fSEmil Renner Berthing { 141*bed5cd6fSEmil Renner Berthing enum th1520_muxtype mt; 142*bed5cd6fSEmil Renner Berthing 143*bed5cd6fSEmil Renner Berthing for (mt = TH1520_MUX_GPIO; mt < ARRAY_SIZE(th1520_muxtype_string); mt++) { 144*bed5cd6fSEmil Renner Berthing if (!strcmp(str, th1520_muxtype_string[mt])) 145*bed5cd6fSEmil Renner Berthing return mt; 146*bed5cd6fSEmil Renner Berthing } 147*bed5cd6fSEmil Renner Berthing return TH1520_MUX_____; 148*bed5cd6fSEmil Renner Berthing } 149*bed5cd6fSEmil Renner Berthing 150*bed5cd6fSEmil Renner Berthing #define TH1520_PAD(_nr, _name, m0, m1, m2, m3, m4, m5, _flags) \ 151*bed5cd6fSEmil Renner Berthing { .number = _nr, .name = #_name, .drv_data = (void *)((_flags) | \ 152*bed5cd6fSEmil Renner Berthing (TH1520_MUX_##m0 << 0) | (TH1520_MUX_##m1 << 5) | (TH1520_MUX_##m2 << 10) | \ 153*bed5cd6fSEmil Renner Berthing (TH1520_MUX_##m3 << 15) | (TH1520_MUX_##m4 << 20) | (TH1520_MUX_##m5 << 25)) } 154*bed5cd6fSEmil Renner Berthing 155*bed5cd6fSEmil Renner Berthing static const struct pinctrl_pin_desc th1520_group1_pins[] = { 156*bed5cd6fSEmil Renner Berthing TH1520_PAD(0, OSC_CLK_IN, ____, ____, ____, ____, ____, ____, TH1520_PAD_NO_PADCFG), 157*bed5cd6fSEmil Renner Berthing TH1520_PAD(1, OSC_CLK_OUT, ____, ____, ____, ____, ____, ____, TH1520_PAD_NO_PADCFG), 158*bed5cd6fSEmil Renner Berthing TH1520_PAD(2, SYS_RST_N, ____, ____, ____, ____, ____, ____, TH1520_PAD_NO_PADCFG), 159*bed5cd6fSEmil Renner Berthing TH1520_PAD(3, RTC_CLK_IN, ____, ____, ____, ____, ____, ____, TH1520_PAD_NO_PADCFG), 160*bed5cd6fSEmil Renner Berthing TH1520_PAD(4, RTC_CLK_OUT, ____, ____, ____, ____, ____, ____, TH1520_PAD_NO_PADCFG), 161*bed5cd6fSEmil Renner Berthing /* skip number 5 so we can calculate register offsets and shifts from the pin number */ 162*bed5cd6fSEmil Renner Berthing TH1520_PAD(6, TEST_MODE, ____, ____, ____, ____, ____, ____, TH1520_PAD_NO_PADCFG), 163*bed5cd6fSEmil Renner Berthing TH1520_PAD(7, DEBUG_MODE, DBG, ____, ____, GPIO, ____, ____, TH1520_PAD_NO_PADCFG), 164*bed5cd6fSEmil Renner Berthing TH1520_PAD(8, POR_SEL, ____, ____, ____, ____, ____, ____, TH1520_PAD_NO_PADCFG), 165*bed5cd6fSEmil Renner Berthing TH1520_PAD(9, I2C_AON_SCL, I2C, ____, ____, GPIO, ____, ____, 0), 166*bed5cd6fSEmil Renner Berthing TH1520_PAD(10, I2C_AON_SDA, I2C, ____, ____, GPIO, ____, ____, 0), 167*bed5cd6fSEmil Renner Berthing TH1520_PAD(11, CPU_JTG_TCLK, JTAG, ____, ____, GPIO, ____, ____, 0), 168*bed5cd6fSEmil Renner Berthing TH1520_PAD(12, CPU_JTG_TMS, JTAG, ____, ____, GPIO, ____, ____, 0), 169*bed5cd6fSEmil Renner Berthing TH1520_PAD(13, CPU_JTG_TDI, JTAG, ____, ____, GPIO, ____, ____, 0), 170*bed5cd6fSEmil Renner Berthing TH1520_PAD(14, CPU_JTG_TDO, JTAG, ____, ____, GPIO, ____, ____, 0), 171*bed5cd6fSEmil Renner Berthing TH1520_PAD(15, CPU_JTG_TRST, JTAG, ____, ____, GPIO, ____, ____, 0), 172*bed5cd6fSEmil Renner Berthing TH1520_PAD(16, AOGPIO_7, CLK, AUD, ____, GPIO, ____, ____, 0), 173*bed5cd6fSEmil Renner Berthing TH1520_PAD(17, AOGPIO_8, UART, AUD, IR, GPIO, ____, ____, 0), 174*bed5cd6fSEmil Renner Berthing TH1520_PAD(18, AOGPIO_9, UART, AUD, IR, GPIO, ____, ____, 0), 175*bed5cd6fSEmil Renner Berthing TH1520_PAD(19, AOGPIO_10, CLK, AUD, ____, GPIO, ____, ____, 0), 176*bed5cd6fSEmil Renner Berthing TH1520_PAD(20, AOGPIO_11, GPIO, AUD, ____, ____, ____, ____, 0), 177*bed5cd6fSEmil Renner Berthing TH1520_PAD(21, AOGPIO_12, GPIO, AUD, ____, ____, ____, ____, 0), 178*bed5cd6fSEmil Renner Berthing TH1520_PAD(22, AOGPIO_13, GPIO, AUD, ____, ____, ____, ____, 0), 179*bed5cd6fSEmil Renner Berthing TH1520_PAD(23, AOGPIO_14, GPIO, AUD, ____, ____, ____, ____, 0), 180*bed5cd6fSEmil Renner Berthing TH1520_PAD(24, AOGPIO_15, GPIO, AUD, ____, ____, ____, ____, 0), 181*bed5cd6fSEmil Renner Berthing TH1520_PAD(25, AUDIO_PA0, AUD, ____, ____, GPIO, ____, ____, 0), 182*bed5cd6fSEmil Renner Berthing TH1520_PAD(26, AUDIO_PA1, AUD, ____, ____, GPIO, ____, ____, 0), 183*bed5cd6fSEmil Renner Berthing TH1520_PAD(27, AUDIO_PA2, AUD, ____, ____, GPIO, ____, ____, 0), 184*bed5cd6fSEmil Renner Berthing TH1520_PAD(28, AUDIO_PA3, AUD, ____, ____, GPIO, ____, ____, 0), 185*bed5cd6fSEmil Renner Berthing TH1520_PAD(29, AUDIO_PA4, AUD, ____, ____, GPIO, ____, ____, 0), 186*bed5cd6fSEmil Renner Berthing TH1520_PAD(30, AUDIO_PA5, AUD, ____, ____, GPIO, ____, ____, 0), 187*bed5cd6fSEmil Renner Berthing TH1520_PAD(31, AUDIO_PA6, AUD, ____, ____, GPIO, ____, ____, 0), 188*bed5cd6fSEmil Renner Berthing TH1520_PAD(32, AUDIO_PA7, AUD, ____, ____, GPIO, ____, ____, 0), 189*bed5cd6fSEmil Renner Berthing TH1520_PAD(33, AUDIO_PA8, AUD, ____, ____, GPIO, ____, ____, 0), 190*bed5cd6fSEmil Renner Berthing TH1520_PAD(34, AUDIO_PA9, AUD, ____, ____, GPIO, ____, ____, 0), 191*bed5cd6fSEmil Renner Berthing TH1520_PAD(35, AUDIO_PA10, AUD, ____, ____, GPIO, ____, ____, 0), 192*bed5cd6fSEmil Renner Berthing TH1520_PAD(36, AUDIO_PA11, AUD, ____, ____, GPIO, ____, ____, 0), 193*bed5cd6fSEmil Renner Berthing TH1520_PAD(37, AUDIO_PA12, AUD, ____, ____, GPIO, ____, ____, 0), 194*bed5cd6fSEmil Renner Berthing TH1520_PAD(38, AUDIO_PA13, AUD, ____, ____, GPIO, ____, ____, 0), 195*bed5cd6fSEmil Renner Berthing TH1520_PAD(39, AUDIO_PA14, AUD, ____, ____, GPIO, ____, ____, 0), 196*bed5cd6fSEmil Renner Berthing TH1520_PAD(40, AUDIO_PA15, AUD, ____, ____, GPIO, ____, ____, 0), 197*bed5cd6fSEmil Renner Berthing TH1520_PAD(41, AUDIO_PA16, AUD, ____, ____, GPIO, ____, ____, 0), 198*bed5cd6fSEmil Renner Berthing TH1520_PAD(42, AUDIO_PA17, AUD, ____, ____, GPIO, ____, ____, 0), 199*bed5cd6fSEmil Renner Berthing TH1520_PAD(43, AUDIO_PA27, AUD, ____, ____, GPIO, ____, ____, 0), 200*bed5cd6fSEmil Renner Berthing TH1520_PAD(44, AUDIO_PA28, AUD, ____, ____, GPIO, ____, ____, 0), 201*bed5cd6fSEmil Renner Berthing TH1520_PAD(45, AUDIO_PA29, AUD, ____, ____, GPIO, ____, ____, 0), 202*bed5cd6fSEmil Renner Berthing TH1520_PAD(46, AUDIO_PA30, AUD, RST, ____, GPIO, ____, ____, 0), 203*bed5cd6fSEmil Renner Berthing }; 204*bed5cd6fSEmil Renner Berthing 205*bed5cd6fSEmil Renner Berthing static const struct pinctrl_pin_desc th1520_group2_pins[] = { 206*bed5cd6fSEmil Renner Berthing TH1520_PAD(0, QSPI1_SCLK, QSPI, ISO, ____, GPIO, FUSE, ____, 0), 207*bed5cd6fSEmil Renner Berthing TH1520_PAD(1, QSPI1_CSN0, QSPI, ____, I2C, GPIO, FUSE, ____, 0), 208*bed5cd6fSEmil Renner Berthing TH1520_PAD(2, QSPI1_D0_MOSI, QSPI, ISO, I2C, GPIO, FUSE, ____, 0), 209*bed5cd6fSEmil Renner Berthing TH1520_PAD(3, QSPI1_D1_MISO, QSPI, ISO, ____, GPIO, FUSE, ____, 0), 210*bed5cd6fSEmil Renner Berthing TH1520_PAD(4, QSPI1_D2_WP, QSPI, ISO, UART, GPIO, FUSE, ____, 0), 211*bed5cd6fSEmil Renner Berthing TH1520_PAD(5, QSPI1_D3_HOLD, QSPI, ISO, UART, GPIO, ____, ____, 0), 212*bed5cd6fSEmil Renner Berthing TH1520_PAD(6, I2C0_SCL, I2C, ____, ____, GPIO, ____, ____, 0), 213*bed5cd6fSEmil Renner Berthing TH1520_PAD(7, I2C0_SDA, I2C, ____, ____, GPIO, ____, ____, 0), 214*bed5cd6fSEmil Renner Berthing TH1520_PAD(8, I2C1_SCL, I2C, ____, ____, GPIO, ____, ____, 0), 215*bed5cd6fSEmil Renner Berthing TH1520_PAD(9, I2C1_SDA, I2C, ____, ____, GPIO, ____, ____, 0), 216*bed5cd6fSEmil Renner Berthing TH1520_PAD(10, UART1_TXD, UART, ____, ____, GPIO, ____, ____, 0), 217*bed5cd6fSEmil Renner Berthing TH1520_PAD(11, UART1_RXD, UART, ____, ____, GPIO, ____, ____, 0), 218*bed5cd6fSEmil Renner Berthing TH1520_PAD(12, UART4_TXD, UART, ____, ____, GPIO, ____, ____, 0), 219*bed5cd6fSEmil Renner Berthing TH1520_PAD(13, UART4_RXD, UART, ____, ____, GPIO, ____, ____, 0), 220*bed5cd6fSEmil Renner Berthing TH1520_PAD(14, UART4_CTSN, UART, ____, ____, GPIO, ____, ____, 0), 221*bed5cd6fSEmil Renner Berthing TH1520_PAD(15, UART4_RTSN, UART, ____, ____, GPIO, ____, ____, 0), 222*bed5cd6fSEmil Renner Berthing TH1520_PAD(16, UART3_TXD, DBG, UART, ____, GPIO, ____, ____, 0), 223*bed5cd6fSEmil Renner Berthing TH1520_PAD(17, UART3_RXD, DBG, UART, ____, GPIO, ____, ____, 0), 224*bed5cd6fSEmil Renner Berthing TH1520_PAD(18, GPIO0_18, GPIO, I2C, ____, ____, ____, ____, 0), 225*bed5cd6fSEmil Renner Berthing TH1520_PAD(19, GPIO0_19, GPIO, I2C, ____, ____, ____, ____, 0), 226*bed5cd6fSEmil Renner Berthing TH1520_PAD(20, GPIO0_20, GPIO, UART, IR, ____, ____, ____, 0), 227*bed5cd6fSEmil Renner Berthing TH1520_PAD(21, GPIO0_21, GPIO, UART, IR, ____, DPU0, DPU1, 0), 228*bed5cd6fSEmil Renner Berthing TH1520_PAD(22, GPIO0_22, GPIO, JTAG, I2C, ____, DPU0, DPU1, 0), 229*bed5cd6fSEmil Renner Berthing TH1520_PAD(23, GPIO0_23, GPIO, JTAG, I2C, ____, DPU0, DPU1, 0), 230*bed5cd6fSEmil Renner Berthing TH1520_PAD(24, GPIO0_24, GPIO, JTAG, QSPI, ____, DPU0, DPU1, 0), 231*bed5cd6fSEmil Renner Berthing TH1520_PAD(25, GPIO0_25, GPIO, JTAG, ____, ____, DPU0, DPU1, 0), 232*bed5cd6fSEmil Renner Berthing TH1520_PAD(26, GPIO0_26, GPIO, JTAG, ____, ____, DPU0, DPU1, 0), 233*bed5cd6fSEmil Renner Berthing TH1520_PAD(27, GPIO0_27, GPIO, ____, I2C, ____, DPU0, DPU1, 0), 234*bed5cd6fSEmil Renner Berthing TH1520_PAD(28, GPIO0_28, GPIO, ____, I2C, ____, DPU0, DPU1, 0), 235*bed5cd6fSEmil Renner Berthing TH1520_PAD(29, GPIO0_29, GPIO, ____, ____, ____, DPU0, DPU1, 0), 236*bed5cd6fSEmil Renner Berthing TH1520_PAD(30, GPIO0_30, GPIO, ____, ____, ____, DPU0, DPU1, 0), 237*bed5cd6fSEmil Renner Berthing TH1520_PAD(31, GPIO0_31, GPIO, ____, ____, ____, DPU0, DPU1, 0), 238*bed5cd6fSEmil Renner Berthing TH1520_PAD(32, GPIO1_0, GPIO, JTAG, ____, ____, DPU0, DPU1, 0), 239*bed5cd6fSEmil Renner Berthing TH1520_PAD(33, GPIO1_1, GPIO, JTAG, ____, ____, DPU0, DPU1, 0), 240*bed5cd6fSEmil Renner Berthing TH1520_PAD(34, GPIO1_2, GPIO, JTAG, ____, ____, DPU0, DPU1, 0), 241*bed5cd6fSEmil Renner Berthing TH1520_PAD(35, GPIO1_3, GPIO, JTAG, ____, ____, DPU0, DPU1, 0), 242*bed5cd6fSEmil Renner Berthing TH1520_PAD(36, GPIO1_4, GPIO, JTAG, ____, ____, DPU0, DPU1, 0), 243*bed5cd6fSEmil Renner Berthing TH1520_PAD(37, GPIO1_5, GPIO, ____, ____, ____, DPU0, DPU1, 0), 244*bed5cd6fSEmil Renner Berthing TH1520_PAD(38, GPIO1_6, GPIO, ____, ____, ____, DPU0, DPU1, 0), 245*bed5cd6fSEmil Renner Berthing TH1520_PAD(39, GPIO1_7, GPIO, QSPI, ____, ____, DPU0, DPU1, 0), 246*bed5cd6fSEmil Renner Berthing TH1520_PAD(40, GPIO1_8, GPIO, QSPI, ____, ____, DPU0, DPU1, 0), 247*bed5cd6fSEmil Renner Berthing TH1520_PAD(41, GPIO1_9, GPIO, QSPI, ____, ____, DPU0, DPU1, 0), 248*bed5cd6fSEmil Renner Berthing TH1520_PAD(42, GPIO1_10, GPIO, QSPI, ____, ____, DPU0, DPU1, 0), 249*bed5cd6fSEmil Renner Berthing TH1520_PAD(43, GPIO1_11, GPIO, QSPI, ____, ____, DPU0, DPU1, 0), 250*bed5cd6fSEmil Renner Berthing TH1520_PAD(44, GPIO1_12, GPIO, QSPI, ____, ____, DPU0, DPU1, 0), 251*bed5cd6fSEmil Renner Berthing TH1520_PAD(45, GPIO1_13, GPIO, UART, ____, ____, DPU0, DPU1, 0), 252*bed5cd6fSEmil Renner Berthing TH1520_PAD(46, GPIO1_14, GPIO, UART, ____, ____, DPU0, DPU1, 0), 253*bed5cd6fSEmil Renner Berthing TH1520_PAD(47, GPIO1_15, GPIO, UART, ____, ____, DPU0, DPU1, 0), 254*bed5cd6fSEmil Renner Berthing TH1520_PAD(48, GPIO1_16, GPIO, UART, ____, ____, DPU0, DPU1, 0), 255*bed5cd6fSEmil Renner Berthing TH1520_PAD(49, CLK_OUT_0, BSEL, CLK, ____, GPIO, ____, ____, 0), 256*bed5cd6fSEmil Renner Berthing TH1520_PAD(50, CLK_OUT_1, BSEL, CLK, ____, GPIO, ____, ____, 0), 257*bed5cd6fSEmil Renner Berthing TH1520_PAD(51, CLK_OUT_2, BSEL, CLK, ____, GPIO, ____, ____, 0), 258*bed5cd6fSEmil Renner Berthing TH1520_PAD(52, CLK_OUT_3, BSEL, CLK, ____, GPIO, ____, ____, 0), 259*bed5cd6fSEmil Renner Berthing TH1520_PAD(53, GPIO1_21, GPIO, ____, ISP, ____, ____, ____, 0), 260*bed5cd6fSEmil Renner Berthing TH1520_PAD(54, GPIO1_22, GPIO, ____, ISP, ____, ____, ____, 0), 261*bed5cd6fSEmil Renner Berthing TH1520_PAD(55, GPIO1_23, GPIO, ____, ISP, ____, ____, ____, 0), 262*bed5cd6fSEmil Renner Berthing TH1520_PAD(56, GPIO1_24, GPIO, ____, ISP, ____, ____, ____, 0), 263*bed5cd6fSEmil Renner Berthing TH1520_PAD(57, GPIO1_25, GPIO, ____, ISP, ____, ____, ____, 0), 264*bed5cd6fSEmil Renner Berthing TH1520_PAD(58, GPIO1_26, GPIO, ____, ISP, ____, ____, ____, 0), 265*bed5cd6fSEmil Renner Berthing TH1520_PAD(59, GPIO1_27, GPIO, ____, ISP, ____, ____, ____, 0), 266*bed5cd6fSEmil Renner Berthing TH1520_PAD(60, GPIO1_28, GPIO, ____, ISP, ____, ____, ____, 0), 267*bed5cd6fSEmil Renner Berthing TH1520_PAD(61, GPIO1_29, GPIO, ____, ISP, ____, ____, ____, 0), 268*bed5cd6fSEmil Renner Berthing TH1520_PAD(62, GPIO1_30, GPIO, ____, ISP, ____, ____, ____, 0), 269*bed5cd6fSEmil Renner Berthing }; 270*bed5cd6fSEmil Renner Berthing 271*bed5cd6fSEmil Renner Berthing static const struct pinctrl_pin_desc th1520_group3_pins[] = { 272*bed5cd6fSEmil Renner Berthing TH1520_PAD(0, UART0_TXD, UART, ____, ____, GPIO, ____, ____, 0), 273*bed5cd6fSEmil Renner Berthing TH1520_PAD(1, UART0_RXD, UART, ____, ____, GPIO, ____, ____, 0), 274*bed5cd6fSEmil Renner Berthing TH1520_PAD(2, QSPI0_SCLK, QSPI, PWM, I2S, GPIO, ____, ____, 0), 275*bed5cd6fSEmil Renner Berthing TH1520_PAD(3, QSPI0_CSN0, QSPI, PWM, I2S, GPIO, ____, ____, 0), 276*bed5cd6fSEmil Renner Berthing TH1520_PAD(4, QSPI0_CSN1, QSPI, PWM, I2S, GPIO, ____, ____, 0), 277*bed5cd6fSEmil Renner Berthing TH1520_PAD(5, QSPI0_D0_MOSI, QSPI, PWM, I2S, GPIO, ____, ____, 0), 278*bed5cd6fSEmil Renner Berthing TH1520_PAD(6, QSPI0_D1_MISO, QSPI, PWM, I2S, GPIO, ____, ____, 0), 279*bed5cd6fSEmil Renner Berthing TH1520_PAD(7, QSPI0_D2_WP, QSPI, PWM, I2S, GPIO, ____, ____, 0), 280*bed5cd6fSEmil Renner Berthing TH1520_PAD(8, QSPI1_D3_HOLD, QSPI, ____, I2S, GPIO, ____, ____, 0), 281*bed5cd6fSEmil Renner Berthing TH1520_PAD(9, I2C2_SCL, I2C, UART, ____, GPIO, ____, ____, 0), 282*bed5cd6fSEmil Renner Berthing TH1520_PAD(10, I2C2_SDA, I2C, UART, ____, GPIO, ____, ____, 0), 283*bed5cd6fSEmil Renner Berthing TH1520_PAD(11, I2C3_SCL, I2C, ____, ____, GPIO, ____, ____, 0), 284*bed5cd6fSEmil Renner Berthing TH1520_PAD(12, I2C3_SDA, I2C, ____, ____, GPIO, ____, ____, 0), 285*bed5cd6fSEmil Renner Berthing TH1520_PAD(13, GPIO2_13, GPIO, SPI, ____, ____, ____, ____, 0), 286*bed5cd6fSEmil Renner Berthing TH1520_PAD(14, SPI_SCLK, SPI, UART, IR, GPIO, ____, ____, 0), 287*bed5cd6fSEmil Renner Berthing TH1520_PAD(15, SPI_CSN, SPI, UART, IR, GPIO, ____, ____, 0), 288*bed5cd6fSEmil Renner Berthing TH1520_PAD(16, SPI_MOSI, SPI, ____, ____, GPIO, ____, ____, 0), 289*bed5cd6fSEmil Renner Berthing TH1520_PAD(17, SPI_MISO, SPI, ____, ____, GPIO, ____, ____, 0), 290*bed5cd6fSEmil Renner Berthing TH1520_PAD(18, GPIO2_18, GPIO, MAC1, ____, ____, ____, ____, 0), 291*bed5cd6fSEmil Renner Berthing TH1520_PAD(19, GPIO2_19, GPIO, MAC1, ____, ____, ____, ____, 0), 292*bed5cd6fSEmil Renner Berthing TH1520_PAD(20, GPIO2_20, GPIO, MAC1, ____, ____, ____, ____, 0), 293*bed5cd6fSEmil Renner Berthing TH1520_PAD(21, GPIO2_21, GPIO, MAC1, ____, ____, ____, ____, 0), 294*bed5cd6fSEmil Renner Berthing TH1520_PAD(22, GPIO2_22, GPIO, MAC1, ____, ____, ____, ____, 0), 295*bed5cd6fSEmil Renner Berthing TH1520_PAD(23, GPIO2_23, GPIO, MAC1, ____, ____, ____, ____, 0), 296*bed5cd6fSEmil Renner Berthing TH1520_PAD(24, GPIO2_24, GPIO, MAC1, ____, ____, ____, ____, 0), 297*bed5cd6fSEmil Renner Berthing TH1520_PAD(25, GPIO2_25, GPIO, MAC1, ____, ____, ____, ____, 0), 298*bed5cd6fSEmil Renner Berthing TH1520_PAD(26, SDIO0_WPRTN, SDIO, ____, ____, GPIO, ____, ____, 0), 299*bed5cd6fSEmil Renner Berthing TH1520_PAD(27, SDIO0_DETN, SDIO, ____, ____, GPIO, ____, ____, 0), 300*bed5cd6fSEmil Renner Berthing TH1520_PAD(28, SDIO1_WPRTN, SDIO, ____, ____, GPIO, ____, ____, 0), 301*bed5cd6fSEmil Renner Berthing TH1520_PAD(29, SDIO1_DETN, SDIO, ____, ____, GPIO, ____, ____, 0), 302*bed5cd6fSEmil Renner Berthing TH1520_PAD(30, GPIO2_30, GPIO, MAC1, ____, ____, ____, ____, 0), 303*bed5cd6fSEmil Renner Berthing TH1520_PAD(31, GPIO2_31, GPIO, MAC1, ____, ____, ____, ____, 0), 304*bed5cd6fSEmil Renner Berthing TH1520_PAD(32, GPIO3_0, GPIO, MAC1, ____, ____, ____, ____, 0), 305*bed5cd6fSEmil Renner Berthing TH1520_PAD(33, GPIO3_1, GPIO, MAC1, ____, ____, ____, ____, 0), 306*bed5cd6fSEmil Renner Berthing TH1520_PAD(34, GPIO3_2, GPIO, PWM, ____, ____, ____, ____, 0), 307*bed5cd6fSEmil Renner Berthing TH1520_PAD(35, GPIO3_3, GPIO, PWM, ____, ____, ____, ____, 0), 308*bed5cd6fSEmil Renner Berthing TH1520_PAD(36, HDMI_SCL, HDMI, PWM, ____, GPIO, ____, ____, 0), 309*bed5cd6fSEmil Renner Berthing TH1520_PAD(37, HDMI_SDA, HDMI, PWM, ____, GPIO, ____, ____, 0), 310*bed5cd6fSEmil Renner Berthing TH1520_PAD(38, HDMI_CEC, HDMI, ____, ____, GPIO, ____, ____, 0), 311*bed5cd6fSEmil Renner Berthing TH1520_PAD(39, GMAC0_TX_CLK, MAC0, ____, ____, GPIO, ____, ____, 0), 312*bed5cd6fSEmil Renner Berthing TH1520_PAD(40, GMAC0_RX_CLK, MAC0, ____, ____, GPIO, ____, ____, 0), 313*bed5cd6fSEmil Renner Berthing TH1520_PAD(41, GMAC0_TXEN, MAC0, UART, ____, GPIO, ____, ____, 0), 314*bed5cd6fSEmil Renner Berthing TH1520_PAD(42, GMAC0_TXD0, MAC0, UART, ____, GPIO, ____, ____, 0), 315*bed5cd6fSEmil Renner Berthing TH1520_PAD(43, GMAC0_TXD1, MAC0, UART, ____, GPIO, ____, ____, 0), 316*bed5cd6fSEmil Renner Berthing TH1520_PAD(44, GMAC0_TXD2, MAC0, UART, ____, GPIO, ____, ____, 0), 317*bed5cd6fSEmil Renner Berthing TH1520_PAD(45, GMAC0_TXD3, MAC0, I2C, ____, GPIO, ____, ____, 0), 318*bed5cd6fSEmil Renner Berthing TH1520_PAD(46, GMAC0_RXDV, MAC0, I2C, ____, GPIO, ____, ____, 0), 319*bed5cd6fSEmil Renner Berthing TH1520_PAD(47, GMAC0_RXD0, MAC0, I2C, ____, GPIO, ____, ____, 0), 320*bed5cd6fSEmil Renner Berthing TH1520_PAD(48, GMAC0_RXD1, MAC0, I2C, ____, GPIO, ____, ____, 0), 321*bed5cd6fSEmil Renner Berthing TH1520_PAD(49, GMAC0_RXD2, MAC0, SPI, ____, GPIO, ____, ____, 0), 322*bed5cd6fSEmil Renner Berthing TH1520_PAD(50, GMAC0_RXD3, MAC0, SPI, ____, GPIO, ____, ____, 0), 323*bed5cd6fSEmil Renner Berthing TH1520_PAD(51, GMAC0_MDC, MAC0, SPI, MAC1, GPIO, ____, ____, 0), 324*bed5cd6fSEmil Renner Berthing TH1520_PAD(52, GMAC0_MDIO, MAC0, SPI, MAC1, GPIO, ____, ____, 0), 325*bed5cd6fSEmil Renner Berthing TH1520_PAD(53, GMAC0_COL, MAC0, PWM, ____, GPIO, ____, ____, 0), 326*bed5cd6fSEmil Renner Berthing TH1520_PAD(54, GMAC0_CRS, MAC0, PWM, ____, GPIO, ____, ____, 0), 327*bed5cd6fSEmil Renner Berthing }; 328*bed5cd6fSEmil Renner Berthing 329*bed5cd6fSEmil Renner Berthing static const struct th1520_pad_group th1520_group1 = { 330*bed5cd6fSEmil Renner Berthing .name = "th1520-group1", 331*bed5cd6fSEmil Renner Berthing .pins = th1520_group1_pins, 332*bed5cd6fSEmil Renner Berthing .npins = ARRAY_SIZE(th1520_group1_pins), 333*bed5cd6fSEmil Renner Berthing }; 334*bed5cd6fSEmil Renner Berthing 335*bed5cd6fSEmil Renner Berthing static const struct th1520_pad_group th1520_group2 = { 336*bed5cd6fSEmil Renner Berthing .name = "th1520-group2", 337*bed5cd6fSEmil Renner Berthing .pins = th1520_group2_pins, 338*bed5cd6fSEmil Renner Berthing .npins = ARRAY_SIZE(th1520_group2_pins), 339*bed5cd6fSEmil Renner Berthing }; 340*bed5cd6fSEmil Renner Berthing 341*bed5cd6fSEmil Renner Berthing static const struct th1520_pad_group th1520_group3 = { 342*bed5cd6fSEmil Renner Berthing .name = "th1520-group3", 343*bed5cd6fSEmil Renner Berthing .pins = th1520_group3_pins, 344*bed5cd6fSEmil Renner Berthing .npins = ARRAY_SIZE(th1520_group3_pins), 345*bed5cd6fSEmil Renner Berthing }; 346*bed5cd6fSEmil Renner Berthing 347*bed5cd6fSEmil Renner Berthing static int th1520_pinctrl_get_groups_count(struct pinctrl_dev *pctldev) 348*bed5cd6fSEmil Renner Berthing { 349*bed5cd6fSEmil Renner Berthing struct th1520_pinctrl *thp = pinctrl_dev_get_drvdata(pctldev); 350*bed5cd6fSEmil Renner Berthing 351*bed5cd6fSEmil Renner Berthing return thp->desc.npins; 352*bed5cd6fSEmil Renner Berthing } 353*bed5cd6fSEmil Renner Berthing 354*bed5cd6fSEmil Renner Berthing static const char *th1520_pinctrl_get_group_name(struct pinctrl_dev *pctldev, 355*bed5cd6fSEmil Renner Berthing unsigned int gsel) 356*bed5cd6fSEmil Renner Berthing { 357*bed5cd6fSEmil Renner Berthing struct th1520_pinctrl *thp = pinctrl_dev_get_drvdata(pctldev); 358*bed5cd6fSEmil Renner Berthing 359*bed5cd6fSEmil Renner Berthing return thp->desc.pins[gsel].name; 360*bed5cd6fSEmil Renner Berthing } 361*bed5cd6fSEmil Renner Berthing 362*bed5cd6fSEmil Renner Berthing static int th1520_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, 363*bed5cd6fSEmil Renner Berthing unsigned int gsel, 364*bed5cd6fSEmil Renner Berthing const unsigned int **pins, 365*bed5cd6fSEmil Renner Berthing unsigned int *npins) 366*bed5cd6fSEmil Renner Berthing { 367*bed5cd6fSEmil Renner Berthing struct th1520_pinctrl *thp = pinctrl_dev_get_drvdata(pctldev); 368*bed5cd6fSEmil Renner Berthing 369*bed5cd6fSEmil Renner Berthing *pins = &thp->desc.pins[gsel].number; 370*bed5cd6fSEmil Renner Berthing *npins = 1; 371*bed5cd6fSEmil Renner Berthing return 0; 372*bed5cd6fSEmil Renner Berthing } 373*bed5cd6fSEmil Renner Berthing 374*bed5cd6fSEmil Renner Berthing #ifdef CONFIG_DEBUG_FS 375*bed5cd6fSEmil Renner Berthing static void th1520_pin_dbg_show(struct pinctrl_dev *pctldev, 376*bed5cd6fSEmil Renner Berthing struct seq_file *s, unsigned int pin) 377*bed5cd6fSEmil Renner Berthing { 378*bed5cd6fSEmil Renner Berthing struct th1520_pinctrl *thp = pinctrl_dev_get_drvdata(pctldev); 379*bed5cd6fSEmil Renner Berthing void __iomem *padcfg = th1520_padcfg(thp, pin); 380*bed5cd6fSEmil Renner Berthing void __iomem *muxcfg = th1520_muxcfg(thp, pin); 381*bed5cd6fSEmil Renner Berthing u32 pad; 382*bed5cd6fSEmil Renner Berthing u32 mux; 383*bed5cd6fSEmil Renner Berthing 384*bed5cd6fSEmil Renner Berthing scoped_guard(raw_spinlock_irqsave, &thp->lock) { 385*bed5cd6fSEmil Renner Berthing pad = readl_relaxed(padcfg); 386*bed5cd6fSEmil Renner Berthing mux = readl_relaxed(muxcfg); 387*bed5cd6fSEmil Renner Berthing } 388*bed5cd6fSEmil Renner Berthing 389*bed5cd6fSEmil Renner Berthing seq_printf(s, "[PADCFG_%03u:0x%x=0x%07x MUXCFG_%03u:0x%x=0x%08x]", 390*bed5cd6fSEmil Renner Berthing 1 + pin / 2, 0x000 + 4 * (pin / 2), pad, 391*bed5cd6fSEmil Renner Berthing 1 + pin / 8, 0x400 + 4 * (pin / 8), mux); 392*bed5cd6fSEmil Renner Berthing } 393*bed5cd6fSEmil Renner Berthing #else 394*bed5cd6fSEmil Renner Berthing #define th1520_pin_dbg_show NULL 395*bed5cd6fSEmil Renner Berthing #endif 396*bed5cd6fSEmil Renner Berthing 397*bed5cd6fSEmil Renner Berthing static void th1520_pinctrl_dt_free_map(struct pinctrl_dev *pctldev, 398*bed5cd6fSEmil Renner Berthing struct pinctrl_map *map, unsigned int nmaps) 399*bed5cd6fSEmil Renner Berthing { 400*bed5cd6fSEmil Renner Berthing unsigned long *seen = NULL; 401*bed5cd6fSEmil Renner Berthing unsigned int i; 402*bed5cd6fSEmil Renner Berthing 403*bed5cd6fSEmil Renner Berthing for (i = 0; i < nmaps; i++) { 404*bed5cd6fSEmil Renner Berthing if (map[i].type == PIN_MAP_TYPE_CONFIGS_PIN && 405*bed5cd6fSEmil Renner Berthing map[i].data.configs.configs != seen) { 406*bed5cd6fSEmil Renner Berthing seen = map[i].data.configs.configs; 407*bed5cd6fSEmil Renner Berthing kfree(seen); 408*bed5cd6fSEmil Renner Berthing } 409*bed5cd6fSEmil Renner Berthing } 410*bed5cd6fSEmil Renner Berthing 411*bed5cd6fSEmil Renner Berthing kfree(map); 412*bed5cd6fSEmil Renner Berthing } 413*bed5cd6fSEmil Renner Berthing 414*bed5cd6fSEmil Renner Berthing static int th1520_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev, 415*bed5cd6fSEmil Renner Berthing struct device_node *np, 416*bed5cd6fSEmil Renner Berthing struct pinctrl_map **maps, 417*bed5cd6fSEmil Renner Berthing unsigned int *num_maps) 418*bed5cd6fSEmil Renner Berthing { 419*bed5cd6fSEmil Renner Berthing struct th1520_pinctrl *thp = pinctrl_dev_get_drvdata(pctldev); 420*bed5cd6fSEmil Renner Berthing struct device_node *child; 421*bed5cd6fSEmil Renner Berthing struct pinctrl_map *map; 422*bed5cd6fSEmil Renner Berthing unsigned long *configs; 423*bed5cd6fSEmil Renner Berthing unsigned int nconfigs; 424*bed5cd6fSEmil Renner Berthing unsigned int nmaps; 425*bed5cd6fSEmil Renner Berthing int ret; 426*bed5cd6fSEmil Renner Berthing 427*bed5cd6fSEmil Renner Berthing nmaps = 0; 428*bed5cd6fSEmil Renner Berthing for_each_available_child_of_node(np, child) { 429*bed5cd6fSEmil Renner Berthing int npins = of_property_count_strings(child, "pins"); 430*bed5cd6fSEmil Renner Berthing 431*bed5cd6fSEmil Renner Berthing if (npins <= 0) { 432*bed5cd6fSEmil Renner Berthing of_node_put(child); 433*bed5cd6fSEmil Renner Berthing dev_err(thp->pctl->dev, "no pins selected for %pOFn.%pOFn\n", 434*bed5cd6fSEmil Renner Berthing np, child); 435*bed5cd6fSEmil Renner Berthing return -EINVAL; 436*bed5cd6fSEmil Renner Berthing } 437*bed5cd6fSEmil Renner Berthing nmaps += npins; 438*bed5cd6fSEmil Renner Berthing if (of_property_present(child, "function")) 439*bed5cd6fSEmil Renner Berthing nmaps += npins; 440*bed5cd6fSEmil Renner Berthing } 441*bed5cd6fSEmil Renner Berthing 442*bed5cd6fSEmil Renner Berthing map = kcalloc(nmaps, sizeof(*map), GFP_KERNEL); 443*bed5cd6fSEmil Renner Berthing if (!map) 444*bed5cd6fSEmil Renner Berthing return -ENOMEM; 445*bed5cd6fSEmil Renner Berthing 446*bed5cd6fSEmil Renner Berthing nmaps = 0; 447*bed5cd6fSEmil Renner Berthing mutex_lock(&thp->mutex); 448*bed5cd6fSEmil Renner Berthing for_each_available_child_of_node(np, child) { 449*bed5cd6fSEmil Renner Berthing unsigned int rollback = nmaps; 450*bed5cd6fSEmil Renner Berthing enum th1520_muxtype muxtype; 451*bed5cd6fSEmil Renner Berthing struct property *prop; 452*bed5cd6fSEmil Renner Berthing const char *funcname; 453*bed5cd6fSEmil Renner Berthing const char **pgnames; 454*bed5cd6fSEmil Renner Berthing const char *pinname; 455*bed5cd6fSEmil Renner Berthing int npins; 456*bed5cd6fSEmil Renner Berthing 457*bed5cd6fSEmil Renner Berthing ret = pinconf_generic_parse_dt_config(child, pctldev, &configs, &nconfigs); 458*bed5cd6fSEmil Renner Berthing if (ret) { 459*bed5cd6fSEmil Renner Berthing dev_err(thp->pctl->dev, "%pOFn.%pOFn: error parsing pin config\n", 460*bed5cd6fSEmil Renner Berthing np, child); 461*bed5cd6fSEmil Renner Berthing goto put_child; 462*bed5cd6fSEmil Renner Berthing } 463*bed5cd6fSEmil Renner Berthing 464*bed5cd6fSEmil Renner Berthing if (!of_property_read_string(child, "function", &funcname)) { 465*bed5cd6fSEmil Renner Berthing muxtype = th1520_muxtype_get(funcname); 466*bed5cd6fSEmil Renner Berthing if (!muxtype) { 467*bed5cd6fSEmil Renner Berthing dev_err(thp->pctl->dev, "%pOFn.%pOFn: unknown function '%s'\n", 468*bed5cd6fSEmil Renner Berthing np, child, funcname); 469*bed5cd6fSEmil Renner Berthing ret = -EINVAL; 470*bed5cd6fSEmil Renner Berthing goto free_configs; 471*bed5cd6fSEmil Renner Berthing } 472*bed5cd6fSEmil Renner Berthing 473*bed5cd6fSEmil Renner Berthing funcname = devm_kasprintf(thp->pctl->dev, GFP_KERNEL, "%pOFn.%pOFn", 474*bed5cd6fSEmil Renner Berthing np, child); 475*bed5cd6fSEmil Renner Berthing if (!funcname) { 476*bed5cd6fSEmil Renner Berthing ret = -ENOMEM; 477*bed5cd6fSEmil Renner Berthing goto free_configs; 478*bed5cd6fSEmil Renner Berthing } 479*bed5cd6fSEmil Renner Berthing 480*bed5cd6fSEmil Renner Berthing npins = of_property_count_strings(child, "pins"); 481*bed5cd6fSEmil Renner Berthing pgnames = devm_kcalloc(thp->pctl->dev, npins, sizeof(*pgnames), GFP_KERNEL); 482*bed5cd6fSEmil Renner Berthing if (!pgnames) { 483*bed5cd6fSEmil Renner Berthing ret = -ENOMEM; 484*bed5cd6fSEmil Renner Berthing goto free_configs; 485*bed5cd6fSEmil Renner Berthing } 486*bed5cd6fSEmil Renner Berthing } else { 487*bed5cd6fSEmil Renner Berthing funcname = NULL; 488*bed5cd6fSEmil Renner Berthing } 489*bed5cd6fSEmil Renner Berthing 490*bed5cd6fSEmil Renner Berthing npins = 0; 491*bed5cd6fSEmil Renner Berthing of_property_for_each_string(child, "pins", prop, pinname) { 492*bed5cd6fSEmil Renner Berthing unsigned int i; 493*bed5cd6fSEmil Renner Berthing 494*bed5cd6fSEmil Renner Berthing for (i = 0; i < thp->desc.npins; i++) { 495*bed5cd6fSEmil Renner Berthing if (!strcmp(pinname, thp->desc.pins[i].name)) 496*bed5cd6fSEmil Renner Berthing break; 497*bed5cd6fSEmil Renner Berthing } 498*bed5cd6fSEmil Renner Berthing if (i == thp->desc.npins) { 499*bed5cd6fSEmil Renner Berthing nmaps = rollback; 500*bed5cd6fSEmil Renner Berthing dev_err(thp->pctl->dev, "%pOFn.%pOFn: unknown pin '%s'\n", 501*bed5cd6fSEmil Renner Berthing np, child, pinname); 502*bed5cd6fSEmil Renner Berthing goto free_configs; 503*bed5cd6fSEmil Renner Berthing } 504*bed5cd6fSEmil Renner Berthing 505*bed5cd6fSEmil Renner Berthing if (nconfigs) { 506*bed5cd6fSEmil Renner Berthing map[nmaps].type = PIN_MAP_TYPE_CONFIGS_PIN; 507*bed5cd6fSEmil Renner Berthing map[nmaps].data.configs.group_or_pin = thp->desc.pins[i].name; 508*bed5cd6fSEmil Renner Berthing map[nmaps].data.configs.configs = configs; 509*bed5cd6fSEmil Renner Berthing map[nmaps].data.configs.num_configs = nconfigs; 510*bed5cd6fSEmil Renner Berthing nmaps += 1; 511*bed5cd6fSEmil Renner Berthing } 512*bed5cd6fSEmil Renner Berthing if (funcname) { 513*bed5cd6fSEmil Renner Berthing pgnames[npins++] = thp->desc.pins[i].name; 514*bed5cd6fSEmil Renner Berthing map[nmaps].type = PIN_MAP_TYPE_MUX_GROUP; 515*bed5cd6fSEmil Renner Berthing map[nmaps].data.mux.function = funcname; 516*bed5cd6fSEmil Renner Berthing map[nmaps].data.mux.group = thp->desc.pins[i].name; 517*bed5cd6fSEmil Renner Berthing nmaps += 1; 518*bed5cd6fSEmil Renner Berthing } 519*bed5cd6fSEmil Renner Berthing } 520*bed5cd6fSEmil Renner Berthing 521*bed5cd6fSEmil Renner Berthing if (funcname) { 522*bed5cd6fSEmil Renner Berthing ret = pinmux_generic_add_function(pctldev, funcname, pgnames, 523*bed5cd6fSEmil Renner Berthing npins, (void *)muxtype); 524*bed5cd6fSEmil Renner Berthing if (ret < 0) { 525*bed5cd6fSEmil Renner Berthing dev_err(thp->pctl->dev, "error adding function %s\n", funcname); 526*bed5cd6fSEmil Renner Berthing goto put_child; 527*bed5cd6fSEmil Renner Berthing } 528*bed5cd6fSEmil Renner Berthing } 529*bed5cd6fSEmil Renner Berthing } 530*bed5cd6fSEmil Renner Berthing 531*bed5cd6fSEmil Renner Berthing *maps = map; 532*bed5cd6fSEmil Renner Berthing *num_maps = nmaps; 533*bed5cd6fSEmil Renner Berthing mutex_unlock(&thp->mutex); 534*bed5cd6fSEmil Renner Berthing return 0; 535*bed5cd6fSEmil Renner Berthing 536*bed5cd6fSEmil Renner Berthing free_configs: 537*bed5cd6fSEmil Renner Berthing kfree(configs); 538*bed5cd6fSEmil Renner Berthing put_child: 539*bed5cd6fSEmil Renner Berthing of_node_put(child); 540*bed5cd6fSEmil Renner Berthing th1520_pinctrl_dt_free_map(pctldev, map, nmaps); 541*bed5cd6fSEmil Renner Berthing mutex_unlock(&thp->mutex); 542*bed5cd6fSEmil Renner Berthing return ret; 543*bed5cd6fSEmil Renner Berthing } 544*bed5cd6fSEmil Renner Berthing 545*bed5cd6fSEmil Renner Berthing static const struct pinctrl_ops th1520_pinctrl_ops = { 546*bed5cd6fSEmil Renner Berthing .get_groups_count = th1520_pinctrl_get_groups_count, 547*bed5cd6fSEmil Renner Berthing .get_group_name = th1520_pinctrl_get_group_name, 548*bed5cd6fSEmil Renner Berthing .get_group_pins = th1520_pinctrl_get_group_pins, 549*bed5cd6fSEmil Renner Berthing .pin_dbg_show = th1520_pin_dbg_show, 550*bed5cd6fSEmil Renner Berthing .dt_node_to_map = th1520_pinctrl_dt_node_to_map, 551*bed5cd6fSEmil Renner Berthing .dt_free_map = th1520_pinctrl_dt_free_map, 552*bed5cd6fSEmil Renner Berthing }; 553*bed5cd6fSEmil Renner Berthing 554*bed5cd6fSEmil Renner Berthing static const u8 th1520_drive_strength_in_ma[16] = { 555*bed5cd6fSEmil Renner Berthing 1, 2, 3, 5, 7, 8, 10, 12, 13, 15, 16, 18, 20, 21, 23, 25, 556*bed5cd6fSEmil Renner Berthing }; 557*bed5cd6fSEmil Renner Berthing 558*bed5cd6fSEmil Renner Berthing static u16 th1520_drive_strength_from_ma(u32 arg) 559*bed5cd6fSEmil Renner Berthing { 560*bed5cd6fSEmil Renner Berthing u16 ds; 561*bed5cd6fSEmil Renner Berthing 562*bed5cd6fSEmil Renner Berthing for (ds = 0; ds < TH1520_PADCFG_DS; ds++) { 563*bed5cd6fSEmil Renner Berthing if (arg <= th1520_drive_strength_in_ma[ds]) 564*bed5cd6fSEmil Renner Berthing return ds; 565*bed5cd6fSEmil Renner Berthing } 566*bed5cd6fSEmil Renner Berthing return TH1520_PADCFG_DS; 567*bed5cd6fSEmil Renner Berthing } 568*bed5cd6fSEmil Renner Berthing 569*bed5cd6fSEmil Renner Berthing static int th1520_padcfg_rmw(struct th1520_pinctrl *thp, unsigned int pin, 570*bed5cd6fSEmil Renner Berthing u32 mask, u32 value) 571*bed5cd6fSEmil Renner Berthing { 572*bed5cd6fSEmil Renner Berthing void __iomem *padcfg = th1520_padcfg(thp, pin); 573*bed5cd6fSEmil Renner Berthing unsigned int shift = th1520_padcfg_shift(pin); 574*bed5cd6fSEmil Renner Berthing u32 tmp; 575*bed5cd6fSEmil Renner Berthing 576*bed5cd6fSEmil Renner Berthing mask <<= shift; 577*bed5cd6fSEmil Renner Berthing value <<= shift; 578*bed5cd6fSEmil Renner Berthing 579*bed5cd6fSEmil Renner Berthing scoped_guard(raw_spinlock_irqsave, &thp->lock) { 580*bed5cd6fSEmil Renner Berthing tmp = readl_relaxed(padcfg); 581*bed5cd6fSEmil Renner Berthing tmp = (tmp & ~mask) | value; 582*bed5cd6fSEmil Renner Berthing writel_relaxed(tmp, padcfg); 583*bed5cd6fSEmil Renner Berthing } 584*bed5cd6fSEmil Renner Berthing return 0; 585*bed5cd6fSEmil Renner Berthing } 586*bed5cd6fSEmil Renner Berthing 587*bed5cd6fSEmil Renner Berthing static int th1520_pinconf_get(struct pinctrl_dev *pctldev, 588*bed5cd6fSEmil Renner Berthing unsigned int pin, unsigned long *config) 589*bed5cd6fSEmil Renner Berthing { 590*bed5cd6fSEmil Renner Berthing struct th1520_pinctrl *thp = pinctrl_dev_get_drvdata(pctldev); 591*bed5cd6fSEmil Renner Berthing const struct pin_desc *desc = pin_desc_get(pctldev, pin); 592*bed5cd6fSEmil Renner Berthing bool enabled; 593*bed5cd6fSEmil Renner Berthing int param; 594*bed5cd6fSEmil Renner Berthing u32 value; 595*bed5cd6fSEmil Renner Berthing u32 arg; 596*bed5cd6fSEmil Renner Berthing 597*bed5cd6fSEmil Renner Berthing if ((uintptr_t)desc->drv_data & TH1520_PAD_NO_PADCFG) 598*bed5cd6fSEmil Renner Berthing return -EOPNOTSUPP; 599*bed5cd6fSEmil Renner Berthing 600*bed5cd6fSEmil Renner Berthing value = readl_relaxed(th1520_padcfg(thp, pin)); 601*bed5cd6fSEmil Renner Berthing value = (value >> th1520_padcfg_shift(pin)) & GENMASK(9, 0); 602*bed5cd6fSEmil Renner Berthing 603*bed5cd6fSEmil Renner Berthing param = pinconf_to_config_param(*config); 604*bed5cd6fSEmil Renner Berthing switch (param) { 605*bed5cd6fSEmil Renner Berthing case PIN_CONFIG_BIAS_DISABLE: 606*bed5cd6fSEmil Renner Berthing enabled = !(value & (TH1520_PADCFG_SPU | TH1520_PADCFG_PE)); 607*bed5cd6fSEmil Renner Berthing arg = 0; 608*bed5cd6fSEmil Renner Berthing break; 609*bed5cd6fSEmil Renner Berthing case PIN_CONFIG_BIAS_PULL_DOWN: 610*bed5cd6fSEmil Renner Berthing enabled = (value & TH1520_PADCFG_BIAS) == TH1520_PADCFG_PE; 611*bed5cd6fSEmil Renner Berthing arg = enabled ? TH1520_PULL_DOWN_OHM : 0; 612*bed5cd6fSEmil Renner Berthing break; 613*bed5cd6fSEmil Renner Berthing case PIN_CONFIG_BIAS_PULL_UP: 614*bed5cd6fSEmil Renner Berthing if (value & TH1520_PADCFG_SPU) { 615*bed5cd6fSEmil Renner Berthing enabled = true; 616*bed5cd6fSEmil Renner Berthing arg = TH1520_PULL_STRONG_OHM; 617*bed5cd6fSEmil Renner Berthing } else if ((value & (TH1520_PADCFG_PE | TH1520_PADCFG_PS)) == 618*bed5cd6fSEmil Renner Berthing (TH1520_PADCFG_PE | TH1520_PADCFG_PS)) { 619*bed5cd6fSEmil Renner Berthing enabled = true; 620*bed5cd6fSEmil Renner Berthing arg = TH1520_PULL_UP_OHM; 621*bed5cd6fSEmil Renner Berthing } else { 622*bed5cd6fSEmil Renner Berthing enabled = false; 623*bed5cd6fSEmil Renner Berthing arg = 0; 624*bed5cd6fSEmil Renner Berthing } 625*bed5cd6fSEmil Renner Berthing break; 626*bed5cd6fSEmil Renner Berthing case PIN_CONFIG_DRIVE_STRENGTH: 627*bed5cd6fSEmil Renner Berthing enabled = true; 628*bed5cd6fSEmil Renner Berthing arg = th1520_drive_strength_in_ma[value & TH1520_PADCFG_DS]; 629*bed5cd6fSEmil Renner Berthing break; 630*bed5cd6fSEmil Renner Berthing case PIN_CONFIG_INPUT_ENABLE: 631*bed5cd6fSEmil Renner Berthing enabled = value & TH1520_PADCFG_IE; 632*bed5cd6fSEmil Renner Berthing arg = enabled ? 1 : 0; 633*bed5cd6fSEmil Renner Berthing break; 634*bed5cd6fSEmil Renner Berthing case PIN_CONFIG_INPUT_SCHMITT_ENABLE: 635*bed5cd6fSEmil Renner Berthing enabled = value & TH1520_PADCFG_ST; 636*bed5cd6fSEmil Renner Berthing arg = enabled ? 1 : 0; 637*bed5cd6fSEmil Renner Berthing break; 638*bed5cd6fSEmil Renner Berthing case PIN_CONFIG_SLEW_RATE: 639*bed5cd6fSEmil Renner Berthing enabled = value & TH1520_PADCFG_SL; 640*bed5cd6fSEmil Renner Berthing arg = enabled ? 1 : 0; 641*bed5cd6fSEmil Renner Berthing break; 642*bed5cd6fSEmil Renner Berthing default: 643*bed5cd6fSEmil Renner Berthing return -EOPNOTSUPP; 644*bed5cd6fSEmil Renner Berthing } 645*bed5cd6fSEmil Renner Berthing 646*bed5cd6fSEmil Renner Berthing *config = pinconf_to_config_packed(param, arg); 647*bed5cd6fSEmil Renner Berthing return enabled ? 0 : -EINVAL; 648*bed5cd6fSEmil Renner Berthing } 649*bed5cd6fSEmil Renner Berthing 650*bed5cd6fSEmil Renner Berthing static int th1520_pinconf_group_get(struct pinctrl_dev *pctldev, 651*bed5cd6fSEmil Renner Berthing unsigned int gsel, unsigned long *config) 652*bed5cd6fSEmil Renner Berthing { 653*bed5cd6fSEmil Renner Berthing struct th1520_pinctrl *thp = pinctrl_dev_get_drvdata(pctldev); 654*bed5cd6fSEmil Renner Berthing unsigned int pin = thp->desc.pins[gsel].number; 655*bed5cd6fSEmil Renner Berthing 656*bed5cd6fSEmil Renner Berthing return th1520_pinconf_get(pctldev, pin, config); 657*bed5cd6fSEmil Renner Berthing } 658*bed5cd6fSEmil Renner Berthing 659*bed5cd6fSEmil Renner Berthing static int th1520_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, 660*bed5cd6fSEmil Renner Berthing unsigned long *configs, unsigned int num_configs) 661*bed5cd6fSEmil Renner Berthing { 662*bed5cd6fSEmil Renner Berthing struct th1520_pinctrl *thp = pinctrl_dev_get_drvdata(pctldev); 663*bed5cd6fSEmil Renner Berthing const struct pin_desc *desc = pin_desc_get(pctldev, pin); 664*bed5cd6fSEmil Renner Berthing unsigned int i; 665*bed5cd6fSEmil Renner Berthing u16 mask, value; 666*bed5cd6fSEmil Renner Berthing 667*bed5cd6fSEmil Renner Berthing if ((uintptr_t)desc->drv_data & TH1520_PAD_NO_PADCFG) 668*bed5cd6fSEmil Renner Berthing return -EOPNOTSUPP; 669*bed5cd6fSEmil Renner Berthing 670*bed5cd6fSEmil Renner Berthing mask = 0; 671*bed5cd6fSEmil Renner Berthing value = 0; 672*bed5cd6fSEmil Renner Berthing for (i = 0; i < num_configs; i++) { 673*bed5cd6fSEmil Renner Berthing int param = pinconf_to_config_param(configs[i]); 674*bed5cd6fSEmil Renner Berthing u32 arg = pinconf_to_config_argument(configs[i]); 675*bed5cd6fSEmil Renner Berthing 676*bed5cd6fSEmil Renner Berthing switch (param) { 677*bed5cd6fSEmil Renner Berthing case PIN_CONFIG_BIAS_DISABLE: 678*bed5cd6fSEmil Renner Berthing mask |= TH1520_PADCFG_BIAS; 679*bed5cd6fSEmil Renner Berthing value &= ~TH1520_PADCFG_BIAS; 680*bed5cd6fSEmil Renner Berthing break; 681*bed5cd6fSEmil Renner Berthing case PIN_CONFIG_BIAS_PULL_DOWN: 682*bed5cd6fSEmil Renner Berthing if (arg == 0) 683*bed5cd6fSEmil Renner Berthing return -EOPNOTSUPP; 684*bed5cd6fSEmil Renner Berthing mask |= TH1520_PADCFG_BIAS; 685*bed5cd6fSEmil Renner Berthing value &= ~TH1520_PADCFG_BIAS; 686*bed5cd6fSEmil Renner Berthing value |= TH1520_PADCFG_PE; 687*bed5cd6fSEmil Renner Berthing break; 688*bed5cd6fSEmil Renner Berthing case PIN_CONFIG_BIAS_PULL_UP: 689*bed5cd6fSEmil Renner Berthing if (arg == 0) 690*bed5cd6fSEmil Renner Berthing return -EOPNOTSUPP; 691*bed5cd6fSEmil Renner Berthing mask |= TH1520_PADCFG_BIAS; 692*bed5cd6fSEmil Renner Berthing value &= ~TH1520_PADCFG_BIAS; 693*bed5cd6fSEmil Renner Berthing if (arg == TH1520_PULL_STRONG_OHM) 694*bed5cd6fSEmil Renner Berthing value |= TH1520_PADCFG_SPU; 695*bed5cd6fSEmil Renner Berthing else 696*bed5cd6fSEmil Renner Berthing value |= TH1520_PADCFG_PE | TH1520_PADCFG_PS; 697*bed5cd6fSEmil Renner Berthing break; 698*bed5cd6fSEmil Renner Berthing case PIN_CONFIG_DRIVE_STRENGTH: 699*bed5cd6fSEmil Renner Berthing mask |= TH1520_PADCFG_DS; 700*bed5cd6fSEmil Renner Berthing value &= ~TH1520_PADCFG_DS; 701*bed5cd6fSEmil Renner Berthing value |= th1520_drive_strength_from_ma(arg); 702*bed5cd6fSEmil Renner Berthing break; 703*bed5cd6fSEmil Renner Berthing case PIN_CONFIG_INPUT_ENABLE: 704*bed5cd6fSEmil Renner Berthing mask |= TH1520_PADCFG_IE; 705*bed5cd6fSEmil Renner Berthing if (arg) 706*bed5cd6fSEmil Renner Berthing value |= TH1520_PADCFG_IE; 707*bed5cd6fSEmil Renner Berthing else 708*bed5cd6fSEmil Renner Berthing value &= ~TH1520_PADCFG_IE; 709*bed5cd6fSEmil Renner Berthing break; 710*bed5cd6fSEmil Renner Berthing case PIN_CONFIG_INPUT_SCHMITT_ENABLE: 711*bed5cd6fSEmil Renner Berthing mask |= TH1520_PADCFG_ST; 712*bed5cd6fSEmil Renner Berthing if (arg) 713*bed5cd6fSEmil Renner Berthing value |= TH1520_PADCFG_ST; 714*bed5cd6fSEmil Renner Berthing else 715*bed5cd6fSEmil Renner Berthing value &= ~TH1520_PADCFG_ST; 716*bed5cd6fSEmil Renner Berthing break; 717*bed5cd6fSEmil Renner Berthing case PIN_CONFIG_SLEW_RATE: 718*bed5cd6fSEmil Renner Berthing mask |= TH1520_PADCFG_SL; 719*bed5cd6fSEmil Renner Berthing if (arg) 720*bed5cd6fSEmil Renner Berthing value |= TH1520_PADCFG_SL; 721*bed5cd6fSEmil Renner Berthing else 722*bed5cd6fSEmil Renner Berthing value &= ~TH1520_PADCFG_SL; 723*bed5cd6fSEmil Renner Berthing break; 724*bed5cd6fSEmil Renner Berthing default: 725*bed5cd6fSEmil Renner Berthing return -EOPNOTSUPP; 726*bed5cd6fSEmil Renner Berthing } 727*bed5cd6fSEmil Renner Berthing } 728*bed5cd6fSEmil Renner Berthing 729*bed5cd6fSEmil Renner Berthing return th1520_padcfg_rmw(thp, pin, mask, value); 730*bed5cd6fSEmil Renner Berthing } 731*bed5cd6fSEmil Renner Berthing 732*bed5cd6fSEmil Renner Berthing static int th1520_pinconf_group_set(struct pinctrl_dev *pctldev, 733*bed5cd6fSEmil Renner Berthing unsigned int gsel, 734*bed5cd6fSEmil Renner Berthing unsigned long *configs, 735*bed5cd6fSEmil Renner Berthing unsigned int num_configs) 736*bed5cd6fSEmil Renner Berthing { 737*bed5cd6fSEmil Renner Berthing struct th1520_pinctrl *thp = pinctrl_dev_get_drvdata(pctldev); 738*bed5cd6fSEmil Renner Berthing unsigned int pin = thp->desc.pins[gsel].number; 739*bed5cd6fSEmil Renner Berthing 740*bed5cd6fSEmil Renner Berthing return th1520_pinconf_set(pctldev, pin, configs, num_configs); 741*bed5cd6fSEmil Renner Berthing } 742*bed5cd6fSEmil Renner Berthing 743*bed5cd6fSEmil Renner Berthing #ifdef CONFIG_DEBUG_FS 744*bed5cd6fSEmil Renner Berthing static void th1520_pinconf_dbg_show(struct pinctrl_dev *pctldev, 745*bed5cd6fSEmil Renner Berthing struct seq_file *s, unsigned int pin) 746*bed5cd6fSEmil Renner Berthing { 747*bed5cd6fSEmil Renner Berthing struct th1520_pinctrl *thp = pinctrl_dev_get_drvdata(pctldev); 748*bed5cd6fSEmil Renner Berthing u32 value = readl_relaxed(th1520_padcfg(thp, pin)); 749*bed5cd6fSEmil Renner Berthing 750*bed5cd6fSEmil Renner Berthing value = (value >> th1520_padcfg_shift(pin)) & GENMASK(9, 0); 751*bed5cd6fSEmil Renner Berthing 752*bed5cd6fSEmil Renner Berthing seq_printf(s, " [0x%03x]", value); 753*bed5cd6fSEmil Renner Berthing } 754*bed5cd6fSEmil Renner Berthing #else 755*bed5cd6fSEmil Renner Berthing #define th1520_pinconf_dbg_show NULL 756*bed5cd6fSEmil Renner Berthing #endif 757*bed5cd6fSEmil Renner Berthing 758*bed5cd6fSEmil Renner Berthing static const struct pinconf_ops th1520_pinconf_ops = { 759*bed5cd6fSEmil Renner Berthing .pin_config_get = th1520_pinconf_get, 760*bed5cd6fSEmil Renner Berthing .pin_config_group_get = th1520_pinconf_group_get, 761*bed5cd6fSEmil Renner Berthing .pin_config_set = th1520_pinconf_set, 762*bed5cd6fSEmil Renner Berthing .pin_config_group_set = th1520_pinconf_group_set, 763*bed5cd6fSEmil Renner Berthing .pin_config_dbg_show = th1520_pinconf_dbg_show, 764*bed5cd6fSEmil Renner Berthing .is_generic = true, 765*bed5cd6fSEmil Renner Berthing }; 766*bed5cd6fSEmil Renner Berthing 767*bed5cd6fSEmil Renner Berthing static int th1520_pinmux_set(struct th1520_pinctrl *thp, unsigned int pin, 768*bed5cd6fSEmil Renner Berthing unsigned long muxdata, enum th1520_muxtype muxtype) 769*bed5cd6fSEmil Renner Berthing { 770*bed5cd6fSEmil Renner Berthing void __iomem *muxcfg = th1520_muxcfg(thp, pin); 771*bed5cd6fSEmil Renner Berthing unsigned int shift = th1520_muxcfg_shift(pin); 772*bed5cd6fSEmil Renner Berthing u32 mask, value, tmp; 773*bed5cd6fSEmil Renner Berthing 774*bed5cd6fSEmil Renner Berthing for (value = 0; muxdata; muxdata >>= 5, value++) { 775*bed5cd6fSEmil Renner Berthing if ((muxdata & GENMASK(4, 0)) == muxtype) 776*bed5cd6fSEmil Renner Berthing break; 777*bed5cd6fSEmil Renner Berthing } 778*bed5cd6fSEmil Renner Berthing if (!muxdata) { 779*bed5cd6fSEmil Renner Berthing dev_err(thp->pctl->dev, "invalid mux %s for pin %s\n", 780*bed5cd6fSEmil Renner Berthing th1520_muxtype_string[muxtype], pin_get_name(thp->pctl, pin)); 781*bed5cd6fSEmil Renner Berthing return -EINVAL; 782*bed5cd6fSEmil Renner Berthing } 783*bed5cd6fSEmil Renner Berthing 784*bed5cd6fSEmil Renner Berthing mask = GENMASK(3, 0) << shift; 785*bed5cd6fSEmil Renner Berthing value = value << shift; 786*bed5cd6fSEmil Renner Berthing 787*bed5cd6fSEmil Renner Berthing scoped_guard(raw_spinlock_irqsave, &thp->lock) { 788*bed5cd6fSEmil Renner Berthing tmp = readl_relaxed(muxcfg); 789*bed5cd6fSEmil Renner Berthing tmp = (tmp & ~mask) | value; 790*bed5cd6fSEmil Renner Berthing writel_relaxed(tmp, muxcfg); 791*bed5cd6fSEmil Renner Berthing } 792*bed5cd6fSEmil Renner Berthing return 0; 793*bed5cd6fSEmil Renner Berthing } 794*bed5cd6fSEmil Renner Berthing 795*bed5cd6fSEmil Renner Berthing static int th1520_pinmux_set_mux(struct pinctrl_dev *pctldev, 796*bed5cd6fSEmil Renner Berthing unsigned int fsel, unsigned int gsel) 797*bed5cd6fSEmil Renner Berthing { 798*bed5cd6fSEmil Renner Berthing struct th1520_pinctrl *thp = pinctrl_dev_get_drvdata(pctldev); 799*bed5cd6fSEmil Renner Berthing const struct function_desc *func = pinmux_generic_get_function(pctldev, fsel); 800*bed5cd6fSEmil Renner Berthing 801*bed5cd6fSEmil Renner Berthing return th1520_pinmux_set(thp, thp->desc.pins[gsel].number, 802*bed5cd6fSEmil Renner Berthing (uintptr_t)thp->desc.pins[gsel].drv_data & TH1520_PAD_MUXDATA, 803*bed5cd6fSEmil Renner Berthing (uintptr_t)func->data); 804*bed5cd6fSEmil Renner Berthing } 805*bed5cd6fSEmil Renner Berthing 806*bed5cd6fSEmil Renner Berthing static int th1520_gpio_request_enable(struct pinctrl_dev *pctldev, 807*bed5cd6fSEmil Renner Berthing struct pinctrl_gpio_range *range, 808*bed5cd6fSEmil Renner Berthing unsigned int offset) 809*bed5cd6fSEmil Renner Berthing { 810*bed5cd6fSEmil Renner Berthing struct th1520_pinctrl *thp = pinctrl_dev_get_drvdata(pctldev); 811*bed5cd6fSEmil Renner Berthing const struct pin_desc *desc = pin_desc_get(pctldev, offset); 812*bed5cd6fSEmil Renner Berthing 813*bed5cd6fSEmil Renner Berthing return th1520_pinmux_set(thp, offset, 814*bed5cd6fSEmil Renner Berthing (uintptr_t)desc->drv_data & TH1520_PAD_MUXDATA, 815*bed5cd6fSEmil Renner Berthing TH1520_MUX_GPIO); 816*bed5cd6fSEmil Renner Berthing } 817*bed5cd6fSEmil Renner Berthing 818*bed5cd6fSEmil Renner Berthing static int th1520_gpio_set_direction(struct pinctrl_dev *pctldev, 819*bed5cd6fSEmil Renner Berthing struct pinctrl_gpio_range *range, 820*bed5cd6fSEmil Renner Berthing unsigned int offset, bool input) 821*bed5cd6fSEmil Renner Berthing { 822*bed5cd6fSEmil Renner Berthing struct th1520_pinctrl *thp = pinctrl_dev_get_drvdata(pctldev); 823*bed5cd6fSEmil Renner Berthing 824*bed5cd6fSEmil Renner Berthing return th1520_padcfg_rmw(thp, offset, TH1520_PADCFG_IE, 825*bed5cd6fSEmil Renner Berthing input ? TH1520_PADCFG_IE : 0); 826*bed5cd6fSEmil Renner Berthing } 827*bed5cd6fSEmil Renner Berthing 828*bed5cd6fSEmil Renner Berthing static const struct pinmux_ops th1520_pinmux_ops = { 829*bed5cd6fSEmil Renner Berthing .get_functions_count = pinmux_generic_get_function_count, 830*bed5cd6fSEmil Renner Berthing .get_function_name = pinmux_generic_get_function_name, 831*bed5cd6fSEmil Renner Berthing .get_function_groups = pinmux_generic_get_function_groups, 832*bed5cd6fSEmil Renner Berthing .set_mux = th1520_pinmux_set_mux, 833*bed5cd6fSEmil Renner Berthing .gpio_request_enable = th1520_gpio_request_enable, 834*bed5cd6fSEmil Renner Berthing .gpio_set_direction = th1520_gpio_set_direction, 835*bed5cd6fSEmil Renner Berthing .strict = true, 836*bed5cd6fSEmil Renner Berthing }; 837*bed5cd6fSEmil Renner Berthing 838*bed5cd6fSEmil Renner Berthing static int th1520_pinctrl_probe(struct platform_device *pdev) 839*bed5cd6fSEmil Renner Berthing { 840*bed5cd6fSEmil Renner Berthing struct device *dev = &pdev->dev; 841*bed5cd6fSEmil Renner Berthing const struct th1520_pad_group *group; 842*bed5cd6fSEmil Renner Berthing struct device_node *np = dev->of_node; 843*bed5cd6fSEmil Renner Berthing struct th1520_pinctrl *thp; 844*bed5cd6fSEmil Renner Berthing struct clk *clk; 845*bed5cd6fSEmil Renner Berthing u32 pin_group; 846*bed5cd6fSEmil Renner Berthing int ret; 847*bed5cd6fSEmil Renner Berthing 848*bed5cd6fSEmil Renner Berthing thp = devm_kzalloc(dev, sizeof(*thp), GFP_KERNEL); 849*bed5cd6fSEmil Renner Berthing if (!thp) 850*bed5cd6fSEmil Renner Berthing return -ENOMEM; 851*bed5cd6fSEmil Renner Berthing 852*bed5cd6fSEmil Renner Berthing thp->base = devm_platform_ioremap_resource(pdev, 0); 853*bed5cd6fSEmil Renner Berthing if (IS_ERR(thp->base)) 854*bed5cd6fSEmil Renner Berthing return PTR_ERR(thp->base); 855*bed5cd6fSEmil Renner Berthing 856*bed5cd6fSEmil Renner Berthing clk = devm_clk_get_enabled(dev, NULL); 857*bed5cd6fSEmil Renner Berthing if (IS_ERR(clk)) 858*bed5cd6fSEmil Renner Berthing return dev_err_probe(dev, PTR_ERR(clk), "error getting clock\n"); 859*bed5cd6fSEmil Renner Berthing 860*bed5cd6fSEmil Renner Berthing ret = of_property_read_u32(np, "thead,pad-group", &pin_group); 861*bed5cd6fSEmil Renner Berthing if (ret) 862*bed5cd6fSEmil Renner Berthing return dev_err_probe(dev, ret, "failed to read the thead,pad-group property\n"); 863*bed5cd6fSEmil Renner Berthing 864*bed5cd6fSEmil Renner Berthing if (pin_group == 1) 865*bed5cd6fSEmil Renner Berthing group = &th1520_group1; 866*bed5cd6fSEmil Renner Berthing else if (pin_group == 2) 867*bed5cd6fSEmil Renner Berthing group = &th1520_group2; 868*bed5cd6fSEmil Renner Berthing else if (pin_group == 3) 869*bed5cd6fSEmil Renner Berthing group = &th1520_group3; 870*bed5cd6fSEmil Renner Berthing else 871*bed5cd6fSEmil Renner Berthing return dev_err_probe(dev, -EINVAL, "unit address did not match any pad group\n"); 872*bed5cd6fSEmil Renner Berthing 873*bed5cd6fSEmil Renner Berthing thp->desc.name = group->name; 874*bed5cd6fSEmil Renner Berthing thp->desc.pins = group->pins; 875*bed5cd6fSEmil Renner Berthing thp->desc.npins = group->npins; 876*bed5cd6fSEmil Renner Berthing thp->desc.pctlops = &th1520_pinctrl_ops; 877*bed5cd6fSEmil Renner Berthing thp->desc.pmxops = &th1520_pinmux_ops; 878*bed5cd6fSEmil Renner Berthing thp->desc.confops = &th1520_pinconf_ops; 879*bed5cd6fSEmil Renner Berthing thp->desc.owner = THIS_MODULE; 880*bed5cd6fSEmil Renner Berthing mutex_init(&thp->mutex); 881*bed5cd6fSEmil Renner Berthing raw_spin_lock_init(&thp->lock); 882*bed5cd6fSEmil Renner Berthing 883*bed5cd6fSEmil Renner Berthing ret = devm_pinctrl_register_and_init(dev, &thp->desc, thp, &thp->pctl); 884*bed5cd6fSEmil Renner Berthing if (ret) 885*bed5cd6fSEmil Renner Berthing return dev_err_probe(dev, ret, "could not register pinctrl driver\n"); 886*bed5cd6fSEmil Renner Berthing 887*bed5cd6fSEmil Renner Berthing return pinctrl_enable(thp->pctl); 888*bed5cd6fSEmil Renner Berthing } 889*bed5cd6fSEmil Renner Berthing 890*bed5cd6fSEmil Renner Berthing static const struct of_device_id th1520_pinctrl_of_match[] = { 891*bed5cd6fSEmil Renner Berthing { .compatible = "thead,th1520-pinctrl"}, 892*bed5cd6fSEmil Renner Berthing { /* sentinel */ } 893*bed5cd6fSEmil Renner Berthing }; 894*bed5cd6fSEmil Renner Berthing MODULE_DEVICE_TABLE(of, th1520_pinctrl_of_match); 895*bed5cd6fSEmil Renner Berthing 896*bed5cd6fSEmil Renner Berthing static struct platform_driver th1520_pinctrl_driver = { 897*bed5cd6fSEmil Renner Berthing .probe = th1520_pinctrl_probe, 898*bed5cd6fSEmil Renner Berthing .driver = { 899*bed5cd6fSEmil Renner Berthing .name = "pinctrl-th1520", 900*bed5cd6fSEmil Renner Berthing .of_match_table = th1520_pinctrl_of_match, 901*bed5cd6fSEmil Renner Berthing }, 902*bed5cd6fSEmil Renner Berthing }; 903*bed5cd6fSEmil Renner Berthing module_platform_driver(th1520_pinctrl_driver); 904*bed5cd6fSEmil Renner Berthing 905*bed5cd6fSEmil Renner Berthing MODULE_DESCRIPTION("Pinctrl driver for the T-Head TH1520 SoC"); 906*bed5cd6fSEmil Renner Berthing MODULE_AUTHOR("Emil Renner Berthing <emil.renner.berthing@canonical.com>"); 907*bed5cd6fSEmil Renner Berthing MODULE_LICENSE("GPL"); 908