| John Crispin | 3f8c50c | 2012-08-28 12:44:59 +0200 | [diff] [blame] | 1 | /* | 
|  | 2 | *  linux/drivers/pinctrl/pinmux-xway.c | 
|  | 3 | *  based on linux/drivers/pinctrl/pinmux-pxa910.c | 
|  | 4 | * | 
|  | 5 | *  This program is free software; you can redistribute it and/or modify | 
|  | 6 | *  it under the terms of the GNU General Public License version 2 as | 
|  | 7 | *  publishhed by the Free Software Foundation. | 
|  | 8 | * | 
|  | 9 | *  Copyright (C) 2012 John Crispin <blogic@openwrt.org> | 
|  | 10 | */ | 
|  | 11 |  | 
|  | 12 | #include <linux/slab.h> | 
|  | 13 | #include <linux/module.h> | 
|  | 14 | #include <linux/of_platform.h> | 
|  | 15 | #include <linux/of_address.h> | 
|  | 16 | #include <linux/of_gpio.h> | 
|  | 17 | #include <linux/ioport.h> | 
|  | 18 | #include <linux/io.h> | 
|  | 19 | #include <linux/device.h> | 
| John Crispin | 3f8c50c | 2012-08-28 12:44:59 +0200 | [diff] [blame] | 20 | #include <linux/platform_device.h> | 
|  | 21 |  | 
|  | 22 | #include "pinctrl-lantiq.h" | 
|  | 23 |  | 
|  | 24 | #include <lantiq_soc.h> | 
|  | 25 |  | 
|  | 26 | /* we have 3 1/2 banks of 16 bit each */ | 
|  | 27 | #define PINS			16 | 
|  | 28 | #define PORT3			3 | 
|  | 29 | #define PORT(x)			(x / PINS) | 
|  | 30 | #define PORT_PIN(x)		(x % PINS) | 
|  | 31 |  | 
|  | 32 | /* we have 2 mux bits that can be set for each pin */ | 
|  | 33 | #define MUX_ALT0	0x1 | 
|  | 34 | #define MUX_ALT1	0x2 | 
|  | 35 |  | 
|  | 36 | /* | 
|  | 37 | * each bank has this offset apart from the 1/2 bank that is mixed into the | 
|  | 38 | * other 3 ranges | 
|  | 39 | */ | 
|  | 40 | #define REG_OFF			0x30 | 
|  | 41 |  | 
|  | 42 | /* these are the offsets to our registers */ | 
|  | 43 | #define GPIO_BASE(p)		(REG_OFF * PORT(p)) | 
|  | 44 | #define GPIO_OUT(p)		GPIO_BASE(p) | 
|  | 45 | #define GPIO_IN(p)		(GPIO_BASE(p) + 0x04) | 
|  | 46 | #define GPIO_DIR(p)		(GPIO_BASE(p) + 0x08) | 
|  | 47 | #define GPIO_ALT0(p)		(GPIO_BASE(p) + 0x0C) | 
|  | 48 | #define GPIO_ALT1(p)		(GPIO_BASE(p) + 0x10) | 
|  | 49 | #define GPIO_OD(p)		(GPIO_BASE(p) + 0x14) | 
|  | 50 | #define GPIO_PUDSEL(p)		(GPIO_BASE(p) + 0x1c) | 
|  | 51 | #define GPIO_PUDEN(p)		(GPIO_BASE(p) + 0x20) | 
|  | 52 |  | 
|  | 53 | /* the 1/2 port needs special offsets for some registers */ | 
|  | 54 | #define GPIO3_OD		(GPIO_BASE(0) + 0x24) | 
|  | 55 | #define GPIO3_PUDSEL		(GPIO_BASE(0) + 0x28) | 
|  | 56 | #define GPIO3_PUDEN		(GPIO_BASE(0) + 0x2C) | 
|  | 57 | #define GPIO3_ALT1		(GPIO_BASE(PINS) + 0x24) | 
|  | 58 |  | 
|  | 59 | /* macros to help us access the registers */ | 
|  | 60 | #define gpio_getbit(m, r, p)	(!!(ltq_r32(m + r) & BIT(p))) | 
|  | 61 | #define gpio_setbit(m, r, p)	ltq_w32_mask(0, BIT(p), m + r) | 
|  | 62 | #define gpio_clearbit(m, r, p)	ltq_w32_mask(BIT(p), 0, m + r) | 
|  | 63 |  | 
|  | 64 | #define MFP_XWAY(a, f0, f1, f2, f3)	\ | 
|  | 65 | {				\ | 
|  | 66 | .name = #a,		\ | 
|  | 67 | .pin = a,		\ | 
|  | 68 | .func = {		\ | 
|  | 69 | XWAY_MUX_##f0,	\ | 
|  | 70 | XWAY_MUX_##f1,	\ | 
|  | 71 | XWAY_MUX_##f2,	\ | 
|  | 72 | XWAY_MUX_##f3,	\ | 
|  | 73 | },			\ | 
|  | 74 | } | 
|  | 75 |  | 
|  | 76 | #define GRP_MUX(a, m, p)		\ | 
|  | 77 | { .name = a, .mux = XWAY_MUX_##m, .pins = p, .npins = ARRAY_SIZE(p), } | 
|  | 78 |  | 
|  | 79 | #define FUNC_MUX(f, m)		\ | 
|  | 80 | { .func = f, .mux = XWAY_MUX_##m, } | 
|  | 81 |  | 
|  | 82 | #define XWAY_MAX_PIN		32 | 
|  | 83 | #define XR9_MAX_PIN		56 | 
|  | 84 |  | 
|  | 85 | enum xway_mux { | 
|  | 86 | XWAY_MUX_GPIO = 0, | 
|  | 87 | XWAY_MUX_SPI, | 
|  | 88 | XWAY_MUX_ASC, | 
|  | 89 | XWAY_MUX_PCI, | 
|  | 90 | XWAY_MUX_CGU, | 
|  | 91 | XWAY_MUX_EBU, | 
|  | 92 | XWAY_MUX_JTAG, | 
|  | 93 | XWAY_MUX_EXIN, | 
|  | 94 | XWAY_MUX_TDM, | 
|  | 95 | XWAY_MUX_STP, | 
|  | 96 | XWAY_MUX_SIN, | 
|  | 97 | XWAY_MUX_GPT, | 
|  | 98 | XWAY_MUX_NMI, | 
|  | 99 | XWAY_MUX_MDIO, | 
|  | 100 | XWAY_MUX_MII, | 
|  | 101 | XWAY_MUX_EPHY, | 
|  | 102 | XWAY_MUX_DFE, | 
|  | 103 | XWAY_MUX_SDIO, | 
|  | 104 | XWAY_MUX_NONE = 0xffff, | 
|  | 105 | }; | 
|  | 106 |  | 
|  | 107 | static const struct ltq_mfp_pin xway_mfp[] = { | 
|  | 108 | /*       pin    f0	f1	f2	f3   */ | 
|  | 109 | MFP_XWAY(GPIO0, GPIO,	EXIN,	NONE,	TDM), | 
|  | 110 | MFP_XWAY(GPIO1, GPIO,	EXIN,	NONE,	NONE), | 
|  | 111 | MFP_XWAY(GPIO2, GPIO,	CGU,	EXIN,	NONE), | 
|  | 112 | MFP_XWAY(GPIO3, GPIO,	CGU,	NONE,	PCI), | 
|  | 113 | MFP_XWAY(GPIO4, GPIO,	STP,	NONE,	ASC), | 
|  | 114 | MFP_XWAY(GPIO5, GPIO,	STP,	NONE,	NONE), | 
|  | 115 | MFP_XWAY(GPIO6, GPIO,	STP,	GPT,	ASC), | 
|  | 116 | MFP_XWAY(GPIO7, GPIO,	CGU,	PCI,	NONE), | 
|  | 117 | MFP_XWAY(GPIO8, GPIO,	CGU,	NMI,	NONE), | 
|  | 118 | MFP_XWAY(GPIO9, GPIO,	ASC,	SPI,	EXIN), | 
|  | 119 | MFP_XWAY(GPIO10, GPIO,	ASC,	SPI,	NONE), | 
|  | 120 | MFP_XWAY(GPIO11, GPIO,	ASC,	PCI,	SPI), | 
|  | 121 | MFP_XWAY(GPIO12, GPIO,	ASC,	NONE,	NONE), | 
|  | 122 | MFP_XWAY(GPIO13, GPIO,	EBU,	SPI,	NONE), | 
|  | 123 | MFP_XWAY(GPIO14, GPIO,	CGU,	PCI,	NONE), | 
|  | 124 | MFP_XWAY(GPIO15, GPIO,	SPI,	JTAG,	NONE), | 
|  | 125 | MFP_XWAY(GPIO16, GPIO,	SPI,	NONE,	JTAG), | 
|  | 126 | MFP_XWAY(GPIO17, GPIO,	SPI,	NONE,	JTAG), | 
|  | 127 | MFP_XWAY(GPIO18, GPIO,	SPI,	NONE,	JTAG), | 
|  | 128 | MFP_XWAY(GPIO19, GPIO,	PCI,	NONE,	NONE), | 
|  | 129 | MFP_XWAY(GPIO20, GPIO,	JTAG,	NONE,	NONE), | 
|  | 130 | MFP_XWAY(GPIO21, GPIO,	PCI,	EBU,	GPT), | 
|  | 131 | MFP_XWAY(GPIO22, GPIO,	SPI,	NONE,	NONE), | 
|  | 132 | MFP_XWAY(GPIO23, GPIO,	EBU,	PCI,	STP), | 
|  | 133 | MFP_XWAY(GPIO24, GPIO,	EBU,	TDM,	PCI), | 
|  | 134 | MFP_XWAY(GPIO25, GPIO,	TDM,	NONE,	ASC), | 
|  | 135 | MFP_XWAY(GPIO26, GPIO,	EBU,	NONE,	TDM), | 
|  | 136 | MFP_XWAY(GPIO27, GPIO,	TDM,	NONE,	ASC), | 
|  | 137 | MFP_XWAY(GPIO28, GPIO,	GPT,	NONE,	NONE), | 
|  | 138 | MFP_XWAY(GPIO29, GPIO,	PCI,	NONE,	NONE), | 
|  | 139 | MFP_XWAY(GPIO30, GPIO,	PCI,	NONE,	NONE), | 
|  | 140 | MFP_XWAY(GPIO31, GPIO,	EBU,	PCI,	NONE), | 
|  | 141 | MFP_XWAY(GPIO32, GPIO,	NONE,	NONE,	EBU), | 
|  | 142 | MFP_XWAY(GPIO33, GPIO,	NONE,	NONE,	EBU), | 
|  | 143 | MFP_XWAY(GPIO34, GPIO,	NONE,	NONE,	EBU), | 
|  | 144 | MFP_XWAY(GPIO35, GPIO,	NONE,	NONE,	EBU), | 
|  | 145 | MFP_XWAY(GPIO36, GPIO,	SIN,	NONE,	EBU), | 
|  | 146 | MFP_XWAY(GPIO37, GPIO,	PCI,	NONE,	NONE), | 
|  | 147 | MFP_XWAY(GPIO38, GPIO,	PCI,	NONE,	NONE), | 
|  | 148 | MFP_XWAY(GPIO39, GPIO,	EXIN,	NONE,	NONE), | 
|  | 149 | MFP_XWAY(GPIO40, GPIO,	NONE,	NONE,	NONE), | 
|  | 150 | MFP_XWAY(GPIO41, GPIO,	NONE,	NONE,	NONE), | 
|  | 151 | MFP_XWAY(GPIO42, GPIO,	MDIO,	NONE,	NONE), | 
|  | 152 | MFP_XWAY(GPIO43, GPIO,	MDIO,	NONE,	NONE), | 
|  | 153 | MFP_XWAY(GPIO44, GPIO,	NONE,	NONE,	SIN), | 
|  | 154 | MFP_XWAY(GPIO45, GPIO,	NONE,	NONE,	SIN), | 
|  | 155 | MFP_XWAY(GPIO46, GPIO,	NONE,	NONE,	EXIN), | 
|  | 156 | MFP_XWAY(GPIO47, GPIO,	NONE,	NONE,	SIN), | 
|  | 157 | MFP_XWAY(GPIO48, GPIO,	EBU,	NONE,	NONE), | 
|  | 158 | MFP_XWAY(GPIO49, GPIO,	EBU,	NONE,	NONE), | 
|  | 159 | MFP_XWAY(GPIO50, GPIO,	NONE,	NONE,	NONE), | 
|  | 160 | MFP_XWAY(GPIO51, GPIO,	NONE,	NONE,	NONE), | 
|  | 161 | MFP_XWAY(GPIO52, GPIO,	NONE,	NONE,	NONE), | 
|  | 162 | MFP_XWAY(GPIO53, GPIO,	NONE,	NONE,	NONE), | 
|  | 163 | MFP_XWAY(GPIO54, GPIO,	NONE,	NONE,	NONE), | 
|  | 164 | MFP_XWAY(GPIO55, GPIO,	NONE,	NONE,	NONE), | 
|  | 165 | }; | 
|  | 166 |  | 
|  | 167 | static const struct ltq_mfp_pin ase_mfp[] = { | 
|  | 168 | /*       pin    f0	f1	f2	f3   */ | 
|  | 169 | MFP_XWAY(GPIO0, GPIO,	EXIN,	MII,	TDM), | 
|  | 170 | MFP_XWAY(GPIO1, GPIO,	STP,	DFE,	EBU), | 
|  | 171 | MFP_XWAY(GPIO2, GPIO,	STP,	DFE,	EPHY), | 
|  | 172 | MFP_XWAY(GPIO3, GPIO,	STP,	EPHY,	EBU), | 
|  | 173 | MFP_XWAY(GPIO4, GPIO,	GPT,	EPHY,	MII), | 
|  | 174 | MFP_XWAY(GPIO5, GPIO,	MII,	ASC,	GPT), | 
|  | 175 | MFP_XWAY(GPIO6, GPIO,	MII,	ASC,	EXIN), | 
|  | 176 | MFP_XWAY(GPIO7, GPIO,	SPI,	MII,	JTAG), | 
|  | 177 | MFP_XWAY(GPIO8, GPIO,	SPI,	MII,	JTAG), | 
|  | 178 | MFP_XWAY(GPIO9, GPIO,	SPI,	MII,	JTAG), | 
|  | 179 | MFP_XWAY(GPIO10, GPIO,	SPI,	MII,	JTAG), | 
|  | 180 | MFP_XWAY(GPIO11, GPIO,	EBU,	CGU,	JTAG), | 
|  | 181 | MFP_XWAY(GPIO12, GPIO,	EBU,	MII,	SDIO), | 
|  | 182 | MFP_XWAY(GPIO13, GPIO,	EBU,	MII,	CGU), | 
|  | 183 | MFP_XWAY(GPIO14, GPIO,	EBU,	SPI,	CGU), | 
|  | 184 | MFP_XWAY(GPIO15, GPIO,	EBU,	SPI,	SDIO), | 
|  | 185 | MFP_XWAY(GPIO16, GPIO,	NONE,	NONE,	NONE), | 
|  | 186 | MFP_XWAY(GPIO17, GPIO,	NONE,	NONE,	NONE), | 
|  | 187 | MFP_XWAY(GPIO18, GPIO,	NONE,	NONE,	NONE), | 
|  | 188 | MFP_XWAY(GPIO19, GPIO,	EBU,	MII,	SDIO), | 
|  | 189 | MFP_XWAY(GPIO20, GPIO,	EBU,	MII,	SDIO), | 
|  | 190 | MFP_XWAY(GPIO21, GPIO,	EBU,	MII,	SDIO), | 
|  | 191 | MFP_XWAY(GPIO22, GPIO,	EBU,	MII,	CGU), | 
|  | 192 | MFP_XWAY(GPIO23, GPIO,	EBU,	MII,	CGU), | 
|  | 193 | MFP_XWAY(GPIO24, GPIO,	EBU,	NONE,	MII), | 
|  | 194 | MFP_XWAY(GPIO25, GPIO,	EBU,	MII,	GPT), | 
|  | 195 | MFP_XWAY(GPIO26, GPIO,	EBU,	MII,	SDIO), | 
|  | 196 | MFP_XWAY(GPIO27, GPIO,	EBU,	NONE,	MII), | 
|  | 197 | MFP_XWAY(GPIO28, GPIO,	MII,	EBU,	SDIO), | 
|  | 198 | MFP_XWAY(GPIO29, GPIO,	EBU,	MII,	EXIN), | 
|  | 199 | MFP_XWAY(GPIO30, GPIO,	NONE,	NONE,	NONE), | 
|  | 200 | MFP_XWAY(GPIO31, GPIO,	NONE,	NONE,	NONE), | 
|  | 201 | }; | 
|  | 202 |  | 
|  | 203 | static const unsigned pins_jtag[] = {GPIO15, GPIO16, GPIO17, GPIO19, GPIO35}; | 
|  | 204 | static const unsigned pins_asc0[] = {GPIO11, GPIO12}; | 
|  | 205 | static const unsigned pins_asc0_cts_rts[] = {GPIO9, GPIO10}; | 
|  | 206 | static const unsigned pins_stp[] = {GPIO4, GPIO5, GPIO6}; | 
|  | 207 | static const unsigned pins_nmi[] = {GPIO8}; | 
|  | 208 | static const unsigned pins_mdio[] = {GPIO42, GPIO43}; | 
|  | 209 |  | 
|  | 210 | static const unsigned pins_ebu_a24[] = {GPIO13}; | 
|  | 211 | static const unsigned pins_ebu_clk[] = {GPIO21}; | 
|  | 212 | static const unsigned pins_ebu_cs1[] = {GPIO23}; | 
|  | 213 | static const unsigned pins_ebu_a23[] = {GPIO24}; | 
|  | 214 | static const unsigned pins_ebu_wait[] = {GPIO26}; | 
|  | 215 | static const unsigned pins_ebu_a25[] = {GPIO31}; | 
|  | 216 | static const unsigned pins_ebu_rdy[] = {GPIO48}; | 
|  | 217 | static const unsigned pins_ebu_rd[] = {GPIO49}; | 
|  | 218 |  | 
|  | 219 | static const unsigned pins_nand_ale[] = {GPIO13}; | 
|  | 220 | static const unsigned pins_nand_cs1[] = {GPIO23}; | 
|  | 221 | static const unsigned pins_nand_cle[] = {GPIO24}; | 
|  | 222 | static const unsigned pins_nand_rdy[] = {GPIO48}; | 
|  | 223 | static const unsigned pins_nand_rd[] = {GPIO49}; | 
|  | 224 |  | 
|  | 225 | static const unsigned pins_exin0[] = {GPIO0}; | 
|  | 226 | static const unsigned pins_exin1[] = {GPIO1}; | 
|  | 227 | static const unsigned pins_exin2[] = {GPIO2}; | 
|  | 228 | static const unsigned pins_exin3[] = {GPIO39}; | 
|  | 229 | static const unsigned pins_exin4[] = {GPIO46}; | 
|  | 230 | static const unsigned pins_exin5[] = {GPIO9}; | 
|  | 231 |  | 
|  | 232 | static const unsigned pins_spi[] = {GPIO16, GPIO17, GPIO18}; | 
|  | 233 | static const unsigned pins_spi_cs1[] = {GPIO15}; | 
|  | 234 | static const unsigned pins_spi_cs2[] = {GPIO21}; | 
|  | 235 | static const unsigned pins_spi_cs3[] = {GPIO13}; | 
|  | 236 | static const unsigned pins_spi_cs4[] = {GPIO10}; | 
|  | 237 | static const unsigned pins_spi_cs5[] = {GPIO9}; | 
|  | 238 | static const unsigned pins_spi_cs6[] = {GPIO11}; | 
|  | 239 |  | 
|  | 240 | static const unsigned pins_gpt1[] = {GPIO28}; | 
|  | 241 | static const unsigned pins_gpt2[] = {GPIO21}; | 
|  | 242 | static const unsigned pins_gpt3[] = {GPIO6}; | 
|  | 243 |  | 
|  | 244 | static const unsigned pins_clkout0[] = {GPIO8}; | 
|  | 245 | static const unsigned pins_clkout1[] = {GPIO7}; | 
|  | 246 | static const unsigned pins_clkout2[] = {GPIO3}; | 
|  | 247 | static const unsigned pins_clkout3[] = {GPIO2}; | 
|  | 248 |  | 
|  | 249 | static const unsigned pins_pci_gnt1[] = {GPIO30}; | 
|  | 250 | static const unsigned pins_pci_gnt2[] = {GPIO23}; | 
|  | 251 | static const unsigned pins_pci_gnt3[] = {GPIO19}; | 
|  | 252 | static const unsigned pins_pci_gnt4[] = {GPIO38}; | 
|  | 253 | static const unsigned pins_pci_req1[] = {GPIO29}; | 
|  | 254 | static const unsigned pins_pci_req2[] = {GPIO31}; | 
|  | 255 | static const unsigned pins_pci_req3[] = {GPIO3}; | 
|  | 256 | static const unsigned pins_pci_req4[] = {GPIO37}; | 
|  | 257 |  | 
|  | 258 | static const unsigned ase_pins_jtag[] = {GPIO7, GPIO8, GPIO9, GPIO10, GPIO11}; | 
|  | 259 | static const unsigned ase_pins_asc[] = {GPIO5, GPIO6}; | 
|  | 260 | static const unsigned ase_pins_stp[] = {GPIO1, GPIO2, GPIO3}; | 
|  | 261 | static const unsigned ase_pins_ephy[] = {GPIO2, GPIO3, GPIO4}; | 
|  | 262 | static const unsigned ase_pins_dfe[] = {GPIO1, GPIO2}; | 
|  | 263 |  | 
|  | 264 | static const unsigned ase_pins_spi[] = {GPIO8, GPIO9, GPIO10}; | 
|  | 265 | static const unsigned ase_pins_spi_cs1[] = {GPIO7}; | 
|  | 266 | static const unsigned ase_pins_spi_cs2[] = {GPIO15}; | 
|  | 267 | static const unsigned ase_pins_spi_cs3[] = {GPIO14}; | 
|  | 268 |  | 
|  | 269 | static const unsigned ase_pins_exin0[] = {GPIO6}; | 
|  | 270 | static const unsigned ase_pins_exin1[] = {GPIO29}; | 
|  | 271 | static const unsigned ase_pins_exin2[] = {GPIO0}; | 
|  | 272 |  | 
|  | 273 | static const unsigned ase_pins_gpt1[] = {GPIO5}; | 
|  | 274 | static const unsigned ase_pins_gpt2[] = {GPIO4}; | 
|  | 275 | static const unsigned ase_pins_gpt3[] = {GPIO25}; | 
|  | 276 |  | 
|  | 277 | static const struct ltq_pin_group xway_grps[] = { | 
|  | 278 | GRP_MUX("exin0", EXIN, pins_exin0), | 
|  | 279 | GRP_MUX("exin1", EXIN, pins_exin1), | 
|  | 280 | GRP_MUX("exin2", EXIN, pins_exin2), | 
|  | 281 | GRP_MUX("jtag", JTAG, pins_jtag), | 
|  | 282 | GRP_MUX("ebu a23", EBU, pins_ebu_a23), | 
|  | 283 | GRP_MUX("ebu a24", EBU, pins_ebu_a24), | 
|  | 284 | GRP_MUX("ebu a25", EBU, pins_ebu_a25), | 
|  | 285 | GRP_MUX("ebu clk", EBU, pins_ebu_clk), | 
|  | 286 | GRP_MUX("ebu cs1", EBU, pins_ebu_cs1), | 
|  | 287 | GRP_MUX("ebu wait", EBU, pins_ebu_wait), | 
|  | 288 | GRP_MUX("nand ale", EBU, pins_nand_ale), | 
|  | 289 | GRP_MUX("nand cs1", EBU, pins_nand_cs1), | 
|  | 290 | GRP_MUX("nand cle", EBU, pins_nand_cle), | 
|  | 291 | GRP_MUX("spi", SPI, pins_spi), | 
|  | 292 | GRP_MUX("spi_cs1", SPI, pins_spi_cs1), | 
|  | 293 | GRP_MUX("spi_cs2", SPI, pins_spi_cs2), | 
|  | 294 | GRP_MUX("spi_cs3", SPI, pins_spi_cs3), | 
|  | 295 | GRP_MUX("spi_cs4", SPI, pins_spi_cs4), | 
|  | 296 | GRP_MUX("spi_cs5", SPI, pins_spi_cs5), | 
|  | 297 | GRP_MUX("spi_cs6", SPI, pins_spi_cs6), | 
|  | 298 | GRP_MUX("asc0", ASC, pins_asc0), | 
|  | 299 | GRP_MUX("asc0 cts rts", ASC, pins_asc0_cts_rts), | 
|  | 300 | GRP_MUX("stp", STP, pins_stp), | 
|  | 301 | GRP_MUX("nmi", NMI, pins_nmi), | 
|  | 302 | GRP_MUX("gpt1", GPT, pins_gpt1), | 
|  | 303 | GRP_MUX("gpt2", GPT, pins_gpt2), | 
|  | 304 | GRP_MUX("gpt3", GPT, pins_gpt3), | 
|  | 305 | GRP_MUX("clkout0", CGU, pins_clkout0), | 
|  | 306 | GRP_MUX("clkout1", CGU, pins_clkout1), | 
|  | 307 | GRP_MUX("clkout2", CGU, pins_clkout2), | 
|  | 308 | GRP_MUX("clkout3", CGU, pins_clkout3), | 
|  | 309 | GRP_MUX("gnt1", PCI, pins_pci_gnt1), | 
|  | 310 | GRP_MUX("gnt2", PCI, pins_pci_gnt2), | 
|  | 311 | GRP_MUX("gnt3", PCI, pins_pci_gnt3), | 
|  | 312 | GRP_MUX("req1", PCI, pins_pci_req1), | 
|  | 313 | GRP_MUX("req2", PCI, pins_pci_req2), | 
|  | 314 | GRP_MUX("req3", PCI, pins_pci_req3), | 
|  | 315 | /* xrx only */ | 
|  | 316 | GRP_MUX("nand rdy", EBU, pins_nand_rdy), | 
|  | 317 | GRP_MUX("nand rd", EBU, pins_nand_rd), | 
|  | 318 | GRP_MUX("exin3", EXIN, pins_exin3), | 
|  | 319 | GRP_MUX("exin4", EXIN, pins_exin4), | 
|  | 320 | GRP_MUX("exin5", EXIN, pins_exin5), | 
|  | 321 | GRP_MUX("gnt4", PCI, pins_pci_gnt4), | 
|  | 322 | GRP_MUX("req4", PCI, pins_pci_gnt4), | 
|  | 323 | GRP_MUX("mdio", MDIO, pins_mdio), | 
|  | 324 | }; | 
|  | 325 |  | 
|  | 326 | static const struct ltq_pin_group ase_grps[] = { | 
|  | 327 | GRP_MUX("exin0", EXIN, ase_pins_exin0), | 
|  | 328 | GRP_MUX("exin1", EXIN, ase_pins_exin1), | 
|  | 329 | GRP_MUX("exin2", EXIN, ase_pins_exin2), | 
|  | 330 | GRP_MUX("jtag", JTAG, ase_pins_jtag), | 
|  | 331 | GRP_MUX("stp", STP, ase_pins_stp), | 
|  | 332 | GRP_MUX("asc", ASC, ase_pins_asc), | 
|  | 333 | GRP_MUX("gpt1", GPT, ase_pins_gpt1), | 
|  | 334 | GRP_MUX("gpt2", GPT, ase_pins_gpt2), | 
|  | 335 | GRP_MUX("gpt3", GPT, ase_pins_gpt3), | 
|  | 336 | GRP_MUX("ephy", EPHY, ase_pins_ephy), | 
|  | 337 | GRP_MUX("dfe", DFE, ase_pins_dfe), | 
|  | 338 | GRP_MUX("spi", SPI, ase_pins_spi), | 
|  | 339 | GRP_MUX("spi_cs1", SPI, ase_pins_spi_cs1), | 
|  | 340 | GRP_MUX("spi_cs2", SPI, ase_pins_spi_cs2), | 
|  | 341 | GRP_MUX("spi_cs3", SPI, ase_pins_spi_cs3), | 
|  | 342 | }; | 
|  | 343 |  | 
|  | 344 | static const char * const xway_pci_grps[] = {"gnt1", "gnt2", | 
|  | 345 | "gnt3", "req1", | 
|  | 346 | "req2", "req3"}; | 
|  | 347 | static const char * const xway_spi_grps[] = {"spi", "spi_cs1", | 
|  | 348 | "spi_cs2", "spi_cs3", | 
|  | 349 | "spi_cs4", "spi_cs5", | 
|  | 350 | "spi_cs6"}; | 
|  | 351 | static const char * const xway_cgu_grps[] = {"clkout0", "clkout1", | 
|  | 352 | "clkout2", "clkout3"}; | 
|  | 353 | static const char * const xway_ebu_grps[] = {"ebu a23", "ebu a24", | 
|  | 354 | "ebu a25", "ebu cs1", | 
|  | 355 | "ebu wait", "ebu clk", | 
|  | 356 | "nand ale", "nand cs1", | 
|  | 357 | "nand cle"}; | 
|  | 358 | static const char * const xway_exin_grps[] = {"exin0", "exin1", "exin2"}; | 
|  | 359 | static const char * const xway_gpt_grps[] = {"gpt1", "gpt2", "gpt3"}; | 
|  | 360 | static const char * const xway_asc_grps[] = {"asc0", "asc0 cts rts"}; | 
|  | 361 | static const char * const xway_jtag_grps[] = {"jtag"}; | 
|  | 362 | static const char * const xway_stp_grps[] = {"stp"}; | 
|  | 363 | static const char * const xway_nmi_grps[] = {"nmi"}; | 
|  | 364 |  | 
|  | 365 | /* ar9/vr9/gr9 */ | 
|  | 366 | static const char * const xrx_mdio_grps[] = {"mdio"}; | 
|  | 367 | static const char * const xrx_ebu_grps[] = {"ebu a23", "ebu a24", | 
|  | 368 | "ebu a25", "ebu cs1", | 
|  | 369 | "ebu wait", "ebu clk", | 
|  | 370 | "nand ale", "nand cs1", | 
|  | 371 | "nand cle", "nand rdy", | 
|  | 372 | "nand rd"}; | 
|  | 373 | static const char * const xrx_exin_grps[] = {"exin0", "exin1", "exin2", | 
|  | 374 | "exin3", "exin4", "exin5"}; | 
|  | 375 | static const char * const xrx_pci_grps[] = {"gnt1", "gnt2", | 
|  | 376 | "gnt3", "gnt4", | 
|  | 377 | "req1", "req2", | 
|  | 378 | "req3", "req4"}; | 
|  | 379 |  | 
|  | 380 | /* ase */ | 
|  | 381 | static const char * const ase_exin_grps[] = {"exin0", "exin1", "exin2"}; | 
|  | 382 | static const char * const ase_gpt_grps[] = {"gpt1", "gpt2", "gpt3"}; | 
|  | 383 | static const char * const ase_dfe_grps[] = {"dfe"}; | 
|  | 384 | static const char * const ase_ephy_grps[] = {"ephy"}; | 
|  | 385 | static const char * const ase_asc_grps[] = {"asc"}; | 
|  | 386 | static const char * const ase_jtag_grps[] = {"jtag"}; | 
|  | 387 | static const char * const ase_stp_grps[] = {"stp"}; | 
|  | 388 | static const char * const ase_spi_grps[] = {"spi", "spi_cs1", | 
|  | 389 | "spi_cs2", "spi_cs3"}; | 
|  | 390 |  | 
|  | 391 | static const struct ltq_pmx_func danube_funcs[] = { | 
|  | 392 | {"spi",		ARRAY_AND_SIZE(xway_spi_grps)}, | 
|  | 393 | {"asc",		ARRAY_AND_SIZE(xway_asc_grps)}, | 
|  | 394 | {"cgu",		ARRAY_AND_SIZE(xway_cgu_grps)}, | 
|  | 395 | {"jtag",	ARRAY_AND_SIZE(xway_jtag_grps)}, | 
|  | 396 | {"exin",	ARRAY_AND_SIZE(xway_exin_grps)}, | 
|  | 397 | {"stp",		ARRAY_AND_SIZE(xway_stp_grps)}, | 
|  | 398 | {"gpt",		ARRAY_AND_SIZE(xway_gpt_grps)}, | 
|  | 399 | {"nmi",		ARRAY_AND_SIZE(xway_nmi_grps)}, | 
|  | 400 | {"pci",		ARRAY_AND_SIZE(xway_pci_grps)}, | 
|  | 401 | {"ebu",		ARRAY_AND_SIZE(xway_ebu_grps)}, | 
|  | 402 | }; | 
|  | 403 |  | 
|  | 404 | static const struct ltq_pmx_func xrx_funcs[] = { | 
|  | 405 | {"spi",		ARRAY_AND_SIZE(xway_spi_grps)}, | 
|  | 406 | {"asc",		ARRAY_AND_SIZE(xway_asc_grps)}, | 
|  | 407 | {"cgu",		ARRAY_AND_SIZE(xway_cgu_grps)}, | 
|  | 408 | {"jtag",	ARRAY_AND_SIZE(xway_jtag_grps)}, | 
|  | 409 | {"exin",	ARRAY_AND_SIZE(xrx_exin_grps)}, | 
|  | 410 | {"stp",		ARRAY_AND_SIZE(xway_stp_grps)}, | 
|  | 411 | {"gpt",		ARRAY_AND_SIZE(xway_gpt_grps)}, | 
|  | 412 | {"nmi",		ARRAY_AND_SIZE(xway_nmi_grps)}, | 
|  | 413 | {"pci",		ARRAY_AND_SIZE(xrx_pci_grps)}, | 
|  | 414 | {"ebu",		ARRAY_AND_SIZE(xrx_ebu_grps)}, | 
|  | 415 | {"mdio",	ARRAY_AND_SIZE(xrx_mdio_grps)}, | 
|  | 416 | }; | 
|  | 417 |  | 
|  | 418 | static const struct ltq_pmx_func ase_funcs[] = { | 
|  | 419 | {"spi",		ARRAY_AND_SIZE(ase_spi_grps)}, | 
|  | 420 | {"asc",		ARRAY_AND_SIZE(ase_asc_grps)}, | 
|  | 421 | {"jtag",	ARRAY_AND_SIZE(ase_jtag_grps)}, | 
|  | 422 | {"exin",	ARRAY_AND_SIZE(ase_exin_grps)}, | 
|  | 423 | {"stp",		ARRAY_AND_SIZE(ase_stp_grps)}, | 
|  | 424 | {"gpt",		ARRAY_AND_SIZE(ase_gpt_grps)}, | 
|  | 425 | {"ephy",	ARRAY_AND_SIZE(ase_ephy_grps)}, | 
|  | 426 | {"dfe",		ARRAY_AND_SIZE(ase_dfe_grps)}, | 
|  | 427 | }; | 
|  | 428 |  | 
|  | 429 | /* ---------  pinconf related code --------- */ | 
|  | 430 | static int xway_pinconf_get(struct pinctrl_dev *pctldev, | 
|  | 431 | unsigned pin, | 
|  | 432 | unsigned long *config) | 
|  | 433 | { | 
|  | 434 | struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctldev); | 
|  | 435 | enum ltq_pinconf_param param = LTQ_PINCONF_UNPACK_PARAM(*config); | 
|  | 436 | int port = PORT(pin); | 
|  | 437 | u32 reg; | 
|  | 438 |  | 
|  | 439 | switch (param) { | 
|  | 440 | case LTQ_PINCONF_PARAM_OPEN_DRAIN: | 
|  | 441 | if (port == PORT3) | 
|  | 442 | reg = GPIO3_OD; | 
|  | 443 | else | 
|  | 444 | reg = GPIO_OD(port); | 
|  | 445 | *config = LTQ_PINCONF_PACK(param, | 
|  | 446 | !!gpio_getbit(info->membase[0], reg, PORT_PIN(port))); | 
|  | 447 | break; | 
|  | 448 |  | 
|  | 449 | case LTQ_PINCONF_PARAM_PULL: | 
|  | 450 | if (port == PORT3) | 
|  | 451 | reg = GPIO3_PUDEN; | 
|  | 452 | else | 
|  | 453 | reg = GPIO_PUDEN(port); | 
|  | 454 | if (!gpio_getbit(info->membase[0], reg, PORT_PIN(port))) { | 
|  | 455 | *config = LTQ_PINCONF_PACK(param, 0); | 
|  | 456 | break; | 
|  | 457 | } | 
|  | 458 |  | 
|  | 459 | if (port == PORT3) | 
|  | 460 | reg = GPIO3_PUDSEL; | 
|  | 461 | else | 
|  | 462 | reg = GPIO_PUDSEL(port); | 
|  | 463 | if (!gpio_getbit(info->membase[0], reg, PORT_PIN(port))) | 
|  | 464 | *config = LTQ_PINCONF_PACK(param, 2); | 
|  | 465 | else | 
|  | 466 | *config = LTQ_PINCONF_PACK(param, 1); | 
|  | 467 | break; | 
|  | 468 |  | 
|  | 469 | default: | 
|  | 470 | dev_err(pctldev->dev, "Invalid config param %04x\n", param); | 
|  | 471 | return -ENOTSUPP; | 
|  | 472 | } | 
|  | 473 | return 0; | 
|  | 474 | } | 
|  | 475 |  | 
|  | 476 | static int xway_pinconf_set(struct pinctrl_dev *pctldev, | 
|  | 477 | unsigned pin, | 
|  | 478 | unsigned long config) | 
|  | 479 | { | 
|  | 480 | struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctldev); | 
|  | 481 | enum ltq_pinconf_param param = LTQ_PINCONF_UNPACK_PARAM(config); | 
|  | 482 | int arg = LTQ_PINCONF_UNPACK_ARG(config); | 
|  | 483 | int port = PORT(pin); | 
|  | 484 | u32 reg; | 
|  | 485 |  | 
|  | 486 | switch (param) { | 
|  | 487 | case LTQ_PINCONF_PARAM_OPEN_DRAIN: | 
|  | 488 | if (port == PORT3) | 
|  | 489 | reg = GPIO3_OD; | 
|  | 490 | else | 
|  | 491 | reg = GPIO_OD(port); | 
|  | 492 | gpio_setbit(info->membase[0], reg, PORT_PIN(port)); | 
|  | 493 | break; | 
|  | 494 |  | 
|  | 495 | case LTQ_PINCONF_PARAM_PULL: | 
|  | 496 | if (port == PORT3) | 
|  | 497 | reg = GPIO3_PUDEN; | 
|  | 498 | else | 
|  | 499 | reg = GPIO_PUDEN(port); | 
|  | 500 | if (arg == 0) { | 
|  | 501 | gpio_clearbit(info->membase[0], reg, PORT_PIN(port)); | 
|  | 502 | break; | 
|  | 503 | } | 
|  | 504 | gpio_setbit(info->membase[0], reg, PORT_PIN(port)); | 
|  | 505 |  | 
|  | 506 | if (port == PORT3) | 
|  | 507 | reg = GPIO3_PUDSEL; | 
|  | 508 | else | 
|  | 509 | reg = GPIO_PUDSEL(port); | 
|  | 510 | if (arg == 1) | 
|  | 511 | gpio_clearbit(info->membase[0], reg, PORT_PIN(port)); | 
|  | 512 | else if (arg == 2) | 
|  | 513 | gpio_setbit(info->membase[0], reg, PORT_PIN(port)); | 
|  | 514 | else | 
|  | 515 | dev_err(pctldev->dev, "Invalid pull value %d\n", arg); | 
|  | 516 | break; | 
|  | 517 |  | 
|  | 518 | default: | 
|  | 519 | dev_err(pctldev->dev, "Invalid config param %04x\n", param); | 
|  | 520 | return -ENOTSUPP; | 
|  | 521 | } | 
|  | 522 | return 0; | 
|  | 523 | } | 
|  | 524 |  | 
|  | 525 | struct pinconf_ops xway_pinconf_ops = { | 
|  | 526 | .pin_config_get	= xway_pinconf_get, | 
|  | 527 | .pin_config_set	= xway_pinconf_set, | 
|  | 528 | }; | 
|  | 529 |  | 
|  | 530 | static struct pinctrl_desc xway_pctrl_desc = { | 
|  | 531 | .owner		= THIS_MODULE, | 
|  | 532 | .confops	= &xway_pinconf_ops, | 
|  | 533 | }; | 
|  | 534 |  | 
|  | 535 | static inline int xway_mux_apply(struct pinctrl_dev *pctrldev, | 
|  | 536 | int pin, int mux) | 
|  | 537 | { | 
|  | 538 | struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev); | 
|  | 539 | int port = PORT(pin); | 
|  | 540 | u32 alt1_reg = GPIO_ALT1(pin); | 
|  | 541 |  | 
|  | 542 | if (port == PORT3) | 
|  | 543 | alt1_reg = GPIO3_ALT1; | 
|  | 544 |  | 
|  | 545 | if (mux & MUX_ALT0) | 
|  | 546 | gpio_setbit(info->membase[0], GPIO_ALT0(pin), PORT_PIN(pin)); | 
|  | 547 | else | 
|  | 548 | gpio_clearbit(info->membase[0], GPIO_ALT0(pin), PORT_PIN(pin)); | 
|  | 549 |  | 
|  | 550 | if (mux & MUX_ALT1) | 
|  | 551 | gpio_setbit(info->membase[0], alt1_reg, PORT_PIN(pin)); | 
|  | 552 | else | 
|  | 553 | gpio_clearbit(info->membase[0], alt1_reg, PORT_PIN(pin)); | 
|  | 554 |  | 
|  | 555 | return 0; | 
|  | 556 | } | 
|  | 557 |  | 
|  | 558 | static const struct ltq_cfg_param xway_cfg_params[] = { | 
|  | 559 | {"lantiq,pull",		LTQ_PINCONF_PARAM_PULL}, | 
|  | 560 | {"lantiq,open-drain",	LTQ_PINCONF_PARAM_OPEN_DRAIN}, | 
|  | 561 | }; | 
|  | 562 |  | 
|  | 563 | static struct ltq_pinmux_info xway_info = { | 
|  | 564 | .desc		= &xway_pctrl_desc, | 
|  | 565 | .apply_mux	= xway_mux_apply, | 
|  | 566 | .params		= xway_cfg_params, | 
|  | 567 | .num_params	= ARRAY_SIZE(xway_cfg_params), | 
|  | 568 | }; | 
|  | 569 |  | 
|  | 570 | /* ---------  gpio_chip related code --------- */ | 
|  | 571 | static void xway_gpio_set(struct gpio_chip *chip, unsigned int pin, int val) | 
|  | 572 | { | 
|  | 573 | struct ltq_pinmux_info *info = dev_get_drvdata(chip->dev); | 
|  | 574 |  | 
|  | 575 | if (val) | 
|  | 576 | gpio_setbit(info->membase[0], GPIO_OUT(pin), PORT_PIN(pin)); | 
|  | 577 | else | 
|  | 578 | gpio_clearbit(info->membase[0], GPIO_OUT(pin), PORT_PIN(pin)); | 
|  | 579 | } | 
|  | 580 |  | 
|  | 581 | static int xway_gpio_get(struct gpio_chip *chip, unsigned int pin) | 
|  | 582 | { | 
|  | 583 | struct ltq_pinmux_info *info = dev_get_drvdata(chip->dev); | 
|  | 584 |  | 
|  | 585 | return gpio_getbit(info->membase[0], GPIO_IN(pin), PORT_PIN(pin)); | 
|  | 586 | } | 
|  | 587 |  | 
|  | 588 | static int xway_gpio_dir_in(struct gpio_chip *chip, unsigned int pin) | 
|  | 589 | { | 
|  | 590 | struct ltq_pinmux_info *info = dev_get_drvdata(chip->dev); | 
|  | 591 |  | 
|  | 592 | gpio_clearbit(info->membase[0], GPIO_DIR(pin), PORT_PIN(pin)); | 
|  | 593 |  | 
|  | 594 | return 0; | 
|  | 595 | } | 
|  | 596 |  | 
|  | 597 | static int xway_gpio_dir_out(struct gpio_chip *chip, unsigned int pin, int val) | 
|  | 598 | { | 
|  | 599 | struct ltq_pinmux_info *info = dev_get_drvdata(chip->dev); | 
|  | 600 |  | 
|  | 601 | gpio_setbit(info->membase[0], GPIO_DIR(pin), PORT_PIN(pin)); | 
|  | 602 | xway_gpio_set(chip, pin, val); | 
|  | 603 |  | 
|  | 604 | return 0; | 
|  | 605 | } | 
|  | 606 |  | 
|  | 607 | static int xway_gpio_req(struct gpio_chip *chip, unsigned offset) | 
|  | 608 | { | 
|  | 609 | int gpio = chip->base + offset; | 
|  | 610 |  | 
|  | 611 | return pinctrl_request_gpio(gpio); | 
|  | 612 | } | 
|  | 613 |  | 
|  | 614 | static void xway_gpio_free(struct gpio_chip *chip, unsigned offset) | 
|  | 615 | { | 
|  | 616 | int gpio = chip->base + offset; | 
|  | 617 |  | 
|  | 618 | pinctrl_free_gpio(gpio); | 
|  | 619 | } | 
|  | 620 |  | 
|  | 621 | static struct gpio_chip xway_chip = { | 
|  | 622 | .label = "gpio-xway", | 
|  | 623 | .direction_input = xway_gpio_dir_in, | 
|  | 624 | .direction_output = xway_gpio_dir_out, | 
|  | 625 | .get = xway_gpio_get, | 
|  | 626 | .set = xway_gpio_set, | 
|  | 627 | .request = xway_gpio_req, | 
|  | 628 | .free = xway_gpio_free, | 
|  | 629 | .base = -1, | 
|  | 630 | }; | 
|  | 631 |  | 
|  | 632 |  | 
|  | 633 | /* --------- register the pinctrl layer --------- */ | 
|  | 634 | static const unsigned xway_exin_pin_map[] = {GPIO0, GPIO1, GPIO2, GPIO39, GPIO46, GPIO9}; | 
|  | 635 | static const unsigned ase_exin_pins_map[] = {GPIO6, GPIO29, GPIO0}; | 
|  | 636 |  | 
|  | 637 | static struct pinctrl_xway_soc { | 
|  | 638 | int pin_count; | 
|  | 639 | const struct ltq_mfp_pin *mfp; | 
|  | 640 | const struct ltq_pin_group *grps; | 
|  | 641 | unsigned int num_grps; | 
|  | 642 | const struct ltq_pmx_func *funcs; | 
|  | 643 | unsigned int num_funcs; | 
|  | 644 | const unsigned *exin; | 
|  | 645 | unsigned int num_exin; | 
|  | 646 | } soc_cfg[] = { | 
|  | 647 | /* legacy xway */ | 
|  | 648 | {XWAY_MAX_PIN, xway_mfp, | 
|  | 649 | xway_grps, ARRAY_SIZE(xway_grps), | 
|  | 650 | danube_funcs, ARRAY_SIZE(danube_funcs), | 
|  | 651 | xway_exin_pin_map, 3}, | 
|  | 652 | /* xway xr9 series */ | 
|  | 653 | {XR9_MAX_PIN, xway_mfp, | 
|  | 654 | xway_grps, ARRAY_SIZE(xway_grps), | 
|  | 655 | xrx_funcs, ARRAY_SIZE(xrx_funcs), | 
|  | 656 | xway_exin_pin_map, 6}, | 
|  | 657 | /* xway ase series */ | 
|  | 658 | {XWAY_MAX_PIN, ase_mfp, | 
|  | 659 | ase_grps, ARRAY_SIZE(ase_grps), | 
|  | 660 | ase_funcs, ARRAY_SIZE(ase_funcs), | 
|  | 661 | ase_exin_pins_map, 3}, | 
|  | 662 | }; | 
|  | 663 |  | 
|  | 664 | static struct pinctrl_gpio_range xway_gpio_range = { | 
|  | 665 | .name	= "XWAY GPIO", | 
|  | 666 | .gc	= &xway_chip, | 
|  | 667 | }; | 
|  | 668 |  | 
|  | 669 | static const struct of_device_id xway_match[] = { | 
|  | 670 | { .compatible = "lantiq,pinctrl-xway", .data = &soc_cfg[0]}, | 
|  | 671 | { .compatible = "lantiq,pinctrl-xr9", .data = &soc_cfg[1]}, | 
|  | 672 | { .compatible = "lantiq,pinctrl-ase", .data = &soc_cfg[2]}, | 
|  | 673 | {}, | 
|  | 674 | }; | 
|  | 675 | MODULE_DEVICE_TABLE(of, xway_match); | 
|  | 676 |  | 
|  | 677 | static int __devinit pinmux_xway_probe(struct platform_device *pdev) | 
|  | 678 | { | 
|  | 679 | const struct of_device_id *match; | 
|  | 680 | const struct pinctrl_xway_soc *xway_soc; | 
|  | 681 | struct resource *res; | 
|  | 682 | int ret, i; | 
|  | 683 |  | 
|  | 684 | /* get and remap our register range */ | 
|  | 685 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 
|  | 686 | if (!res) { | 
|  | 687 | dev_err(&pdev->dev, "Failed to get resource\n"); | 
|  | 688 | return -ENOENT; | 
|  | 689 | } | 
|  | 690 | xway_info.membase[0] = devm_request_and_ioremap(&pdev->dev, res); | 
|  | 691 | if (!xway_info.membase[0]) { | 
|  | 692 | dev_err(&pdev->dev, "Failed to remap resource\n"); | 
|  | 693 | return -ENOMEM; | 
|  | 694 | } | 
|  | 695 |  | 
|  | 696 | match = of_match_device(xway_match, &pdev->dev); | 
|  | 697 | if (match) | 
|  | 698 | xway_soc = (const struct pinctrl_xway_soc *) match->data; | 
|  | 699 | else | 
|  | 700 | xway_soc = &soc_cfg[0]; | 
|  | 701 |  | 
|  | 702 | /* find out how many pads we have */ | 
|  | 703 | xway_chip.ngpio = xway_soc->pin_count; | 
|  | 704 |  | 
|  | 705 | /* load our pad descriptors */ | 
|  | 706 | xway_info.pads = devm_kzalloc(&pdev->dev, | 
|  | 707 | sizeof(struct pinctrl_pin_desc) * xway_chip.ngpio, | 
|  | 708 | GFP_KERNEL); | 
|  | 709 | if (!xway_info.pads) { | 
|  | 710 | dev_err(&pdev->dev, "Failed to allocate pads\n"); | 
|  | 711 | return -ENOMEM; | 
|  | 712 | } | 
|  | 713 | for (i = 0; i < xway_chip.ngpio; i++) { | 
|  | 714 | /* strlen("ioXY") + 1 = 5 */ | 
|  | 715 | char *name = devm_kzalloc(&pdev->dev, 5, GFP_KERNEL); | 
|  | 716 |  | 
|  | 717 | if (!name) { | 
|  | 718 | dev_err(&pdev->dev, "Failed to allocate pad name\n"); | 
|  | 719 | return -ENOMEM; | 
|  | 720 | } | 
|  | 721 | snprintf(name, 5, "io%d", i); | 
|  | 722 | xway_info.pads[i].number = GPIO0 + i; | 
|  | 723 | xway_info.pads[i].name = name; | 
|  | 724 | } | 
|  | 725 | xway_pctrl_desc.pins = xway_info.pads; | 
|  | 726 |  | 
|  | 727 | /* load the gpio chip */ | 
|  | 728 | xway_chip.dev = &pdev->dev; | 
|  | 729 | of_gpiochip_add(&xway_chip); | 
|  | 730 | ret = gpiochip_add(&xway_chip); | 
|  | 731 | if (ret) { | 
|  | 732 | dev_err(&pdev->dev, "Failed to register gpio chip\n"); | 
|  | 733 | return ret; | 
|  | 734 | } | 
|  | 735 |  | 
|  | 736 | /* setup the data needed by pinctrl */ | 
|  | 737 | xway_pctrl_desc.name	= dev_name(&pdev->dev); | 
|  | 738 | xway_pctrl_desc.npins	= xway_chip.ngpio; | 
|  | 739 |  | 
|  | 740 | xway_info.num_pads	= xway_chip.ngpio; | 
|  | 741 | xway_info.num_mfp	= xway_chip.ngpio; | 
|  | 742 | xway_info.mfp		= xway_soc->mfp; | 
|  | 743 | xway_info.grps		= xway_soc->grps; | 
|  | 744 | xway_info.num_grps	= xway_soc->num_grps; | 
|  | 745 | xway_info.funcs		= xway_soc->funcs; | 
|  | 746 | xway_info.num_funcs	= xway_soc->num_funcs; | 
|  | 747 | xway_info.exin		= xway_soc->exin; | 
|  | 748 | xway_info.num_exin	= xway_soc->num_exin; | 
|  | 749 |  | 
|  | 750 | /* register with the generic lantiq layer */ | 
|  | 751 | ret = ltq_pinctrl_register(pdev, &xway_info); | 
|  | 752 | if (ret) { | 
|  | 753 | dev_err(&pdev->dev, "Failed to register pinctrl driver\n"); | 
|  | 754 | return ret; | 
|  | 755 | } | 
|  | 756 |  | 
|  | 757 | /* finish with registering the gpio range in pinctrl */ | 
|  | 758 | xway_gpio_range.npins = xway_chip.ngpio; | 
|  | 759 | xway_gpio_range.base = xway_chip.base; | 
|  | 760 | pinctrl_add_gpio_range(xway_info.pctrl, &xway_gpio_range); | 
|  | 761 | dev_info(&pdev->dev, "Init done\n"); | 
|  | 762 | return 0; | 
|  | 763 | } | 
|  | 764 |  | 
|  | 765 | static struct platform_driver pinmux_xway_driver = { | 
|  | 766 | .probe	= pinmux_xway_probe, | 
|  | 767 | .driver = { | 
|  | 768 | .name	= "pinctrl-xway", | 
|  | 769 | .owner	= THIS_MODULE, | 
|  | 770 | .of_match_table = xway_match, | 
|  | 771 | }, | 
|  | 772 | }; | 
|  | 773 |  | 
|  | 774 | static int __init pinmux_xway_init(void) | 
|  | 775 | { | 
|  | 776 | return platform_driver_register(&pinmux_xway_driver); | 
|  | 777 | } | 
|  | 778 |  | 
|  | 779 | core_initcall_sync(pinmux_xway_init); |