162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Marvell ac5 pinctrl driver based on mvebu pinctrl core
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (C) 2021 Marvell
662306a36Sopenharmony_ci *
762306a36Sopenharmony_ci * Noam Liron <lnoam@marvell.com>
862306a36Sopenharmony_ci */
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#include <linux/err.h>
1162306a36Sopenharmony_ci#include <linux/init.h>
1262306a36Sopenharmony_ci#include <linux/io.h>
1362306a36Sopenharmony_ci#include <linux/platform_device.h>
1462306a36Sopenharmony_ci#include <linux/of.h>
1562306a36Sopenharmony_ci#include <linux/pinctrl/pinctrl.h>
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci#include "pinctrl-mvebu.h"
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_cistatic struct mvebu_mpp_mode ac5_mpp_modes[] = {
2062306a36Sopenharmony_ci	MPP_MODE(0,
2162306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",  NULL),
2262306a36Sopenharmony_ci		 MPP_FUNCTION(1, "sdio",  "d0"),
2362306a36Sopenharmony_ci		 MPP_FUNCTION(2, "nand",  "io4")),
2462306a36Sopenharmony_ci	MPP_MODE(1,
2562306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",  NULL),
2662306a36Sopenharmony_ci		 MPP_FUNCTION(1, "sdio",  "d1"),
2762306a36Sopenharmony_ci		 MPP_FUNCTION(2, "nand",  "io3")),
2862306a36Sopenharmony_ci	MPP_MODE(2,
2962306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",  NULL),
3062306a36Sopenharmony_ci		 MPP_FUNCTION(1, "sdio",  "d2"),
3162306a36Sopenharmony_ci		 MPP_FUNCTION(2, "nand",  "io2")),
3262306a36Sopenharmony_ci	MPP_MODE(3,
3362306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",  NULL),
3462306a36Sopenharmony_ci		 MPP_FUNCTION(1, "sdio",  "d3"),
3562306a36Sopenharmony_ci		 MPP_FUNCTION(2, "nand",  "io7")),
3662306a36Sopenharmony_ci	MPP_MODE(4,
3762306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",  NULL),
3862306a36Sopenharmony_ci		 MPP_FUNCTION(1, "sdio",  "d4"),
3962306a36Sopenharmony_ci		 MPP_FUNCTION(2, "nand",  "io6"),
4062306a36Sopenharmony_ci		 MPP_FUNCTION(3, "uart3", "txd"),
4162306a36Sopenharmony_ci		 MPP_FUNCTION(4, "uart2", "txd")),
4262306a36Sopenharmony_ci	MPP_MODE(5,
4362306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",  NULL),
4462306a36Sopenharmony_ci		 MPP_FUNCTION(1, "sdio",  "d5"),
4562306a36Sopenharmony_ci		 MPP_FUNCTION(2, "nand",  "io5"),
4662306a36Sopenharmony_ci		 MPP_FUNCTION(3, "uart3", "rxd"),
4762306a36Sopenharmony_ci		 MPP_FUNCTION(4, "uart2", "rxd")),
4862306a36Sopenharmony_ci	MPP_MODE(6,
4962306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",  NULL),
5062306a36Sopenharmony_ci		 MPP_FUNCTION(1, "sdio",  "d6"),
5162306a36Sopenharmony_ci		 MPP_FUNCTION(2, "nand",  "io0"),
5262306a36Sopenharmony_ci		 MPP_FUNCTION(3, "i2c1",  "sck")),
5362306a36Sopenharmony_ci	MPP_MODE(7,
5462306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",  NULL),
5562306a36Sopenharmony_ci		 MPP_FUNCTION(1, "sdio",  "d7"),
5662306a36Sopenharmony_ci		 MPP_FUNCTION(2, "nand",  "io1"),
5762306a36Sopenharmony_ci		 MPP_FUNCTION(3, "i2c1",  "sda")),
5862306a36Sopenharmony_ci	MPP_MODE(8,
5962306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",  NULL),
6062306a36Sopenharmony_ci		 MPP_FUNCTION(1, "sdio",  "clk"),
6162306a36Sopenharmony_ci		 MPP_FUNCTION(2, "nand",  "wen")),
6262306a36Sopenharmony_ci	MPP_MODE(9,
6362306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",  NULL),
6462306a36Sopenharmony_ci		 MPP_FUNCTION(1, "sdio",  "cmd"),
6562306a36Sopenharmony_ci		 MPP_FUNCTION(2, "nand",  "ale")),
6662306a36Sopenharmony_ci	MPP_MODE(10,
6762306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",  NULL),
6862306a36Sopenharmony_ci		 MPP_FUNCTION(1, "sdio",  "ds"),
6962306a36Sopenharmony_ci		 MPP_FUNCTION(2, "nand",  "cle")),
7062306a36Sopenharmony_ci	MPP_MODE(11,
7162306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",  NULL),
7262306a36Sopenharmony_ci		 MPP_FUNCTION(1, "sdio",  "rst"),
7362306a36Sopenharmony_ci		 MPP_FUNCTION(2, "nand",  "cen")),
7462306a36Sopenharmony_ci	MPP_MODE(12,
7562306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",  NULL),
7662306a36Sopenharmony_ci		 MPP_FUNCTION(1, "spi0",  "clk")),
7762306a36Sopenharmony_ci	MPP_MODE(13,
7862306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",  NULL),
7962306a36Sopenharmony_ci		 MPP_FUNCTION(1, "spi0",  "csn")),
8062306a36Sopenharmony_ci	MPP_MODE(14,
8162306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",  NULL),
8262306a36Sopenharmony_ci		 MPP_FUNCTION(1, "spi0",  "mosi")),
8362306a36Sopenharmony_ci	MPP_MODE(15,
8462306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",  NULL),
8562306a36Sopenharmony_ci		 MPP_FUNCTION(1, "spi0",  "miso")),
8662306a36Sopenharmony_ci	MPP_MODE(16,
8762306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",  NULL),
8862306a36Sopenharmony_ci		 MPP_FUNCTION(1, "spi0",  "wpn"),
8962306a36Sopenharmony_ci		 MPP_FUNCTION(2, "nand",  "ren"),
9062306a36Sopenharmony_ci		 MPP_FUNCTION(3, "uart1", "txd")),
9162306a36Sopenharmony_ci	MPP_MODE(17,
9262306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",  NULL),
9362306a36Sopenharmony_ci		 MPP_FUNCTION(1, "spi0",  "hold"),
9462306a36Sopenharmony_ci		 MPP_FUNCTION(2, "nand",  "rb"),
9562306a36Sopenharmony_ci		 MPP_FUNCTION(3, "uart1", "rxd")),
9662306a36Sopenharmony_ci	MPP_MODE(18,
9762306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",  NULL),
9862306a36Sopenharmony_ci		 MPP_FUNCTION(1, "tsen_int", NULL),
9962306a36Sopenharmony_ci		 MPP_FUNCTION(2, "uart2", "rxd"),
10062306a36Sopenharmony_ci		 MPP_FUNCTION(3, "wd_int", NULL)),
10162306a36Sopenharmony_ci	MPP_MODE(19,
10262306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",  NULL),
10362306a36Sopenharmony_ci		 MPP_FUNCTION(1, "dev_init_done", NULL),
10462306a36Sopenharmony_ci		 MPP_FUNCTION(2, "uart2", "txd")),
10562306a36Sopenharmony_ci	MPP_MODE(20,
10662306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",  NULL),
10762306a36Sopenharmony_ci		 MPP_FUNCTION(2, "i2c1",  "sck"),
10862306a36Sopenharmony_ci		 MPP_FUNCTION(3, "spi1",  "clk"),
10962306a36Sopenharmony_ci		 MPP_FUNCTION(4, "uart3", "txd")),
11062306a36Sopenharmony_ci	MPP_MODE(21,
11162306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",  NULL),
11262306a36Sopenharmony_ci		 MPP_FUNCTION(2, "i2c1",  "sda"),
11362306a36Sopenharmony_ci		 MPP_FUNCTION(3, "spi1",  "csn"),
11462306a36Sopenharmony_ci		 MPP_FUNCTION(4, "uart3", "rxd")),
11562306a36Sopenharmony_ci	MPP_MODE(22,
11662306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",  NULL),
11762306a36Sopenharmony_ci		 MPP_FUNCTION(3, "spi1",  "mosi")),
11862306a36Sopenharmony_ci	MPP_MODE(23,
11962306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",  NULL),
12062306a36Sopenharmony_ci		 MPP_FUNCTION(3, "spi1",  "miso")),
12162306a36Sopenharmony_ci	MPP_MODE(24,
12262306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",  NULL),
12362306a36Sopenharmony_ci		 MPP_FUNCTION(1, "wd_int", NULL),
12462306a36Sopenharmony_ci		 MPP_FUNCTION(2, "uart2", "txd"),
12562306a36Sopenharmony_ci		 MPP_FUNCTION(3, "uartsd", "txd")),
12662306a36Sopenharmony_ci	MPP_MODE(25,
12762306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",  NULL),
12862306a36Sopenharmony_ci		 MPP_FUNCTION(1, "int_out", NULL),
12962306a36Sopenharmony_ci		 MPP_FUNCTION(2, "uart2", "rxd"),
13062306a36Sopenharmony_ci		 MPP_FUNCTION(3, "uartsd", "rxd")),
13162306a36Sopenharmony_ci	MPP_MODE(26,
13262306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",  NULL),
13362306a36Sopenharmony_ci		 MPP_FUNCTION(1, "i2c0",  "sck"),
13462306a36Sopenharmony_ci		 MPP_FUNCTION(2, "ptp", "clk1"),
13562306a36Sopenharmony_ci		 MPP_FUNCTION(3, "uart3", "txd")),
13662306a36Sopenharmony_ci	MPP_MODE(27,
13762306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",  NULL),
13862306a36Sopenharmony_ci		 MPP_FUNCTION(1, "i2c0",  "sda"),
13962306a36Sopenharmony_ci		 MPP_FUNCTION(2, "ptp", "pulse"),
14062306a36Sopenharmony_ci		 MPP_FUNCTION(3, "uart3", "rxd")),
14162306a36Sopenharmony_ci	MPP_MODE(28,
14262306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",  NULL),
14362306a36Sopenharmony_ci		 MPP_FUNCTION(1, "xg", "mdio"),
14462306a36Sopenharmony_ci		 MPP_FUNCTION(2, "ge", "mdio"),
14562306a36Sopenharmony_ci		 MPP_FUNCTION(3, "uart3", "txd")),
14662306a36Sopenharmony_ci	MPP_MODE(29,
14762306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",  NULL),
14862306a36Sopenharmony_ci		 MPP_FUNCTION(1, "xg", "mdio"),
14962306a36Sopenharmony_ci		 MPP_FUNCTION(2, "ge", "mdio"),
15062306a36Sopenharmony_ci		 MPP_FUNCTION(3, "uart3", "rxd")),
15162306a36Sopenharmony_ci	MPP_MODE(30,
15262306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",  NULL),
15362306a36Sopenharmony_ci		 MPP_FUNCTION(1, "xg", "mdio"),
15462306a36Sopenharmony_ci		 MPP_FUNCTION(2, "ge", "mdio"),
15562306a36Sopenharmony_ci		 MPP_FUNCTION(3, "ge", "mdio")),
15662306a36Sopenharmony_ci	MPP_MODE(31,
15762306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",  NULL),
15862306a36Sopenharmony_ci		 MPP_FUNCTION(1, "xg", "mdio"),
15962306a36Sopenharmony_ci		 MPP_FUNCTION(2, "ge", "mdio"),
16062306a36Sopenharmony_ci		 MPP_FUNCTION(3, "ge", "mdio")),
16162306a36Sopenharmony_ci	MPP_MODE(32,
16262306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",  NULL),
16362306a36Sopenharmony_ci		 MPP_FUNCTION(1, "uart0", "txd")),
16462306a36Sopenharmony_ci	MPP_MODE(33,
16562306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",  NULL),
16662306a36Sopenharmony_ci		 MPP_FUNCTION(1, "uart0", "rxd"),
16762306a36Sopenharmony_ci		 MPP_FUNCTION(2, "ptp", "clk1"),
16862306a36Sopenharmony_ci		 MPP_FUNCTION(3, "ptp", "pulse")),
16962306a36Sopenharmony_ci	MPP_MODE(34,
17062306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",  NULL),
17162306a36Sopenharmony_ci		 MPP_FUNCTION(1, "ge", "mdio"),
17262306a36Sopenharmony_ci		 MPP_FUNCTION(2, "uart3", "rxd")),
17362306a36Sopenharmony_ci	MPP_MODE(35,
17462306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",  NULL),
17562306a36Sopenharmony_ci		 MPP_FUNCTION(1, "ge", "mdio"),
17662306a36Sopenharmony_ci		 MPP_FUNCTION(2, "uart3", "txd"),
17762306a36Sopenharmony_ci		 MPP_FUNCTION(3, "pcie", "rstoutn")),
17862306a36Sopenharmony_ci	MPP_MODE(36,
17962306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",  NULL),
18062306a36Sopenharmony_ci		 MPP_FUNCTION(1, "ptp", "clk0_tp"),
18162306a36Sopenharmony_ci		 MPP_FUNCTION(2, "ptp", "clk1_tp")),
18262306a36Sopenharmony_ci	MPP_MODE(37,
18362306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",  NULL),
18462306a36Sopenharmony_ci		 MPP_FUNCTION(1, "ptp", "pulse_tp"),
18562306a36Sopenharmony_ci		 MPP_FUNCTION(2, "wd_int", NULL)),
18662306a36Sopenharmony_ci	MPP_MODE(38,
18762306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",  NULL),
18862306a36Sopenharmony_ci		 MPP_FUNCTION(1, "synce", "clk_out0")),
18962306a36Sopenharmony_ci	MPP_MODE(39,
19062306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",  NULL),
19162306a36Sopenharmony_ci		 MPP_FUNCTION(1, "synce", "clk_out1")),
19262306a36Sopenharmony_ci	MPP_MODE(40,
19362306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",  NULL),
19462306a36Sopenharmony_ci		 MPP_FUNCTION(1, "ptp", "pclk_out0"),
19562306a36Sopenharmony_ci		 MPP_FUNCTION(2, "ptp", "pclk_out1")),
19662306a36Sopenharmony_ci	MPP_MODE(41,
19762306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",  NULL),
19862306a36Sopenharmony_ci		 MPP_FUNCTION(1, "ptp", "ref_clk"),
19962306a36Sopenharmony_ci		 MPP_FUNCTION(2, "ptp", "clk1"),
20062306a36Sopenharmony_ci		 MPP_FUNCTION(3, "ptp", "pulse"),
20162306a36Sopenharmony_ci		 MPP_FUNCTION(4, "uart2", "txd"),
20262306a36Sopenharmony_ci		 MPP_FUNCTION(5, "i2c1",  "sck")),
20362306a36Sopenharmony_ci	MPP_MODE(42,
20462306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",  NULL),
20562306a36Sopenharmony_ci		 MPP_FUNCTION(1, "ptp", "clk0"),
20662306a36Sopenharmony_ci		 MPP_FUNCTION(2, "ptp", "clk1"),
20762306a36Sopenharmony_ci		 MPP_FUNCTION(3, "ptp", "pulse"),
20862306a36Sopenharmony_ci		 MPP_FUNCTION(4, "uart2", "rxd"),
20962306a36Sopenharmony_ci		 MPP_FUNCTION(5, "i2c1",  "sda")),
21062306a36Sopenharmony_ci	MPP_MODE(43,
21162306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",  NULL),
21262306a36Sopenharmony_ci		 MPP_FUNCTION(1, "led", "clk")),
21362306a36Sopenharmony_ci	MPP_MODE(44,
21462306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",  NULL),
21562306a36Sopenharmony_ci		 MPP_FUNCTION(1, "led", "stb")),
21662306a36Sopenharmony_ci	MPP_MODE(45,
21762306a36Sopenharmony_ci		 MPP_FUNCTION(0, "gpio",  NULL),
21862306a36Sopenharmony_ci		 MPP_FUNCTION(1, "led", "data")),
21962306a36Sopenharmony_ci};
22062306a36Sopenharmony_ci
22162306a36Sopenharmony_cistatic struct mvebu_pinctrl_soc_info ac5_pinctrl_info;
22262306a36Sopenharmony_ci
22362306a36Sopenharmony_cistatic const struct of_device_id ac5_pinctrl_of_match[] = {
22462306a36Sopenharmony_ci	{
22562306a36Sopenharmony_ci		.compatible = "marvell,ac5-pinctrl",
22662306a36Sopenharmony_ci	},
22762306a36Sopenharmony_ci	{ },
22862306a36Sopenharmony_ci};
22962306a36Sopenharmony_ci
23062306a36Sopenharmony_cistatic const struct mvebu_mpp_ctrl ac5_mpp_controls[] = {
23162306a36Sopenharmony_ci	MPP_FUNC_CTRL(0, 45, NULL, mvebu_mmio_mpp_ctrl), };
23262306a36Sopenharmony_ci
23362306a36Sopenharmony_cistatic struct pinctrl_gpio_range ac5_mpp_gpio_ranges[] = {
23462306a36Sopenharmony_ci	MPP_GPIO_RANGE(0,   0,  0, 46), };
23562306a36Sopenharmony_ci
23662306a36Sopenharmony_cistatic int ac5_pinctrl_probe(struct platform_device *pdev)
23762306a36Sopenharmony_ci{
23862306a36Sopenharmony_ci	struct mvebu_pinctrl_soc_info *soc = &ac5_pinctrl_info;
23962306a36Sopenharmony_ci
24062306a36Sopenharmony_ci	soc->variant = 0; /* no variants for ac5 */
24162306a36Sopenharmony_ci	soc->controls = ac5_mpp_controls;
24262306a36Sopenharmony_ci	soc->ncontrols = ARRAY_SIZE(ac5_mpp_controls);
24362306a36Sopenharmony_ci	soc->gpioranges = ac5_mpp_gpio_ranges;
24462306a36Sopenharmony_ci	soc->ngpioranges = ARRAY_SIZE(ac5_mpp_gpio_ranges);
24562306a36Sopenharmony_ci	soc->modes = ac5_mpp_modes;
24662306a36Sopenharmony_ci	soc->nmodes = ac5_mpp_controls[0].npins;
24762306a36Sopenharmony_ci
24862306a36Sopenharmony_ci	pdev->dev.platform_data = soc;
24962306a36Sopenharmony_ci
25062306a36Sopenharmony_ci	return mvebu_pinctrl_simple_mmio_probe(pdev);
25162306a36Sopenharmony_ci}
25262306a36Sopenharmony_ci
25362306a36Sopenharmony_cistatic struct platform_driver ac5_pinctrl_driver = {
25462306a36Sopenharmony_ci	.driver = {
25562306a36Sopenharmony_ci		.name = "ac5-pinctrl",
25662306a36Sopenharmony_ci		.of_match_table = of_match_ptr(ac5_pinctrl_of_match),
25762306a36Sopenharmony_ci	},
25862306a36Sopenharmony_ci	.probe = ac5_pinctrl_probe,
25962306a36Sopenharmony_ci};
26062306a36Sopenharmony_cibuiltin_platform_driver(ac5_pinctrl_driver);
261