linux/drivers/pinctrl/pinctrl-dove.c
<<
>>
Prefs
   1/*
   2 * Marvell Dove pinctrl driver based on mvebu pinctrl core
   3 *
   4 * Author: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License as published by
   8 * the Free Software Foundation; either version 2 of the License, or
   9 * (at your option) any later version.
  10 */
  11
  12#include <linux/err.h>
  13#include <linux/init.h>
  14#include <linux/io.h>
  15#include <linux/module.h>
  16#include <linux/bitops.h>
  17#include <linux/platform_device.h>
  18#include <linux/clk.h>
  19#include <linux/of.h>
  20#include <linux/of_device.h>
  21#include <linux/pinctrl/pinctrl.h>
  22
  23#include "pinctrl-mvebu.h"
  24
  25#define DOVE_SB_REGS_VIRT_BASE          0xfde00000
  26#define DOVE_MPP_VIRT_BASE              (DOVE_SB_REGS_VIRT_BASE | 0xd0200)
  27#define DOVE_PMU_MPP_GENERAL_CTRL       (DOVE_MPP_VIRT_BASE + 0x10)
  28#define  DOVE_AU0_AC97_SEL              BIT(16)
  29#define DOVE_GLOBAL_CONFIG_1            (DOVE_SB_REGS_VIRT_BASE | 0xe802C)
  30#define  DOVE_TWSI_ENABLE_OPTION1       BIT(7)
  31#define DOVE_GLOBAL_CONFIG_2            (DOVE_SB_REGS_VIRT_BASE | 0xe8030)
  32#define  DOVE_TWSI_ENABLE_OPTION2       BIT(20)
  33#define  DOVE_TWSI_ENABLE_OPTION3       BIT(21)
  34#define  DOVE_TWSI_OPTION3_GPIO         BIT(22)
  35#define DOVE_SSP_CTRL_STATUS_1          (DOVE_SB_REGS_VIRT_BASE | 0xe8034)
  36#define  DOVE_SSP_ON_AU1                BIT(0)
  37#define DOVE_MPP_GENERAL_VIRT_BASE      (DOVE_SB_REGS_VIRT_BASE | 0xe803c)
  38#define  DOVE_AU1_SPDIFO_GPIO_EN        BIT(1)
  39#define  DOVE_NAND_GPIO_EN              BIT(0)
  40#define DOVE_GPIO_LO_VIRT_BASE          (DOVE_SB_REGS_VIRT_BASE | 0xd0400)
  41#define DOVE_MPP_CTRL4_VIRT_BASE        (DOVE_GPIO_LO_VIRT_BASE + 0x40)
  42#define  DOVE_SPI_GPIO_SEL              BIT(5)
  43#define  DOVE_UART1_GPIO_SEL            BIT(4)
  44#define  DOVE_AU1_GPIO_SEL              BIT(3)
  45#define  DOVE_CAM_GPIO_SEL              BIT(2)
  46#define  DOVE_SD1_GPIO_SEL              BIT(1)
  47#define  DOVE_SD0_GPIO_SEL              BIT(0)
  48
  49#define MPPS_PER_REG    8
  50#define MPP_BITS        4
  51#define MPP_MASK        0xf
  52
  53#define CONFIG_PMU      BIT(4)
  54
  55static int dove_pmu_mpp_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
  56                                 unsigned long *config)
  57{
  58        unsigned off = (ctrl->pid / MPPS_PER_REG) * MPP_BITS;
  59        unsigned shift = (ctrl->pid % MPPS_PER_REG) * MPP_BITS;
  60        unsigned long pmu = readl(DOVE_PMU_MPP_GENERAL_CTRL);
  61        unsigned long mpp = readl(DOVE_MPP_VIRT_BASE + off);
  62
  63        if (pmu & (1 << ctrl->pid))
  64                *config = CONFIG_PMU;
  65        else
  66                *config = (mpp >> shift) & MPP_MASK;
  67        return 0;
  68}
  69
  70static int dove_pmu_mpp_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
  71                                 unsigned long config)
  72{
  73        unsigned off = (ctrl->pid / MPPS_PER_REG) * MPP_BITS;
  74        unsigned shift = (ctrl->pid % MPPS_PER_REG) * MPP_BITS;
  75        unsigned long pmu = readl(DOVE_PMU_MPP_GENERAL_CTRL);
  76        unsigned long mpp = readl(DOVE_MPP_VIRT_BASE + off);
  77
  78        if (config == CONFIG_PMU)
  79                writel(pmu | (1 << ctrl->pid), DOVE_PMU_MPP_GENERAL_CTRL);
  80        else {
  81                writel(pmu & ~(1 << ctrl->pid), DOVE_PMU_MPP_GENERAL_CTRL);
  82                mpp &= ~(MPP_MASK << shift);
  83                mpp |= config << shift;
  84                writel(mpp, DOVE_MPP_VIRT_BASE + off);
  85        }
  86        return 0;
  87}
  88
  89static int dove_mpp4_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
  90                              unsigned long *config)
  91{
  92        unsigned long mpp4 = readl(DOVE_MPP_CTRL4_VIRT_BASE);
  93        unsigned long mask;
  94
  95        switch (ctrl->pid) {
  96        case 24: /* mpp_camera */
  97                mask = DOVE_CAM_GPIO_SEL;
  98                break;
  99        case 40: /* mpp_sdio0 */
 100                mask = DOVE_SD0_GPIO_SEL;
 101                break;
 102        case 46: /* mpp_sdio1 */
 103                mask = DOVE_SD1_GPIO_SEL;
 104                break;
 105        case 58: /* mpp_spi0 */
 106                mask = DOVE_SPI_GPIO_SEL;
 107                break;
 108        case 62: /* mpp_uart1 */
 109                mask = DOVE_UART1_GPIO_SEL;
 110                break;
 111        default:
 112                return -EINVAL;
 113        }
 114
 115        *config = ((mpp4 & mask) != 0);
 116
 117        return 0;
 118}
 119
 120static int dove_mpp4_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
 121                              unsigned long config)
 122{
 123        unsigned long mpp4 = readl(DOVE_MPP_CTRL4_VIRT_BASE);
 124        unsigned long mask;
 125
 126        switch (ctrl->pid) {
 127        case 24: /* mpp_camera */
 128                mask = DOVE_CAM_GPIO_SEL;
 129                break;
 130        case 40: /* mpp_sdio0 */
 131                mask = DOVE_SD0_GPIO_SEL;
 132                break;
 133        case 46: /* mpp_sdio1 */
 134                mask = DOVE_SD1_GPIO_SEL;
 135                break;
 136        case 58: /* mpp_spi0 */
 137                mask = DOVE_SPI_GPIO_SEL;
 138                break;
 139        case 62: /* mpp_uart1 */
 140                mask = DOVE_UART1_GPIO_SEL;
 141                break;
 142        default:
 143                return -EINVAL;
 144        }
 145
 146        mpp4 &= ~mask;
 147        if (config)
 148                mpp4 |= mask;
 149
 150        writel(mpp4, DOVE_MPP_CTRL4_VIRT_BASE);
 151
 152        return 0;
 153}
 154
 155static int dove_nand_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
 156                              unsigned long *config)
 157{
 158        unsigned long gmpp = readl(DOVE_MPP_GENERAL_VIRT_BASE);
 159
 160        *config = ((gmpp & DOVE_NAND_GPIO_EN) != 0);
 161
 162        return 0;
 163}
 164
 165static int dove_nand_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
 166                              unsigned long config)
 167{
 168        unsigned long gmpp = readl(DOVE_MPP_GENERAL_VIRT_BASE);
 169
 170        gmpp &= ~DOVE_NAND_GPIO_EN;
 171        if (config)
 172                gmpp |= DOVE_NAND_GPIO_EN;
 173
 174        writel(gmpp, DOVE_MPP_GENERAL_VIRT_BASE);
 175
 176        return 0;
 177}
 178
 179static int dove_audio0_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
 180                                unsigned long *config)
 181{
 182        unsigned long pmu = readl(DOVE_PMU_MPP_GENERAL_CTRL);
 183
 184        *config = ((pmu & DOVE_AU0_AC97_SEL) != 0);
 185
 186        return 0;
 187}
 188
 189static int dove_audio0_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
 190                                unsigned long config)
 191{
 192        unsigned long pmu = readl(DOVE_PMU_MPP_GENERAL_CTRL);
 193
 194        pmu &= ~DOVE_AU0_AC97_SEL;
 195        if (config)
 196                pmu |= DOVE_AU0_AC97_SEL;
 197        writel(pmu, DOVE_PMU_MPP_GENERAL_CTRL);
 198
 199        return 0;
 200}
 201
 202static int dove_audio1_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
 203                                unsigned long *config)
 204{
 205        unsigned long mpp4 = readl(DOVE_MPP_CTRL4_VIRT_BASE);
 206        unsigned long sspc1 = readl(DOVE_SSP_CTRL_STATUS_1);
 207        unsigned long gmpp = readl(DOVE_MPP_GENERAL_VIRT_BASE);
 208        unsigned long gcfg2 = readl(DOVE_GLOBAL_CONFIG_2);
 209
 210        *config = 0;
 211        if (mpp4 & DOVE_AU1_GPIO_SEL)
 212                *config |= BIT(3);
 213        if (sspc1 & DOVE_SSP_ON_AU1)
 214                *config |= BIT(2);
 215        if (gmpp & DOVE_AU1_SPDIFO_GPIO_EN)
 216                *config |= BIT(1);
 217        if (gcfg2 & DOVE_TWSI_OPTION3_GPIO)
 218                *config |= BIT(0);
 219
 220        /* SSP/TWSI only if I2S1 not set*/
 221        if ((*config & BIT(3)) == 0)
 222                *config &= ~(BIT(2) | BIT(0));
 223        /* TWSI only if SPDIFO not set*/
 224        if ((*config & BIT(1)) == 0)
 225                *config &= ~BIT(0);
 226        return 0;
 227}
 228
 229static int dove_audio1_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
 230                                unsigned long config)
 231{
 232        unsigned long mpp4 = readl(DOVE_MPP_CTRL4_VIRT_BASE);
 233        unsigned long sspc1 = readl(DOVE_SSP_CTRL_STATUS_1);
 234        unsigned long gmpp = readl(DOVE_MPP_GENERAL_VIRT_BASE);
 235        unsigned long gcfg2 = readl(DOVE_GLOBAL_CONFIG_2);
 236
 237        if (config & BIT(0))
 238                gcfg2 |= DOVE_TWSI_OPTION3_GPIO;
 239        if (config & BIT(1))
 240                gmpp |= DOVE_AU1_SPDIFO_GPIO_EN;
 241        if (config & BIT(2))
 242                sspc1 |= DOVE_SSP_ON_AU1;
 243        if (config & BIT(3))
 244                mpp4 |= DOVE_AU1_GPIO_SEL;
 245
 246        writel(mpp4, DOVE_MPP_CTRL4_VIRT_BASE);
 247        writel(sspc1, DOVE_SSP_CTRL_STATUS_1);
 248        writel(gmpp, DOVE_MPP_GENERAL_VIRT_BASE);
 249        writel(gcfg2, DOVE_GLOBAL_CONFIG_2);
 250
 251        return 0;
 252}
 253
 254/* mpp[52:57] gpio pins depend heavily on current config;
 255 * gpio_req does not try to mux in gpio capabilities to not
 256 * break other functions. If you require all mpps as gpio
 257 * enforce gpio setting by pinctrl mapping.
 258 */
 259static int dove_audio1_ctrl_gpio_req(struct mvebu_mpp_ctrl *ctrl, u8 pid)
 260{
 261        unsigned long config;
 262
 263        dove_audio1_ctrl_get(ctrl, &config);
 264
 265        switch (config) {
 266        case 0x02: /* i2s1 : gpio[56:57] */
 267        case 0x0e: /* ssp  : gpio[56:57] */
 268                if (pid >= 56)
 269                        return 0;
 270                return -ENOTSUPP;
 271        case 0x08: /* spdifo : gpio[52:55] */
 272        case 0x0b: /* twsi   : gpio[52:55] */
 273                if (pid <= 55)
 274                        return 0;
 275                return -ENOTSUPP;
 276        case 0x0a: /* all gpio */
 277                return 0;
 278        /* 0x00 : i2s1/spdifo : no gpio */
 279        /* 0x0c : ssp/spdifo  : no gpio */
 280        /* 0x0f : ssp/twsi    : no gpio */
 281        }
 282        return -ENOTSUPP;
 283}
 284
 285/* mpp[52:57] has gpio pins capable of in and out */
 286static int dove_audio1_ctrl_gpio_dir(struct mvebu_mpp_ctrl *ctrl, u8 pid,
 287                                bool input)
 288{
 289        if (pid < 52 || pid > 57)
 290                return -ENOTSUPP;
 291        return 0;
 292}
 293
 294static int dove_twsi_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
 295                              unsigned long *config)
 296{
 297        unsigned long gcfg1 = readl(DOVE_GLOBAL_CONFIG_1);
 298        unsigned long gcfg2 = readl(DOVE_GLOBAL_CONFIG_2);
 299
 300        *config = 0;
 301        if (gcfg1 & DOVE_TWSI_ENABLE_OPTION1)
 302                *config = 1;
 303        else if (gcfg2 & DOVE_TWSI_ENABLE_OPTION2)
 304                *config = 2;
 305        else if (gcfg2 & DOVE_TWSI_ENABLE_OPTION3)
 306                *config = 3;
 307
 308        return 0;
 309}
 310
 311static int dove_twsi_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
 312                                unsigned long config)
 313{
 314        unsigned long gcfg1 = readl(DOVE_GLOBAL_CONFIG_1);
 315        unsigned long gcfg2 = readl(DOVE_GLOBAL_CONFIG_2);
 316
 317        gcfg1 &= ~DOVE_TWSI_ENABLE_OPTION1;
 318        gcfg2 &= ~(DOVE_TWSI_ENABLE_OPTION2 | DOVE_TWSI_ENABLE_OPTION2);
 319
 320        switch (config) {
 321        case 1:
 322                gcfg1 |= DOVE_TWSI_ENABLE_OPTION1;
 323                break;
 324        case 2:
 325                gcfg2 |= DOVE_TWSI_ENABLE_OPTION2;
 326                break;
 327        case 3:
 328                gcfg2 |= DOVE_TWSI_ENABLE_OPTION3;
 329                break;
 330        }
 331
 332        writel(gcfg1, DOVE_GLOBAL_CONFIG_1);
 333        writel(gcfg2, DOVE_GLOBAL_CONFIG_2);
 334
 335        return 0;
 336}
 337
 338static struct mvebu_mpp_ctrl dove_mpp_controls[] = {
 339        MPP_FUNC_CTRL(0, 0, "mpp0", dove_pmu_mpp_ctrl),
 340        MPP_FUNC_CTRL(1, 1, "mpp1", dove_pmu_mpp_ctrl),
 341        MPP_FUNC_CTRL(2, 2, "mpp2", dove_pmu_mpp_ctrl),
 342        MPP_FUNC_CTRL(3, 3, "mpp3", dove_pmu_mpp_ctrl),
 343        MPP_FUNC_CTRL(4, 4, "mpp4", dove_pmu_mpp_ctrl),
 344        MPP_FUNC_CTRL(5, 5, "mpp5", dove_pmu_mpp_ctrl),
 345        MPP_FUNC_CTRL(6, 6, "mpp6", dove_pmu_mpp_ctrl),
 346        MPP_FUNC_CTRL(7, 7, "mpp7", dove_pmu_mpp_ctrl),
 347        MPP_FUNC_CTRL(8, 8, "mpp8", dove_pmu_mpp_ctrl),
 348        MPP_FUNC_CTRL(9, 9, "mpp9", dove_pmu_mpp_ctrl),
 349        MPP_FUNC_CTRL(10, 10, "mpp10", dove_pmu_mpp_ctrl),
 350        MPP_FUNC_CTRL(11, 11, "mpp11", dove_pmu_mpp_ctrl),
 351        MPP_FUNC_CTRL(12, 12, "mpp12", dove_pmu_mpp_ctrl),
 352        MPP_FUNC_CTRL(13, 13, "mpp13", dove_pmu_mpp_ctrl),
 353        MPP_FUNC_CTRL(14, 14, "mpp14", dove_pmu_mpp_ctrl),
 354        MPP_FUNC_CTRL(15, 15, "mpp15", dove_pmu_mpp_ctrl),
 355        MPP_REG_CTRL(16, 23),
 356        MPP_FUNC_CTRL(24, 39, "mpp_camera", dove_mpp4_ctrl),
 357        MPP_FUNC_CTRL(40, 45, "mpp_sdio0", dove_mpp4_ctrl),
 358        MPP_FUNC_CTRL(46, 51, "mpp_sdio1", dove_mpp4_ctrl),
 359        MPP_FUNC_GPIO_CTRL(52, 57, "mpp_audio1", dove_audio1_ctrl),
 360        MPP_FUNC_CTRL(58, 61, "mpp_spi0", dove_mpp4_ctrl),
 361        MPP_FUNC_CTRL(62, 63, "mpp_uart1", dove_mpp4_ctrl),
 362        MPP_FUNC_CTRL(64, 71, "mpp_nand", dove_nand_ctrl),
 363        MPP_FUNC_CTRL(72, 72, "audio0", dove_audio0_ctrl),
 364        MPP_FUNC_CTRL(73, 73, "twsi", dove_twsi_ctrl),
 365};
 366
 367static struct mvebu_mpp_mode dove_mpp_modes[] = {
 368        MPP_MODE(0,
 369                MPP_FUNCTION(0x00, "gpio", NULL),
 370                MPP_FUNCTION(0x02, "uart2", "rts"),
 371                MPP_FUNCTION(0x03, "sdio0", "cd"),
 372                MPP_FUNCTION(0x0f, "lcd0", "pwm"),
 373                MPP_FUNCTION(0x10, "pmu", NULL)),
 374        MPP_MODE(1,
 375                MPP_FUNCTION(0x00, "gpio", NULL),
 376                MPP_FUNCTION(0x02, "uart2", "cts"),
 377                MPP_FUNCTION(0x03, "sdio0", "wp"),
 378                MPP_FUNCTION(0x0f, "lcd1", "pwm"),
 379                MPP_FUNCTION(0x10, "pmu", NULL)),
 380        MPP_MODE(2,
 381                MPP_FUNCTION(0x00, "gpio", NULL),
 382                MPP_FUNCTION(0x01, "sata", "prsnt"),
 383                MPP_FUNCTION(0x02, "uart2", "txd"),
 384                MPP_FUNCTION(0x03, "sdio0", "buspwr"),
 385                MPP_FUNCTION(0x04, "uart1", "rts"),
 386                MPP_FUNCTION(0x10, "pmu", NULL)),
 387        MPP_MODE(3,
 388                MPP_FUNCTION(0x00, "gpio", NULL),
 389                MPP_FUNCTION(0x01, "sata", "act"),
 390                MPP_FUNCTION(0x02, "uart2", "rxd"),
 391                MPP_FUNCTION(0x03, "sdio0", "ledctrl"),
 392                MPP_FUNCTION(0x04, "uart1", "cts"),
 393                MPP_FUNCTION(0x0f, "lcd-spi", "cs1"),
 394                MPP_FUNCTION(0x10, "pmu", NULL)),
 395        MPP_MODE(4,
 396                MPP_FUNCTION(0x00, "gpio", NULL),
 397                MPP_FUNCTION(0x02, "uart3", "rts"),
 398                MPP_FUNCTION(0x03, "sdio1", "cd"),
 399                MPP_FUNCTION(0x04, "spi1", "miso"),
 400                MPP_FUNCTION(0x10, "pmu", NULL)),
 401        MPP_MODE(5,
 402                MPP_FUNCTION(0x00, "gpio", NULL),
 403                MPP_FUNCTION(0x02, "uart3", "cts"),
 404                MPP_FUNCTION(0x03, "sdio1", "wp"),
 405                MPP_FUNCTION(0x04, "spi1", "cs"),
 406                MPP_FUNCTION(0x10, "pmu", NULL)),
 407        MPP_MODE(6,
 408                MPP_FUNCTION(0x00, "gpio", NULL),
 409                MPP_FUNCTION(0x02, "uart3", "txd"),
 410                MPP_FUNCTION(0x03, "sdio1", "buspwr"),
 411                MPP_FUNCTION(0x04, "spi1", "mosi"),
 412                MPP_FUNCTION(0x10, "pmu", NULL)),
 413        MPP_MODE(7,
 414                MPP_FUNCTION(0x00, "gpio", NULL),
 415                MPP_FUNCTION(0x02, "uart3", "rxd"),
 416                MPP_FUNCTION(0x03, "sdio1", "ledctrl"),
 417                MPP_FUNCTION(0x04, "spi1", "sck"),
 418                MPP_FUNCTION(0x10, "pmu", NULL)),
 419        MPP_MODE(8,
 420                MPP_FUNCTION(0x00, "gpio", NULL),
 421                MPP_FUNCTION(0x01, "watchdog", "rstout"),
 422                MPP_FUNCTION(0x10, "pmu", NULL)),
 423        MPP_MODE(9,
 424                MPP_FUNCTION(0x00, "gpio", NULL),
 425                MPP_FUNCTION(0x05, "pex1", "clkreq"),
 426                MPP_FUNCTION(0x10, "pmu", NULL)),
 427        MPP_MODE(10,
 428                MPP_FUNCTION(0x00, "gpio", NULL),
 429                MPP_FUNCTION(0x05, "ssp", "sclk"),
 430                MPP_FUNCTION(0x10, "pmu", NULL)),
 431        MPP_MODE(11,
 432                MPP_FUNCTION(0x00, "gpio", NULL),
 433                MPP_FUNCTION(0x01, "sata", "prsnt"),
 434                MPP_FUNCTION(0x02, "sata-1", "act"),
 435                MPP_FUNCTION(0x03, "sdio0", "ledctrl"),
 436                MPP_FUNCTION(0x04, "sdio1", "ledctrl"),
 437                MPP_FUNCTION(0x05, "pex0", "clkreq"),
 438                MPP_FUNCTION(0x10, "pmu", NULL)),
 439        MPP_MODE(12,
 440                MPP_FUNCTION(0x00, "gpio", NULL),
 441                MPP_FUNCTION(0x01, "sata", "act"),
 442                MPP_FUNCTION(0x02, "uart2", "rts"),
 443                MPP_FUNCTION(0x03, "audio0", "extclk"),
 444                MPP_FUNCTION(0x04, "sdio1", "cd"),
 445                MPP_FUNCTION(0x10, "pmu", NULL)),
 446        MPP_MODE(13,
 447                MPP_FUNCTION(0x00, "gpio", NULL),
 448                MPP_FUNCTION(0x02, "uart2", "cts"),
 449                MPP_FUNCTION(0x03, "audio1", "extclk"),
 450                MPP_FUNCTION(0x04, "sdio1", "wp"),
 451                MPP_FUNCTION(0x05, "ssp", "extclk"),
 452                MPP_FUNCTION(0x10, "pmu", NULL)),
 453        MPP_MODE(14,
 454                MPP_FUNCTION(0x00, "gpio", NULL),
 455                MPP_FUNCTION(0x02, "uart2", "txd"),
 456                MPP_FUNCTION(0x04, "sdio1", "buspwr"),
 457                MPP_FUNCTION(0x05, "ssp", "rxd"),
 458                MPP_FUNCTION(0x10, "pmu", NULL)),
 459        MPP_MODE(15,
 460                MPP_FUNCTION(0x00, "gpio", NULL),
 461                MPP_FUNCTION(0x02, "uart2", "rxd"),
 462                MPP_FUNCTION(0x04, "sdio1", "ledctrl"),
 463                MPP_FUNCTION(0x05, "ssp", "sfrm"),
 464                MPP_FUNCTION(0x10, "pmu", NULL)),
 465        MPP_MODE(16,
 466                MPP_FUNCTION(0x00, "gpio", NULL),
 467                MPP_FUNCTION(0x02, "uart3", "rts"),
 468                MPP_FUNCTION(0x03, "sdio0", "cd"),
 469                MPP_FUNCTION(0x04, "lcd-spi", "cs1"),
 470                MPP_FUNCTION(0x05, "ac97", "sdi1")),
 471        MPP_MODE(17,
 472                MPP_FUNCTION(0x00, "gpio", NULL),
 473                MPP_FUNCTION(0x01, "ac97-1", "sysclko"),
 474                MPP_FUNCTION(0x02, "uart3", "cts"),
 475                MPP_FUNCTION(0x03, "sdio0", "wp"),
 476                MPP_FUNCTION(0x04, "twsi", "sda"),
 477                MPP_FUNCTION(0x05, "ac97", "sdi2")),
 478        MPP_MODE(18,
 479                MPP_FUNCTION(0x00, "gpio", NULL),
 480                MPP_FUNCTION(0x02, "uart3", "txd"),
 481                MPP_FUNCTION(0x03, "sdio0", "buspwr"),
 482                MPP_FUNCTION(0x04, "lcd0", "pwm"),
 483                MPP_FUNCTION(0x05, "ac97", "sdi3")),
 484        MPP_MODE(19,
 485                MPP_FUNCTION(0x00, "gpio", NULL),
 486                MPP_FUNCTION(0x02, "uart3", "rxd"),
 487                MPP_FUNCTION(0x03, "sdio0", "ledctrl"),
 488                MPP_FUNCTION(0x04, "twsi", "sck")),
 489        MPP_MODE(20,
 490                MPP_FUNCTION(0x00, "gpio", NULL),
 491                MPP_FUNCTION(0x01, "ac97", "sysclko"),
 492                MPP_FUNCTION(0x02, "lcd-spi", "miso"),
 493                MPP_FUNCTION(0x03, "sdio1", "cd"),
 494                MPP_FUNCTION(0x05, "sdio0", "cd"),
 495                MPP_FUNCTION(0x06, "spi1", "miso")),
 496        MPP_MODE(21,
 497                MPP_FUNCTION(0x00, "gpio", NULL),
 498                MPP_FUNCTION(0x01, "uart1", "rts"),
 499                MPP_FUNCTION(0x02, "lcd-spi", "cs0"),
 500                MPP_FUNCTION(0x03, "sdio1", "wp"),
 501                MPP_FUNCTION(0x04, "ssp", "sfrm"),
 502                MPP_FUNCTION(0x05, "sdio0", "wp"),
 503                MPP_FUNCTION(0x06, "spi1", "cs")),
 504        MPP_MODE(22,
 505                MPP_FUNCTION(0x00, "gpio", NULL),
 506                MPP_FUNCTION(0x01, "uart1", "cts"),
 507                MPP_FUNCTION(0x02, "lcd-spi", "mosi"),
 508                MPP_FUNCTION(0x03, "sdio1", "buspwr"),
 509                MPP_FUNCTION(0x04, "ssp", "txd"),
 510                MPP_FUNCTION(0x05, "sdio0", "buspwr"),
 511                MPP_FUNCTION(0x06, "spi1", "mosi")),
 512        MPP_MODE(23,
 513                MPP_FUNCTION(0x00, "gpio", NULL),
 514                MPP_FUNCTION(0x02, "lcd-spi", "sck"),
 515                MPP_FUNCTION(0x03, "sdio1", "ledctrl"),
 516                MPP_FUNCTION(0x04, "ssp", "sclk"),
 517                MPP_FUNCTION(0x05, "sdio0", "ledctrl"),
 518                MPP_FUNCTION(0x06, "spi1", "sck")),
 519        MPP_MODE(24,
 520                MPP_FUNCTION(0x00, "camera", NULL),
 521                MPP_FUNCTION(0x01, "gpio", NULL)),
 522        MPP_MODE(40,
 523                MPP_FUNCTION(0x00, "sdio0", NULL),
 524                MPP_FUNCTION(0x01, "gpio", NULL)),
 525        MPP_MODE(46,
 526                MPP_FUNCTION(0x00, "sdio1", NULL),
 527                MPP_FUNCTION(0x01, "gpio", NULL)),
 528        MPP_MODE(52,
 529                MPP_FUNCTION(0x00, "i2s1/spdifo", NULL),
 530                MPP_FUNCTION(0x02, "i2s1", NULL),
 531                MPP_FUNCTION(0x08, "spdifo", NULL),
 532                MPP_FUNCTION(0x0a, "gpio", NULL),
 533                MPP_FUNCTION(0x0b, "twsi", NULL),
 534                MPP_FUNCTION(0x0c, "ssp/spdifo", NULL),
 535                MPP_FUNCTION(0x0e, "ssp", NULL),
 536                MPP_FUNCTION(0x0f, "ssp/twsi", NULL)),
 537        MPP_MODE(58,
 538                MPP_FUNCTION(0x00, "spi0", NULL),
 539                MPP_FUNCTION(0x01, "gpio", NULL)),
 540        MPP_MODE(62,
 541                MPP_FUNCTION(0x00, "uart1", NULL),
 542                MPP_FUNCTION(0x01, "gpio", NULL)),
 543        MPP_MODE(64,
 544                MPP_FUNCTION(0x00, "nand", NULL),
 545                MPP_FUNCTION(0x01, "gpo", NULL)),
 546        MPP_MODE(72,
 547                MPP_FUNCTION(0x00, "i2s", NULL),
 548                MPP_FUNCTION(0x01, "ac97", NULL)),
 549        MPP_MODE(73,
 550                MPP_FUNCTION(0x00, "twsi-none", NULL),
 551                MPP_FUNCTION(0x01, "twsi-opt1", NULL),
 552                MPP_FUNCTION(0x02, "twsi-opt2", NULL),
 553                MPP_FUNCTION(0x03, "twsi-opt3", NULL)),
 554};
 555
 556static struct pinctrl_gpio_range dove_mpp_gpio_ranges[] = {
 557        MPP_GPIO_RANGE(0,  0,  0, 32),
 558        MPP_GPIO_RANGE(1, 32, 32, 32),
 559        MPP_GPIO_RANGE(2, 64, 64,  8),
 560};
 561
 562static struct mvebu_pinctrl_soc_info dove_pinctrl_info = {
 563        .controls = dove_mpp_controls,
 564        .ncontrols = ARRAY_SIZE(dove_mpp_controls),
 565        .modes = dove_mpp_modes,
 566        .nmodes = ARRAY_SIZE(dove_mpp_modes),
 567        .gpioranges = dove_mpp_gpio_ranges,
 568        .ngpioranges = ARRAY_SIZE(dove_mpp_gpio_ranges),
 569        .variant = 0,
 570};
 571
 572static struct clk *clk;
 573
 574static struct of_device_id dove_pinctrl_of_match[] __devinitdata = {
 575        { .compatible = "marvell,dove-pinctrl", .data = &dove_pinctrl_info },
 576        { }
 577};
 578
 579static int __devinit dove_pinctrl_probe(struct platform_device *pdev)
 580{
 581        const struct of_device_id *match =
 582                of_match_device(dove_pinctrl_of_match, &pdev->dev);
 583        pdev->dev.platform_data = match->data;
 584
 585        /*
 586         * General MPP Configuration Register is part of pdma registers.
 587         * grab clk to make sure it is ticking.
 588         */
 589        clk = devm_clk_get(&pdev->dev, NULL);
 590        if (!IS_ERR(clk))
 591                clk_prepare_enable(clk);
 592
 593        return mvebu_pinctrl_probe(pdev);
 594}
 595
 596static int __devexit dove_pinctrl_remove(struct platform_device *pdev)
 597{
 598        int ret;
 599
 600        ret = mvebu_pinctrl_remove(pdev);
 601        if (!IS_ERR(clk))
 602                clk_disable_unprepare(clk);
 603        return ret;
 604}
 605
 606static struct platform_driver dove_pinctrl_driver = {
 607        .driver = {
 608                .name = "dove-pinctrl",
 609                .owner = THIS_MODULE,
 610                .of_match_table = of_match_ptr(dove_pinctrl_of_match),
 611        },
 612        .probe = dove_pinctrl_probe,
 613        .remove = __devexit_p(dove_pinctrl_remove),
 614};
 615
 616module_platform_driver(dove_pinctrl_driver);
 617
 618MODULE_AUTHOR("Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>");
 619MODULE_DESCRIPTION("Marvell Dove pinctrl driver");
 620MODULE_LICENSE("GPL v2");
 621
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.