162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Combined GPIO and pin controller support for Renesas RZ/A1 (r7s72100) SoC
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (C) 2017 Jacopo Mondi
662306a36Sopenharmony_ci */
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci/*
962306a36Sopenharmony_ci * This pin controller/gpio combined driver supports Renesas devices of RZ/A1
1062306a36Sopenharmony_ci * family.
1162306a36Sopenharmony_ci * This includes SoCs which are sub- or super- sets of this particular line,
1262306a36Sopenharmony_ci * as RZ/A1H (r7s721000), RZ/A1M (r7s721010) and RZ/A1L (r7s721020).
1362306a36Sopenharmony_ci */
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci#include <linux/bitops.h>
1662306a36Sopenharmony_ci#include <linux/err.h>
1762306a36Sopenharmony_ci#include <linux/gpio/driver.h>
1862306a36Sopenharmony_ci#include <linux/init.h>
1962306a36Sopenharmony_ci#include <linux/ioport.h>
2062306a36Sopenharmony_ci#include <linux/module.h>
2162306a36Sopenharmony_ci#include <linux/of.h>
2262306a36Sopenharmony_ci#include <linux/pinctrl/pinconf-generic.h>
2362306a36Sopenharmony_ci#include <linux/pinctrl/pinctrl.h>
2462306a36Sopenharmony_ci#include <linux/pinctrl/pinmux.h>
2562306a36Sopenharmony_ci#include <linux/platform_device.h>
2662306a36Sopenharmony_ci#include <linux/property.h>
2762306a36Sopenharmony_ci#include <linux/slab.h>
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ci#include "../core.h"
3062306a36Sopenharmony_ci#include "../devicetree.h"
3162306a36Sopenharmony_ci#include "../pinconf.h"
3262306a36Sopenharmony_ci#include "../pinmux.h"
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ci#define DRIVER_NAME			"pinctrl-rza1"
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ci#define RZA1_P_REG			0x0000
3762306a36Sopenharmony_ci#define RZA1_PPR_REG			0x0200
3862306a36Sopenharmony_ci#define RZA1_PM_REG			0x0300
3962306a36Sopenharmony_ci#define RZA1_PMC_REG			0x0400
4062306a36Sopenharmony_ci#define RZA1_PFC_REG			0x0500
4162306a36Sopenharmony_ci#define RZA1_PFCE_REG			0x0600
4262306a36Sopenharmony_ci#define RZA1_PFCEA_REG			0x0a00
4362306a36Sopenharmony_ci#define RZA1_PIBC_REG			0x4000
4462306a36Sopenharmony_ci#define RZA1_PBDC_REG			0x4100
4562306a36Sopenharmony_ci#define RZA1_PIPC_REG			0x4200
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_ci#define RZA1_ADDR(mem, reg, port)	((mem) + (reg) + ((port) * 4))
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ci#define RZA1_NPORTS			12
5062306a36Sopenharmony_ci#define RZA1_PINS_PER_PORT		16
5162306a36Sopenharmony_ci#define RZA1_NPINS			(RZA1_PINS_PER_PORT * RZA1_NPORTS)
5262306a36Sopenharmony_ci#define RZA1_PIN_ID_TO_PORT(id)		((id) / RZA1_PINS_PER_PORT)
5362306a36Sopenharmony_ci#define RZA1_PIN_ID_TO_PIN(id)		((id) % RZA1_PINS_PER_PORT)
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ci/*
5662306a36Sopenharmony_ci * Use 16 lower bits [15:0] for pin identifier
5762306a36Sopenharmony_ci * Use 16 higher bits [31:16] for pin mux function
5862306a36Sopenharmony_ci */
5962306a36Sopenharmony_ci#define MUX_PIN_ID_MASK			GENMASK(15, 0)
6062306a36Sopenharmony_ci#define MUX_FUNC_MASK			GENMASK(31, 16)
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_ci#define MUX_FUNC_OFFS			16
6362306a36Sopenharmony_ci#define MUX_FUNC(pinconf)		\
6462306a36Sopenharmony_ci	((pinconf & MUX_FUNC_MASK) >> MUX_FUNC_OFFS)
6562306a36Sopenharmony_ci#define MUX_FUNC_PFC_MASK		BIT(0)
6662306a36Sopenharmony_ci#define MUX_FUNC_PFCE_MASK		BIT(1)
6762306a36Sopenharmony_ci#define MUX_FUNC_PFCEA_MASK		BIT(2)
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_ci/* Pin mux flags */
7062306a36Sopenharmony_ci#define MUX_FLAGS_BIDIR			BIT(0)
7162306a36Sopenharmony_ci#define MUX_FLAGS_SWIO_INPUT		BIT(1)
7262306a36Sopenharmony_ci#define MUX_FLAGS_SWIO_OUTPUT		BIT(2)
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_ci/* ----------------------------------------------------------------------------
7562306a36Sopenharmony_ci * RZ/A1 pinmux flags
7662306a36Sopenharmony_ci */
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ci/*
7962306a36Sopenharmony_ci * rza1_bidir_pin - describe a single pin that needs bidir flag applied.
8062306a36Sopenharmony_ci */
8162306a36Sopenharmony_cistruct rza1_bidir_pin {
8262306a36Sopenharmony_ci	u8 pin: 4;
8362306a36Sopenharmony_ci	u8 func: 4;
8462306a36Sopenharmony_ci};
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ci/*
8762306a36Sopenharmony_ci * rza1_bidir_entry - describe a list of pins that needs bidir flag applied.
8862306a36Sopenharmony_ci *		      Each struct rza1_bidir_entry describes a port.
8962306a36Sopenharmony_ci */
9062306a36Sopenharmony_cistruct rza1_bidir_entry {
9162306a36Sopenharmony_ci	const unsigned int npins;
9262306a36Sopenharmony_ci	const struct rza1_bidir_pin *pins;
9362306a36Sopenharmony_ci};
9462306a36Sopenharmony_ci
9562306a36Sopenharmony_ci/*
9662306a36Sopenharmony_ci * rza1_swio_pin - describe a single pin that needs swio flag applied.
9762306a36Sopenharmony_ci */
9862306a36Sopenharmony_cistruct rza1_swio_pin {
9962306a36Sopenharmony_ci	u16 pin: 4;
10062306a36Sopenharmony_ci	u16 port: 4;
10162306a36Sopenharmony_ci	u16 func: 4;
10262306a36Sopenharmony_ci	u16 input: 1;
10362306a36Sopenharmony_ci};
10462306a36Sopenharmony_ci
10562306a36Sopenharmony_ci/*
10662306a36Sopenharmony_ci * rza1_swio_entry - describe a list of pins that needs swio flag applied
10762306a36Sopenharmony_ci */
10862306a36Sopenharmony_cistruct rza1_swio_entry {
10962306a36Sopenharmony_ci	const unsigned int npins;
11062306a36Sopenharmony_ci	const struct rza1_swio_pin *pins;
11162306a36Sopenharmony_ci};
11262306a36Sopenharmony_ci
11362306a36Sopenharmony_ci/*
11462306a36Sopenharmony_ci * rza1_pinmux_conf - group together bidir and swio pinmux flag tables
11562306a36Sopenharmony_ci */
11662306a36Sopenharmony_cistruct rza1_pinmux_conf {
11762306a36Sopenharmony_ci	const struct rza1_bidir_entry *bidir_entries;
11862306a36Sopenharmony_ci	const struct rza1_swio_entry *swio_entries;
11962306a36Sopenharmony_ci};
12062306a36Sopenharmony_ci
12162306a36Sopenharmony_ci/* ----------------------------------------------------------------------------
12262306a36Sopenharmony_ci * RZ/A1H (r7s72100) pinmux flags
12362306a36Sopenharmony_ci */
12462306a36Sopenharmony_ci
12562306a36Sopenharmony_cistatic const struct rza1_bidir_pin rza1h_bidir_pins_p1[] = {
12662306a36Sopenharmony_ci	{ .pin = 0, .func = 1 },
12762306a36Sopenharmony_ci	{ .pin = 1, .func = 1 },
12862306a36Sopenharmony_ci	{ .pin = 2, .func = 1 },
12962306a36Sopenharmony_ci	{ .pin = 3, .func = 1 },
13062306a36Sopenharmony_ci	{ .pin = 4, .func = 1 },
13162306a36Sopenharmony_ci	{ .pin = 5, .func = 1 },
13262306a36Sopenharmony_ci	{ .pin = 6, .func = 1 },
13362306a36Sopenharmony_ci	{ .pin = 7, .func = 1 },
13462306a36Sopenharmony_ci};
13562306a36Sopenharmony_ci
13662306a36Sopenharmony_cistatic const struct rza1_bidir_pin rza1h_bidir_pins_p2[] = {
13762306a36Sopenharmony_ci	{ .pin = 0, .func = 1 },
13862306a36Sopenharmony_ci	{ .pin = 1, .func = 1 },
13962306a36Sopenharmony_ci	{ .pin = 2, .func = 1 },
14062306a36Sopenharmony_ci	{ .pin = 3, .func = 1 },
14162306a36Sopenharmony_ci	{ .pin = 4, .func = 1 },
14262306a36Sopenharmony_ci	{ .pin = 0, .func = 4 },
14362306a36Sopenharmony_ci	{ .pin = 1, .func = 4 },
14462306a36Sopenharmony_ci	{ .pin = 2, .func = 4 },
14562306a36Sopenharmony_ci	{ .pin = 3, .func = 4 },
14662306a36Sopenharmony_ci	{ .pin = 5, .func = 1 },
14762306a36Sopenharmony_ci	{ .pin = 6, .func = 1 },
14862306a36Sopenharmony_ci	{ .pin = 7, .func = 1 },
14962306a36Sopenharmony_ci	{ .pin = 8, .func = 1 },
15062306a36Sopenharmony_ci	{ .pin = 9, .func = 1 },
15162306a36Sopenharmony_ci	{ .pin = 10, .func = 1 },
15262306a36Sopenharmony_ci	{ .pin = 11, .func = 1 },
15362306a36Sopenharmony_ci	{ .pin = 12, .func = 1 },
15462306a36Sopenharmony_ci	{ .pin = 13, .func = 1 },
15562306a36Sopenharmony_ci	{ .pin = 14, .func = 1 },
15662306a36Sopenharmony_ci	{ .pin = 15, .func = 1 },
15762306a36Sopenharmony_ci	{ .pin = 12, .func = 4 },
15862306a36Sopenharmony_ci	{ .pin = 13, .func = 4 },
15962306a36Sopenharmony_ci	{ .pin = 14, .func = 4 },
16062306a36Sopenharmony_ci	{ .pin = 15, .func = 4 },
16162306a36Sopenharmony_ci};
16262306a36Sopenharmony_ci
16362306a36Sopenharmony_cistatic const struct rza1_bidir_pin rza1h_bidir_pins_p3[] = {
16462306a36Sopenharmony_ci	{ .pin = 3, .func = 2 },
16562306a36Sopenharmony_ci	{ .pin = 10, .func = 7 },
16662306a36Sopenharmony_ci	{ .pin = 11, .func = 7 },
16762306a36Sopenharmony_ci	{ .pin = 13, .func = 7 },
16862306a36Sopenharmony_ci	{ .pin = 14, .func = 7 },
16962306a36Sopenharmony_ci	{ .pin = 15, .func = 7 },
17062306a36Sopenharmony_ci	{ .pin = 10, .func = 8 },
17162306a36Sopenharmony_ci	{ .pin = 11, .func = 8 },
17262306a36Sopenharmony_ci	{ .pin = 13, .func = 8 },
17362306a36Sopenharmony_ci	{ .pin = 14, .func = 8 },
17462306a36Sopenharmony_ci	{ .pin = 15, .func = 8 },
17562306a36Sopenharmony_ci};
17662306a36Sopenharmony_ci
17762306a36Sopenharmony_cistatic const struct rza1_bidir_pin rza1h_bidir_pins_p4[] = {
17862306a36Sopenharmony_ci	{ .pin = 0, .func = 8 },
17962306a36Sopenharmony_ci	{ .pin = 1, .func = 8 },
18062306a36Sopenharmony_ci	{ .pin = 2, .func = 8 },
18162306a36Sopenharmony_ci	{ .pin = 3, .func = 8 },
18262306a36Sopenharmony_ci	{ .pin = 10, .func = 3 },
18362306a36Sopenharmony_ci	{ .pin = 11, .func = 3 },
18462306a36Sopenharmony_ci	{ .pin = 13, .func = 3 },
18562306a36Sopenharmony_ci	{ .pin = 14, .func = 3 },
18662306a36Sopenharmony_ci	{ .pin = 15, .func = 3 },
18762306a36Sopenharmony_ci	{ .pin = 10, .func = 4 },
18862306a36Sopenharmony_ci	{ .pin = 11, .func = 4 },
18962306a36Sopenharmony_ci	{ .pin = 13, .func = 4 },
19062306a36Sopenharmony_ci	{ .pin = 14, .func = 4 },
19162306a36Sopenharmony_ci	{ .pin = 15, .func = 4 },
19262306a36Sopenharmony_ci	{ .pin = 12, .func = 5 },
19362306a36Sopenharmony_ci	{ .pin = 13, .func = 5 },
19462306a36Sopenharmony_ci	{ .pin = 14, .func = 5 },
19562306a36Sopenharmony_ci	{ .pin = 15, .func = 5 },
19662306a36Sopenharmony_ci};
19762306a36Sopenharmony_ci
19862306a36Sopenharmony_cistatic const struct rza1_bidir_pin rza1h_bidir_pins_p6[] = {
19962306a36Sopenharmony_ci	{ .pin = 0, .func = 1 },
20062306a36Sopenharmony_ci	{ .pin = 1, .func = 1 },
20162306a36Sopenharmony_ci	{ .pin = 2, .func = 1 },
20262306a36Sopenharmony_ci	{ .pin = 3, .func = 1 },
20362306a36Sopenharmony_ci	{ .pin = 4, .func = 1 },
20462306a36Sopenharmony_ci	{ .pin = 5, .func = 1 },
20562306a36Sopenharmony_ci	{ .pin = 6, .func = 1 },
20662306a36Sopenharmony_ci	{ .pin = 7, .func = 1 },
20762306a36Sopenharmony_ci	{ .pin = 8, .func = 1 },
20862306a36Sopenharmony_ci	{ .pin = 9, .func = 1 },
20962306a36Sopenharmony_ci	{ .pin = 10, .func = 1 },
21062306a36Sopenharmony_ci	{ .pin = 11, .func = 1 },
21162306a36Sopenharmony_ci	{ .pin = 12, .func = 1 },
21262306a36Sopenharmony_ci	{ .pin = 13, .func = 1 },
21362306a36Sopenharmony_ci	{ .pin = 14, .func = 1 },
21462306a36Sopenharmony_ci	{ .pin = 15, .func = 1 },
21562306a36Sopenharmony_ci};
21662306a36Sopenharmony_ci
21762306a36Sopenharmony_cistatic const struct rza1_bidir_pin rza1h_bidir_pins_p7[] = {
21862306a36Sopenharmony_ci	{ .pin = 13, .func = 3 },
21962306a36Sopenharmony_ci};
22062306a36Sopenharmony_ci
22162306a36Sopenharmony_cistatic const struct rza1_bidir_pin rza1h_bidir_pins_p8[] = {
22262306a36Sopenharmony_ci	{ .pin = 8, .func = 3 },
22362306a36Sopenharmony_ci	{ .pin = 9, .func = 3 },
22462306a36Sopenharmony_ci	{ .pin = 10, .func = 3 },
22562306a36Sopenharmony_ci	{ .pin = 11, .func = 3 },
22662306a36Sopenharmony_ci	{ .pin = 14, .func = 2 },
22762306a36Sopenharmony_ci	{ .pin = 15, .func = 2 },
22862306a36Sopenharmony_ci	{ .pin = 14, .func = 3 },
22962306a36Sopenharmony_ci	{ .pin = 15, .func = 3 },
23062306a36Sopenharmony_ci};
23162306a36Sopenharmony_ci
23262306a36Sopenharmony_cistatic const struct rza1_bidir_pin rza1h_bidir_pins_p9[] = {
23362306a36Sopenharmony_ci	{ .pin = 0, .func = 2 },
23462306a36Sopenharmony_ci	{ .pin = 1, .func = 2 },
23562306a36Sopenharmony_ci	{ .pin = 4, .func = 2 },
23662306a36Sopenharmony_ci	{ .pin = 5, .func = 2 },
23762306a36Sopenharmony_ci	{ .pin = 6, .func = 2 },
23862306a36Sopenharmony_ci	{ .pin = 7, .func = 2 },
23962306a36Sopenharmony_ci};
24062306a36Sopenharmony_ci
24162306a36Sopenharmony_cistatic const struct rza1_bidir_pin rza1h_bidir_pins_p11[] = {
24262306a36Sopenharmony_ci	{ .pin = 6, .func = 2 },
24362306a36Sopenharmony_ci	{ .pin = 7, .func = 2 },
24462306a36Sopenharmony_ci	{ .pin = 9, .func = 2 },
24562306a36Sopenharmony_ci	{ .pin = 6, .func = 4 },
24662306a36Sopenharmony_ci	{ .pin = 7, .func = 4 },
24762306a36Sopenharmony_ci	{ .pin = 9, .func = 4 },
24862306a36Sopenharmony_ci	{ .pin = 10, .func = 2 },
24962306a36Sopenharmony_ci	{ .pin = 11, .func = 2 },
25062306a36Sopenharmony_ci	{ .pin = 10, .func = 4 },
25162306a36Sopenharmony_ci	{ .pin = 11, .func = 4 },
25262306a36Sopenharmony_ci	{ .pin = 12, .func = 4 },
25362306a36Sopenharmony_ci	{ .pin = 13, .func = 4 },
25462306a36Sopenharmony_ci	{ .pin = 14, .func = 4 },
25562306a36Sopenharmony_ci	{ .pin = 15, .func = 4 },
25662306a36Sopenharmony_ci};
25762306a36Sopenharmony_ci
25862306a36Sopenharmony_cistatic const struct rza1_swio_pin rza1h_swio_pins[] = {
25962306a36Sopenharmony_ci	{ .port = 2, .pin = 7, .func = 4, .input = 0 },
26062306a36Sopenharmony_ci	{ .port = 2, .pin = 11, .func = 4, .input = 0 },
26162306a36Sopenharmony_ci	{ .port = 3, .pin = 7, .func = 3, .input = 0 },
26262306a36Sopenharmony_ci	{ .port = 3, .pin = 7, .func = 8, .input = 0 },
26362306a36Sopenharmony_ci	{ .port = 4, .pin = 7, .func = 5, .input = 0 },
26462306a36Sopenharmony_ci	{ .port = 4, .pin = 7, .func = 11, .input = 0 },
26562306a36Sopenharmony_ci	{ .port = 4, .pin = 15, .func = 6, .input = 0 },
26662306a36Sopenharmony_ci	{ .port = 5, .pin = 0, .func = 1, .input = 1 },
26762306a36Sopenharmony_ci	{ .port = 5, .pin = 1, .func = 1, .input = 1 },
26862306a36Sopenharmony_ci	{ .port = 5, .pin = 2, .func = 1, .input = 1 },
26962306a36Sopenharmony_ci	{ .port = 5, .pin = 3, .func = 1, .input = 1 },
27062306a36Sopenharmony_ci	{ .port = 5, .pin = 4, .func = 1, .input = 1 },
27162306a36Sopenharmony_ci	{ .port = 5, .pin = 5, .func = 1, .input = 1 },
27262306a36Sopenharmony_ci	{ .port = 5, .pin = 6, .func = 1, .input = 1 },
27362306a36Sopenharmony_ci	{ .port = 5, .pin = 7, .func = 1, .input = 1 },
27462306a36Sopenharmony_ci	{ .port = 7, .pin = 4, .func = 6, .input = 0 },
27562306a36Sopenharmony_ci	{ .port = 7, .pin = 11, .func = 2, .input = 0 },
27662306a36Sopenharmony_ci	{ .port = 8, .pin = 10, .func = 8, .input = 0 },
27762306a36Sopenharmony_ci	{ .port = 10, .pin = 15, .func = 2, .input = 0 },
27862306a36Sopenharmony_ci};
27962306a36Sopenharmony_ci
28062306a36Sopenharmony_cistatic const struct rza1_bidir_entry rza1h_bidir_entries[RZA1_NPORTS] = {
28162306a36Sopenharmony_ci	[1] = { ARRAY_SIZE(rza1h_bidir_pins_p1), rza1h_bidir_pins_p1 },
28262306a36Sopenharmony_ci	[2] = { ARRAY_SIZE(rza1h_bidir_pins_p2), rza1h_bidir_pins_p2 },
28362306a36Sopenharmony_ci	[3] = { ARRAY_SIZE(rza1h_bidir_pins_p3), rza1h_bidir_pins_p3 },
28462306a36Sopenharmony_ci	[4] = { ARRAY_SIZE(rza1h_bidir_pins_p4), rza1h_bidir_pins_p4 },
28562306a36Sopenharmony_ci	[6] = { ARRAY_SIZE(rza1h_bidir_pins_p6), rza1h_bidir_pins_p6 },
28662306a36Sopenharmony_ci	[7] = { ARRAY_SIZE(rza1h_bidir_pins_p7), rza1h_bidir_pins_p7 },
28762306a36Sopenharmony_ci	[8] = { ARRAY_SIZE(rza1h_bidir_pins_p8), rza1h_bidir_pins_p8 },
28862306a36Sopenharmony_ci	[9] = { ARRAY_SIZE(rza1h_bidir_pins_p9), rza1h_bidir_pins_p9 },
28962306a36Sopenharmony_ci	[11] = { ARRAY_SIZE(rza1h_bidir_pins_p11), rza1h_bidir_pins_p11 },
29062306a36Sopenharmony_ci};
29162306a36Sopenharmony_ci
29262306a36Sopenharmony_cistatic const struct rza1_swio_entry rza1h_swio_entries[] = {
29362306a36Sopenharmony_ci	[0] = { ARRAY_SIZE(rza1h_swio_pins), rza1h_swio_pins },
29462306a36Sopenharmony_ci};
29562306a36Sopenharmony_ci
29662306a36Sopenharmony_ci/* RZ/A1H (r7s72100x) pinmux flags table */
29762306a36Sopenharmony_cistatic const struct rza1_pinmux_conf rza1h_pmx_conf = {
29862306a36Sopenharmony_ci	.bidir_entries	= rza1h_bidir_entries,
29962306a36Sopenharmony_ci	.swio_entries	= rza1h_swio_entries,
30062306a36Sopenharmony_ci};
30162306a36Sopenharmony_ci
30262306a36Sopenharmony_ci/* ----------------------------------------------------------------------------
30362306a36Sopenharmony_ci * RZ/A1L (r7s72102) pinmux flags
30462306a36Sopenharmony_ci */
30562306a36Sopenharmony_ci
30662306a36Sopenharmony_cistatic const struct rza1_bidir_pin rza1l_bidir_pins_p1[] = {
30762306a36Sopenharmony_ci	{ .pin = 0, .func = 1 },
30862306a36Sopenharmony_ci	{ .pin = 1, .func = 1 },
30962306a36Sopenharmony_ci	{ .pin = 2, .func = 1 },
31062306a36Sopenharmony_ci	{ .pin = 3, .func = 1 },
31162306a36Sopenharmony_ci	{ .pin = 4, .func = 1 },
31262306a36Sopenharmony_ci	{ .pin = 5, .func = 1 },
31362306a36Sopenharmony_ci	{ .pin = 6, .func = 1 },
31462306a36Sopenharmony_ci	{ .pin = 7, .func = 1 },
31562306a36Sopenharmony_ci};
31662306a36Sopenharmony_ci
31762306a36Sopenharmony_cistatic const struct rza1_bidir_pin rza1l_bidir_pins_p3[] = {
31862306a36Sopenharmony_ci	{ .pin = 0, .func = 2 },
31962306a36Sopenharmony_ci	{ .pin = 1, .func = 2 },
32062306a36Sopenharmony_ci	{ .pin = 2, .func = 2 },
32162306a36Sopenharmony_ci	{ .pin = 4, .func = 2 },
32262306a36Sopenharmony_ci	{ .pin = 5, .func = 2 },
32362306a36Sopenharmony_ci	{ .pin = 10, .func = 2 },
32462306a36Sopenharmony_ci	{ .pin = 11, .func = 2 },
32562306a36Sopenharmony_ci	{ .pin = 12, .func = 2 },
32662306a36Sopenharmony_ci	{ .pin = 13, .func = 2 },
32762306a36Sopenharmony_ci};
32862306a36Sopenharmony_ci
32962306a36Sopenharmony_cistatic const struct rza1_bidir_pin rza1l_bidir_pins_p4[] = {
33062306a36Sopenharmony_ci	{ .pin = 1, .func = 4 },
33162306a36Sopenharmony_ci	{ .pin = 2, .func = 2 },
33262306a36Sopenharmony_ci	{ .pin = 3, .func = 2 },
33362306a36Sopenharmony_ci	{ .pin = 6, .func = 2 },
33462306a36Sopenharmony_ci	{ .pin = 7, .func = 2 },
33562306a36Sopenharmony_ci};
33662306a36Sopenharmony_ci
33762306a36Sopenharmony_cistatic const struct rza1_bidir_pin rza1l_bidir_pins_p5[] = {
33862306a36Sopenharmony_ci	{ .pin = 0, .func = 1 },
33962306a36Sopenharmony_ci	{ .pin = 1, .func = 1 },
34062306a36Sopenharmony_ci	{ .pin = 2, .func = 1 },
34162306a36Sopenharmony_ci	{ .pin = 3, .func = 1 },
34262306a36Sopenharmony_ci	{ .pin = 4, .func = 1 },
34362306a36Sopenharmony_ci	{ .pin = 5, .func = 1 },
34462306a36Sopenharmony_ci	{ .pin = 6, .func = 1 },
34562306a36Sopenharmony_ci	{ .pin = 7, .func = 1 },
34662306a36Sopenharmony_ci	{ .pin = 8, .func = 1 },
34762306a36Sopenharmony_ci	{ .pin = 9, .func = 1 },
34862306a36Sopenharmony_ci	{ .pin = 10, .func = 1 },
34962306a36Sopenharmony_ci	{ .pin = 11, .func = 1 },
35062306a36Sopenharmony_ci	{ .pin = 12, .func = 1 },
35162306a36Sopenharmony_ci	{ .pin = 13, .func = 1 },
35262306a36Sopenharmony_ci	{ .pin = 14, .func = 1 },
35362306a36Sopenharmony_ci	{ .pin = 15, .func = 1 },
35462306a36Sopenharmony_ci	{ .pin = 0, .func = 2 },
35562306a36Sopenharmony_ci	{ .pin = 1, .func = 2 },
35662306a36Sopenharmony_ci	{ .pin = 2, .func = 2 },
35762306a36Sopenharmony_ci	{ .pin = 3, .func = 2 },
35862306a36Sopenharmony_ci};
35962306a36Sopenharmony_ci
36062306a36Sopenharmony_cistatic const struct rza1_bidir_pin rza1l_bidir_pins_p6[] = {
36162306a36Sopenharmony_ci	{ .pin = 0, .func = 1 },
36262306a36Sopenharmony_ci	{ .pin = 1, .func = 1 },
36362306a36Sopenharmony_ci	{ .pin = 2, .func = 1 },
36462306a36Sopenharmony_ci	{ .pin = 3, .func = 1 },
36562306a36Sopenharmony_ci	{ .pin = 4, .func = 1 },
36662306a36Sopenharmony_ci	{ .pin = 5, .func = 1 },
36762306a36Sopenharmony_ci	{ .pin = 6, .func = 1 },
36862306a36Sopenharmony_ci	{ .pin = 7, .func = 1 },
36962306a36Sopenharmony_ci	{ .pin = 8, .func = 1 },
37062306a36Sopenharmony_ci	{ .pin = 9, .func = 1 },
37162306a36Sopenharmony_ci	{ .pin = 10, .func = 1 },
37262306a36Sopenharmony_ci	{ .pin = 11, .func = 1 },
37362306a36Sopenharmony_ci	{ .pin = 12, .func = 1 },
37462306a36Sopenharmony_ci	{ .pin = 13, .func = 1 },
37562306a36Sopenharmony_ci	{ .pin = 14, .func = 1 },
37662306a36Sopenharmony_ci	{ .pin = 15, .func = 1 },
37762306a36Sopenharmony_ci};
37862306a36Sopenharmony_ci
37962306a36Sopenharmony_cistatic const struct rza1_bidir_pin rza1l_bidir_pins_p7[] = {
38062306a36Sopenharmony_ci	{ .pin = 2, .func = 2 },
38162306a36Sopenharmony_ci	{ .pin = 3, .func = 2 },
38262306a36Sopenharmony_ci	{ .pin = 5, .func = 2 },
38362306a36Sopenharmony_ci	{ .pin = 6, .func = 2 },
38462306a36Sopenharmony_ci	{ .pin = 7, .func = 2 },
38562306a36Sopenharmony_ci	{ .pin = 2, .func = 3 },
38662306a36Sopenharmony_ci	{ .pin = 3, .func = 3 },
38762306a36Sopenharmony_ci	{ .pin = 5, .func = 3 },
38862306a36Sopenharmony_ci	{ .pin = 6, .func = 3 },
38962306a36Sopenharmony_ci	{ .pin = 7, .func = 3 },
39062306a36Sopenharmony_ci};
39162306a36Sopenharmony_ci
39262306a36Sopenharmony_cistatic const struct rza1_bidir_pin rza1l_bidir_pins_p9[] = {
39362306a36Sopenharmony_ci	{ .pin = 1, .func = 2 },
39462306a36Sopenharmony_ci	{ .pin = 0, .func = 3 },
39562306a36Sopenharmony_ci	{ .pin = 1, .func = 3 },
39662306a36Sopenharmony_ci	{ .pin = 3, .func = 3 },
39762306a36Sopenharmony_ci	{ .pin = 4, .func = 3 },
39862306a36Sopenharmony_ci	{ .pin = 5, .func = 3 },
39962306a36Sopenharmony_ci};
40062306a36Sopenharmony_ci
40162306a36Sopenharmony_cistatic const struct rza1_swio_pin rza1l_swio_pins[] = {
40262306a36Sopenharmony_ci	{ .port = 2, .pin = 8, .func = 2, .input = 0 },
40362306a36Sopenharmony_ci	{ .port = 5, .pin = 6, .func = 3, .input = 0 },
40462306a36Sopenharmony_ci	{ .port = 6, .pin = 6, .func = 3, .input = 0 },
40562306a36Sopenharmony_ci	{ .port = 6, .pin = 10, .func = 3, .input = 0 },
40662306a36Sopenharmony_ci	{ .port = 7, .pin = 10, .func = 2, .input = 0 },
40762306a36Sopenharmony_ci	{ .port = 8, .pin = 2, .func = 3, .input = 0 },
40862306a36Sopenharmony_ci};
40962306a36Sopenharmony_ci
41062306a36Sopenharmony_cistatic const struct rza1_bidir_entry rza1l_bidir_entries[RZA1_NPORTS] = {
41162306a36Sopenharmony_ci	[1] = { ARRAY_SIZE(rza1l_bidir_pins_p1), rza1l_bidir_pins_p1 },
41262306a36Sopenharmony_ci	[3] = { ARRAY_SIZE(rza1l_bidir_pins_p3), rza1l_bidir_pins_p3 },
41362306a36Sopenharmony_ci	[4] = { ARRAY_SIZE(rza1l_bidir_pins_p4), rza1l_bidir_pins_p4 },
41462306a36Sopenharmony_ci	[5] = { ARRAY_SIZE(rza1l_bidir_pins_p4), rza1l_bidir_pins_p5 },
41562306a36Sopenharmony_ci	[6] = { ARRAY_SIZE(rza1l_bidir_pins_p6), rza1l_bidir_pins_p6 },
41662306a36Sopenharmony_ci	[7] = { ARRAY_SIZE(rza1l_bidir_pins_p7), rza1l_bidir_pins_p7 },
41762306a36Sopenharmony_ci	[9] = { ARRAY_SIZE(rza1l_bidir_pins_p9), rza1l_bidir_pins_p9 },
41862306a36Sopenharmony_ci};
41962306a36Sopenharmony_ci
42062306a36Sopenharmony_cistatic const struct rza1_swio_entry rza1l_swio_entries[] = {
42162306a36Sopenharmony_ci	[0] = { ARRAY_SIZE(rza1l_swio_pins), rza1l_swio_pins },
42262306a36Sopenharmony_ci};
42362306a36Sopenharmony_ci
42462306a36Sopenharmony_ci/* RZ/A1L (r7s72102x) pinmux flags table */
42562306a36Sopenharmony_cistatic const struct rza1_pinmux_conf rza1l_pmx_conf = {
42662306a36Sopenharmony_ci	.bidir_entries	= rza1l_bidir_entries,
42762306a36Sopenharmony_ci	.swio_entries	= rza1l_swio_entries,
42862306a36Sopenharmony_ci};
42962306a36Sopenharmony_ci
43062306a36Sopenharmony_ci/* ----------------------------------------------------------------------------
43162306a36Sopenharmony_ci * RZ/A1 types
43262306a36Sopenharmony_ci */
43362306a36Sopenharmony_ci/**
43462306a36Sopenharmony_ci * struct rza1_mux_conf - describes a pin multiplexing operation
43562306a36Sopenharmony_ci *
43662306a36Sopenharmony_ci * @id: the pin identifier from 0 to RZA1_NPINS
43762306a36Sopenharmony_ci * @port: the port where pin sits on
43862306a36Sopenharmony_ci * @pin: pin id
43962306a36Sopenharmony_ci * @mux_func: alternate function id number
44062306a36Sopenharmony_ci * @mux_flags: alternate function flags
44162306a36Sopenharmony_ci * @value: output value to set the pin to
44262306a36Sopenharmony_ci */
44362306a36Sopenharmony_cistruct rza1_mux_conf {
44462306a36Sopenharmony_ci	u16 id;
44562306a36Sopenharmony_ci	u8 port;
44662306a36Sopenharmony_ci	u8 pin;
44762306a36Sopenharmony_ci	u8 mux_func;
44862306a36Sopenharmony_ci	u8 mux_flags;
44962306a36Sopenharmony_ci	u8 value;
45062306a36Sopenharmony_ci};
45162306a36Sopenharmony_ci
45262306a36Sopenharmony_ci/**
45362306a36Sopenharmony_ci * struct rza1_port - describes a pin port
45462306a36Sopenharmony_ci *
45562306a36Sopenharmony_ci * This is mostly useful to lock register writes per-bank and not globally.
45662306a36Sopenharmony_ci *
45762306a36Sopenharmony_ci * @lock: protect access to HW registers
45862306a36Sopenharmony_ci * @id: port number
45962306a36Sopenharmony_ci * @base: logical address base
46062306a36Sopenharmony_ci * @pins: pins sitting on this port
46162306a36Sopenharmony_ci */
46262306a36Sopenharmony_cistruct rza1_port {
46362306a36Sopenharmony_ci	spinlock_t lock;
46462306a36Sopenharmony_ci	unsigned int id;
46562306a36Sopenharmony_ci	void __iomem *base;
46662306a36Sopenharmony_ci	struct pinctrl_pin_desc *pins;
46762306a36Sopenharmony_ci};
46862306a36Sopenharmony_ci
46962306a36Sopenharmony_ci/**
47062306a36Sopenharmony_ci * struct rza1_pinctrl - RZ pincontroller device
47162306a36Sopenharmony_ci *
47262306a36Sopenharmony_ci * @dev: parent device structure
47362306a36Sopenharmony_ci * @mutex: protect [pinctrl|pinmux]_generic functions
47462306a36Sopenharmony_ci * @base: logical address base
47562306a36Sopenharmony_ci * @nport: number of pin controller ports
47662306a36Sopenharmony_ci * @ports: pin controller banks
47762306a36Sopenharmony_ci * @pins: pin array for pinctrl core
47862306a36Sopenharmony_ci * @desc: pincontroller desc for pinctrl core
47962306a36Sopenharmony_ci * @pctl: pinctrl device
48062306a36Sopenharmony_ci * @data: device specific data
48162306a36Sopenharmony_ci */
48262306a36Sopenharmony_cistruct rza1_pinctrl {
48362306a36Sopenharmony_ci	struct device *dev;
48462306a36Sopenharmony_ci
48562306a36Sopenharmony_ci	struct mutex mutex;
48662306a36Sopenharmony_ci
48762306a36Sopenharmony_ci	void __iomem *base;
48862306a36Sopenharmony_ci
48962306a36Sopenharmony_ci	unsigned int nport;
49062306a36Sopenharmony_ci	struct rza1_port *ports;
49162306a36Sopenharmony_ci
49262306a36Sopenharmony_ci	struct pinctrl_pin_desc *pins;
49362306a36Sopenharmony_ci	struct pinctrl_desc desc;
49462306a36Sopenharmony_ci	struct pinctrl_dev *pctl;
49562306a36Sopenharmony_ci
49662306a36Sopenharmony_ci	const void *data;
49762306a36Sopenharmony_ci};
49862306a36Sopenharmony_ci
49962306a36Sopenharmony_ci/* ----------------------------------------------------------------------------
50062306a36Sopenharmony_ci * RZ/A1 pinmux flags
50162306a36Sopenharmony_ci */
50262306a36Sopenharmony_cistatic inline bool rza1_pinmux_get_bidir(unsigned int port,
50362306a36Sopenharmony_ci					 unsigned int pin,
50462306a36Sopenharmony_ci					 unsigned int func,
50562306a36Sopenharmony_ci					 const struct rza1_bidir_entry *table)
50662306a36Sopenharmony_ci{
50762306a36Sopenharmony_ci	const struct rza1_bidir_entry *entry = &table[port];
50862306a36Sopenharmony_ci	const struct rza1_bidir_pin *bidir_pin;
50962306a36Sopenharmony_ci	unsigned int i;
51062306a36Sopenharmony_ci
51162306a36Sopenharmony_ci	for (i = 0; i < entry->npins; ++i) {
51262306a36Sopenharmony_ci		bidir_pin = &entry->pins[i];
51362306a36Sopenharmony_ci		if (bidir_pin->pin == pin && bidir_pin->func == func)
51462306a36Sopenharmony_ci			return true;
51562306a36Sopenharmony_ci	}
51662306a36Sopenharmony_ci
51762306a36Sopenharmony_ci	return false;
51862306a36Sopenharmony_ci}
51962306a36Sopenharmony_ci
52062306a36Sopenharmony_cistatic inline int rza1_pinmux_get_swio(unsigned int port,
52162306a36Sopenharmony_ci				       unsigned int pin,
52262306a36Sopenharmony_ci				       unsigned int func,
52362306a36Sopenharmony_ci				       const struct rza1_swio_entry *table)
52462306a36Sopenharmony_ci{
52562306a36Sopenharmony_ci	const struct rza1_swio_pin *swio_pin;
52662306a36Sopenharmony_ci	unsigned int i;
52762306a36Sopenharmony_ci
52862306a36Sopenharmony_ci
52962306a36Sopenharmony_ci	for (i = 0; i < table->npins; ++i) {
53062306a36Sopenharmony_ci		swio_pin = &table->pins[i];
53162306a36Sopenharmony_ci		if (swio_pin->port == port && swio_pin->pin == pin &&
53262306a36Sopenharmony_ci		    swio_pin->func == func)
53362306a36Sopenharmony_ci			return swio_pin->input;
53462306a36Sopenharmony_ci	}
53562306a36Sopenharmony_ci
53662306a36Sopenharmony_ci	return -ENOENT;
53762306a36Sopenharmony_ci}
53862306a36Sopenharmony_ci
53962306a36Sopenharmony_ci/*
54062306a36Sopenharmony_ci * rza1_pinmux_get_flags() - return pinmux flags associated to a pin
54162306a36Sopenharmony_ci */
54262306a36Sopenharmony_cistatic unsigned int rza1_pinmux_get_flags(unsigned int port, unsigned int pin,
54362306a36Sopenharmony_ci					  unsigned int func,
54462306a36Sopenharmony_ci					  struct rza1_pinctrl *rza1_pctl)
54562306a36Sopenharmony_ci
54662306a36Sopenharmony_ci{
54762306a36Sopenharmony_ci	const struct rza1_pinmux_conf *pmx_conf = rza1_pctl->data;
54862306a36Sopenharmony_ci	const struct rza1_bidir_entry *bidir_entries = pmx_conf->bidir_entries;
54962306a36Sopenharmony_ci	const struct rza1_swio_entry *swio_entries = pmx_conf->swio_entries;
55062306a36Sopenharmony_ci	unsigned int pmx_flags = 0;
55162306a36Sopenharmony_ci	int ret;
55262306a36Sopenharmony_ci
55362306a36Sopenharmony_ci	if (rza1_pinmux_get_bidir(port, pin, func, bidir_entries))
55462306a36Sopenharmony_ci		pmx_flags |= MUX_FLAGS_BIDIR;
55562306a36Sopenharmony_ci
55662306a36Sopenharmony_ci	ret = rza1_pinmux_get_swio(port, pin, func, swio_entries);
55762306a36Sopenharmony_ci	if (ret == 0)
55862306a36Sopenharmony_ci		pmx_flags |= MUX_FLAGS_SWIO_OUTPUT;
55962306a36Sopenharmony_ci	else if (ret > 0)
56062306a36Sopenharmony_ci		pmx_flags |= MUX_FLAGS_SWIO_INPUT;
56162306a36Sopenharmony_ci
56262306a36Sopenharmony_ci	return pmx_flags;
56362306a36Sopenharmony_ci}
56462306a36Sopenharmony_ci
56562306a36Sopenharmony_ci/* ----------------------------------------------------------------------------
56662306a36Sopenharmony_ci * RZ/A1 SoC operations
56762306a36Sopenharmony_ci */
56862306a36Sopenharmony_ci
56962306a36Sopenharmony_ci/*
57062306a36Sopenharmony_ci * rza1_set_bit() - un-locked set/clear a single bit in pin configuration
57162306a36Sopenharmony_ci *		    registers
57262306a36Sopenharmony_ci */
57362306a36Sopenharmony_cistatic inline void rza1_set_bit(struct rza1_port *port, unsigned int reg,
57462306a36Sopenharmony_ci				unsigned int bit, bool set)
57562306a36Sopenharmony_ci{
57662306a36Sopenharmony_ci	void __iomem *mem = RZA1_ADDR(port->base, reg, port->id);
57762306a36Sopenharmony_ci	u16 val = ioread16(mem);
57862306a36Sopenharmony_ci
57962306a36Sopenharmony_ci	if (set)
58062306a36Sopenharmony_ci		val |= BIT(bit);
58162306a36Sopenharmony_ci	else
58262306a36Sopenharmony_ci		val &= ~BIT(bit);
58362306a36Sopenharmony_ci
58462306a36Sopenharmony_ci	iowrite16(val, mem);
58562306a36Sopenharmony_ci}
58662306a36Sopenharmony_ci
58762306a36Sopenharmony_cistatic inline unsigned int rza1_get_bit(struct rza1_port *port,
58862306a36Sopenharmony_ci					unsigned int reg, unsigned int bit)
58962306a36Sopenharmony_ci{
59062306a36Sopenharmony_ci	void __iomem *mem = RZA1_ADDR(port->base, reg, port->id);
59162306a36Sopenharmony_ci
59262306a36Sopenharmony_ci	return ioread16(mem) & BIT(bit);
59362306a36Sopenharmony_ci}
59462306a36Sopenharmony_ci
59562306a36Sopenharmony_ci/**
59662306a36Sopenharmony_ci * rza1_pin_reset() - reset a pin to default initial state
59762306a36Sopenharmony_ci *
59862306a36Sopenharmony_ci * Reset pin state disabling input buffer and bi-directional control,
59962306a36Sopenharmony_ci * and configure it as input port.
60062306a36Sopenharmony_ci * Note that pin is now configured with direction as input but with input
60162306a36Sopenharmony_ci * buffer disabled. This implies the pin value cannot be read in this state.
60262306a36Sopenharmony_ci *
60362306a36Sopenharmony_ci * @port: port where pin sits on
60462306a36Sopenharmony_ci * @pin: pin offset
60562306a36Sopenharmony_ci */
60662306a36Sopenharmony_cistatic void rza1_pin_reset(struct rza1_port *port, unsigned int pin)
60762306a36Sopenharmony_ci{
60862306a36Sopenharmony_ci	unsigned long irqflags;
60962306a36Sopenharmony_ci
61062306a36Sopenharmony_ci	spin_lock_irqsave(&port->lock, irqflags);
61162306a36Sopenharmony_ci	rza1_set_bit(port, RZA1_PIBC_REG, pin, 0);
61262306a36Sopenharmony_ci	rza1_set_bit(port, RZA1_PBDC_REG, pin, 0);
61362306a36Sopenharmony_ci
61462306a36Sopenharmony_ci	rza1_set_bit(port, RZA1_PM_REG, pin, 1);
61562306a36Sopenharmony_ci	rza1_set_bit(port, RZA1_PMC_REG, pin, 0);
61662306a36Sopenharmony_ci	rza1_set_bit(port, RZA1_PIPC_REG, pin, 0);
61762306a36Sopenharmony_ci	spin_unlock_irqrestore(&port->lock, irqflags);
61862306a36Sopenharmony_ci}
61962306a36Sopenharmony_ci
62062306a36Sopenharmony_ci/**
62162306a36Sopenharmony_ci * rza1_pin_set_direction() - set I/O direction on a pin in port mode
62262306a36Sopenharmony_ci *
62362306a36Sopenharmony_ci * When running in output port mode keep PBDC enabled to allow reading the
62462306a36Sopenharmony_ci * pin value from PPR.
62562306a36Sopenharmony_ci *
62662306a36Sopenharmony_ci * @port: port where pin sits on
62762306a36Sopenharmony_ci * @pin: pin offset
62862306a36Sopenharmony_ci * @input: input enable/disable flag
62962306a36Sopenharmony_ci */
63062306a36Sopenharmony_cistatic inline void rza1_pin_set_direction(struct rza1_port *port,
63162306a36Sopenharmony_ci					  unsigned int pin, bool input)
63262306a36Sopenharmony_ci{
63362306a36Sopenharmony_ci	unsigned long irqflags;
63462306a36Sopenharmony_ci
63562306a36Sopenharmony_ci	spin_lock_irqsave(&port->lock, irqflags);
63662306a36Sopenharmony_ci
63762306a36Sopenharmony_ci	rza1_set_bit(port, RZA1_PIBC_REG, pin, 1);
63862306a36Sopenharmony_ci	if (input) {
63962306a36Sopenharmony_ci		rza1_set_bit(port, RZA1_PM_REG, pin, 1);
64062306a36Sopenharmony_ci		rza1_set_bit(port, RZA1_PBDC_REG, pin, 0);
64162306a36Sopenharmony_ci	} else {
64262306a36Sopenharmony_ci		rza1_set_bit(port, RZA1_PM_REG, pin, 0);
64362306a36Sopenharmony_ci		rza1_set_bit(port, RZA1_PBDC_REG, pin, 1);
64462306a36Sopenharmony_ci	}
64562306a36Sopenharmony_ci
64662306a36Sopenharmony_ci	spin_unlock_irqrestore(&port->lock, irqflags);
64762306a36Sopenharmony_ci}
64862306a36Sopenharmony_ci
64962306a36Sopenharmony_cistatic inline void rza1_pin_set(struct rza1_port *port, unsigned int pin,
65062306a36Sopenharmony_ci				unsigned int value)
65162306a36Sopenharmony_ci{
65262306a36Sopenharmony_ci	unsigned long irqflags;
65362306a36Sopenharmony_ci
65462306a36Sopenharmony_ci	spin_lock_irqsave(&port->lock, irqflags);
65562306a36Sopenharmony_ci	rza1_set_bit(port, RZA1_P_REG, pin, !!value);
65662306a36Sopenharmony_ci	spin_unlock_irqrestore(&port->lock, irqflags);
65762306a36Sopenharmony_ci}
65862306a36Sopenharmony_ci
65962306a36Sopenharmony_cistatic inline int rza1_pin_get(struct rza1_port *port, unsigned int pin)
66062306a36Sopenharmony_ci{
66162306a36Sopenharmony_ci	return rza1_get_bit(port, RZA1_PPR_REG, pin);
66262306a36Sopenharmony_ci}
66362306a36Sopenharmony_ci
66462306a36Sopenharmony_ci/**
66562306a36Sopenharmony_ci * rza1_pin_mux_single() - configure pin multiplexing on a single pin
66662306a36Sopenharmony_ci *
66762306a36Sopenharmony_ci * @rza1_pctl: RZ/A1 pin controller device
66862306a36Sopenharmony_ci * @mux_conf: pin multiplexing descriptor
66962306a36Sopenharmony_ci */
67062306a36Sopenharmony_cistatic int rza1_pin_mux_single(struct rza1_pinctrl *rza1_pctl,
67162306a36Sopenharmony_ci			       struct rza1_mux_conf *mux_conf)
67262306a36Sopenharmony_ci{
67362306a36Sopenharmony_ci	struct rza1_port *port = &rza1_pctl->ports[mux_conf->port];
67462306a36Sopenharmony_ci	unsigned int pin = mux_conf->pin;
67562306a36Sopenharmony_ci	u8 mux_func = mux_conf->mux_func;
67662306a36Sopenharmony_ci	u8 mux_flags = mux_conf->mux_flags;
67762306a36Sopenharmony_ci	u8 mux_flags_from_table;
67862306a36Sopenharmony_ci
67962306a36Sopenharmony_ci	rza1_pin_reset(port, pin);
68062306a36Sopenharmony_ci
68162306a36Sopenharmony_ci	/* SWIO pinmux flags coming from DT are high precedence */
68262306a36Sopenharmony_ci	mux_flags_from_table = rza1_pinmux_get_flags(port->id, pin, mux_func,
68362306a36Sopenharmony_ci						     rza1_pctl);
68462306a36Sopenharmony_ci	if (mux_flags)
68562306a36Sopenharmony_ci		mux_flags |= (mux_flags_from_table & MUX_FLAGS_BIDIR);
68662306a36Sopenharmony_ci	else
68762306a36Sopenharmony_ci		mux_flags = mux_flags_from_table;
68862306a36Sopenharmony_ci
68962306a36Sopenharmony_ci	if (mux_flags & MUX_FLAGS_BIDIR)
69062306a36Sopenharmony_ci		rza1_set_bit(port, RZA1_PBDC_REG, pin, 1);
69162306a36Sopenharmony_ci
69262306a36Sopenharmony_ci	/*
69362306a36Sopenharmony_ci	 * Enable alternate function mode and select it.
69462306a36Sopenharmony_ci	 *
69562306a36Sopenharmony_ci	 * Be careful here: the pin mux sub-nodes in device tree
69662306a36Sopenharmony_ci	 * enumerate alternate functions from 1 to 8;
69762306a36Sopenharmony_ci	 * subtract 1 before using macros to match registers configuration
69862306a36Sopenharmony_ci	 * which expects numbers from 0 to 7 instead.
69962306a36Sopenharmony_ci	 *
70062306a36Sopenharmony_ci	 * ----------------------------------------------------
70162306a36Sopenharmony_ci	 * Alternate mode selection table:
70262306a36Sopenharmony_ci	 *
70362306a36Sopenharmony_ci	 * PMC	PFC	PFCE	PFCAE	(mux_func - 1)
70462306a36Sopenharmony_ci	 * 1	0	0	0	0
70562306a36Sopenharmony_ci	 * 1	1	0	0	1
70662306a36Sopenharmony_ci	 * 1	0	1	0	2
70762306a36Sopenharmony_ci	 * 1	1	1	0	3
70862306a36Sopenharmony_ci	 * 1	0	0	1	4
70962306a36Sopenharmony_ci	 * 1	1	0	1	5
71062306a36Sopenharmony_ci	 * 1	0	1	1	6
71162306a36Sopenharmony_ci	 * 1	1	1	1	7
71262306a36Sopenharmony_ci	 * ----------------------------------------------------
71362306a36Sopenharmony_ci	 */
71462306a36Sopenharmony_ci	mux_func -= 1;
71562306a36Sopenharmony_ci	rza1_set_bit(port, RZA1_PFC_REG, pin, mux_func & MUX_FUNC_PFC_MASK);
71662306a36Sopenharmony_ci	rza1_set_bit(port, RZA1_PFCE_REG, pin, mux_func & MUX_FUNC_PFCE_MASK);
71762306a36Sopenharmony_ci	rza1_set_bit(port, RZA1_PFCEA_REG, pin, mux_func & MUX_FUNC_PFCEA_MASK);
71862306a36Sopenharmony_ci
71962306a36Sopenharmony_ci	/*
72062306a36Sopenharmony_ci	 * All alternate functions except a few need PIPCn = 1.
72162306a36Sopenharmony_ci	 * If PIPCn has to stay disabled (SW IO mode), configure PMn according
72262306a36Sopenharmony_ci	 * to I/O direction specified by pin configuration -after- PMC has been
72362306a36Sopenharmony_ci	 * set to one.
72462306a36Sopenharmony_ci	 */
72562306a36Sopenharmony_ci	if (mux_flags & (MUX_FLAGS_SWIO_INPUT | MUX_FLAGS_SWIO_OUTPUT))
72662306a36Sopenharmony_ci		rza1_set_bit(port, RZA1_PM_REG, pin,
72762306a36Sopenharmony_ci			     mux_flags & MUX_FLAGS_SWIO_INPUT);
72862306a36Sopenharmony_ci	else
72962306a36Sopenharmony_ci		rza1_set_bit(port, RZA1_PIPC_REG, pin, 1);
73062306a36Sopenharmony_ci
73162306a36Sopenharmony_ci	rza1_set_bit(port, RZA1_PMC_REG, pin, 1);
73262306a36Sopenharmony_ci
73362306a36Sopenharmony_ci	return 0;
73462306a36Sopenharmony_ci}
73562306a36Sopenharmony_ci
73662306a36Sopenharmony_ci/* ----------------------------------------------------------------------------
73762306a36Sopenharmony_ci * gpio operations
73862306a36Sopenharmony_ci */
73962306a36Sopenharmony_ci
74062306a36Sopenharmony_ci/**
74162306a36Sopenharmony_ci * rza1_gpio_request() - configure pin in port mode
74262306a36Sopenharmony_ci *
74362306a36Sopenharmony_ci * Configure a pin as gpio (port mode).
74462306a36Sopenharmony_ci * After reset, the pin is in input mode with input buffer disabled.
74562306a36Sopenharmony_ci * To use the pin as input or output, set_direction shall be called first
74662306a36Sopenharmony_ci *
74762306a36Sopenharmony_ci * @chip: gpio chip where the gpio sits on
74862306a36Sopenharmony_ci * @gpio: gpio offset
74962306a36Sopenharmony_ci */
75062306a36Sopenharmony_cistatic int rza1_gpio_request(struct gpio_chip *chip, unsigned int gpio)
75162306a36Sopenharmony_ci{
75262306a36Sopenharmony_ci	struct rza1_port *port = gpiochip_get_data(chip);
75362306a36Sopenharmony_ci
75462306a36Sopenharmony_ci	rza1_pin_reset(port, gpio);
75562306a36Sopenharmony_ci
75662306a36Sopenharmony_ci	return 0;
75762306a36Sopenharmony_ci}
75862306a36Sopenharmony_ci
75962306a36Sopenharmony_ci/**
76062306a36Sopenharmony_ci * rza1_gpio_free() - reset a pin
76162306a36Sopenharmony_ci *
76262306a36Sopenharmony_ci * Surprisingly, freeing a gpio is equivalent to requesting it.
76362306a36Sopenharmony_ci * Reset pin to port mode, with input buffer disabled. This overwrites all
76462306a36Sopenharmony_ci * port direction settings applied with set_direction
76562306a36Sopenharmony_ci *
76662306a36Sopenharmony_ci * @chip: gpio chip where the gpio sits on
76762306a36Sopenharmony_ci * @gpio: gpio offset
76862306a36Sopenharmony_ci */
76962306a36Sopenharmony_cistatic void rza1_gpio_free(struct gpio_chip *chip, unsigned int gpio)
77062306a36Sopenharmony_ci{
77162306a36Sopenharmony_ci	struct rza1_port *port = gpiochip_get_data(chip);
77262306a36Sopenharmony_ci
77362306a36Sopenharmony_ci	rza1_pin_reset(port, gpio);
77462306a36Sopenharmony_ci}
77562306a36Sopenharmony_ci
77662306a36Sopenharmony_cistatic int rza1_gpio_get_direction(struct gpio_chip *chip, unsigned int gpio)
77762306a36Sopenharmony_ci{
77862306a36Sopenharmony_ci	struct rza1_port *port = gpiochip_get_data(chip);
77962306a36Sopenharmony_ci
78062306a36Sopenharmony_ci	if (rza1_get_bit(port, RZA1_PM_REG, gpio))
78162306a36Sopenharmony_ci		return GPIO_LINE_DIRECTION_IN;
78262306a36Sopenharmony_ci
78362306a36Sopenharmony_ci	return GPIO_LINE_DIRECTION_OUT;
78462306a36Sopenharmony_ci}
78562306a36Sopenharmony_ci
78662306a36Sopenharmony_cistatic int rza1_gpio_direction_input(struct gpio_chip *chip,
78762306a36Sopenharmony_ci				     unsigned int gpio)
78862306a36Sopenharmony_ci{
78962306a36Sopenharmony_ci	struct rza1_port *port = gpiochip_get_data(chip);
79062306a36Sopenharmony_ci
79162306a36Sopenharmony_ci	rza1_pin_set_direction(port, gpio, true);
79262306a36Sopenharmony_ci
79362306a36Sopenharmony_ci	return 0;
79462306a36Sopenharmony_ci}
79562306a36Sopenharmony_ci
79662306a36Sopenharmony_cistatic int rza1_gpio_direction_output(struct gpio_chip *chip,
79762306a36Sopenharmony_ci				      unsigned int gpio,
79862306a36Sopenharmony_ci				      int value)
79962306a36Sopenharmony_ci{
80062306a36Sopenharmony_ci	struct rza1_port *port = gpiochip_get_data(chip);
80162306a36Sopenharmony_ci
80262306a36Sopenharmony_ci	/* Set value before driving pin direction */
80362306a36Sopenharmony_ci	rza1_pin_set(port, gpio, value);
80462306a36Sopenharmony_ci	rza1_pin_set_direction(port, gpio, false);
80562306a36Sopenharmony_ci
80662306a36Sopenharmony_ci	return 0;
80762306a36Sopenharmony_ci}
80862306a36Sopenharmony_ci
80962306a36Sopenharmony_ci/**
81062306a36Sopenharmony_ci * rza1_gpio_get() - read a gpio pin value
81162306a36Sopenharmony_ci *
81262306a36Sopenharmony_ci * Read gpio pin value through PPR register.
81362306a36Sopenharmony_ci * Requires bi-directional mode to work when reading the value of a pin
81462306a36Sopenharmony_ci * in output mode
81562306a36Sopenharmony_ci *
81662306a36Sopenharmony_ci * @chip: gpio chip where the gpio sits on
81762306a36Sopenharmony_ci * @gpio: gpio offset
81862306a36Sopenharmony_ci */
81962306a36Sopenharmony_cistatic int rza1_gpio_get(struct gpio_chip *chip, unsigned int gpio)
82062306a36Sopenharmony_ci{
82162306a36Sopenharmony_ci	struct rza1_port *port = gpiochip_get_data(chip);
82262306a36Sopenharmony_ci
82362306a36Sopenharmony_ci	return rza1_pin_get(port, gpio);
82462306a36Sopenharmony_ci}
82562306a36Sopenharmony_ci
82662306a36Sopenharmony_cistatic void rza1_gpio_set(struct gpio_chip *chip, unsigned int gpio,
82762306a36Sopenharmony_ci			  int value)
82862306a36Sopenharmony_ci{
82962306a36Sopenharmony_ci	struct rza1_port *port = gpiochip_get_data(chip);
83062306a36Sopenharmony_ci
83162306a36Sopenharmony_ci	rza1_pin_set(port, gpio, value);
83262306a36Sopenharmony_ci}
83362306a36Sopenharmony_ci
83462306a36Sopenharmony_cistatic const struct gpio_chip rza1_gpiochip_template = {
83562306a36Sopenharmony_ci	.request		= rza1_gpio_request,
83662306a36Sopenharmony_ci	.free			= rza1_gpio_free,
83762306a36Sopenharmony_ci	.get_direction		= rza1_gpio_get_direction,
83862306a36Sopenharmony_ci	.direction_input	= rza1_gpio_direction_input,
83962306a36Sopenharmony_ci	.direction_output	= rza1_gpio_direction_output,
84062306a36Sopenharmony_ci	.get			= rza1_gpio_get,
84162306a36Sopenharmony_ci	.set			= rza1_gpio_set,
84262306a36Sopenharmony_ci};
84362306a36Sopenharmony_ci/* ----------------------------------------------------------------------------
84462306a36Sopenharmony_ci * pinctrl operations
84562306a36Sopenharmony_ci */
84662306a36Sopenharmony_ci
84762306a36Sopenharmony_ci/**
84862306a36Sopenharmony_ci * rza1_dt_node_pin_count() - Count number of pins in a dt node or in all its
84962306a36Sopenharmony_ci *			      children sub-nodes
85062306a36Sopenharmony_ci *
85162306a36Sopenharmony_ci * @np: device tree node to parse
85262306a36Sopenharmony_ci */
85362306a36Sopenharmony_cistatic int rza1_dt_node_pin_count(struct device_node *np)
85462306a36Sopenharmony_ci{
85562306a36Sopenharmony_ci	struct device_node *child;
85662306a36Sopenharmony_ci	struct property *of_pins;
85762306a36Sopenharmony_ci	unsigned int npins;
85862306a36Sopenharmony_ci
85962306a36Sopenharmony_ci	of_pins = of_find_property(np, "pinmux", NULL);
86062306a36Sopenharmony_ci	if (of_pins)
86162306a36Sopenharmony_ci		return of_pins->length / sizeof(u32);
86262306a36Sopenharmony_ci
86362306a36Sopenharmony_ci	npins = 0;
86462306a36Sopenharmony_ci	for_each_child_of_node(np, child) {
86562306a36Sopenharmony_ci		of_pins = of_find_property(child, "pinmux", NULL);
86662306a36Sopenharmony_ci		if (!of_pins) {
86762306a36Sopenharmony_ci			of_node_put(child);
86862306a36Sopenharmony_ci			return -EINVAL;
86962306a36Sopenharmony_ci		}
87062306a36Sopenharmony_ci
87162306a36Sopenharmony_ci		npins += of_pins->length / sizeof(u32);
87262306a36Sopenharmony_ci	}
87362306a36Sopenharmony_ci
87462306a36Sopenharmony_ci	return npins;
87562306a36Sopenharmony_ci}
87662306a36Sopenharmony_ci
87762306a36Sopenharmony_ci/**
87862306a36Sopenharmony_ci * rza1_parse_pinmux_node() - parse a pin mux sub-node
87962306a36Sopenharmony_ci *
88062306a36Sopenharmony_ci * @rza1_pctl: RZ/A1 pin controller device
88162306a36Sopenharmony_ci * @np: of pmx sub-node
88262306a36Sopenharmony_ci * @mux_confs: array of pin mux configurations to fill with parsed info
88362306a36Sopenharmony_ci * @grpins: array of pin ids to mux
88462306a36Sopenharmony_ci */
88562306a36Sopenharmony_cistatic int rza1_parse_pinmux_node(struct rza1_pinctrl *rza1_pctl,
88662306a36Sopenharmony_ci				  struct device_node *np,
88762306a36Sopenharmony_ci				  struct rza1_mux_conf *mux_confs,
88862306a36Sopenharmony_ci				  unsigned int *grpins)
88962306a36Sopenharmony_ci{
89062306a36Sopenharmony_ci	struct pinctrl_dev *pctldev = rza1_pctl->pctl;
89162306a36Sopenharmony_ci	char const *prop_name = "pinmux";
89262306a36Sopenharmony_ci	unsigned long *pin_configs;
89362306a36Sopenharmony_ci	unsigned int npin_configs;
89462306a36Sopenharmony_ci	struct property *of_pins;
89562306a36Sopenharmony_ci	unsigned int npins;
89662306a36Sopenharmony_ci	u8 pinmux_flags;
89762306a36Sopenharmony_ci	unsigned int i;
89862306a36Sopenharmony_ci	int ret;
89962306a36Sopenharmony_ci
90062306a36Sopenharmony_ci	of_pins = of_find_property(np, prop_name, NULL);
90162306a36Sopenharmony_ci	if (!of_pins) {
90262306a36Sopenharmony_ci		dev_dbg(rza1_pctl->dev, "Missing %s property\n", prop_name);
90362306a36Sopenharmony_ci		return -ENOENT;
90462306a36Sopenharmony_ci	}
90562306a36Sopenharmony_ci	npins = of_pins->length / sizeof(u32);
90662306a36Sopenharmony_ci
90762306a36Sopenharmony_ci	/*
90862306a36Sopenharmony_ci	 * Collect pin configuration properties: they apply to all pins in
90962306a36Sopenharmony_ci	 * this sub-node
91062306a36Sopenharmony_ci	 */
91162306a36Sopenharmony_ci	ret = pinconf_generic_parse_dt_config(np, pctldev, &pin_configs,
91262306a36Sopenharmony_ci					      &npin_configs);
91362306a36Sopenharmony_ci	if (ret) {
91462306a36Sopenharmony_ci		dev_err(rza1_pctl->dev,
91562306a36Sopenharmony_ci			"Unable to parse pin configuration options for %pOFn\n",
91662306a36Sopenharmony_ci			np);
91762306a36Sopenharmony_ci		return ret;
91862306a36Sopenharmony_ci	}
91962306a36Sopenharmony_ci
92062306a36Sopenharmony_ci	/*
92162306a36Sopenharmony_ci	 * Create a mask with pinmux flags from pin configuration;
92262306a36Sopenharmony_ci	 * very few pins (TIOC[0-4][A|B|C|D] require SWIO direction
92362306a36Sopenharmony_ci	 * specified in device tree.
92462306a36Sopenharmony_ci	 */
92562306a36Sopenharmony_ci	pinmux_flags = 0;
92662306a36Sopenharmony_ci	for (i = 0; i < npin_configs && pinmux_flags == 0; i++)
92762306a36Sopenharmony_ci		switch (pinconf_to_config_param(pin_configs[i])) {
92862306a36Sopenharmony_ci		case PIN_CONFIG_INPUT_ENABLE:
92962306a36Sopenharmony_ci			pinmux_flags |= MUX_FLAGS_SWIO_INPUT;
93062306a36Sopenharmony_ci			break;
93162306a36Sopenharmony_ci		case PIN_CONFIG_OUTPUT:	/* for DT backwards compatibility */
93262306a36Sopenharmony_ci		case PIN_CONFIG_OUTPUT_ENABLE:
93362306a36Sopenharmony_ci			pinmux_flags |= MUX_FLAGS_SWIO_OUTPUT;
93462306a36Sopenharmony_ci			break;
93562306a36Sopenharmony_ci		default:
93662306a36Sopenharmony_ci			break;
93762306a36Sopenharmony_ci
93862306a36Sopenharmony_ci		}
93962306a36Sopenharmony_ci
94062306a36Sopenharmony_ci	kfree(pin_configs);
94162306a36Sopenharmony_ci
94262306a36Sopenharmony_ci	/* Collect pin positions and their mux settings. */
94362306a36Sopenharmony_ci	for (i = 0; i < npins; ++i) {
94462306a36Sopenharmony_ci		u32 of_pinconf;
94562306a36Sopenharmony_ci		struct rza1_mux_conf *mux_conf = &mux_confs[i];
94662306a36Sopenharmony_ci
94762306a36Sopenharmony_ci		ret = of_property_read_u32_index(np, prop_name, i, &of_pinconf);
94862306a36Sopenharmony_ci		if (ret)
94962306a36Sopenharmony_ci			return ret;
95062306a36Sopenharmony_ci
95162306a36Sopenharmony_ci		mux_conf->id		= of_pinconf & MUX_PIN_ID_MASK;
95262306a36Sopenharmony_ci		mux_conf->port		= RZA1_PIN_ID_TO_PORT(mux_conf->id);
95362306a36Sopenharmony_ci		mux_conf->pin		= RZA1_PIN_ID_TO_PIN(mux_conf->id);
95462306a36Sopenharmony_ci		mux_conf->mux_func	= MUX_FUNC(of_pinconf);
95562306a36Sopenharmony_ci		mux_conf->mux_flags	= pinmux_flags;
95662306a36Sopenharmony_ci
95762306a36Sopenharmony_ci		if (mux_conf->port >= RZA1_NPORTS ||
95862306a36Sopenharmony_ci		    mux_conf->pin >= RZA1_PINS_PER_PORT) {
95962306a36Sopenharmony_ci			dev_err(rza1_pctl->dev,
96062306a36Sopenharmony_ci				"Wrong port %u pin %u for %s property\n",
96162306a36Sopenharmony_ci				mux_conf->port, mux_conf->pin, prop_name);
96262306a36Sopenharmony_ci			return -EINVAL;
96362306a36Sopenharmony_ci		}
96462306a36Sopenharmony_ci
96562306a36Sopenharmony_ci		grpins[i] = mux_conf->id;
96662306a36Sopenharmony_ci	}
96762306a36Sopenharmony_ci
96862306a36Sopenharmony_ci	return npins;
96962306a36Sopenharmony_ci}
97062306a36Sopenharmony_ci
97162306a36Sopenharmony_ci/**
97262306a36Sopenharmony_ci * rza1_dt_node_to_map() - map a pin mux node to a function/group
97362306a36Sopenharmony_ci *
97462306a36Sopenharmony_ci * Parse and register a pin mux function.
97562306a36Sopenharmony_ci *
97662306a36Sopenharmony_ci * @pctldev: pin controller device
97762306a36Sopenharmony_ci * @np: device tree node to parse
97862306a36Sopenharmony_ci * @map: pointer to pin map (output)
97962306a36Sopenharmony_ci * @num_maps: number of collected maps (output)
98062306a36Sopenharmony_ci */
98162306a36Sopenharmony_cistatic int rza1_dt_node_to_map(struct pinctrl_dev *pctldev,
98262306a36Sopenharmony_ci			       struct device_node *np,
98362306a36Sopenharmony_ci			       struct pinctrl_map **map,
98462306a36Sopenharmony_ci			       unsigned int *num_maps)
98562306a36Sopenharmony_ci{
98662306a36Sopenharmony_ci	struct rza1_pinctrl *rza1_pctl = pinctrl_dev_get_drvdata(pctldev);
98762306a36Sopenharmony_ci	struct rza1_mux_conf *mux_confs, *mux_conf;
98862306a36Sopenharmony_ci	unsigned int *grpins, *grpin;
98962306a36Sopenharmony_ci	struct device_node *child;
99062306a36Sopenharmony_ci	const char *grpname;
99162306a36Sopenharmony_ci	const char **fngrps;
99262306a36Sopenharmony_ci	int ret, npins;
99362306a36Sopenharmony_ci	int gsel, fsel;
99462306a36Sopenharmony_ci
99562306a36Sopenharmony_ci	npins = rza1_dt_node_pin_count(np);
99662306a36Sopenharmony_ci	if (npins < 0) {
99762306a36Sopenharmony_ci		dev_err(rza1_pctl->dev, "invalid pinmux node structure\n");
99862306a36Sopenharmony_ci		return -EINVAL;
99962306a36Sopenharmony_ci	}
100062306a36Sopenharmony_ci
100162306a36Sopenharmony_ci	/*
100262306a36Sopenharmony_ci	 * Functions are made of 1 group only;
100362306a36Sopenharmony_ci	 * in fact, functions and groups are identical for this pin controller
100462306a36Sopenharmony_ci	 * except that functions carry an array of per-pin mux configuration
100562306a36Sopenharmony_ci	 * settings.
100662306a36Sopenharmony_ci	 */
100762306a36Sopenharmony_ci	mux_confs = devm_kcalloc(rza1_pctl->dev, npins, sizeof(*mux_confs),
100862306a36Sopenharmony_ci				 GFP_KERNEL);
100962306a36Sopenharmony_ci	grpins = devm_kcalloc(rza1_pctl->dev, npins, sizeof(*grpins),
101062306a36Sopenharmony_ci			      GFP_KERNEL);
101162306a36Sopenharmony_ci	fngrps = devm_kzalloc(rza1_pctl->dev, sizeof(*fngrps), GFP_KERNEL);
101262306a36Sopenharmony_ci
101362306a36Sopenharmony_ci	if (!mux_confs || !grpins || !fngrps)
101462306a36Sopenharmony_ci		return -ENOMEM;
101562306a36Sopenharmony_ci
101662306a36Sopenharmony_ci	/*
101762306a36Sopenharmony_ci	 * Parse the pinmux node.
101862306a36Sopenharmony_ci	 * If the node does not contain "pinmux" property (-ENOENT)
101962306a36Sopenharmony_ci	 * that property shall be specified in all its children sub-nodes.
102062306a36Sopenharmony_ci	 */
102162306a36Sopenharmony_ci	mux_conf = &mux_confs[0];
102262306a36Sopenharmony_ci	grpin = &grpins[0];
102362306a36Sopenharmony_ci
102462306a36Sopenharmony_ci	ret = rza1_parse_pinmux_node(rza1_pctl, np, mux_conf, grpin);
102562306a36Sopenharmony_ci	if (ret == -ENOENT)
102662306a36Sopenharmony_ci		for_each_child_of_node(np, child) {
102762306a36Sopenharmony_ci			ret = rza1_parse_pinmux_node(rza1_pctl, child, mux_conf,
102862306a36Sopenharmony_ci						     grpin);
102962306a36Sopenharmony_ci			if (ret < 0) {
103062306a36Sopenharmony_ci				of_node_put(child);
103162306a36Sopenharmony_ci				return ret;
103262306a36Sopenharmony_ci			}
103362306a36Sopenharmony_ci
103462306a36Sopenharmony_ci			grpin += ret;
103562306a36Sopenharmony_ci			mux_conf += ret;
103662306a36Sopenharmony_ci		}
103762306a36Sopenharmony_ci	else if (ret < 0)
103862306a36Sopenharmony_ci		return ret;
103962306a36Sopenharmony_ci
104062306a36Sopenharmony_ci	/* Register pin group and function name to pinctrl_generic */
104162306a36Sopenharmony_ci	grpname	= np->name;
104262306a36Sopenharmony_ci	fngrps[0] = grpname;
104362306a36Sopenharmony_ci
104462306a36Sopenharmony_ci	mutex_lock(&rza1_pctl->mutex);
104562306a36Sopenharmony_ci	gsel = pinctrl_generic_add_group(pctldev, grpname, grpins, npins,
104662306a36Sopenharmony_ci					 NULL);
104762306a36Sopenharmony_ci	if (gsel < 0) {
104862306a36Sopenharmony_ci		mutex_unlock(&rza1_pctl->mutex);
104962306a36Sopenharmony_ci		return gsel;
105062306a36Sopenharmony_ci	}
105162306a36Sopenharmony_ci
105262306a36Sopenharmony_ci	fsel = pinmux_generic_add_function(pctldev, grpname, fngrps, 1,
105362306a36Sopenharmony_ci					   mux_confs);
105462306a36Sopenharmony_ci	if (fsel < 0) {
105562306a36Sopenharmony_ci		ret = fsel;
105662306a36Sopenharmony_ci		goto remove_group;
105762306a36Sopenharmony_ci	}
105862306a36Sopenharmony_ci
105962306a36Sopenharmony_ci	dev_info(rza1_pctl->dev, "Parsed function and group %s with %d pins\n",
106062306a36Sopenharmony_ci				 grpname, npins);
106162306a36Sopenharmony_ci
106262306a36Sopenharmony_ci	/* Create map where to retrieve function and mux settings from */
106362306a36Sopenharmony_ci	*num_maps = 0;
106462306a36Sopenharmony_ci	*map = kzalloc(sizeof(**map), GFP_KERNEL);
106562306a36Sopenharmony_ci	if (!*map) {
106662306a36Sopenharmony_ci		ret = -ENOMEM;
106762306a36Sopenharmony_ci		goto remove_function;
106862306a36Sopenharmony_ci	}
106962306a36Sopenharmony_ci
107062306a36Sopenharmony_ci	(*map)->type = PIN_MAP_TYPE_MUX_GROUP;
107162306a36Sopenharmony_ci	(*map)->data.mux.group = np->name;
107262306a36Sopenharmony_ci	(*map)->data.mux.function = np->name;
107362306a36Sopenharmony_ci	*num_maps = 1;
107462306a36Sopenharmony_ci	mutex_unlock(&rza1_pctl->mutex);
107562306a36Sopenharmony_ci
107662306a36Sopenharmony_ci	return 0;
107762306a36Sopenharmony_ci
107862306a36Sopenharmony_ciremove_function:
107962306a36Sopenharmony_ci	pinmux_generic_remove_function(pctldev, fsel);
108062306a36Sopenharmony_ci
108162306a36Sopenharmony_ciremove_group:
108262306a36Sopenharmony_ci	pinctrl_generic_remove_group(pctldev, gsel);
108362306a36Sopenharmony_ci	mutex_unlock(&rza1_pctl->mutex);
108462306a36Sopenharmony_ci
108562306a36Sopenharmony_ci	dev_info(rza1_pctl->dev, "Unable to parse function and group %s\n",
108662306a36Sopenharmony_ci				 grpname);
108762306a36Sopenharmony_ci
108862306a36Sopenharmony_ci	return ret;
108962306a36Sopenharmony_ci}
109062306a36Sopenharmony_ci
109162306a36Sopenharmony_cistatic void rza1_dt_free_map(struct pinctrl_dev *pctldev,
109262306a36Sopenharmony_ci			     struct pinctrl_map *map, unsigned int num_maps)
109362306a36Sopenharmony_ci{
109462306a36Sopenharmony_ci	kfree(map);
109562306a36Sopenharmony_ci}
109662306a36Sopenharmony_ci
109762306a36Sopenharmony_cistatic const struct pinctrl_ops rza1_pinctrl_ops = {
109862306a36Sopenharmony_ci	.get_groups_count	= pinctrl_generic_get_group_count,
109962306a36Sopenharmony_ci	.get_group_name		= pinctrl_generic_get_group_name,
110062306a36Sopenharmony_ci	.get_group_pins		= pinctrl_generic_get_group_pins,
110162306a36Sopenharmony_ci	.dt_node_to_map		= rza1_dt_node_to_map,
110262306a36Sopenharmony_ci	.dt_free_map		= rza1_dt_free_map,
110362306a36Sopenharmony_ci};
110462306a36Sopenharmony_ci
110562306a36Sopenharmony_ci/* ----------------------------------------------------------------------------
110662306a36Sopenharmony_ci * pinmux operations
110762306a36Sopenharmony_ci */
110862306a36Sopenharmony_ci
110962306a36Sopenharmony_ci/**
111062306a36Sopenharmony_ci * rza1_set_mux() - retrieve pins from a group and apply their mux settings
111162306a36Sopenharmony_ci *
111262306a36Sopenharmony_ci * @pctldev: pin controller device
111362306a36Sopenharmony_ci * @selector: function selector
111462306a36Sopenharmony_ci * @group: group selector
111562306a36Sopenharmony_ci */
111662306a36Sopenharmony_cistatic int rza1_set_mux(struct pinctrl_dev *pctldev, unsigned int selector,
111762306a36Sopenharmony_ci			   unsigned int group)
111862306a36Sopenharmony_ci{
111962306a36Sopenharmony_ci	struct rza1_pinctrl *rza1_pctl = pinctrl_dev_get_drvdata(pctldev);
112062306a36Sopenharmony_ci	struct rza1_mux_conf *mux_confs;
112162306a36Sopenharmony_ci	struct function_desc *func;
112262306a36Sopenharmony_ci	struct group_desc *grp;
112362306a36Sopenharmony_ci	int i;
112462306a36Sopenharmony_ci
112562306a36Sopenharmony_ci	grp = pinctrl_generic_get_group(pctldev, group);
112662306a36Sopenharmony_ci	if (!grp)
112762306a36Sopenharmony_ci		return -EINVAL;
112862306a36Sopenharmony_ci
112962306a36Sopenharmony_ci	func = pinmux_generic_get_function(pctldev, selector);
113062306a36Sopenharmony_ci	if (!func)
113162306a36Sopenharmony_ci		return -EINVAL;
113262306a36Sopenharmony_ci
113362306a36Sopenharmony_ci	mux_confs = (struct rza1_mux_conf *)func->data;
113462306a36Sopenharmony_ci	for (i = 0; i < grp->num_pins; ++i) {
113562306a36Sopenharmony_ci		int ret;
113662306a36Sopenharmony_ci
113762306a36Sopenharmony_ci		ret = rza1_pin_mux_single(rza1_pctl, &mux_confs[i]);
113862306a36Sopenharmony_ci		if (ret)
113962306a36Sopenharmony_ci			return ret;
114062306a36Sopenharmony_ci	}
114162306a36Sopenharmony_ci
114262306a36Sopenharmony_ci	return 0;
114362306a36Sopenharmony_ci}
114462306a36Sopenharmony_ci
114562306a36Sopenharmony_cistatic const struct pinmux_ops rza1_pinmux_ops = {
114662306a36Sopenharmony_ci	.get_functions_count	= pinmux_generic_get_function_count,
114762306a36Sopenharmony_ci	.get_function_name	= pinmux_generic_get_function_name,
114862306a36Sopenharmony_ci	.get_function_groups	= pinmux_generic_get_function_groups,
114962306a36Sopenharmony_ci	.set_mux		= rza1_set_mux,
115062306a36Sopenharmony_ci	.strict			= true,
115162306a36Sopenharmony_ci};
115262306a36Sopenharmony_ci
115362306a36Sopenharmony_ci/* ----------------------------------------------------------------------------
115462306a36Sopenharmony_ci * RZ/A1 pin controller driver operations
115562306a36Sopenharmony_ci */
115662306a36Sopenharmony_ci
115762306a36Sopenharmony_ci/**
115862306a36Sopenharmony_ci * rza1_parse_gpiochip() - parse and register a gpio chip and pin range
115962306a36Sopenharmony_ci *
116062306a36Sopenharmony_ci * The gpio controller subnode shall provide a "gpio-ranges" list property as
116162306a36Sopenharmony_ci * defined by gpio device tree binding documentation.
116262306a36Sopenharmony_ci *
116362306a36Sopenharmony_ci * @rza1_pctl: RZ/A1 pin controller device
116462306a36Sopenharmony_ci * @fwnode: gpio-controller firmware node
116562306a36Sopenharmony_ci * @chip: gpio chip to register to gpiolib
116662306a36Sopenharmony_ci * @range: pin range to register to pinctrl core
116762306a36Sopenharmony_ci */
116862306a36Sopenharmony_cistatic int rza1_parse_gpiochip(struct rza1_pinctrl *rza1_pctl,
116962306a36Sopenharmony_ci			       struct fwnode_handle *fwnode,
117062306a36Sopenharmony_ci			       struct gpio_chip *chip,
117162306a36Sopenharmony_ci			       struct pinctrl_gpio_range *range)
117262306a36Sopenharmony_ci{
117362306a36Sopenharmony_ci	const char *list_name = "gpio-ranges";
117462306a36Sopenharmony_ci	struct fwnode_reference_args args;
117562306a36Sopenharmony_ci	unsigned int gpioport;
117662306a36Sopenharmony_ci	u32 pinctrl_base;
117762306a36Sopenharmony_ci	int ret;
117862306a36Sopenharmony_ci
117962306a36Sopenharmony_ci	ret = fwnode_property_get_reference_args(fwnode, list_name, NULL, 3, 0, &args);
118062306a36Sopenharmony_ci	if (ret) {
118162306a36Sopenharmony_ci		dev_err(rza1_pctl->dev, "Unable to parse %s list property\n",
118262306a36Sopenharmony_ci			list_name);
118362306a36Sopenharmony_ci		return ret;
118462306a36Sopenharmony_ci	}
118562306a36Sopenharmony_ci
118662306a36Sopenharmony_ci	/*
118762306a36Sopenharmony_ci	 * Find out on which port this gpio-chip maps to by inspecting the
118862306a36Sopenharmony_ci	 * second argument of the "gpio-ranges" property.
118962306a36Sopenharmony_ci	 */
119062306a36Sopenharmony_ci	pinctrl_base = args.args[1];
119162306a36Sopenharmony_ci	gpioport = RZA1_PIN_ID_TO_PORT(pinctrl_base);
119262306a36Sopenharmony_ci	if (gpioport >= RZA1_NPORTS) {
119362306a36Sopenharmony_ci		dev_err(rza1_pctl->dev,
119462306a36Sopenharmony_ci			"Invalid values in property %s\n", list_name);
119562306a36Sopenharmony_ci		return -EINVAL;
119662306a36Sopenharmony_ci	}
119762306a36Sopenharmony_ci
119862306a36Sopenharmony_ci	*chip		= rza1_gpiochip_template;
119962306a36Sopenharmony_ci	chip->base	= -1;
120062306a36Sopenharmony_ci	chip->ngpio	= args.args[2];
120162306a36Sopenharmony_ci	chip->label	= devm_kasprintf(rza1_pctl->dev, GFP_KERNEL, "%pfwP", fwnode);
120262306a36Sopenharmony_ci	if (!chip->label)
120362306a36Sopenharmony_ci		return -ENOMEM;
120462306a36Sopenharmony_ci
120562306a36Sopenharmony_ci	chip->fwnode	= fwnode;
120662306a36Sopenharmony_ci	chip->parent	= rza1_pctl->dev;
120762306a36Sopenharmony_ci
120862306a36Sopenharmony_ci	range->id	= gpioport;
120962306a36Sopenharmony_ci	range->name	= chip->label;
121062306a36Sopenharmony_ci	range->pin_base	= range->base = pinctrl_base;
121162306a36Sopenharmony_ci	range->npins	= args.args[2];
121262306a36Sopenharmony_ci	range->gc	= chip;
121362306a36Sopenharmony_ci
121462306a36Sopenharmony_ci	ret = devm_gpiochip_add_data(rza1_pctl->dev, chip,
121562306a36Sopenharmony_ci				     &rza1_pctl->ports[gpioport]);
121662306a36Sopenharmony_ci	if (ret)
121762306a36Sopenharmony_ci		return ret;
121862306a36Sopenharmony_ci
121962306a36Sopenharmony_ci	pinctrl_add_gpio_range(rza1_pctl->pctl, range);
122062306a36Sopenharmony_ci
122162306a36Sopenharmony_ci	dev_dbg(rza1_pctl->dev, "Parsed gpiochip %s with %d pins\n",
122262306a36Sopenharmony_ci		chip->label, chip->ngpio);
122362306a36Sopenharmony_ci
122462306a36Sopenharmony_ci	return 0;
122562306a36Sopenharmony_ci}
122662306a36Sopenharmony_ci
122762306a36Sopenharmony_ci/**
122862306a36Sopenharmony_ci * rza1_gpio_register() - parse DT to collect gpio-chips and gpio-ranges
122962306a36Sopenharmony_ci *
123062306a36Sopenharmony_ci * @rza1_pctl: RZ/A1 pin controller device
123162306a36Sopenharmony_ci */
123262306a36Sopenharmony_cistatic int rza1_gpio_register(struct rza1_pinctrl *rza1_pctl)
123362306a36Sopenharmony_ci{
123462306a36Sopenharmony_ci	struct pinctrl_gpio_range *gpio_ranges;
123562306a36Sopenharmony_ci	struct gpio_chip *gpio_chips;
123662306a36Sopenharmony_ci	struct fwnode_handle *child;
123762306a36Sopenharmony_ci	unsigned int ngpiochips;
123862306a36Sopenharmony_ci	unsigned int i;
123962306a36Sopenharmony_ci	int ret;
124062306a36Sopenharmony_ci
124162306a36Sopenharmony_ci	ngpiochips = gpiochip_node_count(rza1_pctl->dev);
124262306a36Sopenharmony_ci	if (ngpiochips == 0) {
124362306a36Sopenharmony_ci		dev_dbg(rza1_pctl->dev, "No gpiochip registered\n");
124462306a36Sopenharmony_ci		return 0;
124562306a36Sopenharmony_ci	}
124662306a36Sopenharmony_ci
124762306a36Sopenharmony_ci	gpio_chips = devm_kcalloc(rza1_pctl->dev, ngpiochips,
124862306a36Sopenharmony_ci				  sizeof(*gpio_chips), GFP_KERNEL);
124962306a36Sopenharmony_ci	gpio_ranges = devm_kcalloc(rza1_pctl->dev, ngpiochips,
125062306a36Sopenharmony_ci				   sizeof(*gpio_ranges), GFP_KERNEL);
125162306a36Sopenharmony_ci	if (!gpio_chips || !gpio_ranges)
125262306a36Sopenharmony_ci		return -ENOMEM;
125362306a36Sopenharmony_ci
125462306a36Sopenharmony_ci	i = 0;
125562306a36Sopenharmony_ci	for_each_gpiochip_node(rza1_pctl->dev, child) {
125662306a36Sopenharmony_ci		ret = rza1_parse_gpiochip(rza1_pctl, child, &gpio_chips[i],
125762306a36Sopenharmony_ci					  &gpio_ranges[i]);
125862306a36Sopenharmony_ci		if (ret) {
125962306a36Sopenharmony_ci			fwnode_handle_put(child);
126062306a36Sopenharmony_ci			return ret;
126162306a36Sopenharmony_ci		}
126262306a36Sopenharmony_ci
126362306a36Sopenharmony_ci		++i;
126462306a36Sopenharmony_ci	}
126562306a36Sopenharmony_ci
126662306a36Sopenharmony_ci	dev_info(rza1_pctl->dev, "Registered %u gpio controllers\n", i);
126762306a36Sopenharmony_ci
126862306a36Sopenharmony_ci	return 0;
126962306a36Sopenharmony_ci}
127062306a36Sopenharmony_ci
127162306a36Sopenharmony_ci/**
127262306a36Sopenharmony_ci * rza1_pinctrl_register() - Enumerate pins, ports and gpiochips; register
127362306a36Sopenharmony_ci *			     them to pinctrl and gpio cores.
127462306a36Sopenharmony_ci *
127562306a36Sopenharmony_ci * @rza1_pctl: RZ/A1 pin controller device
127662306a36Sopenharmony_ci */
127762306a36Sopenharmony_cistatic int rza1_pinctrl_register(struct rza1_pinctrl *rza1_pctl)
127862306a36Sopenharmony_ci{
127962306a36Sopenharmony_ci	struct pinctrl_pin_desc *pins;
128062306a36Sopenharmony_ci	struct rza1_port *ports;
128162306a36Sopenharmony_ci	unsigned int i;
128262306a36Sopenharmony_ci	int ret;
128362306a36Sopenharmony_ci
128462306a36Sopenharmony_ci	pins = devm_kcalloc(rza1_pctl->dev, RZA1_NPINS, sizeof(*pins),
128562306a36Sopenharmony_ci			    GFP_KERNEL);
128662306a36Sopenharmony_ci	ports = devm_kcalloc(rza1_pctl->dev, RZA1_NPORTS, sizeof(*ports),
128762306a36Sopenharmony_ci			     GFP_KERNEL);
128862306a36Sopenharmony_ci	if (!pins || !ports)
128962306a36Sopenharmony_ci		return -ENOMEM;
129062306a36Sopenharmony_ci
129162306a36Sopenharmony_ci	rza1_pctl->pins		= pins;
129262306a36Sopenharmony_ci	rza1_pctl->desc.pins	= pins;
129362306a36Sopenharmony_ci	rza1_pctl->desc.npins	= RZA1_NPINS;
129462306a36Sopenharmony_ci	rza1_pctl->ports	= ports;
129562306a36Sopenharmony_ci
129662306a36Sopenharmony_ci	for (i = 0; i < RZA1_NPINS; ++i) {
129762306a36Sopenharmony_ci		unsigned int pin = RZA1_PIN_ID_TO_PIN(i);
129862306a36Sopenharmony_ci		unsigned int port = RZA1_PIN_ID_TO_PORT(i);
129962306a36Sopenharmony_ci
130062306a36Sopenharmony_ci		pins[i].number = i;
130162306a36Sopenharmony_ci		pins[i].name = devm_kasprintf(rza1_pctl->dev, GFP_KERNEL,
130262306a36Sopenharmony_ci					      "P%u-%u", port, pin);
130362306a36Sopenharmony_ci		if (!pins[i].name)
130462306a36Sopenharmony_ci			return -ENOMEM;
130562306a36Sopenharmony_ci
130662306a36Sopenharmony_ci		if (i % RZA1_PINS_PER_PORT == 0) {
130762306a36Sopenharmony_ci			/*
130862306a36Sopenharmony_ci			 * Setup ports;
130962306a36Sopenharmony_ci			 * they provide per-port lock and logical base address.
131062306a36Sopenharmony_ci			 */
131162306a36Sopenharmony_ci			unsigned int port_id = RZA1_PIN_ID_TO_PORT(i);
131262306a36Sopenharmony_ci
131362306a36Sopenharmony_ci			ports[port_id].id	= port_id;
131462306a36Sopenharmony_ci			ports[port_id].base	= rza1_pctl->base;
131562306a36Sopenharmony_ci			ports[port_id].pins	= &pins[i];
131662306a36Sopenharmony_ci			spin_lock_init(&ports[port_id].lock);
131762306a36Sopenharmony_ci		}
131862306a36Sopenharmony_ci	}
131962306a36Sopenharmony_ci
132062306a36Sopenharmony_ci	ret = devm_pinctrl_register_and_init(rza1_pctl->dev, &rza1_pctl->desc,
132162306a36Sopenharmony_ci					     rza1_pctl, &rza1_pctl->pctl);
132262306a36Sopenharmony_ci	if (ret) {
132362306a36Sopenharmony_ci		dev_err(rza1_pctl->dev,
132462306a36Sopenharmony_ci			"RZ/A1 pin controller registration failed\n");
132562306a36Sopenharmony_ci		return ret;
132662306a36Sopenharmony_ci	}
132762306a36Sopenharmony_ci
132862306a36Sopenharmony_ci	ret = pinctrl_enable(rza1_pctl->pctl);
132962306a36Sopenharmony_ci	if (ret) {
133062306a36Sopenharmony_ci		dev_err(rza1_pctl->dev,
133162306a36Sopenharmony_ci			"RZ/A1 pin controller failed to start\n");
133262306a36Sopenharmony_ci		return ret;
133362306a36Sopenharmony_ci	}
133462306a36Sopenharmony_ci
133562306a36Sopenharmony_ci	ret = rza1_gpio_register(rza1_pctl);
133662306a36Sopenharmony_ci	if (ret) {
133762306a36Sopenharmony_ci		dev_err(rza1_pctl->dev, "RZ/A1 GPIO registration failed\n");
133862306a36Sopenharmony_ci		return ret;
133962306a36Sopenharmony_ci	}
134062306a36Sopenharmony_ci
134162306a36Sopenharmony_ci	return 0;
134262306a36Sopenharmony_ci}
134362306a36Sopenharmony_ci
134462306a36Sopenharmony_cistatic int rza1_pinctrl_probe(struct platform_device *pdev)
134562306a36Sopenharmony_ci{
134662306a36Sopenharmony_ci	struct rza1_pinctrl *rza1_pctl;
134762306a36Sopenharmony_ci	int ret;
134862306a36Sopenharmony_ci
134962306a36Sopenharmony_ci	rza1_pctl = devm_kzalloc(&pdev->dev, sizeof(*rza1_pctl), GFP_KERNEL);
135062306a36Sopenharmony_ci	if (!rza1_pctl)
135162306a36Sopenharmony_ci		return -ENOMEM;
135262306a36Sopenharmony_ci
135362306a36Sopenharmony_ci	rza1_pctl->dev = &pdev->dev;
135462306a36Sopenharmony_ci
135562306a36Sopenharmony_ci	rza1_pctl->base = devm_platform_ioremap_resource(pdev, 0);
135662306a36Sopenharmony_ci	if (IS_ERR(rza1_pctl->base))
135762306a36Sopenharmony_ci		return PTR_ERR(rza1_pctl->base);
135862306a36Sopenharmony_ci
135962306a36Sopenharmony_ci	mutex_init(&rza1_pctl->mutex);
136062306a36Sopenharmony_ci
136162306a36Sopenharmony_ci	platform_set_drvdata(pdev, rza1_pctl);
136262306a36Sopenharmony_ci
136362306a36Sopenharmony_ci	rza1_pctl->desc.name	= DRIVER_NAME;
136462306a36Sopenharmony_ci	rza1_pctl->desc.pctlops	= &rza1_pinctrl_ops;
136562306a36Sopenharmony_ci	rza1_pctl->desc.pmxops	= &rza1_pinmux_ops;
136662306a36Sopenharmony_ci	rza1_pctl->desc.owner	= THIS_MODULE;
136762306a36Sopenharmony_ci	rza1_pctl->data		= of_device_get_match_data(&pdev->dev);
136862306a36Sopenharmony_ci
136962306a36Sopenharmony_ci	ret = rza1_pinctrl_register(rza1_pctl);
137062306a36Sopenharmony_ci	if (ret)
137162306a36Sopenharmony_ci		return ret;
137262306a36Sopenharmony_ci
137362306a36Sopenharmony_ci	dev_info(&pdev->dev,
137462306a36Sopenharmony_ci		 "RZ/A1 pin controller and gpio successfully registered\n");
137562306a36Sopenharmony_ci
137662306a36Sopenharmony_ci	return 0;
137762306a36Sopenharmony_ci}
137862306a36Sopenharmony_ci
137962306a36Sopenharmony_cistatic const struct of_device_id rza1_pinctrl_of_match[] = {
138062306a36Sopenharmony_ci	{
138162306a36Sopenharmony_ci		/* RZ/A1H, RZ/A1M */
138262306a36Sopenharmony_ci		.compatible	= "renesas,r7s72100-ports",
138362306a36Sopenharmony_ci		.data		= &rza1h_pmx_conf,
138462306a36Sopenharmony_ci	},
138562306a36Sopenharmony_ci	{
138662306a36Sopenharmony_ci		/* RZ/A1L */
138762306a36Sopenharmony_ci		.compatible	= "renesas,r7s72102-ports",
138862306a36Sopenharmony_ci		.data		= &rza1l_pmx_conf,
138962306a36Sopenharmony_ci	},
139062306a36Sopenharmony_ci	{ /* sentinel */ }
139162306a36Sopenharmony_ci};
139262306a36Sopenharmony_ci
139362306a36Sopenharmony_cistatic struct platform_driver rza1_pinctrl_driver = {
139462306a36Sopenharmony_ci	.driver = {
139562306a36Sopenharmony_ci		.name = DRIVER_NAME,
139662306a36Sopenharmony_ci		.of_match_table = rza1_pinctrl_of_match,
139762306a36Sopenharmony_ci	},
139862306a36Sopenharmony_ci	.probe = rza1_pinctrl_probe,
139962306a36Sopenharmony_ci};
140062306a36Sopenharmony_ci
140162306a36Sopenharmony_cistatic int __init rza1_pinctrl_init(void)
140262306a36Sopenharmony_ci{
140362306a36Sopenharmony_ci	return platform_driver_register(&rza1_pinctrl_driver);
140462306a36Sopenharmony_ci}
140562306a36Sopenharmony_cicore_initcall(rza1_pinctrl_init);
140662306a36Sopenharmony_ci
140762306a36Sopenharmony_ciMODULE_AUTHOR("Jacopo Mondi <jacopo+renesas@jmondi.org");
140862306a36Sopenharmony_ciMODULE_DESCRIPTION("Pin and gpio controller driver for Reneas RZ/A1 SoC");
1409