Pin control bulk changes for the v3.15 series, no new core

functionality this time, just incremental driver updates:
 
 - A large refactoring of the MVEBU (Marvell) driver.
 
 - A large refactoring of the Tegra (nVidia) driver.
 
 - GPIO interrupt including soft edges support in the
   STi driver.
 
 - Misc updates to PFC (Renesas), AT91, ADI2 (Blackfin),
   pinctrl-single, sirf (CSR), msm (Qualcomm), Exynos (Samsung),
   sunxi (AllWinner), i.MX (Freescale), Baytrail.
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQIcBAABAgAGBQJTORWVAAoJEEEQszewGV1zkCgP/3CxgHSqwAN5ps1IxRhOThgQ
 UClm2EETW9hca7okOdCLgngEYJEtetQ0atAW9yJS6bwK9KP3zhQXVXFBS9ecO3Z4
 U8U6UuKWiBLxZjmaPS6NvSxAY61Co60aoTow67zxrVhnwF/a8Cl7E4y+jD/Q/bmk
 +NM5B9puRYO2kPhjfr9VwIsQamjyCN8uXXI1r5YSR/ti1IbX78DDlz4+fyBfYX5f
 h95B8+kfDzygHIHpuLs3zJiRnKw/Q5G/PbDHyA2TgpL2Z8/Lyv6hvMWZ1O1qFOXi
 SDkyCv0ocXgVlYn6CT7k9s6/q2TVmD7hjiiLHAYebZcBg3NbF3/ApUYzNTAdp7eu
 FuuBPk4wCCvwxs0PFKNWQHzlCvr0WEbZNmUmKFzUOKoZMsl//lsm0l5v0IYJBs1w
 iB/ruetNVLlq9jhMCcmgesSn5JRxOW9jhU/N2VIMSu/L8nIFeTbok8iL3abTEglg
 gE1odnZf6lDsrcuq7VkGq6xXbevxz/pJVG604Y2vNvqvdDbQA9e1F9X+Ggh1gZTb
 Fnb0B7D42LlT5SDSzsxMciOvVAZ5PzRnsDvjIqEs+xp22IiLHQ+fK09AO76DgVy9
 oxb897mc2Oa3BbjJBE/Dkk2QjGlq0vHNf7Mm3W+nerGS5o0C78x7KwEWH7/X5ICd
 szzkXNdY7V8DMMzrsDOe
 =i7Sq
 -----END PGP SIGNATURE-----

Merge tag 'pinctrl-v3.15-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl

Pull pin control bulk changes from Linus Walleij:
 "Pin control bulk changes for the v3.15 series, no new core
  functionality this time, just incremental driver updates:

   - A large refactoring of the MVEBU (Marvell) driver.

   - A large refactoring of the Tegra (nVidia) driver.

   - GPIO interrupt including soft edges support in the STi driver.

   - Misc updates to PFC (Renesas), AT91, ADI2 (Blackfin),
     pinctrl-single, sirf (CSR), msm (Qualcomm), Exynos (Samsung), sunxi
     (AllWinner), i.MX (Freescale), Baytrail"

* tag 'pinctrl-v3.15-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl: (72 commits)
  pinctrl: tegra: add some missing Tegra114 entries
  pinctrl: tegra: fix some mistakes in Tegra124
  pinctrl: msm: fix up out-of-order merge conflict
  pinctrl: st: Fix error check for of_irq_to_resource usage
  pinctrl: tegra: consistency cleanup
  pinctrl: tegra: dynamically calculate function list of groups
  pinctrl: tegra: init Tegra20/30 at module_init time
  pinctrl: st: Use ARRAY_SIZE instead of raw value for number of delays
  pinctrl: st: add pinctrl support for the STiH407 SoC
  pinctrl: st: Enhance the controller to manage unavailable registers
  pinctrl: msm: Simplify msm_config_reg() and callers
  pinctrl: msm: Remove impossible WARN_ON()s
  pinctrl: msm: Replace lookup tables with math
  pinctrl: msm: Drop OF_IRQ dependency
  pinctrl: msm: Drop unused includes
  pinctrl: msm: Check for ngpios > MAX_NR_GPIO
  pinctrl: msm: Silence recursive lockdep warning
  pinctrl: mvebu: silence WARN to dev_warn
  pinctrl: msm: drop wake_irqs bitmap
  pinctrl-baytrail: add function mux checking in gpio pin request
  ...
This commit is contained in:
Linus Torvalds 2014-04-01 13:10:49 -07:00
commit d64b393253
54 changed files with 3439 additions and 4677 deletions

View file

@ -224,7 +224,7 @@ config PINCTRL_MSM
config PINCTRL_MSM8X74
tristate "Qualcomm 8x74 pin controller driver"
depends on GPIOLIB && OF && OF_IRQ
depends on GPIOLIB && OF
select PINCTRL_MSM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for the

View file

@ -186,7 +186,9 @@ int pinctrl_dt_to_map(struct pinctrl *p)
/* CONFIG_OF enabled, p->dev not instantiated from DT */
if (!np) {
dev_dbg(p->dev, "no of_node; not parsing pinctrl DT\n");
if (of_have_populated_dt())
dev_dbg(p->dev,
"no of_node; not parsing pinctrl DT\n");
return 0;
}

View file

@ -8,6 +8,7 @@ config PINCTRL_MVEBU
config PINCTRL_DOVE
bool
select PINCTRL_MVEBU
select MFD_SYSCON
config PINCTRL_KIRKWOOD
bool
@ -17,6 +18,14 @@ config PINCTRL_ARMADA_370
bool
select PINCTRL_MVEBU
config PINCTRL_ARMADA_375
bool
select PINCTRL_MVEBU
config PINCTRL_ARMADA_38X
bool
select PINCTRL_MVEBU
config PINCTRL_ARMADA_XP
bool
select PINCTRL_MVEBU

View file

@ -2,4 +2,6 @@ obj-$(CONFIG_PINCTRL_MVEBU) += pinctrl-mvebu.o
obj-$(CONFIG_PINCTRL_DOVE) += pinctrl-dove.o
obj-$(CONFIG_PINCTRL_KIRKWOOD) += pinctrl-kirkwood.o
obj-$(CONFIG_PINCTRL_ARMADA_370) += pinctrl-armada-370.o
obj-$(CONFIG_PINCTRL_ARMADA_375) += pinctrl-armada-375.o
obj-$(CONFIG_PINCTRL_ARMADA_38X) += pinctrl-armada-38x.o
obj-$(CONFIG_PINCTRL_ARMADA_XP) += pinctrl-armada-xp.o

View file

