linux-stable/drivers/pinctrl/mvebu/pinctrl-armada-370.c
Sebastian Hesselbarth 1217b790ae pinctrl: mvebu: move resource allocation to SoC specific drivers
The way that mvebu pinctrl is designed, requesting mpp registers
in common pinctrl driver does not allow SoC specific drivers to
access this resource.

Move resource allocation in each SoC pinctrl driver and enable
already provided mpp_{set,get} callbacks.

Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Tested-by: Andrew Lunn <andrew@lunn.ch>
Tested-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
2014-02-25 18:37:53 +01:00

439 lines
14 KiB
C

/*
* Marvell Armada 370 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_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),
MPP_FUNCTION(0x1, "uart0", "rxd")),
MPP_MODE(1,
MPP_FUNCTION(0x0, "gpo", NULL),
MPP_FUNCTION(0x1, "uart0", "txd")),
MPP_MODE(2,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "i2c0", "sck"),
MPP_FUNCTION(0x2, "uart0", "txd")),
MPP_MODE(3,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "i2c0", "sda"),
MPP_FUNCTION(0x2, "uart0", "rxd")),
MPP_MODE(4,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "cpu_pd", "vdd")),
MPP_MODE(5,
MPP_FUNCTION(0x0, "gpo", NULL),
MPP_FUNCTION(0x1, "ge0", "txclko"),
MPP_FUNCTION(0x2, "uart1", "txd"),
MPP_FUNCTION(0x4, "spi1", "clk"),
MPP_FUNCTION(0x5, "audio", "mclk")),
MPP_MODE(6,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "ge0", "txd0"),
MPP_FUNCTION(0x2, "sata0", "prsnt"),
MPP_FUNCTION(0x4, "tdm", "rst"),
MPP_FUNCTION(0x5, "audio", "sdo")),
MPP_MODE(7,
MPP_FUNCTION(0x0, "gpo", NULL),
MPP_FUNCTION(0x1, "ge0", "txd1"),
MPP_FUNCTION(0x4, "tdm", "tdx"),
MPP_FUNCTION(0x5, "audio", "lrclk")),
MPP_MODE(8,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "ge0", "txd2"),
MPP_FUNCTION(0x2, "uart0", "rts"),
MPP_FUNCTION(0x4, "tdm", "drx"),
MPP_FUNCTION(0x5, "audio", "bclk")),
MPP_MODE(9,
MPP_FUNCTION(0x0, "gpo", NULL),
MPP_FUNCTION(0x1, "ge0", "txd3"),
MPP_FUNCTION(0x2, "uart1", "txd"),
MPP_FUNCTION(0x3, "sd0", "clk"),
MPP_FUNCTION(0x5, "audio", "spdifo")),
MPP_MODE(10,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "ge0", "txctl"),
MPP_FUNCTION(0x2, "uart0", "cts"),
MPP_FUNCTION(0x4, "tdm", "fsync"),
MPP_FUNCTION(0x5, "audio", "sdi")),
MPP_MODE(11,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "ge0", "rxd0"),
MPP_FUNCTION(0x2, "uart1", "rxd"),
MPP_FUNCTION(0x3, "sd0", "cmd"),
MPP_FUNCTION(0x4, "spi0", "cs1"),
MPP_FUNCTION(0x5, "sata1", "prsnt"),
MPP_FUNCTION(0x6, "spi1", "cs1")),
MPP_MODE(12,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "ge0", "rxd1"),
MPP_FUNCTION(0x2, "i2c1", "sda"),
MPP_FUNCTION(0x3, "sd0", "d0"),
MPP_FUNCTION(0x4, "spi1", "cs0"),
MPP_FUNCTION(0x5, "audio", "spdifi")),
MPP_MODE(13,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "ge0", "rxd2"),
MPP_FUNCTION(0x2, "i2c1", "sck"),
MPP_FUNCTION(0x3, "sd0", "d1"),
MPP_FUNCTION(0x4, "tdm", "pclk"),
MPP_FUNCTION(0x5, "audio", "rmclk")),
MPP_MODE(14,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "ge0", "rxd3"),
MPP_FUNCTION(0x2, "pcie", "clkreq0"),
MPP_FUNCTION(0x3, "sd0", "d2"),
MPP_FUNCTION(0x4, "spi1", "mosi"),
MPP_FUNCTION(0x5, "spi0", "cs2")),
MPP_MODE(15,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "ge0", "rxctl"),
MPP_FUNCTION(0x2, "pcie", "clkreq1"),
MPP_FUNCTION(0x3, "sd0", "d3"),
MPP_FUNCTION(0x4, "spi1", "miso"),
MPP_FUNCTION(0x5, "spi0", "cs3")),
MPP_MODE(16,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "ge0", "rxclk"),
MPP_FUNCTION(0x2, "uart1", "rxd"),
MPP_FUNCTION(0x4, "tdm", "int"),
MPP_FUNCTION(0x5, "audio", "extclk")),
MPP_MODE(17,
MPP_FUNCTION(0x0, "gpo", NULL),
MPP_FUNCTION(0x1, "ge", "mdc")),
MPP_MODE(18,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "ge", "mdio")),
MPP_MODE(19,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "ge0", "txclk"),
MPP_FUNCTION(0x2, "ge1", "txclkout"),
MPP_FUNCTION(0x4, "tdm", "pclk")),
MPP_MODE(20,
MPP_FUNCTION(0x0, "gpo", NULL),
MPP_FUNCTION(0x1, "ge0", "txd4"),
MPP_FUNCTION(0x2, "ge1", "txd0")),
MPP_MODE(21,
MPP_FUNCTION(0x0, "gpo", NULL),
MPP_FUNCTION(0x1, "ge0", "txd5"),
MPP_FUNCTION(0x2, "ge1", "txd1"),
MPP_FUNCTION(0x4, "uart1", "txd")),
MPP_MODE(22,
MPP_FUNCTION(0x0, "gpo", NULL),
MPP_FUNCTION(0x1, "ge0", "txd6"),
MPP_FUNCTION(0x2, "ge1", "txd2"),
MPP_FUNCTION(0x4, "uart0", "rts")),
MPP_MODE(23,
MPP_FUNCTION(0x0, "gpo", NULL),
MPP_FUNCTION(0x1, "ge0", "txd7"),
MPP_FUNCTION(0x2, "ge1", "txd3"),
MPP_FUNCTION(0x4, "spi1", "mosi")),
MPP_MODE(24,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "ge0", "col"),
MPP_FUNCTION(0x2, "ge1", "txctl"),
MPP_FUNCTION(0x4, "spi1", "cs0")),
MPP_MODE(25,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "ge0", "rxerr"),
MPP_FUNCTION(0x2, "ge1", "rxd0"),
MPP_FUNCTION(0x4, "uart1", "rxd")),
MPP_MODE(26,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "ge0", "crs"),
MPP_FUNCTION(0x2, "ge1", "rxd1"),
MPP_FUNCTION(0x4, "spi1", "miso")),
MPP_MODE(27,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "ge0", "rxd4"),
MPP_FUNCTION(0x2, "ge1", "rxd2"),
MPP_FUNCTION(0x4, "uart0", "cts")),
MPP_MODE(28,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "ge0", "rxd5"),
MPP_FUNCTION(0x2, "ge1", "rxd3")),
MPP_MODE(29,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "ge0", "rxd6"),
MPP_FUNCTION(0x2, "ge1", "rxctl"),
MPP_FUNCTION(0x4, "i2c1", "sda")),
MPP_MODE(30,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "ge0", "rxd7"),
MPP_FUNCTION(0x2, "ge1", "rxclk"),
MPP_FUNCTION(0x4, "i2c1", "sck")),
MPP_MODE(31,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x3, "tclk", NULL),
MPP_FUNCTION(0x4, "ge0", "txerr")),
MPP_MODE(32,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "spi0", "cs0")),
MPP_MODE(33,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "dev", "bootcs"),
MPP_FUNCTION(0x2, "spi0", "cs0")),
MPP_MODE(34,
MPP_FUNCTION(0x0, "gpo", NULL),
MPP_FUNCTION(0x1, "dev", "wen0"),
MPP_FUNCTION(0x2, "spi0", "mosi")),
MPP_MODE(35,
MPP_FUNCTION(0x0, "gpo", NULL),
MPP_FUNCTION(0x1, "dev", "oen"),
MPP_FUNCTION(0x2, "spi0", "sck")),
MPP_MODE(36,
MPP_FUNCTION(0x0, "gpo", NULL),
MPP_FUNCTION(0x1, "dev", "a1"),
MPP_FUNCTION(0x2, "spi0", "miso")),
MPP_MODE(37,
MPP_FUNCTION(0x0, "gpo", NULL),
MPP_FUNCTION(0x1, "dev", "a0"),
MPP_FUNCTION(0x2, "sata0", "prsnt")),
MPP_MODE(38,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "dev", "ready"),
MPP_FUNCTION(0x2, "uart1", "cts"),
MPP_FUNCTION(0x3, "uart0", "cts")),
MPP_MODE(39,
MPP_FUNCTION(0x0, "gpo", NULL),
MPP_FUNCTION(0x1, "dev", "ad0"),
MPP_FUNCTION(0x2, "audio", "spdifo")),
MPP_MODE(40,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "dev", "ad1"),
MPP_FUNCTION(0x2, "uart1", "rts"),
MPP_FUNCTION(0x3, "uart0", "rts")),
MPP_MODE(41,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "dev", "ad2"),
MPP_FUNCTION(0x2, "uart1", "rxd")),
MPP_MODE(42,
MPP_FUNCTION(0x0, "gpo", NULL),
MPP_FUNCTION(0x1, "dev", "ad3"),
MPP_FUNCTION(0x2, "uart1", "txd")),
MPP_MODE(43,
MPP_FUNCTION(0x0, "gpo", NULL),
MPP_FUNCTION(0x1, "dev", "ad4"),
MPP_FUNCTION(0x2, "audio", "bclk")),
MPP_MODE(44,
MPP_FUNCTION(0x0, "gpo", NULL),
MPP_FUNCTION(0x1, "dev", "ad5"),
MPP_FUNCTION(0x2, "audio", "mclk")),
MPP_MODE(45,
MPP_FUNCTION(0x0, "gpo", NULL),
MPP_FUNCTION(0x1, "dev", "ad6"),
MPP_FUNCTION(0x2, "audio", "lrclk")),
MPP_MODE(46,
MPP_FUNCTION(0x0, "gpo", NULL),
MPP_FUNCTION(0x1, "dev", "ad7"),
MPP_FUNCTION(0x2, "audio", "sdo")),
MPP_MODE(47,
MPP_FUNCTION(0x0, "gpo", NULL),
MPP_FUNCTION(0x1, "dev", "ad8"),
MPP_FUNCTION(0x3, "sd0", "clk"),
MPP_FUNCTION(0x5, "audio", "spdifo")),
MPP_MODE(48,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "dev", "ad9"),
MPP_FUNCTION(0x2, "uart0", "rts"),
MPP_FUNCTION(0x3, "sd0", "cmd"),
MPP_FUNCTION(0x4, "sata1", "prsnt"),
MPP_FUNCTION(0x5, "spi0", "cs1")),
MPP_MODE(49,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "dev", "ad10"),
MPP_FUNCTION(0x2, "pcie", "clkreq1"),
MPP_FUNCTION(0x3, "sd0", "d0"),
MPP_FUNCTION(0x4, "spi1", "cs0"),
MPP_FUNCTION(0x5, "audio", "spdifi")),
MPP_MODE(50,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "dev", "ad11"),
MPP_FUNCTION(0x2, "uart0", "cts"),
MPP_FUNCTION(0x3, "sd0", "d1"),
MPP_FUNCTION(0x4, "spi1", "miso"),
MPP_FUNCTION(0x5, "audio", "rmclk")),
MPP_MODE(51,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "dev", "ad12"),
MPP_FUNCTION(0x2, "i2c1", "sda"),
MPP_FUNCTION(0x3, "sd0", "d2"),
MPP_FUNCTION(0x4, "spi1", "mosi")),
MPP_MODE(52,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "dev", "ad13"),
MPP_FUNCTION(0x2, "i2c1", "sck"),
MPP_FUNCTION(0x3, "sd0", "d3"),
MPP_FUNCTION(0x4, "spi1", "sck")),
MPP_MODE(53,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "dev", "ad14"),
MPP_FUNCTION(0x2, "sd0", "clk"),
MPP_FUNCTION(0x3, "tdm", "pclk"),
MPP_FUNCTION(0x4, "spi0", "cs2"),
MPP_FUNCTION(0x5, "pcie", "clkreq1")),
MPP_MODE(54,
MPP_FUNCTION(0x0, "gpo", NULL),
MPP_FUNCTION(0x1, "dev", "ad15"),
MPP_FUNCTION(0x3, "tdm", "dtx")),
MPP_MODE(55,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "dev", "cs1"),
MPP_FUNCTION(0x2, "uart1", "txd"),
MPP_FUNCTION(0x3, "tdm", "rst"),
MPP_FUNCTION(0x4, "sata1", "prsnt"),
MPP_FUNCTION(0x5, "sata0", "prsnt")),
MPP_MODE(56,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "dev", "cs2"),
MPP_FUNCTION(0x2, "uart1", "cts"),
MPP_FUNCTION(0x3, "uart0", "cts"),
MPP_FUNCTION(0x4, "spi0", "cs3"),
MPP_FUNCTION(0x5, "pcie", "clkreq0"),
MPP_FUNCTION(0x6, "spi1", "cs1")),
MPP_MODE(57,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "dev", "cs3"),
MPP_FUNCTION(0x2, "uart1", "rxd"),
MPP_FUNCTION(0x3, "tdm", "fsync"),
MPP_FUNCTION(0x4, "sata0", "prsnt"),
MPP_FUNCTION(0x5, "audio", "sdo")),
MPP_MODE(58,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "dev", "cs0"),
MPP_FUNCTION(0x2, "uart1", "rts"),
MPP_FUNCTION(0x3, "tdm", "int"),
MPP_FUNCTION(0x5, "audio", "extclk"),
MPP_FUNCTION(0x6, "uart0", "rts")),
MPP_MODE(59,
MPP_FUNCTION(0x0, "gpo", NULL),
MPP_FUNCTION(0x1, "dev", "ale0"),
MPP_FUNCTION(0x2, "uart1", "rts"),
MPP_FUNCTION(0x3, "uart0", "rts"),
MPP_FUNCTION(0x5, "audio", "bclk")),
MPP_MODE(60,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "dev", "ale1"),
MPP_FUNCTION(0x2, "uart1", "rxd"),
MPP_FUNCTION(0x3, "sata0", "prsnt"),
MPP_FUNCTION(0x4, "pcie", "rst-out"),
MPP_FUNCTION(0x5, "audio", "sdi")),
MPP_MODE(61,
MPP_FUNCTION(0x0, "gpo", NULL),
MPP_FUNCTION(0x1, "dev", "wen1"),
MPP_FUNCTION(0x2, "uart1", "txd"),
MPP_FUNCTION(0x5, "audio", "rclk")),
MPP_MODE(62,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "dev", "a2"),
MPP_FUNCTION(0x2, "uart1", "cts"),
MPP_FUNCTION(0x3, "tdm", "drx"),
MPP_FUNCTION(0x4, "pcie", "clkreq0"),
MPP_FUNCTION(0x5, "audio", "mclk"),
MPP_FUNCTION(0x6, "uart0", "cts")),
MPP_MODE(63,
MPP_FUNCTION(0x0, "gpo", NULL),
MPP_FUNCTION(0x1, "spi0", "sck"),
MPP_FUNCTION(0x2, "tclk", NULL)),
MPP_MODE(64,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "spi0", "miso"),
MPP_FUNCTION(0x2, "spi0-1", "cs1")),
MPP_MODE(65,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "spi0", "mosi"),
MPP_FUNCTION(0x2, "spi0-1", "cs2")),
};
static struct mvebu_pinctrl_soc_info armada_370_pinctrl_info;
static struct of_device_id armada_370_pinctrl_of_match[] = {
{ .compatible = "marvell,mv88f6710-pinctrl" },
{ },
};
static struct mvebu_mpp_ctrl mv88f6710_mpp_controls[] = {
MPP_FUNC_CTRL(0, 65, NULL, armada_370_mpp_ctrl),
};
static struct pinctrl_gpio_range mv88f6710_mpp_gpio_ranges[] = {
MPP_GPIO_RANGE(0, 0, 0, 32),
MPP_GPIO_RANGE(1, 32, 32, 32),
MPP_GPIO_RANGE(2, 64, 64, 2),
};
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;
soc->ncontrols = ARRAY_SIZE(mv88f6710_mpp_controls);
soc->modes = mv88f6710_mpp_modes;
soc->nmodes = ARRAY_SIZE(mv88f6710_mpp_modes);
soc->gpioranges = mv88f6710_mpp_gpio_ranges;
soc->ngpioranges = ARRAY_SIZE(mv88f6710_mpp_gpio_ranges);
pdev->dev.platform_data = soc;
return mvebu_pinctrl_probe(pdev);
}
static int armada_370_pinctrl_remove(struct platform_device *pdev)
{
return mvebu_pinctrl_remove(pdev);
}
static struct platform_driver armada_370_pinctrl_driver = {
.driver = {
.name = "armada-370-pinctrl",
.owner = THIS_MODULE,
.of_match_table = armada_370_pinctrl_of_match,
},
.probe = armada_370_pinctrl_probe,
.remove = armada_370_pinctrl_remove,
};
module_platform_driver(armada_370_pinctrl_driver);
MODULE_AUTHOR("Thomas Petazzoni <thomas.petazzoni@free-electrons.com>");
MODULE_DESCRIPTION("Marvell Armada 370 pinctrl driver");
MODULE_LICENSE("GPL v2");