1 /* 2 * Marvell Armada 370 pinctrl driver based on mvebu pinctrl core 3 * 4 * Copyright (C) 2012 Marvell 5 * 6 * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 */ 13 14 #include <linux/err.h> 15 #include <linux/init.h> 16 #include <linux/io.h> 17 #include <linux/module.h> 18 #include <linux/platform_device.h> 19 #include <linux/clk.h> 20 #include <linux/of.h> 21 #include <linux/of_device.h> 22 #include <linux/pinctrl/pinctrl.h> 23 24 #include "pinctrl-mvebu.h" 25 26 static void __iomem *mpp_base; 27 28 static int armada_370_mpp_ctrl_get(unsigned pid, unsigned long *config) 29 { 30 return default_mpp_ctrl_get(mpp_base, pid, config); 31 } 32 33 static int armada_370_mpp_ctrl_set(unsigned pid, unsigned long config) 34 { 35 return default_mpp_ctrl_set(mpp_base, pid, config); 36 } 37 38 static struct mvebu_mpp_mode mv88f6710_mpp_modes[] = { 39 MPP_MODE(0, 40 MPP_FUNCTION(0x0, "gpio", NULL), 41 MPP_FUNCTION(0x1, "uart0", "rxd")), 42 MPP_MODE(1, 43 MPP_FUNCTION(0x0, "gpo", NULL), 44 MPP_FUNCTION(0x1, "uart0", "txd")), 45 MPP_MODE(2, 46 MPP_FUNCTION(0x0, "gpio", NULL), 47 MPP_FUNCTION(0x1, "i2c0", "sck"), 48 MPP_FUNCTION(0x2, "uart0", "txd")), 49 MPP_MODE(3, 50 MPP_FUNCTION(0x0, "gpio", NULL), 51 MPP_FUNCTION(0x1, "i2c0", "sda"), 52 MPP_FUNCTION(0x2, "uart0", "rxd")), 53 MPP_MODE(4, 54 MPP_FUNCTION(0x0, "gpio", NULL), 55 MPP_FUNCTION(0x1, "vdd", "cpu-pd")), 56 MPP_MODE(5, 57 MPP_FUNCTION(0x0, "gpo", NULL), 58 MPP_FUNCTION(0x1, "ge0", "txclkout"), 59 MPP_FUNCTION(0x2, "uart1", "txd"), 60 MPP_FUNCTION(0x4, "spi1", "sck"), 61 MPP_FUNCTION(0x5, "audio", "mclk")), 62 MPP_MODE(6, 63 MPP_FUNCTION(0x0, "gpio", NULL), 64 MPP_FUNCTION(0x1, "ge0", "txd0"), 65 MPP_FUNCTION(0x2, "sata0", "prsnt"), 66 MPP_FUNCTION(0x4, "tdm", "rst"), 67 MPP_FUNCTION(0x5, "audio", "sdo")), 68 MPP_MODE(7, 69 MPP_FUNCTION(0x0, "gpo", NULL), 70 MPP_FUNCTION(0x1, "ge0", "txd1"), 71 MPP_FUNCTION(0x4, "tdm", "dtx"), 72 MPP_FUNCTION(0x5, "audio", "lrclk")), 73 MPP_MODE(8, 74 MPP_FUNCTION(0x0, "gpio", NULL), 75 MPP_FUNCTION(0x1, "ge0", "txd2"), 76 MPP_FUNCTION(0x2, "uart0", "rts"), 77 MPP_FUNCTION(0x4, "tdm", "drx"), 78 MPP_FUNCTION(0x5, "audio", "bclk")), 79 MPP_MODE(9, 80 MPP_FUNCTION(0x0, "gpo", NULL), 81 MPP_FUNCTION(0x1, "ge0", "txd3"), 82 MPP_FUNCTION(0x2, "uart1", "txd"), 83 MPP_FUNCTION(0x3, "sd0", "clk"), 84 MPP_FUNCTION(0x5, "audio", "spdifo")), 85 MPP_MODE(10, 86 MPP_FUNCTION(0x0, "gpio", NULL), 87 MPP_FUNCTION(0x1, "ge0", "txctl"), 88 MPP_FUNCTION(0x2, "uart0", "cts"), 89 MPP_FUNCTION(0x4, "tdm", "fsync"), 90 MPP_FUNCTION(0x5, "audio", "sdi")), 91 MPP_MODE(11, 92 MPP_FUNCTION(0x0, "gpio", NULL), 93 MPP_FUNCTION(0x1, "ge0", "rxd0"), 94 MPP_FUNCTION(0x2, "uart1", "rxd"), 95 MPP_FUNCTION(0x3, "sd0", "cmd"), 96 MPP_FUNCTION(0x4, "spi0", "cs1"), 97 MPP_FUNCTION(0x5, "sata1", "prsnt"), 98 MPP_FUNCTION(0x6, "spi1", "cs1")), 99 MPP_MODE(12, 100 MPP_FUNCTION(0x0, "gpio", NULL), 101 MPP_FUNCTION(0x1, "ge0", "rxd1"), 102 MPP_FUNCTION(0x2, "i2c1", "sda"), 103 MPP_FUNCTION(0x3, "sd0", "d0"), 104 MPP_FUNCTION(0x4, "spi1", "cs0"), 105 MPP_FUNCTION(0x5, "audio", "spdifi")), 106 MPP_MODE(13, 107 MPP_FUNCTION(0x0, "gpio", NULL), 108 MPP_FUNCTION(0x1, "ge0", "rxd2"), 109 MPP_FUNCTION(0x2, "i2c1", "sck"), 110 MPP_FUNCTION(0x3, "sd0", "d1"), 111 MPP_FUNCTION(0x4, "tdm", "pclk"), 112 MPP_FUNCTION(0x5, "audio", "rmclk")), 113 MPP_MODE(14, 114 MPP_FUNCTION(0x0, "gpio", NULL), 115 MPP_FUNCTION(0x1, "ge0", "rxd3"), 116 MPP_FUNCTION(0x2, "pcie", "clkreq0"), 117 MPP_FUNCTION(0x3, "sd0", "d2"), 118 MPP_FUNCTION(0x4, "spi1", "mosi"), 119 MPP_FUNCTION(0x5, "spi0", "cs2")), 120 MPP_MODE(15, 121 MPP_FUNCTION(0x0, "gpio", NULL), 122 MPP_FUNCTION(0x1, "ge0", "rxctl"), 123 MPP_FUNCTION(0x2, "pcie", "clkreq1"), 124 MPP_FUNCTION(0x3, "sd0", "d3"), 125 MPP_FUNCTION(0x4, "spi1", "miso"), 126 MPP_FUNCTION(0x5, "spi0", "cs3")), 127 MPP_MODE(16, 128 MPP_FUNCTION(0x0, "gpio", NULL), 129 MPP_FUNCTION(0x1, "ge0", "rxclk"), 130 MPP_FUNCTION(0x2, "uart1", "rxd"), 131 MPP_FUNCTION(0x4, "tdm", "int"), 132 MPP_FUNCTION(0x5, "audio", "extclk")), 133 MPP_MODE(17, 134 MPP_FUNCTION(0x0, "gpo", NULL), 135 MPP_FUNCTION(0x1, "ge", "mdc")), 136 MPP_MODE(18, 137 MPP_FUNCTION(0x0, "gpio", NULL), 138 MPP_FUNCTION(0x1, "ge", "mdio")), 139 MPP_MODE(19, 140 MPP_FUNCTION(0x0, "gpio", NULL), 141 MPP_FUNCTION(0x1, "ge0", "txclk"), 142 MPP_FUNCTION(0x2, "ge1", "txclkout"), 143 MPP_FUNCTION(0x4, "tdm", "pclk")), 144 MPP_MODE(20, 145 MPP_FUNCTION(0x0, "gpo", NULL), 146 MPP_FUNCTION(0x1, "ge0", "txd4"), 147 MPP_FUNCTION(0x2, "ge1", "txd0")), 148 MPP_MODE(21, 149 MPP_FUNCTION(0x0, "gpo", NULL), 150 MPP_FUNCTION(0x1, "ge0", "txd5"), 151 MPP_FUNCTION(0x2, "ge1", "txd1"), 152 MPP_FUNCTION(0x4, "uart1", "txd")), 153 MPP_MODE(22, 154 MPP_FUNCTION(0x0, "gpo", NULL), 155 MPP_FUNCTION(0x1, "ge0", "txd6"), 156 MPP_FUNCTION(0x2, "ge1", "txd2"), 157 MPP_FUNCTION(0x4, "uart0", "rts")), 158 MPP_MODE(23, 159 MPP_FUNCTION(0x0, "gpo", NULL), 160 MPP_FUNCTION(0x1, "ge0", "txd7"), 161 MPP_FUNCTION(0x2, "ge1", "txd3"), 162 MPP_FUNCTION(0x4, "spi1", "mosi")), 163 MPP_MODE(24, 164 MPP_FUNCTION(0x0, "gpio", NULL), 165 MPP_FUNCTION(0x1, "ge0", "col"), 166 MPP_FUNCTION(0x2, "ge1", "txctl"), 167 MPP_FUNCTION(0x4, "spi1", "cs0")), 168 MPP_MODE(25, 169 MPP_FUNCTION(0x0, "gpio", NULL), 170 MPP_FUNCTION(0x1, "ge0", "rxerr"), 171 MPP_FUNCTION(0x2, "ge1", "rxd0"), 172 MPP_FUNCTION(0x4, "uart1", "rxd")), 173 MPP_MODE(26, 174 MPP_FUNCTION(0x0, "gpio", NULL), 175 MPP_FUNCTION(0x1, "ge0", "crs"), 176 MPP_FUNCTION(0x2, "ge1", "rxd1"), 177 MPP_FUNCTION(0x4, "spi1", "miso")), 178 MPP_MODE(27, 179 MPP_FUNCTION(0x0, "gpio", NULL), 180 MPP_FUNCTION(0x1, "ge0", "rxd4"), 181 MPP_FUNCTION(0x2, "ge1", "rxd2"), 182 MPP_FUNCTION(0x4, "uart0", "cts")), 183 MPP_MODE(28, 184 MPP_FUNCTION(0x0, "gpio", NULL), 185 MPP_FUNCTION(0x1, "ge0", "rxd5"), 186 MPP_FUNCTION(0x2, "ge1", "rxd3")), 187 MPP_MODE(29, 188 MPP_FUNCTION(0x0, "gpio", NULL), 189 MPP_FUNCTION(0x1, "ge0", "rxd6"), 190 MPP_FUNCTION(0x2, "ge1", "rxctl"), 191 MPP_FUNCTION(0x4, "i2c1", "sda")), 192 MPP_MODE(30, 193 MPP_FUNCTION(0x0, "gpio", NULL), 194 MPP_FUNCTION(0x1, "ge0", "rxd7"), 195 MPP_FUNCTION(0x2, "ge1", "rxclk"), 196 MPP_FUNCTION(0x4, "i2c1", "sck")), 197 MPP_MODE(31, 198 MPP_FUNCTION(0x0, "gpio", NULL), 199 MPP_FUNCTION(0x3, "tclk", NULL), 200 MPP_FUNCTION(0x4, "ge0", "txerr")), 201 MPP_MODE(32, 202 MPP_FUNCTION(0x0, "gpio", NULL), 203 MPP_FUNCTION(0x1, "spi0", "cs0")), 204 MPP_MODE(33, 205 MPP_FUNCTION(0x0, "gpio", NULL), 206 MPP_FUNCTION(0x1, "dev", "bootcs"), 207 MPP_FUNCTION(0x2, "spi0", "cs0")), 208 MPP_MODE(34, 209 MPP_FUNCTION(0x0, "gpo", NULL), 210 MPP_FUNCTION(0x1, "dev", "we0"), 211 MPP_FUNCTION(0x2, "spi0", "mosi")), 212 MPP_MODE(35, 213 MPP_FUNCTION(0x0, "gpo", NULL), 214 MPP_FUNCTION(0x1, "dev", "oe"), 215 MPP_FUNCTION(0x2, "spi0", "sck")), 216 MPP_MODE(36, 217 MPP_FUNCTION(0x0, "gpo", NULL), 218 MPP_FUNCTION(0x1, "dev", "a1"), 219 MPP_FUNCTION(0x2, "spi0", "miso")), 220 MPP_MODE(37, 221 MPP_FUNCTION(0x0, "gpo", NULL), 222 MPP_FUNCTION(0x1, "dev", "a0"), 223 MPP_FUNCTION(0x2, "sata0", "prsnt")), 224 MPP_MODE(38, 225 MPP_FUNCTION(0x0, "gpio", NULL), 226 MPP_FUNCTION(0x1, "dev", "ready"), 227 MPP_FUNCTION(0x2, "uart1", "cts"), 228 MPP_FUNCTION(0x3, "uart0", "cts")), 229 MPP_MODE(39, 230 MPP_FUNCTION(0x0, "gpo", NULL), 231 MPP_FUNCTION(0x1, "dev", "ad0"), 232 MPP_FUNCTION(0x2, "audio", "spdifo")), 233 MPP_MODE(40, 234 MPP_FUNCTION(0x0, "gpio", NULL), 235 MPP_FUNCTION(0x1, "dev", "ad1"), 236 MPP_FUNCTION(0x2, "uart1", "rts"), 237 MPP_FUNCTION(0x3, "uart0", "rts")), 238 MPP_MODE(41, 239 MPP_FUNCTION(0x0, "gpio", NULL), 240 MPP_FUNCTION(0x1, "dev", "ad2"), 241 MPP_FUNCTION(0x2, "uart1", "rxd")), 242 MPP_MODE(42, 243 MPP_FUNCTION(0x0, "gpo", NULL), 244 MPP_FUNCTION(0x1, "dev", "ad3"), 245 MPP_FUNCTION(0x2, "uart1", "txd")), 246 MPP_MODE(43, 247 MPP_FUNCTION(0x0, "gpo", NULL), 248 MPP_FUNCTION(0x1, "dev", "ad4"), 249 MPP_FUNCTION(0x2, "audio", "bclk")), 250 MPP_MODE(44, 251 MPP_FUNCTION(0x0, "gpo", NULL), 252 MPP_FUNCTION(0x1, "dev", "ad5"), 253 MPP_FUNCTION(0x2, "audio", "mclk")), 254 MPP_MODE(45, 255 MPP_FUNCTION(0x0, "gpo", NULL), 256 MPP_FUNCTION(0x1, "dev", "ad6"), 257 MPP_FUNCTION(0x2, "audio", "lrclk")), 258 MPP_MODE(46, 259 MPP_FUNCTION(0x0, "gpo", NULL), 260 MPP_FUNCTION(0x1, "dev", "ad7"), 261 MPP_FUNCTION(0x2, "audio", "sdo")), 262 MPP_MODE(47, 263 MPP_FUNCTION(0x0, "gpo", NULL), 264 MPP_FUNCTION(0x1, "dev", "ad8"), 265 MPP_FUNCTION(0x3, "sd0", "clk"), 266 MPP_FUNCTION(0x5, "audio", "spdifo")), 267 MPP_MODE(48, 268 MPP_FUNCTION(0x0, "gpio", NULL), 269 MPP_FUNCTION(0x1, "dev", "ad9"), 270 MPP_FUNCTION(0x2, "uart0", "rts"), 271 MPP_FUNCTION(0x3, "sd0", "cmd"), 272 MPP_FUNCTION(0x4, "sata1", "prsnt"), 273 MPP_FUNCTION(0x5, "spi0", "cs1")), 274 MPP_MODE(49, 275 MPP_FUNCTION(0x0, "gpio", NULL), 276 MPP_FUNCTION(0x1, "dev", "ad10"), 277 MPP_FUNCTION(0x2, "pcie", "clkreq1"), 278 MPP_FUNCTION(0x3, "sd0", "d0"), 279 MPP_FUNCTION(0x4, "spi1", "cs0"), 280 MPP_FUNCTION(0x5, "audio", "spdifi")), 281 MPP_MODE(50, 282 MPP_FUNCTION(0x0, "gpio", NULL), 283 MPP_FUNCTION(0x1, "dev", "ad11"), 284 MPP_FUNCTION(0x2, "uart0", "cts"), 285 MPP_FUNCTION(0x3, "sd0", "d1"), 286 MPP_FUNCTION(0x4, "spi1", "miso"), 287 MPP_FUNCTION(0x5, "audio", "rmclk")), 288 MPP_MODE(51, 289 MPP_FUNCTION(0x0, "gpio", NULL), 290 MPP_FUNCTION(0x1, "dev", "ad12"), 291 MPP_FUNCTION(0x2, "i2c1", "sda"), 292 MPP_FUNCTION(0x3, "sd0", "d2"), 293 MPP_FUNCTION(0x4, "spi1", "mosi")), 294 MPP_MODE(52, 295 MPP_FUNCTION(0x0, "gpio", NULL), 296 MPP_FUNCTION(0x1, "dev", "ad13"), 297 MPP_FUNCTION(0x2, "i2c1", "sck"), 298 MPP_FUNCTION(0x3, "sd0", "d3"), 299 MPP_FUNCTION(0x4, "spi1", "sck")), 300 MPP_MODE(53, 301 MPP_FUNCTION(0x0, "gpio", NULL), 302 MPP_FUNCTION(0x1, "dev", "ad14"), 303 MPP_FUNCTION(0x2, "sd0", "clk"), 304 MPP_FUNCTION(0x3, "tdm", "pclk"), 305 MPP_FUNCTION(0x4, "spi0", "cs2"), 306 MPP_FUNCTION(0x5, "pcie", "clkreq1")), 307 MPP_MODE(54, 308 MPP_FUNCTION(0x0, "gpo", NULL), 309 MPP_FUNCTION(0x1, "dev", "ad15"), 310 MPP_FUNCTION(0x3, "tdm", "dtx")), 311 MPP_MODE(55, 312 MPP_FUNCTION(0x0, "gpio", NULL), 313 MPP_FUNCTION(0x1, "dev", "cs1"), 314 MPP_FUNCTION(0x2, "uart1", "txd"), 315 MPP_FUNCTION(0x3, "tdm", "rst"), 316 MPP_FUNCTION(0x4, "sata1", "prsnt"), 317 MPP_FUNCTION(0x5, "sata0", "prsnt")), 318 MPP_MODE(56, 319 MPP_FUNCTION(0x0, "gpio", NULL), 320 MPP_FUNCTION(0x1, "dev", "cs2"), 321 MPP_FUNCTION(0x2, "uart1", "cts"), 322 MPP_FUNCTION(0x3, "uart0", "cts"), 323 MPP_FUNCTION(0x4, "spi0", "cs3"), 324 MPP_FUNCTION(0x5, "pcie", "clkreq0"), 325 MPP_FUNCTION(0x6, "spi1", "cs1")), 326 MPP_MODE(57, 327 MPP_FUNCTION(0x0, "gpio", NULL), 328 MPP_FUNCTION(0x1, "dev", "cs3"), 329 MPP_FUNCTION(0x2, "uart1", "rxd"), 330 MPP_FUNCTION(0x3, "tdm", "fsync"), 331 MPP_FUNCTION(0x4, "sata0", "prsnt"), 332 MPP_FUNCTION(0x5, "audio", "sdo")), 333 MPP_MODE(58, 334 MPP_FUNCTION(0x0, "gpio", NULL), 335 MPP_FUNCTION(0x1, "dev", "cs0"), 336 MPP_FUNCTION(0x2, "uart1", "rts"), 337 MPP_FUNCTION(0x3, "tdm", "int"), 338 MPP_FUNCTION(0x5, "audio", "extclk"), 339 MPP_FUNCTION(0x6, "uart0", "rts")), 340 MPP_MODE(59, 341 MPP_FUNCTION(0x0, "gpo", NULL), 342 MPP_FUNCTION(0x1, "dev", "ale0"), 343 MPP_FUNCTION(0x2, "uart1", "rts"), 344 MPP_FUNCTION(0x3, "uart0", "rts"), 345 MPP_FUNCTION(0x5, "audio", "bclk")), 346 MPP_MODE(60, 347 MPP_FUNCTION(0x0, "gpio", NULL), 348 MPP_FUNCTION(0x1, "dev", "ale1"), 349 MPP_FUNCTION(0x2, "uart1", "rxd"), 350 MPP_FUNCTION(0x3, "sata0", "prsnt"), 351 MPP_FUNCTION(0x4, "pcie", "rstout"), 352 MPP_FUNCTION(0x5, "audio", "sdi")), 353 MPP_MODE(61, 354 MPP_FUNCTION(0x0, "gpo", NULL), 355 MPP_FUNCTION(0x1, "dev", "we1"), 356 MPP_FUNCTION(0x2, "uart1", "txd"), 357 MPP_FUNCTION(0x5, "audio", "lrclk")), 358 MPP_MODE(62, 359 MPP_FUNCTION(0x0, "gpio", NULL), 360 MPP_FUNCTION(0x1, "dev", "a2"), 361 MPP_FUNCTION(0x2, "uart1", "cts"), 362 MPP_FUNCTION(0x3, "tdm", "drx"), 363 MPP_FUNCTION(0x4, "pcie", "clkreq0"), 364 MPP_FUNCTION(0x5, "audio", "mclk"), 365 MPP_FUNCTION(0x6, "uart0", "cts")), 366 MPP_MODE(63, 367 MPP_FUNCTION(0x0, "gpio", NULL), 368 MPP_FUNCTION(0x1, "spi0", "sck"), 369 MPP_FUNCTION(0x2, "tclk", NULL)), 370 MPP_MODE(64, 371 MPP_FUNCTION(0x0, "gpio", NULL), 372 MPP_FUNCTION(0x1, "spi0", "miso"), 373 MPP_FUNCTION(0x2, "spi0", "cs1")), 374 MPP_MODE(65, 375 MPP_FUNCTION(0x0, "gpio", NULL), 376 MPP_FUNCTION(0x1, "spi0", "mosi"), 377 MPP_FUNCTION(0x2, "spi0", "cs2")), 378 }; 379 380 static struct mvebu_pinctrl_soc_info armada_370_pinctrl_info; 381 382 static const struct of_device_id armada_370_pinctrl_of_match[] = { 383 { .compatible = "marvell,mv88f6710-pinctrl" }, 384 { }, 385 }; 386 387 static struct mvebu_mpp_ctrl mv88f6710_mpp_controls[] = { 388 MPP_FUNC_CTRL(0, 65, NULL, armada_370_mpp_ctrl), 389 }; 390 391 static struct pinctrl_gpio_range mv88f6710_mpp_gpio_ranges[] = { 392 MPP_GPIO_RANGE(0, 0, 0, 32), 393 MPP_GPIO_RANGE(1, 32, 32, 32), 394 MPP_GPIO_RANGE(2, 64, 64, 2), 395 }; 396 397 static int armada_370_pinctrl_probe(struct platform_device *pdev) 398 { 399 struct mvebu_pinctrl_soc_info *soc = &armada_370_pinctrl_info; 400 struct resource *res; 401 402 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 403 mpp_base = devm_ioremap_resource(&pdev->dev, res); 404 if (IS_ERR(mpp_base)) 405 return PTR_ERR(mpp_base); 406 407 soc->variant = 0; /* no variants for Armada 370 */ 408 soc->controls = mv88f6710_mpp_controls; 409 soc->ncontrols = ARRAY_SIZE(mv88f6710_mpp_controls); 410 soc->modes = mv88f6710_mpp_modes; 411 soc->nmodes = ARRAY_SIZE(mv88f6710_mpp_modes); 412 soc->gpioranges = mv88f6710_mpp_gpio_ranges; 413 soc->ngpioranges = ARRAY_SIZE(mv88f6710_mpp_gpio_ranges); 414 415 pdev->dev.platform_data = soc; 416 417 return mvebu_pinctrl_probe(pdev); 418 } 419 420 static int armada_370_pinctrl_remove(struct platform_device *pdev) 421 { 422 return mvebu_pinctrl_remove(pdev); 423 } 424 425 static struct platform_driver armada_370_pinctrl_driver = { 426 .driver = { 427 .name = "armada-370-pinctrl", 428 .of_match_table = armada_370_pinctrl_of_match, 429 }, 430 .probe = armada_370_pinctrl_probe, 431 .remove = armada_370_pinctrl_remove, 432 }; 433 434 module_platform_driver(armada_370_pinctrl_driver); 435 436 MODULE_AUTHOR("Thomas Petazzoni <thomas.petazzoni@free-electrons.com>"); 437 MODULE_DESCRIPTION("Marvell Armada 370 pinctrl driver"); 438 MODULE_LICENSE("GPL v2"); 439