1/* 2 * Driver for the ST Microelectronics SPEAr300 pinmux 3 * 4 * Copyright (C) 2012 ST Microelectronics 5 * Viresh Kumar <viresh.linux@gmail.com> 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/module.h> 15#include <linux/of_device.h> 16#include <linux/platform_device.h> 17#include "pinctrl-spear3xx.h" 18 19#define DRIVER_NAME "spear300-pinmux" 20 21/* addresses */ 22#define PMX_CONFIG_REG 0x00 23#define MODE_CONFIG_REG 0x04 24 25/* modes */ 26#define NAND_MODE (1 << 0) 27#define NOR_MODE (1 << 1) 28#define PHOTO_FRAME_MODE (1 << 2) 29#define LEND_IP_PHONE_MODE (1 << 3) 30#define HEND_IP_PHONE_MODE (1 << 4) 31#define LEND_WIFI_PHONE_MODE (1 << 5) 32#define HEND_WIFI_PHONE_MODE (1 << 6) 33#define ATA_PABX_WI2S_MODE (1 << 7) 34#define ATA_PABX_I2S_MODE (1 << 8) 35#define CAML_LCDW_MODE (1 << 9) 36#define CAMU_LCD_MODE (1 << 10) 37#define CAMU_WLCD_MODE (1 << 11) 38#define CAML_LCD_MODE (1 << 12) 39 40static struct spear_pmx_mode pmx_mode_nand = { 41 .name = "nand", 42 .mode = NAND_MODE, 43 .reg = MODE_CONFIG_REG, 44 .mask = 0x0000000F, 45 .val = 0x00, 46}; 47 48static struct spear_pmx_mode pmx_mode_nor = { 49 .name = "nor", 50 .mode = NOR_MODE, 51 .reg = MODE_CONFIG_REG, 52 .mask = 0x0000000F, 53 .val = 0x01, 54}; 55 56static struct spear_pmx_mode pmx_mode_photo_frame = { 57 .name = "photo frame mode", 58 .mode = PHOTO_FRAME_MODE, 59 .reg = MODE_CONFIG_REG, 60 .mask = 0x0000000F, 61 .val = 0x02, 62}; 63 64static struct spear_pmx_mode pmx_mode_lend_ip_phone = { 65 .name = "lend ip phone mode", 66 .mode = LEND_IP_PHONE_MODE, 67 .reg = MODE_CONFIG_REG, 68 .mask = 0x0000000F, 69 .val = 0x03, 70}; 71 72static struct spear_pmx_mode pmx_mode_hend_ip_phone = { 73 .name = "hend ip phone mode", 74 .mode = HEND_IP_PHONE_MODE, 75 .reg = MODE_CONFIG_REG, 76 .mask = 0x0000000F, 77 .val = 0x04, 78}; 79 80static struct spear_pmx_mode pmx_mode_lend_wifi_phone = { 81 .name = "lend wifi phone mode", 82 .mode = LEND_WIFI_PHONE_MODE, 83 .reg = MODE_CONFIG_REG, 84 .mask = 0x0000000F, 85 .val = 0x05, 86}; 87 88static struct spear_pmx_mode pmx_mode_hend_wifi_phone = { 89 .name = "hend wifi phone mode", 90 .mode = HEND_WIFI_PHONE_MODE, 91 .reg = MODE_CONFIG_REG, 92 .mask = 0x0000000F, 93 .val = 0x06, 94}; 95 96static struct spear_pmx_mode pmx_mode_ata_pabx_wi2s = { 97 .name = "ata pabx wi2s mode", 98 .mode = ATA_PABX_WI2S_MODE, 99 .reg = MODE_CONFIG_REG, 100 .mask = 0x0000000F, 101 .val = 0x07, 102}; 103 104static struct spear_pmx_mode pmx_mode_ata_pabx_i2s = { 105 .name = "ata pabx i2s mode", 106 .mode = ATA_PABX_I2S_MODE, 107 .reg = MODE_CONFIG_REG, 108 .mask = 0x0000000F, 109 .val = 0x08, 110}; 111 112static struct spear_pmx_mode pmx_mode_caml_lcdw = { 113 .name = "caml lcdw mode", 114 .mode = CAML_LCDW_MODE, 115 .reg = MODE_CONFIG_REG, 116 .mask = 0x0000000F, 117 .val = 0x0C, 118}; 119 120static struct spear_pmx_mode pmx_mode_camu_lcd = { 121 .name = "camu lcd mode", 122 .mode = CAMU_LCD_MODE, 123 .reg = MODE_CONFIG_REG, 124 .mask = 0x0000000F, 125 .val = 0x0D, 126}; 127 128static struct spear_pmx_mode pmx_mode_camu_wlcd = { 129 .name = "camu wlcd mode", 130 .mode = CAMU_WLCD_MODE, 131 .reg = MODE_CONFIG_REG, 132 .mask = 0x0000000F, 133 .val = 0xE, 134}; 135 136static struct spear_pmx_mode pmx_mode_caml_lcd = { 137 .name = "caml lcd mode", 138 .mode = CAML_LCD_MODE, 139 .reg = MODE_CONFIG_REG, 140 .mask = 0x0000000F, 141 .val = 0x0F, 142}; 143 144static struct spear_pmx_mode *spear300_pmx_modes[] = { 145 &pmx_mode_nand, 146 &pmx_mode_nor, 147 &pmx_mode_photo_frame, 148 &pmx_mode_lend_ip_phone, 149 &pmx_mode_hend_ip_phone, 150 &pmx_mode_lend_wifi_phone, 151 &pmx_mode_hend_wifi_phone, 152 &pmx_mode_ata_pabx_wi2s, 153 &pmx_mode_ata_pabx_i2s, 154 &pmx_mode_caml_lcdw, 155 &pmx_mode_camu_lcd, 156 &pmx_mode_camu_wlcd, 157 &pmx_mode_caml_lcd, 158}; 159 160/* fsmc_2chips_pins */ 161static const unsigned fsmc_2chips_pins[] = { 1, 97 }; 162static struct spear_muxreg fsmc_2chips_muxreg[] = { 163 { 164 .reg = PMX_CONFIG_REG, 165 .mask = PMX_FIRDA_MASK, 166 .val = 0, 167 }, 168}; 169 170static struct spear_modemux fsmc_2chips_modemux[] = { 171 { 172 .modes = NAND_MODE | NOR_MODE | PHOTO_FRAME_MODE | 173 ATA_PABX_WI2S_MODE | ATA_PABX_I2S_MODE, 174 .muxregs = fsmc_2chips_muxreg, 175 .nmuxregs = ARRAY_SIZE(fsmc_2chips_muxreg), 176 }, 177}; 178 179static struct spear_pingroup fsmc_2chips_pingroup = { 180 .name = "fsmc_2chips_grp", 181 .pins = fsmc_2chips_pins, 182 .npins = ARRAY_SIZE(fsmc_2chips_pins), 183 .modemuxs = fsmc_2chips_modemux, 184 .nmodemuxs = ARRAY_SIZE(fsmc_2chips_modemux), 185}; 186 187/* fsmc_4chips_pins */ 188static const unsigned fsmc_4chips_pins[] = { 1, 2, 3, 97 }; 189static struct spear_muxreg fsmc_4chips_muxreg[] = { 190 { 191 .reg = PMX_CONFIG_REG, 192 .mask = PMX_FIRDA_MASK | PMX_UART0_MASK, 193 .val = 0, 194 }, 195}; 196 197static struct spear_modemux fsmc_4chips_modemux[] = { 198 { 199 .modes = NAND_MODE | NOR_MODE | PHOTO_FRAME_MODE | 200 ATA_PABX_WI2S_MODE | ATA_PABX_I2S_MODE, 201 .muxregs = fsmc_4chips_muxreg, 202 .nmuxregs = ARRAY_SIZE(fsmc_4chips_muxreg), 203 }, 204}; 205 206static struct spear_pingroup fsmc_4chips_pingroup = { 207 .name = "fsmc_4chips_grp", 208 .pins = fsmc_4chips_pins, 209 .npins = ARRAY_SIZE(fsmc_4chips_pins), 210 .modemuxs = fsmc_4chips_modemux, 211 .nmodemuxs = ARRAY_SIZE(fsmc_4chips_modemux), 212}; 213 214static const char *const fsmc_grps[] = { "fsmc_2chips_grp", "fsmc_4chips_grp" 215}; 216static struct spear_function fsmc_function = { 217 .name = "fsmc", 218 .groups = fsmc_grps, 219 .ngroups = ARRAY_SIZE(fsmc_grps), 220}; 221 222/* clcd_lcdmode_pins */ 223static const unsigned clcd_lcdmode_pins[] = { 49, 50 }; 224static struct spear_muxreg clcd_lcdmode_muxreg[] = { 225 { 226 .reg = PMX_CONFIG_REG, 227 .mask = PMX_TIMER_0_1_MASK | PMX_TIMER_2_3_MASK, 228 .val = 0, 229 }, 230}; 231 232static struct spear_modemux clcd_lcdmode_modemux[] = { 233 { 234 .modes = HEND_IP_PHONE_MODE | HEND_WIFI_PHONE_MODE | 235 CAMU_LCD_MODE | CAML_LCD_MODE, 236 .muxregs = clcd_lcdmode_muxreg, 237 .nmuxregs = ARRAY_SIZE(clcd_lcdmode_muxreg), 238 }, 239}; 240 241static struct spear_pingroup clcd_lcdmode_pingroup = { 242 .name = "clcd_lcdmode_grp", 243 .pins = clcd_lcdmode_pins, 244 .npins = ARRAY_SIZE(clcd_lcdmode_pins), 245 .modemuxs = clcd_lcdmode_modemux, 246 .nmodemuxs = ARRAY_SIZE(clcd_lcdmode_modemux), 247}; 248 249/* clcd_pfmode_pins */ 250static const unsigned clcd_pfmode_pins[] = { 47, 48, 49, 50 }; 251static struct spear_muxreg clcd_pfmode_muxreg[] = { 252 { 253 .reg = PMX_CONFIG_REG, 254 .mask = PMX_TIMER_2_3_MASK, 255 .val = 0, 256 }, 257}; 258 259static struct spear_modemux clcd_pfmode_modemux[] = { 260 { 261 .modes = PHOTO_FRAME_MODE, 262 .muxregs = clcd_pfmode_muxreg, 263 .nmuxregs = ARRAY_SIZE(clcd_pfmode_muxreg), 264 }, 265}; 266 267static struct spear_pingroup clcd_pfmode_pingroup = { 268 .name = "clcd_pfmode_grp", 269 .pins = clcd_pfmode_pins, 270 .npins = ARRAY_SIZE(clcd_pfmode_pins), 271 .modemuxs = clcd_pfmode_modemux, 272 .nmodemuxs = ARRAY_SIZE(clcd_pfmode_modemux), 273}; 274 275static const char *const clcd_grps[] = { "clcd_lcdmode_grp", "clcd_pfmode_grp" 276}; 277static struct spear_function clcd_function = { 278 .name = "clcd", 279 .groups = clcd_grps, 280 .ngroups = ARRAY_SIZE(clcd_grps), 281}; 282 283/* tdm_pins */ 284static const unsigned tdm_pins[] = { 34, 35, 36, 37, 38 }; 285static struct spear_muxreg tdm_muxreg[] = { 286 { 287 .reg = PMX_CONFIG_REG, 288 .mask = PMX_UART0_MODEM_MASK | PMX_SSP_CS_MASK, 289 .val = 0, 290 }, 291}; 292 293static struct spear_modemux tdm_modemux[] = { 294 { 295 .modes = PHOTO_FRAME_MODE | LEND_IP_PHONE_MODE | 296 HEND_IP_PHONE_MODE | LEND_WIFI_PHONE_MODE 297 | HEND_WIFI_PHONE_MODE | ATA_PABX_WI2S_MODE 298 | ATA_PABX_I2S_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE 299 | CAMU_WLCD_MODE | CAML_LCD_MODE, 300 .muxregs = tdm_muxreg, 301 .nmuxregs = ARRAY_SIZE(tdm_muxreg), 302 }, 303}; 304 305static struct spear_pingroup tdm_pingroup = { 306 .name = "tdm_grp", 307 .pins = tdm_pins, 308 .npins = ARRAY_SIZE(tdm_pins), 309 .modemuxs = tdm_modemux, 310 .nmodemuxs = ARRAY_SIZE(tdm_modemux), 311}; 312 313static const char *const tdm_grps[] = { "tdm_grp" }; 314static struct spear_function tdm_function = { 315 .name = "tdm", 316 .groups = tdm_grps, 317 .ngroups = ARRAY_SIZE(tdm_grps), 318}; 319 320/* i2c_clk_pins */ 321static const unsigned i2c_clk_pins[] = { 45, 46, 47, 48 }; 322static struct spear_muxreg i2c_clk_muxreg[] = { 323 { 324 .reg = PMX_CONFIG_REG, 325 .mask = PMX_TIMER_0_1_MASK | PMX_TIMER_2_3_MASK, 326 .val = 0, 327 }, 328}; 329 330static struct spear_modemux i2c_clk_modemux[] = { 331 { 332 .modes = LEND_IP_PHONE_MODE | HEND_IP_PHONE_MODE | 333 LEND_WIFI_PHONE_MODE | HEND_WIFI_PHONE_MODE | 334 ATA_PABX_WI2S_MODE | ATA_PABX_I2S_MODE | CAML_LCDW_MODE 335 | CAML_LCD_MODE, 336 .muxregs = i2c_clk_muxreg, 337 .nmuxregs = ARRAY_SIZE(i2c_clk_muxreg), 338 }, 339}; 340 341static struct spear_pingroup i2c_clk_pingroup = { 342 .name = "i2c_clk_grp_grp", 343 .pins = i2c_clk_pins, 344 .npins = ARRAY_SIZE(i2c_clk_pins), 345 .modemuxs = i2c_clk_modemux, 346 .nmodemuxs = ARRAY_SIZE(i2c_clk_modemux), 347}; 348 349static const char *const i2c_grps[] = { "i2c_clk_grp" }; 350static struct spear_function i2c_function = { 351 .name = "i2c1", 352 .groups = i2c_grps, 353 .ngroups = ARRAY_SIZE(i2c_grps), 354}; 355 356/* caml_pins */ 357static const unsigned caml_pins[] = { 12, 13, 14, 15, 16, 17, 18, 19, 20, 21 }; 358static struct spear_muxreg caml_muxreg[] = { 359 { 360 .reg = PMX_CONFIG_REG, 361 .mask = PMX_MII_MASK, 362 .val = 0, 363 }, 364}; 365 366static struct spear_modemux caml_modemux[] = { 367 { 368 .modes = CAML_LCDW_MODE | CAML_LCD_MODE, 369 .muxregs = caml_muxreg, 370 .nmuxregs = ARRAY_SIZE(caml_muxreg), 371 }, 372}; 373 374static struct spear_pingroup caml_pingroup = { 375 .name = "caml_grp", 376 .pins = caml_pins, 377 .npins = ARRAY_SIZE(caml_pins), 378 .modemuxs = caml_modemux, 379 .nmodemuxs = ARRAY_SIZE(caml_modemux), 380}; 381 382/* camu_pins */ 383static const unsigned camu_pins[] = { 16, 17, 18, 19, 20, 21, 45, 46, 47, 48 }; 384static struct spear_muxreg camu_muxreg[] = { 385 { 386 .reg = PMX_CONFIG_REG, 387 .mask = PMX_TIMER_0_1_MASK | PMX_TIMER_2_3_MASK | PMX_MII_MASK, 388 .val = 0, 389 }, 390}; 391 392static struct spear_modemux camu_modemux[] = { 393 { 394 .modes = CAMU_LCD_MODE | CAMU_WLCD_MODE, 395 .muxregs = camu_muxreg, 396 .nmuxregs = ARRAY_SIZE(camu_muxreg), 397 }, 398}; 399 400static struct spear_pingroup camu_pingroup = { 401 .name = "camu_grp", 402 .pins = camu_pins, 403 .npins = ARRAY_SIZE(camu_pins), 404 .modemuxs = camu_modemux, 405 .nmodemuxs = ARRAY_SIZE(camu_modemux), 406}; 407 408static const char *const cam_grps[] = { "caml_grp", "camu_grp" }; 409static struct spear_function cam_function = { 410 .name = "cam", 411 .groups = cam_grps, 412 .ngroups = ARRAY_SIZE(cam_grps), 413}; 414 415/* dac_pins */ 416static const unsigned dac_pins[] = { 43, 44 }; 417static struct spear_muxreg dac_muxreg[] = { 418 { 419 .reg = PMX_CONFIG_REG, 420 .mask = PMX_TIMER_0_1_MASK, 421 .val = 0, 422 }, 423}; 424 425static struct spear_modemux dac_modemux[] = { 426 { 427 .modes = ATA_PABX_I2S_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE 428 | CAMU_WLCD_MODE | CAML_LCD_MODE, 429 .muxregs = dac_muxreg, 430 .nmuxregs = ARRAY_SIZE(dac_muxreg), 431 }, 432}; 433 434static struct spear_pingroup dac_pingroup = { 435 .name = "dac_grp", 436 .pins = dac_pins, 437 .npins = ARRAY_SIZE(dac_pins), 438 .modemuxs = dac_modemux, 439 .nmodemuxs = ARRAY_SIZE(dac_modemux), 440}; 441 442static const char *const dac_grps[] = { "dac_grp" }; 443static struct spear_function dac_function = { 444 .name = "dac", 445 .groups = dac_grps, 446 .ngroups = ARRAY_SIZE(dac_grps), 447}; 448 449/* i2s_pins */ 450static const unsigned i2s_pins[] = { 39, 40, 41, 42 }; 451static struct spear_muxreg i2s_muxreg[] = { 452 { 453 .reg = PMX_CONFIG_REG, 454 .mask = PMX_UART0_MODEM_MASK, 455 .val = 0, 456 }, 457}; 458 459static struct spear_modemux i2s_modemux[] = { 460 { 461 .modes = LEND_IP_PHONE_MODE | HEND_IP_PHONE_MODE 462 | LEND_WIFI_PHONE_MODE | HEND_WIFI_PHONE_MODE | 463 ATA_PABX_I2S_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE 464 | CAMU_WLCD_MODE | CAML_LCD_MODE, 465 .muxregs = i2s_muxreg, 466 .nmuxregs = ARRAY_SIZE(i2s_muxreg), 467 }, 468}; 469 470static struct spear_pingroup i2s_pingroup = { 471 .name = "i2s_grp", 472 .pins = i2s_pins, 473 .npins = ARRAY_SIZE(i2s_pins), 474 .modemuxs = i2s_modemux, 475 .nmodemuxs = ARRAY_SIZE(i2s_modemux), 476}; 477 478static const char *const i2s_grps[] = { "i2s_grp" }; 479static struct spear_function i2s_function = { 480 .name = "i2s", 481 .groups = i2s_grps, 482 .ngroups = ARRAY_SIZE(i2s_grps), 483}; 484 485/* sdhci_4bit_pins */ 486static const unsigned sdhci_4bit_pins[] = { 28, 29, 30, 31, 32, 33 }; 487static struct spear_muxreg sdhci_4bit_muxreg[] = { 488 { 489 .reg = PMX_CONFIG_REG, 490 .mask = PMX_GPIO_PIN0_MASK | PMX_GPIO_PIN1_MASK | 491 PMX_GPIO_PIN2_MASK | PMX_GPIO_PIN3_MASK | 492 PMX_GPIO_PIN4_MASK | PMX_GPIO_PIN5_MASK, 493 .val = 0, 494 }, 495}; 496 497static struct spear_modemux sdhci_4bit_modemux[] = { 498 { 499 .modes = PHOTO_FRAME_MODE | LEND_IP_PHONE_MODE | 500 HEND_IP_PHONE_MODE | LEND_WIFI_PHONE_MODE | 501 HEND_WIFI_PHONE_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE | 502 CAMU_WLCD_MODE | CAML_LCD_MODE | ATA_PABX_WI2S_MODE, 503 .muxregs = sdhci_4bit_muxreg, 504 .nmuxregs = ARRAY_SIZE(sdhci_4bit_muxreg), 505 }, 506}; 507 508static struct spear_pingroup sdhci_4bit_pingroup = { 509 .name = "sdhci_4bit_grp", 510 .pins = sdhci_4bit_pins, 511 .npins = ARRAY_SIZE(sdhci_4bit_pins), 512 .modemuxs = sdhci_4bit_modemux, 513 .nmodemuxs = ARRAY_SIZE(sdhci_4bit_modemux), 514}; 515 516/* sdhci_8bit_pins */ 517static const unsigned sdhci_8bit_pins[] = { 24, 25, 26, 27, 28, 29, 30, 31, 32, 518 33 }; 519static struct spear_muxreg sdhci_8bit_muxreg[] = { 520 { 521 .reg = PMX_CONFIG_REG, 522 .mask = PMX_GPIO_PIN0_MASK | PMX_GPIO_PIN1_MASK | 523 PMX_GPIO_PIN2_MASK | PMX_GPIO_PIN3_MASK | 524 PMX_GPIO_PIN4_MASK | PMX_GPIO_PIN5_MASK | PMX_MII_MASK, 525 .val = 0, 526 }, 527}; 528 529static struct spear_modemux sdhci_8bit_modemux[] = { 530 { 531 .modes = PHOTO_FRAME_MODE | LEND_IP_PHONE_MODE | 532 HEND_IP_PHONE_MODE | LEND_WIFI_PHONE_MODE | 533 HEND_WIFI_PHONE_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE | 534 CAMU_WLCD_MODE | CAML_LCD_MODE, 535 .muxregs = sdhci_8bit_muxreg, 536 .nmuxregs = ARRAY_SIZE(sdhci_8bit_muxreg), 537 }, 538}; 539 540static struct spear_pingroup sdhci_8bit_pingroup = { 541 .name = "sdhci_8bit_grp", 542 .pins = sdhci_8bit_pins, 543 .npins = ARRAY_SIZE(sdhci_8bit_pins), 544 .modemuxs = sdhci_8bit_modemux, 545 .nmodemuxs = ARRAY_SIZE(sdhci_8bit_modemux), 546}; 547 548static const char *const sdhci_grps[] = { "sdhci_4bit_grp", "sdhci_8bit_grp" }; 549static struct spear_function sdhci_function = { 550 .name = "sdhci", 551 .groups = sdhci_grps, 552 .ngroups = ARRAY_SIZE(sdhci_grps), 553}; 554 555/* gpio1_0_to_3_pins */ 556static const unsigned gpio1_0_to_3_pins[] = { 39, 40, 41, 42 }; 557static struct spear_muxreg gpio1_0_to_3_muxreg[] = { 558 { 559 .reg = PMX_CONFIG_REG, 560 .mask = PMX_UART0_MODEM_MASK, 561 .val = 0, 562 }, 563}; 564 565static struct spear_modemux gpio1_0_to_3_modemux[] = { 566 { 567 .modes = PHOTO_FRAME_MODE, 568 .muxregs = gpio1_0_to_3_muxreg, 569 .nmuxregs = ARRAY_SIZE(gpio1_0_to_3_muxreg), 570 }, 571}; 572 573static struct spear_pingroup gpio1_0_to_3_pingroup = { 574 .name = "gpio1_0_to_3_grp", 575 .pins = gpio1_0_to_3_pins, 576 .npins = ARRAY_SIZE(gpio1_0_to_3_pins), 577 .modemuxs = gpio1_0_to_3_modemux, 578 .nmodemuxs = ARRAY_SIZE(gpio1_0_to_3_modemux), 579}; 580 581/* gpio1_4_to_7_pins */ 582static const unsigned gpio1_4_to_7_pins[] = { 43, 44, 45, 46 }; 583 584static struct spear_muxreg gpio1_4_to_7_muxreg[] = { 585 { 586 .reg = PMX_CONFIG_REG, 587 .mask = PMX_TIMER_0_1_MASK | PMX_TIMER_2_3_MASK, 588 .val = 0, 589 }, 590}; 591 592static struct spear_modemux gpio1_4_to_7_modemux[] = { 593 { 594 .modes = PHOTO_FRAME_MODE, 595 .muxregs = gpio1_4_to_7_muxreg, 596 .nmuxregs = ARRAY_SIZE(gpio1_4_to_7_muxreg), 597 }, 598}; 599 600static struct spear_pingroup gpio1_4_to_7_pingroup = { 601 .name = "gpio1_4_to_7_grp", 602 .pins = gpio1_4_to_7_pins, 603 .npins = ARRAY_SIZE(gpio1_4_to_7_pins), 604 .modemuxs = gpio1_4_to_7_modemux, 605 .nmodemuxs = ARRAY_SIZE(gpio1_4_to_7_modemux), 606}; 607 608static const char *const gpio1_grps[] = { "gpio1_0_to_3_grp", "gpio1_4_to_7_grp" 609}; 610static struct spear_function gpio1_function = { 611 .name = "gpio1", 612 .groups = gpio1_grps, 613 .ngroups = ARRAY_SIZE(gpio1_grps), 614}; 615 616/* pingroups */ 617static struct spear_pingroup *spear300_pingroups[] = { 618 SPEAR3XX_COMMON_PINGROUPS, 619 &fsmc_2chips_pingroup, 620 &fsmc_4chips_pingroup, 621 &clcd_lcdmode_pingroup, 622 &clcd_pfmode_pingroup, 623 &tdm_pingroup, 624 &i2c_clk_pingroup, 625 &caml_pingroup, 626 &camu_pingroup, 627 &dac_pingroup, 628 &i2s_pingroup, 629 &sdhci_4bit_pingroup, 630 &sdhci_8bit_pingroup, 631 &gpio1_0_to_3_pingroup, 632 &gpio1_4_to_7_pingroup, 633}; 634 635/* functions */ 636static struct spear_function *spear300_functions[] = { 637 SPEAR3XX_COMMON_FUNCTIONS, 638 &fsmc_function, 639 &clcd_function, 640 &tdm_function, 641 &i2c_function, 642 &cam_function, 643 &dac_function, 644 &i2s_function, 645 &sdhci_function, 646 &gpio1_function, 647}; 648 649static const struct of_device_id spear300_pinctrl_of_match[] = { 650 { 651 .compatible = "st,spear300-pinmux", 652 }, 653 {}, 654}; 655 656static int spear300_pinctrl_probe(struct platform_device *pdev) 657{ 658 int ret; 659 660 spear3xx_machdata.groups = spear300_pingroups; 661 spear3xx_machdata.ngroups = ARRAY_SIZE(spear300_pingroups); 662 spear3xx_machdata.functions = spear300_functions; 663 spear3xx_machdata.nfunctions = ARRAY_SIZE(spear300_functions); 664 spear3xx_machdata.gpio_pingroups = NULL; 665 spear3xx_machdata.ngpio_pingroups = 0; 666 667 spear3xx_machdata.modes_supported = true; 668 spear3xx_machdata.pmx_modes = spear300_pmx_modes; 669 spear3xx_machdata.npmx_modes = ARRAY_SIZE(spear300_pmx_modes); 670 671 pmx_init_addr(&spear3xx_machdata, PMX_CONFIG_REG); 672 673 ret = spear_pinctrl_probe(pdev, &spear3xx_machdata); 674 if (ret) 675 return ret; 676 677 return 0; 678} 679 680static int spear300_pinctrl_remove(struct platform_device *pdev) 681{ 682 return spear_pinctrl_remove(pdev); 683} 684 685static struct platform_driver spear300_pinctrl_driver = { 686 .driver = { 687 .name = DRIVER_NAME, 688 .of_match_table = spear300_pinctrl_of_match, 689 }, 690 .probe = spear300_pinctrl_probe, 691 .remove = spear300_pinctrl_remove, 692}; 693 694static int __init spear300_pinctrl_init(void) 695{ 696 return platform_driver_register(&spear300_pinctrl_driver); 697} 698arch_initcall(spear300_pinctrl_init); 699 700static void __exit spear300_pinctrl_exit(void) 701{ 702 platform_driver_unregister(&spear300_pinctrl_driver); 703} 704module_exit(spear300_pinctrl_exit); 705 706MODULE_AUTHOR("Viresh Kumar <viresh.linux@gmail.com>"); 707MODULE_DESCRIPTION("ST Microelectronics SPEAr300 pinctrl driver"); 708MODULE_LICENSE("GPL v2"); 709MODULE_DEVICE_TABLE(of, spear300_pinctrl_of_match); 710