162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Lochnagar pin and GPIO control
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (c) 2017-2018 Cirrus Logic, Inc. and
662306a36Sopenharmony_ci *                         Cirrus Logic International Semiconductor Ltd.
762306a36Sopenharmony_ci *
862306a36Sopenharmony_ci * Author: Charles Keepax <ckeepax@opensource.cirrus.com>
962306a36Sopenharmony_ci */
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#include <linux/err.h>
1262306a36Sopenharmony_ci#include <linux/errno.h>
1362306a36Sopenharmony_ci#include <linux/gpio/driver.h>
1462306a36Sopenharmony_ci#include <linux/module.h>
1562306a36Sopenharmony_ci#include <linux/of.h>
1662306a36Sopenharmony_ci#include <linux/platform_device.h>
1762306a36Sopenharmony_ci#include <linux/regmap.h>
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci#include <linux/pinctrl/consumer.h>
2062306a36Sopenharmony_ci#include <linux/pinctrl/pinconf-generic.h>
2162306a36Sopenharmony_ci#include <linux/pinctrl/pinconf.h>
2262306a36Sopenharmony_ci#include <linux/pinctrl/pinctrl.h>
2362306a36Sopenharmony_ci#include <linux/pinctrl/pinmux.h>
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ci#include <linux/mfd/lochnagar.h>
2662306a36Sopenharmony_ci#include <linux/mfd/lochnagar1_regs.h>
2762306a36Sopenharmony_ci#include <linux/mfd/lochnagar2_regs.h>
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ci#include <dt-bindings/pinctrl/lochnagar.h>
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ci#include "../pinctrl-utils.h"
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ci#define LN2_NUM_GPIO_CHANNELS	16
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_ci#define LN_CDC_AIF1_STR		"codec-aif1"
3662306a36Sopenharmony_ci#define LN_CDC_AIF2_STR		"codec-aif2"
3762306a36Sopenharmony_ci#define LN_CDC_AIF3_STR		"codec-aif3"
3862306a36Sopenharmony_ci#define LN_DSP_AIF1_STR		"dsp-aif1"
3962306a36Sopenharmony_ci#define LN_DSP_AIF2_STR		"dsp-aif2"
4062306a36Sopenharmony_ci#define LN_PSIA1_STR		"psia1"
4162306a36Sopenharmony_ci#define LN_PSIA2_STR		"psia2"
4262306a36Sopenharmony_ci#define LN_GF_AIF1_STR		"gf-aif1"
4362306a36Sopenharmony_ci#define LN_GF_AIF2_STR		"gf-aif2"
4462306a36Sopenharmony_ci#define LN_GF_AIF3_STR		"gf-aif3"
4562306a36Sopenharmony_ci#define LN_GF_AIF4_STR		"gf-aif4"
4662306a36Sopenharmony_ci#define LN_SPDIF_AIF_STR	"spdif-aif"
4762306a36Sopenharmony_ci#define LN_USB_AIF1_STR		"usb-aif1"
4862306a36Sopenharmony_ci#define LN_USB_AIF2_STR		"usb-aif2"
4962306a36Sopenharmony_ci#define LN_ADAT_AIF_STR		"adat-aif"
5062306a36Sopenharmony_ci#define LN_SOUNDCARD_AIF_STR	"soundcard-aif"
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_ci#define LN_PIN_GPIO(REV, ID, NAME, REG, SHIFT, INVERT) \
5362306a36Sopenharmony_cistatic const struct lochnagar_pin lochnagar##REV##_##ID##_pin = { \
5462306a36Sopenharmony_ci	.name = NAME, .type = LN_PTYPE_GPIO, .reg = LOCHNAGAR##REV##_##REG, \
5562306a36Sopenharmony_ci	.shift = LOCHNAGAR##REV##_##SHIFT##_SHIFT, .invert = INVERT, \
5662306a36Sopenharmony_ci}
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_ci#define LN_PIN_SAIF(REV, ID, NAME) \
5962306a36Sopenharmony_cistatic const struct lochnagar_pin lochnagar##REV##_##ID##_pin = \
6062306a36Sopenharmony_ci	{ .name = NAME, .type = LN_PTYPE_AIF, }
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_ci#define LN_PIN_AIF(REV, ID) \
6362306a36Sopenharmony_ci	LN_PIN_SAIF(REV, ID##_BCLK,  LN_##ID##_STR"-bclk"); \
6462306a36Sopenharmony_ci	LN_PIN_SAIF(REV, ID##_LRCLK, LN_##ID##_STR"-lrclk"); \
6562306a36Sopenharmony_ci	LN_PIN_SAIF(REV, ID##_RXDAT, LN_##ID##_STR"-rxdat"); \
6662306a36Sopenharmony_ci	LN_PIN_SAIF(REV, ID##_TXDAT, LN_##ID##_STR"-txdat")
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_ci#define LN1_PIN_GPIO(ID, NAME, REG, SHIFT, INVERT) \
6962306a36Sopenharmony_ci	LN_PIN_GPIO(1, ID, NAME, REG, SHIFT, INVERT)
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ci#define LN1_PIN_MUX(ID, NAME) \
7262306a36Sopenharmony_cistatic const struct lochnagar_pin lochnagar1_##ID##_pin = \
7362306a36Sopenharmony_ci	{ .name = NAME, .type = LN_PTYPE_MUX, .reg = LOCHNAGAR1_##ID, }
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_ci#define LN1_PIN_AIF(ID) LN_PIN_AIF(1, ID)
7662306a36Sopenharmony_ci
7762306a36Sopenharmony_ci#define LN2_PIN_GPIO(ID, NAME, REG, SHIFT, INVERT) \
7862306a36Sopenharmony_ci	LN_PIN_GPIO(2, ID, NAME, REG, SHIFT, INVERT)
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_ci#define LN2_PIN_MUX(ID, NAME) \
8162306a36Sopenharmony_cistatic const struct lochnagar_pin lochnagar2_##ID##_pin = \
8262306a36Sopenharmony_ci	{ .name = NAME, .type = LN_PTYPE_MUX, .reg = LOCHNAGAR2_GPIO_##ID, }
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_ci#define LN2_PIN_AIF(ID) LN_PIN_AIF(2, ID)
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ci#define LN2_PIN_GAI(ID) \
8762306a36Sopenharmony_ci	LN2_PIN_MUX(ID##_BCLK,  LN_##ID##_STR"-bclk"); \
8862306a36Sopenharmony_ci	LN2_PIN_MUX(ID##_LRCLK, LN_##ID##_STR"-lrclk"); \
8962306a36Sopenharmony_ci	LN2_PIN_MUX(ID##_RXDAT, LN_##ID##_STR"-rxdat"); \
9062306a36Sopenharmony_ci	LN2_PIN_MUX(ID##_TXDAT, LN_##ID##_STR"-txdat")
9162306a36Sopenharmony_ci
9262306a36Sopenharmony_ci#define LN_PIN(REV, ID) [LOCHNAGAR##REV##_PIN_##ID] = { \
9362306a36Sopenharmony_ci	.number = LOCHNAGAR##REV##_PIN_##ID, \
9462306a36Sopenharmony_ci	.name = lochnagar##REV##_##ID##_pin.name, \
9562306a36Sopenharmony_ci	.drv_data = (void *)&lochnagar##REV##_##ID##_pin, \
9662306a36Sopenharmony_ci}
9762306a36Sopenharmony_ci
9862306a36Sopenharmony_ci#define LN1_PIN(ID) LN_PIN(1, ID)
9962306a36Sopenharmony_ci#define LN2_PIN(ID) LN_PIN(2, ID)
10062306a36Sopenharmony_ci
10162306a36Sopenharmony_ci#define LN_PINS(REV, ID) \
10262306a36Sopenharmony_ci	LN_PIN(REV, ID##_BCLK), LN_PIN(REV, ID##_LRCLK), \
10362306a36Sopenharmony_ci	LN_PIN(REV, ID##_RXDAT), LN_PIN(REV, ID##_TXDAT)
10462306a36Sopenharmony_ci
10562306a36Sopenharmony_ci#define LN1_PINS(ID) LN_PINS(1, ID)
10662306a36Sopenharmony_ci#define LN2_PINS(ID) LN_PINS(2, ID)
10762306a36Sopenharmony_ci
10862306a36Sopenharmony_cienum {
10962306a36Sopenharmony_ci	LOCHNAGAR1_PIN_GF_GPIO2 = LOCHNAGAR1_PIN_NUM_GPIOS,
11062306a36Sopenharmony_ci	LOCHNAGAR1_PIN_GF_GPIO3,
11162306a36Sopenharmony_ci	LOCHNAGAR1_PIN_GF_GPIO7,
11262306a36Sopenharmony_ci	LOCHNAGAR1_PIN_LED1,
11362306a36Sopenharmony_ci	LOCHNAGAR1_PIN_LED2,
11462306a36Sopenharmony_ci	LOCHNAGAR1_PIN_CDC_AIF1_BCLK,
11562306a36Sopenharmony_ci	LOCHNAGAR1_PIN_CDC_AIF1_LRCLK,
11662306a36Sopenharmony_ci	LOCHNAGAR1_PIN_CDC_AIF1_RXDAT,
11762306a36Sopenharmony_ci	LOCHNAGAR1_PIN_CDC_AIF1_TXDAT,
11862306a36Sopenharmony_ci	LOCHNAGAR1_PIN_CDC_AIF2_BCLK,
11962306a36Sopenharmony_ci	LOCHNAGAR1_PIN_CDC_AIF2_LRCLK,
12062306a36Sopenharmony_ci	LOCHNAGAR1_PIN_CDC_AIF2_RXDAT,
12162306a36Sopenharmony_ci	LOCHNAGAR1_PIN_CDC_AIF2_TXDAT,
12262306a36Sopenharmony_ci	LOCHNAGAR1_PIN_CDC_AIF3_BCLK,
12362306a36Sopenharmony_ci	LOCHNAGAR1_PIN_CDC_AIF3_LRCLK,
12462306a36Sopenharmony_ci	LOCHNAGAR1_PIN_CDC_AIF3_RXDAT,
12562306a36Sopenharmony_ci	LOCHNAGAR1_PIN_CDC_AIF3_TXDAT,
12662306a36Sopenharmony_ci	LOCHNAGAR1_PIN_DSP_AIF1_BCLK,
12762306a36Sopenharmony_ci	LOCHNAGAR1_PIN_DSP_AIF1_LRCLK,
12862306a36Sopenharmony_ci	LOCHNAGAR1_PIN_DSP_AIF1_RXDAT,
12962306a36Sopenharmony_ci	LOCHNAGAR1_PIN_DSP_AIF1_TXDAT,
13062306a36Sopenharmony_ci	LOCHNAGAR1_PIN_DSP_AIF2_BCLK,
13162306a36Sopenharmony_ci	LOCHNAGAR1_PIN_DSP_AIF2_LRCLK,
13262306a36Sopenharmony_ci	LOCHNAGAR1_PIN_DSP_AIF2_RXDAT,
13362306a36Sopenharmony_ci	LOCHNAGAR1_PIN_DSP_AIF2_TXDAT,
13462306a36Sopenharmony_ci	LOCHNAGAR1_PIN_PSIA1_BCLK,
13562306a36Sopenharmony_ci	LOCHNAGAR1_PIN_PSIA1_LRCLK,
13662306a36Sopenharmony_ci	LOCHNAGAR1_PIN_PSIA1_RXDAT,
13762306a36Sopenharmony_ci	LOCHNAGAR1_PIN_PSIA1_TXDAT,
13862306a36Sopenharmony_ci	LOCHNAGAR1_PIN_PSIA2_BCLK,
13962306a36Sopenharmony_ci	LOCHNAGAR1_PIN_PSIA2_LRCLK,
14062306a36Sopenharmony_ci	LOCHNAGAR1_PIN_PSIA2_RXDAT,
14162306a36Sopenharmony_ci	LOCHNAGAR1_PIN_PSIA2_TXDAT,
14262306a36Sopenharmony_ci	LOCHNAGAR1_PIN_SPDIF_AIF_BCLK,
14362306a36Sopenharmony_ci	LOCHNAGAR1_PIN_SPDIF_AIF_LRCLK,
14462306a36Sopenharmony_ci	LOCHNAGAR1_PIN_SPDIF_AIF_RXDAT,
14562306a36Sopenharmony_ci	LOCHNAGAR1_PIN_SPDIF_AIF_TXDAT,
14662306a36Sopenharmony_ci	LOCHNAGAR1_PIN_GF_AIF3_BCLK,
14762306a36Sopenharmony_ci	LOCHNAGAR1_PIN_GF_AIF3_RXDAT,
14862306a36Sopenharmony_ci	LOCHNAGAR1_PIN_GF_AIF3_LRCLK,
14962306a36Sopenharmony_ci	LOCHNAGAR1_PIN_GF_AIF3_TXDAT,
15062306a36Sopenharmony_ci	LOCHNAGAR1_PIN_GF_AIF4_BCLK,
15162306a36Sopenharmony_ci	LOCHNAGAR1_PIN_GF_AIF4_RXDAT,
15262306a36Sopenharmony_ci	LOCHNAGAR1_PIN_GF_AIF4_LRCLK,
15362306a36Sopenharmony_ci	LOCHNAGAR1_PIN_GF_AIF4_TXDAT,
15462306a36Sopenharmony_ci	LOCHNAGAR1_PIN_GF_AIF1_BCLK,
15562306a36Sopenharmony_ci	LOCHNAGAR1_PIN_GF_AIF1_RXDAT,
15662306a36Sopenharmony_ci	LOCHNAGAR1_PIN_GF_AIF1_LRCLK,
15762306a36Sopenharmony_ci	LOCHNAGAR1_PIN_GF_AIF1_TXDAT,
15862306a36Sopenharmony_ci	LOCHNAGAR1_PIN_GF_AIF2_BCLK,
15962306a36Sopenharmony_ci	LOCHNAGAR1_PIN_GF_AIF2_RXDAT,
16062306a36Sopenharmony_ci	LOCHNAGAR1_PIN_GF_AIF2_LRCLK,
16162306a36Sopenharmony_ci	LOCHNAGAR1_PIN_GF_AIF2_TXDAT,
16262306a36Sopenharmony_ci
16362306a36Sopenharmony_ci	LOCHNAGAR2_PIN_SPDIF_AIF_BCLK = LOCHNAGAR2_PIN_NUM_GPIOS,
16462306a36Sopenharmony_ci	LOCHNAGAR2_PIN_SPDIF_AIF_LRCLK,
16562306a36Sopenharmony_ci	LOCHNAGAR2_PIN_SPDIF_AIF_RXDAT,
16662306a36Sopenharmony_ci	LOCHNAGAR2_PIN_SPDIF_AIF_TXDAT,
16762306a36Sopenharmony_ci	LOCHNAGAR2_PIN_USB_AIF1_BCLK,
16862306a36Sopenharmony_ci	LOCHNAGAR2_PIN_USB_AIF1_LRCLK,
16962306a36Sopenharmony_ci	LOCHNAGAR2_PIN_USB_AIF1_RXDAT,
17062306a36Sopenharmony_ci	LOCHNAGAR2_PIN_USB_AIF1_TXDAT,
17162306a36Sopenharmony_ci	LOCHNAGAR2_PIN_USB_AIF2_BCLK,
17262306a36Sopenharmony_ci	LOCHNAGAR2_PIN_USB_AIF2_LRCLK,
17362306a36Sopenharmony_ci	LOCHNAGAR2_PIN_USB_AIF2_RXDAT,
17462306a36Sopenharmony_ci	LOCHNAGAR2_PIN_USB_AIF2_TXDAT,
17562306a36Sopenharmony_ci	LOCHNAGAR2_PIN_ADAT_AIF_BCLK,
17662306a36Sopenharmony_ci	LOCHNAGAR2_PIN_ADAT_AIF_LRCLK,
17762306a36Sopenharmony_ci	LOCHNAGAR2_PIN_ADAT_AIF_RXDAT,
17862306a36Sopenharmony_ci	LOCHNAGAR2_PIN_ADAT_AIF_TXDAT,
17962306a36Sopenharmony_ci	LOCHNAGAR2_PIN_SOUNDCARD_AIF_BCLK,
18062306a36Sopenharmony_ci	LOCHNAGAR2_PIN_SOUNDCARD_AIF_LRCLK,
18162306a36Sopenharmony_ci	LOCHNAGAR2_PIN_SOUNDCARD_AIF_RXDAT,
18262306a36Sopenharmony_ci	LOCHNAGAR2_PIN_SOUNDCARD_AIF_TXDAT,
18362306a36Sopenharmony_ci};
18462306a36Sopenharmony_ci
18562306a36Sopenharmony_cienum lochnagar_pin_type {
18662306a36Sopenharmony_ci	LN_PTYPE_GPIO,
18762306a36Sopenharmony_ci	LN_PTYPE_MUX,
18862306a36Sopenharmony_ci	LN_PTYPE_AIF,
18962306a36Sopenharmony_ci	LN_PTYPE_COUNT,
19062306a36Sopenharmony_ci};
19162306a36Sopenharmony_ci
19262306a36Sopenharmony_cistruct lochnagar_pin {
19362306a36Sopenharmony_ci	const char name[20];
19462306a36Sopenharmony_ci
19562306a36Sopenharmony_ci	enum lochnagar_pin_type type;
19662306a36Sopenharmony_ci
19762306a36Sopenharmony_ci	unsigned int reg;
19862306a36Sopenharmony_ci	int shift;
19962306a36Sopenharmony_ci	bool invert;
20062306a36Sopenharmony_ci};
20162306a36Sopenharmony_ci
20262306a36Sopenharmony_ciLN1_PIN_GPIO(CDC_RESET,    "codec-reset",    RST,      CDC_RESET,    1);
20362306a36Sopenharmony_ciLN1_PIN_GPIO(DSP_RESET,    "dsp-reset",      RST,      DSP_RESET,    1);
20462306a36Sopenharmony_ciLN1_PIN_GPIO(CDC_CIF1MODE, "codec-cif1mode", I2C_CTRL, CDC_CIF_MODE, 0);
20562306a36Sopenharmony_ciLN1_PIN_MUX(GF_GPIO2,      "gf-gpio2");
20662306a36Sopenharmony_ciLN1_PIN_MUX(GF_GPIO3,      "gf-gpio3");
20762306a36Sopenharmony_ciLN1_PIN_MUX(GF_GPIO7,      "gf-gpio7");
20862306a36Sopenharmony_ciLN1_PIN_MUX(LED1,          "led1");
20962306a36Sopenharmony_ciLN1_PIN_MUX(LED2,          "led2");
21062306a36Sopenharmony_ciLN1_PIN_AIF(CDC_AIF1);
21162306a36Sopenharmony_ciLN1_PIN_AIF(CDC_AIF2);
21262306a36Sopenharmony_ciLN1_PIN_AIF(CDC_AIF3);
21362306a36Sopenharmony_ciLN1_PIN_AIF(DSP_AIF1);
21462306a36Sopenharmony_ciLN1_PIN_AIF(DSP_AIF2);
21562306a36Sopenharmony_ciLN1_PIN_AIF(PSIA1);
21662306a36Sopenharmony_ciLN1_PIN_AIF(PSIA2);
21762306a36Sopenharmony_ciLN1_PIN_AIF(SPDIF_AIF);
21862306a36Sopenharmony_ciLN1_PIN_AIF(GF_AIF1);
21962306a36Sopenharmony_ciLN1_PIN_AIF(GF_AIF2);
22062306a36Sopenharmony_ciLN1_PIN_AIF(GF_AIF3);
22162306a36Sopenharmony_ciLN1_PIN_AIF(GF_AIF4);
22262306a36Sopenharmony_ci
22362306a36Sopenharmony_ciLN2_PIN_GPIO(CDC_RESET,    "codec-reset",    MINICARD_RESETS, CDC_RESET,     1);
22462306a36Sopenharmony_ciLN2_PIN_GPIO(DSP_RESET,    "dsp-reset",      MINICARD_RESETS, DSP_RESET,     1);
22562306a36Sopenharmony_ciLN2_PIN_GPIO(CDC_CIF1MODE, "codec-cif1mode", COMMS_CTRL4,     CDC_CIF1MODE,  0);
22662306a36Sopenharmony_ciLN2_PIN_GPIO(CDC_LDOENA,   "codec-ldoena",   POWER_CTRL,      PWR_ENA,       0);
22762306a36Sopenharmony_ciLN2_PIN_GPIO(SPDIF_HWMODE, "spdif-hwmode",   SPDIF_CTRL,      SPDIF_HWMODE,  0);
22862306a36Sopenharmony_ciLN2_PIN_GPIO(SPDIF_RESET,  "spdif-reset",    SPDIF_CTRL,      SPDIF_RESET,   1);
22962306a36Sopenharmony_ciLN2_PIN_MUX(FPGA_GPIO1,    "fpga-gpio1");
23062306a36Sopenharmony_ciLN2_PIN_MUX(FPGA_GPIO2,    "fpga-gpio2");
23162306a36Sopenharmony_ciLN2_PIN_MUX(FPGA_GPIO3,    "fpga-gpio3");
23262306a36Sopenharmony_ciLN2_PIN_MUX(FPGA_GPIO4,    "fpga-gpio4");
23362306a36Sopenharmony_ciLN2_PIN_MUX(FPGA_GPIO5,    "fpga-gpio5");
23462306a36Sopenharmony_ciLN2_PIN_MUX(FPGA_GPIO6,    "fpga-gpio6");
23562306a36Sopenharmony_ciLN2_PIN_MUX(CDC_GPIO1,     "codec-gpio1");
23662306a36Sopenharmony_ciLN2_PIN_MUX(CDC_GPIO2,     "codec-gpio2");
23762306a36Sopenharmony_ciLN2_PIN_MUX(CDC_GPIO3,     "codec-gpio3");
23862306a36Sopenharmony_ciLN2_PIN_MUX(CDC_GPIO4,     "codec-gpio4");
23962306a36Sopenharmony_ciLN2_PIN_MUX(CDC_GPIO5,     "codec-gpio5");
24062306a36Sopenharmony_ciLN2_PIN_MUX(CDC_GPIO6,     "codec-gpio6");
24162306a36Sopenharmony_ciLN2_PIN_MUX(CDC_GPIO7,     "codec-gpio7");
24262306a36Sopenharmony_ciLN2_PIN_MUX(CDC_GPIO8,     "codec-gpio8");
24362306a36Sopenharmony_ciLN2_PIN_MUX(DSP_GPIO1,     "dsp-gpio1");
24462306a36Sopenharmony_ciLN2_PIN_MUX(DSP_GPIO2,     "dsp-gpio2");
24562306a36Sopenharmony_ciLN2_PIN_MUX(DSP_GPIO3,     "dsp-gpio3");
24662306a36Sopenharmony_ciLN2_PIN_MUX(DSP_GPIO4,     "dsp-gpio4");
24762306a36Sopenharmony_ciLN2_PIN_MUX(DSP_GPIO5,     "dsp-gpio5");
24862306a36Sopenharmony_ciLN2_PIN_MUX(DSP_GPIO6,     "dsp-gpio6");
24962306a36Sopenharmony_ciLN2_PIN_MUX(GF_GPIO2,      "gf-gpio2");
25062306a36Sopenharmony_ciLN2_PIN_MUX(GF_GPIO3,      "gf-gpio3");
25162306a36Sopenharmony_ciLN2_PIN_MUX(GF_GPIO7,      "gf-gpio7");
25262306a36Sopenharmony_ciLN2_PIN_MUX(DSP_UART1_RX,  "dsp-uart1-rx");
25362306a36Sopenharmony_ciLN2_PIN_MUX(DSP_UART1_TX,  "dsp-uart1-tx");
25462306a36Sopenharmony_ciLN2_PIN_MUX(DSP_UART2_RX,  "dsp-uart2-rx");
25562306a36Sopenharmony_ciLN2_PIN_MUX(DSP_UART2_TX,  "dsp-uart2-tx");
25662306a36Sopenharmony_ciLN2_PIN_MUX(GF_UART2_RX,   "gf-uart2-rx");
25762306a36Sopenharmony_ciLN2_PIN_MUX(GF_UART2_TX,   "gf-uart2-tx");
25862306a36Sopenharmony_ciLN2_PIN_MUX(USB_UART_RX,   "usb-uart-rx");
25962306a36Sopenharmony_ciLN2_PIN_MUX(CDC_PDMCLK1,   "codec-pdmclk1");
26062306a36Sopenharmony_ciLN2_PIN_MUX(CDC_PDMDAT1,   "codec-pdmdat1");
26162306a36Sopenharmony_ciLN2_PIN_MUX(CDC_PDMCLK2,   "codec-pdmclk2");
26262306a36Sopenharmony_ciLN2_PIN_MUX(CDC_PDMDAT2,   "codec-pdmdat2");
26362306a36Sopenharmony_ciLN2_PIN_MUX(CDC_DMICCLK1,  "codec-dmicclk1");
26462306a36Sopenharmony_ciLN2_PIN_MUX(CDC_DMICDAT1,  "codec-dmicdat1");
26562306a36Sopenharmony_ciLN2_PIN_MUX(CDC_DMICCLK2,  "codec-dmicclk2");
26662306a36Sopenharmony_ciLN2_PIN_MUX(CDC_DMICDAT2,  "codec-dmicdat2");
26762306a36Sopenharmony_ciLN2_PIN_MUX(CDC_DMICCLK3,  "codec-dmicclk3");
26862306a36Sopenharmony_ciLN2_PIN_MUX(CDC_DMICDAT3,  "codec-dmicdat3");
26962306a36Sopenharmony_ciLN2_PIN_MUX(CDC_DMICCLK4,  "codec-dmicclk4");
27062306a36Sopenharmony_ciLN2_PIN_MUX(CDC_DMICDAT4,  "codec-dmicdat4");
27162306a36Sopenharmony_ciLN2_PIN_MUX(DSP_DMICCLK1,  "dsp-dmicclk1");
27262306a36Sopenharmony_ciLN2_PIN_MUX(DSP_DMICDAT1,  "dsp-dmicdat1");
27362306a36Sopenharmony_ciLN2_PIN_MUX(DSP_DMICCLK2,  "dsp-dmicclk2");
27462306a36Sopenharmony_ciLN2_PIN_MUX(DSP_DMICDAT2,  "dsp-dmicdat2");
27562306a36Sopenharmony_ciLN2_PIN_MUX(I2C2_SCL,      "i2c2-scl");
27662306a36Sopenharmony_ciLN2_PIN_MUX(I2C2_SDA,      "i2c2-sda");
27762306a36Sopenharmony_ciLN2_PIN_MUX(I2C3_SCL,      "i2c3-scl");
27862306a36Sopenharmony_ciLN2_PIN_MUX(I2C3_SDA,      "i2c3-sda");
27962306a36Sopenharmony_ciLN2_PIN_MUX(I2C4_SCL,      "i2c4-scl");
28062306a36Sopenharmony_ciLN2_PIN_MUX(I2C4_SDA,      "i2c4-sda");
28162306a36Sopenharmony_ciLN2_PIN_MUX(DSP_STANDBY,   "dsp-standby");
28262306a36Sopenharmony_ciLN2_PIN_MUX(CDC_MCLK1,     "codec-mclk1");
28362306a36Sopenharmony_ciLN2_PIN_MUX(CDC_MCLK2,     "codec-mclk2");
28462306a36Sopenharmony_ciLN2_PIN_MUX(DSP_CLKIN,     "dsp-clkin");
28562306a36Sopenharmony_ciLN2_PIN_MUX(PSIA1_MCLK,    "psia1-mclk");
28662306a36Sopenharmony_ciLN2_PIN_MUX(PSIA2_MCLK,    "psia2-mclk");
28762306a36Sopenharmony_ciLN2_PIN_MUX(GF_GPIO1,      "gf-gpio1");
28862306a36Sopenharmony_ciLN2_PIN_MUX(GF_GPIO5,      "gf-gpio5");
28962306a36Sopenharmony_ciLN2_PIN_MUX(DSP_GPIO20,    "dsp-gpio20");
29062306a36Sopenharmony_ciLN2_PIN_GAI(CDC_AIF1);
29162306a36Sopenharmony_ciLN2_PIN_GAI(CDC_AIF2);
29262306a36Sopenharmony_ciLN2_PIN_GAI(CDC_AIF3);
29362306a36Sopenharmony_ciLN2_PIN_GAI(DSP_AIF1);
29462306a36Sopenharmony_ciLN2_PIN_GAI(DSP_AIF2);
29562306a36Sopenharmony_ciLN2_PIN_GAI(PSIA1);
29662306a36Sopenharmony_ciLN2_PIN_GAI(PSIA2);
29762306a36Sopenharmony_ciLN2_PIN_GAI(GF_AIF1);
29862306a36Sopenharmony_ciLN2_PIN_GAI(GF_AIF2);
29962306a36Sopenharmony_ciLN2_PIN_GAI(GF_AIF3);
30062306a36Sopenharmony_ciLN2_PIN_GAI(GF_AIF4);
30162306a36Sopenharmony_ciLN2_PIN_AIF(SPDIF_AIF);
30262306a36Sopenharmony_ciLN2_PIN_AIF(USB_AIF1);
30362306a36Sopenharmony_ciLN2_PIN_AIF(USB_AIF2);
30462306a36Sopenharmony_ciLN2_PIN_AIF(ADAT_AIF);
30562306a36Sopenharmony_ciLN2_PIN_AIF(SOUNDCARD_AIF);
30662306a36Sopenharmony_ci
30762306a36Sopenharmony_cistatic const struct pinctrl_pin_desc lochnagar1_pins[] = {
30862306a36Sopenharmony_ci	LN1_PIN(CDC_RESET),      LN1_PIN(DSP_RESET),    LN1_PIN(CDC_CIF1MODE),
30962306a36Sopenharmony_ci	LN1_PIN(GF_GPIO2),       LN1_PIN(GF_GPIO3),     LN1_PIN(GF_GPIO7),
31062306a36Sopenharmony_ci	LN1_PIN(LED1),           LN1_PIN(LED2),
31162306a36Sopenharmony_ci	LN1_PINS(CDC_AIF1),      LN1_PINS(CDC_AIF2),    LN1_PINS(CDC_AIF3),
31262306a36Sopenharmony_ci	LN1_PINS(DSP_AIF1),      LN1_PINS(DSP_AIF2),
31362306a36Sopenharmony_ci	LN1_PINS(PSIA1),         LN1_PINS(PSIA2),
31462306a36Sopenharmony_ci	LN1_PINS(SPDIF_AIF),
31562306a36Sopenharmony_ci	LN1_PINS(GF_AIF1),       LN1_PINS(GF_AIF2),
31662306a36Sopenharmony_ci	LN1_PINS(GF_AIF3),       LN1_PINS(GF_AIF4),
31762306a36Sopenharmony_ci};
31862306a36Sopenharmony_ci
31962306a36Sopenharmony_cistatic const struct pinctrl_pin_desc lochnagar2_pins[] = {
32062306a36Sopenharmony_ci	LN2_PIN(CDC_RESET),      LN2_PIN(DSP_RESET),    LN2_PIN(CDC_CIF1MODE),
32162306a36Sopenharmony_ci	LN2_PIN(CDC_LDOENA),
32262306a36Sopenharmony_ci	LN2_PIN(SPDIF_HWMODE),   LN2_PIN(SPDIF_RESET),
32362306a36Sopenharmony_ci	LN2_PIN(FPGA_GPIO1),     LN2_PIN(FPGA_GPIO2),   LN2_PIN(FPGA_GPIO3),
32462306a36Sopenharmony_ci	LN2_PIN(FPGA_GPIO4),     LN2_PIN(FPGA_GPIO5),   LN2_PIN(FPGA_GPIO6),
32562306a36Sopenharmony_ci	LN2_PIN(CDC_GPIO1),      LN2_PIN(CDC_GPIO2),    LN2_PIN(CDC_GPIO3),
32662306a36Sopenharmony_ci	LN2_PIN(CDC_GPIO4),      LN2_PIN(CDC_GPIO5),    LN2_PIN(CDC_GPIO6),
32762306a36Sopenharmony_ci	LN2_PIN(CDC_GPIO7),      LN2_PIN(CDC_GPIO8),
32862306a36Sopenharmony_ci	LN2_PIN(DSP_GPIO1),      LN2_PIN(DSP_GPIO2),    LN2_PIN(DSP_GPIO3),
32962306a36Sopenharmony_ci	LN2_PIN(DSP_GPIO4),      LN2_PIN(DSP_GPIO5),    LN2_PIN(DSP_GPIO6),
33062306a36Sopenharmony_ci	LN2_PIN(DSP_GPIO20),
33162306a36Sopenharmony_ci	LN2_PIN(GF_GPIO1),       LN2_PIN(GF_GPIO2),     LN2_PIN(GF_GPIO3),
33262306a36Sopenharmony_ci	LN2_PIN(GF_GPIO5),       LN2_PIN(GF_GPIO7),
33362306a36Sopenharmony_ci	LN2_PINS(CDC_AIF1),      LN2_PINS(CDC_AIF2),    LN2_PINS(CDC_AIF3),
33462306a36Sopenharmony_ci	LN2_PINS(DSP_AIF1),      LN2_PINS(DSP_AIF2),
33562306a36Sopenharmony_ci	LN2_PINS(PSIA1),         LN2_PINS(PSIA2),
33662306a36Sopenharmony_ci	LN2_PINS(GF_AIF1),       LN2_PINS(GF_AIF2),
33762306a36Sopenharmony_ci	LN2_PINS(GF_AIF3),       LN2_PINS(GF_AIF4),
33862306a36Sopenharmony_ci	LN2_PIN(DSP_UART1_RX),   LN2_PIN(DSP_UART1_TX),
33962306a36Sopenharmony_ci	LN2_PIN(DSP_UART2_RX),   LN2_PIN(DSP_UART2_TX),
34062306a36Sopenharmony_ci	LN2_PIN(GF_UART2_RX),    LN2_PIN(GF_UART2_TX),
34162306a36Sopenharmony_ci	LN2_PIN(USB_UART_RX),
34262306a36Sopenharmony_ci	LN2_PIN(CDC_PDMCLK1),    LN2_PIN(CDC_PDMDAT1),
34362306a36Sopenharmony_ci	LN2_PIN(CDC_PDMCLK2),    LN2_PIN(CDC_PDMDAT2),
34462306a36Sopenharmony_ci	LN2_PIN(CDC_DMICCLK1),   LN2_PIN(CDC_DMICDAT1),
34562306a36Sopenharmony_ci	LN2_PIN(CDC_DMICCLK2),   LN2_PIN(CDC_DMICDAT2),
34662306a36Sopenharmony_ci	LN2_PIN(CDC_DMICCLK3),   LN2_PIN(CDC_DMICDAT3),
34762306a36Sopenharmony_ci	LN2_PIN(CDC_DMICCLK4),   LN2_PIN(CDC_DMICDAT4),
34862306a36Sopenharmony_ci	LN2_PIN(DSP_DMICCLK1),   LN2_PIN(DSP_DMICDAT1),
34962306a36Sopenharmony_ci	LN2_PIN(DSP_DMICCLK2),   LN2_PIN(DSP_DMICDAT2),
35062306a36Sopenharmony_ci	LN2_PIN(I2C2_SCL),       LN2_PIN(I2C2_SDA),
35162306a36Sopenharmony_ci	LN2_PIN(I2C3_SCL),       LN2_PIN(I2C3_SDA),
35262306a36Sopenharmony_ci	LN2_PIN(I2C4_SCL),       LN2_PIN(I2C4_SDA),
35362306a36Sopenharmony_ci	LN2_PIN(DSP_STANDBY),
35462306a36Sopenharmony_ci	LN2_PIN(CDC_MCLK1),      LN2_PIN(CDC_MCLK2),
35562306a36Sopenharmony_ci	LN2_PIN(DSP_CLKIN),
35662306a36Sopenharmony_ci	LN2_PIN(PSIA1_MCLK),     LN2_PIN(PSIA2_MCLK),
35762306a36Sopenharmony_ci	LN2_PINS(SPDIF_AIF),
35862306a36Sopenharmony_ci	LN2_PINS(USB_AIF1),      LN2_PINS(USB_AIF2),
35962306a36Sopenharmony_ci	LN2_PINS(ADAT_AIF),
36062306a36Sopenharmony_ci	LN2_PINS(SOUNDCARD_AIF),
36162306a36Sopenharmony_ci};
36262306a36Sopenharmony_ci
36362306a36Sopenharmony_ci#define LN_AIF_PINS(REV, ID) \
36462306a36Sopenharmony_ci	LOCHNAGAR##REV##_PIN_##ID##_BCLK, \
36562306a36Sopenharmony_ci	LOCHNAGAR##REV##_PIN_##ID##_LRCLK, \
36662306a36Sopenharmony_ci	LOCHNAGAR##REV##_PIN_##ID##_TXDAT, \
36762306a36Sopenharmony_ci	LOCHNAGAR##REV##_PIN_##ID##_RXDAT,
36862306a36Sopenharmony_ci
36962306a36Sopenharmony_ci#define LN1_AIF(ID, CTRL) \
37062306a36Sopenharmony_cistatic const struct lochnagar_aif lochnagar1_##ID##_aif = { \
37162306a36Sopenharmony_ci	.name = LN_##ID##_STR, \
37262306a36Sopenharmony_ci	.pins = { LN_AIF_PINS(1, ID) }, \
37362306a36Sopenharmony_ci	.src_reg = LOCHNAGAR1_##ID##_SEL, \
37462306a36Sopenharmony_ci	.src_mask = LOCHNAGAR1_SRC_MASK, \
37562306a36Sopenharmony_ci	.ctrl_reg = LOCHNAGAR1_##CTRL, \
37662306a36Sopenharmony_ci	.ena_mask = LOCHNAGAR1_##ID##_ENA_MASK, \
37762306a36Sopenharmony_ci	.master_mask = LOCHNAGAR1_##ID##_LRCLK_DIR_MASK | \
37862306a36Sopenharmony_ci		       LOCHNAGAR1_##ID##_BCLK_DIR_MASK, \
37962306a36Sopenharmony_ci}
38062306a36Sopenharmony_ci
38162306a36Sopenharmony_ci#define LN2_AIF(ID) \
38262306a36Sopenharmony_cistatic const struct lochnagar_aif lochnagar2_##ID##_aif = { \
38362306a36Sopenharmony_ci	.name = LN_##ID##_STR, \
38462306a36Sopenharmony_ci	.pins = { LN_AIF_PINS(2, ID) }, \
38562306a36Sopenharmony_ci	.src_reg = LOCHNAGAR2_##ID##_CTRL,  \
38662306a36Sopenharmony_ci	.src_mask = LOCHNAGAR2_AIF_SRC_MASK, \
38762306a36Sopenharmony_ci	.ctrl_reg = LOCHNAGAR2_##ID##_CTRL, \
38862306a36Sopenharmony_ci	.ena_mask = LOCHNAGAR2_AIF_ENA_MASK, \
38962306a36Sopenharmony_ci	.master_mask = LOCHNAGAR2_AIF_LRCLK_DIR_MASK | \
39062306a36Sopenharmony_ci		       LOCHNAGAR2_AIF_BCLK_DIR_MASK, \
39162306a36Sopenharmony_ci}
39262306a36Sopenharmony_ci
39362306a36Sopenharmony_cistruct lochnagar_aif {
39462306a36Sopenharmony_ci	const char name[16];
39562306a36Sopenharmony_ci
39662306a36Sopenharmony_ci	unsigned int pins[4];
39762306a36Sopenharmony_ci
39862306a36Sopenharmony_ci	u16 src_reg;
39962306a36Sopenharmony_ci	u16 src_mask;
40062306a36Sopenharmony_ci
40162306a36Sopenharmony_ci	u16 ctrl_reg;
40262306a36Sopenharmony_ci	u16 ena_mask;
40362306a36Sopenharmony_ci	u16 master_mask;
40462306a36Sopenharmony_ci};
40562306a36Sopenharmony_ci
40662306a36Sopenharmony_ciLN1_AIF(CDC_AIF1,      CDC_AIF_CTRL1);
40762306a36Sopenharmony_ciLN1_AIF(CDC_AIF2,      CDC_AIF_CTRL1);
40862306a36Sopenharmony_ciLN1_AIF(CDC_AIF3,      CDC_AIF_CTRL2);
40962306a36Sopenharmony_ciLN1_AIF(DSP_AIF1,      DSP_AIF);
41062306a36Sopenharmony_ciLN1_AIF(DSP_AIF2,      DSP_AIF);
41162306a36Sopenharmony_ciLN1_AIF(PSIA1,         PSIA_AIF);
41262306a36Sopenharmony_ciLN1_AIF(PSIA2,         PSIA_AIF);
41362306a36Sopenharmony_ciLN1_AIF(GF_AIF1,       GF_AIF1);
41462306a36Sopenharmony_ciLN1_AIF(GF_AIF2,       GF_AIF2);
41562306a36Sopenharmony_ciLN1_AIF(GF_AIF3,       GF_AIF1);
41662306a36Sopenharmony_ciLN1_AIF(GF_AIF4,       GF_AIF2);
41762306a36Sopenharmony_ciLN1_AIF(SPDIF_AIF,     EXT_AIF_CTRL);
41862306a36Sopenharmony_ci
41962306a36Sopenharmony_ciLN2_AIF(CDC_AIF1);
42062306a36Sopenharmony_ciLN2_AIF(CDC_AIF2);
42162306a36Sopenharmony_ciLN2_AIF(CDC_AIF3);
42262306a36Sopenharmony_ciLN2_AIF(DSP_AIF1);
42362306a36Sopenharmony_ciLN2_AIF(DSP_AIF2);
42462306a36Sopenharmony_ciLN2_AIF(PSIA1);
42562306a36Sopenharmony_ciLN2_AIF(PSIA2);
42662306a36Sopenharmony_ciLN2_AIF(GF_AIF1);
42762306a36Sopenharmony_ciLN2_AIF(GF_AIF2);
42862306a36Sopenharmony_ciLN2_AIF(GF_AIF3);
42962306a36Sopenharmony_ciLN2_AIF(GF_AIF4);
43062306a36Sopenharmony_ciLN2_AIF(SPDIF_AIF);
43162306a36Sopenharmony_ciLN2_AIF(USB_AIF1);
43262306a36Sopenharmony_ciLN2_AIF(USB_AIF2);
43362306a36Sopenharmony_ciLN2_AIF(ADAT_AIF);
43462306a36Sopenharmony_ciLN2_AIF(SOUNDCARD_AIF);
43562306a36Sopenharmony_ci
43662306a36Sopenharmony_ci#define LN2_OP_AIF	0x00
43762306a36Sopenharmony_ci#define LN2_OP_GPIO	0xFE
43862306a36Sopenharmony_ci
43962306a36Sopenharmony_ci#define LN_FUNC(NAME, TYPE, OP) \
44062306a36Sopenharmony_ci	{ .name = NAME, .type = LN_FTYPE_##TYPE, .op = OP }
44162306a36Sopenharmony_ci
44262306a36Sopenharmony_ci#define LN_FUNC_PIN(REV, ID, OP) \
44362306a36Sopenharmony_ci	LN_FUNC(lochnagar##REV##_##ID##_pin.name, PIN, OP)
44462306a36Sopenharmony_ci
44562306a36Sopenharmony_ci#define LN1_FUNC_PIN(ID, OP) LN_FUNC_PIN(1, ID, OP)
44662306a36Sopenharmony_ci#define LN2_FUNC_PIN(ID, OP) LN_FUNC_PIN(2, ID, OP)
44762306a36Sopenharmony_ci
44862306a36Sopenharmony_ci#define LN_FUNC_AIF(REV, ID, OP) \
44962306a36Sopenharmony_ci	LN_FUNC(lochnagar##REV##_##ID##_aif.name, AIF, OP)
45062306a36Sopenharmony_ci
45162306a36Sopenharmony_ci#define LN1_FUNC_AIF(ID, OP) LN_FUNC_AIF(1, ID, OP)
45262306a36Sopenharmony_ci#define LN2_FUNC_AIF(ID, OP) LN_FUNC_AIF(2, ID, OP)
45362306a36Sopenharmony_ci
45462306a36Sopenharmony_ci#define LN2_FUNC_GAI(ID, OP, BOP, LROP, RXOP, TXOP) \
45562306a36Sopenharmony_ci	LN2_FUNC_AIF(ID, OP), \
45662306a36Sopenharmony_ci	LN_FUNC(lochnagar2_##ID##_BCLK_pin.name, PIN, BOP), \
45762306a36Sopenharmony_ci	LN_FUNC(lochnagar2_##ID##_LRCLK_pin.name, PIN, LROP), \
45862306a36Sopenharmony_ci	LN_FUNC(lochnagar2_##ID##_RXDAT_pin.name, PIN, RXOP), \
45962306a36Sopenharmony_ci	LN_FUNC(lochnagar2_##ID##_TXDAT_pin.name, PIN, TXOP)
46062306a36Sopenharmony_ci
46162306a36Sopenharmony_cienum lochnagar_func_type {
46262306a36Sopenharmony_ci	LN_FTYPE_PIN,
46362306a36Sopenharmony_ci	LN_FTYPE_AIF,
46462306a36Sopenharmony_ci	LN_FTYPE_COUNT,
46562306a36Sopenharmony_ci};
46662306a36Sopenharmony_ci
46762306a36Sopenharmony_cistruct lochnagar_func {
46862306a36Sopenharmony_ci	const char * const name;
46962306a36Sopenharmony_ci
47062306a36Sopenharmony_ci	enum lochnagar_func_type type;
47162306a36Sopenharmony_ci
47262306a36Sopenharmony_ci	u8 op;
47362306a36Sopenharmony_ci};
47462306a36Sopenharmony_ci
47562306a36Sopenharmony_cistatic const struct lochnagar_func lochnagar1_funcs[] = {
47662306a36Sopenharmony_ci	LN_FUNC("dsp-gpio1",       PIN, 0x01),
47762306a36Sopenharmony_ci	LN_FUNC("dsp-gpio2",       PIN, 0x02),
47862306a36Sopenharmony_ci	LN_FUNC("dsp-gpio3",       PIN, 0x03),
47962306a36Sopenharmony_ci	LN_FUNC("codec-gpio1",     PIN, 0x04),
48062306a36Sopenharmony_ci	LN_FUNC("codec-gpio2",     PIN, 0x05),
48162306a36Sopenharmony_ci	LN_FUNC("codec-gpio3",     PIN, 0x06),
48262306a36Sopenharmony_ci	LN_FUNC("codec-gpio4",     PIN, 0x07),
48362306a36Sopenharmony_ci	LN_FUNC("codec-gpio5",     PIN, 0x08),
48462306a36Sopenharmony_ci	LN_FUNC("codec-gpio6",     PIN, 0x09),
48562306a36Sopenharmony_ci	LN_FUNC("codec-gpio7",     PIN, 0x0A),
48662306a36Sopenharmony_ci	LN_FUNC("codec-gpio8",     PIN, 0x0B),
48762306a36Sopenharmony_ci	LN1_FUNC_PIN(GF_GPIO2,          0x0C),
48862306a36Sopenharmony_ci	LN1_FUNC_PIN(GF_GPIO3,          0x0D),
48962306a36Sopenharmony_ci	LN1_FUNC_PIN(GF_GPIO7,          0x0E),
49062306a36Sopenharmony_ci
49162306a36Sopenharmony_ci	LN1_FUNC_AIF(SPDIF_AIF,         0x01),
49262306a36Sopenharmony_ci	LN1_FUNC_AIF(PSIA1,             0x02),
49362306a36Sopenharmony_ci	LN1_FUNC_AIF(PSIA2,             0x03),
49462306a36Sopenharmony_ci	LN1_FUNC_AIF(CDC_AIF1,          0x04),
49562306a36Sopenharmony_ci	LN1_FUNC_AIF(CDC_AIF2,          0x05),
49662306a36Sopenharmony_ci	LN1_FUNC_AIF(CDC_AIF3,          0x06),
49762306a36Sopenharmony_ci	LN1_FUNC_AIF(DSP_AIF1,          0x07),
49862306a36Sopenharmony_ci	LN1_FUNC_AIF(DSP_AIF2,          0x08),
49962306a36Sopenharmony_ci	LN1_FUNC_AIF(GF_AIF3,           0x09),
50062306a36Sopenharmony_ci	LN1_FUNC_AIF(GF_AIF4,           0x0A),
50162306a36Sopenharmony_ci	LN1_FUNC_AIF(GF_AIF1,           0x0B),
50262306a36Sopenharmony_ci	LN1_FUNC_AIF(GF_AIF2,           0x0C),
50362306a36Sopenharmony_ci};
50462306a36Sopenharmony_ci
50562306a36Sopenharmony_cistatic const struct lochnagar_func lochnagar2_funcs[] = {
50662306a36Sopenharmony_ci	LN_FUNC("aif",             PIN, LN2_OP_AIF),
50762306a36Sopenharmony_ci	LN2_FUNC_PIN(FPGA_GPIO1,        0x01),
50862306a36Sopenharmony_ci	LN2_FUNC_PIN(FPGA_GPIO2,        0x02),
50962306a36Sopenharmony_ci	LN2_FUNC_PIN(FPGA_GPIO3,        0x03),
51062306a36Sopenharmony_ci	LN2_FUNC_PIN(FPGA_GPIO4,        0x04),
51162306a36Sopenharmony_ci	LN2_FUNC_PIN(FPGA_GPIO5,        0x05),
51262306a36Sopenharmony_ci	LN2_FUNC_PIN(FPGA_GPIO6,        0x06),
51362306a36Sopenharmony_ci	LN2_FUNC_PIN(CDC_GPIO1,         0x07),
51462306a36Sopenharmony_ci	LN2_FUNC_PIN(CDC_GPIO2,         0x08),
51562306a36Sopenharmony_ci	LN2_FUNC_PIN(CDC_GPIO3,         0x09),
51662306a36Sopenharmony_ci	LN2_FUNC_PIN(CDC_GPIO4,         0x0A),
51762306a36Sopenharmony_ci	LN2_FUNC_PIN(CDC_GPIO5,         0x0B),
51862306a36Sopenharmony_ci	LN2_FUNC_PIN(CDC_GPIO6,         0x0C),
51962306a36Sopenharmony_ci	LN2_FUNC_PIN(CDC_GPIO7,         0x0D),
52062306a36Sopenharmony_ci	LN2_FUNC_PIN(CDC_GPIO8,         0x0E),
52162306a36Sopenharmony_ci	LN2_FUNC_PIN(DSP_GPIO1,         0x0F),
52262306a36Sopenharmony_ci	LN2_FUNC_PIN(DSP_GPIO2,         0x10),
52362306a36Sopenharmony_ci	LN2_FUNC_PIN(DSP_GPIO3,         0x11),
52462306a36Sopenharmony_ci	LN2_FUNC_PIN(DSP_GPIO4,         0x12),
52562306a36Sopenharmony_ci	LN2_FUNC_PIN(DSP_GPIO5,         0x13),
52662306a36Sopenharmony_ci	LN2_FUNC_PIN(DSP_GPIO6,         0x14),
52762306a36Sopenharmony_ci	LN2_FUNC_PIN(GF_GPIO2,          0x15),
52862306a36Sopenharmony_ci	LN2_FUNC_PIN(GF_GPIO3,          0x16),
52962306a36Sopenharmony_ci	LN2_FUNC_PIN(GF_GPIO7,          0x17),
53062306a36Sopenharmony_ci	LN2_FUNC_PIN(GF_GPIO1,          0x18),
53162306a36Sopenharmony_ci	LN2_FUNC_PIN(GF_GPIO5,          0x19),
53262306a36Sopenharmony_ci	LN2_FUNC_PIN(DSP_GPIO20,        0x1A),
53362306a36Sopenharmony_ci	LN_FUNC("codec-clkout",    PIN, 0x20),
53462306a36Sopenharmony_ci	LN_FUNC("dsp-clkout",      PIN, 0x21),
53562306a36Sopenharmony_ci	LN_FUNC("pmic-32k",        PIN, 0x22),
53662306a36Sopenharmony_ci	LN_FUNC("spdif-clkout",    PIN, 0x23),
53762306a36Sopenharmony_ci	LN_FUNC("clk-12m288",      PIN, 0x24),
53862306a36Sopenharmony_ci	LN_FUNC("clk-11m2986",     PIN, 0x25),
53962306a36Sopenharmony_ci	LN_FUNC("clk-24m576",      PIN, 0x26),
54062306a36Sopenharmony_ci	LN_FUNC("clk-22m5792",     PIN, 0x27),
54162306a36Sopenharmony_ci	LN_FUNC("xmos-mclk",       PIN, 0x29),
54262306a36Sopenharmony_ci	LN_FUNC("gf-clkout1",      PIN, 0x2A),
54362306a36Sopenharmony_ci	LN_FUNC("gf-mclk1",        PIN, 0x2B),
54462306a36Sopenharmony_ci	LN_FUNC("gf-mclk3",        PIN, 0x2C),
54562306a36Sopenharmony_ci	LN_FUNC("gf-mclk2",        PIN, 0x2D),
54662306a36Sopenharmony_ci	LN_FUNC("gf-clkout2",      PIN, 0x2E),
54762306a36Sopenharmony_ci	LN2_FUNC_PIN(CDC_MCLK1,         0x2F),
54862306a36Sopenharmony_ci	LN2_FUNC_PIN(CDC_MCLK2,         0x30),
54962306a36Sopenharmony_ci	LN2_FUNC_PIN(DSP_CLKIN,         0x31),
55062306a36Sopenharmony_ci	LN2_FUNC_PIN(PSIA1_MCLK,        0x32),
55162306a36Sopenharmony_ci	LN2_FUNC_PIN(PSIA2_MCLK,        0x33),
55262306a36Sopenharmony_ci	LN_FUNC("spdif-mclk",      PIN, 0x34),
55362306a36Sopenharmony_ci	LN_FUNC("codec-irq",       PIN, 0x42),
55462306a36Sopenharmony_ci	LN2_FUNC_PIN(CDC_RESET,         0x43),
55562306a36Sopenharmony_ci	LN2_FUNC_PIN(DSP_RESET,         0x44),
55662306a36Sopenharmony_ci	LN_FUNC("dsp-irq",         PIN, 0x45),
55762306a36Sopenharmony_ci	LN2_FUNC_PIN(DSP_STANDBY,       0x46),
55862306a36Sopenharmony_ci	LN2_FUNC_PIN(CDC_PDMCLK1,       0x90),
55962306a36Sopenharmony_ci	LN2_FUNC_PIN(CDC_PDMDAT1,       0x91),
56062306a36Sopenharmony_ci	LN2_FUNC_PIN(CDC_PDMCLK2,       0x92),
56162306a36Sopenharmony_ci	LN2_FUNC_PIN(CDC_PDMDAT2,       0x93),
56262306a36Sopenharmony_ci	LN2_FUNC_PIN(CDC_DMICCLK1,      0xA0),
56362306a36Sopenharmony_ci	LN2_FUNC_PIN(CDC_DMICDAT1,      0xA1),
56462306a36Sopenharmony_ci	LN2_FUNC_PIN(CDC_DMICCLK2,      0xA2),
56562306a36Sopenharmony_ci	LN2_FUNC_PIN(CDC_DMICDAT2,      0xA3),
56662306a36Sopenharmony_ci	LN2_FUNC_PIN(CDC_DMICCLK3,      0xA4),
56762306a36Sopenharmony_ci	LN2_FUNC_PIN(CDC_DMICDAT3,      0xA5),
56862306a36Sopenharmony_ci	LN2_FUNC_PIN(CDC_DMICCLK4,      0xA6),
56962306a36Sopenharmony_ci	LN2_FUNC_PIN(CDC_DMICDAT4,      0xA7),
57062306a36Sopenharmony_ci	LN2_FUNC_PIN(DSP_DMICCLK1,      0xA8),
57162306a36Sopenharmony_ci	LN2_FUNC_PIN(DSP_DMICDAT1,      0xA9),
57262306a36Sopenharmony_ci	LN2_FUNC_PIN(DSP_DMICCLK2,      0xAA),
57362306a36Sopenharmony_ci	LN2_FUNC_PIN(DSP_DMICDAT2,      0xAB),
57462306a36Sopenharmony_ci	LN2_FUNC_PIN(DSP_UART1_RX,      0xC0),
57562306a36Sopenharmony_ci	LN2_FUNC_PIN(DSP_UART1_TX,      0xC1),
57662306a36Sopenharmony_ci	LN2_FUNC_PIN(DSP_UART2_RX,      0xC2),
57762306a36Sopenharmony_ci	LN2_FUNC_PIN(DSP_UART2_TX,      0xC3),
57862306a36Sopenharmony_ci	LN2_FUNC_PIN(GF_UART2_RX,       0xC4),
57962306a36Sopenharmony_ci	LN2_FUNC_PIN(GF_UART2_TX,       0xC5),
58062306a36Sopenharmony_ci	LN2_FUNC_PIN(USB_UART_RX,       0xC6),
58162306a36Sopenharmony_ci	LN_FUNC("usb-uart-tx",     PIN, 0xC7),
58262306a36Sopenharmony_ci	LN2_FUNC_PIN(I2C2_SCL,          0xE0),
58362306a36Sopenharmony_ci	LN2_FUNC_PIN(I2C2_SDA,          0xE1),
58462306a36Sopenharmony_ci	LN2_FUNC_PIN(I2C3_SCL,          0xE2),
58562306a36Sopenharmony_ci	LN2_FUNC_PIN(I2C3_SDA,          0xE3),
58662306a36Sopenharmony_ci	LN2_FUNC_PIN(I2C4_SCL,          0xE4),
58762306a36Sopenharmony_ci	LN2_FUNC_PIN(I2C4_SDA,          0xE5),
58862306a36Sopenharmony_ci
58962306a36Sopenharmony_ci	LN2_FUNC_AIF(SPDIF_AIF,         0x01),
59062306a36Sopenharmony_ci	LN2_FUNC_GAI(PSIA1,             0x02, 0x50, 0x51, 0x52, 0x53),
59162306a36Sopenharmony_ci	LN2_FUNC_GAI(PSIA2,             0x03, 0x54, 0x55, 0x56, 0x57),
59262306a36Sopenharmony_ci	LN2_FUNC_GAI(CDC_AIF1,          0x04, 0x59, 0x5B, 0x5A, 0x58),
59362306a36Sopenharmony_ci	LN2_FUNC_GAI(CDC_AIF2,          0x05, 0x5D, 0x5F, 0x5E, 0x5C),
59462306a36Sopenharmony_ci	LN2_FUNC_GAI(CDC_AIF3,          0x06, 0x61, 0x62, 0x63, 0x60),
59562306a36Sopenharmony_ci	LN2_FUNC_GAI(DSP_AIF1,          0x07, 0x65, 0x67, 0x66, 0x64),
59662306a36Sopenharmony_ci	LN2_FUNC_GAI(DSP_AIF2,          0x08, 0x69, 0x6B, 0x6A, 0x68),
59762306a36Sopenharmony_ci	LN2_FUNC_GAI(GF_AIF3,           0x09, 0x6D, 0x6F, 0x6C, 0x6E),
59862306a36Sopenharmony_ci	LN2_FUNC_GAI(GF_AIF4,           0x0A, 0x71, 0x73, 0x70, 0x72),
59962306a36Sopenharmony_ci	LN2_FUNC_GAI(GF_AIF1,           0x0B, 0x75, 0x77, 0x74, 0x76),
60062306a36Sopenharmony_ci	LN2_FUNC_GAI(GF_AIF2,           0x0C, 0x79, 0x7B, 0x78, 0x7A),
60162306a36Sopenharmony_ci	LN2_FUNC_AIF(USB_AIF1,          0x0D),
60262306a36Sopenharmony_ci	LN2_FUNC_AIF(USB_AIF2,          0x0E),
60362306a36Sopenharmony_ci	LN2_FUNC_AIF(ADAT_AIF,          0x0F),
60462306a36Sopenharmony_ci	LN2_FUNC_AIF(SOUNDCARD_AIF,     0x10),
60562306a36Sopenharmony_ci};
60662306a36Sopenharmony_ci
60762306a36Sopenharmony_ci#define LN_GROUP_PIN(REV, ID) { \
60862306a36Sopenharmony_ci	.name = lochnagar##REV##_##ID##_pin.name, \
60962306a36Sopenharmony_ci	.type = LN_FTYPE_PIN, \
61062306a36Sopenharmony_ci	.pins = &lochnagar##REV##_pins[LOCHNAGAR##REV##_PIN_##ID].number, \
61162306a36Sopenharmony_ci	.npins = 1, \
61262306a36Sopenharmony_ci	.priv = &lochnagar##REV##_pins[LOCHNAGAR##REV##_PIN_##ID], \
61362306a36Sopenharmony_ci}
61462306a36Sopenharmony_ci
61562306a36Sopenharmony_ci#define LN_GROUP_AIF(REV, ID) { \
61662306a36Sopenharmony_ci	.name = lochnagar##REV##_##ID##_aif.name, \
61762306a36Sopenharmony_ci	.type = LN_FTYPE_AIF, \
61862306a36Sopenharmony_ci	.pins = lochnagar##REV##_##ID##_aif.pins, \
61962306a36Sopenharmony_ci	.npins = ARRAY_SIZE(lochnagar##REV##_##ID##_aif.pins), \
62062306a36Sopenharmony_ci	.priv = &lochnagar##REV##_##ID##_aif, \
62162306a36Sopenharmony_ci}
62262306a36Sopenharmony_ci
62362306a36Sopenharmony_ci#define LN1_GROUP_PIN(ID) LN_GROUP_PIN(1, ID)
62462306a36Sopenharmony_ci#define LN2_GROUP_PIN(ID) LN_GROUP_PIN(2, ID)
62562306a36Sopenharmony_ci
62662306a36Sopenharmony_ci#define LN1_GROUP_AIF(ID) LN_GROUP_AIF(1, ID)
62762306a36Sopenharmony_ci#define LN2_GROUP_AIF(ID) LN_GROUP_AIF(2, ID)
62862306a36Sopenharmony_ci
62962306a36Sopenharmony_ci#define LN2_GROUP_GAI(ID) \
63062306a36Sopenharmony_ci	LN2_GROUP_AIF(ID), \
63162306a36Sopenharmony_ci	LN2_GROUP_PIN(ID##_BCLK), LN2_GROUP_PIN(ID##_LRCLK), \
63262306a36Sopenharmony_ci	LN2_GROUP_PIN(ID##_RXDAT), LN2_GROUP_PIN(ID##_TXDAT)
63362306a36Sopenharmony_ci
63462306a36Sopenharmony_cistruct lochnagar_group {
63562306a36Sopenharmony_ci	const char * const name;
63662306a36Sopenharmony_ci
63762306a36Sopenharmony_ci	enum lochnagar_func_type type;
63862306a36Sopenharmony_ci
63962306a36Sopenharmony_ci	const unsigned int *pins;
64062306a36Sopenharmony_ci	unsigned int npins;
64162306a36Sopenharmony_ci
64262306a36Sopenharmony_ci	const void *priv;
64362306a36Sopenharmony_ci};
64462306a36Sopenharmony_ci
64562306a36Sopenharmony_cistatic const struct lochnagar_group lochnagar1_groups[] = {
64662306a36Sopenharmony_ci	LN1_GROUP_PIN(GF_GPIO2),       LN1_GROUP_PIN(GF_GPIO3),
64762306a36Sopenharmony_ci	LN1_GROUP_PIN(GF_GPIO7),
64862306a36Sopenharmony_ci	LN1_GROUP_PIN(LED1),           LN1_GROUP_PIN(LED2),
64962306a36Sopenharmony_ci	LN1_GROUP_AIF(CDC_AIF1),       LN1_GROUP_AIF(CDC_AIF2),
65062306a36Sopenharmony_ci	LN1_GROUP_AIF(CDC_AIF3),
65162306a36Sopenharmony_ci	LN1_GROUP_AIF(DSP_AIF1),       LN1_GROUP_AIF(DSP_AIF2),
65262306a36Sopenharmony_ci	LN1_GROUP_AIF(PSIA1),          LN1_GROUP_AIF(PSIA2),
65362306a36Sopenharmony_ci	LN1_GROUP_AIF(GF_AIF1),        LN1_GROUP_AIF(GF_AIF2),
65462306a36Sopenharmony_ci	LN1_GROUP_AIF(GF_AIF3),        LN1_GROUP_AIF(GF_AIF4),
65562306a36Sopenharmony_ci	LN1_GROUP_AIF(SPDIF_AIF),
65662306a36Sopenharmony_ci};
65762306a36Sopenharmony_ci
65862306a36Sopenharmony_cistatic const struct lochnagar_group lochnagar2_groups[] = {
65962306a36Sopenharmony_ci	LN2_GROUP_PIN(FPGA_GPIO1),     LN2_GROUP_PIN(FPGA_GPIO2),
66062306a36Sopenharmony_ci	LN2_GROUP_PIN(FPGA_GPIO3),     LN2_GROUP_PIN(FPGA_GPIO4),
66162306a36Sopenharmony_ci	LN2_GROUP_PIN(FPGA_GPIO5),     LN2_GROUP_PIN(FPGA_GPIO6),
66262306a36Sopenharmony_ci	LN2_GROUP_PIN(CDC_GPIO1),      LN2_GROUP_PIN(CDC_GPIO2),
66362306a36Sopenharmony_ci	LN2_GROUP_PIN(CDC_GPIO3),      LN2_GROUP_PIN(CDC_GPIO4),
66462306a36Sopenharmony_ci	LN2_GROUP_PIN(CDC_GPIO5),      LN2_GROUP_PIN(CDC_GPIO6),
66562306a36Sopenharmony_ci	LN2_GROUP_PIN(CDC_GPIO7),      LN2_GROUP_PIN(CDC_GPIO8),
66662306a36Sopenharmony_ci	LN2_GROUP_PIN(DSP_GPIO1),      LN2_GROUP_PIN(DSP_GPIO2),
66762306a36Sopenharmony_ci	LN2_GROUP_PIN(DSP_GPIO3),      LN2_GROUP_PIN(DSP_GPIO4),
66862306a36Sopenharmony_ci	LN2_GROUP_PIN(DSP_GPIO5),      LN2_GROUP_PIN(DSP_GPIO6),
66962306a36Sopenharmony_ci	LN2_GROUP_PIN(DSP_GPIO20),
67062306a36Sopenharmony_ci	LN2_GROUP_PIN(GF_GPIO1),
67162306a36Sopenharmony_ci	LN2_GROUP_PIN(GF_GPIO2),       LN2_GROUP_PIN(GF_GPIO5),
67262306a36Sopenharmony_ci	LN2_GROUP_PIN(GF_GPIO3),       LN2_GROUP_PIN(GF_GPIO7),
67362306a36Sopenharmony_ci	LN2_GROUP_PIN(DSP_UART1_RX),   LN2_GROUP_PIN(DSP_UART1_TX),
67462306a36Sopenharmony_ci	LN2_GROUP_PIN(DSP_UART2_RX),   LN2_GROUP_PIN(DSP_UART2_TX),
67562306a36Sopenharmony_ci	LN2_GROUP_PIN(GF_UART2_RX),    LN2_GROUP_PIN(GF_UART2_TX),
67662306a36Sopenharmony_ci	LN2_GROUP_PIN(USB_UART_RX),
67762306a36Sopenharmony_ci	LN2_GROUP_PIN(CDC_PDMCLK1),    LN2_GROUP_PIN(CDC_PDMDAT1),
67862306a36Sopenharmony_ci	LN2_GROUP_PIN(CDC_PDMCLK2),    LN2_GROUP_PIN(CDC_PDMDAT2),
67962306a36Sopenharmony_ci	LN2_GROUP_PIN(CDC_DMICCLK1),   LN2_GROUP_PIN(CDC_DMICDAT1),
68062306a36Sopenharmony_ci	LN2_GROUP_PIN(CDC_DMICCLK2),   LN2_GROUP_PIN(CDC_DMICDAT2),
68162306a36Sopenharmony_ci	LN2_GROUP_PIN(CDC_DMICCLK3),   LN2_GROUP_PIN(CDC_DMICDAT3),
68262306a36Sopenharmony_ci	LN2_GROUP_PIN(CDC_DMICCLK4),   LN2_GROUP_PIN(CDC_DMICDAT4),
68362306a36Sopenharmony_ci	LN2_GROUP_PIN(DSP_DMICCLK1),   LN2_GROUP_PIN(DSP_DMICDAT1),
68462306a36Sopenharmony_ci	LN2_GROUP_PIN(DSP_DMICCLK2),   LN2_GROUP_PIN(DSP_DMICDAT2),
68562306a36Sopenharmony_ci	LN2_GROUP_PIN(I2C2_SCL),       LN2_GROUP_PIN(I2C2_SDA),
68662306a36Sopenharmony_ci	LN2_GROUP_PIN(I2C3_SCL),       LN2_GROUP_PIN(I2C3_SDA),
68762306a36Sopenharmony_ci	LN2_GROUP_PIN(I2C4_SCL),       LN2_GROUP_PIN(I2C4_SDA),
68862306a36Sopenharmony_ci	LN2_GROUP_PIN(DSP_STANDBY),
68962306a36Sopenharmony_ci	LN2_GROUP_PIN(CDC_MCLK1),      LN2_GROUP_PIN(CDC_MCLK2),
69062306a36Sopenharmony_ci	LN2_GROUP_PIN(DSP_CLKIN),
69162306a36Sopenharmony_ci	LN2_GROUP_PIN(PSIA1_MCLK),     LN2_GROUP_PIN(PSIA2_MCLK),
69262306a36Sopenharmony_ci	LN2_GROUP_GAI(CDC_AIF1),       LN2_GROUP_GAI(CDC_AIF2),
69362306a36Sopenharmony_ci	LN2_GROUP_GAI(CDC_AIF3),
69462306a36Sopenharmony_ci	LN2_GROUP_GAI(DSP_AIF1),       LN2_GROUP_GAI(DSP_AIF2),
69562306a36Sopenharmony_ci	LN2_GROUP_GAI(PSIA1),          LN2_GROUP_GAI(PSIA2),
69662306a36Sopenharmony_ci	LN2_GROUP_GAI(GF_AIF1),        LN2_GROUP_GAI(GF_AIF2),
69762306a36Sopenharmony_ci	LN2_GROUP_GAI(GF_AIF3),        LN2_GROUP_GAI(GF_AIF4),
69862306a36Sopenharmony_ci	LN2_GROUP_AIF(SPDIF_AIF),
69962306a36Sopenharmony_ci	LN2_GROUP_AIF(USB_AIF1),       LN2_GROUP_AIF(USB_AIF2),
70062306a36Sopenharmony_ci	LN2_GROUP_AIF(ADAT_AIF),
70162306a36Sopenharmony_ci	LN2_GROUP_AIF(SOUNDCARD_AIF),
70262306a36Sopenharmony_ci};
70362306a36Sopenharmony_ci
70462306a36Sopenharmony_cistruct lochnagar_func_groups {
70562306a36Sopenharmony_ci	const char **groups;
70662306a36Sopenharmony_ci	unsigned int ngroups;
70762306a36Sopenharmony_ci};
70862306a36Sopenharmony_ci
70962306a36Sopenharmony_cistruct lochnagar_pin_priv {
71062306a36Sopenharmony_ci	struct lochnagar *lochnagar;
71162306a36Sopenharmony_ci	struct device *dev;
71262306a36Sopenharmony_ci
71362306a36Sopenharmony_ci	const struct lochnagar_func *funcs;
71462306a36Sopenharmony_ci	unsigned int nfuncs;
71562306a36Sopenharmony_ci
71662306a36Sopenharmony_ci	const struct pinctrl_pin_desc *pins;
71762306a36Sopenharmony_ci	unsigned int npins;
71862306a36Sopenharmony_ci
71962306a36Sopenharmony_ci	const struct lochnagar_group *groups;
72062306a36Sopenharmony_ci	unsigned int ngroups;
72162306a36Sopenharmony_ci
72262306a36Sopenharmony_ci	struct lochnagar_func_groups func_groups[LN_FTYPE_COUNT];
72362306a36Sopenharmony_ci
72462306a36Sopenharmony_ci	struct gpio_chip gpio_chip;
72562306a36Sopenharmony_ci};
72662306a36Sopenharmony_ci
72762306a36Sopenharmony_cistatic int lochnagar_get_groups_count(struct pinctrl_dev *pctldev)
72862306a36Sopenharmony_ci{
72962306a36Sopenharmony_ci	struct lochnagar_pin_priv *priv = pinctrl_dev_get_drvdata(pctldev);
73062306a36Sopenharmony_ci
73162306a36Sopenharmony_ci	return priv->ngroups;
73262306a36Sopenharmony_ci}
73362306a36Sopenharmony_ci
73462306a36Sopenharmony_cistatic const char *lochnagar_get_group_name(struct pinctrl_dev *pctldev,
73562306a36Sopenharmony_ci					    unsigned int group_idx)
73662306a36Sopenharmony_ci{
73762306a36Sopenharmony_ci	struct lochnagar_pin_priv *priv = pinctrl_dev_get_drvdata(pctldev);
73862306a36Sopenharmony_ci
73962306a36Sopenharmony_ci	return priv->groups[group_idx].name;
74062306a36Sopenharmony_ci}
74162306a36Sopenharmony_ci
74262306a36Sopenharmony_cistatic int lochnagar_get_group_pins(struct pinctrl_dev *pctldev,
74362306a36Sopenharmony_ci				    unsigned int group_idx,
74462306a36Sopenharmony_ci				    const unsigned int **pins,
74562306a36Sopenharmony_ci				    unsigned int *num_pins)
74662306a36Sopenharmony_ci{
74762306a36Sopenharmony_ci	struct lochnagar_pin_priv *priv = pinctrl_dev_get_drvdata(pctldev);
74862306a36Sopenharmony_ci
74962306a36Sopenharmony_ci	*pins = priv->groups[group_idx].pins;
75062306a36Sopenharmony_ci	*num_pins = priv->groups[group_idx].npins;
75162306a36Sopenharmony_ci
75262306a36Sopenharmony_ci	return 0;
75362306a36Sopenharmony_ci}
75462306a36Sopenharmony_ci
75562306a36Sopenharmony_cistatic const struct pinctrl_ops lochnagar_pin_group_ops = {
75662306a36Sopenharmony_ci	.get_groups_count = lochnagar_get_groups_count,
75762306a36Sopenharmony_ci	.get_group_name = lochnagar_get_group_name,
75862306a36Sopenharmony_ci	.get_group_pins = lochnagar_get_group_pins,
75962306a36Sopenharmony_ci	.dt_node_to_map = pinconf_generic_dt_node_to_map_all,
76062306a36Sopenharmony_ci	.dt_free_map = pinctrl_utils_free_map,
76162306a36Sopenharmony_ci};
76262306a36Sopenharmony_ci
76362306a36Sopenharmony_cistatic int lochnagar_get_funcs_count(struct pinctrl_dev *pctldev)
76462306a36Sopenharmony_ci{
76562306a36Sopenharmony_ci	struct lochnagar_pin_priv *priv = pinctrl_dev_get_drvdata(pctldev);
76662306a36Sopenharmony_ci
76762306a36Sopenharmony_ci	return priv->nfuncs;
76862306a36Sopenharmony_ci}
76962306a36Sopenharmony_ci
77062306a36Sopenharmony_cistatic const char *lochnagar_get_func_name(struct pinctrl_dev *pctldev,
77162306a36Sopenharmony_ci					   unsigned int func_idx)
77262306a36Sopenharmony_ci{
77362306a36Sopenharmony_ci	struct lochnagar_pin_priv *priv = pinctrl_dev_get_drvdata(pctldev);
77462306a36Sopenharmony_ci
77562306a36Sopenharmony_ci	return priv->funcs[func_idx].name;
77662306a36Sopenharmony_ci}
77762306a36Sopenharmony_ci
77862306a36Sopenharmony_cistatic int lochnagar_get_func_groups(struct pinctrl_dev *pctldev,
77962306a36Sopenharmony_ci				     unsigned int func_idx,
78062306a36Sopenharmony_ci				     const char * const **groups,
78162306a36Sopenharmony_ci				     unsigned int * const num_groups)
78262306a36Sopenharmony_ci{
78362306a36Sopenharmony_ci	struct lochnagar_pin_priv *priv = pinctrl_dev_get_drvdata(pctldev);
78462306a36Sopenharmony_ci	int func_type;
78562306a36Sopenharmony_ci
78662306a36Sopenharmony_ci	func_type = priv->funcs[func_idx].type;
78762306a36Sopenharmony_ci
78862306a36Sopenharmony_ci	*groups = priv->func_groups[func_type].groups;
78962306a36Sopenharmony_ci	*num_groups = priv->func_groups[func_type].ngroups;
79062306a36Sopenharmony_ci
79162306a36Sopenharmony_ci	return 0;
79262306a36Sopenharmony_ci}
79362306a36Sopenharmony_ci
79462306a36Sopenharmony_cistatic int lochnagar2_get_gpio_chan(struct lochnagar_pin_priv *priv,
79562306a36Sopenharmony_ci				    unsigned int op)
79662306a36Sopenharmony_ci{
79762306a36Sopenharmony_ci	struct regmap *regmap = priv->lochnagar->regmap;
79862306a36Sopenharmony_ci	unsigned int val;
79962306a36Sopenharmony_ci	int free = -1;
80062306a36Sopenharmony_ci	int i, ret;
80162306a36Sopenharmony_ci
80262306a36Sopenharmony_ci	for (i = 0; i < LN2_NUM_GPIO_CHANNELS; i++) {
80362306a36Sopenharmony_ci		ret = regmap_read(regmap, LOCHNAGAR2_GPIO_CHANNEL1 + i, &val);
80462306a36Sopenharmony_ci		if (ret)
80562306a36Sopenharmony_ci			return ret;
80662306a36Sopenharmony_ci
80762306a36Sopenharmony_ci		val &= LOCHNAGAR2_GPIO_CHANNEL_SRC_MASK;
80862306a36Sopenharmony_ci
80962306a36Sopenharmony_ci		if (val == op)
81062306a36Sopenharmony_ci			return i + 1;
81162306a36Sopenharmony_ci
81262306a36Sopenharmony_ci		if (free < 0 && !val)
81362306a36Sopenharmony_ci			free = i;
81462306a36Sopenharmony_ci	}
81562306a36Sopenharmony_ci
81662306a36Sopenharmony_ci	if (free >= 0) {
81762306a36Sopenharmony_ci		ret = regmap_update_bits(regmap,
81862306a36Sopenharmony_ci					 LOCHNAGAR2_GPIO_CHANNEL1 + free,
81962306a36Sopenharmony_ci					 LOCHNAGAR2_GPIO_CHANNEL_SRC_MASK, op);
82062306a36Sopenharmony_ci		if (ret)
82162306a36Sopenharmony_ci			return ret;
82262306a36Sopenharmony_ci
82362306a36Sopenharmony_ci		free++;
82462306a36Sopenharmony_ci
82562306a36Sopenharmony_ci		dev_dbg(priv->dev, "Set channel %d to 0x%x\n", free, op);
82662306a36Sopenharmony_ci
82762306a36Sopenharmony_ci		return free;
82862306a36Sopenharmony_ci	}
82962306a36Sopenharmony_ci
83062306a36Sopenharmony_ci	return -ENOSPC;
83162306a36Sopenharmony_ci}
83262306a36Sopenharmony_ci
83362306a36Sopenharmony_cistatic int lochnagar_pin_set_mux(struct lochnagar_pin_priv *priv,
83462306a36Sopenharmony_ci				 const struct lochnagar_pin *pin,
83562306a36Sopenharmony_ci				 unsigned int op)
83662306a36Sopenharmony_ci{
83762306a36Sopenharmony_ci	int ret;
83862306a36Sopenharmony_ci
83962306a36Sopenharmony_ci	switch (priv->lochnagar->type) {
84062306a36Sopenharmony_ci	case LOCHNAGAR1:
84162306a36Sopenharmony_ci		break;
84262306a36Sopenharmony_ci	default:
84362306a36Sopenharmony_ci		ret = lochnagar2_get_gpio_chan(priv, op);
84462306a36Sopenharmony_ci		if (ret < 0) {
84562306a36Sopenharmony_ci			dev_err(priv->dev, "Failed to get channel for %s: %d\n",
84662306a36Sopenharmony_ci				pin->name, ret);
84762306a36Sopenharmony_ci			return ret;
84862306a36Sopenharmony_ci		}
84962306a36Sopenharmony_ci
85062306a36Sopenharmony_ci		op = ret;
85162306a36Sopenharmony_ci		break;
85262306a36Sopenharmony_ci	}
85362306a36Sopenharmony_ci
85462306a36Sopenharmony_ci	dev_dbg(priv->dev, "Set pin %s to 0x%x\n", pin->name, op);
85562306a36Sopenharmony_ci
85662306a36Sopenharmony_ci	ret = regmap_write(priv->lochnagar->regmap, pin->reg, op);
85762306a36Sopenharmony_ci	if (ret)
85862306a36Sopenharmony_ci		dev_err(priv->dev, "Failed to set %s mux: %d\n",
85962306a36Sopenharmony_ci			pin->name, ret);
86062306a36Sopenharmony_ci
86162306a36Sopenharmony_ci	return 0;
86262306a36Sopenharmony_ci}
86362306a36Sopenharmony_ci
86462306a36Sopenharmony_cistatic int lochnagar_aif_set_mux(struct lochnagar_pin_priv *priv,
86562306a36Sopenharmony_ci				 const struct lochnagar_group *group,
86662306a36Sopenharmony_ci				 unsigned int op)
86762306a36Sopenharmony_ci{
86862306a36Sopenharmony_ci	struct regmap *regmap = priv->lochnagar->regmap;
86962306a36Sopenharmony_ci	const struct lochnagar_aif *aif = group->priv;
87062306a36Sopenharmony_ci	const struct lochnagar_pin *pin;
87162306a36Sopenharmony_ci	int i, ret;
87262306a36Sopenharmony_ci
87362306a36Sopenharmony_ci	ret = regmap_update_bits(regmap, aif->src_reg, aif->src_mask, op);
87462306a36Sopenharmony_ci	if (ret) {
87562306a36Sopenharmony_ci		dev_err(priv->dev, "Failed to set %s source: %d\n",
87662306a36Sopenharmony_ci			group->name, ret);
87762306a36Sopenharmony_ci		return ret;
87862306a36Sopenharmony_ci	}
87962306a36Sopenharmony_ci
88062306a36Sopenharmony_ci	ret = regmap_update_bits(regmap, aif->ctrl_reg,
88162306a36Sopenharmony_ci				 aif->ena_mask, aif->ena_mask);
88262306a36Sopenharmony_ci	if (ret) {
88362306a36Sopenharmony_ci		dev_err(priv->dev, "Failed to set %s enable: %d\n",
88462306a36Sopenharmony_ci			group->name, ret);
88562306a36Sopenharmony_ci		return ret;
88662306a36Sopenharmony_ci	}
88762306a36Sopenharmony_ci
88862306a36Sopenharmony_ci	for (i = 0; i < group->npins; i++) {
88962306a36Sopenharmony_ci		pin = priv->pins[group->pins[i]].drv_data;
89062306a36Sopenharmony_ci
89162306a36Sopenharmony_ci		if (pin->type != LN_PTYPE_MUX)
89262306a36Sopenharmony_ci			continue;
89362306a36Sopenharmony_ci
89462306a36Sopenharmony_ci		dev_dbg(priv->dev, "Set pin %s to AIF\n", pin->name);
89562306a36Sopenharmony_ci
89662306a36Sopenharmony_ci		ret = regmap_update_bits(regmap, pin->reg,
89762306a36Sopenharmony_ci					 LOCHNAGAR2_GPIO_SRC_MASK,
89862306a36Sopenharmony_ci					 LN2_OP_AIF);
89962306a36Sopenharmony_ci		if (ret) {
90062306a36Sopenharmony_ci			dev_err(priv->dev, "Failed to set %s to AIF: %d\n",
90162306a36Sopenharmony_ci				pin->name, ret);
90262306a36Sopenharmony_ci			return ret;
90362306a36Sopenharmony_ci		}
90462306a36Sopenharmony_ci	}
90562306a36Sopenharmony_ci
90662306a36Sopenharmony_ci	return 0;
90762306a36Sopenharmony_ci}
90862306a36Sopenharmony_ci
90962306a36Sopenharmony_cistatic int lochnagar_set_mux(struct pinctrl_dev *pctldev,
91062306a36Sopenharmony_ci			     unsigned int func_idx, unsigned int group_idx)
91162306a36Sopenharmony_ci{
91262306a36Sopenharmony_ci	struct lochnagar_pin_priv *priv = pinctrl_dev_get_drvdata(pctldev);
91362306a36Sopenharmony_ci	const struct lochnagar_func *func = &priv->funcs[func_idx];
91462306a36Sopenharmony_ci	const struct lochnagar_group *group = &priv->groups[group_idx];
91562306a36Sopenharmony_ci	const struct lochnagar_pin *pin;
91662306a36Sopenharmony_ci
91762306a36Sopenharmony_ci	switch (func->type) {
91862306a36Sopenharmony_ci	case LN_FTYPE_AIF:
91962306a36Sopenharmony_ci		dev_dbg(priv->dev, "Set group %s to %s\n",
92062306a36Sopenharmony_ci			group->name, func->name);
92162306a36Sopenharmony_ci
92262306a36Sopenharmony_ci		return lochnagar_aif_set_mux(priv, group, func->op);
92362306a36Sopenharmony_ci	case LN_FTYPE_PIN:
92462306a36Sopenharmony_ci		pin = priv->pins[*group->pins].drv_data;
92562306a36Sopenharmony_ci
92662306a36Sopenharmony_ci		dev_dbg(priv->dev, "Set pin %s to %s\n", pin->name, func->name);
92762306a36Sopenharmony_ci
92862306a36Sopenharmony_ci		return lochnagar_pin_set_mux(priv, pin, func->op);
92962306a36Sopenharmony_ci	default:
93062306a36Sopenharmony_ci		return -EINVAL;
93162306a36Sopenharmony_ci	}
93262306a36Sopenharmony_ci}
93362306a36Sopenharmony_ci
93462306a36Sopenharmony_cistatic int lochnagar_gpio_request(struct pinctrl_dev *pctldev,
93562306a36Sopenharmony_ci				  struct pinctrl_gpio_range *range,
93662306a36Sopenharmony_ci				  unsigned int offset)
93762306a36Sopenharmony_ci{
93862306a36Sopenharmony_ci	struct lochnagar_pin_priv *priv = pinctrl_dev_get_drvdata(pctldev);
93962306a36Sopenharmony_ci	struct lochnagar *lochnagar = priv->lochnagar;
94062306a36Sopenharmony_ci	const struct lochnagar_pin *pin = priv->pins[offset].drv_data;
94162306a36Sopenharmony_ci	int ret;
94262306a36Sopenharmony_ci
94362306a36Sopenharmony_ci	dev_dbg(priv->dev, "Requesting GPIO %s\n", pin->name);
94462306a36Sopenharmony_ci
94562306a36Sopenharmony_ci	if (lochnagar->type == LOCHNAGAR1 || pin->type != LN_PTYPE_MUX)
94662306a36Sopenharmony_ci		return 0;
94762306a36Sopenharmony_ci
94862306a36Sopenharmony_ci	ret = lochnagar2_get_gpio_chan(priv, LN2_OP_GPIO);
94962306a36Sopenharmony_ci	if (ret < 0) {
95062306a36Sopenharmony_ci		dev_err(priv->dev, "Failed to get low channel: %d\n", ret);
95162306a36Sopenharmony_ci		return ret;
95262306a36Sopenharmony_ci	}
95362306a36Sopenharmony_ci
95462306a36Sopenharmony_ci	ret = lochnagar2_get_gpio_chan(priv, LN2_OP_GPIO | 0x1);
95562306a36Sopenharmony_ci	if (ret < 0) {
95662306a36Sopenharmony_ci		dev_err(priv->dev, "Failed to get high channel: %d\n", ret);
95762306a36Sopenharmony_ci		return ret;
95862306a36Sopenharmony_ci	}
95962306a36Sopenharmony_ci
96062306a36Sopenharmony_ci	return 0;
96162306a36Sopenharmony_ci}
96262306a36Sopenharmony_ci
96362306a36Sopenharmony_cistatic int lochnagar_gpio_set_direction(struct pinctrl_dev *pctldev,
96462306a36Sopenharmony_ci					struct pinctrl_gpio_range *range,
96562306a36Sopenharmony_ci					unsigned int offset,
96662306a36Sopenharmony_ci					bool input)
96762306a36Sopenharmony_ci{
96862306a36Sopenharmony_ci	/* The GPIOs only support output */
96962306a36Sopenharmony_ci	if (input)
97062306a36Sopenharmony_ci		return -EINVAL;
97162306a36Sopenharmony_ci
97262306a36Sopenharmony_ci	return 0;
97362306a36Sopenharmony_ci}
97462306a36Sopenharmony_ci
97562306a36Sopenharmony_cistatic const struct pinmux_ops lochnagar_pin_mux_ops = {
97662306a36Sopenharmony_ci	.get_functions_count = lochnagar_get_funcs_count,
97762306a36Sopenharmony_ci	.get_function_name = lochnagar_get_func_name,
97862306a36Sopenharmony_ci	.get_function_groups = lochnagar_get_func_groups,
97962306a36Sopenharmony_ci	.set_mux = lochnagar_set_mux,
98062306a36Sopenharmony_ci
98162306a36Sopenharmony_ci	.gpio_request_enable = lochnagar_gpio_request,
98262306a36Sopenharmony_ci	.gpio_set_direction = lochnagar_gpio_set_direction,
98362306a36Sopenharmony_ci
98462306a36Sopenharmony_ci	.strict = true,
98562306a36Sopenharmony_ci};
98662306a36Sopenharmony_ci
98762306a36Sopenharmony_cistatic int lochnagar_aif_set_master(struct lochnagar_pin_priv *priv,
98862306a36Sopenharmony_ci				    unsigned int group_idx, bool master)
98962306a36Sopenharmony_ci{
99062306a36Sopenharmony_ci	struct regmap *regmap = priv->lochnagar->regmap;
99162306a36Sopenharmony_ci	const struct lochnagar_group *group = &priv->groups[group_idx];
99262306a36Sopenharmony_ci	const struct lochnagar_aif *aif = group->priv;
99362306a36Sopenharmony_ci	unsigned int val = 0;
99462306a36Sopenharmony_ci	int ret;
99562306a36Sopenharmony_ci
99662306a36Sopenharmony_ci	if (group->type != LN_FTYPE_AIF)
99762306a36Sopenharmony_ci		return -EINVAL;
99862306a36Sopenharmony_ci
99962306a36Sopenharmony_ci	if (!master)
100062306a36Sopenharmony_ci		val = aif->master_mask;
100162306a36Sopenharmony_ci
100262306a36Sopenharmony_ci	dev_dbg(priv->dev, "Set AIF %s to %s\n",
100362306a36Sopenharmony_ci		group->name, master ? "master" : "slave");
100462306a36Sopenharmony_ci
100562306a36Sopenharmony_ci	ret = regmap_update_bits(regmap, aif->ctrl_reg, aif->master_mask, val);
100662306a36Sopenharmony_ci	if (ret) {
100762306a36Sopenharmony_ci		dev_err(priv->dev, "Failed to set %s mode: %d\n",
100862306a36Sopenharmony_ci			group->name, ret);
100962306a36Sopenharmony_ci		return ret;
101062306a36Sopenharmony_ci	}
101162306a36Sopenharmony_ci
101262306a36Sopenharmony_ci	return 0;
101362306a36Sopenharmony_ci}
101462306a36Sopenharmony_ci
101562306a36Sopenharmony_cistatic int lochnagar_conf_group_set(struct pinctrl_dev *pctldev,
101662306a36Sopenharmony_ci				    unsigned int group_idx,
101762306a36Sopenharmony_ci				    unsigned long *configs,
101862306a36Sopenharmony_ci				    unsigned int num_configs)
101962306a36Sopenharmony_ci{
102062306a36Sopenharmony_ci	struct lochnagar_pin_priv *priv = pinctrl_dev_get_drvdata(pctldev);
102162306a36Sopenharmony_ci	int i, ret;
102262306a36Sopenharmony_ci
102362306a36Sopenharmony_ci	for (i = 0; i < num_configs; i++) {
102462306a36Sopenharmony_ci		unsigned int param = pinconf_to_config_param(*configs);
102562306a36Sopenharmony_ci
102662306a36Sopenharmony_ci		switch (param) {
102762306a36Sopenharmony_ci		case PIN_CONFIG_OUTPUT_ENABLE:
102862306a36Sopenharmony_ci			ret = lochnagar_aif_set_master(priv, group_idx, true);
102962306a36Sopenharmony_ci			if (ret)
103062306a36Sopenharmony_ci				return ret;
103162306a36Sopenharmony_ci			break;
103262306a36Sopenharmony_ci		case PIN_CONFIG_INPUT_ENABLE:
103362306a36Sopenharmony_ci			ret = lochnagar_aif_set_master(priv, group_idx, false);
103462306a36Sopenharmony_ci			if (ret)
103562306a36Sopenharmony_ci				return ret;
103662306a36Sopenharmony_ci			break;
103762306a36Sopenharmony_ci		default:
103862306a36Sopenharmony_ci			return -ENOTSUPP;
103962306a36Sopenharmony_ci		}
104062306a36Sopenharmony_ci
104162306a36Sopenharmony_ci		configs++;
104262306a36Sopenharmony_ci	}
104362306a36Sopenharmony_ci
104462306a36Sopenharmony_ci	return 0;
104562306a36Sopenharmony_ci}
104662306a36Sopenharmony_ci
104762306a36Sopenharmony_cistatic const struct pinconf_ops lochnagar_pin_conf_ops = {
104862306a36Sopenharmony_ci	.pin_config_group_set = lochnagar_conf_group_set,
104962306a36Sopenharmony_ci};
105062306a36Sopenharmony_ci
105162306a36Sopenharmony_cistatic const struct pinctrl_desc lochnagar_pin_desc = {
105262306a36Sopenharmony_ci	.name = "lochnagar-pinctrl",
105362306a36Sopenharmony_ci	.owner = THIS_MODULE,
105462306a36Sopenharmony_ci
105562306a36Sopenharmony_ci	.pctlops = &lochnagar_pin_group_ops,
105662306a36Sopenharmony_ci	.pmxops = &lochnagar_pin_mux_ops,
105762306a36Sopenharmony_ci	.confops = &lochnagar_pin_conf_ops,
105862306a36Sopenharmony_ci};
105962306a36Sopenharmony_ci
106062306a36Sopenharmony_cistatic void lochnagar_gpio_set(struct gpio_chip *chip,
106162306a36Sopenharmony_ci			       unsigned int offset, int value)
106262306a36Sopenharmony_ci{
106362306a36Sopenharmony_ci	struct lochnagar_pin_priv *priv = gpiochip_get_data(chip);
106462306a36Sopenharmony_ci	struct lochnagar *lochnagar = priv->lochnagar;
106562306a36Sopenharmony_ci	const struct lochnagar_pin *pin = priv->pins[offset].drv_data;
106662306a36Sopenharmony_ci	int ret;
106762306a36Sopenharmony_ci
106862306a36Sopenharmony_ci	value = !!value;
106962306a36Sopenharmony_ci
107062306a36Sopenharmony_ci	dev_dbg(priv->dev, "Set GPIO %s to %s\n",
107162306a36Sopenharmony_ci		pin->name, value ? "high" : "low");
107262306a36Sopenharmony_ci
107362306a36Sopenharmony_ci	switch (pin->type) {
107462306a36Sopenharmony_ci	case LN_PTYPE_MUX:
107562306a36Sopenharmony_ci		value |= LN2_OP_GPIO;
107662306a36Sopenharmony_ci
107762306a36Sopenharmony_ci		ret = lochnagar_pin_set_mux(priv, pin, value);
107862306a36Sopenharmony_ci		break;
107962306a36Sopenharmony_ci	case LN_PTYPE_GPIO:
108062306a36Sopenharmony_ci		if (pin->invert)
108162306a36Sopenharmony_ci			value = !value;
108262306a36Sopenharmony_ci
108362306a36Sopenharmony_ci		ret = regmap_update_bits(lochnagar->regmap, pin->reg,
108462306a36Sopenharmony_ci					 BIT(pin->shift), value << pin->shift);
108562306a36Sopenharmony_ci		break;
108662306a36Sopenharmony_ci	default:
108762306a36Sopenharmony_ci		ret = -EINVAL;
108862306a36Sopenharmony_ci		break;
108962306a36Sopenharmony_ci	}
109062306a36Sopenharmony_ci
109162306a36Sopenharmony_ci	if (ret < 0)
109262306a36Sopenharmony_ci		dev_err(chip->parent, "Failed to set %s value: %d\n",
109362306a36Sopenharmony_ci			pin->name, ret);
109462306a36Sopenharmony_ci}
109562306a36Sopenharmony_ci
109662306a36Sopenharmony_cistatic int lochnagar_gpio_direction_out(struct gpio_chip *chip,
109762306a36Sopenharmony_ci					unsigned int offset, int value)
109862306a36Sopenharmony_ci{
109962306a36Sopenharmony_ci	lochnagar_gpio_set(chip, offset, value);
110062306a36Sopenharmony_ci
110162306a36Sopenharmony_ci	return pinctrl_gpio_direction_output(chip->base + offset);
110262306a36Sopenharmony_ci}
110362306a36Sopenharmony_ci
110462306a36Sopenharmony_cistatic int lochnagar_fill_func_groups(struct lochnagar_pin_priv *priv)
110562306a36Sopenharmony_ci{
110662306a36Sopenharmony_ci	struct lochnagar_func_groups *funcs;
110762306a36Sopenharmony_ci	int i;
110862306a36Sopenharmony_ci
110962306a36Sopenharmony_ci	for (i = 0; i < priv->ngroups; i++)
111062306a36Sopenharmony_ci		priv->func_groups[priv->groups[i].type].ngroups++;
111162306a36Sopenharmony_ci
111262306a36Sopenharmony_ci	for (i = 0; i < LN_FTYPE_COUNT; i++) {
111362306a36Sopenharmony_ci		funcs = &priv->func_groups[i];
111462306a36Sopenharmony_ci
111562306a36Sopenharmony_ci		if (!funcs->ngroups)
111662306a36Sopenharmony_ci			continue;
111762306a36Sopenharmony_ci
111862306a36Sopenharmony_ci		funcs->groups = devm_kcalloc(priv->dev, funcs->ngroups,
111962306a36Sopenharmony_ci					     sizeof(*funcs->groups),
112062306a36Sopenharmony_ci					     GFP_KERNEL);
112162306a36Sopenharmony_ci		if (!funcs->groups)
112262306a36Sopenharmony_ci			return -ENOMEM;
112362306a36Sopenharmony_ci
112462306a36Sopenharmony_ci		funcs->ngroups = 0;
112562306a36Sopenharmony_ci	}
112662306a36Sopenharmony_ci
112762306a36Sopenharmony_ci	for (i = 0; i < priv->ngroups; i++) {
112862306a36Sopenharmony_ci		funcs = &priv->func_groups[priv->groups[i].type];
112962306a36Sopenharmony_ci
113062306a36Sopenharmony_ci		funcs->groups[funcs->ngroups++] = priv->groups[i].name;
113162306a36Sopenharmony_ci	}
113262306a36Sopenharmony_ci
113362306a36Sopenharmony_ci	return 0;
113462306a36Sopenharmony_ci}
113562306a36Sopenharmony_ci
113662306a36Sopenharmony_cistatic int lochnagar_pin_probe(struct platform_device *pdev)
113762306a36Sopenharmony_ci{
113862306a36Sopenharmony_ci	struct lochnagar *lochnagar = dev_get_drvdata(pdev->dev.parent);
113962306a36Sopenharmony_ci	struct lochnagar_pin_priv *priv;
114062306a36Sopenharmony_ci	struct pinctrl_desc *desc;
114162306a36Sopenharmony_ci	struct pinctrl_dev *pctl;
114262306a36Sopenharmony_ci	struct device *dev = &pdev->dev;
114362306a36Sopenharmony_ci	int ret;
114462306a36Sopenharmony_ci
114562306a36Sopenharmony_ci	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
114662306a36Sopenharmony_ci	if (!priv)
114762306a36Sopenharmony_ci		return -ENOMEM;
114862306a36Sopenharmony_ci
114962306a36Sopenharmony_ci	priv->dev = dev;
115062306a36Sopenharmony_ci	priv->lochnagar = lochnagar;
115162306a36Sopenharmony_ci
115262306a36Sopenharmony_ci	desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL);
115362306a36Sopenharmony_ci	if (!desc)
115462306a36Sopenharmony_ci		return -ENOMEM;
115562306a36Sopenharmony_ci
115662306a36Sopenharmony_ci	*desc = lochnagar_pin_desc;
115762306a36Sopenharmony_ci
115862306a36Sopenharmony_ci	priv->gpio_chip.label = dev_name(dev);
115962306a36Sopenharmony_ci	priv->gpio_chip.request = gpiochip_generic_request;
116062306a36Sopenharmony_ci	priv->gpio_chip.free = gpiochip_generic_free;
116162306a36Sopenharmony_ci	priv->gpio_chip.direction_output = lochnagar_gpio_direction_out;
116262306a36Sopenharmony_ci	priv->gpio_chip.set = lochnagar_gpio_set;
116362306a36Sopenharmony_ci	priv->gpio_chip.can_sleep = true;
116462306a36Sopenharmony_ci	priv->gpio_chip.parent = dev;
116562306a36Sopenharmony_ci	priv->gpio_chip.base = -1;
116662306a36Sopenharmony_ci
116762306a36Sopenharmony_ci	switch (lochnagar->type) {
116862306a36Sopenharmony_ci	case LOCHNAGAR1:
116962306a36Sopenharmony_ci		priv->funcs = lochnagar1_funcs;
117062306a36Sopenharmony_ci		priv->nfuncs = ARRAY_SIZE(lochnagar1_funcs);
117162306a36Sopenharmony_ci		priv->pins = lochnagar1_pins;
117262306a36Sopenharmony_ci		priv->npins = ARRAY_SIZE(lochnagar1_pins);
117362306a36Sopenharmony_ci		priv->groups = lochnagar1_groups;
117462306a36Sopenharmony_ci		priv->ngroups = ARRAY_SIZE(lochnagar1_groups);
117562306a36Sopenharmony_ci
117662306a36Sopenharmony_ci		priv->gpio_chip.ngpio = LOCHNAGAR1_PIN_NUM_GPIOS;
117762306a36Sopenharmony_ci		break;
117862306a36Sopenharmony_ci	case LOCHNAGAR2:
117962306a36Sopenharmony_ci		priv->funcs = lochnagar2_funcs;
118062306a36Sopenharmony_ci		priv->nfuncs = ARRAY_SIZE(lochnagar2_funcs);
118162306a36Sopenharmony_ci		priv->pins = lochnagar2_pins;
118262306a36Sopenharmony_ci		priv->npins = ARRAY_SIZE(lochnagar2_pins);
118362306a36Sopenharmony_ci		priv->groups = lochnagar2_groups;
118462306a36Sopenharmony_ci		priv->ngroups = ARRAY_SIZE(lochnagar2_groups);
118562306a36Sopenharmony_ci
118662306a36Sopenharmony_ci		priv->gpio_chip.ngpio = LOCHNAGAR2_PIN_NUM_GPIOS;
118762306a36Sopenharmony_ci		break;
118862306a36Sopenharmony_ci	default:
118962306a36Sopenharmony_ci		dev_err(dev, "Unknown Lochnagar type: %d\n", lochnagar->type);
119062306a36Sopenharmony_ci		return -EINVAL;
119162306a36Sopenharmony_ci	}
119262306a36Sopenharmony_ci
119362306a36Sopenharmony_ci	ret = lochnagar_fill_func_groups(priv);
119462306a36Sopenharmony_ci	if (ret < 0)
119562306a36Sopenharmony_ci		return ret;
119662306a36Sopenharmony_ci
119762306a36Sopenharmony_ci	desc->pins = priv->pins;
119862306a36Sopenharmony_ci	desc->npins = priv->npins;
119962306a36Sopenharmony_ci
120062306a36Sopenharmony_ci	pctl = devm_pinctrl_register(dev, desc, priv);
120162306a36Sopenharmony_ci	if (IS_ERR(pctl)) {
120262306a36Sopenharmony_ci		ret = PTR_ERR(pctl);
120362306a36Sopenharmony_ci		dev_err(priv->dev, "Failed to register pinctrl: %d\n", ret);
120462306a36Sopenharmony_ci		return ret;
120562306a36Sopenharmony_ci	}
120662306a36Sopenharmony_ci
120762306a36Sopenharmony_ci	ret = devm_gpiochip_add_data(dev, &priv->gpio_chip, priv);
120862306a36Sopenharmony_ci	if (ret < 0) {
120962306a36Sopenharmony_ci		dev_err(&pdev->dev, "Failed to register gpiochip: %d\n", ret);
121062306a36Sopenharmony_ci		return ret;
121162306a36Sopenharmony_ci	}
121262306a36Sopenharmony_ci
121362306a36Sopenharmony_ci	return 0;
121462306a36Sopenharmony_ci}
121562306a36Sopenharmony_ci
121662306a36Sopenharmony_cistatic const struct of_device_id lochnagar_of_match[] = {
121762306a36Sopenharmony_ci	{ .compatible = "cirrus,lochnagar-pinctrl" },
121862306a36Sopenharmony_ci	{}
121962306a36Sopenharmony_ci};
122062306a36Sopenharmony_ciMODULE_DEVICE_TABLE(of, lochnagar_of_match);
122162306a36Sopenharmony_ci
122262306a36Sopenharmony_cistatic struct platform_driver lochnagar_pin_driver = {
122362306a36Sopenharmony_ci	.driver = {
122462306a36Sopenharmony_ci		.name = "lochnagar-pinctrl",
122562306a36Sopenharmony_ci		.of_match_table = of_match_ptr(lochnagar_of_match),
122662306a36Sopenharmony_ci	},
122762306a36Sopenharmony_ci
122862306a36Sopenharmony_ci	.probe = lochnagar_pin_probe,
122962306a36Sopenharmony_ci};
123062306a36Sopenharmony_cimodule_platform_driver(lochnagar_pin_driver);
123162306a36Sopenharmony_ci
123262306a36Sopenharmony_ciMODULE_AUTHOR("Charles Keepax <ckeepax@opensource.cirrus.com>");
123362306a36Sopenharmony_ciMODULE_DESCRIPTION("Pinctrl driver for Cirrus Logic Lochnagar Board");
123462306a36Sopenharmony_ciMODULE_LICENSE("GPL v2");
1235