pinctrl-spear310.c (9357B)
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/of_device.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 */ 24static const unsigned emi_cs_0_to_5_pins[] = { 45, 46, 47, 48, 49, 50 }; 25static 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 33static 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 40static 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 48static const char *const emi_cs_0_to_5_grps[] = { "emi_cs_0_to_5_grp" }; 49static 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 */ 56static const unsigned uart1_pins[] = { 0, 1 }; 57static struct spear_muxreg uart1_muxreg[] = { 58 { 59 .reg = PMX_CONFIG_REG, 60 .mask = PMX_FIRDA_MASK, 61 .val = 0, 62 }, 63}; 64 65static struct spear_modemux uart1_modemux[] = { 66 { 67 .muxregs = uart1_muxreg, 68 .nmuxregs = ARRAY_SIZE(uart1_muxreg), 69 }, 70}; 71 72static 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 80static const char *const uart1_grps[] = { "uart1_grp" }; 81static struct spear_function uart1_function = { 82 .name = "uart1", 83 .groups = uart1_grps, 84 .ngroups = ARRAY_SIZE(uart1_grps), 85}; 86 87/* uart2_pins */ 88static const unsigned uart2_pins[] = { 43, 44 }; 89static struct spear_muxreg uart2_muxreg[] = { 90 { 91 .reg = PMX_CONFIG_REG, 92 .mask = PMX_TIMER_0_1_MASK, 93 .val = 0, 94 }, 95}; 96 97static struct spear_modemux uart2_modemux[] = { 98 { 99 .muxregs = uart2_muxreg, 100 .nmuxregs = ARRAY_SIZE(uart2_muxreg), 101 }, 102}; 103 104static 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 112static const char *const uart2_grps[] = { "uart2_grp" }; 113static struct spear_function uart2_function = { 114 .name = "uart2", 115 .groups = uart2_grps, 116 .ngroups = ARRAY_SIZE(uart2_grps), 117}; 118 119/* uart3_pins */ 120static const unsigned uart3_pins[] = { 37, 38 }; 121static struct spear_muxreg uart3_muxreg[] = { 122 { 123 .reg = PMX_CONFIG_REG, 124 .mask = PMX_UART0_MODEM_MASK, 125 .val = 0, 126 }, 127}; 128 129static struct spear_modemux uart3_modemux[] = { 130 { 131 .muxregs = uart3_muxreg, 132 .nmuxregs = ARRAY_SIZE(uart3_muxreg), 133 }, 134}; 135 136static 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 144static const char *const uart3_grps[] = { "uart3_grp" }; 145static struct spear_function uart3_function = { 146 .name = "uart3", 147 .groups = uart3_grps, 148 .ngroups = ARRAY_SIZE(uart3_grps), 149}; 150 151/* uart4_pins */ 152static const unsigned uart4_pins[] = { 39, 40 }; 153static struct spear_muxreg uart4_muxreg[] = { 154 { 155 .reg = PMX_CONFIG_REG, 156 .mask = PMX_UART0_MODEM_MASK, 157 .val = 0, 158 }, 159}; 160 161static struct spear_modemux uart4_modemux[] = { 162 { 163 .muxregs = uart4_muxreg, 164 .nmuxregs = ARRAY_SIZE(uart4_muxreg), 165 }, 166}; 167 168static 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 176static const char *const uart4_grps[] = { "uart4_grp" }; 177static struct spear_function uart4_function = { 178 .name = "uart4", 179 .groups = uart4_grps, 180 .ngroups = ARRAY_SIZE(uart4_grps), 181}; 182 183/* uart5_pins */ 184static const unsigned uart5_pins[] = { 41, 42 }; 185static struct spear_muxreg uart5_muxreg[] = { 186 { 187 .reg = PMX_CONFIG_REG, 188 .mask = PMX_UART0_MODEM_MASK, 189 .val = 0, 190 }, 191}; 192 193static struct spear_modemux uart5_modemux[] = { 194 { 195 .muxregs = uart5_muxreg, 196 .nmuxregs = ARRAY_SIZE(uart5_muxreg), 197 }, 198}; 199 200static 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 208static const char *const uart5_grps[] = { "uart5_grp" }; 209static struct spear_function uart5_function = { 210 .name = "uart5", 211 .groups = uart5_grps, 212 .ngroups = ARRAY_SIZE(uart5_grps), 213}; 214 215/* fsmc_pins */ 216static const unsigned fsmc_pins[] = { 34, 35, 36 }; 217static struct spear_muxreg fsmc_muxreg[] = { 218 { 219 .reg = PMX_CONFIG_REG, 220 .mask = PMX_SSP_CS_MASK, 221 .val = 0, 222 }, 223}; 224 225static struct spear_modemux fsmc_modemux[] = { 226 { 227 .muxregs = fsmc_muxreg, 228 .nmuxregs = ARRAY_SIZE(fsmc_muxreg), 229 }, 230}; 231 232static 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 240static const char *const fsmc_grps[] = { "fsmc_grp" }; 241static struct spear_function fsmc_function = { 242 .name = "fsmc", 243 .groups = fsmc_grps, 244 .ngroups = ARRAY_SIZE(fsmc_grps), 245}; 246 247/* rs485_0_pins */ 248static const unsigned rs485_0_pins[] = { 19, 20, 21, 22, 23 }; 249static struct spear_muxreg rs485_0_muxreg[] = { 250 { 251 .reg = PMX_CONFIG_REG, 252 .mask = PMX_MII_MASK, 253 .val = 0, 254 }, 255}; 256 257static struct spear_modemux rs485_0_modemux[] = { 258 { 259 .muxregs = rs485_0_muxreg, 260 .nmuxregs = ARRAY_SIZE(rs485_0_muxreg), 261 }, 262}; 263 264static 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 272static const char *const rs485_0_grps[] = { "rs485_0" }; 273static 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 */ 280static const unsigned rs485_1_pins[] = { 14, 15, 16, 17, 18 }; 281static struct spear_muxreg rs485_1_muxreg[] = { 282 { 283 .reg = PMX_CONFIG_REG, 284 .mask = PMX_MII_MASK, 285 .val = 0, 286 }, 287}; 288 289static struct spear_modemux rs485_1_modemux[] = { 290 { 291 .muxregs = rs485_1_muxreg, 292 .nmuxregs = ARRAY_SIZE(rs485_1_muxreg), 293 }, 294}; 295 296static 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 304static const char *const rs485_1_grps[] = { "rs485_1" }; 305static 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 */ 312static const unsigned tdm_pins[] = { 10, 11, 12, 13 }; 313static struct spear_muxreg tdm_muxreg[] = { 314 { 315 .reg = PMX_CONFIG_REG, 316 .mask = PMX_MII_MASK, 317 .val = 0, 318 }, 319}; 320 321static struct spear_modemux tdm_modemux[] = { 322 { 323 .muxregs = tdm_muxreg, 324 .nmuxregs = ARRAY_SIZE(tdm_muxreg), 325 }, 326}; 327 328static 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 336static const char *const tdm_grps[] = { "tdm_grp" }; 337static struct spear_function tdm_function = { 338 .name = "tdm", 339 .groups = tdm_grps, 340 .ngroups = ARRAY_SIZE(tdm_grps), 341}; 342 343/* pingroups */ 344static 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 */ 359static 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 373static const struct of_device_id spear310_pinctrl_of_match[] = { 374 { 375 .compatible = "st,spear310-pinmux", 376 }, 377 {}, 378}; 379 380static 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 396static 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 404static int __init spear310_pinctrl_init(void) 405{ 406 return platform_driver_register(&spear310_pinctrl_driver); 407} 408arch_initcall(spear310_pinctrl_init);