@ -23,6 +23,18 @@
#include "pinctrl-mvebu.h"
static void __iomem *mpp_base;
static int armada_370_mpp_ctrl_get(unsigned pid, unsigned long *config)
{
return default_mpp_ctrl_get(mpp_base, pid, config);
}
static int armada_370_mpp_ctrl_set(unsigned pid, unsigned long config)
{
return default_mpp_ctrl_set(mpp_base, pid, config);
}
static struct mvebu_mpp_mode mv88f6710_mpp_modes[] = {
MPP_MODE(0,
MPP_FUNCTION(0x0, "gpio", NULL),
@ -373,7 +385,7 @@ static struct of_device_id armada_370_pinctrl_of_match[] = {
};
static struct mvebu_mpp_ctrl mv88f6710_mpp_controls[] = {
MPP_REG_CTRL(0, 65),
MPP_FUNC_CTRL(0, 65, NULL, armada_370_mpp_ctrl),
};
static struct pinctrl_gpio_range mv88f6710_mpp_gpio_ranges[] = {
@ -385,6 +397,12 @@ static struct pinctrl_gpio_range mv88f6710_mpp_gpio_ranges[] = {
static int armada_370_pinctrl_probe(struct platform_device *pdev)
{
struct mvebu_pinctrl_soc_info *soc = &armada_370_pinctrl_info;
struct resource *res;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
mpp_base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(mpp_base))
return PTR_ERR(mpp_base);
soc->variant = 0; /* no variants for Armada 370 */
soc->controls = mv88f6710_mpp_controls;

View file

@ -0,0 +1,459 @@
/*
* Marvell Armada 375 pinctrl driver based on mvebu pinctrl core
*
* Copyright (C) 2012 Marvell
*
* Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#include <linux/err.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/pinctrl/pinctrl.h>
#include "pinctrl-mvebu.h"
static void __iomem *mpp_base;
static int armada_375_mpp_ctrl_get(unsigned pid, unsigned long *config)
{
return default_mpp_ctrl_get(mpp_base, pid, config);
}
static int armada_375_mpp_ctrl_set(unsigned pid, unsigned long config)
{
return default_mpp_ctrl_set(mpp_base, pid, config);
}
static struct mvebu_mpp_mode mv88f6720_mpp_modes[] = {
MPP_MODE(0,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "dev", "ad2"),
MPP_FUNCTION(0x2, "spi0", "cs1"),
MPP_FUNCTION(0x3, "spi1", "cs1"),
MPP_FUNCTION(0x5, "nand", "io2")),
MPP_MODE(1,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "dev", "ad3"),
MPP_FUNCTION(0x2, "spi0", "mosi"),
MPP_FUNCTION(0x3, "spi1", "mosi"),
MPP_FUNCTION(0x5, "nand", "io3")),
MPP_MODE(2,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "dev", "ad4"),
MPP_FUNCTION(0x2, "ptp", "eventreq"),
MPP_FUNCTION(0x3, "led", "c0"),
MPP_FUNCTION(0x4, "audio", "sdi"),
MPP_FUNCTION(0x5, "nand", "io4"),
MPP_FUNCTION(0x6, "spi1", "mosi")),
MPP_MODE(3,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "dev", "ad5"),
MPP_FUNCTION(0x2, "ptp", "triggen"),
MPP_FUNCTION(0x3, "led", "p3"),
MPP_FUNCTION(0x4, "audio", "mclk"),
MPP_FUNCTION(0x5, "nand", "io5"),
MPP_FUNCTION(0x6, "spi1", "miso")),
MPP_MODE(4,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "dev", "ad6"),
MPP_FUNCTION(0x2, "spi0", "miso"),
MPP_FUNCTION(0x3, "spi1", "miso"),
MPP_FUNCTION(0x5, "nand", "io6")),
MPP_MODE(5,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "dev", "ad7"),
MPP_FUNCTION(0x2, "spi0", "cs2"),
MPP_FUNCTION(0x3, "spi1", "cs2"),
MPP_FUNCTION(0x5, "nand", "io7"),
MPP_FUNCTION(0x6, "spi1", "miso")),
MPP_MODE(6,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "dev", "ad0"),
MPP_FUNCTION(0x3, "led", "p1"),
MPP_FUNCTION(0x4, "audio", "rclk"),
MPP_FUNCTION(0x5, "nand", "io0")),
MPP_MODE(7,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "dev", "ad1"),
MPP_FUNCTION(0x2, "ptp", "clk"),
MPP_FUNCTION(0x3, "led", "p2"),
MPP_FUNCTION(0x4, "audio", "extclk"),
MPP_FUNCTION(0x5, "nand", "io1")),
MPP_MODE(8,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "dev ", "bootcs"),
MPP_FUNCTION(0x2, "spi0", "cs0"),
MPP_FUNCTION(0x3, "spi1", "cs0"),
MPP_FUNCTION(0x5, "nand", "ce")),
MPP_MODE(9,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "nf", "wen"),
MPP_FUNCTION(0x2, "spi0", "sck"),
MPP_FUNCTION(0x3, "spi1", "sck"),
MPP_FUNCTION(0x5, "nand", "we")),
MPP_MODE(10,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "nf", "ren"),
MPP_FUNCTION(0x2, "dram", "vttctrl"),
MPP_FUNCTION(0x3, "led", "c1"),
MPP_FUNCTION(0x5, "nand", "re"),
MPP_FUNCTION(0x6, "spi1", "sck")),
MPP_MODE(11,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "dev", "a0"),
MPP_FUNCTION(0x3, "led", "c2"),
MPP_FUNCTION(0x4, "audio", "sdo"),
MPP_FUNCTION(0x5, "nand", "cle")),
MPP_MODE(12,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "dev", "a1"),
MPP_FUNCTION(0x4, "audio", "bclk"),
MPP_FUNCTION(0x5, "nand", "ale")),
MPP_MODE(13,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "dev", "readyn"),
MPP_FUNCTION(0x2, "pcie0", "rstoutn"),
MPP_FUNCTION(0x3, "pcie1", "rstoutn"),
MPP_FUNCTION(0x5, "nand", "rb"),
MPP_FUNCTION(0x6, "spi1", "mosi")),
MPP_MODE(14,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x2, "i2c0", "sda"),
MPP_FUNCTION(0x3, "uart1", "txd")),
MPP_MODE(15,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x2, "i2c0", "sck"),
MPP_FUNCTION(0x3, "uart1", "rxd")),
MPP_MODE(16,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x2, "uart0", "txd")),
MPP_MODE(17,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x2, "uart0", "rxd")),
MPP_MODE(18,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x2, "tdm", "intn")),
MPP_MODE(19,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x2, "tdm", "rstn")),
MPP_MODE(20,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x2, "tdm", "pclk")),
MPP_MODE(21,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x2, "tdm", "fsync")),
MPP_MODE(22,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x2, "tdm", "drx")),
MPP_MODE(23,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x2, "tdm", "dtx")),
MPP_MODE(24,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "led", "p0"),
MPP_FUNCTION(0x2, "ge1", "rxd0"),
MPP_FUNCTION(0x3, "sd", "cmd"),
MPP_FUNCTION(0x4, "uart0", "rts"),
MPP_FUNCTION(0x5, "spi0", "cs0"),
MPP_FUNCTION(0x6, "dev", "cs1")),
MPP_MODE(25,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "led", "p2"),
MPP_FUNCTION(0x2, "ge1", "rxd1"),
MPP_FUNCTION(0x3, "sd", "d0"),
MPP_FUNCTION(0x4, "uart0", "cts"),
MPP_FUNCTION(0x5, "spi0", "mosi"),
MPP_FUNCTION(0x6, "dev", "cs2")),
MPP_MODE(26,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "pcie0", "clkreq"),
MPP_FUNCTION(0x2, "ge1", "rxd2"),
MPP_FUNCTION(0x3, "sd", "d2"),
MPP_FUNCTION(0x4, "uart1", "rts"),
MPP_FUNCTION(0x5, "spi0", "cs1"),
MPP_FUNCTION(0x6, "led", "c1")),
MPP_MODE(27,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "pcie1", "clkreq"),
MPP_FUNCTION(0x2, "ge1", "rxd3"),
MPP_FUNCTION(0x3, "sd", "d1"),
MPP_FUNCTION(0x4, "uart1", "cts"),
MPP_FUNCTION(0x5, "spi0", "miso"),
MPP_FUNCTION(0x6, "led", "c2")),
MPP_MODE(28,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "led", "p3"),
MPP_FUNCTION(0x2, "ge1", "txctl"),
MPP_FUNCTION(0x3, "sd", "clk"),
MPP_FUNCTION(0x5, "dram", "vttctrl")),
MPP_MODE(29,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "pcie1", "clkreq"),
MPP_FUNCTION(0x2, "ge1", "rxclk"),
MPP_FUNCTION(0x3, "sd", "d3"),
MPP_FUNCTION(0x5, "spi0", "sck"),
MPP_FUNCTION(0x6, "pcie0", "rstoutn")),
MPP_MODE(30,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x2, "ge1", "txd0"),
MPP_FUNCTION(0x3, "spi1", "cs0"),
MPP_FUNCTION(0x5, "led", "p3"),
MPP_FUNCTION(0x6, "ptp", "eventreq")),
MPP_MODE(31,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x2, "ge1", "txd1"),
MPP_FUNCTION(0x3, "spi1", "mosi"),
MPP_FUNCTION(0x5, "led", "p0")),
MPP_MODE(32,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x2, "ge1", "txd2"),
MPP_FUNCTION(0x3, "spi1", "sck"),
MPP_FUNCTION(0x4, "ptp", "triggen"),
MPP_FUNCTION(0x5, "led", "c0")),
MPP_MODE(33,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x2, "ge1", "txd3"),
MPP_FUNCTION(0x3, "spi1", "miso"),
MPP_FUNCTION(0x5, "led", "p2")),
MPP_MODE(34,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x2, "ge1", "txclkout"),
MPP_FUNCTION(0x3, "spi1", "sck"),
MPP_FUNCTION(0x5, "led", "c1")),
MPP_MODE(35,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x2, "ge1", "rxctl"),
MPP_FUNCTION(0x3, "spi1", "cs1"),
MPP_FUNCTION(0x4, "spi0", "cs2"),
MPP_FUNCTION(0x5, "led", "p1")),
MPP_MODE(36,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "pcie0", "clkreq"),
MPP_FUNCTION(0x5, "led", "c2")),
MPP_MODE(37,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "pcie0", "clkreq"),
MPP_FUNCTION(0x2, "tdm", "intn"),
MPP_FUNCTION(0x4, "ge", "mdc")),
MPP_MODE(38,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "pcie1", "clkreq"),
MPP_FUNCTION(0x4, "ge", "mdio")),
MPP_MODE(39,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x4, "ref", "clkout"),
MPP_FUNCTION(0x5, "led", "p3")),
MPP_MODE(40,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x4, "uart1", "txd"),
MPP_FUNCTION(0x5, "led", "p0")),
MPP_MODE(41,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x4, "uart1", "rxd"),
MPP_FUNCTION(0x5, "led", "p1")),
MPP_MODE(42,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x3, "spi1", "cs2"),
MPP_FUNCTION(0x4, "led", "c0"),
MPP_FUNCTION(0x6, "ptp", "clk")),
MPP_MODE(43,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x2, "sata0", "prsnt"),
MPP_FUNCTION(0x4, "dram", "vttctrl"),
MPP_FUNCTION(0x5, "led", "c1")),
MPP_MODE(44,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x4, "sata0", "prsnt")),
MPP_MODE(45,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x2, "spi0", "cs2"),
MPP_FUNCTION(0x4, "pcie0", "rstoutn"),
MPP_FUNCTION(0x5, "led", "c2"),
MPP_FUNCTION(0x6, "spi1", "cs2")),
MPP_MODE(46,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "led", "p0"),
MPP_FUNCTION(0x2, "ge0", "txd0"),
MPP_FUNCTION(0x3, "ge1", "txd0"),
MPP_FUNCTION(0x6, "dev", "wen1")),
MPP_MODE(47,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "led", "p1"),
MPP_FUNCTION(0x2, "ge0", "txd1"),
MPP_FUNCTION(0x3, "ge1", "txd1"),
MPP_FUNCTION(0x5, "ptp", "triggen"),
MPP_FUNCTION(0x6, "dev", "ale0")),
MPP_MODE(48,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "led", "p2"),
MPP_FUNCTION(0x2, "ge0", "txd2"),
MPP_FUNCTION(0x3, "ge1", "txd2"),
MPP_FUNCTION(0x6, "dev", "ale1")),
MPP_MODE(49,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "led", "p3"),
MPP_FUNCTION(0x2, "ge0", "txd3"),
MPP_FUNCTION(0x3, "ge1", "txd3"),
MPP_FUNCTION(0x6, "dev", "a2")),
MPP_MODE(50,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "led", "c0"),
MPP_FUNCTION(0x2, "ge0", "rxd0"),
MPP_FUNCTION(0x3, "ge1", "rxd0"),
MPP_FUNCTION(0x5, "ptp", "eventreq"),
MPP_FUNCTION(0x6, "dev", "ad12")),
MPP_MODE(51,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "led", "c1"),
MPP_FUNCTION(0x2, "ge0", "rxd1"),
MPP_FUNCTION(0x3, "ge1", "rxd1"),
MPP_FUNCTION(0x6, "dev", "ad8")),
MPP_MODE(52,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "led", "c2"),
MPP_FUNCTION(0x2, "ge0", "rxd2"),
MPP_FUNCTION(0x3, "ge1", "rxd2"),
MPP_FUNCTION(0x5, "i2c0", "sda"),
MPP_FUNCTION(0x6, "dev", "ad9")),
MPP_MODE(53,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "pcie1", "rstoutn"),
MPP_FUNCTION(0x2, "ge0", "rxd3"),
MPP_FUNCTION(0x3, "ge1", "rxd3"),
MPP_FUNCTION(0x5, "i2c0", "sck"),
MPP_FUNCTION(0x6, "dev", "ad10")),
MPP_MODE(54,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "pcie0", "rstoutn"),
MPP_FUNCTION(0x2, "ge0", "rxctl"),
MPP_FUNCTION(0x3, "ge1", "rxctl"),
MPP_FUNCTION(0x6, "dev", "ad11")),
MPP_MODE(55,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x2, "ge0", "rxclk"),
MPP_FUNCTION(0x3, "ge1", "rxclk"),
MPP_FUNCTION(0x6, "dev", "cs0")),
MPP_MODE(56,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x2, "ge0", "txclkout"),
MPP_FUNCTION(0x3, "ge1", "txclkout"),
MPP_FUNCTION(0x6, "dev", "oe")),
MPP_MODE(57,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x2, "ge0", "txctl"),
MPP_FUNCTION(0x3, "ge1", "txctl"),
MPP_FUNCTION(0x6, "dev", "wen0")),
MPP_MODE(58,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x4, "led", "c0")),
MPP_MODE(59,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x4, "led", "c1")),
MPP_MODE(60,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x2, "uart1", "txd"),
MPP_FUNCTION(0x4, "led", "c2"),
MPP_FUNCTION(0x6, "dev", "ad13")),
MPP_MODE(61,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "i2c1", "sda"),
MPP_FUNCTION(0x2, "uart1", "rxd"),
MPP_FUNCTION(0x3, "spi1", "cs2"),
MPP_FUNCTION(0x4, "led", "p0"),
MPP_FUNCTION(0x6, "dev", "ad14")),
MPP_MODE(62,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "i2c1", "sck"),
MPP_FUNCTION(0x4, "led", "p1"),
MPP_FUNCTION(0x6, "dev", "ad15")),
MPP_MODE(63,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x2, "ptp", "triggen"),
MPP_FUNCTION(0x4, "led", "p2"),
MPP_FUNCTION(0x6, "dev", "burst")),
MPP_MODE(64,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x2, "dram", "vttctrl"),
MPP_FUNCTION(0x4, "led", "p3")),
MPP_MODE(65,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "sata1", "prsnt")),
MPP_MODE(66,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x2, "ptp", "eventreq"),
MPP_FUNCTION(0x4, "spi1", "cs3"),
MPP_FUNCTION(0x5, "pcie0", "rstoutn"),
MPP_FUNCTION(0x6, "dev", "cs3")),
};
static struct mvebu_pinctrl_soc_info armada_375_pinctrl_info;
static struct of_device_id armada_375_pinctrl_of_match[] = {
{ .compatible = "marvell,mv88f6720-pinctrl" },
{ },
};
static struct mvebu_mpp_ctrl mv88f6720_mpp_controls[] = {
MPP_FUNC_CTRL(0, 69, NULL, armada_375_mpp_ctrl),
};
static struct pinctrl_gpio_range mv88f6720_mpp_gpio_ranges[] = {
MPP_GPIO_RANGE(0, 0, 0, 32),
MPP_GPIO_RANGE(1, 32, 32, 32),
MPP_GPIO_RANGE(2, 64, 64, 3),
};
static int armada_375_pinctrl_probe(struct platform_device *pdev)
{
struct mvebu_pinctrl_soc_info *soc = &armada_375_pinctrl_info;
struct resource *res;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
mpp_base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(mpp_base))
return PTR_ERR(mpp_base);
soc->variant = 0; /* no variants for Armada 375 */
soc->controls = mv88f6720_mpp_controls;
soc->ncontrols = ARRAY_SIZE(mv88f6720_mpp_controls);
soc->modes = mv88f6720_mpp_modes;
soc->nmodes = ARRAY_SIZE(mv88f6720_mpp_modes);
soc->gpioranges = mv88f6720_mpp_gpio_ranges;
soc->ngpioranges = ARRAY_SIZE(mv88f6720_mpp_gpio_ranges);
pdev->dev.platform_data = soc;
return mvebu_pinctrl_probe(pdev);
}
static int armada_375_pinctrl_remove(struct platform_device *pdev)
{
return mvebu_pinctrl_remove(pdev);
}
static struct platform_driver armada_375_pinctrl_driver = {
.driver = {
.name = "armada-375-pinctrl",
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(armada_375_pinctrl_of_match),
},
.probe = armada_375_pinctrl_probe,
.remove = armada_375_pinctrl_remove,
};
module_platform_driver(armada_375_pinctrl_driver);
MODULE_AUTHOR("Thomas Petazzoni <[email protected]>");
MODULE_DESCRIPTION("Marvell Armada 375 pinctrl driver");
MODULE_LICENSE("GPL v2");

View file

@ -0,0 +1,462 @@
/*
* Marvell Armada 380/385 pinctrl driver based on mvebu pinctrl core
*
* Copyright (C) 2013 Marvell
*
* Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#include <linux/err.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/pinctrl/pinctrl.h>
#include "pinctrl-mvebu.h"
static void __iomem *mpp_base;
static int armada_38x_mpp_ctrl_get(unsigned pid, unsigned long *config)
{
return default_mpp_ctrl_get(mpp_base, pid, config);
}
static int armada_38x_mpp_ctrl_set(unsigned pid, unsigned long config)
{
return default_mpp_ctrl_set(mpp_base, pid, config);
}
enum {
V_88F6810 = BIT(0),
V_88F6820 = BIT(1),
V_88F6828 = BIT(2),
V_88F6810_PLUS = (V_88F6810 | V_88F6820 | V_88F6828),
V_88F6820_PLUS = (V_88F6820 | V_88F6828),
};
static struct mvebu_mpp_mode armada_38x_mpp_modes[] = {
MPP_MODE(0,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
MPP_VAR_FUNCTION(1, "ua0", "rxd", V_88F6810_PLUS)),
MPP_MODE(1,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
MPP_VAR_FUNCTION(1, "ua0", "txd", V_88F6810_PLUS)),
MPP_MODE(2,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
MPP_VAR_FUNCTION(1, "i2c0", "sck", V_88F6810_PLUS)),
MPP_MODE(3,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
MPP_VAR_FUNCTION(1, "i2c0", "sda", V_88F6810_PLUS)),
MPP_MODE(4,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
MPP_VAR_FUNCTION(1, "ge", "mdc", V_88F6810_PLUS),
MPP_VAR_FUNCTION(2, "ua1", "txd", V_88F6810_PLUS),
MPP_VAR_FUNCTION(3, "ua0", "rts", V_88F6810_PLUS)),
MPP_MODE(5,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
MPP_VAR_FUNCTION(1, "ge", "mdio", V_88F6810_PLUS),
MPP_VAR_FUNCTION(2, "ua1", "rxd", V_88F6810_PLUS),
MPP_VAR_FUNCTION(3, "ua0", "cts", V_88F6810_PLUS)),
MPP_MODE(6,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
MPP_VAR_FUNCTION(1, "ge0", "txclkout", V_88F6810_PLUS),
MPP_VAR_FUNCTION(2, "ge0", "crs", V_88F6810_PLUS),
MPP_VAR_FUNCTION(5, "dev", "cs3", V_88F6810_PLUS)),
MPP_MODE(7,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
MPP_VAR_FUNCTION(1, "ge0", "txd0", V_88F6810_PLUS),
MPP_VAR_FUNCTION(5, "dev", "ad9", V_88F6810_PLUS)),
MPP_MODE(8,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
MPP_VAR_FUNCTION(1, "ge0", "txd1", V_88F6810_PLUS),
MPP_VAR_FUNCTION(5, "dev", "ad10", V_88F6810_PLUS)),
MPP_MODE(9,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
MPP_VAR_FUNCTION(1, "ge0", "txd2", V_88F6810_PLUS),
MPP_VAR_FUNCTION(5, "dev", "ad11", V_88F6810_PLUS)),
MPP_MODE(10,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
MPP_VAR_FUNCTION(1, "ge0", "txd3", V_88F6810_PLUS),
MPP_VAR_FUNCTION(5, "dev", "ad12", V_88F6810_PLUS)),
MPP_MODE(11,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
MPP_VAR_FUNCTION(1, "ge0", "txctl", V_88F6810_PLUS),
MPP_VAR_FUNCTION(5, "dev", "ad13", V_88F6810_PLUS)),
MPP_MODE(12,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
MPP_VAR_FUNCTION(1, "ge0", "rxd0", V_88F6810_PLUS),
MPP_VAR_FUNCTION(2, "pcie0", "rstout", V_88F6810_PLUS),
MPP_VAR_FUNCTION(3, "pcie1", "rstout", V_88F6820_PLUS),
MPP_VAR_FUNCTION(4, "spi0", "cs1", V_88F6810_PLUS),
MPP_VAR_FUNCTION(5, "dev", "ad14", V_88F6810_PLUS)),
MPP_MODE(13,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
MPP_VAR_FUNCTION(1, "ge0", "rxd1", V_88F6810_PLUS),
MPP_VAR_FUNCTION(2, "pcie0", "clkreq", V_88F6810_PLUS),
MPP_VAR_FUNCTION(3, "pcie1", "clkreq", V_88F6820_PLUS),
MPP_VAR_FUNCTION(4, "spi0", "cs2", V_88F6810_PLUS),
MPP_VAR_FUNCTION(5, "dev", "ad15", V_88F6810_PLUS)),
MPP_MODE(14,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
MPP_VAR_FUNCTION(1, "ge0", "rxd2", V_88F6810_PLUS),
MPP_VAR_FUNCTION(2, "ptp", "clk", V_88F6810_PLUS),
MPP_VAR_FUNCTION(3, "m", "vtt_ctrl", V_88F6810_PLUS),
MPP_VAR_FUNCTION(4, "spi0", "cs3", V_88F6810_PLUS),
MPP_VAR_FUNCTION(5, "dev", "wen1", V_88F6810_PLUS)),
MPP_MODE(15,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
MPP_VAR_FUNCTION(1, "ge0", "rxd3", V_88F6810_PLUS),
MPP_VAR_FUNCTION(2, "ge", "mdc slave", V_88F6810_PLUS),
MPP_VAR_FUNCTION(3, "pcie0", "rstout", V_88F6810_PLUS),
MPP_VAR_FUNCTION(4, "spi0", "mosi", V_88F6810_PLUS),
MPP_VAR_FUNCTION(5, "pcie1", "rstout", V_88F6820_PLUS)),
MPP_MODE(16,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
MPP_VAR_FUNCTION(1, "ge0", "rxctl", V_88F6810_PLUS),
MPP_VAR_FUNCTION(2, "ge", "mdio slave", V_88F6810_PLUS),
MPP_VAR_FUNCTION(3, "m", "decc_err", V_88F6810_PLUS),
MPP_VAR_FUNCTION(4, "spi0", "miso", V_88F6810_PLUS),
MPP_VAR_FUNCTION(5, "pcie0", "clkreq", V_88F6810_PLUS)),
MPP_MODE(17,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
MPP_VAR_FUNCTION(1, "ge0", "rxclk", V_88F6810_PLUS),
MPP_VAR_FUNCTION(2, "ptp", "clk", V_88F6810_PLUS),
MPP_VAR_FUNCTION(3, "ua1", "rxd", V_88F6810_PLUS),
MPP_VAR_FUNCTION(4, "spi0", "sck", V_88F6810_PLUS),
MPP_VAR_FUNCTION(5, "sata1", "prsnt", V_88F6810_PLUS)),
MPP_MODE(18,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
MPP_VAR_FUNCTION(1, "ge0", "rxerr", V_88F6810_PLUS),
MPP_VAR_FUNCTION(2, "ptp", "trig_gen", V_88F6810_PLUS),
MPP_VAR_FUNCTION(3, "ua1", "txd", V_88F6810_PLUS),
MPP_VAR_FUNCTION(4, "spi0", "cs0", V_88F6810_PLUS),
MPP_VAR_FUNCTION(5, "pcie1", "rstout", V_88F6820_PLUS)),
MPP_MODE(19,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
MPP_VAR_FUNCTION(1, "ge0", "col", V_88F6810_PLUS),
MPP_VAR_FUNCTION(2, "ptp", "event_req", V_88F6810_PLUS),
MPP_VAR_FUNCTION(3, "pcie0", "clkreq", V_88F6810_PLUS),
MPP_VAR_FUNCTION(4, "sata1", "prsnt", V_88F6810_PLUS),
MPP_VAR_FUNCTION(5, "ua0", "cts", V_88F6810_PLUS)),
MPP_MODE(20,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
MPP_VAR_FUNCTION(1, "ge0", "txclk", V_88F6810_PLUS),
MPP_VAR_FUNCTION(2, "ptp", "clk", V_88F6810_PLUS),
MPP_VAR_FUNCTION(3, "pcie1", "rstout", V_88F6820_PLUS),
MPP_VAR_FUNCTION(4, "sata0", "prsnt", V_88F6810_PLUS),
MPP_VAR_FUNCTION(5, "ua0", "rts", V_88F6810_PLUS)),
MPP_MODE(21,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
MPP_VAR_FUNCTION(1, "spi0", "cs1", V_88F6810_PLUS),
MPP_VAR_FUNCTION(2, "ge1", "rxd0", V_88F6810_PLUS),
MPP_VAR_FUNCTION(3, "sata0", "prsnt", V_88F6810_PLUS),
MPP_VAR_FUNCTION(4, "sd0", "cmd", V_88F6810_PLUS),
MPP_VAR_FUNCTION(5, "dev", "bootcs", V_88F6810_PLUS)),
MPP_MODE(22,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
MPP_VAR_FUNCTION(1, "spi0", "mosi", V_88F6810_PLUS),
MPP_VAR_FUNCTION(5, "dev", "ad0", V_88F6810_PLUS)),
MPP_MODE(23,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
MPP_VAR_FUNCTION(1, "spi0", "sck", V_88F6810_PLUS),
MPP_VAR_FUNCTION(5, "dev", "ad2", V_88F6810_PLUS)),
MPP_MODE(24,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
MPP_VAR_FUNCTION(1, "spi0", "miso", V_88F6810_PLUS),
MPP_VAR_FUNCTION(2, "ua0", "cts", V_88F6810_PLUS),
MPP_VAR_FUNCTION(3, "ua1", "rxd", V_88F6810_PLUS),
MPP_VAR_FUNCTION(4, "sd0", "d4", V_88F6810_PLUS),
MPP_VAR_FUNCTION(5, "dev", "ready", V_88F6810_PLUS)),
MPP_MODE(25,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
MPP_VAR_FUNCTION(1, "spi0", "cs0", V_88F6810_PLUS),
MPP_VAR_FUNCTION(2, "ua0", "rts", V_88F6810_PLUS),
MPP_VAR_FUNCTION(3, "ua1", "txd", V_88F6810_PLUS),
MPP_VAR_FUNCTION(4, "sd0", "d5", V_88F6810_PLUS),
MPP_VAR_FUNCTION(5, "dev", "cs0", V_88F6810_PLUS)),
MPP_MODE(26,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
MPP_VAR_FUNCTION(1, "spi0", "cs2", V_88F6810_PLUS),
MPP_VAR_FUNCTION(3, "i2c1", "sck", V_88F6810_PLUS),
MPP_VAR_FUNCTION(4, "sd0", "d6", V_88F6810_PLUS),
MPP_VAR_FUNCTION(5, "dev", "cs1", V_88F6810_PLUS)),
MPP_MODE(27,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
MPP_VAR_FUNCTION(1, "spi0", "cs3", V_88F6810_PLUS),
MPP_VAR_FUNCTION(2, "ge1", "txclkout", V_88F6810_PLUS),
MPP_VAR_FUNCTION(3, "i2c1", "sda", V_88F6810_PLUS),
MPP_VAR_FUNCTION(4, "sd0", "d7", V_88F6810_PLUS),
MPP_VAR_FUNCTION(5, "dev", "cs2", V_88F6810_PLUS)),
MPP_MODE(28,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
MPP_VAR_FUNCTION(2, "ge1", "txd0", V_88F6810_PLUS),
MPP_VAR_FUNCTION(4, "sd0", "clk", V_88F6810_PLUS),
MPP_VAR_FUNCTION(5, "dev", "ad5", V_88F6810_PLUS)),
MPP_MODE(29,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
MPP_VAR_FUNCTION(2, "ge1", "txd1", V_88F6810_PLUS),
MPP_VAR_FUNCTION(5, "dev", "ale0", V_88F6810_PLUS)),
MPP_MODE(30,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
MPP_VAR_FUNCTION(2, "ge1", "txd2", V_88F6810_PLUS),
MPP_VAR_FUNCTION(5, "dev", "oen", V_88F6810_PLUS)),
MPP_MODE(31,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
MPP_VAR_FUNCTION(2, "ge1", "txd3", V_88F6810_PLUS),
MPP_VAR_FUNCTION(5, "dev", "ale1", V_88F6810_PLUS)),
MPP_MODE(32,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
MPP_VAR_FUNCTION(2, "ge1", "txctl", V_88F6810_PLUS),
MPP_VAR_FUNCTION(5, "dev", "wen0", V_88F6810_PLUS)),
MPP_MODE(33,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
MPP_VAR_FUNCTION(1, "m", "decc_err", V_88F6810_PLUS),
MPP_VAR_FUNCTION(5, "dev", "ad3", V_88F6810_PLUS)),
MPP_MODE(34,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
MPP_VAR_FUNCTION(5, "dev", "ad1", V_88F6810_PLUS)),
MPP_MODE(35,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
MPP_VAR_FUNCTION(1, "ref", "clk_out1", V_88F6810_PLUS),
MPP_VAR_FUNCTION(5, "dev", "a1", V_88F6810_PLUS)),
MPP_MODE(36,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
MPP_VAR_FUNCTION(1, "ptp", "trig_gen", V_88F6810_PLUS),
MPP_VAR_FUNCTION(5, "dev", "a0", V_88F6810_PLUS)),
MPP_MODE(37,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
MPP_VAR_FUNCTION(1, "ptp", "clk", V_88F6810_PLUS),
MPP_VAR_FUNCTION(2, "ge1", "rxclk", V_88F6810_PLUS),
MPP_VAR_FUNCTION(4, "sd0", "d3", V_88F6810_PLUS),
MPP_VAR_FUNCTION(5, "dev", "ad8", V_88F6810_PLUS)),
MPP_MODE(38,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
MPP_VAR_FUNCTION(1, "ptp", "event_req", V_88F6810_PLUS),
MPP_VAR_FUNCTION(2, "ge1", "rxd1", V_88F6810_PLUS),
MPP_VAR_FUNCTION(3, "ref", "clk_out0", V_88F6810_PLUS),
MPP_VAR_FUNCTION(4, "sd0", "d0", V_88F6810_PLUS),
MPP_VAR_FUNCTION(5, "dev", "ad4", V_88F6810_PLUS)),
MPP_MODE(39,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
MPP_VAR_FUNCTION(1, "i2c1", "sck", V_88F6810_PLUS),
MPP_VAR_FUNCTION(2, "ge1", "rxd2", V_88F6810_PLUS),
MPP_VAR_FUNCTION(3, "ua0", "cts", V_88F6810_PLUS),
MPP_VAR_FUNCTION(4, "sd0", "d1", V_88F6810_PLUS),
MPP_VAR_FUNCTION(5, "dev", "a2", V_88F6810_PLUS)),
MPP_MODE(40,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
MPP_VAR_FUNCTION(1, "i2c1", "sda", V_88F6810_PLUS),
MPP_VAR_FUNCTION(2, "ge1", "rxd3", V_88F6810_PLUS),
MPP_VAR_FUNCTION(3, "ua0", "rts", V_88F6810_PLUS),
MPP_VAR_FUNCTION(4, "sd0", "d2", V_88F6810_PLUS),
MPP_VAR_FUNCTION(5, "dev", "ad6", V_88F6810_PLUS)),
MPP_MODE(41,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
MPP_VAR_FUNCTION(1, "ua1", "rxd", V_88F6810_PLUS),
MPP_VAR_FUNCTION(2, "ge1", "rxctl", V_88F6810_PLUS),
MPP_VAR_FUNCTION(3, "ua0", "cts", V_88F6810_PLUS),
MPP_VAR_FUNCTION(4, "spi1", "cs3", V_88F6810_PLUS),
MPP_VAR_FUNCTION(5, "dev", "burst/last", V_88F6810_PLUS)),
MPP_MODE(42,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
MPP_VAR_FUNCTION(1, "ua1", "txd", V_88F6810_PLUS),
MPP_VAR_FUNCTION(3, "ua0", "rts", V_88F6810_PLUS),
MPP_VAR_FUNCTION(5, "dev", "ad7", V_88F6810_PLUS)),
MPP_MODE(43,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
MPP_VAR_FUNCTION(1, "pcie0", "clkreq", V_88F6810_PLUS),
MPP_VAR_FUNCTION(2, "m", "vtt_ctrl", V_88F6810_PLUS),
MPP_VAR_FUNCTION(3, "m", "decc_err", V_88F6810_PLUS),
MPP_VAR_FUNCTION(4, "pcie0", "rstout", V_88F6810_PLUS),
MPP_VAR_FUNCTION(5, "dev", "clkout", V_88F6810_PLUS)),
MPP_MODE(44,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
MPP_VAR_FUNCTION(1, "sata0", "prsnt", V_88F6810_PLUS),
MPP_VAR_FUNCTION(2, "sata1", "prsnt", V_88F6810_PLUS),
MPP_VAR_FUNCTION(3, "sata2", "prsnt", V_88F6828),
MPP_VAR_FUNCTION(4, "sata3", "prsnt", V_88F6828),
MPP_VAR_FUNCTION(5, "pcie0", "rstout", V_88F6810_PLUS)),
MPP_MODE(45,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
MPP_VAR_FUNCTION(1, "ref", "clk_out0", V_88F6810_PLUS),
MPP_VAR_FUNCTION(2, "pcie0", "rstout", V_88F6810_PLUS),
MPP_VAR_FUNCTION(3, "pcie1", "rstout", V_88F6820_PLUS),
MPP_VAR_FUNCTION(4, "pcie2", "rstout", V_88F6810_PLUS),
MPP_VAR_FUNCTION(5, "pcie3", "rstout", V_88F6810_PLUS)),
MPP_MODE(46,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
MPP_VAR_FUNCTION(1, "ref", "clk_out1", V_88F6810_PLUS),
MPP_VAR_FUNCTION(2, "pcie0", "rstout", V_88F6810_PLUS),
MPP_VAR_FUNCTION(3, "pcie1", "rstout", V_88F6820_PLUS),
MPP_VAR_FUNCTION(4, "pcie2", "rstout", V_88F6810_PLUS),
MPP_VAR_FUNCTION(5, "pcie3", "rstout", V_88F6810_PLUS)),
MPP_MODE(47,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
MPP_VAR_FUNCTION(1, "sata0", "prsnt", V_88F6810_PLUS),
MPP_VAR_FUNCTION(2, "sata1", "prsnt", V_88F6810_PLUS),
MPP_VAR_FUNCTION(3, "sata2", "prsnt", V_88F6828),
MPP_VAR_FUNCTION(4, "spi1", "cs2", V_88F6810_PLUS),
MPP_VAR_FUNCTION(5, "sata3", "prsnt", V_88F6828)),
MPP_MODE(48,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
MPP_VAR_FUNCTION(1, "sata0", "prsnt", V_88F6810_PLUS),
MPP_VAR_FUNCTION(2, "m", "vtt_ctrl", V_88F6810_PLUS),
MPP_VAR_FUNCTION(3, "tdm2c", "pclk", V_88F6810_PLUS),
MPP_VAR_FUNCTION(4, "audio", "mclk", V_88F6810_PLUS),
MPP_VAR_FUNCTION(5, "sd0", "d4", V_88F6810_PLUS)),
MPP_MODE(49,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
MPP_VAR_FUNCTION(1, "sata2", "prsnt", V_88F6828),
MPP_VAR_FUNCTION(2, "sata3", "prsnt", V_88F6828),
MPP_VAR_FUNCTION(3, "tdm2c", "fsync", V_88F6810_PLUS),
MPP_VAR_FUNCTION(4, "audio", "lrclk", V_88F6810_PLUS),
MPP_VAR_FUNCTION(5, "sd0", "d5", V_88F6810_PLUS)),
MPP_MODE(50,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
MPP_VAR_FUNCTION(1, "pcie0", "rstout", V_88F6810_PLUS),
MPP_VAR_FUNCTION(2, "pcie1", "rstout", V_88F6820_PLUS),
MPP_VAR_FUNCTION(3, "tdm2c", "drx", V_88F6810_PLUS),
MPP_VAR_FUNCTION(4, "audio", "extclk", V_88F6810_PLUS),
MPP_VAR_FUNCTION(5, "sd0", "cmd", V_88F6810_PLUS)),
MPP_MODE(51,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
MPP_VAR_FUNCTION(3, "tdm2c", "dtx", V_88F6810_PLUS),
MPP_VAR_FUNCTION(4, "audio", "sdo", V_88F6810_PLUS),
MPP_VAR_FUNCTION(5, "m", "decc_err", V_88F6810_PLUS)),
MPP_MODE(52,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
MPP_VAR_FUNCTION(1, "pcie0", "rstout", V_88F6810_PLUS),
MPP_VAR_FUNCTION(2, "pcie1", "rstout", V_88F6820_PLUS),
MPP_VAR_FUNCTION(3, "tdm2c", "intn", V_88F6810_PLUS),
MPP_VAR_FUNCTION(4, "audio", "sdi", V_88F6810_PLUS),
MPP_VAR_FUNCTION(5, "sd0", "d6", V_88F6810_PLUS)),
MPP_MODE(53,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
MPP_VAR_FUNCTION(1, "sata1", "prsnt", V_88F6810_PLUS),
MPP_VAR_FUNCTION(2, "sata0", "prsnt", V_88F6810_PLUS),
MPP_VAR_FUNCTION(3, "tdm2c", "rstn", V_88F6810_PLUS),
MPP_VAR_FUNCTION(4, "audio", "bclk", V_88F6810_PLUS),
MPP_VAR_FUNCTION(5, "sd0", "d7", V_88F6810_PLUS)),
MPP_MODE(54,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
MPP_VAR_FUNCTION(1, "sata0", "prsnt", V_88F6810_PLUS),
MPP_VAR_FUNCTION(2, "sata1", "prsnt", V_88F6810_PLUS),
MPP_VAR_FUNCTION(3, "pcie0", "rstout", V_88F6810_PLUS),
MPP_VAR_FUNCTION(4, "pcie1", "rstout", V_88F6820_PLUS),
MPP_VAR_FUNCTION(5, "sd0", "d3", V_88F6810_PLUS)),
MPP_MODE(55,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
MPP_VAR_FUNCTION(1, "ua1", "cts", V_88F6810_PLUS),
MPP_VAR_FUNCTION(2, "ge", "mdio", V_88F6810_PLUS),
MPP_VAR_FUNCTION(3, "pcie1", "clkreq", V_88F6820_PLUS),
MPP_VAR_FUNCTION(4, "spi1", "cs1", V_88F6810_PLUS),
MPP_VAR_FUNCTION(5, "sd0", "d0", V_88F6810_PLUS)),
MPP_MODE(56,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
MPP_VAR_FUNCTION(1, "ua1", "rts", V_88F6810_PLUS),
MPP_VAR_FUNCTION(2, "ge", "mdc", V_88F6810_PLUS),
MPP_VAR_FUNCTION(3, "m", "decc_err", V_88F6810_PLUS),
MPP_VAR_FUNCTION(4, "spi1", "mosi", V_88F6810_PLUS)),
MPP_MODE(57,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
MPP_VAR_FUNCTION(4, "spi1", "sck", V_88F6810_PLUS),
MPP_VAR_FUNCTION(5, "sd0", "clk", V_88F6810_PLUS)),
MPP_MODE(58,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
MPP_VAR_FUNCTION(1, "pcie1", "clkreq", V_88F6820_PLUS),
MPP_VAR_FUNCTION(2, "i2c1", "sck", V_88F6810_PLUS),
MPP_VAR_FUNCTION(3, "pcie2", "clkreq", V_88F6810_PLUS),
MPP_VAR_FUNCTION(4, "spi1", "miso", V_88F6810_PLUS),
MPP_VAR_FUNCTION(5, "sd0", "d1", V_88F6810_PLUS)),
MPP_MODE(59,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
MPP_VAR_FUNCTION(1, "pcie0", "rstout", V_88F6810_PLUS),
MPP_VAR_FUNCTION(2, "i2c1", "sda", V_88F6810_PLUS),
MPP_VAR_FUNCTION(3, "pcie1", "rstout", V_88F6820_PLUS),
MPP_VAR_FUNCTION(4, "spi1", "cs0", V_88F6810_PLUS),
MPP_VAR_FUNCTION(5, "sd0", "d2", V_88F6810_PLUS)),
};
static struct mvebu_pinctrl_soc_info armada_38x_pinctrl_info;
static struct of_device_id armada_38x_pinctrl_of_match[] = {
{
.compatible = "marvell,mv88f6810-pinctrl",
.data = (void *) V_88F6810,
},
{
.compatible = "marvell,mv88f6820-pinctrl",
.data = (void *) V_88F6820,
},
{
.compatible = "marvell,mv88f6828-pinctrl",
.data = (void *) V_88F6828,
},
{ },
};
static struct mvebu_mpp_ctrl armada_38x_mpp_controls[] = {
MPP_FUNC_CTRL(0, 59, NULL, armada_38x_mpp_ctrl),
};
static struct pinctrl_gpio_range armada_38x_mpp_gpio_ranges[] = {
MPP_GPIO_RANGE(0, 0, 0, 32),
MPP_GPIO_RANGE(1, 32, 32, 27),
};
static int armada_38x_pinctrl_probe(struct platform_device *pdev)
{
struct mvebu_pinctrl_soc_info *soc = &armada_38x_pinctrl_info;
const struct of_device_id *match =
of_match_device(armada_38x_pinctrl_of_match, &pdev->dev);
struct resource *res;
if (!match)
return -ENODEV;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
mpp_base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(mpp_base))
return PTR_ERR(mpp_base);
soc->variant = (unsigned) match->data & 0xff;
soc->controls = armada_38x_mpp_controls;
soc->ncontrols = ARRAY_SIZE(armada_38x_mpp_controls);
soc->gpioranges = armada_38x_mpp_gpio_ranges;
soc->ngpioranges = ARRAY_SIZE(armada_38x_mpp_gpio_ranges);
soc->modes = armada_38x_mpp_modes;
soc->nmodes = armada_38x_mpp_controls[0].npins;
pdev->dev.platform_data = soc;
return mvebu_pinctrl_probe(pdev);
}
static int armada_38x_pinctrl_remove(struct platform_device *pdev)
{
return mvebu_pinctrl_remove(pdev);
}
static struct platform_driver armada_38x_pinctrl_driver = {
.driver = {
.name = "armada-38x-pinctrl",
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(armada_38x_pinctrl_of_match),
},
.probe = armada_38x_pinctrl_probe,
.remove = armada_38x_pinctrl_remove,
};
module_platform_driver(armada_38x_pinctrl_driver);
MODULE_AUTHOR("Thomas Petazzoni <[email protected]>");
MODULE_DESCRIPTION("Marvell Armada 38x pinctrl driver");
MODULE_LICENSE("GPL v2");

View file

@ -33,6 +33,18 @@
#include "pinctrl-mvebu.h"
static void __iomem *mpp_base;
static int armada_xp_mpp_ctrl_get(unsigned pid, unsigned long *config)
{
return default_mpp_ctrl_get(mpp_base, pid, config);
}
static int armada_xp_mpp_ctrl_set(unsigned pid, unsigned long config)
{
return default_mpp_ctrl_set(mpp_base, pid, config);
}
enum armada_xp_variant {
V_MV78230 = BIT(0),
V_MV78260 = BIT(1),
@ -366,7 +378,7 @@ static struct of_device_id armada_xp_pinctrl_of_match[] = {
};
static struct mvebu_mpp_ctrl mv78230_mpp_controls[] = {
MPP_REG_CTRL(0, 48),
MPP_FUNC_CTRL(0, 48, NULL, armada_xp_mpp_ctrl),
};
static struct pinctrl_gpio_range mv78230_mpp_gpio_ranges[] = {
@ -375,7 +387,7 @@ static struct pinctrl_gpio_range mv78230_mpp_gpio_ranges[] = {
};
static struct mvebu_mpp_ctrl mv78260_mpp_controls[] = {
MPP_REG_CTRL(0, 66),
MPP_FUNC_CTRL(0, 66, NULL, armada_xp_mpp_ctrl),
};
static struct pinctrl_gpio_range mv78260_mpp_gpio_ranges[] = {
@ -385,7 +397,7 @@ static struct pinctrl_gpio_range mv78260_mpp_gpio_ranges[] = {
};
static struct mvebu_mpp_ctrl mv78460_mpp_controls[] = {
MPP_REG_CTRL(0, 66),
MPP_FUNC_CTRL(0, 66, NULL, armada_xp_mpp_ctrl),
};
static struct pinctrl_gpio_range mv78460_mpp_gpio_ranges[] = {
@ -399,10 +411,16 @@ static int armada_xp_pinctrl_probe(struct platform_device *pdev)
struct mvebu_pinctrl_soc_info *soc = &armada_xp_pinctrl_info;
const struct of_device_id *match =
of_match_device(armada_xp_pinctrl_of_match, &pdev->dev);
struct resource *res;
if (!match)
return -ENODEV;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
mpp_base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(mpp_base))
return PTR_ERR(mpp_base);
soc->variant = (unsigned) match->data & 0xff;
switch (soc->variant) {

View file

@ -18,107 +18,122 @@
#include <linux/clk.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/mfd/syscon.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/regmap.h>
#include "pinctrl-mvebu.h"
#define DOVE_SB_REGS_VIRT_BASE IOMEM(0xfde00000)
#define DOVE_MPP_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE + 0xd0200)
#define DOVE_PMU_MPP_GENERAL_CTRL (DOVE_MPP_VIRT_BASE + 0x10)
#define DOVE_AU0_AC97_SEL BIT(16)
#define DOVE_PMU_SIGNAL_SELECT_0 (DOVE_SB_REGS_VIRT_BASE + 0xd802C)
#define DOVE_PMU_SIGNAL_SELECT_1 (DOVE_SB_REGS_VIRT_BASE + 0xd8030)
#define DOVE_GLOBAL_CONFIG_1 (DOVE_SB_REGS_VIRT_BASE + 0xe802C)
#define DOVE_GLOBAL_CONFIG_1 (DOVE_SB_REGS_VIRT_BASE + 0xe802C)
#define DOVE_TWSI_ENABLE_OPTION1 BIT(7)
#define DOVE_GLOBAL_CONFIG_2 (DOVE_SB_REGS_VIRT_BASE + 0xe8030)
#define DOVE_TWSI_ENABLE_OPTION2 BIT(20)
#define DOVE_TWSI_ENABLE_OPTION3 BIT(21)
#define DOVE_TWSI_OPTION3_GPIO BIT(22)
#define DOVE_SSP_CTRL_STATUS_1 (DOVE_SB_REGS_VIRT_BASE + 0xe8034)
#define DOVE_SSP_ON_AU1 BIT(0)
#define DOVE_MPP_GENERAL_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE + 0xe803c)
#define DOVE_AU1_SPDIFO_GPIO_EN BIT(1)
#define DOVE_NAND_GPIO_EN BIT(0)
#define DOVE_GPIO_LO_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE + 0xd0400)
#define DOVE_MPP_CTRL4_VIRT_BASE (DOVE_GPIO_LO_VIRT_BASE + 0x40)
#define DOVE_SPI_GPIO_SEL BIT(5)
#define DOVE_UART1_GPIO_SEL BIT(4)
#define DOVE_AU1_GPIO_SEL BIT(3)
#define DOVE_CAM_GPIO_SEL BIT(2)
#define DOVE_SD1_GPIO_SEL BIT(1)
#define DOVE_SD0_GPIO_SEL BIT(0)
/* Internal registers can be configured at any 1 MiB aligned address */
#define INT_REGS_MASK ~(SZ_1M - 1)
#define MPP4_REGS_OFFS 0xd0440
#define PMU_REGS_OFFS 0xd802c
#define GC_REGS_OFFS 0xe802c
#define MPPS_PER_REG 8
#define MPP_BITS 4
#define MPP_MASK 0xf
/* MPP Base registers */
#define PMU_MPP_GENERAL_CTRL 0x10
#define AU0_AC97_SEL BIT(16)
/* MPP Control 4 register */
#define SPI_GPIO_SEL BIT(5)
#define UART1_GPIO_SEL BIT(4)
#define AU1_GPIO_SEL BIT(3)
#define CAM_GPIO_SEL BIT(2)
#define SD1_GPIO_SEL BIT(1)
#define SD0_GPIO_SEL BIT(0)
/* PMU Signal Select registers */
#define PMU_SIGNAL_SELECT_0 0x00
#define PMU_SIGNAL_SELECT_1 0x04
/* Global Config regmap registers */
#define GLOBAL_CONFIG_1 0x00
#define TWSI_ENABLE_OPTION1 BIT(7)
#define GLOBAL_CONFIG_2 0x04
#define TWSI_ENABLE_OPTION2 BIT(20)
#define TWSI_ENABLE_OPTION3 BIT(21)
#define TWSI_OPTION3_GPIO BIT(22)
#define SSP_CTRL_STATUS_1 0x08
#define SSP_ON_AU1 BIT(0)
#define MPP_GENERAL_CONFIG 0x10
#define AU1_SPDIFO_GPIO_EN BIT(1)
#define NAND_GPIO_EN BIT(0)
#define CONFIG_PMU BIT(4)
static int dove_pmu_mpp_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
unsigned long *config)
static void __iomem *mpp_base;
static void __iomem *mpp4_base;
static void __iomem *pmu_base;
static struct regmap *gconfmap;
static int dove_mpp_ctrl_get(unsigned pid, unsigned long *config)
{
unsigned off = (ctrl->pid / MPPS_PER_REG) * MPP_BITS;
unsigned shift = (ctrl->pid % MPPS_PER_REG) * MPP_BITS;
unsigned long pmu = readl(DOVE_PMU_MPP_GENERAL_CTRL);
return default_mpp_ctrl_get(mpp_base, pid, config);
}
static int dove_mpp_ctrl_set(unsigned pid, unsigned long config)
{
return default_mpp_ctrl_set(mpp_base, pid, config);
}
static int dove_pmu_mpp_ctrl_get(unsigned pid, unsigned long *config)
{
unsigned off = (pid / MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
unsigned shift = (pid % MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
unsigned long pmu = readl(mpp_base + PMU_MPP_GENERAL_CTRL);
unsigned long func;
if (pmu & (1 << ctrl->pid)) {
func = readl(DOVE_PMU_SIGNAL_SELECT_0 + off);
*config = (func >> shift) & MPP_MASK;
*config |= CONFIG_PMU;
} else {
func = readl(DOVE_MPP_VIRT_BASE + off);
*config = (func >> shift) & MPP_MASK;
}
if ((pmu & BIT(pid)) == 0)
return default_mpp_ctrl_get(mpp_base, pid, config);
func = readl(pmu_base + PMU_SIGNAL_SELECT_0 + off);
*config = (func >> shift) & MVEBU_MPP_MASK;
*config |= CONFIG_PMU;
return 0;
}
static int dove_pmu_mpp_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
unsigned long config)
static int dove_pmu_mpp_ctrl_set(unsigned pid, unsigned long config)
{
unsigned off = (ctrl->pid / MPPS_PER_REG) * MPP_BITS;
unsigned shift = (ctrl->pid % MPPS_PER_REG) * MPP_BITS;
unsigned long pmu = readl(DOVE_PMU_MPP_GENERAL_CTRL);
unsigned off = (pid / MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
unsigned shift = (pid % MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
unsigned long pmu = readl(mpp_base + PMU_MPP_GENERAL_CTRL);
unsigned long func;
if (config & CONFIG_PMU) {
writel(pmu | (1 << ctrl->pid), DOVE_PMU_MPP_GENERAL_CTRL);
func = readl(DOVE_PMU_SIGNAL_SELECT_0 + off);
func &= ~(MPP_MASK << shift);
func |= (config & MPP_MASK) << shift;
writel(func, DOVE_PMU_SIGNAL_SELECT_0 + off);
} else {
writel(pmu & ~(1 << ctrl->pid), DOVE_PMU_MPP_GENERAL_CTRL);
func = readl(DOVE_MPP_VIRT_BASE + off);
func &= ~(MPP_MASK << shift);
func |= (config & MPP_MASK) << shift;
writel(func, DOVE_MPP_VIRT_BASE + off);
if ((config & CONFIG_PMU) == 0) {
writel(pmu & ~BIT(pid), mpp_base + PMU_MPP_GENERAL_CTRL);
return default_mpp_ctrl_set(mpp_base, pid, config);
}
writel(pmu | BIT(pid), mpp_base + PMU_MPP_GENERAL_CTRL);
func = readl(pmu_base + PMU_SIGNAL_SELECT_0 + off);
func &= ~(MVEBU_MPP_MASK << shift);
func |= (config & MVEBU_MPP_MASK) << shift;
writel(func, pmu_base + PMU_SIGNAL_SELECT_0 + off);
return 0;
}
static int dove_mpp4_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
unsigned long *config)
static int dove_mpp4_ctrl_get(unsigned pid, unsigned long *config)
{
unsigned long mpp4 = readl(DOVE_MPP_CTRL4_VIRT_BASE);
unsigned long mpp4 = readl(mpp4_base);
unsigned long mask;
switch (ctrl->pid) {
switch (pid) {
case 24: /* mpp_camera */
mask = DOVE_CAM_GPIO_SEL;
mask = CAM_GPIO_SEL;
break;
case 40: /* mpp_sdio0 */
mask = DOVE_SD0_GPIO_SEL;
mask = SD0_GPIO_SEL;
break;
case 46: /* mpp_sdio1 */
mask = DOVE_SD1_GPIO_SEL;
mask = SD1_GPIO_SEL;
break;
case 58: /* mpp_spi0 */
mask = DOVE_SPI_GPIO_SEL;
mask = SPI_GPIO_SEL;
break;
case 62: /* mpp_uart1 */
mask = DOVE_UART1_GPIO_SEL;
mask = UART1_GPIO_SEL;
break;
default:
return -EINVAL;
@ -129,27 +144,26 @@ static int dove_mpp4_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
return 0;
}
static int dove_mpp4_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
unsigned long config)
static int dove_mpp4_ctrl_set(unsigned pid, unsigned long config)
{
unsigned long mpp4 = readl(DOVE_MPP_CTRL4_VIRT_BASE);
unsigned long mpp4 = readl(mpp4_base);
unsigned long mask;
switch (ctrl->pid) {
switch (pid) {
case 24: /* mpp_camera */
mask = DOVE_CAM_GPIO_SEL;
mask = CAM_GPIO_SEL;
break;
case 40: /* mpp_sdio0 */
mask = DOVE_SD0_GPIO_SEL;
mask = SD0_GPIO_SEL;
break;
case 46: /* mpp_sdio1 */
mask = DOVE_SD1_GPIO_SEL;
mask = SD1_GPIO_SEL;
break;
case 58: /* mpp_spi0 */
mask = DOVE_SPI_GPIO_SEL;
mask = SPI_GPIO_SEL;
break;
case 62: /* mpp_uart1 */
mask = DOVE_UART1_GPIO_SEL;
mask = UART1_GPIO_SEL;
break;
default:
return -EINVAL;
@ -159,74 +173,69 @@ static int dove_mpp4_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
if (config)
mpp4 |= mask;
writel(mpp4, DOVE_MPP_CTRL4_VIRT_BASE);
writel(mpp4, mpp4_base);
return 0;
}
static int dove_nand_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
unsigned long *config)
static int dove_nand_ctrl_get(unsigned pid, unsigned long *config)
{
unsigned long gmpp = readl(DOVE_MPP_GENERAL_VIRT_BASE);
unsigned int gmpp;
*config = ((gmpp & DOVE_NAND_GPIO_EN) != 0);
regmap_read(gconfmap, MPP_GENERAL_CONFIG, &gmpp);
*config = ((gmpp & NAND_GPIO_EN) != 0);
return 0;
}
static int dove_nand_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
unsigned long config)
static int dove_nand_ctrl_set(unsigned pid, unsigned long config)
{
unsigned long gmpp = readl(DOVE_MPP_GENERAL_VIRT_BASE);
regmap_update_bits(gconfmap, MPP_GENERAL_CONFIG,
NAND_GPIO_EN,
(config) ? NAND_GPIO_EN : 0);
return 0;
}
gmpp &= ~DOVE_NAND_GPIO_EN;
static int dove_audio0_ctrl_get(unsigned pid, unsigned long *config)
{
unsigned long pmu = readl(mpp_base + PMU_MPP_GENERAL_CTRL);
*config = ((pmu & AU0_AC97_SEL) != 0);
return 0;
}
static int dove_audio0_ctrl_set(unsigned pid, unsigned long config)
{
unsigned long pmu = readl(mpp_base + PMU_MPP_GENERAL_CTRL);
pmu &= ~AU0_AC97_SEL;
if (config)
gmpp |= DOVE_NAND_GPIO_EN;
writel(gmpp, DOVE_MPP_GENERAL_VIRT_BASE);
pmu |= AU0_AC97_SEL;
writel(pmu, mpp_base + PMU_MPP_GENERAL_CTRL);
return 0;
}
static int dove_audio0_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
unsigned long *config)
static int dove_audio1_ctrl_get(unsigned pid, unsigned long *config)
{
unsigned long pmu = readl(DOVE_PMU_MPP_GENERAL_CTRL);
unsigned int mpp4 = readl(mpp4_base);
unsigned int sspc1;
unsigned int gmpp;
unsigned int gcfg2;
*config = ((pmu & DOVE_AU0_AC97_SEL) != 0);
return 0;
}
static int dove_audio0_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
unsigned long config)
{
unsigned long pmu = readl(DOVE_PMU_MPP_GENERAL_CTRL);
pmu &= ~DOVE_AU0_AC97_SEL;
if (config)
pmu |= DOVE_AU0_AC97_SEL;
writel(pmu, DOVE_PMU_MPP_GENERAL_CTRL);
return 0;
}
static int dove_audio1_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
unsigned long *config)
{
unsigned long mpp4 = readl(DOVE_MPP_CTRL4_VIRT_BASE);
unsigned long sspc1 = readl(DOVE_SSP_CTRL_STATUS_1);
unsigned long gmpp = readl(DOVE_MPP_GENERAL_VIRT_BASE);
unsigned long gcfg2 = readl(DOVE_GLOBAL_CONFIG_2);
regmap_read(gconfmap, SSP_CTRL_STATUS_1, &sspc1);
regmap_read(gconfmap, MPP_GENERAL_CONFIG, &gmpp);
regmap_read(gconfmap, GLOBAL_CONFIG_2, &gcfg2);
*config = 0;
if (mpp4 & DOVE_AU1_GPIO_SEL)
if (mpp4 & AU1_GPIO_SEL)
*config |= BIT(3);
if (sspc1 & DOVE_SSP_ON_AU1)
if (sspc1 & SSP_ON_AU1)
*config |= BIT(2);
if (gmpp & DOVE_AU1_SPDIFO_GPIO_EN)
if (gmpp & AU1_SPDIFO_GPIO_EN)
*config |= BIT(1);
if (gcfg2 & DOVE_TWSI_OPTION3_GPIO)
if (gcfg2 & TWSI_OPTION3_GPIO)
*config |= BIT(0);
/* SSP/TWSI only if I2S1 not set*/
@ -238,35 +247,24 @@ static int dove_audio1_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
return 0;
}
static int dove_audio1_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
unsigned long config)
static int dove_audio1_ctrl_set(unsigned pid, unsigned long config)
{
unsigned long mpp4 = readl(DOVE_MPP_CTRL4_VIRT_BASE);
unsigned long sspc1 = readl(DOVE_SSP_CTRL_STATUS_1);
unsigned long gmpp = readl(DOVE_MPP_GENERAL_VIRT_BASE);
unsigned long gcfg2 = readl(DOVE_GLOBAL_CONFIG_2);
unsigned int mpp4 = readl(mpp4_base);
/*
* clear all audio1 related bits before configure
*/
gcfg2 &= ~DOVE_TWSI_OPTION3_GPIO;
gmpp &= ~DOVE_AU1_SPDIFO_GPIO_EN;
sspc1 &= ~DOVE_SSP_ON_AU1;
mpp4 &= ~DOVE_AU1_GPIO_SEL;
if (config & BIT(0))
gcfg2 |= DOVE_TWSI_OPTION3_GPIO;
if (config & BIT(1))
gmpp |= DOVE_AU1_SPDIFO_GPIO_EN;
if (config & BIT(2))
sspc1 |= DOVE_SSP_ON_AU1;
mpp4 &= ~AU1_GPIO_SEL;
if (config & BIT(3))
mpp4 |= DOVE_AU1_GPIO_SEL;
mpp4 |= AU1_GPIO_SEL;
writel(mpp4, mpp4_base);
writel(mpp4, DOVE_MPP_CTRL4_VIRT_BASE);
writel(sspc1, DOVE_SSP_CTRL_STATUS_1);
writel(gmpp, DOVE_MPP_GENERAL_VIRT_BASE);
writel(gcfg2, DOVE_GLOBAL_CONFIG_2);
regmap_update_bits(gconfmap, SSP_CTRL_STATUS_1,
SSP_ON_AU1,
(config & BIT(2)) ? SSP_ON_AU1 : 0);
regmap_update_bits(gconfmap, MPP_GENERAL_CONFIG,
AU1_SPDIFO_GPIO_EN,
(config & BIT(1)) ? AU1_SPDIFO_GPIO_EN : 0);
regmap_update_bits(gconfmap, GLOBAL_CONFIG_2,
TWSI_OPTION3_GPIO,
(config & BIT(0)) ? TWSI_OPTION3_GPIO : 0);
return 0;
}
@ -276,11 +274,11 @@ static int dove_audio1_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
* break other functions. If you require all mpps as gpio
* enforce gpio setting by pinctrl mapping.
*/
static int dove_audio1_ctrl_gpio_req(struct mvebu_mpp_ctrl *ctrl, u8 pid)
static int dove_audio1_ctrl_gpio_req(unsigned pid)
{
unsigned long config;
dove_audio1_ctrl_get(ctrl, &config);
dove_audio1_ctrl_get(pid, &config);
switch (config) {
case 0x02: /* i2s1 : gpio[56:57] */
@ -303,76 +301,62 @@ static int dove_audio1_ctrl_gpio_req(struct mvebu_mpp_ctrl *ctrl, u8 pid)
}
/* mpp[52:57] has gpio pins capable of in and out */
static int dove_audio1_ctrl_gpio_dir(struct mvebu_mpp_ctrl *ctrl, u8 pid,
bool input)
static int dove_audio1_ctrl_gpio_dir(unsigned pid, bool input)
{
if (pid < 52 || pid > 57)
return -ENOTSUPP;
return 0;
}
static int dove_twsi_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
unsigned long *config)
static int dove_twsi_ctrl_get(unsigned pid, unsigned long *config)
{
unsigned long gcfg1 = readl(DOVE_GLOBAL_CONFIG_1);
unsigned long gcfg2 = readl(DOVE_GLOBAL_CONFIG_2);
unsigned int gcfg1;
unsigned int gcfg2;
regmap_read(gconfmap, GLOBAL_CONFIG_1, &gcfg1);
regmap_read(gconfmap, GLOBAL_CONFIG_2, &gcfg2);
*config = 0;
if (gcfg1 & DOVE_TWSI_ENABLE_OPTION1)
if (gcfg1 & TWSI_ENABLE_OPTION1)
*config = 1;
else if (gcfg2 & DOVE_TWSI_ENABLE_OPTION2)
else if (gcfg2 & TWSI_ENABLE_OPTION2)
*config = 2;
else if (gcfg2 & DOVE_TWSI_ENABLE_OPTION3)
else if (gcfg2 & TWSI_ENABLE_OPTION3)
*config = 3;
return 0;
}
static int dove_twsi_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
unsigned long config)
static int dove_twsi_ctrl_set(unsigned pid, unsigned long config)
{
unsigned long gcfg1 = readl(DOVE_GLOBAL_CONFIG_1);
unsigned long gcfg2 = readl(DOVE_GLOBAL_CONFIG_2);
gcfg1 &= ~DOVE_TWSI_ENABLE_OPTION1;
gcfg2 &= ~(DOVE_TWSI_ENABLE_OPTION2 | DOVE_TWSI_ENABLE_OPTION3);
unsigned int gcfg1 = 0;
unsigned int gcfg2 = 0;
switch (config) {
case 1:
gcfg1 |= DOVE_TWSI_ENABLE_OPTION1;
gcfg1 = TWSI_ENABLE_OPTION1;
break;
case 2:
gcfg2 |= DOVE_TWSI_ENABLE_OPTION2;
gcfg2 = TWSI_ENABLE_OPTION2;
break;
case 3:
gcfg2 |= DOVE_TWSI_ENABLE_OPTION3;
gcfg2 = TWSI_ENABLE_OPTION3;
break;
}
writel(gcfg1, DOVE_GLOBAL_CONFIG_1);
writel(gcfg2, DOVE_GLOBAL_CONFIG_2);
regmap_update_bits(gconfmap, GLOBAL_CONFIG_1,
TWSI_ENABLE_OPTION1,
gcfg1);
regmap_update_bits(gconfmap, GLOBAL_CONFIG_2,
TWSI_ENABLE_OPTION2 | TWSI_ENABLE_OPTION3,
gcfg2);
return 0;
}
static struct mvebu_mpp_ctrl dove_mpp_controls[] = {
MPP_FUNC_CTRL(0, 0, "mpp0", dove_pmu_mpp_ctrl),
MPP_FUNC_CTRL(1, 1, "mpp1", dove_pmu_mpp_ctrl),
MPP_FUNC_CTRL(2, 2, "mpp2", dove_pmu_mpp_ctrl),
MPP_FUNC_CTRL(3, 3, "mpp3", dove_pmu_mpp_ctrl),
MPP_FUNC_CTRL(4, 4, "mpp4", dove_pmu_mpp_ctrl),
MPP_FUNC_CTRL(5, 5, "mpp5", dove_pmu_mpp_ctrl),
MPP_FUNC_CTRL(6, 6, "mpp6", dove_pmu_mpp_ctrl),
MPP_FUNC_CTRL(7, 7, "mpp7", dove_pmu_mpp_ctrl),
MPP_FUNC_CTRL(8, 8, "mpp8", dove_pmu_mpp_ctrl),
MPP_FUNC_CTRL(9, 9, "mpp9", dove_pmu_mpp_ctrl),
MPP_FUNC_CTRL(10, 10, "mpp10", dove_pmu_mpp_ctrl),
MPP_FUNC_CTRL(11, 11, "mpp11", dove_pmu_mpp_ctrl),
MPP_FUNC_CTRL(12, 12, "mpp12", dove_pmu_mpp_ctrl),
MPP_FUNC_CTRL(13, 13, "mpp13", dove_pmu_mpp_ctrl),
MPP_FUNC_CTRL(14, 14, "mpp14", dove_pmu_mpp_ctrl),
MPP_FUNC_CTRL(15, 15, "mpp15", dove_pmu_mpp_ctrl),
MPP_REG_CTRL(16, 23),
MPP_FUNC_CTRL(0, 15, NULL, dove_pmu_mpp_ctrl),
MPP_FUNC_CTRL(16, 23, NULL, dove_mpp_ctrl),
MPP_FUNC_CTRL(24, 39, "mpp_camera", dove_mpp4_ctrl),
MPP_FUNC_CTRL(40, 45, "mpp_sdio0", dove_mpp4_ctrl),
MPP_FUNC_CTRL(46, 51, "mpp_sdio1", dove_mpp4_ctrl),
@ -772,8 +756,17 @@ static struct of_device_id dove_pinctrl_of_match[] = {
{ }
};
static struct regmap_config gc_regmap_config = {
.reg_bits = 32,
.val_bits = 32,
.reg_stride = 4,
.max_register = 5,
};
static int dove_pinctrl_probe(struct platform_device *pdev)
{
struct resource *res, *mpp_res;
struct resource fb_res;
const struct of_device_id *match =
of_match_device(dove_pinctrl_of_match, &pdev->dev);
pdev->dev.platform_data = (void *)match->data;
@ -789,6 +782,59 @@ static int dove_pinctrl_probe(struct platform_device *pdev)
}
clk_prepare_enable(clk);
mpp_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
mpp_base = devm_ioremap_resource(&pdev->dev, mpp_res);
if (IS_ERR(mpp_base))
return PTR_ERR(mpp_base);
/* prepare fallback resource */
memcpy(&fb_res, mpp_res, sizeof(struct resource));
fb_res.start = 0;
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
if (!res) {
dev_warn(&pdev->dev, "falling back to hardcoded MPP4 resource\n");
adjust_resource(&fb_res,
(mpp_res->start & INT_REGS_MASK) + MPP4_REGS_OFFS, 0x4);
res = &fb_res;
}
mpp4_base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(mpp4_base))
return PTR_ERR(mpp4_base);
res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
if (!res) {
dev_warn(&pdev->dev, "falling back to hardcoded PMU resource\n");
adjust_resource(&fb_res,
(mpp_res->start & INT_REGS_MASK) + PMU_REGS_OFFS, 0x8);
res = &fb_res;
}
pmu_base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(pmu_base))
return PTR_ERR(pmu_base);
gconfmap = syscon_regmap_lookup_by_compatible("marvell,dove-global-config");
if (IS_ERR(gconfmap)) {
void __iomem *gc_base;
dev_warn(&pdev->dev, "falling back to hardcoded global registers\n");
adjust_resource(&fb_res,
(mpp_res->start & INT_REGS_MASK) + GC_REGS_OFFS, 0x14);
gc_base = devm_ioremap_resource(&pdev->dev, &fb_res);
if (IS_ERR(gc_base))
return PTR_ERR(gc_base);
gconfmap = devm_regmap_init_mmio(&pdev->dev,
gc_base, &gc_regmap_config);
if (IS_ERR(gconfmap))
return PTR_ERR(gconfmap);
}
/* Warn on any missing DT resource */
if (fb_res.start)
dev_warn(&pdev->dev, FW_BUG "Missing pinctrl regs in DTB. Please update your firmware.\n");
return mvebu_pinctrl_probe(pdev);
}

