162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Driver for the NXP ISP1760 chip
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright 2021 Linaro, Rui Miguel Silva
662306a36Sopenharmony_ci * Copyright 2014 Laurent Pinchart
762306a36Sopenharmony_ci * Copyright 2007 Sebastian Siewior
862306a36Sopenharmony_ci *
962306a36Sopenharmony_ci * Contacts:
1062306a36Sopenharmony_ci *	Sebastian Siewior <bigeasy@linutronix.de>
1162306a36Sopenharmony_ci *	Laurent Pinchart <laurent.pinchart@ideasonboard.com>
1262306a36Sopenharmony_ci *	Rui Miguel Silva <rui.silva@linaro.org>
1362306a36Sopenharmony_ci */
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci#include <linux/delay.h>
1662306a36Sopenharmony_ci#include <linux/gpio/consumer.h>
1762306a36Sopenharmony_ci#include <linux/io.h>
1862306a36Sopenharmony_ci#include <linux/kernel.h>
1962306a36Sopenharmony_ci#include <linux/module.h>
2062306a36Sopenharmony_ci#include <linux/regmap.h>
2162306a36Sopenharmony_ci#include <linux/slab.h>
2262306a36Sopenharmony_ci#include <linux/usb.h>
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ci#include "isp1760-core.h"
2562306a36Sopenharmony_ci#include "isp1760-hcd.h"
2662306a36Sopenharmony_ci#include "isp1760-regs.h"
2762306a36Sopenharmony_ci#include "isp1760-udc.h"
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_cistatic int isp1760_init_core(struct isp1760_device *isp)
3062306a36Sopenharmony_ci{
3162306a36Sopenharmony_ci	struct isp1760_hcd *hcd = &isp->hcd;
3262306a36Sopenharmony_ci	struct isp1760_udc *udc = &isp->udc;
3362306a36Sopenharmony_ci	u32 otg_ctrl;
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_ci	/* Low-level chip reset */
3662306a36Sopenharmony_ci	if (isp->rst_gpio) {
3762306a36Sopenharmony_ci		gpiod_set_value_cansleep(isp->rst_gpio, 1);
3862306a36Sopenharmony_ci		msleep(50);
3962306a36Sopenharmony_ci		gpiod_set_value_cansleep(isp->rst_gpio, 0);
4062306a36Sopenharmony_ci	}
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_ci	/*
4362306a36Sopenharmony_ci	 * Reset the host controller, including the CPU interface
4462306a36Sopenharmony_ci	 * configuration.
4562306a36Sopenharmony_ci	 */
4662306a36Sopenharmony_ci	isp1760_field_set(hcd->fields, SW_RESET_RESET_ALL);
4762306a36Sopenharmony_ci	msleep(100);
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ci	/* Setup HW Mode Control: This assumes a level active-low interrupt */
5062306a36Sopenharmony_ci	if ((isp->devflags & ISP1760_FLAG_ANALOG_OC) && hcd->is_isp1763) {
5162306a36Sopenharmony_ci		dev_err(isp->dev, "isp1763 analog overcurrent not available\n");
5262306a36Sopenharmony_ci		return -EINVAL;
5362306a36Sopenharmony_ci	}
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ci	if (isp->devflags & ISP1760_FLAG_BUS_WIDTH_16)
5662306a36Sopenharmony_ci		isp1760_field_clear(hcd->fields, HW_DATA_BUS_WIDTH);
5762306a36Sopenharmony_ci	if (isp->devflags & ISP1760_FLAG_BUS_WIDTH_8)
5862306a36Sopenharmony_ci		isp1760_field_set(hcd->fields, HW_DATA_BUS_WIDTH);
5962306a36Sopenharmony_ci	if (isp->devflags & ISP1760_FLAG_ANALOG_OC)
6062306a36Sopenharmony_ci		isp1760_field_set(hcd->fields, HW_ANA_DIGI_OC);
6162306a36Sopenharmony_ci	if (isp->devflags & ISP1760_FLAG_DACK_POL_HIGH)
6262306a36Sopenharmony_ci		isp1760_field_set(hcd->fields, HW_DACK_POL_HIGH);
6362306a36Sopenharmony_ci	if (isp->devflags & ISP1760_FLAG_DREQ_POL_HIGH)
6462306a36Sopenharmony_ci		isp1760_field_set(hcd->fields, HW_DREQ_POL_HIGH);
6562306a36Sopenharmony_ci	if (isp->devflags & ISP1760_FLAG_INTR_POL_HIGH)
6662306a36Sopenharmony_ci		isp1760_field_set(hcd->fields, HW_INTR_HIGH_ACT);
6762306a36Sopenharmony_ci	if (isp->devflags & ISP1760_FLAG_INTR_EDGE_TRIG)
6862306a36Sopenharmony_ci		isp1760_field_set(hcd->fields, HW_INTR_EDGE_TRIG);
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_ci	/*
7162306a36Sopenharmony_ci	 * The ISP1761 has a dedicated DC IRQ line but supports sharing the HC
7262306a36Sopenharmony_ci	 * IRQ line for both the host and device controllers. Hardcode IRQ
7362306a36Sopenharmony_ci	 * sharing for now and disable the DC interrupts globally to avoid
7462306a36Sopenharmony_ci	 * spurious interrupts during HCD registration.
7562306a36Sopenharmony_ci	 */
7662306a36Sopenharmony_ci	if (isp->devflags & ISP1760_FLAG_ISP1761) {
7762306a36Sopenharmony_ci		isp1760_reg_write(udc->regs, ISP176x_DC_MODE, 0);
7862306a36Sopenharmony_ci		isp1760_field_set(hcd->fields, HW_COMN_IRQ);
7962306a36Sopenharmony_ci	}
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_ci	/*
8262306a36Sopenharmony_ci	 * PORT 1 Control register of the ISP1760 is the OTG control register
8362306a36Sopenharmony_ci	 * on ISP1761.
8462306a36Sopenharmony_ci	 *
8562306a36Sopenharmony_ci	 * TODO: Really support OTG. For now we configure port 1 in device mode
8662306a36Sopenharmony_ci	 */
8762306a36Sopenharmony_ci	if (isp->devflags & ISP1760_FLAG_ISP1761) {
8862306a36Sopenharmony_ci		if (isp->devflags & ISP1760_FLAG_PERIPHERAL_EN) {
8962306a36Sopenharmony_ci			otg_ctrl = (ISP176x_HW_DM_PULLDOWN_CLEAR |
9062306a36Sopenharmony_ci				    ISP176x_HW_DP_PULLDOWN_CLEAR |
9162306a36Sopenharmony_ci				    ISP176x_HW_OTG_DISABLE);
9262306a36Sopenharmony_ci		} else {
9362306a36Sopenharmony_ci			otg_ctrl = (ISP176x_HW_SW_SEL_HC_DC_CLEAR |
9462306a36Sopenharmony_ci				    ISP176x_HW_VBUS_DRV |
9562306a36Sopenharmony_ci				    ISP176x_HW_SEL_CP_EXT);
9662306a36Sopenharmony_ci		}
9762306a36Sopenharmony_ci		isp1760_reg_write(hcd->regs, ISP176x_HC_OTG_CTRL, otg_ctrl);
9862306a36Sopenharmony_ci	}
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_ci	dev_info(isp->dev, "%s bus width: %u, oc: %s\n",
10162306a36Sopenharmony_ci		 hcd->is_isp1763 ? "isp1763" : "isp1760",
10262306a36Sopenharmony_ci		 isp->devflags & ISP1760_FLAG_BUS_WIDTH_8 ? 8 :
10362306a36Sopenharmony_ci		 isp->devflags & ISP1760_FLAG_BUS_WIDTH_16 ? 16 : 32,
10462306a36Sopenharmony_ci		 hcd->is_isp1763 ? "not available" :
10562306a36Sopenharmony_ci		 isp->devflags & ISP1760_FLAG_ANALOG_OC ? "analog" : "digital");
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_ci	return 0;
10862306a36Sopenharmony_ci}
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_civoid isp1760_set_pullup(struct isp1760_device *isp, bool enable)
11162306a36Sopenharmony_ci{
11262306a36Sopenharmony_ci	struct isp1760_udc *udc = &isp->udc;
11362306a36Sopenharmony_ci
11462306a36Sopenharmony_ci	if (enable)
11562306a36Sopenharmony_ci		isp1760_field_set(udc->fields, HW_DP_PULLUP);
11662306a36Sopenharmony_ci	else
11762306a36Sopenharmony_ci		isp1760_field_set(udc->fields, HW_DP_PULLUP_CLEAR);
11862306a36Sopenharmony_ci}
11962306a36Sopenharmony_ci
12062306a36Sopenharmony_ci/*
12162306a36Sopenharmony_ci * ISP1760/61:
12262306a36Sopenharmony_ci *
12362306a36Sopenharmony_ci * 60kb divided in:
12462306a36Sopenharmony_ci * - 32 blocks @ 256  bytes
12562306a36Sopenharmony_ci * - 20 blocks @ 1024 bytes
12662306a36Sopenharmony_ci * -  4 blocks @ 8192 bytes
12762306a36Sopenharmony_ci */
12862306a36Sopenharmony_cistatic const struct isp1760_memory_layout isp176x_memory_conf = {
12962306a36Sopenharmony_ci	.blocks[0]		= 32,
13062306a36Sopenharmony_ci	.blocks_size[0]		= 256,
13162306a36Sopenharmony_ci	.blocks[1]		= 20,
13262306a36Sopenharmony_ci	.blocks_size[1]		= 1024,
13362306a36Sopenharmony_ci	.blocks[2]		= 4,
13462306a36Sopenharmony_ci	.blocks_size[2]		= 8192,
13562306a36Sopenharmony_ci
13662306a36Sopenharmony_ci	.slot_num		= 32,
13762306a36Sopenharmony_ci	.payload_blocks		= 32 + 20 + 4,
13862306a36Sopenharmony_ci	.payload_area_size	= 0xf000,
13962306a36Sopenharmony_ci};
14062306a36Sopenharmony_ci
14162306a36Sopenharmony_ci/*
14262306a36Sopenharmony_ci * ISP1763:
14362306a36Sopenharmony_ci *
14462306a36Sopenharmony_ci * 20kb divided in:
14562306a36Sopenharmony_ci * - 8 blocks @ 256  bytes
14662306a36Sopenharmony_ci * - 2 blocks @ 1024 bytes
14762306a36Sopenharmony_ci * - 4 blocks @ 4096 bytes
14862306a36Sopenharmony_ci */
14962306a36Sopenharmony_cistatic const struct isp1760_memory_layout isp1763_memory_conf = {
15062306a36Sopenharmony_ci	.blocks[0]		= 8,
15162306a36Sopenharmony_ci	.blocks_size[0]		= 256,
15262306a36Sopenharmony_ci	.blocks[1]		= 2,
15362306a36Sopenharmony_ci	.blocks_size[1]		= 1024,
15462306a36Sopenharmony_ci	.blocks[2]		= 4,
15562306a36Sopenharmony_ci	.blocks_size[2]		= 4096,
15662306a36Sopenharmony_ci
15762306a36Sopenharmony_ci	.slot_num		= 16,
15862306a36Sopenharmony_ci	.payload_blocks		= 8 + 2 + 4,
15962306a36Sopenharmony_ci	.payload_area_size	= 0x5000,
16062306a36Sopenharmony_ci};
16162306a36Sopenharmony_ci
16262306a36Sopenharmony_cistatic const struct regmap_range isp176x_hc_volatile_ranges[] = {
16362306a36Sopenharmony_ci	regmap_reg_range(ISP176x_HC_USBCMD, ISP176x_HC_ATL_PTD_LASTPTD),
16462306a36Sopenharmony_ci	regmap_reg_range(ISP176x_HC_BUFFER_STATUS, ISP176x_HC_MEMORY),
16562306a36Sopenharmony_ci	regmap_reg_range(ISP176x_HC_INTERRUPT, ISP176x_HC_OTG_CTRL_CLEAR),
16662306a36Sopenharmony_ci};
16762306a36Sopenharmony_ci
16862306a36Sopenharmony_cistatic const struct regmap_access_table isp176x_hc_volatile_table = {
16962306a36Sopenharmony_ci	.yes_ranges	= isp176x_hc_volatile_ranges,
17062306a36Sopenharmony_ci	.n_yes_ranges	= ARRAY_SIZE(isp176x_hc_volatile_ranges),
17162306a36Sopenharmony_ci};
17262306a36Sopenharmony_ci
17362306a36Sopenharmony_cistatic const struct regmap_config isp1760_hc_regmap_conf = {
17462306a36Sopenharmony_ci	.name = "isp1760-hc",
17562306a36Sopenharmony_ci	.reg_bits = 16,
17662306a36Sopenharmony_ci	.reg_stride = 4,
17762306a36Sopenharmony_ci	.val_bits = 32,
17862306a36Sopenharmony_ci	.fast_io = true,
17962306a36Sopenharmony_ci	.max_register = ISP176x_HC_OTG_CTRL_CLEAR,
18062306a36Sopenharmony_ci	.volatile_table = &isp176x_hc_volatile_table,
18162306a36Sopenharmony_ci};
18262306a36Sopenharmony_ci
18362306a36Sopenharmony_cistatic const struct reg_field isp1760_hc_reg_fields[] = {
18462306a36Sopenharmony_ci	[HCS_PPC]		= REG_FIELD(ISP176x_HC_HCSPARAMS, 4, 4),
18562306a36Sopenharmony_ci	[HCS_N_PORTS]		= REG_FIELD(ISP176x_HC_HCSPARAMS, 0, 3),
18662306a36Sopenharmony_ci	[HCC_ISOC_CACHE]	= REG_FIELD(ISP176x_HC_HCCPARAMS, 7, 7),
18762306a36Sopenharmony_ci	[HCC_ISOC_THRES]	= REG_FIELD(ISP176x_HC_HCCPARAMS, 4, 6),
18862306a36Sopenharmony_ci	[CMD_LRESET]		= REG_FIELD(ISP176x_HC_USBCMD, 7, 7),
18962306a36Sopenharmony_ci	[CMD_RESET]		= REG_FIELD(ISP176x_HC_USBCMD, 1, 1),
19062306a36Sopenharmony_ci	[CMD_RUN]		= REG_FIELD(ISP176x_HC_USBCMD, 0, 0),
19162306a36Sopenharmony_ci	[STS_PCD]		= REG_FIELD(ISP176x_HC_USBSTS, 2, 2),
19262306a36Sopenharmony_ci	[HC_FRINDEX]		= REG_FIELD(ISP176x_HC_FRINDEX, 0, 13),
19362306a36Sopenharmony_ci	[FLAG_CF]		= REG_FIELD(ISP176x_HC_CONFIGFLAG, 0, 0),
19462306a36Sopenharmony_ci	[HC_ISO_PTD_DONEMAP]	= REG_FIELD(ISP176x_HC_ISO_PTD_DONEMAP, 0, 31),
19562306a36Sopenharmony_ci	[HC_ISO_PTD_SKIPMAP]	= REG_FIELD(ISP176x_HC_ISO_PTD_SKIPMAP, 0, 31),
19662306a36Sopenharmony_ci	[HC_ISO_PTD_LASTPTD]	= REG_FIELD(ISP176x_HC_ISO_PTD_LASTPTD, 0, 31),
19762306a36Sopenharmony_ci	[HC_INT_PTD_DONEMAP]	= REG_FIELD(ISP176x_HC_INT_PTD_DONEMAP, 0, 31),
19862306a36Sopenharmony_ci	[HC_INT_PTD_SKIPMAP]	= REG_FIELD(ISP176x_HC_INT_PTD_SKIPMAP, 0, 31),
19962306a36Sopenharmony_ci	[HC_INT_PTD_LASTPTD]	= REG_FIELD(ISP176x_HC_INT_PTD_LASTPTD, 0, 31),
20062306a36Sopenharmony_ci	[HC_ATL_PTD_DONEMAP]	= REG_FIELD(ISP176x_HC_ATL_PTD_DONEMAP, 0, 31),
20162306a36Sopenharmony_ci	[HC_ATL_PTD_SKIPMAP]	= REG_FIELD(ISP176x_HC_ATL_PTD_SKIPMAP, 0, 31),
20262306a36Sopenharmony_ci	[HC_ATL_PTD_LASTPTD]	= REG_FIELD(ISP176x_HC_ATL_PTD_LASTPTD, 0, 31),
20362306a36Sopenharmony_ci	[PORT_OWNER]		= REG_FIELD(ISP176x_HC_PORTSC1, 13, 13),
20462306a36Sopenharmony_ci	[PORT_POWER]		= REG_FIELD(ISP176x_HC_PORTSC1, 12, 12),
20562306a36Sopenharmony_ci	[PORT_LSTATUS]		= REG_FIELD(ISP176x_HC_PORTSC1, 10, 11),
20662306a36Sopenharmony_ci	[PORT_RESET]		= REG_FIELD(ISP176x_HC_PORTSC1, 8, 8),
20762306a36Sopenharmony_ci	[PORT_SUSPEND]		= REG_FIELD(ISP176x_HC_PORTSC1, 7, 7),
20862306a36Sopenharmony_ci	[PORT_RESUME]		= REG_FIELD(ISP176x_HC_PORTSC1, 6, 6),
20962306a36Sopenharmony_ci	[PORT_PE]		= REG_FIELD(ISP176x_HC_PORTSC1, 2, 2),
21062306a36Sopenharmony_ci	[PORT_CSC]		= REG_FIELD(ISP176x_HC_PORTSC1, 1, 1),
21162306a36Sopenharmony_ci	[PORT_CONNECT]		= REG_FIELD(ISP176x_HC_PORTSC1, 0, 0),
21262306a36Sopenharmony_ci	[ALL_ATX_RESET]		= REG_FIELD(ISP176x_HC_HW_MODE_CTRL, 31, 31),
21362306a36Sopenharmony_ci	[HW_ANA_DIGI_OC]	= REG_FIELD(ISP176x_HC_HW_MODE_CTRL, 15, 15),
21462306a36Sopenharmony_ci	[HW_COMN_IRQ]		= REG_FIELD(ISP176x_HC_HW_MODE_CTRL, 10, 10),
21562306a36Sopenharmony_ci	[HW_DATA_BUS_WIDTH]	= REG_FIELD(ISP176x_HC_HW_MODE_CTRL, 8, 8),
21662306a36Sopenharmony_ci	[HW_DACK_POL_HIGH]	= REG_FIELD(ISP176x_HC_HW_MODE_CTRL, 6, 6),
21762306a36Sopenharmony_ci	[HW_DREQ_POL_HIGH]	= REG_FIELD(ISP176x_HC_HW_MODE_CTRL, 5, 5),
21862306a36Sopenharmony_ci	[HW_INTR_HIGH_ACT]	= REG_FIELD(ISP176x_HC_HW_MODE_CTRL, 2, 2),
21962306a36Sopenharmony_ci	[HW_INTR_EDGE_TRIG]	= REG_FIELD(ISP176x_HC_HW_MODE_CTRL, 1, 1),
22062306a36Sopenharmony_ci	[HW_GLOBAL_INTR_EN]	= REG_FIELD(ISP176x_HC_HW_MODE_CTRL, 0, 0),
22162306a36Sopenharmony_ci	[HC_CHIP_REV]		= REG_FIELD(ISP176x_HC_CHIP_ID, 16, 31),
22262306a36Sopenharmony_ci	[HC_CHIP_ID_HIGH]	= REG_FIELD(ISP176x_HC_CHIP_ID, 8, 15),
22362306a36Sopenharmony_ci	[HC_CHIP_ID_LOW]	= REG_FIELD(ISP176x_HC_CHIP_ID, 0, 7),
22462306a36Sopenharmony_ci	[HC_SCRATCH]		= REG_FIELD(ISP176x_HC_SCRATCH, 0, 31),
22562306a36Sopenharmony_ci	[SW_RESET_RESET_ALL]	= REG_FIELD(ISP176x_HC_RESET, 0, 0),
22662306a36Sopenharmony_ci	[ISO_BUF_FILL]		= REG_FIELD(ISP176x_HC_BUFFER_STATUS, 2, 2),
22762306a36Sopenharmony_ci	[INT_BUF_FILL]		= REG_FIELD(ISP176x_HC_BUFFER_STATUS, 1, 1),
22862306a36Sopenharmony_ci	[ATL_BUF_FILL]		= REG_FIELD(ISP176x_HC_BUFFER_STATUS, 0, 0),
22962306a36Sopenharmony_ci	[MEM_BANK_SEL]		= REG_FIELD(ISP176x_HC_MEMORY, 16, 17),
23062306a36Sopenharmony_ci	[MEM_START_ADDR]	= REG_FIELD(ISP176x_HC_MEMORY, 0, 15),
23162306a36Sopenharmony_ci	[HC_INTERRUPT]		= REG_FIELD(ISP176x_HC_INTERRUPT, 0, 9),
23262306a36Sopenharmony_ci	[HC_ATL_IRQ_ENABLE]	= REG_FIELD(ISP176x_HC_INTERRUPT_ENABLE, 8, 8),
23362306a36Sopenharmony_ci	[HC_INT_IRQ_ENABLE]	= REG_FIELD(ISP176x_HC_INTERRUPT_ENABLE, 7, 7),
23462306a36Sopenharmony_ci	[HC_ISO_IRQ_MASK_OR]	= REG_FIELD(ISP176x_HC_ISO_IRQ_MASK_OR, 0, 31),
23562306a36Sopenharmony_ci	[HC_INT_IRQ_MASK_OR]	= REG_FIELD(ISP176x_HC_INT_IRQ_MASK_OR, 0, 31),
23662306a36Sopenharmony_ci	[HC_ATL_IRQ_MASK_OR]	= REG_FIELD(ISP176x_HC_ATL_IRQ_MASK_OR, 0, 31),
23762306a36Sopenharmony_ci	[HC_ISO_IRQ_MASK_AND]	= REG_FIELD(ISP176x_HC_ISO_IRQ_MASK_AND, 0, 31),
23862306a36Sopenharmony_ci	[HC_INT_IRQ_MASK_AND]	= REG_FIELD(ISP176x_HC_INT_IRQ_MASK_AND, 0, 31),
23962306a36Sopenharmony_ci	[HC_ATL_IRQ_MASK_AND]	= REG_FIELD(ISP176x_HC_ATL_IRQ_MASK_AND, 0, 31),
24062306a36Sopenharmony_ci	[HW_OTG_DISABLE_CLEAR]	= REG_FIELD(ISP176x_HC_OTG_CTRL, 26, 26),
24162306a36Sopenharmony_ci	[HW_SW_SEL_HC_DC_CLEAR]	= REG_FIELD(ISP176x_HC_OTG_CTRL, 23, 23),
24262306a36Sopenharmony_ci	[HW_VBUS_DRV_CLEAR]	= REG_FIELD(ISP176x_HC_OTG_CTRL, 20, 20),
24362306a36Sopenharmony_ci	[HW_SEL_CP_EXT_CLEAR]	= REG_FIELD(ISP176x_HC_OTG_CTRL, 19, 19),
24462306a36Sopenharmony_ci	[HW_DM_PULLDOWN_CLEAR]	= REG_FIELD(ISP176x_HC_OTG_CTRL, 18, 18),
24562306a36Sopenharmony_ci	[HW_DP_PULLDOWN_CLEAR]	= REG_FIELD(ISP176x_HC_OTG_CTRL, 17, 17),
24662306a36Sopenharmony_ci	[HW_DP_PULLUP_CLEAR]	= REG_FIELD(ISP176x_HC_OTG_CTRL, 16, 16),
24762306a36Sopenharmony_ci	[HW_OTG_DISABLE]	= REG_FIELD(ISP176x_HC_OTG_CTRL, 10, 10),
24862306a36Sopenharmony_ci	[HW_SW_SEL_HC_DC]	= REG_FIELD(ISP176x_HC_OTG_CTRL, 7, 7),
24962306a36Sopenharmony_ci	[HW_VBUS_DRV]		= REG_FIELD(ISP176x_HC_OTG_CTRL, 4, 4),
25062306a36Sopenharmony_ci	[HW_SEL_CP_EXT]		= REG_FIELD(ISP176x_HC_OTG_CTRL, 3, 3),
25162306a36Sopenharmony_ci	[HW_DM_PULLDOWN]	= REG_FIELD(ISP176x_HC_OTG_CTRL, 2, 2),
25262306a36Sopenharmony_ci	[HW_DP_PULLDOWN]	= REG_FIELD(ISP176x_HC_OTG_CTRL, 1, 1),
25362306a36Sopenharmony_ci	[HW_DP_PULLUP]		= REG_FIELD(ISP176x_HC_OTG_CTRL, 0, 0),
25462306a36Sopenharmony_ci	/* Make sure the array is sized properly during compilation */
25562306a36Sopenharmony_ci	[HC_FIELD_MAX]		= {},
25662306a36Sopenharmony_ci};
25762306a36Sopenharmony_ci
25862306a36Sopenharmony_cistatic const struct reg_field isp1763_hc_reg_fields[] = {
25962306a36Sopenharmony_ci	[CMD_LRESET]		= REG_FIELD(ISP1763_HC_USBCMD, 7, 7),
26062306a36Sopenharmony_ci	[CMD_RESET]		= REG_FIELD(ISP1763_HC_USBCMD, 1, 1),
26162306a36Sopenharmony_ci	[CMD_RUN]		= REG_FIELD(ISP1763_HC_USBCMD, 0, 0),
26262306a36Sopenharmony_ci	[STS_PCD]		= REG_FIELD(ISP1763_HC_USBSTS, 2, 2),
26362306a36Sopenharmony_ci	[HC_FRINDEX]		= REG_FIELD(ISP1763_HC_FRINDEX, 0, 13),
26462306a36Sopenharmony_ci	[FLAG_CF]		= REG_FIELD(ISP1763_HC_CONFIGFLAG, 0, 0),
26562306a36Sopenharmony_ci	[HC_ISO_PTD_DONEMAP]	= REG_FIELD(ISP1763_HC_ISO_PTD_DONEMAP, 0, 15),
26662306a36Sopenharmony_ci	[HC_ISO_PTD_SKIPMAP]	= REG_FIELD(ISP1763_HC_ISO_PTD_SKIPMAP, 0, 15),
26762306a36Sopenharmony_ci	[HC_ISO_PTD_LASTPTD]	= REG_FIELD(ISP1763_HC_ISO_PTD_LASTPTD, 0, 15),
26862306a36Sopenharmony_ci	[HC_INT_PTD_DONEMAP]	= REG_FIELD(ISP1763_HC_INT_PTD_DONEMAP, 0, 15),
26962306a36Sopenharmony_ci	[HC_INT_PTD_SKIPMAP]	= REG_FIELD(ISP1763_HC_INT_PTD_SKIPMAP, 0, 15),
27062306a36Sopenharmony_ci	[HC_INT_PTD_LASTPTD]	= REG_FIELD(ISP1763_HC_INT_PTD_LASTPTD, 0, 15),
27162306a36Sopenharmony_ci	[HC_ATL_PTD_DONEMAP]	= REG_FIELD(ISP1763_HC_ATL_PTD_DONEMAP, 0, 15),
27262306a36Sopenharmony_ci	[HC_ATL_PTD_SKIPMAP]	= REG_FIELD(ISP1763_HC_ATL_PTD_SKIPMAP, 0, 15),
27362306a36Sopenharmony_ci	[HC_ATL_PTD_LASTPTD]	= REG_FIELD(ISP1763_HC_ATL_PTD_LASTPTD, 0, 15),
27462306a36Sopenharmony_ci	[PORT_OWNER]		= REG_FIELD(ISP1763_HC_PORTSC1, 13, 13),
27562306a36Sopenharmony_ci	[PORT_POWER]		= REG_FIELD(ISP1763_HC_PORTSC1, 12, 12),
27662306a36Sopenharmony_ci	[PORT_LSTATUS]		= REG_FIELD(ISP1763_HC_PORTSC1, 10, 11),
27762306a36Sopenharmony_ci	[PORT_RESET]		= REG_FIELD(ISP1763_HC_PORTSC1, 8, 8),
27862306a36Sopenharmony_ci	[PORT_SUSPEND]		= REG_FIELD(ISP1763_HC_PORTSC1, 7, 7),
27962306a36Sopenharmony_ci	[PORT_RESUME]		= REG_FIELD(ISP1763_HC_PORTSC1, 6, 6),
28062306a36Sopenharmony_ci	[PORT_PE]		= REG_FIELD(ISP1763_HC_PORTSC1, 2, 2),
28162306a36Sopenharmony_ci	[PORT_CSC]		= REG_FIELD(ISP1763_HC_PORTSC1, 1, 1),
28262306a36Sopenharmony_ci	[PORT_CONNECT]		= REG_FIELD(ISP1763_HC_PORTSC1, 0, 0),
28362306a36Sopenharmony_ci	[HW_DATA_BUS_WIDTH]	= REG_FIELD(ISP1763_HC_HW_MODE_CTRL, 4, 4),
28462306a36Sopenharmony_ci	[HW_DACK_POL_HIGH]	= REG_FIELD(ISP1763_HC_HW_MODE_CTRL, 6, 6),
28562306a36Sopenharmony_ci	[HW_DREQ_POL_HIGH]	= REG_FIELD(ISP1763_HC_HW_MODE_CTRL, 5, 5),
28662306a36Sopenharmony_ci	[HW_INTF_LOCK]		= REG_FIELD(ISP1763_HC_HW_MODE_CTRL, 3, 3),
28762306a36Sopenharmony_ci	[HW_INTR_HIGH_ACT]	= REG_FIELD(ISP1763_HC_HW_MODE_CTRL, 2, 2),
28862306a36Sopenharmony_ci	[HW_INTR_EDGE_TRIG]	= REG_FIELD(ISP1763_HC_HW_MODE_CTRL, 1, 1),
28962306a36Sopenharmony_ci	[HW_GLOBAL_INTR_EN]	= REG_FIELD(ISP1763_HC_HW_MODE_CTRL, 0, 0),
29062306a36Sopenharmony_ci	[SW_RESET_RESET_ATX]	= REG_FIELD(ISP1763_HC_RESET, 3, 3),
29162306a36Sopenharmony_ci	[SW_RESET_RESET_ALL]	= REG_FIELD(ISP1763_HC_RESET, 0, 0),
29262306a36Sopenharmony_ci	[HC_CHIP_ID_HIGH]	= REG_FIELD(ISP1763_HC_CHIP_ID, 0, 15),
29362306a36Sopenharmony_ci	[HC_CHIP_ID_LOW]	= REG_FIELD(ISP1763_HC_CHIP_REV, 8, 15),
29462306a36Sopenharmony_ci	[HC_CHIP_REV]		= REG_FIELD(ISP1763_HC_CHIP_REV, 0, 7),
29562306a36Sopenharmony_ci	[HC_SCRATCH]		= REG_FIELD(ISP1763_HC_SCRATCH, 0, 15),
29662306a36Sopenharmony_ci	[ISO_BUF_FILL]		= REG_FIELD(ISP1763_HC_BUFFER_STATUS, 2, 2),
29762306a36Sopenharmony_ci	[INT_BUF_FILL]		= REG_FIELD(ISP1763_HC_BUFFER_STATUS, 1, 1),
29862306a36Sopenharmony_ci	[ATL_BUF_FILL]		= REG_FIELD(ISP1763_HC_BUFFER_STATUS, 0, 0),
29962306a36Sopenharmony_ci	[MEM_START_ADDR]	= REG_FIELD(ISP1763_HC_MEMORY, 0, 15),
30062306a36Sopenharmony_ci	[HC_DATA]		= REG_FIELD(ISP1763_HC_DATA, 0, 15),
30162306a36Sopenharmony_ci	[HC_INTERRUPT]		= REG_FIELD(ISP1763_HC_INTERRUPT, 0, 10),
30262306a36Sopenharmony_ci	[HC_ATL_IRQ_ENABLE]	= REG_FIELD(ISP1763_HC_INTERRUPT_ENABLE, 8, 8),
30362306a36Sopenharmony_ci	[HC_INT_IRQ_ENABLE]	= REG_FIELD(ISP1763_HC_INTERRUPT_ENABLE, 7, 7),
30462306a36Sopenharmony_ci	[HC_ISO_IRQ_MASK_OR]	= REG_FIELD(ISP1763_HC_ISO_IRQ_MASK_OR, 0, 15),
30562306a36Sopenharmony_ci	[HC_INT_IRQ_MASK_OR]	= REG_FIELD(ISP1763_HC_INT_IRQ_MASK_OR, 0, 15),
30662306a36Sopenharmony_ci	[HC_ATL_IRQ_MASK_OR]	= REG_FIELD(ISP1763_HC_ATL_IRQ_MASK_OR, 0, 15),
30762306a36Sopenharmony_ci	[HC_ISO_IRQ_MASK_AND]	= REG_FIELD(ISP1763_HC_ISO_IRQ_MASK_AND, 0, 15),
30862306a36Sopenharmony_ci	[HC_INT_IRQ_MASK_AND]	= REG_FIELD(ISP1763_HC_INT_IRQ_MASK_AND, 0, 15),
30962306a36Sopenharmony_ci	[HC_ATL_IRQ_MASK_AND]	= REG_FIELD(ISP1763_HC_ATL_IRQ_MASK_AND, 0, 15),
31062306a36Sopenharmony_ci	[HW_HC_2_DIS]		= REG_FIELD(ISP1763_HC_OTG_CTRL_SET, 15, 15),
31162306a36Sopenharmony_ci	[HW_OTG_DISABLE]	= REG_FIELD(ISP1763_HC_OTG_CTRL_SET, 10, 10),
31262306a36Sopenharmony_ci	[HW_SW_SEL_HC_DC]	= REG_FIELD(ISP1763_HC_OTG_CTRL_SET, 7, 7),
31362306a36Sopenharmony_ci	[HW_VBUS_DRV]		= REG_FIELD(ISP1763_HC_OTG_CTRL_SET, 4, 4),
31462306a36Sopenharmony_ci	[HW_SEL_CP_EXT]		= REG_FIELD(ISP1763_HC_OTG_CTRL_SET, 3, 3),
31562306a36Sopenharmony_ci	[HW_DM_PULLDOWN]	= REG_FIELD(ISP1763_HC_OTG_CTRL_SET, 2, 2),
31662306a36Sopenharmony_ci	[HW_DP_PULLDOWN]	= REG_FIELD(ISP1763_HC_OTG_CTRL_SET, 1, 1),
31762306a36Sopenharmony_ci	[HW_DP_PULLUP]		= REG_FIELD(ISP1763_HC_OTG_CTRL_SET, 0, 0),
31862306a36Sopenharmony_ci	[HW_HC_2_DIS_CLEAR]	= REG_FIELD(ISP1763_HC_OTG_CTRL_CLEAR, 15, 15),
31962306a36Sopenharmony_ci	[HW_OTG_DISABLE_CLEAR]	= REG_FIELD(ISP1763_HC_OTG_CTRL_CLEAR, 10, 10),
32062306a36Sopenharmony_ci	[HW_SW_SEL_HC_DC_CLEAR]	= REG_FIELD(ISP1763_HC_OTG_CTRL_CLEAR, 7, 7),
32162306a36Sopenharmony_ci	[HW_VBUS_DRV_CLEAR]	= REG_FIELD(ISP1763_HC_OTG_CTRL_CLEAR, 4, 4),
32262306a36Sopenharmony_ci	[HW_SEL_CP_EXT_CLEAR]	= REG_FIELD(ISP1763_HC_OTG_CTRL_CLEAR, 3, 3),
32362306a36Sopenharmony_ci	[HW_DM_PULLDOWN_CLEAR]	= REG_FIELD(ISP1763_HC_OTG_CTRL_CLEAR, 2, 2),
32462306a36Sopenharmony_ci	[HW_DP_PULLDOWN_CLEAR]	= REG_FIELD(ISP1763_HC_OTG_CTRL_CLEAR, 1, 1),
32562306a36Sopenharmony_ci	[HW_DP_PULLUP_CLEAR]	= REG_FIELD(ISP1763_HC_OTG_CTRL_CLEAR, 0, 0),
32662306a36Sopenharmony_ci	/* Make sure the array is sized properly during compilation */
32762306a36Sopenharmony_ci	[HC_FIELD_MAX]		= {},
32862306a36Sopenharmony_ci};
32962306a36Sopenharmony_ci
33062306a36Sopenharmony_cistatic const struct regmap_range isp1763_hc_volatile_ranges[] = {
33162306a36Sopenharmony_ci	regmap_reg_range(ISP1763_HC_USBCMD, ISP1763_HC_ATL_PTD_LASTPTD),
33262306a36Sopenharmony_ci	regmap_reg_range(ISP1763_HC_BUFFER_STATUS, ISP1763_HC_DATA),
33362306a36Sopenharmony_ci	regmap_reg_range(ISP1763_HC_INTERRUPT, ISP1763_HC_OTG_CTRL_CLEAR),
33462306a36Sopenharmony_ci};
33562306a36Sopenharmony_ci
33662306a36Sopenharmony_cistatic const struct regmap_access_table isp1763_hc_volatile_table = {
33762306a36Sopenharmony_ci	.yes_ranges	= isp1763_hc_volatile_ranges,
33862306a36Sopenharmony_ci	.n_yes_ranges	= ARRAY_SIZE(isp1763_hc_volatile_ranges),
33962306a36Sopenharmony_ci};
34062306a36Sopenharmony_ci
34162306a36Sopenharmony_cistatic const struct regmap_config isp1763_hc_regmap_conf = {
34262306a36Sopenharmony_ci	.name = "isp1763-hc",
34362306a36Sopenharmony_ci	.reg_bits = 8,
34462306a36Sopenharmony_ci	.reg_stride = 2,
34562306a36Sopenharmony_ci	.val_bits = 16,
34662306a36Sopenharmony_ci	.fast_io = true,
34762306a36Sopenharmony_ci	.max_register = ISP1763_HC_OTG_CTRL_CLEAR,
34862306a36Sopenharmony_ci	.volatile_table = &isp1763_hc_volatile_table,
34962306a36Sopenharmony_ci};
35062306a36Sopenharmony_ci
35162306a36Sopenharmony_cistatic const struct regmap_range isp176x_dc_volatile_ranges[] = {
35262306a36Sopenharmony_ci	regmap_reg_range(ISP176x_DC_EPMAXPKTSZ, ISP176x_DC_EPTYPE),
35362306a36Sopenharmony_ci	regmap_reg_range(ISP176x_DC_BUFLEN, ISP176x_DC_EPINDEX),
35462306a36Sopenharmony_ci};
35562306a36Sopenharmony_ci
35662306a36Sopenharmony_cistatic const struct regmap_access_table isp176x_dc_volatile_table = {
35762306a36Sopenharmony_ci	.yes_ranges	= isp176x_dc_volatile_ranges,
35862306a36Sopenharmony_ci	.n_yes_ranges	= ARRAY_SIZE(isp176x_dc_volatile_ranges),
35962306a36Sopenharmony_ci};
36062306a36Sopenharmony_ci
36162306a36Sopenharmony_cistatic const struct regmap_config isp1761_dc_regmap_conf = {
36262306a36Sopenharmony_ci	.name = "isp1761-dc",
36362306a36Sopenharmony_ci	.reg_bits = 16,
36462306a36Sopenharmony_ci	.reg_stride = 4,
36562306a36Sopenharmony_ci	.val_bits = 32,
36662306a36Sopenharmony_ci	.fast_io = true,
36762306a36Sopenharmony_ci	.max_register = ISP176x_DC_TESTMODE,
36862306a36Sopenharmony_ci	.volatile_table = &isp176x_dc_volatile_table,
36962306a36Sopenharmony_ci};
37062306a36Sopenharmony_ci
37162306a36Sopenharmony_cistatic const struct reg_field isp1761_dc_reg_fields[] = {
37262306a36Sopenharmony_ci	[DC_DEVEN]		= REG_FIELD(ISP176x_DC_ADDRESS, 7, 7),
37362306a36Sopenharmony_ci	[DC_DEVADDR]		= REG_FIELD(ISP176x_DC_ADDRESS, 0, 6),
37462306a36Sopenharmony_ci	[DC_VBUSSTAT]		= REG_FIELD(ISP176x_DC_MODE, 8, 8),
37562306a36Sopenharmony_ci	[DC_SFRESET]		= REG_FIELD(ISP176x_DC_MODE, 4, 4),
37662306a36Sopenharmony_ci	[DC_GLINTENA]		= REG_FIELD(ISP176x_DC_MODE, 3, 3),
37762306a36Sopenharmony_ci	[DC_CDBGMOD_ACK]	= REG_FIELD(ISP176x_DC_INTCONF, 6, 6),
37862306a36Sopenharmony_ci	[DC_DDBGMODIN_ACK]	= REG_FIELD(ISP176x_DC_INTCONF, 4, 4),
37962306a36Sopenharmony_ci	[DC_DDBGMODOUT_ACK]	= REG_FIELD(ISP176x_DC_INTCONF, 2, 2),
38062306a36Sopenharmony_ci	[DC_INTPOL]		= REG_FIELD(ISP176x_DC_INTCONF, 0, 0),
38162306a36Sopenharmony_ci	[DC_IEPRXTX_7]		= REG_FIELD(ISP176x_DC_INTENABLE, 25, 25),
38262306a36Sopenharmony_ci	[DC_IEPRXTX_6]		= REG_FIELD(ISP176x_DC_INTENABLE, 23, 23),
38362306a36Sopenharmony_ci	[DC_IEPRXTX_5]		= REG_FIELD(ISP176x_DC_INTENABLE, 21, 21),
38462306a36Sopenharmony_ci	[DC_IEPRXTX_4]		= REG_FIELD(ISP176x_DC_INTENABLE, 19, 19),
38562306a36Sopenharmony_ci	[DC_IEPRXTX_3]		= REG_FIELD(ISP176x_DC_INTENABLE, 17, 17),
38662306a36Sopenharmony_ci	[DC_IEPRXTX_2]		= REG_FIELD(ISP176x_DC_INTENABLE, 15, 15),
38762306a36Sopenharmony_ci	[DC_IEPRXTX_1]		= REG_FIELD(ISP176x_DC_INTENABLE, 13, 13),
38862306a36Sopenharmony_ci	[DC_IEPRXTX_0]		= REG_FIELD(ISP176x_DC_INTENABLE, 11, 11),
38962306a36Sopenharmony_ci	[DC_IEP0SETUP]		= REG_FIELD(ISP176x_DC_INTENABLE, 8, 8),
39062306a36Sopenharmony_ci	[DC_IEVBUS]		= REG_FIELD(ISP176x_DC_INTENABLE, 7, 7),
39162306a36Sopenharmony_ci	[DC_IEHS_STA]		= REG_FIELD(ISP176x_DC_INTENABLE, 5, 5),
39262306a36Sopenharmony_ci	[DC_IERESM]		= REG_FIELD(ISP176x_DC_INTENABLE, 4, 4),
39362306a36Sopenharmony_ci	[DC_IESUSP]		= REG_FIELD(ISP176x_DC_INTENABLE, 3, 3),
39462306a36Sopenharmony_ci	[DC_IEBRST]		= REG_FIELD(ISP176x_DC_INTENABLE, 0, 0),
39562306a36Sopenharmony_ci	[DC_EP0SETUP]		= REG_FIELD(ISP176x_DC_EPINDEX, 5, 5),
39662306a36Sopenharmony_ci	[DC_ENDPIDX]		= REG_FIELD(ISP176x_DC_EPINDEX, 1, 4),
39762306a36Sopenharmony_ci	[DC_EPDIR]		= REG_FIELD(ISP176x_DC_EPINDEX, 0, 0),
39862306a36Sopenharmony_ci	[DC_CLBUF]		= REG_FIELD(ISP176x_DC_CTRLFUNC, 4, 4),
39962306a36Sopenharmony_ci	[DC_VENDP]		= REG_FIELD(ISP176x_DC_CTRLFUNC, 3, 3),
40062306a36Sopenharmony_ci	[DC_DSEN]		= REG_FIELD(ISP176x_DC_CTRLFUNC, 2, 2),
40162306a36Sopenharmony_ci	[DC_STATUS]		= REG_FIELD(ISP176x_DC_CTRLFUNC, 1, 1),
40262306a36Sopenharmony_ci	[DC_STALL]		= REG_FIELD(ISP176x_DC_CTRLFUNC, 0, 0),
40362306a36Sopenharmony_ci	[DC_BUFLEN]		= REG_FIELD(ISP176x_DC_BUFLEN, 0, 15),
40462306a36Sopenharmony_ci	[DC_FFOSZ]		= REG_FIELD(ISP176x_DC_EPMAXPKTSZ, 0, 10),
40562306a36Sopenharmony_ci	[DC_EPENABLE]		= REG_FIELD(ISP176x_DC_EPTYPE, 3, 3),
40662306a36Sopenharmony_ci	[DC_ENDPTYP]		= REG_FIELD(ISP176x_DC_EPTYPE, 0, 1),
40762306a36Sopenharmony_ci	[DC_UFRAMENUM]		= REG_FIELD(ISP176x_DC_FRAMENUM, 11, 13),
40862306a36Sopenharmony_ci	[DC_FRAMENUM]		= REG_FIELD(ISP176x_DC_FRAMENUM, 0, 10),
40962306a36Sopenharmony_ci	[DC_CHIP_ID_HIGH]	= REG_FIELD(ISP176x_DC_CHIPID, 16, 31),
41062306a36Sopenharmony_ci	[DC_CHIP_ID_LOW]	= REG_FIELD(ISP176x_DC_CHIPID, 0, 15),
41162306a36Sopenharmony_ci	[DC_SCRATCH]		= REG_FIELD(ISP176x_DC_SCRATCH, 0, 15),
41262306a36Sopenharmony_ci	/* Make sure the array is sized properly during compilation */
41362306a36Sopenharmony_ci	[DC_FIELD_MAX]		= {},
41462306a36Sopenharmony_ci};
41562306a36Sopenharmony_ci
41662306a36Sopenharmony_cistatic const struct regmap_range isp1763_dc_volatile_ranges[] = {
41762306a36Sopenharmony_ci	regmap_reg_range(ISP1763_DC_EPMAXPKTSZ, ISP1763_DC_EPTYPE),
41862306a36Sopenharmony_ci	regmap_reg_range(ISP1763_DC_BUFLEN, ISP1763_DC_EPINDEX),
41962306a36Sopenharmony_ci};
42062306a36Sopenharmony_ci
42162306a36Sopenharmony_cistatic const struct regmap_access_table isp1763_dc_volatile_table = {
42262306a36Sopenharmony_ci	.yes_ranges	= isp1763_dc_volatile_ranges,
42362306a36Sopenharmony_ci	.n_yes_ranges	= ARRAY_SIZE(isp1763_dc_volatile_ranges),
42462306a36Sopenharmony_ci};
42562306a36Sopenharmony_ci
42662306a36Sopenharmony_cistatic const struct reg_field isp1763_dc_reg_fields[] = {
42762306a36Sopenharmony_ci	[DC_DEVEN]		= REG_FIELD(ISP1763_DC_ADDRESS, 7, 7),
42862306a36Sopenharmony_ci	[DC_DEVADDR]		= REG_FIELD(ISP1763_DC_ADDRESS, 0, 6),
42962306a36Sopenharmony_ci	[DC_VBUSSTAT]		= REG_FIELD(ISP1763_DC_MODE, 8, 8),
43062306a36Sopenharmony_ci	[DC_SFRESET]		= REG_FIELD(ISP1763_DC_MODE, 4, 4),
43162306a36Sopenharmony_ci	[DC_GLINTENA]		= REG_FIELD(ISP1763_DC_MODE, 3, 3),
43262306a36Sopenharmony_ci	[DC_CDBGMOD_ACK]	= REG_FIELD(ISP1763_DC_INTCONF, 6, 6),
43362306a36Sopenharmony_ci	[DC_DDBGMODIN_ACK]	= REG_FIELD(ISP1763_DC_INTCONF, 4, 4),
43462306a36Sopenharmony_ci	[DC_DDBGMODOUT_ACK]	= REG_FIELD(ISP1763_DC_INTCONF, 2, 2),
43562306a36Sopenharmony_ci	[DC_INTPOL]		= REG_FIELD(ISP1763_DC_INTCONF, 0, 0),
43662306a36Sopenharmony_ci	[DC_IEPRXTX_7]		= REG_FIELD(ISP1763_DC_INTENABLE, 25, 25),
43762306a36Sopenharmony_ci	[DC_IEPRXTX_6]		= REG_FIELD(ISP1763_DC_INTENABLE, 23, 23),
43862306a36Sopenharmony_ci	[DC_IEPRXTX_5]		= REG_FIELD(ISP1763_DC_INTENABLE, 21, 21),
43962306a36Sopenharmony_ci	[DC_IEPRXTX_4]		= REG_FIELD(ISP1763_DC_INTENABLE, 19, 19),
44062306a36Sopenharmony_ci	[DC_IEPRXTX_3]		= REG_FIELD(ISP1763_DC_INTENABLE, 17, 17),
44162306a36Sopenharmony_ci	[DC_IEPRXTX_2]		= REG_FIELD(ISP1763_DC_INTENABLE, 15, 15),
44262306a36Sopenharmony_ci	[DC_IEPRXTX_1]		= REG_FIELD(ISP1763_DC_INTENABLE, 13, 13),
44362306a36Sopenharmony_ci	[DC_IEPRXTX_0]		= REG_FIELD(ISP1763_DC_INTENABLE, 11, 11),
44462306a36Sopenharmony_ci	[DC_IEP0SETUP]		= REG_FIELD(ISP1763_DC_INTENABLE, 8, 8),
44562306a36Sopenharmony_ci	[DC_IEVBUS]		= REG_FIELD(ISP1763_DC_INTENABLE, 7, 7),
44662306a36Sopenharmony_ci	[DC_IEHS_STA]		= REG_FIELD(ISP1763_DC_INTENABLE, 5, 5),
44762306a36Sopenharmony_ci	[DC_IERESM]		= REG_FIELD(ISP1763_DC_INTENABLE, 4, 4),
44862306a36Sopenharmony_ci	[DC_IESUSP]		= REG_FIELD(ISP1763_DC_INTENABLE, 3, 3),
44962306a36Sopenharmony_ci	[DC_IEBRST]		= REG_FIELD(ISP1763_DC_INTENABLE, 0, 0),
45062306a36Sopenharmony_ci	[DC_EP0SETUP]		= REG_FIELD(ISP1763_DC_EPINDEX, 5, 5),
45162306a36Sopenharmony_ci	[DC_ENDPIDX]		= REG_FIELD(ISP1763_DC_EPINDEX, 1, 4),
45262306a36Sopenharmony_ci	[DC_EPDIR]		= REG_FIELD(ISP1763_DC_EPINDEX, 0, 0),
45362306a36Sopenharmony_ci	[DC_CLBUF]		= REG_FIELD(ISP1763_DC_CTRLFUNC, 4, 4),
45462306a36Sopenharmony_ci	[DC_VENDP]		= REG_FIELD(ISP1763_DC_CTRLFUNC, 3, 3),
45562306a36Sopenharmony_ci	[DC_DSEN]		= REG_FIELD(ISP1763_DC_CTRLFUNC, 2, 2),
45662306a36Sopenharmony_ci	[DC_STATUS]		= REG_FIELD(ISP1763_DC_CTRLFUNC, 1, 1),
45762306a36Sopenharmony_ci	[DC_STALL]		= REG_FIELD(ISP1763_DC_CTRLFUNC, 0, 0),
45862306a36Sopenharmony_ci	[DC_BUFLEN]		= REG_FIELD(ISP1763_DC_BUFLEN, 0, 15),
45962306a36Sopenharmony_ci	[DC_FFOSZ]		= REG_FIELD(ISP1763_DC_EPMAXPKTSZ, 0, 10),
46062306a36Sopenharmony_ci	[DC_EPENABLE]		= REG_FIELD(ISP1763_DC_EPTYPE, 3, 3),
46162306a36Sopenharmony_ci	[DC_ENDPTYP]		= REG_FIELD(ISP1763_DC_EPTYPE, 0, 1),
46262306a36Sopenharmony_ci	[DC_UFRAMENUM]		= REG_FIELD(ISP1763_DC_FRAMENUM, 11, 13),
46362306a36Sopenharmony_ci	[DC_FRAMENUM]		= REG_FIELD(ISP1763_DC_FRAMENUM, 0, 10),
46462306a36Sopenharmony_ci	[DC_CHIP_ID_HIGH]	= REG_FIELD(ISP1763_DC_CHIPID_HIGH, 0, 15),
46562306a36Sopenharmony_ci	[DC_CHIP_ID_LOW]	= REG_FIELD(ISP1763_DC_CHIPID_LOW, 0, 15),
46662306a36Sopenharmony_ci	[DC_SCRATCH]		= REG_FIELD(ISP1763_DC_SCRATCH, 0, 15),
46762306a36Sopenharmony_ci	/* Make sure the array is sized properly during compilation */
46862306a36Sopenharmony_ci	[DC_FIELD_MAX]		= {},
46962306a36Sopenharmony_ci};
47062306a36Sopenharmony_ci
47162306a36Sopenharmony_cistatic const struct regmap_config isp1763_dc_regmap_conf = {
47262306a36Sopenharmony_ci	.name = "isp1763-dc",
47362306a36Sopenharmony_ci	.reg_bits = 8,
47462306a36Sopenharmony_ci	.reg_stride = 2,
47562306a36Sopenharmony_ci	.val_bits = 16,
47662306a36Sopenharmony_ci	.fast_io = true,
47762306a36Sopenharmony_ci	.max_register = ISP1763_DC_TESTMODE,
47862306a36Sopenharmony_ci	.volatile_table = &isp1763_dc_volatile_table,
47962306a36Sopenharmony_ci};
48062306a36Sopenharmony_ci
48162306a36Sopenharmony_ciint isp1760_register(struct resource *mem, int irq, unsigned long irqflags,
48262306a36Sopenharmony_ci		     struct device *dev, unsigned int devflags)
48362306a36Sopenharmony_ci{
48462306a36Sopenharmony_ci	const struct regmap_config *hc_regmap;
48562306a36Sopenharmony_ci	const struct reg_field *hc_reg_fields;
48662306a36Sopenharmony_ci	const struct regmap_config *dc_regmap;
48762306a36Sopenharmony_ci	const struct reg_field *dc_reg_fields;
48862306a36Sopenharmony_ci	struct isp1760_device *isp;
48962306a36Sopenharmony_ci	struct isp1760_hcd *hcd;
49062306a36Sopenharmony_ci	struct isp1760_udc *udc;
49162306a36Sopenharmony_ci	struct regmap_field *f;
49262306a36Sopenharmony_ci	bool udc_enabled;
49362306a36Sopenharmony_ci	int ret;
49462306a36Sopenharmony_ci	int i;
49562306a36Sopenharmony_ci
49662306a36Sopenharmony_ci	/*
49762306a36Sopenharmony_ci	 * If neither the HCD not the UDC is enabled return an error, as no
49862306a36Sopenharmony_ci	 * device would be registered.
49962306a36Sopenharmony_ci	 */
50062306a36Sopenharmony_ci	udc_enabled = ((devflags & ISP1760_FLAG_ISP1763) ||
50162306a36Sopenharmony_ci		       (devflags & ISP1760_FLAG_ISP1761));
50262306a36Sopenharmony_ci
50362306a36Sopenharmony_ci	if ((!IS_ENABLED(CONFIG_USB_ISP1760_HCD) || usb_disabled()) &&
50462306a36Sopenharmony_ci	    (!udc_enabled || !IS_ENABLED(CONFIG_USB_ISP1761_UDC)))
50562306a36Sopenharmony_ci		return -ENODEV;
50662306a36Sopenharmony_ci
50762306a36Sopenharmony_ci	isp = devm_kzalloc(dev, sizeof(*isp), GFP_KERNEL);
50862306a36Sopenharmony_ci	if (!isp)
50962306a36Sopenharmony_ci		return -ENOMEM;
51062306a36Sopenharmony_ci
51162306a36Sopenharmony_ci	isp->dev = dev;
51262306a36Sopenharmony_ci	isp->devflags = devflags;
51362306a36Sopenharmony_ci	hcd = &isp->hcd;
51462306a36Sopenharmony_ci	udc = &isp->udc;
51562306a36Sopenharmony_ci
51662306a36Sopenharmony_ci	hcd->is_isp1763 = !!(devflags & ISP1760_FLAG_ISP1763);
51762306a36Sopenharmony_ci	udc->is_isp1763 = !!(devflags & ISP1760_FLAG_ISP1763);
51862306a36Sopenharmony_ci
51962306a36Sopenharmony_ci	if (!hcd->is_isp1763 && (devflags & ISP1760_FLAG_BUS_WIDTH_8)) {
52062306a36Sopenharmony_ci		dev_err(dev, "isp1760/61 do not support data width 8\n");
52162306a36Sopenharmony_ci		return -EINVAL;
52262306a36Sopenharmony_ci	}
52362306a36Sopenharmony_ci
52462306a36Sopenharmony_ci	if (hcd->is_isp1763) {
52562306a36Sopenharmony_ci		hc_regmap = &isp1763_hc_regmap_conf;
52662306a36Sopenharmony_ci		hc_reg_fields = &isp1763_hc_reg_fields[0];
52762306a36Sopenharmony_ci		dc_regmap = &isp1763_dc_regmap_conf;
52862306a36Sopenharmony_ci		dc_reg_fields = &isp1763_dc_reg_fields[0];
52962306a36Sopenharmony_ci	} else {
53062306a36Sopenharmony_ci		hc_regmap = &isp1760_hc_regmap_conf;
53162306a36Sopenharmony_ci		hc_reg_fields = &isp1760_hc_reg_fields[0];
53262306a36Sopenharmony_ci		dc_regmap = &isp1761_dc_regmap_conf;
53362306a36Sopenharmony_ci		dc_reg_fields = &isp1761_dc_reg_fields[0];
53462306a36Sopenharmony_ci	}
53562306a36Sopenharmony_ci
53662306a36Sopenharmony_ci	isp->rst_gpio = devm_gpiod_get_optional(dev, NULL, GPIOD_OUT_HIGH);
53762306a36Sopenharmony_ci	if (IS_ERR(isp->rst_gpio))
53862306a36Sopenharmony_ci		return PTR_ERR(isp->rst_gpio);
53962306a36Sopenharmony_ci
54062306a36Sopenharmony_ci	hcd->base = devm_ioremap_resource(dev, mem);
54162306a36Sopenharmony_ci	if (IS_ERR(hcd->base))
54262306a36Sopenharmony_ci		return PTR_ERR(hcd->base);
54362306a36Sopenharmony_ci
54462306a36Sopenharmony_ci	hcd->regs = devm_regmap_init_mmio(dev, hcd->base, hc_regmap);
54562306a36Sopenharmony_ci	if (IS_ERR(hcd->regs))
54662306a36Sopenharmony_ci		return PTR_ERR(hcd->regs);
54762306a36Sopenharmony_ci
54862306a36Sopenharmony_ci	for (i = 0; i < HC_FIELD_MAX; i++) {
54962306a36Sopenharmony_ci		f = devm_regmap_field_alloc(dev, hcd->regs, hc_reg_fields[i]);
55062306a36Sopenharmony_ci		if (IS_ERR(f))
55162306a36Sopenharmony_ci			return PTR_ERR(f);
55262306a36Sopenharmony_ci
55362306a36Sopenharmony_ci		hcd->fields[i] = f;
55462306a36Sopenharmony_ci	}
55562306a36Sopenharmony_ci
55662306a36Sopenharmony_ci	udc->regs = devm_regmap_init_mmio(dev, hcd->base, dc_regmap);
55762306a36Sopenharmony_ci	if (IS_ERR(udc->regs))
55862306a36Sopenharmony_ci		return PTR_ERR(udc->regs);
55962306a36Sopenharmony_ci
56062306a36Sopenharmony_ci	for (i = 0; i < DC_FIELD_MAX; i++) {
56162306a36Sopenharmony_ci		f = devm_regmap_field_alloc(dev, udc->regs, dc_reg_fields[i]);
56262306a36Sopenharmony_ci		if (IS_ERR(f))
56362306a36Sopenharmony_ci			return PTR_ERR(f);
56462306a36Sopenharmony_ci
56562306a36Sopenharmony_ci		udc->fields[i] = f;
56662306a36Sopenharmony_ci	}
56762306a36Sopenharmony_ci
56862306a36Sopenharmony_ci	if (hcd->is_isp1763)
56962306a36Sopenharmony_ci		hcd->memory_layout = &isp1763_memory_conf;
57062306a36Sopenharmony_ci	else
57162306a36Sopenharmony_ci		hcd->memory_layout = &isp176x_memory_conf;
57262306a36Sopenharmony_ci
57362306a36Sopenharmony_ci	ret = isp1760_init_core(isp);
57462306a36Sopenharmony_ci	if (ret < 0)
57562306a36Sopenharmony_ci		return ret;
57662306a36Sopenharmony_ci
57762306a36Sopenharmony_ci	if (IS_ENABLED(CONFIG_USB_ISP1760_HCD) && !usb_disabled()) {
57862306a36Sopenharmony_ci		ret = isp1760_hcd_register(hcd, mem, irq,
57962306a36Sopenharmony_ci					   irqflags | IRQF_SHARED, dev);
58062306a36Sopenharmony_ci		if (ret < 0)
58162306a36Sopenharmony_ci			return ret;
58262306a36Sopenharmony_ci	}
58362306a36Sopenharmony_ci
58462306a36Sopenharmony_ci	if (udc_enabled && IS_ENABLED(CONFIG_USB_ISP1761_UDC)) {
58562306a36Sopenharmony_ci		ret = isp1760_udc_register(isp, irq, irqflags);
58662306a36Sopenharmony_ci		if (ret < 0) {
58762306a36Sopenharmony_ci			isp1760_hcd_unregister(hcd);
58862306a36Sopenharmony_ci			return ret;
58962306a36Sopenharmony_ci		}
59062306a36Sopenharmony_ci	}
59162306a36Sopenharmony_ci
59262306a36Sopenharmony_ci	dev_set_drvdata(dev, isp);
59362306a36Sopenharmony_ci
59462306a36Sopenharmony_ci	return 0;
59562306a36Sopenharmony_ci}
59662306a36Sopenharmony_ci
59762306a36Sopenharmony_civoid isp1760_unregister(struct device *dev)
59862306a36Sopenharmony_ci{
59962306a36Sopenharmony_ci	struct isp1760_device *isp = dev_get_drvdata(dev);
60062306a36Sopenharmony_ci
60162306a36Sopenharmony_ci	isp1760_udc_unregister(isp);
60262306a36Sopenharmony_ci	isp1760_hcd_unregister(&isp->hcd);
60362306a36Sopenharmony_ci}
60462306a36Sopenharmony_ci
60562306a36Sopenharmony_ciMODULE_DESCRIPTION("Driver for the ISP1760 USB-controller from NXP");
60662306a36Sopenharmony_ciMODULE_AUTHOR("Sebastian Siewior <bigeasy@linuxtronix.de>");
60762306a36Sopenharmony_ciMODULE_LICENSE("GPL v2");
608