409 lines · c
1/*2 * Driver for the ST Microelectronics SPEAr310 pinmux3 *4 * Copyright (C) 2012 ST Microelectronics5 * Viresh Kumar <vireshk@kernel.org>6 *7 * This file is licensed under the terms of the GNU General Public8 * License version 2. This program is licensed "as is" without any9 * 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 0x0822 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);409