View file

@ -21,6 +21,18 @@
#include "pinctrl-mvebu.h"
static void __iomem *mpp_base;
static int kirkwood_mpp_ctrl_get(unsigned pid, unsigned long *config)
{
return default_mpp_ctrl_get(mpp_base, pid, config);
}
static int kirkwood_mpp_ctrl_set(unsigned pid, unsigned long config)
{
return default_mpp_ctrl_set(mpp_base, pid, config);
}
#define V(f6180, f6190, f6192, f6281, f6282, dx4122) \
((f6180 << 0) | (f6190 << 1) | (f6192 << 2) | \
(f6281 << 3) | (f6282 << 4) | (dx4122 << 5))
@ -359,7 +371,7 @@ static struct mvebu_mpp_mode mv88f6xxx_mpp_modes[] = {
};
static struct mvebu_mpp_ctrl mv88f6180_mpp_controls[] = {
MPP_REG_CTRL(0, 29),
MPP_FUNC_CTRL(0, 29, NULL, kirkwood_mpp_ctrl),
};
static struct pinctrl_gpio_range mv88f6180_gpio_ranges[] = {
@ -367,7 +379,7 @@ static struct pinctrl_gpio_range mv88f6180_gpio_ranges[] = {
};
static struct mvebu_mpp_ctrl mv88f619x_mpp_controls[] = {
MPP_REG_CTRL(0, 35),
MPP_FUNC_CTRL(0, 35, NULL, kirkwood_mpp_ctrl),
};
static struct pinctrl_gpio_range mv88f619x_gpio_ranges[] = {
@ -376,7 +388,7 @@ static struct pinctrl_gpio_range mv88f619x_gpio_ranges[] = {
};
static struct mvebu_mpp_ctrl mv88f628x_mpp_controls[] = {
MPP_REG_CTRL(0, 49),
MPP_FUNC_CTRL(0, 49, NULL, kirkwood_mpp_ctrl),
};
static struct pinctrl_gpio_range mv88f628x_gpio_ranges[] = {
@ -456,9 +468,16 @@ static struct of_device_id kirkwood_pinctrl_of_match[] = {
static int kirkwood_pinctrl_probe(struct platform_device *pdev)
{
struct resource *res;
const struct of_device_id *match =
of_match_device(kirkwood_pinctrl_of_match, &pdev->dev);
pdev->dev.platform_data = (void *)match->data;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
mpp_base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(mpp_base))
return PTR_ERR(mpp_base);
return mvebu_pinctrl_probe(pdev);
}

View file

@ -50,7 +50,6 @@ struct mvebu_pinctrl {
struct device *dev;
struct pinctrl_dev *pctldev;
struct pinctrl_desc desc;
void __iomem *base;
struct mvebu_pinctrl_group *groups;
unsigned num_groups;
struct mvebu_pinctrl_function *functions;
@ -138,43 +137,6 @@ static struct mvebu_pinctrl_function *mvebu_pinctrl_find_function_by_name(
return NULL;
}
/*
* Common mpp pin configuration registers on MVEBU are
* registers of eight 4-bit values for each mpp setting.
* Register offset and bit mask are calculated accordingly below.
*/
static int mvebu_common_mpp_get(struct mvebu_pinctrl *pctl,
struct mvebu_pinctrl_group *grp,
unsigned long *config)
{
unsigned pin = grp->gid;
unsigned off = (pin / MPPS_PER_REG) * MPP_BITS;
unsigned shift = (pin % MPPS_PER_REG) * MPP_BITS;
*config = readl(pctl->base + off);
*config >>= shift;
*config &= MPP_MASK;
return 0;
}
static int mvebu_common_mpp_set(struct mvebu_pinctrl *pctl,
struct mvebu_pinctrl_group *grp,
unsigned long config)
{
unsigned pin = grp->gid;
unsigned off = (pin / MPPS_PER_REG) * MPP_BITS;
unsigned shift = (pin % MPPS_PER_REG) * MPP_BITS;
unsigned long reg;
reg = readl(pctl->base + off);
reg &= ~(MPP_MASK << shift);
reg |= (config << shift);
writel(reg, pctl->base + off);
return 0;
}
static int mvebu_pinconf_group_get(struct pinctrl_dev *pctldev,
unsigned gid, unsigned long *config)
{
@ -184,10 +146,7 @@ static int mvebu_pinconf_group_get(struct pinctrl_dev *pctldev,
if (!grp->ctrl)
return -EINVAL;
if (grp->ctrl->mpp_get)
return grp->ctrl->mpp_get(grp->ctrl, config);
return mvebu_common_mpp_get(pctl, grp, config);
return grp->ctrl->mpp_get(grp->pins[0], config);
}
static int mvebu_pinconf_group_set(struct pinctrl_dev *pctldev,
@ -202,11 +161,7 @@ static int mvebu_pinconf_group_set(struct pinctrl_dev *pctldev,
return -EINVAL;
for (i = 0; i < num_configs; i++) {
if (grp->ctrl->mpp_set)
ret = grp->ctrl->mpp_set(grp->ctrl, configs[i]);
else
ret = mvebu_common_mpp_set(pctl, grp, configs[i]);
ret = grp->ctrl->mpp_set(grp->pins[0], configs[i]);
if (ret)
return ret;
} /* for each config */
@ -347,7 +302,7 @@ static int mvebu_pinmux_gpio_request_enable(struct pinctrl_dev *pctldev,
return -EINVAL;
if (grp->ctrl->mpp_gpio_req)
return grp->ctrl->mpp_gpio_req(grp->ctrl, offset);
return grp->ctrl->mpp_gpio_req(offset);
setting = mvebu_pinctrl_find_gpio_setting(pctl, grp);
if (!setting)
@ -370,7 +325,7 @@ static int mvebu_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev,
return -EINVAL;
if (grp->ctrl->mpp_gpio_dir)
return grp->ctrl->mpp_gpio_dir(grp->ctrl, offset, input);
return grp->ctrl->mpp_gpio_dir(offset, input);
setting = mvebu_pinctrl_find_gpio_setting(pctl, grp);
if (!setting)
@ -593,11 +548,12 @@ static int mvebu_pinctrl_build_functions(struct platform_device *pdev,
int mvebu_pinctrl_probe(struct platform_device *pdev)
{
struct mvebu_pinctrl_soc_info *soc = dev_get_platdata(&pdev->dev);
struct resource *res;
struct mvebu_pinctrl *pctl;
void __iomem *base;
struct pinctrl_pin_desc *pdesc;
unsigned gid, n, k;
unsigned size, noname = 0;
char *noname_buf;
void *p;
int ret;
if (!soc || !soc->controls || !soc->modes) {
@ -605,11 +561,6 @@ int mvebu_pinctrl_probe(struct platform_device *pdev)
return -EINVAL;
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(base))
return PTR_ERR(base);
pctl = devm_kzalloc(&pdev->dev, sizeof(struct mvebu_pinctrl),
GFP_KERNEL);
if (!pctl) {
@ -623,7 +574,6 @@ int mvebu_pinctrl_probe(struct platform_device *pdev)
pctl->desc.pmxops = &mvebu_pinmux_ops;
pctl->desc.confops = &mvebu_pinconf_ops;
pctl->variant = soc->variant;
pctl->base = base;
pctl->dev = &pdev->dev;
platform_set_drvdata(pdev, pctl);
@ -633,33 +583,23 @@ int mvebu_pinctrl_probe(struct platform_device *pdev)
pctl->desc.npins = 0;
for (n = 0; n < soc->ncontrols; n++) {
struct mvebu_mpp_ctrl *ctrl = &soc->controls[n];
char *names;
pctl->desc.npins += ctrl->npins;
/* initial control pins */
/* initialize control's pins[] array */
for (k = 0; k < ctrl->npins; k++)
ctrl->pins[k] = ctrl->pid + k;
/* special soc specific control */
if (ctrl->mpp_get || ctrl->mpp_set) {
if (!ctrl->name || !ctrl->mpp_get || !ctrl->mpp_set) {
dev_err(&pdev->dev, "wrong soc control info\n");
return -EINVAL;
}
/*
* We allow to pass controls with NULL name that we treat
* as a range of one-pin groups with generic mvebu register
* controls.
*/
if (!ctrl->name) {
pctl->num_groups += ctrl->npins;
noname += ctrl->npins;
} else {
pctl->num_groups += 1;
continue;
}
/* generic mvebu register control */
names = devm_kzalloc(&pdev->dev, ctrl->npins * 8, GFP_KERNEL);
if (!names) {
dev_err(&pdev->dev, "failed to alloc mpp names\n");
return -ENOMEM;
}
for (k = 0; k < ctrl->npins; k++)
sprintf(names + 8*k, "mpp%d", ctrl->pid+k);
ctrl->name = names;
pctl->num_groups += ctrl->npins;
}
pdesc = devm_kzalloc(&pdev->dev, pctl->desc.npins *
@ -673,12 +613,17 @@ int mvebu_pinctrl_probe(struct platform_device *pdev)
pdesc[n].number = n;
pctl->desc.pins = pdesc;
pctl->groups = devm_kzalloc(&pdev->dev, pctl->num_groups *
sizeof(struct mvebu_pinctrl_group), GFP_KERNEL);
if (!pctl->groups) {
dev_err(&pdev->dev, "failed to alloc pinctrl groups\n");
/*
* allocate groups and name buffers for unnamed groups.
*/
size = pctl->num_groups * sizeof(*pctl->groups) + noname * 8;
p = devm_kzalloc(&pdev->dev, size, GFP_KERNEL);
if (!p) {
dev_err(&pdev->dev, "failed to alloc group data\n");
return -ENOMEM;
}
pctl->groups = p;
noname_buf = p + pctl->num_groups * sizeof(*pctl->groups);
/* assign mpp controls to groups */
gid = 0;
@ -690,17 +635,26 @@ int mvebu_pinctrl_probe(struct platform_device *pdev)
pctl->groups[gid].pins = ctrl->pins;
pctl->groups[gid].npins = ctrl->npins;
/* generic mvebu register control maps to a number of groups */
if (!ctrl->mpp_get && !ctrl->mpp_set) {
/*
* We treat unnamed controls as a range of one-pin groups
* with generic mvebu register controls. Use one group for
* each in this range and assign a default group name.
*/
if (!ctrl->name) {
pctl->groups[gid].name = noname_buf;
pctl->groups[gid].npins = 1;
sprintf(noname_buf, "mpp%d", ctrl->pid+0);
noname_buf += 8;
for (k = 1; k < ctrl->npins; k++) {
gid++;
pctl->groups[gid].gid = gid;
pctl->groups[gid].ctrl = ctrl;
pctl->groups[gid].name = &ctrl->name[8*k];
pctl->groups[gid].name = noname_buf;
pctl->groups[gid].pins = &ctrl->pins[k];
pctl->groups[gid].npins = 1;
sprintf(noname_buf, "mpp%d", ctrl->pid+k);
noname_buf += 8;
}
}
gid++;

View file

@ -28,20 +28,19 @@
* between two or more different settings, e.g. assign mpp pin 13 to
* uart1 or sata.
*
* If optional mpp_get/_set functions are set these are used to get/set
* a specific mode. Otherwise it is assumed that the mpp control is based
* on 4-bit groups in subsequent registers. The optional mpp_gpio_req/_dir
* functions can be used to allow pin settings with varying gpio pins.
* The mpp_get/_set functions are mandatory and are used to get/set a
* specific mode. The optional mpp_gpio_req/_dir functions can be used
* to allow pin settings with varying gpio pins.
*/
struct mvebu_mpp_ctrl {
const char *name;
u8 pid;
u8 npins;
unsigned *pins;
int (*mpp_get)(struct mvebu_mpp_ctrl *ctrl, unsigned long *config);
int (*mpp_set)(struct mvebu_mpp_ctrl *ctrl, unsigned long config);
int (*mpp_gpio_req)(struct mvebu_mpp_ctrl *ctrl, u8 pid);
int (*mpp_gpio_dir)(struct mvebu_mpp_ctrl *ctrl, u8 pid, bool input);
int (*mpp_get)(unsigned pid, unsigned long *config);
int (*mpp_set)(unsigned pid, unsigned long config);
int (*mpp_gpio_req)(unsigned pid);
int (*mpp_gpio_dir)(unsigned pid, bool input);
};
/**
@ -114,18 +113,6 @@ struct mvebu_pinctrl_soc_info {
int ngpioranges;
};
#define MPP_REG_CTRL(_idl, _idh) \
{ \
.name = NULL, \
.pid = _idl, \
.npins = _idh - _idl + 1, \
.pins = (unsigned[_idh - _idl + 1]) { }, \
.mpp_get = NULL, \
.mpp_set = NULL, \
.mpp_gpio_req = NULL, \
.mpp_gpio_dir = NULL, \
}
#define MPP_FUNC_CTRL(_idl, _idh, _name, _func) \
{ \
.name = _name, \
@ -186,6 +173,34 @@ struct mvebu_pinctrl_soc_info {
.npins = _npins, \
}
#define MVEBU_MPPS_PER_REG 8
#define MVEBU_MPP_BITS 4
#define MVEBU_MPP_MASK 0xf
static inline int default_mpp_ctrl_get(void __iomem *base, unsigned int pid,
unsigned long *config)
{
unsigned off = (pid / MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
unsigned shift = (pid % MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
*config = (readl(base + off) >> shift) & MVEBU_MPP_MASK;
return 0;
}
static inline int default_mpp_ctrl_set(void __iomem *base, unsigned int pid,
unsigned long config)
{
unsigned off = (pid / MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
unsigned shift = (pid % MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
unsigned long reg;
reg = readl(base + off) & ~(MVEBU_MPP_MASK << shift);
writel(reg | (config << shift), base + off);
return 0;
}
int mvebu_pinctrl_probe(struct platform_device *pdev);
int mvebu_pinctrl_remove(struct platform_device *pdev);

View file

@ -309,39 +309,6 @@ static const unsigned keys_8x8_pins[] = {
GPIO_PE4, GPIO_PE5, GPIO_PE6, GPIO_PE7,
};
static const struct adi_pin_group adi_pin_groups[] = {
ADI_PIN_GROUP("uart0grp", uart0_pins),
ADI_PIN_GROUP("uart1grp", uart1_pins),
ADI_PIN_GROUP("uart1ctsrtsgrp", uart1_ctsrts_pins),
ADI_PIN_GROUP("uart2grp", uart2_pins),
ADI_PIN_GROUP("uart3grp", uart3_pins),
ADI_PIN_GROUP("uart3ctsrtsgrp", uart3_ctsrts_pins),
ADI_PIN_GROUP("rsi0grp", rsi0_pins),
ADI_PIN_GROUP("spi0grp", spi0_pins),
ADI_PIN_GROUP("spi1grp", spi1_pins),
ADI_PIN_GROUP("twi0grp", twi0_pins),
ADI_PIN_GROUP("twi1grp", twi1_pins),
ADI_PIN_GROUP("rotarygrp", rotary_pins),
ADI_PIN_GROUP("can0grp", can0_pins),
ADI_PIN_GROUP("can1grp", can1_pins),
ADI_PIN_GROUP("smc0grp", smc0_pins),
ADI_PIN_GROUP("sport0grp", sport0_pins),
ADI_PIN_GROUP("sport1grp", sport1_pins),
ADI_PIN_GROUP("sport2grp", sport2_pins),
ADI_PIN_GROUP("sport3grp", sport3_pins),
ADI_PIN_GROUP("ppi0_8bgrp", ppi0_8b_pins),
ADI_PIN_GROUP("ppi0_16bgrp", ppi0_16b_pins),
ADI_PIN_GROUP("ppi0_24bgrp", ppi0_24b_pins),
ADI_PIN_GROUP("ppi1_8bgrp", ppi1_8b_pins),
ADI_PIN_GROUP("ppi1_16bgrp", ppi1_16b_pins),
ADI_PIN_GROUP("ppi2_8bgrp", ppi2_8b_pins),
ADI_PIN_GROUP("atapigrp", atapi_pins),
ADI_PIN_GROUP("atapialtergrp", atapi_alter_pins),
ADI_PIN_GROUP("nfc0grp", nfc0_pins),
ADI_PIN_GROUP("keys_4x4grp", keys_4x4_pins),
ADI_PIN_GROUP("keys_8x8grp", keys_8x8_pins),
};
static const unsigned short uart0_mux[] = {
P_UART0_TX, P_UART0_RX,
0
@ -513,6 +480,39 @@ static const unsigned short keys_8x8_mux[] = {
0
};
static const struct adi_pin_group adi_pin_groups[] = {
ADI_PIN_GROUP("uart0grp", uart0_pins, uart0_mux),
ADI_PIN_GROUP("uart1grp", uart1_pins, uart1_mux),
ADI_PIN_GROUP("uart1ctsrtsgrp", uart1_ctsrts_pins, uart1_ctsrts_mux),
ADI_PIN_GROUP("uart2grp", uart2_pins, uart2_mux),
ADI_PIN_GROUP("uart3grp", uart3_pins, uart3_mux),
ADI_PIN_GROUP("uart3ctsrtsgrp", uart3_ctsrts_pins, uart3_ctsrts_mux),
ADI_PIN_GROUP("rsi0grp", rsi0_pins, rsi0_mux),
ADI_PIN_GROUP("spi0grp", spi0_pins, spi0_mux),
ADI_PIN_GROUP("spi1grp", spi1_pins, spi1_mux),
ADI_PIN_GROUP("twi0grp", twi0_pins, twi0_mux),
ADI_PIN_GROUP("twi1grp", twi1_pins, twi1_mux),
ADI_PIN_GROUP("rotarygrp", rotary_pins, rotary_mux),
ADI_PIN_GROUP("can0grp", can0_pins, can0_mux),
ADI_PIN_GROUP("can1grp", can1_pins, can1_mux),
ADI_PIN_GROUP("smc0grp", smc0_pins, smc0_mux),
ADI_PIN_GROUP("sport0grp", sport0_pins, sport0_mux),
ADI_PIN_GROUP("sport1grp", sport1_pins, sport1_mux),
ADI_PIN_GROUP("sport2grp", sport2_pins, sport2_mux),
ADI_PIN_GROUP("sport3grp", sport3_pins, sport3_mux),
ADI_PIN_GROUP("ppi0_8bgrp", ppi0_8b_pins, ppi0_8b_mux),
ADI_PIN_GROUP("ppi0_16bgrp", ppi0_16b_pins, ppi0_16b_mux),
ADI_PIN_GROUP("ppi0_24bgrp", ppi0_24b_pins, ppi0_24b_mux),
ADI_PIN_GROUP("ppi1_8bgrp", ppi1_8b_pins, ppi1_8b_mux),
ADI_PIN_GROUP("ppi1_16bgrp", ppi1_16b_pins, ppi1_16b_mux),
ADI_PIN_GROUP("ppi2_8bgrp", ppi2_8b_pins, ppi2_8b_mux),
ADI_PIN_GROUP("atapigrp", atapi_pins, atapi_mux),
ADI_PIN_GROUP("atapialtergrp", atapi_alter_pins, atapi_alter_mux),
ADI_PIN_GROUP("nfc0grp", nfc0_pins, nfc0_mux),
ADI_PIN_GROUP("keys_4x4grp", keys_4x4_pins, keys_4x4_mux),
ADI_PIN_GROUP("keys_8x8grp", keys_8x8_pins, keys_8x8_mux),
};
static const char * const uart0grp[] = { "uart0grp" };
static const char * const uart1grp[] = { "uart1grp" };
static const char * const uart1ctsrtsgrp[] = { "uart1ctsrtsgrp" };
@ -532,49 +532,45 @@ static const char * const sport0grp[] = { "sport0grp" };
static const char * const sport1grp[] = { "sport1grp" };
static const char * const sport2grp[] = { "sport2grp" };
static const char * const sport3grp[] = { "sport3grp" };
static const char * const ppi0_8bgrp[] = { "ppi0_8bgrp" };
static const char * const ppi0_16bgrp[] = { "ppi0_16bgrp" };
static const char * const ppi0_24bgrp[] = { "ppi0_24bgrp" };
static const char * const ppi1_8bgrp[] = { "ppi1_8bgrp" };
static const char * const ppi1_16bgrp[] = { "ppi1_16bgrp" };
static const char * const ppi2_8bgrp[] = { "ppi2_8bgrp" };
static const char * const ppi0grp[] = { "ppi0_8bgrp",
"ppi0_16bgrp",
"ppi0_24bgrp" };
static const char * const ppi1grp[] = { "ppi1_8bgrp",
"ppi1_16bgrp" };
static const char * const ppi2grp[] = { "ppi2_8bgrp" };
static const char * const atapigrp[] = { "atapigrp" };
static const char * const atapialtergrp[] = { "atapialtergrp" };
static const char * const nfc0grp[] = { "nfc0grp" };
static const char * const keys_4x4grp[] = { "keys_4x4grp" };
static const char * const keys_8x8grp[] = { "keys_8x8grp" };
static const char * const keysgrp[] = { "keys_4x4grp",
"keys_8x8grp" };
static const struct adi_pmx_func adi_pmx_functions[] = {
ADI_PMX_FUNCTION("uart0", uart0grp, uart0_mux),
ADI_PMX_FUNCTION("uart1", uart1grp, uart1_mux),
ADI_PMX_FUNCTION("uart1_ctsrts", uart1ctsrtsgrp, uart1_ctsrts_mux),
ADI_PMX_FUNCTION("uart2", uart2grp, uart2_mux),
ADI_PMX_FUNCTION("uart3", uart3grp, uart3_mux),
ADI_PMX_FUNCTION("uart3_ctsrts", uart3ctsrtsgrp, uart3_ctsrts_mux),
ADI_PMX_FUNCTION("rsi0", rsi0grp, rsi0_mux),
ADI_PMX_FUNCTION("spi0", spi0grp, spi0_mux),
ADI_PMX_FUNCTION("spi1", spi1grp, spi1_mux),
ADI_PMX_FUNCTION("twi0", twi0grp, twi0_mux),
ADI_PMX_FUNCTION("twi1", twi1grp, twi1_mux),
ADI_PMX_FUNCTION("rotary", rotarygrp, rotary_mux),
ADI_PMX_FUNCTION("can0", can0grp, can0_mux),
ADI_PMX_FUNCTION("can1", can1grp, can1_mux),
ADI_PMX_FUNCTION("smc0", smc0grp, smc0_mux),
ADI_PMX_FUNCTION("sport0", sport0grp, sport0_mux),
ADI_PMX_FUNCTION("sport1", sport1grp, sport1_mux),
ADI_PMX_FUNCTION("sport2", sport2grp, sport2_mux),
ADI_PMX_FUNCTION("sport3", sport3grp, sport3_mux),
ADI_PMX_FUNCTION("ppi0_8b", ppi0_8bgrp, ppi0_8b_mux),
ADI_PMX_FUNCTION("ppi0_16b", ppi0_16bgrp, ppi0_16b_mux),
ADI_PMX_FUNCTION("ppi0_24b", ppi0_24bgrp, ppi0_24b_mux),
ADI_PMX_FUNCTION("ppi1_8b", ppi1_8bgrp, ppi1_8b_mux),
ADI_PMX_FUNCTION("ppi1_16b", ppi1_16bgrp, ppi1_16b_mux),
ADI_PMX_FUNCTION("ppi2_8b", ppi2_8bgrp, ppi2_8b_mux),
ADI_PMX_FUNCTION("atapi", atapigrp, atapi_mux),
ADI_PMX_FUNCTION("atapi_alter", atapialtergrp, atapi_alter_mux),
ADI_PMX_FUNCTION("nfc0", nfc0grp, nfc0_mux),
ADI_PMX_FUNCTION("keys_4x4", keys_4x4grp, keys_4x4_mux),
ADI_PMX_FUNCTION("keys_8x8", keys_8x8grp, keys_8x8_mux),
ADI_PMX_FUNCTION("uart0", uart0grp),
ADI_PMX_FUNCTION("uart1", uart1grp),
ADI_PMX_FUNCTION("uart1_ctsrts", uart1ctsrtsgrp),
ADI_PMX_FUNCTION("uart2", uart2grp),
ADI_PMX_FUNCTION("uart3", uart3grp),
ADI_PMX_FUNCTION("uart3_ctsrts", uart3ctsrtsgrp),
ADI_PMX_FUNCTION("rsi0", rsi0grp),
ADI_PMX_FUNCTION("spi0", spi0grp),
ADI_PMX_FUNCTION("spi1", spi1grp),
ADI_PMX_FUNCTION("twi0", twi0grp),
ADI_PMX_FUNCTION("twi1", twi1grp),
ADI_PMX_FUNCTION("rotary", rotarygrp),
ADI_PMX_FUNCTION("can0", can0grp),
ADI_PMX_FUNCTION("can1", can1grp),
ADI_PMX_FUNCTION("smc0", smc0grp),
ADI_PMX_FUNCTION("sport0", sport0grp),
ADI_PMX_FUNCTION("sport1", sport1grp),
ADI_PMX_FUNCTION("sport2", sport2grp),
ADI_PMX_FUNCTION("sport3", sport3grp),
ADI_PMX_FUNCTION("ppi0", ppi0grp),
ADI_PMX_FUNCTION("ppi1", ppi1grp),
ADI_PMX_FUNCTION("ppi2", ppi2grp),
ADI_PMX_FUNCTION("atapi", atapigrp),
ADI_PMX_FUNCTION("atapi_alter", atapialtergrp),
ADI_PMX_FUNCTION("nfc0", nfc0grp),
ADI_PMX_FUNCTION("keys", keysgrp),
};
static const struct adi_pinctrl_soc_data adi_bf54x_soc = {

View file

@ -259,37 +259,6 @@ static const unsigned lp3_pins[] = {
GPIO_PF12, GPIO_PF13, GPIO_PF14, GPIO_PF15,
};
static const struct adi_pin_group adi_pin_groups[] = {
ADI_PIN_GROUP("uart0grp", uart0_pins),
ADI_PIN_GROUP("uart0ctsrtsgrp", uart0_ctsrts_pins),
ADI_PIN_GROUP("uart1grp", uart1_pins),
ADI_PIN_GROUP("uart1ctsrtsgrp", uart1_ctsrts_pins),
ADI_PIN_GROUP("rsi0grp", rsi0_pins),
ADI_PIN_GROUP("eth0grp", eth0_pins),
ADI_PIN_GROUP("eth1grp", eth1_pins),
ADI_PIN_GROUP("spi0grp", spi0_pins),
ADI_PIN_GROUP("spi1grp", spi1_pins),
ADI_PIN_GROUP("twi0grp", twi0_pins),
ADI_PIN_GROUP("twi1grp", twi1_pins),
ADI_PIN_GROUP("rotarygrp", rotary_pins),
ADI_PIN_GROUP("can0grp", can0_pins),
ADI_PIN_GROUP("smc0grp", smc0_pins),
ADI_PIN_GROUP("sport0grp", sport0_pins),
ADI_PIN_GROUP("sport1grp", sport1_pins),
ADI_PIN_GROUP("sport2grp", sport2_pins),
ADI_PIN_GROUP("ppi0_8bgrp", ppi0_8b_pins),
ADI_PIN_GROUP("ppi0_16bgrp", ppi0_16b_pins),
ADI_PIN_GROUP("ppi0_24bgrp", ppi0_24b_pins),
ADI_PIN_GROUP("ppi1_8bgrp", ppi1_8b_pins),
ADI_PIN_GROUP("ppi1_16bgrp", ppi1_16b_pins),
ADI_PIN_GROUP("ppi2_8bgrp", ppi2_8b_pins),
ADI_PIN_GROUP("ppi2_16bgrp", ppi2_16b_pins),
ADI_PIN_GROUP("lp0grp", lp0_pins),
ADI_PIN_GROUP("lp1grp", lp1_pins),
ADI_PIN_GROUP("lp2grp", lp2_pins),
ADI_PIN_GROUP("lp3grp", lp3_pins),
};
static const unsigned short uart0_mux[] = {
P_UART0_TX, P_UART0_RX,
0
@ -446,6 +415,37 @@ static const unsigned short lp3_mux[] = {
0
};
static const struct adi_pin_group adi_pin_groups[] = {
ADI_PIN_GROUP("uart0grp", uart0_pins, uart0_mux),
ADI_PIN_GROUP("uart0ctsrtsgrp", uart0_ctsrts_pins, uart0_ctsrts_mux),
ADI_PIN_GROUP("uart1grp", uart1_pins, uart1_mux),
ADI_PIN_GROUP("uart1ctsrtsgrp", uart1_ctsrts_pins, uart1_ctsrts_mux),
ADI_PIN_GROUP("rsi0grp", rsi0_pins, rsi0_mux),
ADI_PIN_GROUP("eth0grp", eth0_pins, eth0_mux),
ADI_PIN_GROUP("eth1grp", eth1_pins, eth1_mux),
ADI_PIN_GROUP("spi0grp", spi0_pins, spi0_mux),
ADI_PIN_GROUP("spi1grp", spi1_pins, spi1_mux),
ADI_PIN_GROUP("twi0grp", twi0_pins, twi0_mux),
ADI_PIN_GROUP("twi1grp", twi1_pins, twi1_mux),
ADI_PIN_GROUP("rotarygrp", rotary_pins, rotary_mux),
ADI_PIN_GROUP("can0grp", can0_pins, can0_mux),
ADI_PIN_GROUP("smc0grp", smc0_pins, smc0_mux),
ADI_PIN_GROUP("sport0grp", sport0_pins, sport0_mux),
ADI_PIN_GROUP("sport1grp", sport1_pins, sport1_mux),
ADI_PIN_GROUP("sport2grp", sport2_pins, sport2_mux),
ADI_PIN_GROUP("ppi0_8bgrp", ppi0_8b_pins, ppi0_8b_mux),
ADI_PIN_GROUP("ppi0_16bgrp", ppi0_16b_pins, ppi0_16b_mux),
ADI_PIN_GROUP("ppi0_24bgrp", ppi0_24b_pins, ppi0_24b_mux),
ADI_PIN_GROUP("ppi1_8bgrp", ppi1_8b_pins, ppi1_8b_mux),
ADI_PIN_GROUP("ppi1_16bgrp", ppi1_16b_pins, ppi1_16b_mux),
ADI_PIN_GROUP("ppi2_8bgrp", ppi2_8b_pins, ppi2_8b_mux),
ADI_PIN_GROUP("ppi2_16bgrp", ppi2_16b_pins, ppi2_16b_mux),
ADI_PIN_GROUP("lp0grp", lp0_pins, lp0_mux),
ADI_PIN_GROUP("lp1grp", lp1_pins, lp1_mux),
ADI_PIN_GROUP("lp2grp", lp2_pins, lp2_mux),
ADI_PIN_GROUP("lp3grp", lp3_pins, lp3_mux),
};
static const char * const uart0grp[] = { "uart0grp" };
static const char * const uart0ctsrtsgrp[] = { "uart0ctsrtsgrp" };
static const char * const uart1grp[] = { "uart1grp" };
@ -463,47 +463,43 @@ static const char * const smc0grp[] = { "smc0grp" };
static const char * const sport0grp[] = { "sport0grp" };
static const char * const sport1grp[] = { "sport1grp" };
static const char * const sport2grp[] = { "sport2grp" };
static const char * const ppi0_8bgrp[] = { "ppi0_8bgrp" };
static const char * const ppi0_16bgrp[] = { "ppi0_16bgrp" };
static const char * const ppi0_24bgrp[] = { "ppi0_24bgrp" };
static const char * const ppi1_8bgrp[] = { "ppi1_8bgrp" };
static const char * const ppi1_16bgrp[] = { "ppi1_16bgrp" };
static const char * const ppi2_8bgrp[] = { "ppi2_8bgrp" };
static const char * const ppi2_16bgrp[] = { "ppi2_16bgrp" };
static const char * const ppi0grp[] = { "ppi0_8bgrp",
"ppi0_16bgrp",
"ppi0_24bgrp" };
static const char * const ppi1grp[] = { "ppi1_8bgrp",
"ppi1_16bgrp" };
static const char * const ppi2grp[] = { "ppi2_8bgrp",
"ppi2_16bgrp" };
static const char * const lp0grp[] = { "lp0grp" };
static const char * const lp1grp[] = { "lp1grp" };
static const char * const lp2grp[] = { "lp2grp" };
static const char * const lp3grp[] = { "lp3grp" };
static const struct adi_pmx_func adi_pmx_functions[] = {
ADI_PMX_FUNCTION("uart0", uart0grp, uart0_mux),
ADI_PMX_FUNCTION("uart0_ctsrts", uart0ctsrtsgrp, uart0_ctsrts_mux),
ADI_PMX_FUNCTION("uart1", uart1grp, uart1_mux),
ADI_PMX_FUNCTION("uart1_ctsrts", uart1ctsrtsgrp, uart1_ctsrts_mux),
ADI_PMX_FUNCTION("rsi0", rsi0grp, rsi0_mux),
ADI_PMX_FUNCTION("eth0", eth0grp, eth0_mux),
ADI_PMX_FUNCTION("eth1", eth1grp, eth1_mux),
ADI_PMX_FUNCTION("spi0", spi0grp, spi0_mux),
ADI_PMX_FUNCTION("spi1", spi1grp, spi1_mux),
ADI_PMX_FUNCTION("twi0", twi0grp, twi0_mux),
ADI_PMX_FUNCTION("twi1", twi1grp, twi1_mux),
ADI_PMX_FUNCTION("rotary", rotarygrp, rotary_mux),
ADI_PMX_FUNCTION("can0", can0grp, can0_mux),
ADI_PMX_FUNCTION("smc0", smc0grp, smc0_mux),
ADI_PMX_FUNCTION("sport0", sport0grp, sport0_mux),
ADI_PMX_FUNCTION("sport1", sport1grp, sport1_mux),
ADI_PMX_FUNCTION("sport2", sport2grp, sport2_mux),
ADI_PMX_FUNCTION("ppi0_8b", ppi0_8bgrp, ppi0_8b_mux),
ADI_PMX_FUNCTION("ppi0_16b", ppi0_16bgrp, ppi0_16b_mux),
ADI_PMX_FUNCTION("ppi0_24b", ppi0_24bgrp, ppi0_24b_mux),
ADI_PMX_FUNCTION("ppi1_8b", ppi1_8bgrp, ppi1_8b_mux),
ADI_PMX_FUNCTION("ppi1_16b", ppi1_16bgrp, ppi1_16b_mux),
ADI_PMX_FUNCTION("ppi2_8b", ppi2_8bgrp, ppi2_8b_mux),
ADI_PMX_FUNCTION("ppi2_16b", ppi2_16bgrp, ppi2_16b_mux),
ADI_PMX_FUNCTION("lp0", lp0grp, lp0_mux),
ADI_PMX_FUNCTION("lp1", lp1grp, lp1_mux),
ADI_PMX_FUNCTION("lp2", lp2grp, lp2_mux),
ADI_PMX_FUNCTION("lp3", lp3grp, lp3_mux),
ADI_PMX_FUNCTION("uart0", uart0grp),
ADI_PMX_FUNCTION("uart0_ctsrts", uart0ctsrtsgrp),
ADI_PMX_FUNCTION("uart1", uart1grp),
ADI_PMX_FUNCTION("uart1_ctsrts", uart1ctsrtsgrp),
ADI_PMX_FUNCTION("rsi0", rsi0grp),
ADI_PMX_FUNCTION("eth0", eth0grp),
ADI_PMX_FUNCTION("eth1", eth1grp),
ADI_PMX_FUNCTION("spi0", spi0grp),
ADI_PMX_FUNCTION("spi1", spi1grp),
ADI_PMX_FUNCTION("twi0", twi0grp),
ADI_PMX_FUNCTION("twi1", twi1grp),
ADI_PMX_FUNCTION("rotary", rotarygrp),
ADI_PMX_FUNCTION("can0", can0grp),
ADI_PMX_FUNCTION("smc0", smc0grp),
ADI_PMX_FUNCTION("sport0", sport0grp),
ADI_PMX_FUNCTION("sport1", sport1grp),
ADI_PMX_FUNCTION("sport2", sport2grp),
ADI_PMX_FUNCTION("ppi0", ppi0grp),
ADI_PMX_FUNCTION("ppi1", ppi1grp),
ADI_PMX_FUNCTION("ppi2", ppi2grp),
ADI_PMX_FUNCTION("lp0", lp0grp),
ADI_PMX_FUNCTION("lp1", lp1grp),
ADI_PMX_FUNCTION("lp2", lp2grp),
ADI_PMX_FUNCTION("lp3", lp3grp),
};
static const struct adi_pinctrl_soc_data adi_bf60x_soc = {

View file

@ -89,6 +89,19 @@ struct gpio_port_saved {
u32 mux;
};
/*
* struct gpio_pint_saved - PINT registers saved in PM operations
*
* @assign: ASSIGN register
* @edge_set: EDGE_SET register
* @invert_set: INVERT_SET register
*/
struct gpio_pint_saved {
u32 assign;
u32 edge_set;
u32 invert_set;
};
/**
* struct gpio_pint - Pin interrupt controller device. Multiple ADI GPIO
* banks can be mapped into one Pin interrupt controller.
@ -114,7 +127,7 @@ struct gpio_pint {
int irq;
struct irq_domain *domain[2];
struct gpio_pint_regs *regs;
struct adi_pm_pint_save saved_data;
struct gpio_pint_saved saved_data;
int map_count;
spinlock_t lock;
@ -160,7 +173,7 @@ struct adi_pinctrl {
struct gpio_port {
struct list_head node;
void __iomem *base;
unsigned int irq_base;
int irq_base;
unsigned int width;
struct gpio_port_t *regs;
struct gpio_port_saved saved_data;
@ -605,8 +618,8 @@ static struct pinctrl_ops adi_pctrl_ops = {
.get_group_pins = adi_get_group_pins,
};
static int adi_pinmux_enable(struct pinctrl_dev *pctldev, unsigned selector,
unsigned group)
static int adi_pinmux_enable(struct pinctrl_dev *pctldev, unsigned func_id,
unsigned group_id)
{
struct adi_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctldev);
struct gpio_port *port;
@ -614,7 +627,7 @@ static int adi_pinmux_enable(struct pinctrl_dev *pctldev, unsigned selector,
unsigned long flags;
unsigned short *mux, pin;
mux = (unsigned short *)pinctrl->soc->functions[selector].mux;
mux = (unsigned short *)pinctrl->soc->groups[group_id].mux;
while (*mux) {
pin = P_IDENT(*mux);
@ -628,7 +641,7 @@ static int adi_pinmux_enable(struct pinctrl_dev *pctldev, unsigned selector,
spin_lock_irqsave(&port->lock, flags);
portmux_setup(port, pin_to_offset(range, pin),
P_FUNCT2MUX(*mux));
P_FUNCT2MUX(*mux));
port_setup(port, pin_to_offset(range, pin), false);
mux++;
@ -638,8 +651,8 @@ static int adi_pinmux_enable(struct pinctrl_dev *pctldev, unsigned selector,
return 0;
}
static void adi_pinmux_disable(struct pinctrl_dev *pctldev, unsigned selector,
unsigned group)
static void adi_pinmux_disable(struct pinctrl_dev *pctldev, unsigned func_id,
unsigned group_id)
{
struct adi_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctldev);
struct gpio_port *port;
@ -647,7 +660,7 @@ static void adi_pinmux_disable(struct pinctrl_dev *pctldev, unsigned selector,
unsigned long flags;
unsigned short *mux, pin;
mux = (unsigned short *)pinctrl->soc->functions[selector].mux;
mux = (unsigned short *)pinctrl->soc->groups[group_id].mux;
while (*mux) {
pin = P_IDENT(*mux);

View file

@ -21,13 +21,15 @@ struct adi_pin_group {
const char *name;
const unsigned *pins;
const unsigned num;
const unsigned short *mux;
};
#define ADI_PIN_GROUP(n, p) \
#define ADI_PIN_GROUP(n, p, m) \
{ \
.name = n, \
.pins = p, \
.num = ARRAY_SIZE(p), \
.mux = m, \
}
/**
@ -41,15 +43,13 @@ struct adi_pmx_func {
const char *name;
const char * const *groups;
const unsigned num_groups;
const unsigned short *mux;
};
#define ADI_PMX_FUNCTION(n, g, m) \
#define ADI_PMX_FUNCTION(n, g) \
{ \
.name = n, \
.groups = g, \
.num_groups = ARRAY_SIZE(g), \
.mux = m, \
}
/**

View file

@ -1137,6 +1137,17 @@ static void at91_gpio_free(struct gpio_chip *chip, unsigned offset)
pinctrl_free_gpio(gpio);
}
static int at91_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
{
struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip);
void __iomem *pio = at91_gpio->regbase;
unsigned mask = 1 << offset;
u32 osr;
osr = readl_relaxed(pio + PIO_OSR);
return !(osr & mask);
}
static int at91_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
{
struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip);
@ -1325,6 +1336,31 @@ static int alt_gpio_irq_type(struct irq_data *d, unsigned type)
return 0;
}
static unsigned int gpio_irq_startup(struct irq_data *d)
{
struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(d);
unsigned pin = d->hwirq;
int ret;
ret = gpio_lock_as_irq(&at91_gpio->chip, pin);
if (ret) {
dev_err(at91_gpio->chip.dev, "unable to lock pind %lu IRQ\n",
d->hwirq);
return ret;
}
gpio_irq_unmask(d);
return 0;
}
static void gpio_irq_shutdown(struct irq_data *d)
{
struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(d);
unsigned pin = d->hwirq;
gpio_irq_mask(d);
gpio_unlock_as_irq(&at91_gpio->chip, pin);
}
#ifdef CONFIG_PM
static u32 wakeups[MAX_GPIO_BANKS];
@ -1399,6 +1435,8 @@ void at91_pinctrl_gpio_resume(void)
static struct irq_chip gpio_irqchip = {
.name = "GPIO",
.irq_startup = gpio_irq_startup,
.irq_shutdown = gpio_irq_shutdown,
.irq_disable = gpio_irq_mask,
.irq_mask = gpio_irq_mask,
.irq_unmask = gpio_irq_unmask,
@ -1543,6 +1581,7 @@ static int at91_gpio_of_irq_setup(struct device_node *node,
static struct gpio_chip at91_gpio_template = {
.request = at91_gpio_request,
.free = at91_gpio_free,
.get_direction = at91_gpio_get_direction,
.direction_input = at91_gpio_direction_input,
.get = at91_gpio_get,
.direction_output = at91_gpio_direction_output,

View file

@ -60,6 +60,10 @@
#define BYT_NGPIO_NCORE 28
#define BYT_NGPIO_SUS 44
#define BYT_SCORE_ACPI_UID "1"
#define BYT_NCORE_ACPI_UID "2"
#define BYT_SUS_ACPI_UID "3"
/*
* Baytrail gpio controller consist of three separate sub-controllers called
* SCORE, NCORE and SUS. The sub-controllers are identified by their acpi UID.
@ -102,17 +106,17 @@ static unsigned const sus_pins[BYT_NGPIO_SUS] = {
static struct pinctrl_gpio_range byt_ranges[] = {
{
.name = "1", /* match with acpi _UID in probe */
.name = BYT_SCORE_ACPI_UID, /* match with acpi _UID in probe */
.npins = BYT_NGPIO_SCORE,
.pins = score_pins,
},
{
.name = "2",
.name = BYT_NCORE_ACPI_UID,
.npins = BYT_NGPIO_NCORE,
.pins = ncore_pins,
},
{
.name = "3",
.name = BYT_SUS_ACPI_UID,
.npins = BYT_NGPIO_SUS,
.pins = sus_pins,
},
@ -145,9 +149,41 @@ static void __iomem *byt_gpio_reg(struct gpio_chip *chip, unsigned offset,
return vg->reg_base + reg_offset + reg;
}
static bool is_special_pin(struct byt_gpio *vg, unsigned offset)
{
/* SCORE pin 92-93 */
if (!strcmp(vg->range->name, BYT_SCORE_ACPI_UID) &&
offset >= 92 && offset <= 93)
return true;
/* SUS pin 11-21 */
if (!strcmp(vg->range->name, BYT_SUS_ACPI_UID) &&
offset >= 11 && offset <= 21)
return true;
return false;
}
static int byt_gpio_request(struct gpio_chip *chip, unsigned offset)
{
struct byt_gpio *vg = to_byt_gpio(chip);
void __iomem *reg = byt_gpio_reg(chip, offset, BYT_CONF0_REG);
u32 value;
bool special;
/*
* In most cases, func pin mux 000 means GPIO function.
* But, some pins may have func pin mux 001 represents
* GPIO function. Only allow user to export pin with
* func pin mux preset as GPIO function by BIOS/FW.
*/
value = readl(reg) & BYT_PIN_MUX;
special = is_special_pin(vg, offset);
if ((special && value != 1) || (!special && value)) {
dev_err(&vg->pdev->dev,
"pin %u cannot be used as GPIO.\n", offset);
return -EINVAL;
}
pm_runtime_get(&vg->pdev->dev);

View file

@ -1042,6 +1042,88 @@ struct samsung_pin_ctrl exynos5250_pin_ctrl[] = {
},
};
/* pin banks of exynos5260 pin-controller 0 */
static struct samsung_pin_bank exynos5260_pin_banks0[] = {
EXYNOS_PIN_BANK_EINTG(4, 0x000, "gpa0", 0x00),
EXYNOS_PIN_BANK_EINTG(7, 0x020, "gpa1", 0x04),
EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpa2", 0x08),
EXYNOS_PIN_BANK_EINTG(5, 0x060, "gpb0", 0x0c),
EXYNOS_PIN_BANK_EINTG(4, 0x080, "gpb1", 0x10),
EXYNOS_PIN_BANK_EINTG(5, 0x0a0, "gpb2", 0x14),
EXYNOS_PIN_BANK_EINTG(8, 0x0c0, "gpb3", 0x18),
EXYNOS_PIN_BANK_EINTG(8, 0x0e0, "gpb4", 0x1c),
EXYNOS_PIN_BANK_EINTG(8, 0x100, "gpb5", 0x20),
EXYNOS_PIN_BANK_EINTG(8, 0x120, "gpd0", 0x24),
EXYNOS_PIN_BANK_EINTG(7, 0x140, "gpd1", 0x28),
EXYNOS_PIN_BANK_EINTG(5, 0x160, "gpd2", 0x2c),
EXYNOS_PIN_BANK_EINTG(8, 0x180, "gpe0", 0x30),
EXYNOS_PIN_BANK_EINTG(5, 0x1a0, "gpe1", 0x34),
EXYNOS_PIN_BANK_EINTG(4, 0x1c0, "gpf0", 0x38),
EXYNOS_PIN_BANK_EINTG(8, 0x1e0, "gpf1", 0x3c),
EXYNOS_PIN_BANK_EINTG(2, 0x200, "gpk0", 0x40),
EXYNOS_PIN_BANK_EINTW(8, 0xc00, "gpx0", 0x00),
EXYNOS_PIN_BANK_EINTW(8, 0xc20, "gpx1", 0x04),
EXYNOS_PIN_BANK_EINTW(8, 0xc40, "gpx2", 0x08),
EXYNOS_PIN_BANK_EINTW(8, 0xc60, "gpx3", 0x0c),
};
/* pin banks of exynos5260 pin-controller 1 */
static struct samsung_pin_bank exynos5260_pin_banks1[] = {
EXYNOS_PIN_BANK_EINTG(7, 0x000, "gpc0", 0x00),
EXYNOS_PIN_BANK_EINTG(6, 0x020, "gpc1", 0x04),
EXYNOS_PIN_BANK_EINTG(7, 0x040, "gpc2", 0x08),
EXYNOS_PIN_BANK_EINTG(4, 0x060, "gpc3", 0x0c),
EXYNOS_PIN_BANK_EINTG(4, 0x080, "gpc4", 0x10),
};
/* pin banks of exynos5260 pin-controller 2 */
static struct samsung_pin_bank exynos5260_pin_banks2[] = {
EXYNOS_PIN_BANK_EINTG(7, 0x000, "gpz0", 0x00),
EXYNOS_PIN_BANK_EINTG(4, 0x020, "gpz1", 0x04),
};
/*
* Samsung pinctrl driver data for Exynos5260 SoC. Exynos5260 SoC includes
* three gpio/pin-mux/pinconfig controllers.
*/
struct samsung_pin_ctrl exynos5260_pin_ctrl[] = {
{
/* pin-controller instance 0 data */
.pin_banks = exynos5260_pin_banks0,
.nr_banks = ARRAY_SIZE(exynos5260_pin_banks0),
.geint_con = EXYNOS_GPIO_ECON_OFFSET,
.geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
.geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
.weint_con = EXYNOS_WKUP_ECON_OFFSET,
.weint_mask = EXYNOS_WKUP_EMASK_OFFSET,
.weint_pend = EXYNOS_WKUP_EPEND_OFFSET,
.svc = EXYNOS_SVC_OFFSET,
.eint_gpio_init = exynos_eint_gpio_init,
.eint_wkup_init = exynos_eint_wkup_init,
.label = "exynos5260-gpio-ctrl0",
}, {
/* pin-controller instance 1 data */
.pin_banks = exynos5260_pin_banks1,
.nr_banks = ARRAY_SIZE(exynos5260_pin_banks1),
.geint_con = EXYNOS_GPIO_ECON_OFFSET,
.geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
.geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
.svc = EXYNOS_SVC_OFFSET,
.eint_gpio_init = exynos_eint_gpio_init,
.label = "exynos5260-gpio-ctrl1",
}, {
/* pin-controller instance 2 data */
.pin_banks = exynos5260_pin_banks2,
.nr_banks = ARRAY_SIZE(exynos5260_pin_banks2),
.geint_con = EXYNOS_GPIO_ECON_OFFSET,
.geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
.geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
.svc = EXYNOS_SVC_OFFSET,
.eint_gpio_init = exynos_eint_gpio_init,
.label = "exynos5260-gpio-ctrl2",
},
};
/* pin banks of exynos5420 pin-controller 0 */
static struct samsung_pin_bank exynos5420_pin_banks0[] = {
EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpy7", 0x00),

View file

@ -491,7 +491,7 @@ static int imx_pinctrl_parse_groups(struct device_node *np,
pin->mux_mode |= IOMUXC_CONFIG_SION;
pin->config = config & ~IMX_PAD_SION;
dev_dbg(info->dev, "%s: %d 0x%08lx", info->pins[i].name,
dev_dbg(info->dev, "%s: %d 0x%08lx", info->pins[pin_id].name,
pin->mux_mode, pin->config);
}

View file

@ -28,7 +28,6 @@
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/irqchip/chained_irq.h>
#include <linux/of_irq.h>
#include <linux/spinlock.h>
#include "core.h"
@ -50,7 +49,6 @@
* @enabled_irqs: Bitmap of currently enabled irqs.
* @dual_edge_irqs: Bitmap of irqs that need sw emulated dual edge
* detection.
* @wake_irqs: Bitmap of irqs with requested as wakeup source.
* @soc; Reference to soc_data of platform specific data.
* @regs: Base address for the TLMM register map.
*/
@ -65,7 +63,6 @@ struct msm_pinctrl {
DECLARE_BITMAP(dual_edge_irqs, MAX_NR_GPIO);
DECLARE_BITMAP(enabled_irqs, MAX_NR_GPIO);
DECLARE_BITMAP(wake_irqs, MAX_NR_GPIO);
const struct msm_pinctrl_soc_data *soc;
void __iomem *regs;
@ -203,42 +200,29 @@ static const struct pinmux_ops msm_pinmux_ops = {
static int msm_config_reg(struct msm_pinctrl *pctrl,
const struct msm_pingroup *g,
unsigned param,
s16 *reg,
unsigned *mask,
unsigned *bit)
{
switch (param) {
case PIN_CONFIG_BIAS_DISABLE:
*reg = g->ctl_reg;
*bit = g->pull_bit;
*mask = 3;
break;
case PIN_CONFIG_BIAS_PULL_DOWN:
*reg = g->ctl_reg;
*bit = g->pull_bit;
*mask = 3;
break;
case PIN_CONFIG_BIAS_PULL_UP:
*reg = g->ctl_reg;
*bit = g->pull_bit;
*mask = 3;
break;
case PIN_CONFIG_DRIVE_STRENGTH:
*reg = g->ctl_reg;
*bit = g->drv_bit;
*mask = 7;
break;
case PIN_CONFIG_OUTPUT:
*bit = g->oe_bit;
*mask = 1;
break;
default:
dev_err(pctrl->dev, "Invalid config param %04x\n", param);
return -ENOTSUPP;
}
if (*reg < 0) {
dev_err(pctrl->dev, "Config param %04x not supported on group %s\n",
param, g->name);
return -ENOTSUPP;
}
return 0;
}
@ -261,8 +245,10 @@ static int msm_config_set(struct pinctrl_dev *pctldev, unsigned int pin,
#define MSM_PULL_DOWN 1
#define MSM_PULL_UP 3
static const unsigned msm_regval_to_drive[] = { 2, 4, 6, 8, 10, 12, 14, 16 };
static const unsigned msm_drive_to_regval[] = { -1, -1, 0, -1, 1, -1, 2, -1, 3, -1, 4, -1, 5, -1, 6, -1, 7 };
static unsigned msm_regval_to_drive(u32 val)
{
return (val + 1) * 2;
}
static int msm_config_group_get(struct pinctrl_dev *pctldev,
unsigned int group,
@ -274,17 +260,16 @@ static int msm_config_group_get(struct pinctrl_dev *pctldev,
unsigned mask;
unsigned arg;
unsigned bit;
s16 reg;
int ret;
u32 val;
g = &pctrl->soc->groups[group];
ret = msm_config_reg(pctrl, g, param, &reg, &mask, &bit);
ret = msm_config_reg(pctrl, g, param, &mask, &bit);
if (ret < 0)
return ret;
val = readl(pctrl->regs + reg);
val = readl(pctrl->regs + g->ctl_reg);
arg = (val >> bit) & mask;
/* Convert register value to pinconf value */
@ -299,7 +284,15 @@ static int msm_config_group_get(struct pinctrl_dev *pctldev,
arg = arg == MSM_PULL_UP;
break;
case PIN_CONFIG_DRIVE_STRENGTH:
arg = msm_regval_to_drive[arg];
arg = msm_regval_to_drive(arg);
break;
case PIN_CONFIG_OUTPUT:
/* Pin is not output */
if (!arg)
return -EINVAL;
val = readl(pctrl->regs + g->io_reg);
arg = !!(val & BIT(g->in_bit));
break;
default:
dev_err(pctrl->dev, "Unsupported config parameter: %x\n",
@ -324,7 +317,6 @@ static int msm_config_group_set(struct pinctrl_dev *pctldev,
unsigned mask;
unsigned arg;
unsigned bit;
s16 reg;
int ret;
u32 val;
int i;
@ -335,7 +327,7 @@ static int msm_config_group_set(struct pinctrl_dev *pctldev,
param = pinconf_to_config_param(configs[i]);
arg = pinconf_to_config_argument(configs[i]);
ret = msm_config_reg(pctrl, g, param, &reg, &mask, &bit);
ret = msm_config_reg(pctrl, g, param, &mask, &bit);
if (ret < 0)
return ret;
@ -352,10 +344,24 @@ static int msm_config_group_set(struct pinctrl_dev *pctldev,
break;
case PIN_CONFIG_DRIVE_STRENGTH:
/* Check for invalid values */
if (arg >= ARRAY_SIZE(msm_drive_to_regval))
if (arg > 16 || arg < 2 || (arg % 2) != 0)
arg = -1;
else
arg = msm_drive_to_regval[arg];
arg = (arg / 2) - 1;
break;
case PIN_CONFIG_OUTPUT:
/* set output value */
spin_lock_irqsave(&pctrl->lock, flags);
val = readl(pctrl->regs + g->io_reg);
if (arg)
val |= BIT(g->out_bit);
else
val &= ~BIT(g->out_bit);
writel(val, pctrl->regs + g->io_reg);
spin_unlock_irqrestore(&pctrl->lock, flags);
/* enable output */
arg = 1;
break;
default:
dev_err(pctrl->dev, "Unsupported config parameter: %x\n",
@ -370,10 +376,10 @@ static int msm_config_group_set(struct pinctrl_dev *pctldev,
}
spin_lock_irqsave(&pctrl->lock, flags);
val = readl(pctrl->regs + reg);
val = readl(pctrl->regs + g->ctl_reg);
val &= ~(mask << bit);
val |= arg << bit;
writel(val, pctrl->regs + reg);
writel(val, pctrl->regs + g->ctl_reg);
spin_unlock_irqrestore(&pctrl->lock, flags);
}
@ -402,8 +408,6 @@ static int msm_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
u32 val;
g = &pctrl->soc->groups[offset];
if (WARN_ON(g->io_reg < 0))
return -EINVAL;
spin_lock_irqsave(&pctrl->lock, flags);
@ -424,8 +428,6 @@ static int msm_gpio_direction_output(struct gpio_chip *chip, unsigned offset, in
u32 val;
g = &pctrl->soc->groups[offset];
if (WARN_ON(g->io_reg < 0))
return -EINVAL;
spin_lock_irqsave(&pctrl->lock, flags);
@ -452,8 +454,6 @@ static int msm_gpio_get(struct gpio_chip *chip, unsigned offset)
u32 val;
g = &pctrl->soc->groups[offset];
if (WARN_ON(g->io_reg < 0))
return -EINVAL;
val = readl(pctrl->regs + g->io_reg);
return !!(val & BIT(g->in_bit));
@ -467,8 +467,6 @@ static void msm_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
u32 val;
g = &pctrl->soc->groups[offset];
if (WARN_ON(g->io_reg < 0))
return;
spin_lock_irqsave(&pctrl->lock, flags);
@ -534,7 +532,7 @@ static void msm_gpio_dbg_show_one(struct seq_file *s,
pull = (ctl_reg >> g->pull_bit) & 3;
seq_printf(s, " %-8s: %-3s %d", g->name, is_out ? "out" : "in", func);
seq_printf(s, " %dmA", msm_regval_to_drive[drive]);
seq_printf(s, " %dmA", msm_regval_to_drive(drive));
seq_printf(s, " %s", pulls[pull]);
}
@ -617,8 +615,6 @@ static void msm_gpio_irq_mask(struct irq_data *d)
pctrl = irq_data_get_irq_chip_data(d);
g = &pctrl->soc->groups[d->hwirq];
if (WARN_ON(g->intr_cfg_reg < 0))
return;
spin_lock_irqsave(&pctrl->lock, flags);
@ -640,8 +636,6 @@ static void msm_gpio_irq_unmask(struct irq_data *d)
pctrl = irq_data_get_irq_chip_data(d);
g = &pctrl->soc->groups[d->hwirq];
if (WARN_ON(g->intr_status_reg < 0))
return;
spin_lock_irqsave(&pctrl->lock, flags);
@ -667,8 +661,6 @@ static void msm_gpio_irq_ack(struct irq_data *d)
pctrl = irq_data_get_irq_chip_data(d);
g = &pctrl->soc->groups[d->hwirq];
if (WARN_ON(g->intr_status_reg < 0))
return;
spin_lock_irqsave(&pctrl->lock, flags);
@ -693,8 +685,6 @@ static int msm_gpio_irq_set_type(struct irq_data *d, unsigned int type)
pctrl = irq_data_get_irq_chip_data(d);
g = &pctrl->soc->groups[d->hwirq];
if (WARN_ON(g->intr_cfg_reg < 0))
return -EINVAL;
spin_lock_irqsave(&pctrl->lock, flags);
@ -783,22 +773,12 @@ static int msm_gpio_irq_set_wake(struct irq_data *d, unsigned int on)
{
struct msm_pinctrl *pctrl;
unsigned long flags;
unsigned ngpio;
pctrl = irq_data_get_irq_chip_data(d);
ngpio = pctrl->chip.ngpio;
spin_lock_irqsave(&pctrl->lock, flags);
if (on) {
if (bitmap_empty(pctrl->wake_irqs, ngpio))
enable_irq_wake(pctrl->irq);
set_bit(d->hwirq, pctrl->wake_irqs);
} else {
clear_bit(d->hwirq, pctrl->wake_irqs);
if (bitmap_empty(pctrl->wake_irqs, ngpio))
disable_irq_wake(pctrl->irq);
}
irq_set_irq_wake(pctrl->irq, on);
spin_unlock_irqrestore(&pctrl->lock, flags);
@ -869,6 +849,12 @@ static void msm_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
chained_irq_exit(chip, desc);
}
/*
* This lock class tells lockdep that GPIO irqs are in a different
* category than their parents, so it won't report false recursion.
*/
static struct lock_class_key gpio_lock_class;
static int msm_gpio_init(struct msm_pinctrl *pctrl)
{
struct gpio_chip *chip;
@ -876,10 +862,14 @@ static int msm_gpio_init(struct msm_pinctrl *pctrl)
int ret;
int i;
int r;
unsigned ngpio = pctrl->soc->ngpios;
if (WARN_ON(ngpio > MAX_NR_GPIO))
return -EINVAL;
chip = &pctrl->chip;
chip->base = 0;
chip->ngpio = pctrl->soc->ngpios;
chip->ngpio = ngpio;
chip->label = dev_name(pctrl->dev);
chip->dev = pctrl->dev;
chip->owner = THIS_MODULE;
@ -907,6 +897,7 @@ static int msm_gpio_init(struct msm_pinctrl *pctrl)
for (i = 0; i < chip->ngpio; i++) {
irq = irq_create_mapping(pctrl->domain, i);
irq_set_lockdep_class(irq, &gpio_lock_class);
irq_set_chip_and_handler(irq, &msm_gpio_irq_chip, handle_edge_irq);
irq_set_chip_data(irq, pctrl);
}

View file

@ -13,10 +13,7 @@
#ifndef __PINCTRL_MSM_H__
#define __PINCTRL_MSM_H__
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/machine.h>
struct pinctrl_pin_desc;
/**
* struct msm_function - a pinmux function

View file

@ -15,7 +15,6 @@
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#include "pinctrl-msm.h"
@ -406,6 +405,7 @@ enum msm8x74_functions {
MSM_MUX_blsp_i2c6,
MSM_MUX_blsp_i2c11,
MSM_MUX_blsp_spi1,
MSM_MUX_blsp_spi8,
MSM_MUX_blsp_uart2,
MSM_MUX_blsp_uart8,
MSM_MUX_slimbus,
@ -416,6 +416,9 @@ static const char * const blsp_i2c2_groups[] = { "gpio6", "gpio7" };
static const char * const blsp_i2c6_groups[] = { "gpio29", "gpio30" };
static const char * const blsp_i2c11_groups[] = { "gpio83", "gpio84" };
static const char * const blsp_spi1_groups[] = { "gpio0", "gpio1", "gpio2", "gpio3" };
static const char * const blsp_spi8_groups[] = {
"gpio45", "gpio46", "gpio47", "gpio48"
};
static const char * const blsp_uart2_groups[] = { "gpio4", "gpio5" };
static const char * const blsp_uart8_groups[] = { "gpio45", "gpio46" };
static const char * const slimbus_groups[] = { "gpio70", "gpio71" };
@ -425,6 +428,7 @@ static const struct msm_function msm8x74_functions[] = {
FUNCTION(blsp_i2c6),
FUNCTION(blsp_i2c11),
FUNCTION(blsp_spi1),
FUNCTION(blsp_spi8),
FUNCTION(blsp_uart2),
FUNCTION(blsp_uart8),
FUNCTION(slimbus),
@ -476,10 +480,10 @@ static const struct msm_pingroup msm8x74_groups[] = {
PINGROUP(42, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(43, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(44, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(45, NA, blsp_uart8, NA, NA, NA, NA, NA),
PINGROUP(46, NA, blsp_uart8, NA, NA, NA, NA, NA),
PINGROUP(47, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(48, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(45, blsp_spi8, blsp_uart8, NA, NA, NA, NA, NA),
PINGROUP(46, blsp_spi8, blsp_uart8, NA, NA, NA, NA, NA),
PINGROUP(47, blsp_spi8, NA, NA, NA, NA, NA, NA),
PINGROUP(48, blsp_spi8, NA, NA, NA, NA, NA, NA),
PINGROUP(49, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(50, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(51, NA, NA, NA, NA, NA, NA, NA),

View file

@ -2035,27 +2035,29 @@ static const struct of_device_id nmk_pinctrl_match[] = {
{},
};
static int nmk_pinctrl_suspend(struct platform_device *pdev, pm_message_t state)
#ifdef CONFIG_PM_SLEEP
static int nmk_pinctrl_suspend(struct device *dev)
{
struct nmk_pinctrl *npct;
npct = platform_get_drvdata(pdev);
npct = dev_get_drvdata(dev);
if (!npct)
return -EINVAL;
return pinctrl_force_sleep(npct->pctl);
}
static int nmk_pinctrl_resume(struct platform_device *pdev)
static int nmk_pinctrl_resume(struct device *dev)
{
struct nmk_pinctrl *npct;
npct = platform_get_drvdata(pdev);
npct = dev_get_drvdata(dev);
if (!npct)
return -EINVAL;
return pinctrl_force_default(npct->pctl);
}
#endif
static int nmk_pinctrl_probe(struct platform_device *pdev)
{
@ -2144,17 +2146,18 @@ static struct platform_driver nmk_gpio_driver = {
.probe = nmk_gpio_probe,
};
static SIMPLE_DEV_PM_OPS(nmk_pinctrl_pm_ops,
nmk_pinctrl_suspend,
nmk_pinctrl_resume);
static struct platform_driver nmk_pinctrl_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "pinctrl-nomadik",
.of_match_table = nmk_pinctrl_match,
.pm = &nmk_pinctrl_pm_ops,
},
.probe = nmk_pinctrl_probe,
#ifdef CONFIG_PM
.suspend = nmk_pinctrl_suspend,
.resume = nmk_pinctrl_resume,
#endif
};
static int __init nmk_gpio_init(void)

View file

@ -1120,6 +1120,8 @@ static const struct of_device_id samsung_pinctrl_dt_match[] = {
.data = (void *)exynos4x12_pin_ctrl },
{ .compatible = "samsung,exynos5250-pinctrl",
.data = (void *)exynos5250_pin_ctrl },
{ .compatible = "samsung,exynos5260-pinctrl",
.data = (void *)exynos5260_pin_ctrl },
{ .compatible = "samsung,exynos5420-pinctrl",
.data = (void *)exynos5420_pin_ctrl },
{ .compatible = "samsung,s5pv210-pinctrl",

View file

@ -254,6 +254,7 @@ struct samsung_pmx_func {
extern struct samsung_pin_ctrl exynos4210_pin_ctrl[];
extern struct samsung_pin_ctrl exynos4x12_pin_ctrl[];
extern struct samsung_pin_ctrl exynos5250_pin_ctrl[];
extern struct samsung_pin_ctrl exynos5260_pin_ctrl[];
extern struct samsung_pin_ctrl exynos5420_pin_ctrl[];
extern struct samsung_pin_ctrl s3c64xx_pin_ctrl[];
extern struct samsung_pin_ctrl s3c2412_pin_ctrl[];

View file

@ -662,6 +662,7 @@ static int pcs_pinconf_get(struct pinctrl_dev *pctldev,
break;
case PIN_CONFIG_DRIVE_STRENGTH:
case PIN_CONFIG_SLEW_RATE:
case PIN_CONFIG_LOW_POWER_MODE:
default:
*config = data;
break;
@ -699,6 +700,7 @@ static int pcs_pinconf_set(struct pinctrl_dev *pctldev,
case PIN_CONFIG_INPUT_SCHMITT:
case PIN_CONFIG_DRIVE_STRENGTH:
case PIN_CONFIG_SLEW_RATE:
case PIN_CONFIG_LOW_POWER_MODE:
shift = ffs(func->conf[i].mask) - 1;
data &= ~func->conf[i].mask;
data |= (arg << shift) & func->conf[i].mask;
@ -1101,6 +1103,7 @@ static int pcs_parse_pinconf(struct pcs_device *pcs, struct device_node *np,
{ "pinctrl-single,drive-strength", PIN_CONFIG_DRIVE_STRENGTH, },
{ "pinctrl-single,slew-rate", PIN_CONFIG_SLEW_RATE, },
{ "pinctrl-single,input-schmitt", PIN_CONFIG_INPUT_SCHMITT, },
{ "pinctrl-single,low-power-mode", PIN_CONFIG_LOW_POWER_MODE, },
};
struct pcs_conf_type prop4[] = {
{ "pinctrl-single,bias-pullup", PIN_CONFIG_BIAS_PULL_UP, },

View file

@ -13,7 +13,12 @@
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/irqdesc.h>
#include <linux/irqdomain.h>
#include <linux/irqchip/chained_irq.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/of_gpio.h>
#include <linux/of_address.h>
#include <linux/regmap.h>
@ -266,11 +271,59 @@ struct st_pctl_group {
struct st_pinconf *pin_conf;
};
/*
* Edge triggers are not supported at hardware level, it is supported by
* software by exploiting the level trigger support in hardware.
* Software uses a virtual register (EDGE_CONF) for edge trigger configuration
* of each gpio pin in a GPIO bank.
*
* Each bank has a 32 bit EDGE_CONF register which is divided in to 8 parts of
* 4-bits. Each 4-bit space is allocated for each pin in a gpio bank.
*
* bit allocation per pin is:
* Bits: [0 - 3] | [4 - 7] [8 - 11] ... ... ... ... [ 28 - 31]
* --------------------------------------------------------
* | pin-0 | pin-2 | pin-3 | ... ... ... ... | pin -7 |
* --------------------------------------------------------
*
* A pin can have one of following the values in its edge configuration field.
*
* ------- ----------------------------
* [0-3] - Description
* ------- ----------------------------
* 0000 - No edge IRQ.
* 0001 - Falling edge IRQ.
* 0010 - Rising edge IRQ.
* 0011 - Rising and Falling edge IRQ.
* ------- ----------------------------
*/
#define ST_IRQ_EDGE_CONF_BITS_PER_PIN 4
#define ST_IRQ_EDGE_MASK 0xf
#define ST_IRQ_EDGE_FALLING BIT(0)
#define ST_IRQ_EDGE_RISING BIT(1)
#define ST_IRQ_EDGE_BOTH (BIT(0) | BIT(1))
#define ST_IRQ_RISING_EDGE_CONF(pin) \
(ST_IRQ_EDGE_RISING << (pin * ST_IRQ_EDGE_CONF_BITS_PER_PIN))
#define ST_IRQ_FALLING_EDGE_CONF(pin) \
(ST_IRQ_EDGE_FALLING << (pin * ST_IRQ_EDGE_CONF_BITS_PER_PIN))
#define ST_IRQ_BOTH_EDGE_CONF(pin) \
(ST_IRQ_EDGE_BOTH << (pin * ST_IRQ_EDGE_CONF_BITS_PER_PIN))
#define ST_IRQ_EDGE_CONF(conf, pin) \
(conf >> (pin * ST_IRQ_EDGE_CONF_BITS_PER_PIN) & ST_IRQ_EDGE_MASK)
struct st_gpio_bank {
struct gpio_chip gpio_chip;
struct pinctrl_gpio_range range;
void __iomem *base;
struct st_pio_control pc;
struct irq_domain *domain;
unsigned long irq_edge_conf;
spinlock_t lock;
};
struct st_pinctrl {
@ -284,6 +337,7 @@ struct st_pinctrl {
int ngroups;
struct regmap *regmap;
const struct st_pctl_data *data;
void __iomem *irqmux_base;
};
/* SOC specific data */
@ -330,12 +384,25 @@ static unsigned int stih416_delays[] = {0, 300, 500, 750, 1000, 1250, 1500,
static const struct st_pctl_data stih416_data = {
.rt_style = st_retime_style_dedicated,
.input_delays = stih416_delays,
.ninput_delays = 14,
.ninput_delays = ARRAY_SIZE(stih416_delays),
.output_delays = stih416_delays,
.noutput_delays = 14,
.noutput_delays = ARRAY_SIZE(stih416_delays),
.alt = 0, .oe = 40, .pu = 50, .od = 60, .rt = 100,
};
static const struct st_pctl_data stih407_flashdata = {
.rt_style = st_retime_style_none,
.input_delays = stih416_delays,
.ninput_delays = ARRAY_SIZE(stih416_delays),
.output_delays = stih416_delays,
.noutput_delays = ARRAY_SIZE(stih416_delays),
.alt = 0,
.oe = -1, /* Not Available */
.pu = -1, /* Not Available */
.od = 60,
.rt = 100,
};
/* Low level functions.. */
static inline int st_gpio_bank(int gpio)
{
@ -356,25 +423,29 @@ static void st_pinconf_set_config(struct st_pio_control *pc,
unsigned int oe_value, pu_value, od_value;
unsigned long mask = BIT(pin);
regmap_field_read(output_enable, &oe_value);
regmap_field_read(pull_up, &pu_value);
regmap_field_read(open_drain, &od_value);
if (output_enable) {
regmap_field_read(output_enable, &oe_value);
oe_value &= ~mask;
if (config & ST_PINCONF_OE)
oe_value |= mask;
regmap_field_write(output_enable, oe_value);
}
/* Clear old values */
oe_value &= ~mask;
pu_value &= ~mask;
od_value &= ~mask;
if (pull_up) {
regmap_field_read(pull_up, &pu_value);
pu_value &= ~mask;
if (config & ST_PINCONF_PU)
pu_value |= mask;
regmap_field_write(pull_up, pu_value);
}
if (config & ST_PINCONF_OE)
oe_value |= mask;
if (config & ST_PINCONF_PU)
pu_value |= mask;
if (config & ST_PINCONF_OD)
od_value |= mask;
regmap_field_write(output_enable, oe_value);
regmap_field_write(pull_up, pu_value);
regmap_field_write(open_drain, od_value);
if (open_drain) {
regmap_field_read(open_drain, &od_value);
od_value &= ~mask;
if (config & ST_PINCONF_OD)
od_value |= mask;
regmap_field_write(open_drain, od_value);
}
}
static void st_pctl_set_function(struct st_pio_control *pc,
@ -385,6 +456,9 @@ static void st_pctl_set_function(struct st_pio_control *pc,
int pin = st_gpio_pin(pin_id);
int offset = pin * 4;
if (!alt)
return;
regmap_field_read(alt, &val);
val &= ~(0xf << offset);
val |= function << offset;
@ -522,17 +596,23 @@ static void st_pinconf_get_direction(struct st_pio_control *pc,
{
unsigned int oe_value, pu_value, od_value;
regmap_field_read(pc->oe, &oe_value);
regmap_field_read(pc->pu, &pu_value);
regmap_field_read(pc->od, &od_value);
if (pc->oe) {
regmap_field_read(pc->oe, &oe_value);
if (oe_value & BIT(pin))
ST_PINCONF_PACK_OE(*config);
}
if (oe_value & BIT(pin))
ST_PINCONF_PACK_OE(*config);
if (pu_value & BIT(pin))
ST_PINCONF_PACK_PU(*config);
if (od_value & BIT(pin))
ST_PINCONF_PACK_OD(*config);
if (pc->pu) {
regmap_field_read(pc->pu, &pu_value);
if (pu_value & BIT(pin))
ST_PINCONF_PACK_PU(*config);
}
if (pc->od) {
regmap_field_read(pc->od, &od_value);
if (od_value & BIT(pin))
ST_PINCONF_PACK_OD(*config);
}
}
static int st_pinconf_get_retime_packed(struct st_pinctrl *info,
@ -1051,8 +1131,21 @@ static int st_pctl_dt_setup_retime(struct st_pinctrl *info,
return -EINVAL;
}
static int st_parse_syscfgs(struct st_pinctrl *info,
int bank, struct device_node *np)
static struct regmap_field *st_pc_get_value(struct device *dev,
struct regmap *regmap, int bank,
int data, int lsb, int msb)
{
struct reg_field reg = REG_FIELD((data + bank) * 4, lsb, msb);
if (data < 0)
return NULL;
return devm_regmap_field_alloc(dev, regmap, reg);
}
static void st_parse_syscfgs(struct st_pinctrl *info, int bank,
struct device_node *np)
{
const struct st_pctl_data *data = info->data;
/**
@ -1062,29 +1155,21 @@ static int st_parse_syscfgs(struct st_pinctrl *info,
*/
int lsb = (bank%4) * ST_GPIO_PINS_PER_BANK;
int msb = lsb + ST_GPIO_PINS_PER_BANK - 1;
struct reg_field alt_reg = REG_FIELD((data->alt + bank) * 4, 0, 31);
struct reg_field oe_reg = REG_FIELD((data->oe + bank/4) * 4, lsb, msb);
struct reg_field pu_reg = REG_FIELD((data->pu + bank/4) * 4, lsb, msb);
struct reg_field od_reg = REG_FIELD((data->od + bank/4) * 4, lsb, msb);
struct st_pio_control *pc = &info->banks[bank].pc;
struct device *dev = info->dev;
struct regmap *regmap = info->regmap;
pc->alt = devm_regmap_field_alloc(dev, regmap, alt_reg);
pc->oe = devm_regmap_field_alloc(dev, regmap, oe_reg);
pc->pu = devm_regmap_field_alloc(dev, regmap, pu_reg);
pc->od = devm_regmap_field_alloc(dev, regmap, od_reg);
if (IS_ERR(pc->alt) || IS_ERR(pc->oe) ||
IS_ERR(pc->pu) || IS_ERR(pc->od))
return -EINVAL;
pc->alt = st_pc_get_value(dev, regmap, bank, data->alt, 0, 31);
pc->oe = st_pc_get_value(dev, regmap, bank/4, data->oe, lsb, msb);
pc->pu = st_pc_get_value(dev, regmap, bank/4, data->pu, lsb, msb);
pc->od = st_pc_get_value(dev, regmap, bank/4, data->od, lsb, msb);
/* retime avaiable for all pins by default */
pc->rt_pin_mask = 0xff;
of_property_read_u32(np, "st,retime-pin-mask", &pc->rt_pin_mask);
st_pctl_dt_setup_retime(info, bank, pc);
return 0;
return;
}
/*
@ -1200,6 +1285,194 @@ static int st_pctl_parse_functions(struct device_node *np,
return 0;
}
static int st_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
{
struct st_gpio_bank *bank = gpio_chip_to_bank(chip);
int irq = -ENXIO;
if (offset < chip->ngpio)
irq = irq_find_mapping(bank->domain, offset);
dev_info(chip->dev, "%s: request IRQ for GPIO %d, return %d\n",
chip->label, offset + chip->base, irq);
return irq;
}
static void st_gpio_irq_mask(struct irq_data *d)
{
struct st_gpio_bank *bank = irq_data_get_irq_chip_data(d);
writel(BIT(d->hwirq), bank->base + REG_PIO_CLR_PMASK);
}
static void st_gpio_irq_unmask(struct irq_data *d)
{
struct st_gpio_bank *bank = irq_data_get_irq_chip_data(d);
writel(BIT(d->hwirq), bank->base + REG_PIO_SET_PMASK);
}
static unsigned int st_gpio_irq_startup(struct irq_data *d)
{
struct st_gpio_bank *bank = irq_data_get_irq_chip_data(d);
if (gpio_lock_as_irq(&bank->gpio_chip, d->hwirq))
dev_err(bank->gpio_chip.dev,
"unable to lock HW IRQ %lu for IRQ\n",
d->hwirq);
st_gpio_irq_unmask(d);
return 0;
}
static void st_gpio_irq_shutdown(struct irq_data *d)
{
struct st_gpio_bank *bank = irq_data_get_irq_chip_data(d);
st_gpio_irq_mask(d);
gpio_unlock_as_irq(&bank->gpio_chip, d->hwirq);
}
static int st_gpio_irq_set_type(struct irq_data *d, unsigned type)
{
struct st_gpio_bank *bank = irq_data_get_irq_chip_data(d);
unsigned long flags;
int comp, pin = d->hwirq;
u32 val;
u32 pin_edge_conf = 0;
switch (type) {
case IRQ_TYPE_LEVEL_HIGH:
comp = 0;
break;
case IRQ_TYPE_EDGE_FALLING:
comp = 0;
pin_edge_conf = ST_IRQ_FALLING_EDGE_CONF(pin);
break;
case IRQ_TYPE_LEVEL_LOW:
comp = 1;
break;
case IRQ_TYPE_EDGE_RISING:
comp = 1;
pin_edge_conf = ST_IRQ_RISING_EDGE_CONF(pin);
break;
case IRQ_TYPE_EDGE_BOTH:
comp = st_gpio_get(&bank->gpio_chip, pin);
pin_edge_conf = ST_IRQ_BOTH_EDGE_CONF(pin);
break;
default:
return -EINVAL;
}
spin_lock_irqsave(&bank->lock, flags);
bank->irq_edge_conf &= ~(ST_IRQ_EDGE_MASK << (
pin * ST_IRQ_EDGE_CONF_BITS_PER_PIN));
bank->irq_edge_conf |= pin_edge_conf;
spin_unlock_irqrestore(&bank->lock, flags);
val = readl(bank->base + REG_PIO_PCOMP);
val &= ~BIT(pin);
val |= (comp << pin);
writel(val, bank->base + REG_PIO_PCOMP);
return 0;
}
/*
* As edge triggers are not supported at hardware level, it is supported by
* software by exploiting the level trigger support in hardware.
*
* Steps for detection raising edge interrupt in software.
*
* Step 1: CONFIGURE pin to detect level LOW interrupts.
*
* Step 2: DETECT level LOW interrupt and in irqmux/gpio bank interrupt handler,
* if the value of pin is low, then CONFIGURE pin for level HIGH interrupt.
* IGNORE calling the actual interrupt handler for the pin at this stage.
*
* Step 3: DETECT level HIGH interrupt and in irqmux/gpio-bank interrupt handler
* if the value of pin is HIGH, CONFIGURE pin for level LOW interrupt and then
* DISPATCH the interrupt to the interrupt handler of the pin.
*
* step-1 ________ __________
* | | step - 3
* | |
* step -2 |_____|
*
* falling edge is also detected int the same way.
*
*/
static void __gpio_irq_handler(struct st_gpio_bank *bank)
{
unsigned long port_in, port_mask, port_comp, active_irqs;
unsigned long bank_edge_mask, flags;
int n, val, ecfg;
spin_lock_irqsave(&bank->lock, flags);
bank_edge_mask = bank->irq_edge_conf;
spin_unlock_irqrestore(&bank->lock, flags);
for (;;) {
port_in = readl(bank->base + REG_PIO_PIN);
port_comp = readl(bank->base + REG_PIO_PCOMP);
port_mask = readl(bank->base + REG_PIO_PMASK);
active_irqs = (port_in ^ port_comp) & port_mask;
if (active_irqs == 0)
break;
for_each_set_bit(n, &active_irqs, BITS_PER_LONG) {
/* check if we are detecting fake edges ... */
ecfg = ST_IRQ_EDGE_CONF(bank_edge_mask, n);
if (ecfg) {
/* edge detection. */
val = st_gpio_get(&bank->gpio_chip, n);
writel(BIT(n),
val ? bank->base + REG_PIO_SET_PCOMP :
bank->base + REG_PIO_CLR_PCOMP);
if (ecfg != ST_IRQ_EDGE_BOTH &&
!((ecfg & ST_IRQ_EDGE_FALLING) ^ val))
continue;
}
generic_handle_irq(irq_find_mapping(bank->domain, n));
}
}
}
static void st_gpio_irq_handler(unsigned irq, struct irq_desc *desc)
{
/* interrupt dedicated per bank */
struct irq_chip *chip = irq_get_chip(irq);
struct st_gpio_bank *bank = irq_get_handler_data(irq);
chained_irq_enter(chip, desc);
__gpio_irq_handler(bank);
chained_irq_exit(chip, desc);
}
static void st_gpio_irqmux_handler(unsigned irq, struct irq_desc *desc)
{
struct irq_chip *chip = irq_get_chip(irq);
struct st_pinctrl *info = irq_get_handler_data(irq);
unsigned long status;
int n;
chained_irq_enter(chip, desc);
status = readl(info->irqmux_base);
for_each_set_bit(n, &status, ST_GPIO_PINS_PER_BANK)
__gpio_irq_handler(&info->banks[n]);
chained_irq_exit(chip, desc);
}
static struct gpio_chip st_gpio_template = {
.request = st_gpio_request,
.free = st_gpio_free,
@ -1210,6 +1483,34 @@ static struct gpio_chip st_gpio_template = {
.ngpio = ST_GPIO_PINS_PER_BANK,
.of_gpio_n_cells = 1,
.of_xlate = st_gpio_xlate,
.to_irq = st_gpio_to_irq,
};
static struct irq_chip st_gpio_irqchip = {
.name = "GPIO",
.irq_mask = st_gpio_irq_mask,
.irq_unmask = st_gpio_irq_unmask,
.irq_set_type = st_gpio_irq_set_type,
.irq_startup = st_gpio_irq_startup,
.irq_shutdown = st_gpio_irq_shutdown,
};
static int st_gpio_irq_domain_map(struct irq_domain *h,
unsigned int virq, irq_hw_number_t hw)
{
struct st_gpio_bank *bank = h->host_data;
irq_set_chip(virq, &st_gpio_irqchip);
irq_set_handler(virq, handle_simple_irq);
set_irq_flags(virq, IRQF_VALID);
irq_set_chip_data(virq, bank);
return 0;
}
static struct irq_domain_ops st_gpio_irq_ops = {
.map = st_gpio_irq_domain_map,
.xlate = irq_domain_xlate_twocell,
};
static int st_gpiolib_register_bank(struct st_pinctrl *info,
@ -1219,8 +1520,8 @@ static int st_gpiolib_register_bank(struct st_pinctrl *info,
struct pinctrl_gpio_range *range = &bank->range;
struct device *dev = info->dev;
int bank_num = of_alias_get_id(np, "gpio");
struct resource res;
int err;
struct resource res, irq_res;
int gpio_irq = 0, err, i;
if (of_address_to_resource(np, 0, &res))
return -ENODEV;
@ -1233,6 +1534,7 @@ static int st_gpiolib_register_bank(struct st_pinctrl *info,
bank->gpio_chip.base = bank_num * ST_GPIO_PINS_PER_BANK;
bank->gpio_chip.ngpio = ST_GPIO_PINS_PER_BANK;
bank->gpio_chip.of_node = np;
spin_lock_init(&bank->lock);
of_property_read_string(np, "st,bank-name", &range->name);
bank->gpio_chip.label = range->name;
@ -1248,6 +1550,51 @@ static int st_gpiolib_register_bank(struct st_pinctrl *info,
}
dev_info(dev, "%s bank added.\n", range->name);
/**
* GPIO bank can have one of the two possible types of
* interrupt-wirings.
*
* First type is via irqmux, single interrupt is used by multiple
* gpio banks. This reduces number of overall interrupts numbers
* required. All these banks belong to a single pincontroller.
* _________
* | |----> [gpio-bank (n) ]
* | |----> [gpio-bank (n + 1)]
* [irqN]-- | irq-mux |----> [gpio-bank (n + 2)]
* | |----> [gpio-bank (... )]
* |_________|----> [gpio-bank (n + 7)]
*
* Second type has a dedicated interrupt per each gpio bank.
*
* [irqN]----> [gpio-bank (n)]
*/
if (of_irq_to_resource(np, 0, &irq_res)) {
gpio_irq = irq_res.start;
irq_set_chained_handler(gpio_irq, st_gpio_irq_handler);
irq_set_handler_data(gpio_irq, bank);
}
if (info->irqmux_base > 0 || gpio_irq > 0) {
/* Setup IRQ domain */
bank->domain = irq_domain_add_linear(np,
ST_GPIO_PINS_PER_BANK,
&st_gpio_irq_ops, bank);
if (!bank->domain) {
dev_err(dev, "Failed to add irq domain for %s\n",
np->full_name);
} else {
for (i = 0; i < ST_GPIO_PINS_PER_BANK; i++) {
if (irq_create_mapping(bank->domain, i) < 0)
dev_err(dev,
"Failed to map IRQ %i\n", i);
}
}
} else {
dev_info(dev, "No IRQ support for %s bank\n", np->full_name);
}
return 0;
}
@ -1264,6 +1611,10 @@ static struct of_device_id st_pctl_of_match[] = {
{ .compatible = "st,stih416-rear-pinctrl", .data = &stih416_data},
{ .compatible = "st,stih416-fvdp-fe-pinctrl", .data = &stih416_data},
{ .compatible = "st,stih416-fvdp-lite-pinctrl", .data = &stih416_data},
{ .compatible = "st,stih407-sbc-pinctrl", .data = &stih416_data},
{ .compatible = "st,stih407-front-pinctrl", .data = &stih416_data},
{ .compatible = "st,stih407-rear-pinctrl", .data = &stih416_data},
{ .compatible = "st,stih407-flash-pinctrl", .data = &stih407_flashdata},
{ /* sentinel */ }
};
@ -1276,6 +1627,8 @@ static int st_pctl_probe_dt(struct platform_device *pdev,
struct device_node *np = pdev->dev.of_node;
struct device_node *child;
int grp_index = 0;
int irq = 0;
struct resource *res;
st_pctl_dt_child_count(info, np);
if (!info->nbanks) {
@ -1306,6 +1659,21 @@ static int st_pctl_probe_dt(struct platform_device *pdev,
}
info->data = of_match_node(st_pctl_of_match, np)->data;
irq = platform_get_irq(pdev, 0);
if (irq > 0) {
res = platform_get_resource_byname(pdev,
IORESOURCE_MEM, "irqmux");
info->irqmux_base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(info->irqmux_base))
return PTR_ERR(info->irqmux_base);
irq_set_chained_handler(irq, st_gpio_irqmux_handler);
irq_set_handler_data(irq, info);
}
pctl_desc->npins = info->nbanks * ST_GPIO_PINS_PER_BANK;
pdesc = devm_kzalloc(&pdev->dev,
sizeof(*pdesc) * pctl_desc->npins, GFP_KERNEL);

View file

@ -1932,27 +1932,27 @@ static const struct sunxi_desc_pin sun5i_a13_pins[] = {
SUNXI_PIN(SUNXI_PINCTRL_PIN_PF0,
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x4, "mmc0")), /* D1 */
SUNXI_FUNCTION(0x2, "mmc0")), /* D1 */
SUNXI_PIN(SUNXI_PINCTRL_PIN_PF1,
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x4, "mmc0")), /* D0 */
SUNXI_FUNCTION(0x2, "mmc0")), /* D0 */
SUNXI_PIN(SUNXI_PINCTRL_PIN_PF2,
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x4, "mmc0")), /* CLK */
SUNXI_FUNCTION(0x2, "mmc0")), /* CLK */
SUNXI_PIN(SUNXI_PINCTRL_PIN_PF3,
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x4, "mmc0")), /* CMD */
SUNXI_FUNCTION(0x2, "mmc0")), /* CMD */
SUNXI_PIN(SUNXI_PINCTRL_PIN_PF4,
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x4, "mmc0")), /* D3 */
SUNXI_FUNCTION(0x2, "mmc0")), /* D3 */
SUNXI_PIN(SUNXI_PINCTRL_PIN_PF5,
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x4, "mmc0")), /* D2 */
SUNXI_FUNCTION(0x2, "mmc0")), /* D2 */
/* Hole */
SUNXI_PIN(SUNXI_PINCTRL_PIN_PG0,
SUNXI_FUNCTION(0x0, "gpio_in"),

View file

@ -39,6 +39,7 @@ struct tegra_pmx {
struct pinctrl_dev *pctl;
const struct tegra_pinctrl_soc_data *soc;
const char **group_pins;
int nbanks;
void __iomem **regs;
@ -620,6 +621,8 @@ int tegra_pinctrl_probe(struct platform_device *pdev,
struct tegra_pmx *pmx;
struct resource *res;
int i;
const char **group_pins;
int fn, gn, gfn;
pmx = devm_kzalloc(&pdev->dev, sizeof(*pmx), GFP_KERNEL);
if (!pmx) {
@ -629,6 +632,41 @@ int tegra_pinctrl_probe(struct platform_device *pdev,
pmx->dev = &pdev->dev;
pmx->soc = soc_data;
/*
* Each mux group will appear in 4 functions' list of groups.
* This over-allocates slightly, since not all groups are mux groups.
*/
pmx->group_pins = devm_kzalloc(&pdev->dev,
soc_data->ngroups * 4 * sizeof(*pmx->group_pins),
GFP_KERNEL);
if (!pmx->group_pins)
return -ENOMEM;
group_pins = pmx->group_pins;
for (fn = 0; fn < soc_data->nfunctions; fn++) {
struct tegra_function *func = &soc_data->functions[fn];
func->groups = group_pins;
for (gn = 0; gn < soc_data->ngroups; gn++) {
const struct tegra_pingroup *g = &soc_data->groups[gn];
if (g->mux_reg == -1)
continue;
for (gfn = 0; gfn < 4; gfn++)
if (g->funcs[gfn] == fn)
break;
if (gfn == 4)
continue;
BUG_ON(group_pins - pmx->group_pins >=
soc_data->ngroups * 4);
*group_pins++ = g->name;
func->ngroups++;
}
}
tegra_pinctrl_gpio_range.npins = pmx->soc->ngpios;
tegra_pinctrl_desc.name = dev_name(&pdev->dev);
tegra_pinctrl_desc.pins = pmx->soc->pins;

View file

@ -72,7 +72,7 @@ enum tegra_pinconf_tristate {
*/
struct tegra_function {
const char *name;
const char * const *groups;
const char **groups;
unsigned ngroups;
};
@ -193,7 +193,7 @@ struct tegra_pinctrl_soc_data {
unsigned ngpios;
const struct pinctrl_pin_desc *pins;
unsigned npins;
const struct tegra_function *functions;
struct tegra_function *functions;
unsigned nfunctions;
const struct tegra_pingroup *groups;
unsigned ngroups;

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1894,637 +1894,12 @@ enum tegra_mux {
TEGRA_MUX_XIO,
};
static const char * const ahb_clk_groups[] = {
"cdev2",
};
static const char * const apb_clk_groups[] = {
"cdev2",
};
static const char * const audio_sync_groups[] = {
"cdev1",
};
static const char * const crt_groups[] = {
"crtp",
"lm1",
};
static const char * const dap1_groups[] = {
"dap1",
};
static const char * const dap2_groups[] = {
"dap2",
};
static const char * const dap3_groups[] = {
"dap3",
};
static const char * const dap4_groups[] = {
"dap4",
};
static const char * const dap5_groups[] = {
"gme",
};
static const char * const displaya_groups[] = {
"lcsn",
"ld0",
"ld1",
"ld10",
"ld11",
"ld12",
"ld13",
"ld14",
"ld15",
"ld16",
"ld17",
"ld2",
"ld3",
"ld4",
"ld5",
"ld6",
"ld7",
"ld8",
"ld9",
"ldc",
"ldi",
"lhp0",
"lhp1",
"lhp2",
"lhs",
"lm0",
"lm1",
"lpp",
"lpw0",
"lpw1",
"lpw2",
"lsc0",
"lsc1",
"lsck",
"lsda",
"lsdi",
"lspi",
"lvp0",
"lvp1",
"lvs",
};
static const char * const displayb_groups[] = {
"lcsn",
"ld0",
"ld1",
"ld10",
"ld11",
"ld12",
"ld13",
"ld14",
"ld15",
"ld16",
"ld17",
"ld2",
"ld3",
"ld4",
"ld5",
"ld6",
"ld7",
"ld8",
"ld9",
"ldc",
"ldi",
"lhp0",
"lhp1",
"lhp2",
"lhs",
"lm0",
"lm1",
"lpp",
"lpw0",
"lpw1",
"lpw2",
"lsc0",
"lsc1",
"lsck",
"lsda",
"lsdi",
"lspi",
"lvp0",
"lvp1",
"lvs",
};
static const char * const emc_test0_dll_groups[] = {
"kbca",
};
static const char * const emc_test1_dll_groups[] = {
"kbcc",
};
static const char * const gmi_groups[] = {
"ata",
"atb",
"atc",
"atd",
"ate",
"dap1",
"dap2",
"dap4",
"gma",
"gmb",
"gmc",
"gmd",
"gme",
"gpu",
"irrx",
"irtx",
"pta",
"spia",
"spib",
"spic",
"spid",
"spie",
"uca",
"ucb",
};
static const char * const gmi_int_groups[] = {
"gmb",
};
static const char * const hdmi_groups[] = {
"hdint",
"lpw0",
"lpw2",
"lsc1",
"lsck",
"lsda",
"lspi",
"pta",
};
static const char * const i2cp_groups[] = {
"i2cp",
};
static const char * const i2c1_groups[] = {
"rm",
"spdi",
"spdo",
"spig",
"spih",
};
static const char * const i2c2_groups[] = {
"ddc",
"pta",
};
static const char * const i2c3_groups[] = {
"dtf",
};
static const char * const ide_groups[] = {
"ata",
"atb",
"atc",
"atd",
"ate",
"gmb",
};
static const char * const irda_groups[] = {
"uad",
};
static const char * const kbc_groups[] = {
"kbca",
"kbcb",
"kbcc",
"kbcd",
"kbce",
"kbcf",
};
static const char * const mio_groups[] = {
"kbcb",
"kbcd",
"kbcf",
};
static const char * const mipi_hs_groups[] = {
"uaa",
"uab",
};
static const char * const nand_groups[] = {
"ata",
"atb",
"atc",
"atd",
"ate",
"gmb",
"gmd",
"kbca",
"kbcb",
"kbcc",
"kbcd",
"kbce",
"kbcf",
};
static const char * const osc_groups[] = {
"cdev1",
"cdev2",
};
static const char * const owr_groups[] = {
"kbce",
"owc",
"uac",
};
static const char * const pcie_groups[] = {
"gpv",
"slxa",
"slxk",
};
static const char * const plla_out_groups[] = {
"cdev1",
};
static const char * const pllc_out1_groups[] = {
"csus",
};
static const char * const pllm_out1_groups[] = {
"cdev1",
};
static const char * const pllp_out2_groups[] = {
"csus",
};
static const char * const pllp_out3_groups[] = {
"csus",
};
static const char * const pllp_out4_groups[] = {
"cdev2",
};
static const char * const pwm_groups[] = {
"gpu",
"sdb",
"sdc",
"sdd",
"ucb",
};
static const char * const pwr_intr_groups[] = {
"pmc",
};
static const char * const pwr_on_groups[] = {
"pmc",
};
static const char * const rsvd1_groups[] = {
"dta",
"dtb",
"dtc",
"dtd",
"dte",
"gmd",
"gme",
};
static const char * const rsvd2_groups[] = {
"crtp",
"dap1",
"dap3",
"dap4",
"ddc",
"dtb",
"dtc",
"dte",
"dtf",
"gpu7",
"gpv",
"hdint",
"i2cp",
"owc",
"rm",
"sdio1",
"spdi",
"spdo",
"uac",
"uca",
"uda",
};
static const char * const rsvd3_groups[] = {
"crtp",
"dap2",
"dap3",
"ddc",
"gpu7",
"gpv",
"hdint",
"i2cp",
"ld17",
"ldc",
"ldi",
"lhp0",
"lhp1",
"lhp2",
"lm1",
"lpp",
"lpw1",
"lvp0",
"lvp1",
"owc",
"pmc",
"rm",
"uac",
};
static const char * const rsvd4_groups[] = {
"ata",
"ate",
"crtp",
"dap3",
"dap4",
"ddc",
"dta",
"dtc",
"dtd",
"dtf",
"gpu",
"gpu7",
"gpv",
"hdint",
"i2cp",
"kbce",
"lcsn",
"ld0",
"ld1",
"ld2",
"ld3",
"ld4",
"ld5",
"ld6",
"ld7",
"ld8",
"ld9",
"ld10",
"ld11",
"ld12",
"ld13",
"ld14",
"ld15",
"ld16",
"ld17",
"ldc",
"ldi",
"lhp0",
"lhp1",
"lhp2",
"lhs",
"lm0",
"lpp",
"lpw1",
"lsc0",
"lsdi",
"lvp0",
"lvp1",
"lvs",
"owc",
"pmc",
"pta",
"rm",
"spif",
"uac",
"uca",
"ucb",
};
static const char * const rtck_groups[] = {
"gpu7",
};
static const char * const sdio1_groups[] = {
"sdio1",
};
static const char * const sdio2_groups[] = {
"dap1",
"dta",
"dtd",
"kbca",
"kbcb",
"kbcd",
"spdi",
"spdo",
};
static const char * const sdio3_groups[] = {
"sdb",
"sdc",
"sdd",
"slxa",
"slxc",
"slxd",
"slxk",
};
static const char * const sdio4_groups[] = {
"atb",
"atc",
"atd",
"gma",
"gme",
};
static const char * const sflash_groups[] = {
"gmc",
"gmd",
};
static const char * const spdif_groups[] = {
"slxc",
"slxd",
"spdi",
"spdo",
"uad",
};
static const char * const spi1_groups[] = {
"dtb",
"dte",
"spia",
"spib",
"spic",
"spid",
"spie",
"spif",
"uda",
};
static const char * const spi2_groups[] = {
"sdb",
"slxa",
"slxc",
"slxd",
"slxk",
"spia",
"spib",
"spic",
"spid",
"spie",
"spif",
"spig",
"spih",
"uab",
};
static const char * const spi2_alt_groups[] = {
"spid",
"spie",
"spig",
"spih",
};
static const char * const spi3_groups[] = {
"gma",
"lcsn",
"lm0",
"lpw0",
"lpw2",
"lsc1",
"lsck",
"lsda",
"lsdi",
"sdc",
"sdd",
"spia",
"spib",
"spic",
"spif",
"spig",
"spih",
"uaa",
};
static const char * const spi4_groups[] = {
"gmc",
"irrx",
"irtx",
"slxa",
"slxc",
"slxd",
"slxk",
"uad",
};
static const char * const trace_groups[] = {
"kbcc",
"kbcf",
};
static const char * const twc_groups[] = {
"dap2",
"sdc",
};
static const char * const uarta_groups[] = {
"gpu",
"irrx",
"irtx",
"sdb",
"sdd",
"sdio1",
"uaa",
"uab",
"uad",
};
static const char * const uartb_groups[] = {
"irrx",
"irtx",
};
static const char * const uartc_groups[] = {
"uca",
"ucb",
};
static const char * const uartd_groups[] = {
"gmc",
"uda",
};
static const char * const uarte_groups[] = {
"gma",
"sdio1",
};
static const char * const ulpi_groups[] = {
"uaa",
"uab",
"uda",
};
static const char * const vi_groups[] = {
"dta",
"dtb",
"dtc",
"dtd",
"dte",
"dtf",
};
static const char * const vi_sensor_clk_groups[] = {
"csus",
};
static const char * const xio_groups[] = {
"ld0",
"ld1",
"ld10",
"ld11",
"ld12",
"ld13",
"ld14",
"ld15",
"ld16",
"ld2",
"ld3",
"ld4",
"ld5",
"ld6",
"ld7",
"ld8",
"ld9",
"lhs",
"lsc0",
"lspi",
"lvs",
};
#define FUNCTION(fname) \
{ \
.name = #fname, \
.groups = fname##_groups, \
.ngroups = ARRAY_SIZE(fname##_groups), \
}
static const struct tegra_function tegra20_functions[] = {
static struct tegra_function tegra20_functions[] = {
FUNCTION(ahb_clk),
FUNCTION(apb_clk),
FUNCTION(audio_sync),
@ -2881,18 +2256,7 @@ static struct platform_driver tegra20_pinctrl_driver = {
.probe = tegra20_pinctrl_probe,
.remove = tegra_pinctrl_remove,
};
static int __init tegra20_pinctrl_init(void)
{
return platform_driver_register(&tegra20_pinctrl_driver);
}
arch_initcall(tegra20_pinctrl_init);
static void __exit tegra20_pinctrl_exit(void)
{
platform_driver_unregister(&tegra20_pinctrl_driver);
}
module_exit(tegra20_pinctrl_exit);
module_platform_driver(tegra20_pinctrl_driver);
MODULE_AUTHOR("Stephen Warren <[email protected]>");
MODULE_DESCRIPTION("NVIDIA Tegra20 pinctrl driver");

File diff suppressed because it is too large Load diff

View file

@ -2260,6 +2260,42 @@ static const unsigned int msiof0_tx_pins[] = {
static const unsigned int msiof0_tx_mux[] = {
MSIOF0_TXD_MARK,
};
static const unsigned int msiof0_clk_b_pins[] = {
/* SCK */
RCAR_GP_PIN(1, 23),
};
static const unsigned int msiof0_clk_b_mux[] = {
MSIOF0_SCK_B_MARK,
};
static const unsigned int msiof0_ss1_b_pins[] = {
/* SS1 */
RCAR_GP_PIN(1, 12),
};
static const unsigned int msiof0_ss1_b_mux[] = {
MSIOF0_SS1_B_MARK,
};
static const unsigned int msiof0_ss2_b_pins[] = {
/* SS2 */
RCAR_GP_PIN(1, 10),
};
static const unsigned int msiof0_ss2_b_mux[] = {
MSIOF0_SS2_B_MARK,
};
static const unsigned int msiof0_rx_b_pins[] = {
/* RXD */
RCAR_GP_PIN(1, 29),
};
static const unsigned int msiof0_rx_b_mux[] = {
MSIOF0_RXD_B_MARK,
};
static const unsigned int msiof0_tx_b_pins[] = {
/* TXD */
RCAR_GP_PIN(1, 28),
};
static const unsigned int msiof0_tx_b_mux[] = {
MSIOF0_TXD_B_MARK,
};
/* - MSIOF1 ----------------------------------------------------------------- */
static const unsigned int msiof1_clk_pins[] = {
/* SCK */
@ -2303,6 +2339,42 @@ static const unsigned int msiof1_tx_pins[] = {
static const unsigned int msiof1_tx_mux[] = {
MSIOF1_TXD_MARK,
};
static const unsigned int msiof1_clk_b_pins[] = {
/* SCK */
RCAR_GP_PIN(1, 16),
};
static const unsigned int msiof1_clk_b_mux[] = {
MSIOF1_SCK_B_MARK,
};
static const unsigned int msiof1_ss1_b_pins[] = {
/* SS1 */
RCAR_GP_PIN(0, 18),
};
static const unsigned int msiof1_ss1_b_mux[] = {
MSIOF1_SS1_B_MARK,
};
static const unsigned int msiof1_ss2_b_pins[] = {
/* SS2 */
RCAR_GP_PIN(0, 19),
};
static const unsigned int msiof1_ss2_b_mux[] = {
MSIOF1_SS2_B_MARK,
};
static const unsigned int msiof1_rx_b_pins[] = {
/* RXD */
RCAR_GP_PIN(1, 17),
};
static const unsigned int msiof1_rx_b_mux[] = {
MSIOF1_RXD_B_MARK,
};
static const unsigned int msiof1_tx_b_pins[] = {
/* TXD */
RCAR_GP_PIN(0, 20),
};
static const unsigned int msiof1_tx_b_mux[] = {
MSIOF1_TXD_B_MARK,
};
/* - MSIOF2 ----------------------------------------------------------------- */
static const unsigned int msiof2_clk_pins[] = {
/* SCK */
@ -2389,6 +2461,58 @@ static const unsigned int msiof3_tx_pins[] = {
static const unsigned int msiof3_tx_mux[] = {
MSIOF3_TXD_MARK,
};
static const unsigned int msiof3_clk_b_pins[] = {
/* SCK */
RCAR_GP_PIN(0, 0),
};
static const unsigned int msiof3_clk_b_mux[] = {
MSIOF3_SCK_B_MARK,
};
static const unsigned int msiof3_sync_b_pins[] = {
/* SYNC */
RCAR_GP_PIN(0, 1),
};
static const unsigned int msiof3_sync_b_mux[] = {
MSIOF3_SYNC_B_MARK,
};
static const unsigned int msiof3_rx_b_pins[] = {
/* RXD */
RCAR_GP_PIN(0, 2),
};
static const unsigned int msiof3_rx_b_mux[] = {
MSIOF3_RXD_B_MARK,
};
static const unsigned int msiof3_tx_b_pins[] = {
/* TXD */
RCAR_GP_PIN(0, 3),
};
static const unsigned int msiof3_tx_b_mux[] = {
MSIOF3_TXD_B_MARK,
};
/* - QSPI ------------------------------------------------------------------- */
static const unsigned int qspi_ctrl_pins[] = {
/* SPCLK, SSL */
RCAR_GP_PIN(1, 4), RCAR_GP_PIN(1, 9),
};
static const unsigned int qspi_ctrl_mux[] = {
SPCLK_MARK, SSL_MARK,
};
static const unsigned int qspi_data2_pins[] = {
/* MOSI_IO0, MISO_IO1 */
RCAR_GP_PIN(1, 5), RCAR_GP_PIN(1, 6),
};
static const unsigned int qspi_data2_mux[] = {
MOSI_IO0_MARK, MISO_IO1_MARK,
};
static const unsigned int qspi_data4_pins[] = {
/* MOSI_IO0, MISO_IO1, IO2, IO3 */
RCAR_GP_PIN(1, 5), RCAR_GP_PIN(1, 6), RCAR_GP_PIN(1, 7),
RCAR_GP_PIN(1, 8),
};
static const unsigned int qspi_data4_mux[] = {
MOSI_IO0_MARK, MISO_IO1_MARK, IO2_MARK, IO3_MARK,
};
/* - SCIF0 ------------------------------------------------------------------ */
static const unsigned int scif0_data_pins[] = {
/* RX, TX */
@ -3231,6 +3355,13 @@ static const unsigned int usb0_pins[] = {
static const unsigned int usb0_mux[] = {
USB0_PWEN_MARK, USB0_OVC_VBUS_MARK,
};
static const unsigned int usb0_ovc_vbus_pins[] = {
/* OVC/VBUS */
RCAR_GP_PIN(5, 19),
};
static const unsigned int usb0_ovc_vbus_mux[] = {
USB0_OVC_VBUS_MARK,
};
/* - USB1 ------------------------------------------------------------------- */
static const unsigned int usb1_pins[] = {
/* PWEN, OVC */
@ -3653,12 +3784,22 @@ static const struct sh_pfc_pin_group pinmux_groups[] = {
SH_PFC_PIN_GROUP(msiof0_ss2),
SH_PFC_PIN_GROUP(msiof0_rx),
SH_PFC_PIN_GROUP(msiof0_tx),
SH_PFC_PIN_GROUP(msiof0_clk_b),
SH_PFC_PIN_GROUP(msiof0_ss1_b),
SH_PFC_PIN_GROUP(msiof0_ss2_b),
SH_PFC_PIN_GROUP(msiof0_rx_b),
SH_PFC_PIN_GROUP(msiof0_tx_b),
SH_PFC_PIN_GROUP(msiof1_clk),
SH_PFC_PIN_GROUP(msiof1_sync),
SH_PFC_PIN_GROUP(msiof1_ss1),
SH_PFC_PIN_GROUP(msiof1_ss2),
SH_PFC_PIN_GROUP(msiof1_rx),
SH_PFC_PIN_GROUP(msiof1_tx),
SH_PFC_PIN_GROUP(msiof1_clk_b),
SH_PFC_PIN_GROUP(msiof1_ss1_b),
SH_PFC_PIN_GROUP(msiof1_ss2_b),
SH_PFC_PIN_GROUP(msiof1_rx_b),
SH_PFC_PIN_GROUP(msiof1_tx_b),
SH_PFC_PIN_GROUP(msiof2_clk),
SH_PFC_PIN_GROUP(msiof2_sync),
SH_PFC_PIN_GROUP(msiof2_ss1),
@ -3671,6 +3812,13 @@ static const struct sh_pfc_pin_group pinmux_groups[] = {
SH_PFC_PIN_GROUP(msiof3_ss2),
SH_PFC_PIN_GROUP(msiof3_rx),
SH_PFC_PIN_GROUP(msiof3_tx),
SH_PFC_PIN_GROUP(msiof3_clk_b),
SH_PFC_PIN_GROUP(msiof3_sync_b),
SH_PFC_PIN_GROUP(msiof3_rx_b),
SH_PFC_PIN_GROUP(msiof3_tx_b),
SH_PFC_PIN_GROUP(qspi_ctrl),
SH_PFC_PIN_GROUP(qspi_data2),
SH_PFC_PIN_GROUP(qspi_data4),
SH_PFC_PIN_GROUP(scif0_data),
SH_PFC_PIN_GROUP(scif0_clk),
SH_PFC_PIN_GROUP(scif0_ctrl),
@ -3789,6 +3937,7 @@ static const struct sh_pfc_pin_group pinmux_groups[] = {
SH_PFC_PIN_GROUP(tpu0_to2),
SH_PFC_PIN_GROUP(tpu0_to3),
SH_PFC_PIN_GROUP(usb0),
SH_PFC_PIN_GROUP(usb0_ovc_vbus),
SH_PFC_PIN_GROUP(usb1),
SH_PFC_PIN_GROUP(usb2),
VIN_DATA_PIN_GROUP(vin0_data, 24),
@ -3941,6 +4090,11 @@ static const char * const msiof0_groups[] = {
"msiof0_ss2",
"msiof0_rx",
"msiof0_tx",
"msiof0_clk_b",
"msiof0_ss1_b",
"msiof0_ss2_b",
"msiof0_rx_b",
"msiof0_tx_b",
};
static const char * const msiof1_groups[] = {
@ -3950,6 +4104,11 @@ static const char * const msiof1_groups[] = {
"msiof1_ss2",
"msiof1_rx",
"msiof1_tx",
"msiof1_clk_b",
"msiof1_ss1_b",
"msiof1_ss2_b",
"msiof1_rx_b",
"msiof1_tx_b",
};
static const char * const msiof2_groups[] = {
@ -3968,6 +4127,16 @@ static const char * const msiof3_groups[] = {
"msiof3_ss2",
"msiof3_rx",
"msiof3_tx",
"msiof3_clk_b",
"msiof3_sync_b",
"msiof3_rx_b",
"msiof3_tx_b",
};
static const char * const qspi_groups[] = {
"qspi_ctrl",
"qspi_data2",
"qspi_data4",
};
static const char * const scif0_groups[] = {
@ -4134,6 +4303,7 @@ static const char * const tpu0_groups[] = {
static const char * const usb0_groups[] = {
"usb0",
"usb0_ovc_vbus",
};
static const char * const usb1_groups[] = {
@ -4213,6 +4383,7 @@ static const struct sh_pfc_function pinmux_functions[] = {
SH_PFC_FUNCTION(msiof1),
SH_PFC_FUNCTION(msiof2),
SH_PFC_FUNCTION(msiof3),
SH_PFC_FUNCTION(qspi),
SH_PFC_FUNCTION(scif0),
SH_PFC_FUNCTION(scif1),
SH_PFC_FUNCTION(scif2),

View file

@ -1945,6 +1945,50 @@ static const unsigned int i2c4_c_pins[] = {
static const unsigned int i2c4_c_mux[] = {
SCL4_C_MARK, SDA4_C_MARK,
};
/* - I2C7 ------------------------------------------------------------------- */
static const unsigned int i2c7_pins[] = {
/* SCL, SDA */
RCAR_GP_PIN(5, 15), RCAR_GP_PIN(5, 16),
};
static const unsigned int i2c7_mux[] = {
SCL7_MARK, SDA7_MARK,
};
static const unsigned int i2c7_b_pins[] = {
/* SCL, SDA */
RCAR_GP_PIN(2, 2), RCAR_GP_PIN(2, 3),
};
static const unsigned int i2c7_b_mux[] = {
SCL7_B_MARK, SDA7_B_MARK,
};
static const unsigned int i2c7_c_pins[] = {
/* SCL, SDA */
RCAR_GP_PIN(6, 28), RCAR_GP_PIN(6, 29),
};
static const unsigned int i2c7_c_mux[] = {
SCL7_C_MARK, SDA7_C_MARK,
};
/* - I2C8 ------------------------------------------------------------------- */
static const unsigned int i2c8_pins[] = {
/* SCL, SDA */
RCAR_GP_PIN(4, 13), RCAR_GP_PIN(4, 14),
};
static const unsigned int i2c8_mux[] = {
SCL8_MARK, SDA8_MARK,
};
static const unsigned int i2c8_b_pins[] = {
/* SCL, SDA */
RCAR_GP_PIN(2, 4), RCAR_GP_PIN(2, 5),
};
static const unsigned int i2c8_b_mux[] = {
SCL8_B_MARK, SDA8_B_MARK,
};
static const unsigned int i2c8_c_pins[] = {
/* SCL, SDA */
RCAR_GP_PIN(6, 22), RCAR_GP_PIN(6, 23),
};
static const unsigned int i2c8_c_mux[] = {
SCL8_C_MARK, SDA8_C_MARK,
};
/* - INTC ------------------------------------------------------------------- */
static const unsigned int intc_irq0_pins[] = {
/* IRQ */
@ -2051,6 +2095,92 @@ static const unsigned int msiof0_tx_pins[] = {
static const unsigned int msiof0_tx_mux[] = {
MSIOF0_TXD_MARK,
};
static const unsigned int msiof0_clk_b_pins[] = {
/* SCK */
RCAR_GP_PIN(0, 16),
};
static const unsigned int msiof0_clk_b_mux[] = {
MSIOF0_SCK_B_MARK,
};
static const unsigned int msiof0_sync_b_pins[] = {
/* SYNC */
RCAR_GP_PIN(0, 17),
};
static const unsigned int msiof0_sync_b_mux[] = {
MSIOF0_SYNC_B_MARK,
};
static const unsigned int msiof0_ss1_b_pins[] = {
/* SS1 */
RCAR_GP_PIN(0, 18),
};
static const unsigned int msiof0_ss1_b_mux[] = {
MSIOF0_SS1_B_MARK,
};
static const unsigned int msiof0_ss2_b_pins[] = {
/* SS2 */
RCAR_GP_PIN(0, 19),
};
static const unsigned int msiof0_ss2_b_mux[] = {
MSIOF0_SS2_B_MARK,
};
static const unsigned int msiof0_rx_b_pins[] = {
/* RXD */
RCAR_GP_PIN(0, 21),
};
static const unsigned int msiof0_rx_b_mux[] = {
MSIOF0_RXD_B_MARK,
};
static const unsigned int msiof0_tx_b_pins[] = {
/* TXD */
RCAR_GP_PIN(0, 20),
};
static const unsigned int msiof0_tx_b_mux[] = {
MSIOF0_TXD_B_MARK,
};
static const unsigned int msiof0_clk_c_pins[] = {
/* SCK */
RCAR_GP_PIN(5, 26),
};
static const unsigned int msiof0_clk_c_mux[] = {
MSIOF0_SCK_C_MARK,
};
static const unsigned int msiof0_sync_c_pins[] = {
/* SYNC */
RCAR_GP_PIN(5, 25),
};
static const unsigned int msiof0_sync_c_mux[] = {
MSIOF0_SYNC_C_MARK,
};
static const unsigned int msiof0_ss1_c_pins[] = {
/* SS1 */
RCAR_GP_PIN(5, 27),
};
static const unsigned int msiof0_ss1_c_mux[] = {
MSIOF0_SS1_C_MARK,
};
static const unsigned int msiof0_ss2_c_pins[] = {
/* SS2 */
RCAR_GP_PIN(5, 28),
};
static const unsigned int msiof0_ss2_c_mux[] = {
MSIOF0_SS2_C_MARK,
};
static const unsigned int msiof0_rx_c_pins[] = {
/* RXD */
RCAR_GP_PIN(5, 29),
};
static const unsigned int msiof0_rx_c_mux[] = {
MSIOF0_RXD_C_MARK,
};
static const unsigned int msiof0_tx_c_pins[] = {
/* TXD */
RCAR_GP_PIN(5, 30),
};
static const unsigned int msiof0_tx_c_mux[] = {
MSIOF0_TXD_C_MARK,
};
/* - MSIOF1 ----------------------------------------------------------------- */
static const unsigned int msiof1_clk_pins[] = {
/* SCK */
@ -2094,6 +2224,143 @@ static const unsigned int msiof1_tx_pins[] = {
static const unsigned int msiof1_tx_mux[] = {
MSIOF1_TXD_MARK,
};
static const unsigned int msiof1_clk_b_pins[] = {
/* SCK */
RCAR_GP_PIN(2, 29),
};
static const unsigned int msiof1_clk_b_mux[] = {
MSIOF1_SCK_B_MARK,
};
static const unsigned int msiof1_sync_b_pins[] = {
/* SYNC */
RCAR_GP_PIN(2, 30),
};
static const unsigned int msiof1_sync_b_mux[] = {
MSIOF1_SYNC_B_MARK,
};
static const unsigned int msiof1_ss1_b_pins[] = {
/* SS1 */
RCAR_GP_PIN(2, 31),
};
static const unsigned int msiof1_ss1_b_mux[] = {
MSIOF1_SS1_B_MARK,
};
static const unsigned int msiof1_ss2_b_pins[] = {
/* SS2 */
RCAR_GP_PIN(7, 16),
};
static const unsigned int msiof1_ss2_b_mux[] = {
MSIOF1_SS2_B_MARK,
};
static const unsigned int msiof1_rx_b_pins[] = {
/* RXD */
RCAR_GP_PIN(7, 18),
};
static const unsigned int msiof1_rx_b_mux[] = {
MSIOF1_RXD_B_MARK,
};
static const unsigned int msiof1_tx_b_pins[] = {
/* TXD */
RCAR_GP_PIN(7, 17),
};
static const unsigned int msiof1_tx_b_mux[] = {
MSIOF1_TXD_B_MARK,
};
static const unsigned int msiof1_clk_c_pins[] = {
/* SCK */
RCAR_GP_PIN(2, 15),
};
static const unsigned int msiof1_clk_c_mux[] = {
MSIOF1_SCK_C_MARK,
};
static const unsigned int msiof1_sync_c_pins[] = {
/* SYNC */
RCAR_GP_PIN(2, 16),
};
static const unsigned int msiof1_sync_c_mux[] = {
MSIOF1_SYNC_C_MARK,
};
static const unsigned int msiof1_rx_c_pins[] = {
/* RXD */
RCAR_GP_PIN(2, 18),
};
static const unsigned int msiof1_rx_c_mux[] = {
MSIOF1_RXD_C_MARK,
};
static const unsigned int msiof1_tx_c_pins[] = {
/* TXD */
RCAR_GP_PIN(2, 17),
};
static const unsigned int msiof1_tx_c_mux[] = {
MSIOF1_TXD_C_MARK,
};
static const unsigned int msiof1_clk_d_pins[] = {
/* SCK */
RCAR_GP_PIN(0, 28),
};
static const unsigned int msiof1_clk_d_mux[] = {
MSIOF1_SCK_D_MARK,
};
static const unsigned int msiof1_sync_d_pins[] = {
/* SYNC */
RCAR_GP_PIN(0, 30),
};
static const unsigned int msiof1_sync_d_mux[] = {
MSIOF1_SYNC_D_MARK,
};
static const unsigned int msiof1_ss1_d_pins[] = {
/* SS1 */
RCAR_GP_PIN(0, 29),
};
static const unsigned int msiof1_ss1_d_mux[] = {
MSIOF1_SS1_D_MARK,
};
static const unsigned int msiof1_rx_d_pins[] = {
/* RXD */
RCAR_GP_PIN(0, 27),
};
static const unsigned int msiof1_rx_d_mux[] = {
MSIOF1_RXD_D_MARK,
};
static const unsigned int msiof1_tx_d_pins[] = {
/* TXD */
RCAR_GP_PIN(0, 26),
};
static const unsigned int msiof1_tx_d_mux[] = {
MSIOF1_TXD_D_MARK,
};
static const unsigned int msiof1_clk_e_pins[] = {
/* SCK */
RCAR_GP_PIN(5, 18),
};
static const unsigned int msiof1_clk_e_mux[] = {
MSIOF1_SCK_E_MARK,
};
static const unsigned int msiof1_sync_e_pins[] = {
/* SYNC */
RCAR_GP_PIN(5, 19),
};
static const unsigned int msiof1_sync_e_mux[] = {
MSIOF1_SYNC_E_MARK,
};
static const unsigned int msiof1_rx_e_pins[] = {
/* RXD */
RCAR_GP_PIN(5, 17),
};
static const unsigned int msiof1_rx_e_mux[] = {
MSIOF1_RXD_E_MARK,
};
static const unsigned int msiof1_tx_e_pins[] = {
/* TXD */
RCAR_GP_PIN(5, 20),
};
static const unsigned int msiof1_tx_e_mux[] = {
MSIOF1_TXD_E_MARK,
};
/* - MSIOF2 ----------------------------------------------------------------- */
static const unsigned int msiof2_clk_pins[] = {
/* SCK */
@ -2137,6 +2404,197 @@ static const unsigned int msiof2_tx_pins[] = {
static const unsigned int msiof2_tx_mux[] = {
MSIOF2_TXD_MARK,
};
static const unsigned int msiof2_clk_b_pins[] = {
/* SCK */
RCAR_GP_PIN(3, 0),
};
static const unsigned int msiof2_clk_b_mux[] = {
MSIOF2_SCK_B_MARK,
};
static const unsigned int msiof2_sync_b_pins[] = {
/* SYNC */
RCAR_GP_PIN(3, 1),
};
static const unsigned int msiof2_sync_b_mux[] = {
MSIOF2_SYNC_B_MARK,
};
static const unsigned int msiof2_ss1_b_pins[] = {
/* SS1 */
RCAR_GP_PIN(3, 8),
};
static const unsigned int msiof2_ss1_b_mux[] = {
MSIOF2_SS1_B_MARK,
};
static const unsigned int msiof2_ss2_b_pins[] = {
/* SS2 */
RCAR_GP_PIN(3, 9),
};
static const unsigned int msiof2_ss2_b_mux[] = {
MSIOF2_SS2_B_MARK,
};
static const unsigned int msiof2_rx_b_pins[] = {
/* RXD */
RCAR_GP_PIN(3, 17),
};
static const unsigned int msiof2_rx_b_mux[] = {
MSIOF2_RXD_B_MARK,
};
static const unsigned int msiof2_tx_b_pins[] = {
/* TXD */
RCAR_GP_PIN(3, 16),
};
static const unsigned int msiof2_tx_b_mux[] = {
MSIOF2_TXD_B_MARK,
};
static const unsigned int msiof2_clk_c_pins[] = {
/* SCK */
RCAR_GP_PIN(2, 2),
};
static const unsigned int msiof2_clk_c_mux[] = {
MSIOF2_SCK_C_MARK,
};
static const unsigned int msiof2_sync_c_pins[] = {
/* SYNC */
RCAR_GP_PIN(2, 3),
};
static const unsigned int msiof2_sync_c_mux[] = {
MSIOF2_SYNC_C_MARK,
};
static const unsigned int msiof2_rx_c_pins[] = {
/* RXD */
RCAR_GP_PIN(2, 5),
};
static const unsigned int msiof2_rx_c_mux[] = {
MSIOF2_RXD_C_MARK,
};
static const unsigned int msiof2_tx_c_pins[] = {
/* TXD */
RCAR_GP_PIN(2, 4),
};
static const unsigned int msiof2_tx_c_mux[] = {
MSIOF2_TXD_C_MARK,
};
static const unsigned int msiof2_clk_d_pins[] = {
/* SCK */
RCAR_GP_PIN(2, 14),
};
static const unsigned int msiof2_clk_d_mux[] = {
MSIOF2_SCK_D_MARK,
};
static const unsigned int msiof2_sync_d_pins[] = {
/* SYNC */
RCAR_GP_PIN(2, 15),
};
static const unsigned int msiof2_sync_d_mux[] = {
MSIOF2_SYNC_D_MARK,
};
static const unsigned int msiof2_ss1_d_pins[] = {
/* SS1 */
RCAR_GP_PIN(2, 17),
};
static const unsigned int msiof2_ss1_d_mux[] = {
MSIOF2_SS1_D_MARK,
};
static const unsigned int msiof2_ss2_d_pins[] = {
/* SS2 */
RCAR_GP_PIN(2, 19),
};
static const unsigned int msiof2_ss2_d_mux[] = {
MSIOF2_SS2_D_MARK,
};
static const unsigned int msiof2_rx_d_pins[] = {
/* RXD */
RCAR_GP_PIN(2, 18),
};
static const unsigned int msiof2_rx_d_mux[] = {
MSIOF2_RXD_D_MARK,
};
static const unsigned int msiof2_tx_d_pins[] = {
/* TXD */
RCAR_GP_PIN(2, 16),
};
static const unsigned int msiof2_tx_d_mux[] = {
MSIOF2_TXD_D_MARK,
};
static const unsigned int msiof2_clk_e_pins[] = {
/* SCK */
RCAR_GP_PIN(7, 15),
};
static const unsigned int msiof2_clk_e_mux[] = {
MSIOF2_SCK_E_MARK,
};
static const unsigned int msiof2_sync_e_pins[] = {
/* SYNC */
RCAR_GP_PIN(7, 16),
};
static const unsigned int msiof2_sync_e_mux[] = {
MSIOF2_SYNC_E_MARK,
};
static const unsigned int msiof2_rx_e_pins[] = {
/* RXD */
RCAR_GP_PIN(7, 14),
};
static const unsigned int msiof2_rx_e_mux[] = {
MSIOF2_RXD_E_MARK,
};
static const unsigned int msiof2_tx_e_pins[] = {
/* TXD */
RCAR_GP_PIN(7, 13),
};
static const unsigned int msiof2_tx_e_mux[] = {
MSIOF2_TXD_E_MARK,
};
/* - QSPI ------------------------------------------------------------------- */
static const unsigned int qspi_ctrl_pins[] = {
/* SPCLK, SSL */
RCAR_GP_PIN(1, 4), RCAR_GP_PIN(1, 9),
};
static const unsigned int qspi_ctrl_mux[] = {
SPCLK_MARK, SSL_MARK,
};
static const unsigned int qspi_data2_pins[] = {
/* MOSI_IO0, MISO_IO1 */
RCAR_GP_PIN(1, 5), RCAR_GP_PIN(1, 6),
};
static const unsigned int qspi_data2_mux[] = {
MOSI_IO0_MARK, MISO_IO1_MARK,
};
static const unsigned int qspi_data4_pins[] = {
/* MOSI_IO0, MISO_IO1, IO2, IO3 */
RCAR_GP_PIN(1, 5), RCAR_GP_PIN(1, 6), RCAR_GP_PIN(1, 7),
RCAR_GP_PIN(1, 8),
};
static const unsigned int qspi_data4_mux[] = {
MOSI_IO0_MARK, MISO_IO1_MARK, IO2_MARK, IO3_MARK,
};
static const unsigned int qspi_ctrl_b_pins[] = {
/* SPCLK, SSL */
RCAR_GP_PIN(6, 0), RCAR_GP_PIN(6, 5),
};
static const unsigned int qspi_ctrl_b_mux[] = {
SPCLK_B_MARK, SSL_B_MARK,
};
static const unsigned int qspi_data2_b_pins[] = {
/* MOSI_IO0, MISO_IO1 */
RCAR_GP_PIN(6, 1), RCAR_GP_PIN(6, 2),
};
static const unsigned int qspi_data2_b_mux[] = {
MOSI_IO0_B_MARK, MISO_IO1_B_MARK,
};
static const unsigned int qspi_data4_b_pins[] = {
/* MOSI_IO0, MISO_IO1, IO2, IO3 */
RCAR_GP_PIN(6, 1), RCAR_GP_PIN(6, 2), RCAR_GP_PIN(6, 3),
RCAR_GP_PIN(6, 4),
};
static const unsigned int qspi_data4_b_mux[] = {
SPCLK_B_MARK, MOSI_IO0_B_MARK, MISO_IO1_B_MARK,
IO2_B_MARK, IO3_B_MARK, SSL_B_MARK,
};
/* - SCIF0 ------------------------------------------------------------------ */
static const unsigned int scif0_data_pins[] = {
/* RX, TX */
@ -3125,6 +3583,12 @@ static const struct sh_pfc_pin_group pinmux_groups[] = {
SH_PFC_PIN_GROUP(i2c4),
SH_PFC_PIN_GROUP(i2c4_b),
SH_PFC_PIN_GROUP(i2c4_c),
SH_PFC_PIN_GROUP(i2c7),
SH_PFC_PIN_GROUP(i2c7_b),
SH_PFC_PIN_GROUP(i2c7_c),
SH_PFC_PIN_GROUP(i2c8),
SH_PFC_PIN_GROUP(i2c8_b),
SH_PFC_PIN_GROUP(i2c8_c),
SH_PFC_PIN_GROUP(intc_irq0),
SH_PFC_PIN_GROUP(intc_irq1),
SH_PFC_PIN_GROUP(intc_irq2),
@ -3139,18 +3603,75 @@ static const struct sh_pfc_pin_group pinmux_groups[] = {
SH_PFC_PIN_GROUP(msiof0_ss2),
SH_PFC_PIN_GROUP(msiof0_rx),
SH_PFC_PIN_GROUP(msiof0_tx),
SH_PFC_PIN_GROUP(msiof0_clk_b),
SH_PFC_PIN_GROUP(msiof0_sync_b),
SH_PFC_PIN_GROUP(msiof0_ss1_b),
SH_PFC_PIN_GROUP(msiof0_ss2_b),
SH_PFC_PIN_GROUP(msiof0_rx_b),
SH_PFC_PIN_GROUP(msiof0_tx_b),
SH_PFC_PIN_GROUP(msiof0_clk_c),
SH_PFC_PIN_GROUP(msiof0_sync_c),
SH_PFC_PIN_GROUP(msiof0_ss1_c),
SH_PFC_PIN_GROUP(msiof0_ss2_c),
SH_PFC_PIN_GROUP(msiof0_rx_c),
SH_PFC_PIN_GROUP(msiof0_tx_c),
SH_PFC_PIN_GROUP(msiof1_clk),
SH_PFC_PIN_GROUP(msiof1_sync),
SH_PFC_PIN_GROUP(msiof1_ss1),
SH_PFC_PIN_GROUP(msiof1_ss2),
SH_PFC_PIN_GROUP(msiof1_rx),
SH_PFC_PIN_GROUP(msiof1_tx),
SH_PFC_PIN_GROUP(msiof1_clk_b),
SH_PFC_PIN_GROUP(msiof1_sync_b),
SH_PFC_PIN_GROUP(msiof1_ss1_b),
SH_PFC_PIN_GROUP(msiof1_ss2_b),
SH_PFC_PIN_GROUP(msiof1_rx_b),
SH_PFC_PIN_GROUP(msiof1_tx_b),
SH_PFC_PIN_GROUP(msiof1_clk_c),
SH_PFC_PIN_GROUP(msiof1_sync_c),
SH_PFC_PIN_GROUP(msiof1_rx_c),
SH_PFC_PIN_GROUP(msiof1_tx_c),
SH_PFC_PIN_GROUP(msiof1_clk_d),
SH_PFC_PIN_GROUP(msiof1_sync_d),
SH_PFC_PIN_GROUP(msiof1_ss1_d),
SH_PFC_PIN_GROUP(msiof1_rx_d),
SH_PFC_PIN_GROUP(msiof1_tx_d),
SH_PFC_PIN_GROUP(msiof1_clk_e),
SH_PFC_PIN_GROUP(msiof1_sync_e),
SH_PFC_PIN_GROUP(msiof1_rx_e),
SH_PFC_PIN_GROUP(msiof1_tx_e),
SH_PFC_PIN_GROUP(msiof2_clk),
SH_PFC_PIN_GROUP(msiof2_sync),
SH_PFC_PIN_GROUP(msiof2_ss1),
SH_PFC_PIN_GROUP(msiof2_ss2),
SH_PFC_PIN_GROUP(msiof2_rx),
SH_PFC_PIN_GROUP(msiof2_tx),
SH_PFC_PIN_GROUP(msiof2_clk_b),
SH_PFC_PIN_GROUP(msiof2_sync_b),
SH_PFC_PIN_GROUP(msiof2_ss1_b),
SH_PFC_PIN_GROUP(msiof2_ss2_b),
SH_PFC_PIN_GROUP(msiof2_rx_b),
SH_PFC_PIN_GROUP(msiof2_tx_b),
SH_PFC_PIN_GROUP(msiof2_clk_c),
SH_PFC_PIN_GROUP(msiof2_sync_c),
SH_PFC_PIN_GROUP(msiof2_rx_c),
SH_PFC_PIN_GROUP(msiof2_tx_c),
SH_PFC_PIN_GROUP(msiof2_clk_d),
SH_PFC_PIN_GROUP(msiof2_sync_d),
SH_PFC_PIN_GROUP(msiof2_ss1_d),
SH_PFC_PIN_GROUP(msiof2_ss2_d),
SH_PFC_PIN_GROUP(msiof2_rx_d),
SH_PFC_PIN_GROUP(msiof2_tx_d),
SH_PFC_PIN_GROUP(msiof2_clk_e),
SH_PFC_PIN_GROUP(msiof2_sync_e),
SH_PFC_PIN_GROUP(msiof2_rx_e),
SH_PFC_PIN_GROUP(msiof2_tx_e),
SH_PFC_PIN_GROUP(qspi_ctrl),
SH_PFC_PIN_GROUP(qspi_data2),
SH_PFC_PIN_GROUP(qspi_data4),
SH_PFC_PIN_GROUP(qspi_ctrl_b),
SH_PFC_PIN_GROUP(qspi_data2_b),
SH_PFC_PIN_GROUP(qspi_data4_b),
SH_PFC_PIN_GROUP(scif0_data),
SH_PFC_PIN_GROUP(scif0_data_b),
SH_PFC_PIN_GROUP(scif0_data_c),
@ -3337,6 +3858,18 @@ static const char * const i2c4_groups[] = {
"i2c4_c",
};
static const char * const i2c7_groups[] = {
"i2c7",
"i2c7_b",
"i2c7_c",
};
static const char * const i2c8_groups[] = {
"i2c8",
"i2c8_b",
"i2c8_c",
};
static const char * const intc_groups[] = {
"intc_irq0",
"intc_irq1",
@ -3358,6 +3891,18 @@ static const char * const msiof0_groups[] = {
"msiof0_ss2",
"msiof0_rx",
"msiof0_tx",
"msiof0_clk_b",
"msiof0_sync_b",
"msiof0_ss1_b",
"msiof0_ss2_b",
"msiof0_rx_b",
"msiof0_tx_b",
"msiof0_clk_c",
"msiof0_sync_c",
"msiof0_ss1_c",
"msiof0_ss2_c",
"msiof0_rx_c",
"msiof0_tx_c",
};
static const char * const msiof1_groups[] = {
@ -3367,6 +3912,25 @@ static const char * const msiof1_groups[] = {
"msiof1_ss2",
"msiof1_rx",
"msiof1_tx",
"msiof1_clk_b",
"msiof1_sync_b",
"msiof1_ss1_b",
"msiof1_ss2_b",
"msiof1_rx_b",
"msiof1_tx_b",
"msiof1_clk_c",
"msiof1_sync_c",
"msiof1_rx_c",
"msiof1_tx_c",
"msiof1_clk_d",
"msiof1_sync_d",
"msiof1_ss1_d",
"msiof1_rx_d",
"msiof1_tx_d",
"msiof1_clk_e",
"msiof1_sync_e",
"msiof1_rx_e",
"msiof1_tx_e",
};
static const char * const msiof2_groups[] = {
@ -3376,6 +3940,35 @@ static const char * const msiof2_groups[] = {
"msiof2_ss2",
"msiof2_rx",
"msiof2_tx",
"msiof2_clk_b",
"msiof2_sync_b",
"msiof2_ss1_b",
"msiof2_ss2_b",
"msiof2_rx_b",
"msiof2_tx_b",
"msiof2_clk_c",
"msiof2_sync_c",
"msiof2_rx_c",
"msiof2_tx_c",
"msiof2_clk_d",
"msiof2_sync_d",
"msiof2_ss1_d",
"msiof2_ss2_d",
"msiof2_rx_d",
"msiof2_tx_d",
"msiof2_clk_e",
"msiof2_sync_e",
"msiof2_rx_e",
"msiof2_tx_e",
};
static const char * const qspi_groups[] = {
"qspi_ctrl",
"qspi_data2",
"qspi_data4",
"qspi_ctrl_b",
"qspi_data2_b",
"qspi_data4_b",
};
static const char * const scif0_groups[] = {
@ -3568,11 +4161,14 @@ static const struct sh_pfc_function pinmux_functions[] = {
SH_PFC_FUNCTION(i2c2),
SH_PFC_FUNCTION(i2c3),
SH_PFC_FUNCTION(i2c4),
SH_PFC_FUNCTION(i2c7),
SH_PFC_FUNCTION(i2c8),
SH_PFC_FUNCTION(intc),
SH_PFC_FUNCTION(mmc),
SH_PFC_FUNCTION(msiof0),
SH_PFC_FUNCTION(msiof1),
SH_PFC_FUNCTION(msiof2),
SH_PFC_FUNCTION(qspi),
SH_PFC_FUNCTION(scif0),
SH_PFC_FUNCTION(scif1),
SH_PFC_FUNCTION(scif2),

View file

@ -1,7 +1,8 @@
/*
* pinctrl pads, groups, functions for CSR SiRFatlasVI
*
* Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
* Copyright (c) 2011 - 2014 Cambridge Silicon Radio Limited, a CSR plc group
* company.
*
* Licensed under GPLv2 or later.
*/
@ -529,6 +530,40 @@ static const struct sirfsoc_padmux usp0_padmux = {
static const unsigned usp0_pins[] = { 51, 52, 53, 54, 55 };
static const struct sirfsoc_muxmask usp0_only_utfs_muxmask[] = {
{
.group = 1,
.mask = BIT(19) | BIT(20) | BIT(21) | BIT(22),
},
};
static const struct sirfsoc_padmux usp0_only_utfs_padmux = {
.muxmask_counts = ARRAY_SIZE(usp0_only_utfs_muxmask),
.muxmask = usp0_only_utfs_muxmask,
.ctrlreg = SIRFSOC_RSC_PIN_MUX,
.funcmask = BIT(1) | BIT(2) | BIT(6),
.funcval = 0,
};
static const unsigned usp0_only_utfs_pins[] = { 51, 52, 53, 54 };
static const struct sirfsoc_muxmask usp0_only_urfs_muxmask[] = {
{
.group = 1,
.mask = BIT(19) | BIT(20) | BIT(21) | BIT(23),
},
};
static const struct sirfsoc_padmux usp0_only_urfs_padmux = {
.muxmask_counts = ARRAY_SIZE(usp0_only_urfs_muxmask),
.muxmask = usp0_only_urfs_muxmask,
.ctrlreg = SIRFSOC_RSC_PIN_MUX,
.funcmask = BIT(1) | BIT(2) | BIT(9),
.funcval = 0,
};
static const unsigned usp0_only_urfs_pins[] = { 51, 52, 53, 55 };
static const struct sirfsoc_muxmask usp0_uart_nostreamctrl_muxmask[] = {
{
.group = 1,
@ -905,6 +940,8 @@ static const struct sirfsoc_pin_group sirfsoc_pin_groups[] = {
SIRFSOC_PIN_GROUP("usp0grp", usp0_pins),
SIRFSOC_PIN_GROUP("usp0_uart_nostreamctrl_grp",
usp0_uart_nostreamctrl_pins),
SIRFSOC_PIN_GROUP("usp0_only_utfs_grp", usp0_only_utfs_pins),
SIRFSOC_PIN_GROUP("usp0_only_urfs_grp", usp0_only_urfs_pins),
SIRFSOC_PIN_GROUP("usp1grp", usp1_pins),
SIRFSOC_PIN_GROUP("usp1_uart_nostreamctrl_grp",
usp1_uart_nostreamctrl_pins),
@ -953,6 +990,9 @@ static const char * const uart2_nostreamctrlgrp[] = { "uart2_nostreamctrlgrp" };
static const char * const usp0_uart_nostreamctrl_grp[] = {
"usp0_uart_nostreamctrl_grp" };
static const char * const usp0grp[] = { "usp0grp" };
static const char * const usp0_only_utfs_grp[] = { "usp0_only_utfs_grp" };
static const char * const usp0_only_urfs_grp[] = { "usp0_only_urfs_grp" };
static const char * const usp1grp[] = { "usp1grp" };
static const char * const usp1_uart_nostreamctrl_grp[] = {
"usp1_uart_nostreamctrl_grp" };
@ -1003,6 +1043,10 @@ static const struct sirfsoc_pmx_func sirfsoc_pmx_functions[] = {
SIRFSOC_PMX_FUNCTION("usp0_uart_nostreamctrl",
usp0_uart_nostreamctrl_grp,
usp0_uart_nostreamctrl_padmux),
SIRFSOC_PMX_FUNCTION("usp0_only_utfs", usp0_only_utfs_grp,
usp0_only_utfs_padmux),
SIRFSOC_PMX_FUNCTION("usp0_only_urfs", usp0_only_urfs_grp,
usp0_only_urfs_padmux),
SIRFSOC_PMX_FUNCTION("usp1", usp1grp, usp1_padmux),
SIRFSOC_PMX_FUNCTION("usp1_uart_nostreamctrl",
usp1_uart_nostreamctrl_grp,

View file

@ -1,7 +1,8 @@
/*
* pinctrl pads, groups, functions for CSR SiRFprimaII
*
* Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
* Copyright (c) 2011 - 2014 Cambridge Silicon Radio Limited, a CSR plc group
* company.
*
* Licensed under GPLv2 or later.
*/

View file

@ -1,7 +1,8 @@
/*
* pinmux driver for CSR SiRFprimaII
*
* Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
* Copyright (c) 2011 - 2014 Cambridge Silicon Radio Limited, a CSR plc group
* company.
*
* Licensed under GPLv2 or later.
*/