162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Marvell Armada ap806 pinctrl driver based on mvebu pinctrl core
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (C) 2017 Marvell
662306a36Sopenharmony_ci *
762306a36Sopenharmony_ci * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
862306a36Sopenharmony_ci * Hanna Hawa <hannah@marvell.com>
962306a36Sopenharmony_ci */
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#include <linux/err.h>
1262306a36Sopenharmony_ci#include <linux/init.h>
1362306a36Sopenharmony_ci#include <linux/io.h>
1462306a36Sopenharmony_ci#include <linux/platform_device.h>
1562306a36Sopenharmony_ci#include <linux/of.h>
1662306a36Sopenharmony_ci#include <linux/of_device.h>
1762306a36Sopenharmony_ci#include <linux/pinctrl/pinctrl.h>
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci#include "pinctrl-mvebu.h"
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_cistatic struct mvebu_mpp_mode armada_ap806_mpp_modes[] = {
2262306a36Sopenharmony_ci	MPP_MODE(0,
2362306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",    NULL),
2462306a36Sopenharmony_ci		 MPP_FUNCTION(1, "sdio",    "clk"),
2562306a36Sopenharmony_ci		 MPP_FUNCTION(3, "spi0",    "clk")),
2662306a36Sopenharmony_ci	MPP_MODE(1,
2762306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",    NULL),
2862306a36Sopenharmony_ci		 MPP_FUNCTION(1, "sdio",    "cmd"),
2962306a36Sopenharmony_ci		 MPP_FUNCTION(3, "spi0",    "miso")),
3062306a36Sopenharmony_ci	MPP_MODE(2,
3162306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",    NULL),
3262306a36Sopenharmony_ci		 MPP_FUNCTION(1, "sdio",    "d0"),
3362306a36Sopenharmony_ci		 MPP_FUNCTION(3, "spi0",    "mosi")),
3462306a36Sopenharmony_ci	MPP_MODE(3,
3562306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",    NULL),
3662306a36Sopenharmony_ci		 MPP_FUNCTION(1, "sdio",    "d1"),
3762306a36Sopenharmony_ci		 MPP_FUNCTION(3, "spi0",    "cs0n")),
3862306a36Sopenharmony_ci	MPP_MODE(4,
3962306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",    NULL),
4062306a36Sopenharmony_ci		 MPP_FUNCTION(1, "sdio",    "d2"),
4162306a36Sopenharmony_ci		 MPP_FUNCTION(3, "i2c0",    "sda")),
4262306a36Sopenharmony_ci	MPP_MODE(5,
4362306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",    NULL),
4462306a36Sopenharmony_ci		 MPP_FUNCTION(1, "sdio",    "d3"),
4562306a36Sopenharmony_ci		 MPP_FUNCTION(3, "i2c0",    "sdk")),
4662306a36Sopenharmony_ci	MPP_MODE(6,
4762306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",    NULL),
4862306a36Sopenharmony_ci		 MPP_FUNCTION(1, "sdio",    "ds")),
4962306a36Sopenharmony_ci	MPP_MODE(7,
5062306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",    NULL),
5162306a36Sopenharmony_ci		 MPP_FUNCTION(1, "sdio",    "d4"),
5262306a36Sopenharmony_ci		 MPP_FUNCTION(3, "uart1",   "rxd")),
5362306a36Sopenharmony_ci	MPP_MODE(8,
5462306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",    NULL),
5562306a36Sopenharmony_ci		 MPP_FUNCTION(1, "sdio",    "d5"),
5662306a36Sopenharmony_ci		 MPP_FUNCTION(3, "uart1",   "txd")),
5762306a36Sopenharmony_ci	MPP_MODE(9,
5862306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",    NULL),
5962306a36Sopenharmony_ci		 MPP_FUNCTION(1, "sdio",    "d6"),
6062306a36Sopenharmony_ci		 MPP_FUNCTION(3, "spi0",    "cs1n")),
6162306a36Sopenharmony_ci	MPP_MODE(10,
6262306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",    NULL),
6362306a36Sopenharmony_ci		 MPP_FUNCTION(1, "sdio",    "d7")),
6462306a36Sopenharmony_ci	MPP_MODE(11,
6562306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",    NULL),
6662306a36Sopenharmony_ci		 MPP_FUNCTION(3, "uart0",   "txd")),
6762306a36Sopenharmony_ci	MPP_MODE(12,
6862306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",    NULL),
6962306a36Sopenharmony_ci		 MPP_FUNCTION(1, "sdio",    "pw_off"),
7062306a36Sopenharmony_ci		 MPP_FUNCTION(2, "sdio",    "hw_rst")),
7162306a36Sopenharmony_ci	MPP_MODE(13,
7262306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",    NULL)),
7362306a36Sopenharmony_ci	MPP_MODE(14,
7462306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",    NULL)),
7562306a36Sopenharmony_ci	MPP_MODE(15,
7662306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",    NULL)),
7762306a36Sopenharmony_ci	MPP_MODE(16,
7862306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",    NULL)),
7962306a36Sopenharmony_ci	MPP_MODE(17,
8062306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",    NULL)),
8162306a36Sopenharmony_ci	MPP_MODE(18,
8262306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",    NULL)),
8362306a36Sopenharmony_ci	MPP_MODE(19,
8462306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",    NULL),
8562306a36Sopenharmony_ci		 MPP_FUNCTION(3, "uart0",   "rxd"),
8662306a36Sopenharmony_ci		 MPP_FUNCTION(4, "sdio",    "pw_off")),
8762306a36Sopenharmony_ci};
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_cistatic struct mvebu_pinctrl_soc_info armada_ap806_pinctrl_info;
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_cistatic const struct of_device_id armada_ap806_pinctrl_of_match[] = {
9262306a36Sopenharmony_ci	{
9362306a36Sopenharmony_ci		.compatible = "marvell,ap806-pinctrl",
9462306a36Sopenharmony_ci	},
9562306a36Sopenharmony_ci	{ },
9662306a36Sopenharmony_ci};
9762306a36Sopenharmony_ci
9862306a36Sopenharmony_cistatic const struct mvebu_mpp_ctrl armada_ap806_mpp_controls[] = {
9962306a36Sopenharmony_ci	MPP_FUNC_CTRL(0, 19, NULL, mvebu_regmap_mpp_ctrl),
10062306a36Sopenharmony_ci};
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_cistatic struct pinctrl_gpio_range armada_ap806_mpp_gpio_ranges[] = {
10362306a36Sopenharmony_ci	MPP_GPIO_RANGE(0,   0,  0, 20),
10462306a36Sopenharmony_ci};
10562306a36Sopenharmony_ci
10662306a36Sopenharmony_cistatic int armada_ap806_pinctrl_probe(struct platform_device *pdev)
10762306a36Sopenharmony_ci{
10862306a36Sopenharmony_ci	struct mvebu_pinctrl_soc_info *soc = &armada_ap806_pinctrl_info;
10962306a36Sopenharmony_ci	const struct of_device_id *match =
11062306a36Sopenharmony_ci		of_match_device(armada_ap806_pinctrl_of_match, &pdev->dev);
11162306a36Sopenharmony_ci
11262306a36Sopenharmony_ci	if (!match || !pdev->dev.parent)
11362306a36Sopenharmony_ci		return -ENODEV;
11462306a36Sopenharmony_ci
11562306a36Sopenharmony_ci	soc->variant = 0; /* no variants for Armada AP806 */
11662306a36Sopenharmony_ci	soc->controls = armada_ap806_mpp_controls;
11762306a36Sopenharmony_ci	soc->ncontrols = ARRAY_SIZE(armada_ap806_mpp_controls);
11862306a36Sopenharmony_ci	soc->gpioranges = armada_ap806_mpp_gpio_ranges;
11962306a36Sopenharmony_ci	soc->ngpioranges = ARRAY_SIZE(armada_ap806_mpp_gpio_ranges);
12062306a36Sopenharmony_ci	soc->modes = armada_ap806_mpp_modes;
12162306a36Sopenharmony_ci	soc->nmodes = armada_ap806_mpp_controls[0].npins;
12262306a36Sopenharmony_ci
12362306a36Sopenharmony_ci	pdev->dev.platform_data = soc;
12462306a36Sopenharmony_ci
12562306a36Sopenharmony_ci	return mvebu_pinctrl_simple_regmap_probe(pdev, pdev->dev.parent, 0);
12662306a36Sopenharmony_ci}
12762306a36Sopenharmony_ci
12862306a36Sopenharmony_cistatic struct platform_driver armada_ap806_pinctrl_driver = {
12962306a36Sopenharmony_ci	.driver = {
13062306a36Sopenharmony_ci		.name = "armada-ap806-pinctrl",
13162306a36Sopenharmony_ci		.of_match_table = of_match_ptr(armada_ap806_pinctrl_of_match),
13262306a36Sopenharmony_ci	},
13362306a36Sopenharmony_ci	.probe = armada_ap806_pinctrl_probe,
13462306a36Sopenharmony_ci};
13562306a36Sopenharmony_ci
13662306a36Sopenharmony_cibuiltin_platform_driver(armada_ap806_pinctrl_driver);
137