1 /* 2 * Driver for the ST Microelectronics SPEAr310 pinmux 3 * 4 * Copyright (C) 2012 ST Microelectronics 5 * Viresh Kumar <vireshk@kernel.org> 6 * 7 * This file is licensed under the terms of the GNU General Public 8 * License version 2. This program is licensed "as is" without any 9 * warranty of any kind, whether express or implied. 10 */ 11 12 #include <linux/err.h> 13 #include <linux/init.h> 14 #include <linux/mod_devicetable.h> 15 #include <linux/platform_device.h> 16 #include "pinctrl-spear3xx.h" 17 18 #define DRIVER_NAME "spear310-pinmux" 19 20 /* addresses */ 21 #define PMX_CONFIG_REG 0x08 22 23 /* emi_cs_0_to_5_pins */ 24 static const unsigned emi_cs_0_to_5_pins[] = { 45, 46, 47, 48, 49, 50 }; 25 static struct spear_muxreg emi_cs_0_to_5_muxreg[] = { 26 { 27 .reg = PMX_CONFIG_REG, 28 .mask = PMX_TIMER_0_1_MASK | PMX_TIMER_2_3_MASK, 29 .val = 0, 30 }, 31 }; 32 33 static struct spear_modemux emi_cs_0_to_5_modemux[] = { 34 { 35 .muxregs = emi_cs_0_to_5_muxreg, 36 .nmuxregs = ARRAY_SIZE(emi_cs_0_to_5_muxreg), 37 }, 38 }; 39 40 static struct spear_pingroup emi_cs_0_to_5_pingroup = { 41 .name = "emi_cs_0_to_5_grp", 42 .pins = emi_cs_0_to_5_pins, 43 .npins = ARRAY_SIZE(emi_cs_0_to_5_pins), 44 .modemuxs = emi_cs_0_to_5_modemux, 45 .nmodemuxs = ARRAY_SIZE(emi_cs_0_to_5_modemux), 46 }; 47 48 static const char *const emi_cs_0_to_5_grps[] = { "emi_cs_0_to_5_grp" }; 49 static struct spear_function emi_cs_0_to_5_function = { 50 .name = "emi", 51 .groups = emi_cs_0_to_5_grps, 52 .ngroups = ARRAY_SIZE(emi_cs_0_to_5_grps), 53 }; 54 55 /* uart1_pins */ 56 static const unsigned uart1_pins[] = { 0, 1 }; 57 static struct spear_muxreg uart1_muxreg[] = { 58 { 59 .reg = PMX_CONFIG_REG, 60 .mask = PMX_FIRDA_MASK, 61 .val = 0, 62 }, 63 }; 64 65 static struct spear_modemux uart1_modemux[] = { 66 { 67 .muxregs = uart1_muxreg, 68 .nmuxregs = ARRAY_SIZE(uart1_muxreg), 69 }, 70 }; 71 72 static struct spear_pingroup uart1_pingroup = { 73 .name = "uart1_grp", 74 .pins = uart1_pins, 75 .npins = ARRAY_SIZE(uart1_pins), 76 .modemuxs = uart1_modemux, 77 .nmodemuxs = ARRAY_SIZE(uart1_modemux), 78 }; 79 80 static const char *const uart1_grps[] = { "uart1_grp" }; 81 static struct spear_function uart1_function = { 82 .name = "uart1", 83 .groups = uart1_grps, 84 .ngroups = ARRAY_SIZE(uart1_grps), 85 }; 86 87 /* uart2_pins */ 88 static const unsigned uart2_pins[] = { 43, 44 }; 89 static struct spear_muxreg uart2_muxreg[] = { 90 { 91 .reg = PMX_CONFIG_REG, 92 .mask = PMX_TIMER_0_1_MASK, 93 .val = 0, 94 }, 95 }; 96 97 static struct spear_modemux uart2_modemux[] = { 98 { 99 .muxregs = uart2_muxreg, 100 .nmuxregs = ARRAY_SIZE(uart2_muxreg), 101 }, 102 }; 103 104 static struct spear_pingroup uart2_pingroup = { 105 .name = "uart2_grp", 106 .pins = uart2_pins, 107 .npins = ARRAY_SIZE(uart2_pins), 108 .modemuxs = uart2_modemux, 109 .nmodemuxs = ARRAY_SIZE(uart2_modemux), 110 }; 111 112 static const char *const uart2_grps[] = { "uart2_grp" }; 113 static struct spear_function uart2_function = { 114 .name = "uart2", 115 .groups = uart2_grps, 116 .ngroups = ARRAY_SIZE(uart2_grps), 117 }; 118 119 /* uart3_pins */ 120 static const unsigned uart3_pins[] = { 37, 38 }; 121 static struct spear_muxreg uart3_muxreg[] = { 122 { 123 .reg = PMX_CONFIG_REG, 124 .mask = PMX_UART0_MODEM_MASK, 125 .val = 0, 126 }, 127 }; 128 129 static struct spear_modemux uart3_modemux[] = { 130 { 131 .muxregs = uart3_muxreg, 132 .nmuxregs = ARRAY_SIZE(uart3_muxreg), 133 }, 134 }; 135 136 static struct spear_pingroup uart3_pingroup = { 137 .name = "uart3_grp", 138 .pins = uart3_pins, 139 .npins = ARRAY_SIZE(uart3_pins), 140 .modemuxs = uart3_modemux, 141 .nmodemuxs = ARRAY_SIZE(uart3_modemux), 142 }; 143 144 static const char *const uart3_grps[] = { "uart3_grp" }; 145 static struct spear_function uart3_function = { 146 .name = "uart3", 147 .groups = uart3_grps, 148 .ngroups = ARRAY_SIZE(uart3_grps), 149 }; 150 151 /* uart4_pins */ 152 static const unsigned uart4_pins[] = { 39, 40 }; 153 static struct spear_muxreg uart4_muxreg[] = { 154 { 155 .reg = PMX_CONFIG_REG, 156 .mask = PMX_UART0_MODEM_MASK, 157 .val = 0, 158 }, 159 }; 160 161 static struct spear_modemux uart4_modemux[] = { 162 { 163 .muxregs = uart4_muxreg, 164 .nmuxregs = ARRAY_SIZE(uart4_muxreg), 165 }, 166 }; 167 168 static struct spear_pingroup uart4_pingroup = { 169 .name = "uart4_grp", 170 .pins = uart4_pins, 171 .npins = ARRAY_SIZE(uart4_pins), 172 .modemuxs = uart4_modemux, 173 .nmodemuxs = ARRAY_SIZE(uart4_modemux), 174 }; 175 176 static const char *const uart4_grps[] = { "uart4_grp" }; 177 static struct spear_function uart4_function = { 178 .name = "uart4", 179 .groups = uart4_grps, 180 .ngroups = ARRAY_SIZE(uart4_grps), 181 }; 182 183 /* uart5_pins */ 184 static const unsigned uart5_pins[] = { 41, 42 }; 185 static struct spear_muxreg uart5_muxreg[] = { 186 { 187 .reg = PMX_CONFIG_REG, 188 .mask = PMX_UART0_MODEM_MASK, 189 .val = 0, 190 }, 191 }; 192 193 static struct spear_modemux uart5_modemux[] = { 194 { 195 .muxregs = uart5_muxreg, 196 .nmuxregs = ARRAY_SIZE(uart5_muxreg), 197 }, 198 }; 199 200 static struct spear_pingroup uart5_pingroup = { 201 .name = "uart5_grp", 202 .pins = uart5_pins, 203 .npins = ARRAY_SIZE(uart5_pins), 204 .modemuxs = uart5_modemux, 205 .nmodemuxs = ARRAY_SIZE(uart5_modemux), 206 }; 207 208 static const char *const uart5_grps[] = { "uart5_grp" }; 209 static struct spear_function uart5_function = { 210 .name = "uart5", 211 .groups = uart5_grps, 212 .ngroups = ARRAY_SIZE(uart5_grps), 213 }; 214 215 /* fsmc_pins */ 216 static const unsigned fsmc_pins[] = { 34, 35, 36 }; 217 static struct spear_muxreg fsmc_muxreg[] = { 218 { 219 .reg = PMX_CONFIG_REG, 220 .mask = PMX_SSP_CS_MASK, 221 .val = 0, 222 }, 223 }; 224 225 static struct spear_modemux fsmc_modemux[] = { 226 { 227 .muxregs = fsmc_muxreg, 228 .nmuxregs = ARRAY_SIZE(fsmc_muxreg), 229 }, 230 }; 231 232 static struct spear_pingroup fsmc_pingroup = { 233 .name = "fsmc_grp", 234 .pins = fsmc_pins, 235 .npins = ARRAY_SIZE(fsmc_pins), 236 .modemuxs = fsmc_modemux, 237 .nmodemuxs = ARRAY_SIZE(fsmc_modemux), 238 }; 239 240 static const char *const fsmc_grps[] = { "fsmc_grp" }; 241 static struct spear_function fsmc_function = { 242 .name = "fsmc", 243 .groups = fsmc_grps, 244 .ngroups = ARRAY_SIZE(fsmc_grps), 245 }; 246 247 /* rs485_0_pins */ 248 static const unsigned rs485_0_pins[] = { 19, 20, 21, 22, 23 }; 249 static struct spear_muxreg rs485_0_muxreg[] = { 250 { 251 .reg = PMX_CONFIG_REG, 252 .mask = PMX_MII_MASK, 253 .val = 0, 254 }, 255 }; 256 257 static struct spear_modemux rs485_0_modemux[] = { 258 { 259 .muxregs = rs485_0_muxreg, 260 .nmuxregs = ARRAY_SIZE(rs485_0_muxreg), 261 }, 262 }; 263 264 static struct spear_pingroup rs485_0_pingroup = { 265 .name = "rs485_0_grp", 266 .pins = rs485_0_pins, 267 .npins = ARRAY_SIZE(rs485_0_pins), 268 .modemuxs = rs485_0_modemux, 269 .nmodemuxs = ARRAY_SIZE(rs485_0_modemux), 270 }; 271 272 static const char *const rs485_0_grps[] = { "rs485_0" }; 273 static struct spear_function rs485_0_function = { 274 .name = "rs485_0", 275 .groups = rs485_0_grps, 276 .ngroups = ARRAY_SIZE(rs485_0_grps), 277 }; 278 279 /* rs485_1_pins */ 280 static const unsigned rs485_1_pins[] = { 14, 15, 16, 17, 18 }; 281 static struct spear_muxreg rs485_1_muxreg[] = { 282 { 283 .reg = PMX_CONFIG_REG, 284 .mask = PMX_MII_MASK, 285 .val = 0, 286 }, 287 }; 288 289 static struct spear_modemux rs485_1_modemux[] = { 290 { 291 .muxregs = rs485_1_muxreg, 292 .nmuxregs = ARRAY_SIZE(rs485_1_muxreg), 293 }, 294 }; 295 296 static struct spear_pingroup rs485_1_pingroup = { 297 .name = "rs485_1_grp", 298 .pins = rs485_1_pins, 299 .npins = ARRAY_SIZE(rs485_1_pins), 300 .modemuxs = rs485_1_modemux, 301 .nmodemuxs = ARRAY_SIZE(rs485_1_modemux), 302 }; 303 304 static const char *const rs485_1_grps[] = { "rs485_1" }; 305 static struct spear_function rs485_1_function = { 306 .name = "rs485_1", 307 .groups = rs485_1_grps, 308 .ngroups = ARRAY_SIZE(rs485_1_grps), 309 }; 310 311 /* tdm_pins */ 312 static const unsigned tdm_pins[] = { 10, 11, 12, 13 }; 313 static struct spear_muxreg tdm_muxreg[] = { 314 { 315 .reg = PMX_CONFIG_REG, 316 .mask = PMX_MII_MASK, 317 .val = 0, 318 }, 319 }; 320 321 static struct spear_modemux tdm_modemux[] = { 322 { 323 .muxregs = tdm_muxreg, 324 .nmuxregs = ARRAY_SIZE(tdm_muxreg), 325 }, 326 }; 327 328 static struct spear_pingroup tdm_pingroup = { 329 .name = "tdm_grp", 330 .pins = tdm_pins, 331 .npins = ARRAY_SIZE(tdm_pins), 332 .modemuxs = tdm_modemux, 333 .nmodemuxs = ARRAY_SIZE(tdm_modemux), 334 }; 335 336 static const char *const tdm_grps[] = { "tdm_grp" }; 337 static struct spear_function tdm_function = { 338 .name = "tdm", 339 .groups = tdm_grps, 340 .ngroups = ARRAY_SIZE(tdm_grps), 341 }; 342 343 /* pingroups */ 344 static struct spear_pingroup *spear310_pingroups[] = { 345 SPEAR3XX_COMMON_PINGROUPS, 346 &emi_cs_0_to_5_pingroup, 347 &uart1_pingroup, 348 &uart2_pingroup, 349 &uart3_pingroup, 350 &uart4_pingroup, 351 &uart5_pingroup, 352 &fsmc_pingroup, 353 &rs485_0_pingroup, 354 &rs485_1_pingroup, 355 &tdm_pingroup, 356 }; 357 358 /* functions */ 359 static struct spear_function *spear310_functions[] = { 360 SPEAR3XX_COMMON_FUNCTIONS, 361 &emi_cs_0_to_5_function, 362 &uart1_function, 363 &uart2_function, 364 &uart3_function, 365 &uart4_function, 366 &uart5_function, 367 &fsmc_function, 368 &rs485_0_function, 369 &rs485_1_function, 370 &tdm_function, 371 }; 372 373 static const struct of_device_id spear310_pinctrl_of_match[] = { 374 { 375 .compatible = "st,spear310-pinmux", 376 }, 377 {}, 378 }; 379 380 static int spear310_pinctrl_probe(struct platform_device *pdev) 381 { 382 spear3xx_machdata.groups = spear310_pingroups; 383 spear3xx_machdata.ngroups = ARRAY_SIZE(spear310_pingroups); 384 spear3xx_machdata.functions = spear310_functions; 385 spear3xx_machdata.nfunctions = ARRAY_SIZE(spear310_functions); 386 387 pmx_init_addr(&spear3xx_machdata, PMX_CONFIG_REG); 388 pmx_init_gpio_pingroup_addr(spear3xx_machdata.gpio_pingroups, 389 spear3xx_machdata.ngpio_pingroups, PMX_CONFIG_REG); 390 391 spear3xx_machdata.modes_supported = false; 392 393 return spear_pinctrl_probe(pdev, &spear3xx_machdata); 394 } 395 396 static struct platform_driver spear310_pinctrl_driver = { 397 .driver = { 398 .name = DRIVER_NAME, 399 .of_match_table = spear310_pinctrl_of_match, 400 }, 401 .probe = spear310_pinctrl_probe, 402 }; 403 404 static int __init spear310_pinctrl_init(void) 405 { 406 return platform_driver_register(&spear310_pinctrl_driver); 407 } 408 arch_initcall(spear310_pinctrl_init); 409