From dc4bcc93dd30e858538b708d9a178d00b9fb842a Mon Sep 17 00:00:00 2001 From: Aaron Brice Date: Tue, 26 May 2026 22:30:19 +0000 Subject: [PATCH 01/10] drivers: bus: Add nxp-fspi-bus NXP FlexSPI(FSPI) BUS controller driver. Signed-off-by: Aaron Brice --- drivers/bus/Kconfig | 7 + drivers/bus/Makefile | 1 + drivers/bus/nxp-fspi-bus.c | 664 +++++++++++++++++++++++++++++++++++++ 3 files changed, 672 insertions(+) create mode 100644 drivers/bus/nxp-fspi-bus.c diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig index 08c924dff5e7..46ca53d85d89 100644 --- a/drivers/bus/Kconfig +++ b/drivers/bus/Kconfig @@ -132,6 +132,13 @@ config MVEBU_MBUS Driver needed for the MBus configuration on Marvell EBU SoCs (Kirkwood, Dove, Orion5x, MV78XX0 and Armada 370/XP). +config NXP_FSPI_BUS + bool "NXP FSPI AHB Bus" + depends on ARCH_MXC || COMPILE_TEST + help + Driver for the NXP FlexSPI controller which provides a memory + mapped AHB bus. + config OMAP_INTERCONNECT tristate "OMAP INTERCONNECT DRIVER" depends on ARCH_OMAP2PLUS diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile index 12c76654df2a..74029602b503 100644 --- a/drivers/bus/Makefile +++ b/drivers/bus/Makefile @@ -20,6 +20,7 @@ obj-$(CONFIG_IMX_WEIM) += imx-weim.o obj-$(CONFIG_INTEL_IXP4XX_EB) += intel-ixp4xx-eb.o obj-$(CONFIG_MIPS_CDMM) += mips_cdmm.o obj-$(CONFIG_MVEBU_MBUS) += mvebu-mbus.o +obj-$(CONFIG_NXP_FSPI_BUS) += nxp-fspi-bus.o # Interconnect bus driver for OMAP SoCs. obj-$(CONFIG_OMAP_INTERCONNECT) += omap_l3_smx.o omap_l3_noc.o diff --git a/drivers/bus/nxp-fspi-bus.c b/drivers/bus/nxp-fspi-bus.c new file mode 100644 index 000000000000..fa3cb51fa547 --- /dev/null +++ b/drivers/bus/nxp-fspi-bus.c @@ -0,0 +1,664 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/* + * NXP FlexSPI(FSPI) BUS controller driver. + * + * This driver is written based on the spi-nxp-fspi.c, but instead of a SPI + * peripheral this FlexSPI core can be used as a memory mapped FPGA bus + * interface. + * + * This currently is hard coded to support memory mapped reads and writes to a + * single chip select: + * Read: + * [7:0] "0x9" (identifies ddr read) + * [15:0] address + * 8 dummy clocks + * [(8*n)-1:0] read data + * + * Write: + * [7:0] "0x8" (identifies write) + * [15:0] address + * [(8*n)-1:0] write data + * + * This driver is planned to attempt to upstream, in which case we should be able + * to refactor the flexspi driver to share common register definitions. This uses + * the existing defines from flexspi but adds ~4 definitions. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Registers used by the driver */ +#define FSPI_MCR0 0x00 +#define FSPI_MCR0_AHB_TIMEOUT(x) ((x) << 24) +#define FSPI_MCR0_IP_TIMEOUT(x) ((x) << 16) +#define FSPI_MCR0_LEARN_EN BIT(15) +#define FSPI_MCR0_SCRFRUN_EN BIT(14) +#define FSPI_MCR0_OCTCOMB_EN BIT(13) +#define FSPI_MCR0_DOZE_EN BIT(12) +#define FSPI_MCR0_HSEN BIT(11) +#define FSPI_MCR0_SERCLKDIV BIT(8) +#define FSPI_MCR0_ATDF_EN BIT(7) +#define FSPI_MCR0_ARDF_EN BIT(6) +#define FSPI_MCR0_RXCLKSRC(x) ((x) << 4) +#define FSPI_MCR0_END_CFG(x) ((x) << 2) +#define FSPI_MCR0_MDIS BIT(1) +#define FSPI_MCR0_SWRST BIT(0) + +#define FSPI_MCR1 0x04 +#define FSPI_MCR1_SEQ_TIMEOUT(x) ((x) << 16) +#define FSPI_MCR1_AHB_TIMEOUT(x) (x) + +#define FSPI_MCR2 0x08 +#define FSPI_MCR2_IDLE_WAIT(x) ((x) << 24) +#define FSPI_MCR2_SAMEDEVICEEN BIT(15) +#define FSPI_MCR2_CLRLRPHS BIT(14) +#define FSPI_MCR2_CLRAHBBUFOPT BIT(11) +#define FSPI_MCR2_ABRDATSZ BIT(8) +#define FSPI_MCR2_ABRLEARN BIT(7) +#define FSPI_MCR2_ABR_READ BIT(6) +#define FSPI_MCR2_ABRWRITE BIT(5) +#define FSPI_MCR2_ABRDUMMY BIT(4) +#define FSPI_MCR2_ABR_MODE BIT(3) +#define FSPI_MCR2_ABRCADDR BIT(2) +#define FSPI_MCR2_ABRRADDR BIT(1) +#define FSPI_MCR2_ABR_CMD BIT(0) + +#define FSPI_AHBCR 0x0c +#define FSPI_AHBCR_RDADDROPT BIT(6) +#define FSPI_AHBCR_PREF_EN BIT(5) +#define FSPI_AHBCR_BUFF_EN BIT(4) +#define FSPI_AHBCR_CACH_EN BIT(3) +#define FSPI_AHBCR_CLRTXBUF BIT(2) +#define FSPI_AHBCR_CLRRXBUF BIT(1) +#define FSPI_AHBCR_PAR_EN BIT(0) + +#define FSPI_INTEN 0x10 +#define FSPI_INTEN_SCLKSBWR BIT(9) +#define FSPI_INTEN_SCLKSBRD BIT(8) +#define FSPI_INTEN_DATALRNFL BIT(7) +#define FSPI_INTEN_IPTXWE BIT(6) +#define FSPI_INTEN_IPRXWA BIT(5) +#define FSPI_INTEN_AHBCMDERR BIT(4) +#define FSPI_INTEN_IPCMDERR BIT(3) +#define FSPI_INTEN_AHBCMDGE BIT(2) +#define FSPI_INTEN_IPCMDGE BIT(1) +#define FSPI_INTEN_IPCMDDONE BIT(0) + +#define FSPI_INTR 0x14 +#define FSPI_INTR_SCLKSBWR BIT(9) +#define FSPI_INTR_SCLKSBRD BIT(8) +#define FSPI_INTR_DATALRNFL BIT(7) +#define FSPI_INTR_IPTXWE BIT(6) +#define FSPI_INTR_IPRXWA BIT(5) +#define FSPI_INTR_AHBCMDERR BIT(4) +#define FSPI_INTR_IPCMDERR BIT(3) +#define FSPI_INTR_AHBCMDGE BIT(2) +#define FSPI_INTR_IPCMDGE BIT(1) +#define FSPI_INTR_IPCMDDONE BIT(0) + +#define FSPI_LUTKEY 0x18 +#define FSPI_LUTKEY_VALUE 0x5AF05AF0 + +#define FSPI_LCKCR 0x1C + +#define FSPI_LCKER_LOCK 0x1 +#define FSPI_LCKER_UNLOCK 0x2 + +#define FSPI_BUFXCR_INVALID_MSTRID 0xE +#define FSPI_AHBRX_BUF0CR0 0x20 +#define FSPI_AHBRX_BUF1CR0 0x24 +#define FSPI_AHBRX_BUF2CR0 0x28 +#define FSPI_AHBRX_BUF3CR0 0x2C +#define FSPI_AHBRX_BUF4CR0 0x30 +#define FSPI_AHBRX_BUF5CR0 0x34 +#define FSPI_AHBRX_BUF6CR0 0x38 +#define FSPI_AHBRX_BUF7CR0 0x3C +#define FSPI_AHBRXBUF0CR7_MSTRID(x) (((u32)(x) << 16)) +#define FSPI_AHBRXBUF0CR7_BUFSZ(x) (((u32)(x) << 0)) +#define FSPI_AHBRXBUF0CR7_PREF BIT(31) + +#define FSPI_AHBRX_BUF0CR1 0x40 +#define FSPI_AHBRX_BUF1CR1 0x44 +#define FSPI_AHBRX_BUF2CR1 0x48 +#define FSPI_AHBRX_BUF3CR1 0x4C +#define FSPI_AHBRX_BUF4CR1 0x50 +#define FSPI_AHBRX_BUF5CR1 0x54 +#define FSPI_AHBRX_BUF6CR1 0x58 +#define FSPI_AHBRX_BUF7CR1 0x5C + +#define FSPI_FLSHA1CR0 0x60 +#define FSPI_FLSHA2CR0 0x64 +#define FSPI_FLSHB1CR0 0x68 +#define FSPI_FLSHB2CR0 0x6C +#define FSPI_FLSHXCR0_SZ_KB 10 +#define FSPI_FLSHXCR0_SZ(x) ((x) >> FSPI_FLSHXCR0_SZ_KB) + +#define FSPI_FLSHA1CR1 0x70 +#define FSPI_FLSHA2CR1 0x74 +#define FSPI_FLSHB1CR1 0x78 +#define FSPI_FLSHB2CR1 0x7C +#define FSPI_FLSHXCR1_CSINTR(x) ((x) << 16) +#define FSPI_FLSHXCR1_CAS(x) ((x) << 11) +#define FSPI_FLSHXCR1_WA BIT(10) +#define FSPI_FLSHXCR1_TCSH(x) ((x) << 5) +#define FSPI_FLSHXCR1_TCSS(x) (x) + +#define FSPI_FLSHA1CR2 0x80 +#define FSPI_FLSHA2CR2 0x84 +#define FSPI_FLSHB1CR2 0x88 +#define FSPI_FLSHB2CR2 0x8C +#define FSPI_FLSHXCR2_CLRINSP BIT(24) +#define FSPI_FLSHXCR2_AWRWAIT BIT(16) +#define FSPI_FLSHXCR2_AWRSEQN_SHIFT 13 +#define FSPI_FLSHXCR2_AWRSEQI_SHIFT 8 +#define FSPI_FLSHXCR2_ARDSEQN_SHIFT 5 +#define FSPI_FLSHXCR2_ARDSEQI_SHIFT 0 + +#define FSPI_FLSHACR4 0x94 + +#define FSPI_IPCR0 0xA0 + +#define FSPI_IPCR1 0xA4 +#define FSPI_IPCR1_IPAREN BIT(31) +#define FSPI_IPCR1_SEQNUM_SHIFT 24 +#define FSPI_IPCR1_SEQID_SHIFT 16 +#define FSPI_IPCR1_IDATSZ(x) (x) + +#define FSPI_IPCMD 0xB0 +#define FSPI_IPCMD_TRG BIT(0) + +#define FSPI_DLPR 0xB4 + +#define FSPI_IPRXFCR 0xB8 +#define FSPI_IPRXFCR_CLR BIT(0) +#define FSPI_IPRXFCR_DMA_EN BIT(1) +#define FSPI_IPRXFCR_WMRK(x) ((x) << 2) + +#define FSPI_IPTXFCR 0xBC +#define FSPI_IPTXFCR_CLR BIT(0) +#define FSPI_IPTXFCR_DMA_EN BIT(1) +#define FSPI_IPTXFCR_WMRK(x) ((x) << 2) + +#define FSPI_DLLACR 0xC0 +#define FSPI_DLLACR_OVRDEN BIT(8) +#define FSPI_DLLACR_SLVDLY(x) ((x) << 3) +#define FSPI_DLLACR_DLLRESET BIT(1) +#define FSPI_DLLACR_DLLEN BIT(0) + +#define FSPI_DLLBCR 0xC4 +#define FSPI_DLLBCR_OVRDEN BIT(8) +#define FSPI_DLLBCR_SLVDLY(x) ((x) << 3) +#define FSPI_DLLBCR_DLLRESET BIT(1) +#define FSPI_DLLBCR_DLLEN BIT(0) + +#define FSPI_STS0 0xE0 +#define FSPI_STS0_DLPHB(x) ((x) << 8) +#define FSPI_STS0_DLPHA(x) ((x) << 4) +#define FSPI_STS0_CMD_SRC(x) ((x) << 2) +#define FSPI_STS0_ARB_IDLE BIT(1) +#define FSPI_STS0_SEQ_IDLE BIT(0) + +#define FSPI_STS1 0xE4 +#define FSPI_STS1_IP_ERRCD(x) ((x) << 24) +#define FSPI_STS1_IP_ERRID(x) ((x) << 16) +#define FSPI_STS1_AHB_ERRCD(x) ((x) << 8) +#define FSPI_STS1_AHB_ERRID(x) (x) + +#define FSPI_STS2 0xE8 +#define FSPI_STS2_BREFLOCK BIT(17) +#define FSPI_STS2_BSLVLOCK BIT(16) +#define FSPI_STS2_AREFLOCK BIT(1) +#define FSPI_STS2_ASLVLOCK BIT(0) +#define FSPI_STS2_AB_LOCK (FSPI_STS2_BREFLOCK | \ + FSPI_STS2_BSLVLOCK | \ + FSPI_STS2_AREFLOCK | \ + FSPI_STS2_ASLVLOCK) + +#define FSPI_AHBSPNST 0xEC +#define FSPI_AHBSPNST_DATLFT(x) ((x) << 16) +#define FSPI_AHBSPNST_BUFID(x) ((x) << 1) +#define FSPI_AHBSPNST_ACTIVE BIT(0) + +#define FSPI_IPRXFSTS 0xF0 +#define FSPI_IPRXFSTS_RDCNTR(x) ((x) << 16) +#define FSPI_IPRXFSTS_FILL(x) (x) + +#define FSPI_IPTXFSTS 0xF4 +#define FSPI_IPTXFSTS_WRCNTR(x) ((x) << 16) +#define FSPI_IPTXFSTS_FILL(x) (x) + +#define FSPI_RFDR 0x100 +#define FSPI_TFDR 0x180 + +#define FSPI_LUT_BASE 0x200 + +/* register map end */ + +/* Instruction set for the LUT register. */ +#define LUT_STOP 0x00 +#define LUT_CMD 0x01 +#define LUT_ADDR 0x02 +#define LUT_CADDR_SDR 0x03 +#define LUT_MODE 0x04 +#define LUT_MODE2 0x05 +#define LUT_MODE4 0x06 +#define LUT_MODE8 0x07 +#define LUT_NXP_WRITE 0x08 +#define LUT_NXP_READ 0x09 +#define LUT_LEARN_SDR 0x0A +#define LUT_DATSZ_SDR 0x0B +#define LUT_DUMMY 0x0C +#define LUT_DUMMY_RWDS_SDR 0x0D +#define LUT_JMP_ON_CS 0x1F +#define LUT_CMD_DDR 0x21 +#define LUT_ADDR_DDR 0x22 +#define LUT_CADDR_DDR 0x23 +#define LUT_MODE_DDR 0x24 +#define LUT_MODE2_DDR 0x25 +#define LUT_MODE4_DDR 0x26 +#define LUT_MODE8_DDR 0x27 +#define LUT_WRITE_DDR 0x28 +#define LUT_READ_DDR 0x29 +#define LUT_LEARN_DDR 0x2A +#define LUT_DATSZ_DDR 0x2B +#define LUT_DUMMY_DDR 0x2C +#define LUT_DUMMY_RWDS_DDR 0x2D + +/* + * Calculate number of required PAD bits for LUT register. + * + * The pad stands for the number of IO lines [0:7]. + * For example, the octal read needs eight IO lines, + * so you should use LUT_PAD(8). This macro + * returns 3 i.e. use eight (2^3) IP lines for read. + */ +#define LUT_PAD(x) (fls(x) - 1) + +/* + * Macro for constructing the LUT entries with the following + * register layout: + * + * --------------------------------------------------- + * | INSTR1 | PAD1 | OPRND1 | INSTR0 | PAD0 | OPRND0 | + * --------------------------------------------------- + */ +#define PAD_SHIFT 8 +#define INSTR_SHIFT 10 +#define OPRND_SHIFT 16 + +/* Macros for constructing the LUT register. */ +#define LUT_DEF(idx, ins, pad, opr) \ + ((((ins) << INSTR_SHIFT) | ((pad) << PAD_SHIFT) | \ + (opr)) << (((idx) % 2) * OPRND_SHIFT)) + +#define POLL_TOUT 5000 +#define NXP_FSPI_MAX_CHIPSELECT 4 +#define NXP_FSPI_MIN_IOMAP SZ_4M + +#define DCFG_RCWSR1 0x100 +#define SYS_PLL_RAT GENMASK(6, 2) + +struct nxp_fspi { + void __iomem *iobase; + struct clk *clk, *clk_en; + struct device *dev; + int clk_rate; +}; + +static void fspi_writel(struct nxp_fspi *f, u32 val, void __iomem *addr) +{ + iowrite32(val, addr); +} + +static u32 fspi_readl(struct nxp_fspi *f, void __iomem *addr) +{ + return ioread32(addr); +} + +/* Instead of busy looping invoke readl_poll_timeout functionality. */ +static int fspi_readl_poll_tout(struct nxp_fspi *f, void __iomem *base, + u32 mask, u32 delay_us, + u32 timeout_us, bool c) +{ + u32 reg; + + if (c) + return readl_poll_timeout(base, reg, (reg & mask), + delay_us, timeout_us); + else + return readl_poll_timeout(base, reg, !(reg & mask), + delay_us, timeout_us); +} + +static int nxp_fspi_clk_prep_enable(struct nxp_fspi *f) +{ + int ret; + + ret = clk_prepare_enable(f->clk_en); + if (ret) + return ret; + + ret = clk_prepare_enable(f->clk); + if (ret) { + clk_disable_unprepare(f->clk_en); + return ret; + } + + return 0; +} + +static void nxp_fspi_clk_disable_unprep(struct nxp_fspi *f) +{ + clk_disable_unprepare(f->clk); + clk_disable_unprepare(f->clk_en); +} + +static int nxp_fspi_ahb_bus_setup(struct nxp_fspi *f) +{ + const int cs = 0; + const int pads = 4; + void __iomem *base = f->iobase; + uint64_t size_kb; + u32 seq0[4] = {0, 0, 0, 0}; + u32 seq1[4] = {0, 0, 0, 0}; + u32 reg, mcr0; + int ret; + int i; + + ret = clk_set_rate(f->clk, f->clk_rate); + if (ret) + return ret; + + ret = nxp_fspi_clk_prep_enable(f); + if (ret) + return ret; + + /* Reset the module */ + /* w1c register, wait unit clear */ + ret = fspi_readl_poll_tout(f, f->iobase + FSPI_MCR0, + FSPI_MCR0_SWRST, 0, POLL_TOUT, false); + WARN_ON(ret); + + /* Disable the module */ + fspi_writel(f, FSPI_MCR0_MDIS, base + FSPI_MCR0); + + /* + * Config the DLL register to default value, enable the target clock delay + * line delay cell override mode, and use 1 fixed delay cell in DLL delay + * chain, this is the suggested setting when clock rate < 100MHz. + */ + fspi_writel(f, FSPI_DLLACR_OVRDEN, base + FSPI_DLLACR); + fspi_writel(f, FSPI_DLLBCR_OVRDEN, base + FSPI_DLLBCR); + + /* + * Disable same device enable bit and configure all target devices + * independently. + */ + reg = fspi_readl(f, f->iobase + FSPI_MCR2); + reg = reg & ~(FSPI_MCR2_SAMEDEVICEEN); + fspi_writel(f, reg, base + FSPI_MCR2); + + /* AHB configuration for access buffer 0~7. */ + for (i = 0; i < 7; i++) + fspi_writel(f, 0, base + FSPI_AHBRX_BUF0CR0 + 4 * i); + + /* + * Set ADATSZ with the maximum AHB buffer size to improve the read + * performance. + */ + fspi_writel(f, (SZ_2K / 8 | FSPI_AHBRXBUF0CR7_PREF), + base + FSPI_AHBRX_BUF7CR0); + + /* prefetch and no start address alignment limitation */ + fspi_writel(f, FSPI_AHBCR_PREF_EN | FSPI_AHBCR_RDADDROPT, + base + FSPI_AHBCR); + + /* Reset the FLSHxCR1 registers. */ + reg = FSPI_FLSHXCR1_TCSH(0x3) | FSPI_FLSHXCR1_TCSS(0x3); + fspi_writel(f, reg, base + FSPI_FLSHA1CR1); + fspi_writel(f, reg, base + FSPI_FLSHA2CR1); + fspi_writel(f, reg, base + FSPI_FLSHB1CR1); + fspi_writel(f, reg, base + FSPI_FLSHB2CR1); + + /* + * The driver only uses one single LUT entry, that is updated on + * each call of exec_op(). Index 0 is preset at boot with a basic + * read operation, so let's use the last entry. + */ + /* AHB Read - Set lut sequence ID for all CS. */ + fspi_writel(f, 31, base + FSPI_FLSHA1CR2); + fspi_writel(f, 31, base + FSPI_FLSHA2CR2); + fspi_writel(f, 31, base + FSPI_FLSHB1CR2); + fspi_writel(f, 31, base + FSPI_FLSHB2CR2); + + /* Setup MCR0 config */ + mcr0 = (u32)(FSPI_MCR0_RXCLKSRC(0x0) | + FSPI_MCR0_DOZE_EN | + FSPI_MCR0_SCRFRUN_EN | + FSPI_MCR0_IP_TIMEOUT(0xFF) | + FSPI_MCR0_AHB_TIMEOUT(0xFF)); + + fspi_writel(f, mcr0, base + FSPI_MCR0); + + /* Setup MCR1 config */ + reg = FSPI_MCR1_SEQ_TIMEOUT(0xFFFF) | + FSPI_MCR1_AHB_TIMEOUT(0xFFFF); + fspi_writel(f, reg, base + FSPI_MCR1); + + /* Setup MCR2 config */ + reg = FSPI_MCR2_IDLE_WAIT(20) | + FSPI_MCR2_CLRAHBBUFOPT; + fspi_writel(f, reg, base + FSPI_MCR2); + + /* Setup AHB config */ + reg = FSPI_AHBCR_BUFF_EN; + fspi_writel(f, reg, base + FSPI_AHBCR); + + /* Set up ahb buffers */ + reg = FSPI_AHBRXBUF0CR7_MSTRID(FSPI_BUFXCR_INVALID_MSTRID); + fspi_writel(f, reg, base + FSPI_AHBRX_BUF0CR0); + fspi_writel(f, reg, base + FSPI_AHBRX_BUF1CR0); + fspi_writel(f, reg, base + FSPI_AHBRX_BUF2CR0); + fspi_writel(f, reg, base + FSPI_AHBRX_BUF3CR0); + fspi_writel(f, reg, base + FSPI_AHBRX_BUF4CR0); + fspi_writel(f, reg, base + FSPI_AHBRX_BUF5CR0); + fspi_writel(f, reg, base + FSPI_AHBRX_BUF6CR0); + + reg = FSPI_AHBRXBUF0CR7_BUFSZ(1);// in units of 64-bits // Max burst size is 32-bytes + fspi_writel(f, 0, base + FSPI_AHBRX_BUF7CR0); + + /* Reset FLSHxxCR0 registers */ + fspi_writel(f, 0, f->iobase + FSPI_FLSHA1CR0); + fspi_writel(f, 0, f->iobase + FSPI_FLSHA2CR0); + fspi_writel(f, 0, f->iobase + FSPI_FLSHB1CR0); + fspi_writel(f, 0, f->iobase + FSPI_FLSHB2CR0); + + /* Assign controller memory mapped space as size, KBytes, of flash. */ + size_kb = FSPI_FLSHXCR0_SZ(0x10000000); + + fspi_writel(f, size_kb, f->iobase + FSPI_FLSHA1CR0 + 4 * cs); + + /* Set bus parameters */ + reg = FSPI_FLSHXCR1_CSINTR(2) | /* 2 is minimum */ + FSPI_FLSHXCR1_TCSH(0) | + FSPI_FLSHXCR1_TCSS(0); + fspi_writel(f, reg, base + FSPI_FLSHA1CR1); + fspi_writel(f, reg, base + FSPI_FLSHA2CR1); + fspi_writel(f, reg, base + FSPI_FLSHB1CR1); + fspi_writel(f, reg, base + FSPI_FLSHB2CR1); + + reg = fspi_readl(f, base + FSPI_FLSHA1CR2) & 0xffff0000; + reg |= (0 << FSPI_FLSHXCR2_AWRSEQN_SHIFT) | + (1 << FSPI_FLSHXCR2_AWRSEQI_SHIFT) | + (0 << FSPI_FLSHXCR2_ARDSEQI_SHIFT) | + (0 << FSPI_FLSHXCR2_ARDSEQN_SHIFT); + fspi_writel(f, reg, base + FSPI_FLSHA1CR2); + + reg = 0x1; + fspi_writel(f, reg, base + FSPI_FLSHACR4); + + /* Magic number, finish testing and see what we need here*/ + fspi_writel(f, FSPI_DLLACR_DLLEN | FSPI_DLLACR_SLVDLY(0x37), + f->iobase + FSPI_DLLACR); + + /* + * LUT Sequence 0 is an SDR Read. + */ + seq0[0] = LUT_DEF(0, LUT_CMD, LUT_PAD(pads), LUT_NXP_READ) | + LUT_DEF(1, LUT_ADDR, LUT_PAD(pads), 16); + seq0[1] = LUT_DEF(2, LUT_DUMMY, LUT_PAD(pads), 8) | + LUT_DEF(3, LUT_NXP_READ, LUT_PAD(pads), 0); + seq0[2] = LUT_DEF(4, LUT_STOP, 0, 0); + + /* + * LUT Sequence 1 is a SDR Write + */ + seq1[0] = LUT_DEF(0, LUT_CMD, LUT_PAD(pads), LUT_NXP_WRITE) | + LUT_DEF(1, LUT_ADDR, LUT_PAD(pads), 16); + seq1[1] = LUT_DEF(2, LUT_NXP_WRITE, LUT_PAD(pads), 0) | + LUT_DEF(3, LUT_STOP, 0, 0); + + /* unlock LUT */ + fspi_writel(f, FSPI_LUTKEY_VALUE, f->iobase + FSPI_LUTKEY); + fspi_writel(f, FSPI_LCKER_UNLOCK, f->iobase + FSPI_LCKCR); + + /* configure read lut */ + for (i = 0; i < ARRAY_SIZE(seq0); i++) + fspi_writel(f, seq0[i], base + FSPI_LUT_BASE + (i*4)); + + /* configure write lut */ + for (i = 0; i < ARRAY_SIZE(seq1); i++) + fspi_writel(f, seq1[i], base + FSPI_LUT_BASE + 0x10 + (i*4)); + + /* lock LUT */ + fspi_writel(f, FSPI_LUTKEY_VALUE, f->iobase + FSPI_LUTKEY); + fspi_writel(f, FSPI_LCKER_LOCK, f->iobase + FSPI_LCKCR); + + /* Deassert disable */ + fspi_writel(f, mcr0, base + FSPI_MCR0); + + /* Wait for controller being ready. */ + ret = fspi_readl_poll_tout(f, f->iobase + FSPI_STS0, + FSPI_STS0_ARB_IDLE, 1, POLL_TOUT, true); + if (ret) + return ret; + + return 0; +} + +static void nxp_fspi_cleanup(void *data) +{ + struct nxp_fspi *f = data; + int ret; + + /* enable clock first since there is reigster access */ + ret = pm_runtime_get_sync(f->dev); + if (ret < 0) + dev_err(f->dev, "Failed to enable clock %d\n", __LINE__); + + /* disable the hardware */ + fspi_writel(f, FSPI_MCR0_MDIS, f->iobase + FSPI_MCR0); + + nxp_fspi_clk_disable_unprep(f); +} + +static int nxp_fspi_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct nxp_fspi *f; + int ret; + + f = devm_kzalloc(dev, sizeof(*f), GFP_KERNEL); + if (!f) + return -ENOMEM; + + f->dev = dev; + platform_set_drvdata(pdev, f); + + f->iobase = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(f->iobase)) { + ret = PTR_ERR(f->iobase); + return ret; + } + + /* find the clocks */ + if (dev_of_node(&pdev->dev)) { + f->clk_en = devm_clk_get(dev, "fspi_en"); + if (IS_ERR(f->clk_en)) { + ret = PTR_ERR(f->clk_en); + return ret; + } + + f->clk = devm_clk_get(dev, "fspi"); + if (IS_ERR(f->clk)) { + ret = PTR_ERR(f->clk); + return ret; + } + } + + ret = of_property_read_u32(np, "clock-frequency", &f->clk_rate); + if (ret) + return ret; + pm_runtime_enable(dev); + + /* enable clock */ + ret = pm_runtime_get_sync(f->dev); + if (ret < 0) { + dev_err(f->dev, "Failed to enable clock %d\n", __LINE__); + return ret; + } + + ret = nxp_fspi_ahb_bus_setup(f); + if (ret) + return ret; + + ret = devm_add_action_or_reset(dev, nxp_fspi_cleanup, f); + if (ret) + return ret; + + + return of_platform_default_populate(np, NULL, NULL); +} + +static const struct of_device_id nxp_fspi_dt_ids[] = { + { .compatible = "nxp,imx93-fspi-bus", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, nxp_fspi_dt_ids); + +static struct platform_driver nxp_fspi_driver = { + .driver = { + .name = "nxp-fspi-bus", + .of_match_table = nxp_fspi_dt_ids, + }, + .probe = nxp_fspi_probe, +}; +module_platform_driver(nxp_fspi_driver); + +MODULE_DESCRIPTION("NXP FSPI BUS Driver"); +MODULE_AUTHOR("embeddedTS"); +MODULE_LICENSE("GPL"); From e1c8b56f962d9c2d31c8ed9ae67fb32a03b2dc45 Mon Sep 17 00:00:00 2001 From: Aaron Brice Date: Tue, 26 May 2026 22:44:10 +0000 Subject: [PATCH 02/10] drivers: irqchip: Add irq-ts9370 Support for FPGA IRQ controller on TS-9370 board. Signed-off-by: Aaron Brice --- drivers/irqchip/Kconfig | 7 ++ drivers/irqchip/Makefile | 1 + drivers/irqchip/irq-ts9370.c | 174 +++++++++++++++++++++++++++++++++++ 3 files changed, 182 insertions(+) create mode 100644 drivers/irqchip/irq-ts9370.c diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index 7a93d99fb02b..d70ea51bf057 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -345,6 +345,13 @@ config TS4800_IRQ help Support for the TS-4800 FPGA IRQ controller +config TS9370_IRQ + tristate "TS-9370 IRQ controller" + select IRQ_DOMAIN + depends on HAS_IOMEM + help + Support for the TS-9370 FPGA IRQ controller + config TSWEIM_FPGA_INTC tristate "TS-71XX WEIM FPGA IRQ Support" default n diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index 077d2d8af7f3..5d0ec5c09f23 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile @@ -62,6 +62,7 @@ obj-$(CONFIG_ARCH_VT8500) += irq-vt8500.o obj-$(CONFIG_ST_IRQCHIP) += irq-st.o obj-$(CONFIG_TB10X_IRQC) += irq-tb10x.o obj-$(CONFIG_TS4800_IRQ) += irq-ts4800.o +obj-$(CONFIG_TS9370_IRQ) += irq-ts9370.o obj-$(CONFIG_TSWEIM_FPGA_INTC) += irq-ts71xxweim.o obj-$(CONFIG_XTENSA) += irq-xtensa-pic.o obj-$(CONFIG_XTENSA_MX) += irq-xtensa-mx.o diff --git a/drivers/irqchip/irq-ts9370.c b/drivers/irqchip/irq-ts9370.c new file mode 100644 index 000000000000..0885ce29afa8 --- /dev/null +++ b/drivers/irqchip/irq-ts9370.c @@ -0,0 +1,174 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2025 - Technologic Systems, DBA embeddedTS + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define IRQ_STATUS 0x0 +#define IRQ_MASK_SET 0x4 +#define IRQ_MASK_CLR 0x8 + +struct ts9370_irq_data { + struct regmap *regmap; + struct device *dev; + struct irq_domain *domain; + raw_spinlock_t lock; + int irq; +}; + +static void ts9370_irq_mask(struct irq_data *d) +{ + struct ts9370_irq_data *data = irq_data_get_irq_chip_data(d); + u32 reg = BIT(d->hwirq); + + regmap_write(data->regmap, IRQ_MASK_SET, reg); +} + +static void ts9370_irq_unmask(struct irq_data *d) +{ + struct ts9370_irq_data *data = irq_data_get_irq_chip_data(d); + u32 reg = BIT(d->hwirq); + + regmap_write(data->regmap, IRQ_MASK_CLR, reg); +} + +static const struct irq_chip ts9370_chip = { + .irq_mask = ts9370_irq_mask, + .irq_unmask = ts9370_irq_unmask, +}; + +static int ts9370_irqdomain_map(struct irq_domain *d, unsigned int irq, + irq_hw_number_t hwirq) +{ + struct ts9370_irq_data *data = d->host_data; + + irq_set_chip_and_handler(irq, &ts9370_chip, handle_level_irq); + irq_set_chip_data(irq, data); + irq_set_noprobe(irq); + + return 0; +} + +static const struct irq_domain_ops ts9370_ic_ops = { + .map = ts9370_irqdomain_map, + .xlate = irq_domain_xlate_onecell, +}; + +static irqreturn_t ts9370_irq_handler(int irq, void *priv) +{ + struct ts9370_irq_data *data = (struct ts9370_irq_data *)priv; + unsigned long lock_flags; + unsigned long status; + int i; + + regmap_read(data->regmap, IRQ_STATUS, (u32 *)&status); + + for_each_set_bit(i, &status, 32) { + raw_spin_lock_irqsave(&data->lock, lock_flags); + generic_handle_domain_irq(data->domain, i); + raw_spin_unlock_irqrestore(&data->lock, + lock_flags); + } + + return IRQ_HANDLED; +} + +static int ts9370_ic_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *node = dev->of_node; + struct ts9370_irq_data *data; + const struct regmap_config regmap_cfg = { + .reg_bits = 32, + .val_bits = 32, + }; + void __iomem *base; + int ret = 0; + + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->dev = dev; + + base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(base)) + return PTR_ERR(base); + + data->regmap = devm_regmap_init_mmio(dev, base, ®map_cfg); + if (IS_ERR(data->regmap)) { + dev_err(dev, "failed to initialize regmap\n"); + return PTR_ERR(data->regmap); + } + + /* Disable all interrupts initially */ + regmap_write(data->regmap, IRQ_MASK_SET, 0xffffffff); + + raw_spin_lock_init(&data->lock); + platform_set_drvdata(pdev, data); + + data->irq = platform_get_irq(pdev, 0); + if (data->irq < 0) + return data->irq; + + data->domain = irq_domain_add_linear(node, 32, &ts9370_ic_ops, data); + if (!data->domain) { + dev_err(dev, "cannot add IRQ domain\n"); + return -ENOMEM; + } + + ret = request_irq(data->irq, ts9370_irq_handler, + 0, dev_name(dev), data); + if (ret) + goto out_domain_remove; + + return 0; + +out_domain_remove: + irq_domain_remove(data->domain); + irq_dispose_mapping(data->irq); + + return ret; +} + +static void ts9370_ic_remove(struct platform_device *pdev) +{ + struct ts9370_irq_data *data = platform_get_drvdata(pdev); + + irq_domain_remove(data->domain); +} + +static const struct of_device_id ts9370_ic_of_match[] = { + { .compatible = "technologic,ts9370-irqc", }, + {}, +}; +MODULE_DEVICE_TABLE(of, ts9370_ic_of_match); + +static struct platform_driver ts9370_ic_driver = { + .probe = ts9370_ic_probe, + .remove = ts9370_ic_remove, + .driver = { + .name = "ts9370-irqc", + .of_match_table = ts9370_ic_of_match, + }, +}; +module_platform_driver(ts9370_ic_driver); + +MODULE_AUTHOR("Mark Featherston "); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:ts9370_irqc"); From 1139199388e04696be4483f578bd51bbd962b489 Mon Sep 17 00:00:00 2001 From: Aaron Brice Date: Tue, 26 May 2026 22:47:43 +0000 Subject: [PATCH 03/10] drivers: pinctrl: Adding technologic pinctrl Adding pinctrl drivers for ts9370 and tsxbar. Signed-off-by: Aaron Brice --- drivers/pinctrl/Kconfig | 1 + drivers/pinctrl/technologic/Kconfig | 16 + drivers/pinctrl/technologic/Makefile | 5 + drivers/pinctrl/technologic/pinctrl-ts9370.c | 145 +++++++ drivers/pinctrl/technologic/pinctrl-tsxbar.c | 388 +++++++++++++++++++ drivers/pinctrl/technologic/pinctrl-tsxbar.h | 49 +++ 6 files changed, 604 insertions(+) create mode 100644 drivers/pinctrl/technologic/Kconfig create mode 100644 drivers/pinctrl/technologic/Makefile create mode 100644 drivers/pinctrl/technologic/pinctrl-ts9370.c create mode 100644 drivers/pinctrl/technologic/pinctrl-tsxbar.c create mode 100644 drivers/pinctrl/technologic/pinctrl-tsxbar.h diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 4f8507ebbdac..35eb6e4c4b49 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -707,6 +707,7 @@ source "drivers/pinctrl/starfive/Kconfig" source "drivers/pinctrl/stm32/Kconfig" source "drivers/pinctrl/sunplus/Kconfig" source "drivers/pinctrl/sunxi/Kconfig" +source "drivers/pinctrl/technologic/Kconfig" source "drivers/pinctrl/tegra/Kconfig" source "drivers/pinctrl/ti/Kconfig" source "drivers/pinctrl/uniphier/Kconfig" diff --git a/drivers/pinctrl/technologic/Kconfig b/drivers/pinctrl/technologic/Kconfig new file mode 100644 index 000000000000..b37bd8009a90 --- /dev/null +++ b/drivers/pinctrl/technologic/Kconfig @@ -0,0 +1,16 @@ +# SPDX-License-Identifier: GPL-2.0-only +config PINCTRL_TSXBAR + tristate + depends on OF + depends on ARCH_MXC + select GENERIC_PINCTRL_GROUPS + select GENERIC_PINMUX_FUNCTIONS + select PINCONF + select REGMAP + +config PINCTRL_TS9370 + tristate "TS-9370 pinctrl driver" + depends on ARCH_MXC + select PINCTRL_TSXBAR + help + Say Y here to enable the TS-9370 pinctrl driver diff --git a/drivers/pinctrl/technologic/Makefile b/drivers/pinctrl/technologic/Makefile new file mode 100644 index 000000000000..b5e0d7a8063a --- /dev/null +++ b/drivers/pinctrl/technologic/Makefile @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0 +# VIA/Wondermedia pinctrl support + +obj-$(CONFIG_PINCTRL_TSXBAR) += pinctrl-tsxbar.o +obj-$(CONFIG_PINCTRL_TS9370) += pinctrl-ts9370.o diff --git a/drivers/pinctrl/technologic/pinctrl-ts9370.c b/drivers/pinctrl/technologic/pinctrl-ts9370.c new file mode 100644 index 000000000000..a8ca4cc46a90 --- /dev/null +++ b/drivers/pinctrl/technologic/pinctrl-ts9370.c @@ -0,0 +1,145 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include +#include +#include +#include +#include + +#include "pinctrl-tsxbar.h" + +static const struct tsxbar_desc_group ts9370_pinctrl_groups[] = { + TSXBAR_PINCTRL_GROUP("BT_RXD", 0x000, + TSXBAR_PINCTRL_FUNCTION("UART6_TXD", 0x1, 0x000, 0x0)), + TSXBAR_PINCTRL_GROUP("BT_CTS", 0x003, + TSXBAR_PINCTRL_FUNCTION("UART6_RTS", 0x1, 0x000, 0x0)), + TSXBAR_PINCTRL_GROUP("DP_19P2MHZ_CLK", 0x004, + TSXBAR_PINCTRL_FUNCTION("DC_1", 0x1, 0x010, 0x1)), + TSXBAR_PINCTRL_GROUP("MIKRO_TXD", 0x006, + TSXBAR_PINCTRL_FUNCTION("GPIO0_IO14", 0x0, 0x000, 0x0), + TSXBAR_PINCTRL_FUNCTION("UART8_TXD", 0x1, 0x000, 0x0)), + TSXBAR_PINCTRL_GROUP("MIKRO_RXD", 0x007, + TSXBAR_PINCTRL_FUNCTION("GPIO0_IO15", 0x0, 0x000, 0x0)), + TSXBAR_PINCTRL_GROUP("MIKRO_SPI_CLK", 0x008, + TSXBAR_PINCTRL_FUNCTION("GPIO0_IO16", 0x0, 0x000, 0x0), + TSXBAR_PINCTRL_FUNCTION("LPSPI4_CLK", 0x1, 0x000, 0x0)), + TSXBAR_PINCTRL_GROUP("MIKRO_SPI_CS#", 0x009, + TSXBAR_PINCTRL_FUNCTION("GPIO0_IO17", 0x0, 0x000, 0x0), + TSXBAR_PINCTRL_FUNCTION("lpspi4_cs_mux_1", 0x1, 0x000, 0x0)), + TSXBAR_PINCTRL_GROUP("MIKRO_SPI_MISO", 0x00A, + TSXBAR_PINCTRL_FUNCTION("GPIO0_IO18", 0x0, 0x000, 0x0)), + TSXBAR_PINCTRL_GROUP("MIKRO_SPI_MOSI", 0x00B, + TSXBAR_PINCTRL_FUNCTION("GPIO0_IO19", 0x0, 0x000, 0x0), + TSXBAR_PINCTRL_FUNCTION("LPSPI4_MOSI", 0x1, 0x000, 0x0)), + TSXBAR_PINCTRL_GROUP("MIKRO_RESET#", 0x00C, + TSXBAR_PINCTRL_FUNCTION("GPIO0_IO20", 0x0, 0x000, 0x0)), + TSXBAR_PINCTRL_GROUP("MIKRO_AN", 0x00D, + TSXBAR_PINCTRL_FUNCTION("GPIO0_IO21", 0x0, 0x000, 0x0)), + TSXBAR_PINCTRL_GROUP("MIKRO_PWM", 0x00E, + TSXBAR_PINCTRL_FUNCTION("GPIO0_IO22", 0x0, 0x000, 0x0), + TSXBAR_PINCTRL_FUNCTION("PWM0_OUT", 0x1, 0x000, 0x0)), + TSXBAR_PINCTRL_GROUP("MIKRO_INT", 0x00F, + TSXBAR_PINCTRL_FUNCTION("GPIO0_IO23", 0x0, 0x000, 0x0)), + TSXBAR_PINCTRL_GROUP("DC_1", 0x010, + TSXBAR_PINCTRL_FUNCTION("GPIO2_IO27", 0x0, 0x000, 0x0), + TSXBAR_PINCTRL_FUNCTION("UART7_TX", 0x1, 0x000, 0x0), + TSXBAR_PINCTRL_FUNCTION("LPSPI4_CLK", 0x2, 0x000, 0x0)), + TSXBAR_PINCTRL_GROUP("DC_3", 0x011, + TSXBAR_PINCTRL_FUNCTION("GPIO2_IO28", 0x0, 0x000, 0x0)), + TSXBAR_PINCTRL_GROUP("DC_5", 0x012, + TSXBAR_PINCTRL_FUNCTION("GPIO2_IO29", 0x0, 0x000, 0x0), + TSXBAR_PINCTRL_FUNCTION("UART7_RTS", 0x1, 0x000, 0x0), + TSXBAR_PINCTRL_FUNCTION("LPSPI4_MOSI", 0x2, 0x000, 0x0)), + TSXBAR_PINCTRL_GROUP("DC_7", 0x013, + TSXBAR_PINCTRL_FUNCTION("GPIO2_IO30", 0x0, 0x000, 0x0), + TSXBAR_PINCTRL_FUNCTION("lpspi4_cs_mux_2", 0x1, 0x000, 0x0)), + TSXBAR_PINCTRL_GROUP("DC_9", 0x014, + TSXBAR_PINCTRL_FUNCTION("GPIO2_IO31", 0x0, 0x000, 0x0)), + TSXBAR_PINCTRL_GROUP("EN_LS_OUT_1", 0x019, + TSXBAR_PINCTRL_FUNCTION("GPIO2_IO17", 0x0, 0x000, 0x0)), + TSXBAR_PINCTRL_GROUP("EN_LS_OUT_2", 0x01A, + TSXBAR_PINCTRL_FUNCTION("GPIO2_IO18", 0x0, 0x000, 0x0)), + TSXBAR_PINCTRL_GROUP("EN_LS_OUT_3", 0x01B, + TSXBAR_PINCTRL_FUNCTION("GPIO2_IO19", 0x0, 0x000, 0x0)), + TSXBAR_PINCTRL_GROUP("EN_LS_OUT_4", 0x01C, + TSXBAR_PINCTRL_FUNCTION("GPIO2_IO20", 0x0, 0x000, 0x0)), + TSXBAR_PINCTRL_GROUP("EN_HS_SW", 0x01D, + TSXBAR_PINCTRL_FUNCTION("GPIO2_IO16", 0x0, 0x000, 0x0)), + TSXBAR_PINCTRL_GROUP("PRIM_485_TXD", 0x01E, + TSXBAR_PINCTRL_FUNCTION("UART7_TXD", 0x1, 0x000, 0x0)), + TSXBAR_PINCTRL_GROUP("PRIM_485_TXEN", 0x01F, + TSXBAR_PINCTRL_FUNCTION("UART7_RTS", 0x1, 0x000, 0x0)), + TSXBAR_PINCTRL_GROUP("SEC_485_TXEN", 0x021, + TSXBAR_PINCTRL_FUNCTION("UART3_RTS", 0x1, 0x000, 0x0)), + TSXBAR_PINCTRL_GROUP("SEC_UART_TX", 0x023, + TSXBAR_PINCTRL_FUNCTION("UART3_TXD", 0x1, 0x000, 0x0)), + TSXBAR_PINCTRL_GROUP("EN_GREEN_LED#", 0x024, + TSXBAR_PINCTRL_FUNCTION("GPIO0_IO0", 0x0, 0x000, 0x0)), + TSXBAR_PINCTRL_GROUP("EN_RED_LED#", 0x025, + TSXBAR_PINCTRL_FUNCTION("GPIO0_IO2", 0x0, 0x000, 0x0)), + TSXBAR_PINCTRL_GROUP("CODEC_CLK", 0x027, + TSXBAR_PINCTRL_FUNCTION("PLL_CLK_OUT", 0x1, 0x000, 0x0)), + TSXBAR_PINCTRL_GROUP("NIM_RESET#", 0x028, + TSXBAR_PINCTRL_FUNCTION("GPIO0_IO4", 0x0, 0x000, 0x0)), + TSXBAR_PINCTRL_GROUP("NIM_CTS#", 0x029, + TSXBAR_PINCTRL_FUNCTION("GPIO0_IO5", 0x0, 0x000, 0x0)), + TSXBAR_PINCTRL_GROUP("NIM_PWR_ON#", 0x02A, + TSXBAR_PINCTRL_FUNCTION("GPIO0_IO6", 0x0, 0x000, 0x0)), + TSXBAR_PINCTRL_GROUP("NIM_TXD", 0x02C, + TSXBAR_PINCTRL_FUNCTION("GPIO0_IO10", 0x0, 0x000, 0x0), + TSXBAR_PINCTRL_FUNCTION("UART5_TXD", 0x1, 0x000, 0x0)), + TSXBAR_PINCTRL_GROUP("NIM_RXD", 0x02D, + TSXBAR_PINCTRL_FUNCTION("GPIO0_IO11", 0x0, 0x000, 0x0)), + TSXBAR_PINCTRL_GROUP("UART3_RXD", 0x031, + TSXBAR_PINCTRL_FUNCTION("SECOND_PORT_RXD_3V", 0x1, 0x000, 0x0)), + TSXBAR_PINCTRL_GROUP("UART5_RXD", 0x033, + TSXBAR_PINCTRL_FUNCTION("NIM_RXD", 0x1, 0x02D, 0x1)), + TSXBAR_PINCTRL_GROUP("UART6_RXD", 0x034, + TSXBAR_PINCTRL_FUNCTION("BT_TXD", 0x1, 0x001, 0x1)), + TSXBAR_PINCTRL_GROUP("UART6_CTS", 0x035, + TSXBAR_PINCTRL_FUNCTION("BT_RTS", 0x1, 0x002, 0x1)), + TSXBAR_PINCTRL_GROUP("UART7_RXD", 0x036, + TSXBAR_PINCTRL_FUNCTION("PRIM_485_RXD_3V", 0x1, 0x000, 0x0), + TSXBAR_PINCTRL_FUNCTION("DC_3", 0x2, 0x011, 0x1), + TSXBAR_PINCTRL_FUNCTION("SECOND_PORT_RXD_3V", 0x3, 0x000, 0x0)), + TSXBAR_PINCTRL_GROUP("UART7_CTS", 0x037, + TSXBAR_PINCTRL_FUNCTION("DC_7", 0x1, 0x013, 0x1)), + TSXBAR_PINCTRL_GROUP("UART8_RXD", 0x038, + TSXBAR_PINCTRL_FUNCTION("MIKRO_RXD", 0x1, 0x007, 0x1)), + TSXBAR_PINCTRL_GROUP("lpspi4_miso_mux_1", 0x039, + TSXBAR_PINCTRL_FUNCTION("MIKRO_SPI_MISO", 0x1, 0x00A, 0x1)), + TSXBAR_PINCTRL_GROUP("lpspi4_miso_mux_2", 0x03A, + TSXBAR_PINCTRL_FUNCTION("DC_3", 0x1, 0x011, 0x1)), + TSXBAR_PINCTRL_GROUP("EN_BLUE_LED", 0x03B, + TSXBAR_PINCTRL_FUNCTION("GPIO0_IO3", 0x0, 0x000, 0x0)), +}; + +static const struct tsxbar_pinctrl_desc ts9370_pinctrl_data = { + .groups = ts9370_pinctrl_groups, + .ngroups = ARRAY_SIZE(ts9370_pinctrl_groups), +}; + +static const struct of_device_id ts9370_pinctrl_match[] = { + { + .compatible = "technologic,ts9370-xbar", + .data = &ts9370_pinctrl_data, + }, + {} +}; + +static int ts9370_pinctrl_probe(struct platform_device *pdev) +{ + const struct of_device_id *match = + of_match_device(ts9370_pinctrl_match, &pdev->dev); + + return tsxbar_pinctrl_probe(pdev, match->data); +} + +static struct platform_driver ts9370_pinctrl_driver = { + .probe = ts9370_pinctrl_probe, + .driver = { + .name = "ts9370-xbar", + .of_match_table = ts9370_pinctrl_match, + }, +}; +builtin_platform_driver(ts9370_pinctrl_driver); diff --git a/drivers/pinctrl/technologic/pinctrl-tsxbar.c b/drivers/pinctrl/technologic/pinctrl-tsxbar.c new file mode 100644 index 000000000000..2b53040bde67 --- /dev/null +++ b/drivers/pinctrl/technologic/pinctrl-tsxbar.c @@ -0,0 +1,388 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * embeddedTS FPGA XBAR pinmux driver + * + * Copyright (C) 2025 embeddedTS + * + * Mark Featherston + */ + +#include +#include +#include +#include +#include + +#include "../pinctrl-utils.h" +#include "pinctrl-tsxbar.h" + +#define XBAR_PIN_WIDTH 4 +#define XBAR_PIN_HIGHZ BIT(4) + +#define TSXBAR_PIN_CELL_SIZE 16 // 4 * 4 bytes (4 cells per pin) + +struct tsxbar_pinctrl { + struct regmap *regmap; + struct device *dev; + const struct tsxbar_pinctrl_desc *desc; + struct tsxbar_pinctrl_function *functions; + unsigned int nfunctions; + struct pinctrl_dev *pctrl_dev; +}; + +static int tsxbar_pinctrl_get_group_count(struct pinctrl_dev *pctrl_dev) +{ + struct tsxbar_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev); + + return pctrl->desc->ngroups; +} + +static const char *tsxbar_pinctrl_get_group_name(struct pinctrl_dev *pctrl_dev, + unsigned int group) +{ + struct tsxbar_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev); + + return pctrl->desc->groups[group].name; +} + +static int tsxbar_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev, + struct device_node *np, + struct pinctrl_map **map, + unsigned int *num_maps) +{ + const struct tsxbar_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + const struct tsxbar_desc_group *group; + const struct tsxbar_desc_function *func; + const __be32 *list; + int size, num_pins; + struct pinctrl_map *new_map; + int i; + u32 pinidx, funcsel; + + list = of_get_property(np, "xbar,pins", &size); + if (!list || size % (4 * sizeof(u32))) + return -EINVAL; + + num_pins = size / (4 * sizeof(u32)); + new_map = kcalloc(num_pins, sizeof(*new_map), GFP_KERNEL); + if (!new_map) + return -ENOMEM; + + for (i = 0; i < num_pins; i++) { + /* */ + pinidx = be32_to_cpu(*list++); + funcsel = be32_to_cpu(*list++); + list += 2; /* skip high-Z info; driver handles it at runtime */ + group = NULL; + func = NULL; + + for (int g = 0; g < pctrl->desc->ngroups; g++) { + if (pctrl->desc->groups[g].pinidx == pinidx) { + group = &pctrl->desc->groups[g]; + for (int f = 0; group->functions[f].name; f++) { + if (group->functions[f].funcsel == funcsel) { + func = &group->functions[f]; + break; + } + } + break; + } + } + + if (!group || !func) { + dev_err(pctrl->dev, "No matching group/function for pinidx=0x%x funcsel=0x%x\n", + pinidx, funcsel); + kfree(new_map); + return -EINVAL; + } + + new_map[i].type = PIN_MAP_TYPE_MUX_GROUP; + new_map[i].data.mux.group = group->name; + new_map[i].data.mux.function = func->name; + } + + *map = new_map; + *num_maps = num_pins; + + return 0; +} + +static const struct pinctrl_ops tsxbar_pinctrl_ops = { + .get_groups_count = &tsxbar_pinctrl_get_group_count, + .get_group_name = &tsxbar_pinctrl_get_group_name, + .dt_node_to_map = &tsxbar_pinctrl_dt_node_to_map, + .dt_free_map = &pinctrl_utils_free_map, +}; + +static int tsxbar_pinmux_get_functions_count(struct pinctrl_dev *pctrl_dev) +{ + struct tsxbar_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev); + + return pctrl->nfunctions; +} + +static const char *tsxbar_pinmux_get_function_name(struct pinctrl_dev *pctrl_dev, + unsigned int function) +{ + struct tsxbar_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev); + + return pctrl->functions[function].name; +} + +static int tsxbar_pinmux_get_function_groups(struct pinctrl_dev *pctrl_dev, + unsigned int function, + const char *const **groups, + unsigned *const num_groups) +{ + struct tsxbar_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev); + + *groups = pctrl->functions[function].groups; + *num_groups = pctrl->functions[function].ngroups; + + return 0; +} + +static struct tsxbar_desc_function * +tsxbar_pinctrl_find_function_by_name(struct tsxbar_pinctrl *pctrl, + const struct tsxbar_desc_group *group, + const char *fname) +{ + struct tsxbar_desc_function *function = group->functions; + + while (function->name) { + if (!strcmp(function->name, fname)) + return function; + + function++; + } + + return NULL; +} + +static int tsxbar_pinmux_set(struct pinctrl_dev *pctrl_dev, + unsigned int function, + unsigned int group) +{ + struct tsxbar_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev); + const struct tsxbar_desc_group *gdesc = pctrl->desc->groups + group; + struct tsxbar_pinctrl_function *func = pctrl->functions + function; + struct tsxbar_desc_function *fdesc; + u32 shift; + u32 reg; + u32 mask; + u32 val; + + fdesc = tsxbar_pinctrl_find_function_by_name(pctrl, gdesc, func->name); + if (!fdesc) + return -EINVAL; + + reg = XBAR_PIN_WIDTH * (gdesc->pinidx / 8); + shift = XBAR_PIN_WIDTH * (gdesc->pinidx % 8); + mask = GENMASK(shift + XBAR_PIN_WIDTH - 1, shift); + val = fdesc->funcsel << shift; + + dev_dbg(pctrl->dev, + "tsxbar: mux group=%s func=%s pinidx=%u reg=0x%03x shift=%u mask=0x%08x val=0x%08x\n", + gdesc->name, func->name, gdesc->pinidx, + reg, shift, mask, val); + + regmap_update_bits(pctrl->regmap, reg, mask, val); + + /* If high-z is set, we need to set the input pin as high-z */ + if (fdesc->highz_en) { + reg = XBAR_PIN_WIDTH * (fdesc->highz_pinidx / 8); + shift = XBAR_PIN_WIDTH * (fdesc->highz_pinidx % 8); + mask = GENMASK(shift + XBAR_PIN_WIDTH - 1, shift); + val = XBAR_PIN_HIGHZ << shift; + + dev_dbg(pctrl->dev, + "tsxbar: high-z pinidx=%u reg=0x%03x shift=%u mask=0x%08x val=0x%08x\n", + fdesc->highz_pinidx, + reg, shift, mask, val); + regmap_update_bits(pctrl->regmap, reg, mask, val); + } + + return 0; +} + +static const struct pinmux_ops tsxbar_pinmux_ops = { + .get_functions_count = &tsxbar_pinmux_get_functions_count, + .get_function_name = &tsxbar_pinmux_get_function_name, + .get_function_groups = &tsxbar_pinmux_get_function_groups, + .set_mux = &tsxbar_pinmux_set, +}; + +static struct pinctrl_desc tsxbar_pctrl_desc = { + .name = "tsxbar-pinctrl", + .pctlops = &tsxbar_pinctrl_ops, + .pmxops = &tsxbar_pinmux_ops, + .owner = THIS_MODULE, +}; + +static const struct regmap_config txbar_regmap_config = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, + .max_register = 0x3FF, +}; + +static void tsxbar_pinctrl_add_function(struct tsxbar_pinctrl *pctrl, + const char *fname) +{ + struct tsxbar_pinctrl_function *func = pctrl->functions; + + /* Skip functions that exist */ + while (func->name) { + if (!strcmp(func->name, fname)) { + func->ngroups++; + return; + } + func++; + } + + func->name = fname; + func->ngroups = 1; + pctrl->nfunctions++; +} + +static unsigned int tsxbar_count_functions(const struct tsxbar_pinctrl_desc *d) +{ + unsigned int total = 0; + unsigned int i; + + for (i = 0; i < d->ngroups; i++) + if (d->groups[i].functions) + for (const struct tsxbar_desc_function *f = + d->groups[i].functions; f->name; f++) + total++; + + return total; +} + +static int tsxbar_add_unique_funcs(struct tsxbar_pinctrl *pctrl) +{ + const struct tsxbar_desc_function *f; + unsigned int i; + + for (i = 0; i < pctrl->desc->ngroups; i++) { + f = pctrl->desc->groups[i].functions; + + while (f && f->name) { + tsxbar_pinctrl_add_function(pctrl, f->name); + f++; + } + } + + return 0; +} + +static int tsxbar_alloc_groups(struct platform_device *pdev, + struct tsxbar_pinctrl *pctrl) +{ + struct tsxbar_pinctrl_function *fn; + unsigned int i; + + for (i = 0; i < pctrl->nfunctions; i++) { + fn = &pctrl->functions[i]; + + if (!fn->ngroups) /* If a function is never referenced */ + continue; + + fn->groups = devm_kcalloc(&pdev->dev, fn->ngroups, + sizeof(char *), GFP_KERNEL); + if (!fn->groups) + return -ENOMEM; + + fn->ngroups = 0; + } + return 0; +} + +static void tsxbar_map_funcs_to_groups(struct tsxbar_pinctrl *pctrl) +{ + struct tsxbar_pinctrl_function *pinctrl_fn; + const struct tsxbar_desc_function *func; + const struct tsxbar_desc_group *grp; + unsigned int g, i; + + for (g = 0; g < pctrl->desc->ngroups; g++) { + grp = &pctrl->desc->groups[g]; + func = grp->functions; + + while (func && func->name) { + for (i = 0; i < pctrl->nfunctions; i++) + if (!strcmp(pctrl->functions[i].name, func->name)) { + pinctrl_fn = &pctrl->functions[i]; + pinctrl_fn->groups[pinctrl_fn->ngroups++] = grp->name; + break; + } + func++; + } + } +} + +static int tsxbar_pinctrl_build_state(struct platform_device *pdev) +{ + struct tsxbar_pinctrl *pctrl = platform_get_drvdata(pdev); + int max_functions = tsxbar_count_functions(pctrl->desc); + int ret; + + BUG_ON(max_functions == 0); + + pctrl->functions = devm_kcalloc(&pdev->dev, max_functions, + sizeof(*pctrl->functions), GFP_KERNEL); + if (!pctrl->functions) + return -ENOMEM; + + tsxbar_add_unique_funcs(pctrl); + + ret = tsxbar_alloc_groups(pdev, pctrl); + if (ret) + return ret; + + tsxbar_map_funcs_to_groups(pctrl); + + return 0; +} + +int tsxbar_pinctrl_probe(struct platform_device *pdev, + const struct tsxbar_pinctrl_desc *desc) +{ + struct device *dev = &pdev->dev; + struct tsxbar_pinctrl *pctrl; + void __iomem *base; + int ret; + + pctrl = devm_kzalloc(dev, sizeof(*pctrl), GFP_KERNEL); + if (!pctrl) + return -ENOMEM; + + platform_set_drvdata(pdev, pctrl); + + base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(base)) + return PTR_ERR(base); + + pctrl->regmap = devm_regmap_init_mmio(dev, base, &txbar_regmap_config); + if (IS_ERR(pctrl->regmap)) + return PTR_ERR(pctrl->regmap); + + pctrl->dev = &pdev->dev; + pctrl->desc = desc; + + ret = tsxbar_pinctrl_build_state(pdev); + if (ret) { + dev_err(&pdev->dev, "Cannot build crossbar state: %d\n", ret); + return ret; + } + + pctrl->pctrl_dev = devm_pinctrl_register(dev, &tsxbar_pctrl_desc, + pctrl); + if (IS_ERR(pctrl->pctrl_dev)) { + dev_err(dev, "failed to register pinctrl driver\n"); + return PTR_ERR(pctrl->pctrl_dev); + } + + return 0; +} +EXPORT_SYMBOL_GPL(tsxbar_pinctrl_probe); diff --git a/drivers/pinctrl/technologic/pinctrl-tsxbar.h b/drivers/pinctrl/technologic/pinctrl-tsxbar.h new file mode 100644 index 000000000000..6541cd88a8c9 --- /dev/null +++ b/drivers/pinctrl/technologic/pinctrl-tsxbar.h @@ -0,0 +1,49 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __PINCTRL_TSXBAR_H +#define __PINCTRL_TSXBAR_H + +struct tsxbar_desc_function { + const char *name; + u8 funcsel; + u8 highz_pinidx; + u8 highz_en; +}; + +struct tsxbar_desc_group { + const char *name; + u8 pinidx; + struct tsxbar_desc_function *functions; +}; + +struct tsxbar_pinctrl_desc { + const struct tsxbar_desc_group *groups; + unsigned int ngroups; +}; + +struct tsxbar_pinctrl_function { + const char *name; + const char **groups; + unsigned int ngroups; +}; + +#define TSXBAR_PINCTRL_GROUP(_name, _pinidx, ...) \ + { \ + .name = _name, \ + .pinidx = _pinidx, \ + .functions = (struct tsxbar_desc_function[]){ \ + __VA_ARGS__, { } }, \ + } + +#define TSXBAR_PINCTRL_FUNCTION(_name, _funcsel, _hz_pinidx, _hz_en) \ + { \ + .name = (_name), \ + .funcsel = (_funcsel), \ + .highz_pinidx = (_hz_pinidx), \ + .highz_en = (_hz_en), \ + } + +int tsxbar_pinctrl_probe(struct platform_device *pdev, + const struct tsxbar_pinctrl_desc *desc); + +#endif /* __PINCTRL_TSXBAR_H */ From 204b650cb7480daa8ca7792d779c490f651f8c16 Mon Sep 17 00:00:00 2001 From: Aaron Brice Date: Tue, 26 May 2026 22:49:04 +0000 Subject: [PATCH 04/10] drivers: gpio: Adding gpio-ts9370 TS-9370 expanded GPIO support. Signed-off-by: Aaron Brice --- drivers/gpio/Kconfig | 8 + drivers/gpio/Makefile | 1 + drivers/gpio/gpio-ts9370.c | 327 +++++++++++++++++++++++++++++++++++++ 3 files changed, 336 insertions(+) create mode 100644 drivers/gpio/gpio-ts9370.c diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 3b3675ee2684..0b3ea7fc3ca0 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -1274,6 +1274,14 @@ config GPIO_TS4900 Series supported include TS-4100, TS-4900, TS-7680, TS-7970, and TS-7990. +config GPIO_TS9370 + tristate "embeddedTS TS-9370 GPIO Support" + select GPIO_GENERIC + select GPIOLIB_IRQCHIP + default n + help + Say yes here to support GPIO on the embeddedTS products. + endmenu menu "MFD GPIO expanders" diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 6cf4bcb30341..425344dbae43 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -193,6 +193,7 @@ obj-$(CONFIG_GPIO_TS4900) += gpio-ts4900.o obj-$(CONFIG_GPIO_TS5500) += gpio-ts5500.o obj-$(CONFIG_GPIO_TS71XXWEIM) += gpio-ts71xxweim.o obj-$(CONFIG_GPIO_TS7800V2) += gpio-ts7800-v2.o +obj-$(CONFIG_GPIO_TS9370) += gpio-ts9370.o obj-$(CONFIG_GPIO_TWL4030) += gpio-twl4030.o obj-$(CONFIG_GPIO_TWL6040) += gpio-twl6040.o obj-$(CONFIG_GPIO_UNIPHIER) += gpio-uniphier.o diff --git a/drivers/gpio/gpio-ts9370.c b/drivers/gpio/gpio-ts9370.c new file mode 100644 index 000000000000..207e2f46ebab --- /dev/null +++ b/drivers/gpio/gpio-ts9370.c @@ -0,0 +1,327 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Read Decodes */ +#define TS9370_OE_IN 0x00 +#define TS9370_OUT_DATA 0x08 +#define TS9370_IN 0x0C + +/* Write Decodes */ +#define TS9370_OE_SET 0x00 +#define TS9370_OE_CLR 0x04 +#define TS9370_DAT_SET 0x08 +#define TS9370_DAT_CLR 0x0C +#define TS9370_IRQ_PENDING 0x10 /* Read is pending */ +#define TS9370_IRQ_ACK 0x10 /* Write is ack */ +#define TS9370_IRQ_MASK_SET 0x14 +#define TS9370_IRQ_MASK_CLR 0x18 +#define TS9370_IRQ_MASK_AND_ACK 0x1C +#define TS9370_IRQ_EDGE_LEVEL 0x20 +#define TS9370_IRQ_EDGE_SEL 0x24 +#define TS9370_IRQ_POL 0x28 + +struct ts9370_gpio_priv { + struct regmap *map; + struct device *dev; + struct gpio_chip chip; + struct irq_chip irqchip; + raw_spinlock_t lock; + int irq; +}; + +static int ts9370_gpio_set(struct gpio_chip *chip, unsigned int pin, int val) +{ + int ret; + struct ts9370_gpio_priv *p = gpiochip_get_data(chip); + + if (val) + ret = regmap_write(p->map, TS9370_DAT_SET, BIT(pin)); + else + ret = regmap_write(p->map, TS9370_DAT_CLR, BIT(pin)); + return ret; +} + +static int ts9370_gpio_set_multiple(struct gpio_chip *chip, + unsigned long *mask, + unsigned long *bits) +{ + int ret; + struct ts9370_gpio_priv *p = gpiochip_get_data(chip); + + ret = regmap_write(p->map, TS9370_DAT_SET, *mask & *bits); + if (ret == 0) + ret = regmap_write(p->map, TS9370_DAT_CLR, *mask & (~*bits)); + return ret; +} + +static int ts9370_gpio_get(struct gpio_chip *chip, unsigned int pin) +{ + struct ts9370_gpio_priv *p = gpiochip_get_data(chip); + u32 in; + + regmap_read(p->map, TS9370_IN, &in); + + return !!(in & BIT(pin)); +} + +static int ts9370_gpio_direction_input(struct gpio_chip *chip, + unsigned int pin) +{ + struct ts9370_gpio_priv *p = gpiochip_get_data(chip); + + regmap_write(p->map, TS9370_OE_CLR, BIT(pin)); + return 0; +} + + +static int ts9370_gpio_direction_output(struct gpio_chip *chip, + unsigned int pin, int val) +{ + struct ts9370_gpio_priv *p = gpiochip_get_data(chip); + + if (val) + regmap_write(p->map, TS9370_DAT_SET, BIT(pin)); + else + regmap_write(p->map, TS9370_DAT_CLR, BIT(pin)); + + regmap_write(p->map, TS9370_OE_SET, BIT(pin)); + + return 0; +} + +static int ts9370_gpio_direction_get(struct gpio_chip *chip, + unsigned int pin) +{ + struct ts9370_gpio_priv *p = gpiochip_get_data(chip); + u32 oe_in; + + regmap_read(p->map, TS9370_OE_IN, &oe_in); + return !(oe_in & BIT(pin)); +} + +static void gpio_ts9370_irq_mask(struct irq_data *d) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct ts9370_gpio_priv *p = gpiochip_get_data(gc); + u32 reg = BIT(irqd_to_hwirq(d)); + + regmap_write(p->map, TS9370_IRQ_MASK_SET, reg); + gpiochip_disable_irq(gc, d->hwirq); +} + +static void gpio_ts9370_irq_mask_ack(struct irq_data *d) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct ts9370_gpio_priv *p = gpiochip_get_data(gc); + u32 reg = BIT(irqd_to_hwirq(d)); + + regmap_write(p->map, TS9370_IRQ_MASK_AND_ACK, reg); +} + +static void gpio_ts9370_irq_unmask(struct irq_data *d) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct ts9370_gpio_priv *p = gpiochip_get_data(gc); + u32 reg = BIT(irqd_to_hwirq(d)); + + gpiochip_enable_irq(gc, d->hwirq); + regmap_write(p->map, TS9370_IRQ_MASK_CLR, reg); +} + +static void gpio_ts9370_irq_ack(struct irq_data *d) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct ts9370_gpio_priv *p = gpiochip_get_data(gc); + u32 reg = BIT(irqd_to_hwirq(d)); + + regmap_write(p->map, TS9370_IRQ_ACK, reg); +} + +static int gpio_ts9370_irq_set_type(struct irq_data *d, unsigned int type) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct ts9370_gpio_priv *p = gpiochip_get_data(gc); + unsigned int hwirq = irqd_to_hwirq(d); + u32 polarity, edge, edge_sel; + int ret = 0; + + regmap_read(p->map, TS9370_IRQ_POL, &polarity); + regmap_read(p->map, TS9370_IRQ_EDGE_LEVEL, &edge); + regmap_read(p->map, TS9370_IRQ_EDGE_SEL, &edge_sel); + + switch (type & IRQ_TYPE_SENSE_MASK) { + case IRQ_TYPE_LEVEL_HIGH: + edge &= ~BIT(hwirq); + edge_sel &= ~BIT(hwirq); + polarity |= BIT(hwirq); + irq_set_handler_locked(d, handle_level_irq); + break; + case IRQ_TYPE_LEVEL_LOW: + edge &= ~BIT(hwirq); + polarity &= ~BIT(hwirq); + edge_sel &= ~BIT(hwirq); + irq_set_handler_locked(d, handle_level_irq); + break; + case IRQ_TYPE_EDGE_RISING: + edge |= BIT(hwirq); + edge_sel &= ~BIT(hwirq); + polarity |= BIT(hwirq); + irq_set_handler_locked(d, handle_edge_irq); + break; + case IRQ_TYPE_EDGE_FALLING: + edge |= BIT(hwirq); + edge_sel &= ~BIT(hwirq); + polarity &= ~BIT(hwirq); + irq_set_handler_locked(d, handle_edge_irq); + break; + case IRQ_TYPE_EDGE_BOTH: + edge |= BIT(hwirq); + edge_sel |= BIT(hwirq); + polarity &= ~BIT(hwirq); + irq_set_handler_locked(d, handle_edge_irq); + break; + default: + ret = -EINVAL; + } + + regmap_write(p->map, TS9370_IRQ_POL, polarity); + regmap_write(p->map, TS9370_IRQ_EDGE_LEVEL, edge); + regmap_write(p->map, TS9370_IRQ_EDGE_SEL, edge_sel); + + return ret; +} + +static void gpio_ts9370_irq_handler(struct irq_desc *desc) +{ + struct gpio_chip *gc = irq_desc_get_handler_data(desc); + struct ts9370_gpio_priv *p = gpiochip_get_data(gc); + struct irq_chip *irqchip = irq_desc_get_chip(desc); + unsigned long pending; + u32 reg; + u32 bit; + + regmap_read(p->map, TS9370_IRQ_PENDING, ®); + pending = reg; + chained_irq_enter(irqchip, desc); + for_each_set_bit(bit, &pending, 32) { + generic_handle_domain_irq(gc->irq.domain, bit); + } + chained_irq_exit(irqchip, desc); +} + +static void gpio_ts9370_irq_print_chip(struct irq_data *data, struct seq_file *p) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(data); + + seq_printf(p, dev_name(gc->parent)); +} + +static const struct irq_chip ts9370_irq_chip = { + .irq_ack = gpio_ts9370_irq_ack, + .irq_mask = gpio_ts9370_irq_mask, + .irq_mask_ack = gpio_ts9370_irq_mask_ack, + .irq_unmask = gpio_ts9370_irq_unmask, + .irq_set_type = gpio_ts9370_irq_set_type, + .irq_print_chip = gpio_ts9370_irq_print_chip, + .flags = IRQCHIP_IMMUTABLE, + GPIOCHIP_IRQ_RESOURCE_HELPERS, +}; + +static const struct regmap_config ts9370_gpio_regmap_config = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, + .max_register = 0x3F, +}; + +static int ts9370_gpio_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct ts9370_gpio_priv *p; + struct gpio_irq_chip *girq; + void __iomem *base; + + p = devm_kzalloc(dev, sizeof(struct ts9370_gpio_priv), GFP_KERNEL); + if (!p) + return -ENOMEM; + + p->dev = dev; + p->irq = platform_get_irq(pdev, 0); + if (p->irq == -EPROBE_DEFER) + return -EPROBE_DEFER; + + base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(base)) + return PTR_ERR(base); + + raw_spin_lock_init(&p->lock); + + p->map = devm_regmap_init_mmio(dev, base, &ts9370_gpio_regmap_config); + if (IS_ERR(p->map)) + return PTR_ERR(p->map); + + /* Default to mask all interrupts */ + regmap_write(p->map, TS9370_IRQ_MASK_AND_ACK, 0xFFFFFFFF); + + p->chip.label = dev_name(dev); + p->chip.owner = THIS_MODULE; + p->chip.direction_input = ts9370_gpio_direction_input; + p->chip.direction_output = ts9370_gpio_direction_output; + p->chip.get_direction = ts9370_gpio_direction_get; + p->chip.set = ts9370_gpio_set; + p->chip.set_multiple = ts9370_gpio_set_multiple; + p->chip.get = ts9370_gpio_get; + p->chip.base = -1; + p->chip.ngpio = 32; + p->chip.parent = dev; + + if (p->irq >= 0) { + girq = &p->chip.irq; + gpio_irq_chip_set_chip(girq, &ts9370_irq_chip); + girq->parent_handler = gpio_ts9370_irq_handler; + girq->num_parents = 1; + girq->parents = devm_kcalloc(&pdev->dev, 1, + sizeof(*girq->parents), + GFP_KERNEL); + if (!girq->parents) + return -ENOMEM; + girq->parents[0] = p->irq; + girq->handler = handle_bad_irq; + } + + return devm_gpiochip_add_data(dev, &p->chip, p); +} + +static const struct of_device_id ts9370_gpio_of_match[] = { + { .compatible = "technologic,ts9370-gpio", }, + {}, +}; +MODULE_DEVICE_TABLE(of, ts9370_gpio_of_match); + +static struct platform_driver ts9370_gpio_driver = { + .probe = ts9370_gpio_probe, + .driver = { + .name = "ts9370-gpio", + .of_match_table = ts9370_gpio_of_match, + .suppress_bind_attrs = true, + }, +}; +module_platform_driver(ts9370_gpio_driver); + +MODULE_AUTHOR("Mark Featherston "); +MODULE_DESCRIPTION("TS-9370 FPGA GPIO driver"); +MODULE_LICENSE("GPL"); From e99c2f90a28bf18cf3c34cef580c5359e0038d29 Mon Sep 17 00:00:00 2001 From: Aaron Brice Date: Tue, 26 May 2026 22:50:24 +0000 Subject: [PATCH 05/10] drivers: irqchip: Adding irq-wizard Interrupts from embeddedTS wizard microcontroller. Signed-off-by: Aaron Brice --- drivers/irqchip/Kconfig | 7 +++ drivers/irqchip/Makefile | 1 + drivers/irqchip/irq-wizard.c | 94 +++++++++++++++++++++++++++++++++++ include/linux/mfd/ts_wizard.h | 6 ++- 4 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 drivers/irqchip/irq-wizard.c diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index d70ea51bf057..f5340885a9d4 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -352,6 +352,13 @@ config TS9370_IRQ help Support for the TS-9370 FPGA IRQ controller +config WIZARD_IRQ + tristate "embeddedTS Wizard IRQ controller" + select IRQ_DOMAIN + depends on MFD_TS_WIZARD + help + Add support for interrupts under the embeddedTS Wizard management microcontroller + config TSWEIM_FPGA_INTC tristate "TS-71XX WEIM FPGA IRQ Support" default n diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index 5d0ec5c09f23..d4027c4bf2f0 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile @@ -64,6 +64,7 @@ obj-$(CONFIG_TB10X_IRQC) += irq-tb10x.o obj-$(CONFIG_TS4800_IRQ) += irq-ts4800.o obj-$(CONFIG_TS9370_IRQ) += irq-ts9370.o obj-$(CONFIG_TSWEIM_FPGA_INTC) += irq-ts71xxweim.o +obj-$(CONFIG_WIZARD_IRQ) += irq-wizard.o obj-$(CONFIG_XTENSA) += irq-xtensa-pic.o obj-$(CONFIG_XTENSA_MX) += irq-xtensa-mx.o obj-$(CONFIG_XILINX_INTC) += irq-xilinx-intc.o diff --git a/drivers/irqchip/irq-wizard.c b/drivers/irqchip/irq-wizard.c new file mode 100644 index 000000000000..4137264d5075 --- /dev/null +++ b/drivers/irqchip/irq-wizard.c @@ -0,0 +1,94 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * embeddedTS Wizard MFD I2C controller + */ + +#include +#include +#include +#include +#include +#include +#include + +#define MAX_IRQS 16 + +#define IRQ_STATUS 0 +#define IRQ_ACK 1 +#define IRQ_MASK_SET 2 +#define IRQ_MASK_CLR 3 +#define IRQ_MASK_RW 4 + +static const struct regmap_irq wizard_irqs[MAX_IRQS] = { + REGMAP_IRQ_REG(0, 0, BIT(0)), + REGMAP_IRQ_REG(1, 0, BIT(1)), + REGMAP_IRQ_REG(2, 0, BIT(2)), + REGMAP_IRQ_REG(3, 0, BIT(3)), + REGMAP_IRQ_REG(4, 0, BIT(4)), + REGMAP_IRQ_REG(5, 0, BIT(5)), + REGMAP_IRQ_REG(6, 0, BIT(6)), + REGMAP_IRQ_REG(7, 0, BIT(7)), + REGMAP_IRQ_REG(8, 0, BIT(8)), + REGMAP_IRQ_REG(9, 0, BIT(9)), + REGMAP_IRQ_REG(10, 0, BIT(10)), + REGMAP_IRQ_REG(11, 0, BIT(11)), + REGMAP_IRQ_REG(12, 0, BIT(12)), + REGMAP_IRQ_REG(13, 0, BIT(13)), + REGMAP_IRQ_REG(14, 0, BIT(14)), + REGMAP_IRQ_REG(15, 0, BIT(15)), +}; + +static const struct regmap_irq_chip wizard_regmap_ic = { + .name = "wizard-irq", + .irqs = wizard_irqs, + .num_irqs = ARRAY_SIZE(wizard_irqs), + .num_regs = 1, + .irq_reg_stride = 1, + + .status_base = WIZARD_IRQCHIP_BASE + IRQ_STATUS, + .ack_base = WIZARD_IRQCHIP_BASE + IRQ_ACK, + .mask_base = WIZARD_IRQCHIP_BASE + IRQ_MASK_RW, +}; + +static int wizard_irq_probe(struct platform_device *pdev) +{ + struct ts_wizard *wizard = dev_get_drvdata(pdev->dev.parent); + struct device *dev = &pdev->dev; + struct regmap_irq_chip_data *ricd; + int parent_irq; + + if (!wizard || !wizard->regmap) + return -ENODEV; + + parent_irq = platform_get_irq(pdev, 0); + if (parent_irq < 0) + return parent_irq; + + return devm_regmap_add_irq_chip_fwnode(dev, + dev_fwnode(dev), + wizard->regmap, + parent_irq, + 0, + 0, + &wizard_regmap_ic, + &ricd); +} + +static const struct of_device_id wizard_of_match[] = { + { .compatible = "technologic,wizard-irq", }, + { } +}; +MODULE_DEVICE_TABLE(of, wizard_of_match); + +static struct platform_driver wizard_driver = { + .driver = { + .name = "wizard-irq", + .of_match_table = wizard_of_match, + }, + .probe = wizard_irq_probe, +}; +module_platform_driver(wizard_driver); + +MODULE_DESCRIPTION("embeddedTS wizard IRQ controller"); +MODULE_AUTHOR("Mark Featherston "); +MODULE_LICENSE("GPL"); diff --git a/include/linux/mfd/ts_wizard.h b/include/linux/mfd/ts_wizard.h index 6ce7b173249b..57ba868a9b51 100644 --- a/include/linux/mfd/ts_wizard.h +++ b/include/linux/mfd/ts_wizard.h @@ -23,9 +23,13 @@ struct ts_wizard { #define WIZ_SERIAL1 35 #define WIZ_SERIAL2 36 #define WIZ_SERIAL_CTRL 37 +#define WIZARD_SILO_BASE 64 #define WIZ_ADC_BASE 128 #define WIZ_ADC_LAST 159 #define WIZ_TEMPERATURE 160 +#define WIZARD_CURRENT 161 + +#define WIZARD_IRQCHIP_BASE 512 enum gen_flags_t { FLG_FORCE_USB_CON = (1 << 4), @@ -65,4 +69,4 @@ enum wiz_serial_ctrl_t { WIZ_SN_LOCKED = (1 << 0), }; -#endif \ No newline at end of file +#endif From bad546a27cd5b2eb981d41de14725c31303ef3bb Mon Sep 17 00:00:00 2001 From: Aaron Brice Date: Tue, 26 May 2026 22:52:09 +0000 Subject: [PATCH 06/10] iio: adc: ti-adc128s052: Adding adc121s021 support Add single channel ADC121S021 ADC chip support to the TI ADC128S052 driver. Signed-off-by: Aaron Brice --- drivers/iio/adc/ti-adc128s052.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/iio/adc/ti-adc128s052.c b/drivers/iio/adc/ti-adc128s052.c index 4ae65793ad9b..94e14dde5c00 100644 --- a/drivers/iio/adc/ti-adc128s052.c +++ b/drivers/iio/adc/ti-adc128s052.c @@ -7,6 +7,7 @@ * https://www.ti.com/lit/ds/symlink/adc128s052.pdf * https://www.ti.com/lit/ds/symlink/adc122s021.pdf * https://www.ti.com/lit/ds/symlink/adc124s021.pdf + * https://www.ti.com/lit/ds/symlink/adc121s021.pdf */ #include @@ -128,6 +129,12 @@ static const struct iio_chan_spec simple_8chan_adc_channels[] = { static const char * const bd79104_regulators[] = { "iovdd" }; +static const struct adc128_configuration adc121s_config = { + .channels = simple_1chan_adc_channels, + .num_channels = ARRAY_SIZE(simple_1chan_adc_channels), + .refname = "vref", +}; + static const struct adc128_configuration adc122s_config = { .channels = simple_2chan_adc_channels, .num_channels = ARRAY_SIZE(simple_2chan_adc_channels), @@ -232,6 +239,7 @@ static int adc128_probe(struct spi_device *spi) static const struct of_device_id adc128_of_match[] = { { .compatible = "ti,adc128s052", .data = &adc128s_config }, + { .compatible = "ti,adc121s021", .data = &adc121s_config }, { .compatible = "ti,adc122s021", .data = &adc122s_config }, { .compatible = "ti,adc122s051", .data = &adc122s_config }, { .compatible = "ti,adc122s101", .data = &adc122s_config }, @@ -249,6 +257,7 @@ MODULE_DEVICE_TABLE(of, adc128_of_match); static const struct spi_device_id adc128_id[] = { { "adc128s052", (kernel_ulong_t)&adc128s_config }, + { "adc122s021", (kernel_ulong_t)&adc121s_config }, { "adc122s021", (kernel_ulong_t)&adc122s_config }, { "adc122s051", (kernel_ulong_t)&adc122s_config }, { "adc122s101", (kernel_ulong_t)&adc122s_config }, From 46ec3d9998ffc02843a648e9f42b8bd1c5e83c92 Mon Sep 17 00:00:00 2001 From: Aaron Brice Date: Mon, 1 Jun 2026 23:46:16 +0000 Subject: [PATCH 07/10] drivers: power: Adding tssilo driver Adding driver for TS-SILO supercap power supply. The TS-SILO provides power long enough for the system to be able to shut down gracefully if power is lost. Signed-off-by: Aaron Brice --- drivers/power/supply/tssilo_supercaps.c | 364 ++++++++++++++++++++++++ 1 file changed, 364 insertions(+) create mode 100644 drivers/power/supply/tssilo_supercaps.c diff --git a/drivers/power/supply/tssilo_supercaps.c b/drivers/power/supply/tssilo_supercaps.c new file mode 100644 index 000000000000..a10c184f07a3 --- /dev/null +++ b/drivers/power/supply/tssilo_supercaps.c @@ -0,0 +1,364 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Supercaps driver for the embeddedTS SILO controller + * Copyright (C) 2024-2025 Technologic Systems, Inc. dba embeddedTS + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#define SILO_RESERVED0 (WIZARD_SILO_BASE + 0) +#define SILO_STATUS (WIZARD_SILO_BASE + 1) +#define SILO_CONTROL (WIZARD_SILO_BASE + 2) + +#define SILO_REQUESTED_CHG_CURRENT_MA (WIZARD_SILO_BASE + 4) +#define SILO_MAX_SUPPORTED_CHRG_CURRENT_MA (WIZARD_SILO_BASE + 5) + +#define SILO_PCT_CHARGED (WIZARD_SILO_BASE + 8) +#define SILO_CRITICAL_PCT (WIZARD_SILO_BASE + 9) + +#define SILO_STARTUP_REQUESTED_CHG_CURRENT_MA (WIZARD_SILO_BASE + 12) +#define SILO_MIN_PWR_ON_PCT (WIZARD_SILO_BASE + 13) + +#define SILO_STATUS_CHARGING BIT(0) +#define SILO_STATUS_PWR_FAIL BIT(15) +#define SILO_STATUS_MODE_MASK 0x3E +#define SILO_STATUS_MODE_SHIFT 1 + +#define SILO_STATUS_MODE_DISABLED 0 +#define SILO_STATUS_MODE_CHARGING 1 +#define SILO_STATUS_MODE_FULL 2 +#define SILO_STATUS_MODE_DISCHARGING 3 + +#define SILO_CONTROL_CHRG_EN BIT(0) +#define SILO_CONTROL_PWRUP BIT(1) + +struct silo_data { + struct regmap *regmap; + struct power_supply *psy; +}; + +static int get_pct_charged(struct silo_data *data) +{ + int ret; + unsigned int val; + + ret = regmap_read(data->regmap, SILO_PCT_CHARGED, &val); + if (ret) { + dev_err(&data->psy->dev, "%s failed from regmap_read (rc=%d)\n", __func__, ret); + return ret; + } + return val; +} + +static ssize_t startup_charge_current_ma_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct silo_data *data = dev_get_drvdata(dev); + int ret, val; + + ret = regmap_read(data->regmap, SILO_STARTUP_REQUESTED_CHG_CURRENT_MA, &val); + if (ret) + return ret; + return sprintf(buf, "%d\n", val); +} + +static ssize_t startup_charge_current_ma_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct silo_data *data = dev_get_drvdata(dev); + unsigned int max; + int ret; + int val; + + ret = kstrtoint(buf, 10, &val); + if (ret) + return ret; + + ret = regmap_read(data->regmap, SILO_MAX_SUPPORTED_CHRG_CURRENT_MA, &max); + if (ret) + return ret; + if (val < 0 || val > max) + return -EINVAL; + + ret = regmap_write(data->regmap, SILO_STARTUP_REQUESTED_CHG_CURRENT_MA, val); + if (ret) + return ret; + + power_supply_changed(data->psy); + + return count; +} + +static ssize_t min_power_on_pct_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct silo_data *data = dev_get_drvdata(dev); + unsigned int val; + int ret; + + ret = regmap_read(data->regmap, SILO_MIN_PWR_ON_PCT, &val); + if (ret) + return ret; + + return sprintf(buf, "%d\n", val); +} + +static ssize_t min_power_on_pct_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct silo_data *data = dev_get_drvdata(dev); + unsigned int val; + int ret; + + ret = kstrtoint(buf, 10, &val); + if (ret) + return ret; + + if (val > 100) + return -EINVAL; + + ret = regmap_write(data->regmap, SILO_MIN_PWR_ON_PCT, val); + if (ret) + return ret; + + power_supply_changed(data->psy); + + return count; +} + +static DEVICE_ATTR_RW(startup_charge_current_ma); +static DEVICE_ATTR_RW(min_power_on_pct); + +/* + * Currently these are our properties that do not map to any standard + * power supply properties. + */ +static struct attribute *silo_attrs[] = { + &dev_attr_startup_charge_current_ma.attr, + &dev_attr_min_power_on_pct.attr, + NULL, +}; + +static const struct attribute_group silo_attr_group = { + .attrs = silo_attrs, +}; + +static int silo_property_is_writable(struct power_supply *psy, + enum power_supply_property psp) +{ + switch (psp) { + case POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR: + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: + case POWER_SUPPLY_PROP_CAPACITY_ALERT_MIN: + return 1; + default: + break; + } + return 0; +} + +static enum power_supply_property silo_props[] = { + POWER_SUPPLY_PROP_ONLINE, + POWER_SUPPLY_PROP_STATUS, + POWER_SUPPLY_PROP_CAPACITY, + POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR, + POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT, + POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, + POWER_SUPPLY_PROP_CAPACITY_ALERT_MIN +}; + +static int silo_get_property(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + unsigned int reg; + int ret; + + struct silo_data *data = power_supply_get_drvdata(psy); + + switch (psp) { + case POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR: + ret = regmap_test_bits(data->regmap, SILO_CONTROL, SILO_CONTROL_CHRG_EN); + if (ret < 0) + return ret; + val->intval = (ret ? POWER_SUPPLY_CHARGE_BEHAVIOUR_AUTO : + POWER_SUPPLY_CHARGE_BEHAVIOUR_INHIBIT_CHARGE); + return 0; + case POWER_SUPPLY_PROP_ONLINE: + ret = regmap_read(data->regmap, SILO_STATUS, ®); + val->intval = !(reg & SILO_STATUS_PWR_FAIL); + return ret; + case POWER_SUPPLY_PROP_CAPACITY: + ret = get_pct_charged(data); + if (ret < 0) + return ret; + val->intval = ret; + return 0; + case POWER_SUPPLY_PROP_CAPACITY_ALERT_MIN: + return regmap_read(data->regmap, SILO_CRITICAL_PCT, &val->intval); + case POWER_SUPPLY_PROP_STATUS: + ret = regmap_read(data->regmap, SILO_STATUS, ®); + reg = (reg & SILO_STATUS_MODE_MASK) >> SILO_STATUS_MODE_SHIFT; + + switch (reg) { + case SILO_STATUS_MODE_DISABLED: + val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; + break; + case SILO_STATUS_MODE_CHARGING: + val->intval = POWER_SUPPLY_STATUS_CHARGING; + break; + case SILO_STATUS_MODE_FULL: + val->intval = POWER_SUPPLY_STATUS_FULL; + break; + case SILO_STATUS_MODE_DISCHARGING: + val->intval = POWER_SUPPLY_STATUS_DISCHARGING; + break; + default: + val->intval = POWER_SUPPLY_STATUS_UNKNOWN; + break; + } + return 0; + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: + return regmap_read(data->regmap, SILO_REQUESTED_CHG_CURRENT_MA, &val->intval); + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: + return regmap_read(data->regmap, SILO_MAX_SUPPORTED_CHRG_CURRENT_MA, &val->intval); + default: + return -EINVAL; + } + return -ENODATA; +} + +static int silo_set_property(struct power_supply *psy, + enum power_supply_property psp, + const union power_supply_propval *val) +{ + struct silo_data *data = power_supply_get_drvdata(psy); + unsigned int value; + int ret; + + if (psp == POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT) { + ret = regmap_read(data->regmap, SILO_MAX_SUPPORTED_CHRG_CURRENT_MA, &value); + if (ret) + return ret; + if (val->intval < 0 || val->intval > value) + return -EINVAL; + ret = regmap_write(data->regmap, SILO_REQUESTED_CHG_CURRENT_MA, val->intval); + } else if (psp == POWER_SUPPLY_PROP_CAPACITY_ALERT_MIN) + ret = regmap_write(data->regmap, SILO_CRITICAL_PCT, val->intval); + else if (psp == POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR) { + value = ((val->intval == POWER_SUPPLY_CHARGE_BEHAVIOUR_AUTO) ? + SILO_CONTROL_CHRG_EN : 0); + ret = regmap_update_bits(data->regmap, SILO_CONTROL, + SILO_CONTROL_CHRG_EN, value); + } else + return -EINVAL; + + if (!ret) + power_supply_changed(data->psy); + + return ret; +} + +static const struct power_supply_desc silo_desc = { + .name = "silo", + .type = POWER_SUPPLY_TYPE_UPS, + .properties = silo_props, + .num_properties = ARRAY_SIZE(silo_props), + .get_property = silo_get_property, + .set_property = silo_set_property, + .property_is_writeable = silo_property_is_writable, + .no_thermal = true, + .charge_behaviours = + BIT(POWER_SUPPLY_CHARGE_BEHAVIOUR_AUTO) | + BIT(POWER_SUPPLY_CHARGE_BEHAVIOUR_INHIBIT_CHARGE), +}; + +static irqreturn_t silo_irq_handler(int irq, void *dev_id) +{ + struct silo_data *data = dev_id; + + power_supply_changed(data->psy); + return IRQ_HANDLED; +} + +static int ts_silo_probe(struct platform_device *pdev) +{ + struct ts_wizard *wizard = dev_get_drvdata(pdev->dev.parent); + struct device *dev = &pdev->dev; + struct silo_data *data; + struct power_supply_config psy_cfg = {}; + int ret; + int irq; + + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); + if (!data) { + return -ENOMEM; + } + data->regmap = wizard->regmap; + platform_set_drvdata(pdev, data); + + irq = platform_get_irq(pdev, 0); + if (irq < 0) + return irq; + + psy_cfg.drv_data = data; + data->psy = devm_power_supply_register(dev, &silo_desc, &psy_cfg); + if (IS_ERR(data->psy)) { + dev_err(dev, "devm_power_supply_register failed (rc=%pe)", data->psy); + return PTR_ERR(data->psy); + } + + ret = sysfs_create_group(&dev->kobj, &silo_attr_group); + if (ret) { + dev_err(dev, "sysfs_create_group failed (rc=%d)\n", ret); + return ret; + } + + ret = devm_request_threaded_irq(dev, irq, + NULL, silo_irq_handler, + IRQF_ONESHOT, dev_name(dev), data); + return ret; +} + +static void ts_silo_remove(struct platform_device *pdev) +{ + sysfs_remove_group(&pdev->dev.kobj, &silo_attr_group); +} + +static const struct of_device_id silo_of_match[] = { + { .compatible = "technologic,wizard-silo", }, + {} +}; +MODULE_DEVICE_TABLE(of, silo_of_match); + +static struct platform_driver silo_driver = { + .driver = { + .name = "silo", + .of_match_table = silo_of_match, + }, + .probe = ts_silo_probe, + .remove = ts_silo_remove, +}; + +module_platform_driver(silo_driver); + +MODULE_DESCRIPTION("embeddedTS SILO supercaps driver"); +MODULE_AUTHOR("Lionel D. Hummel "); +MODULE_LICENSE("GPL"); From 8e851d8cca1c6772f9e23ffadf6a1ee15f54106f Mon Sep 17 00:00:00 2001 From: Aaron Brice Date: Thu, 4 Jun 2026 19:51:03 +0000 Subject: [PATCH 08/10] sound: codecs: Adding tac5x1x-i2c driver Driver code comes from commit 1a07aaa2a9980ba2829d1a1733968c89f5a77ef3 of https://git.ti.com/git/lpaa-android-drivers/tac5x1x-linux-driver.git --- .../devicetree/bindings/sound/ti,tac5x1x.yaml | 260 ++ sound/soc/codecs/Kconfig | 12 + sound/soc/codecs/Makefile | 2 + sound/soc/codecs/tac5x1x-i2c.c | 2449 +++++++++++++++++ sound/soc/codecs/tac5x1x.h | 304 ++ 5 files changed, 3027 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/ti,tac5x1x.yaml create mode 100644 sound/soc/codecs/tac5x1x-i2c.c create mode 100644 sound/soc/codecs/tac5x1x.h diff --git a/Documentation/devicetree/bindings/sound/ti,tac5x1x.yaml b/Documentation/devicetree/bindings/sound/ti,tac5x1x.yaml new file mode 100644 index 000000000000..1cc068f82226 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/ti,tac5x1x.yaml @@ -0,0 +1,260 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +# Copyright (C) 2025 Texas Instruments Incorporated +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/ti,tac5x1x.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Texas Instruments TAC5X1X Codec + +description: | + TAC5X1X are series of low-power and high performance mono or stereo + audio codecs, as well as multiple inputs and outputs programmable in + single-ended or fully differential configurations. Device supports both + Microphone and Line In input on ADC Channel. DAC Output can be configured + for either Line Out or Head Phone Load. + + The serial control bus supports SPI or I2C protocols, while the serial audio + data bus is programmable for I2S, left/right-justified, DSP, or TDM modes. + + Specification about the codecs can be found at: + https://www.ti.com/lit/gpn/taa5212 + https://www.ti.com/lit/gpn/taa5412-q1 + https://www.ti.com/lit/gpn/tac5111 + https://www.ti.com/lit/gpn/tac5112 + https://www.ti.com/lit/gpn/tac5211 + https://www.ti.com/lit/gpn/tac5212 + https://www.ti.com/lit/gpn/tac5311-q1 + https://www.ti.com/lit/gpn/tac5312-q1 + https://www.ti.com/lit/gpn/tac5411-q1 + https://www.ti.com/lit/gpn/tac5412-q1 + https://www.ti.com/lit/gpn/tad5112 + https://www.ti.com/lit/gpn/tad5212 + +maintainers: + - Niranjan H Y + - Kevin Lu + +properties: + compatible: + enum: + - ti,taa5212 + - ti,taa5412 + - ti,tac5111 + - ti,tac5112 + - ti,tac5211 + - ti,tac5212 + - ti,tac5311 + - ti,tac5312 + - ti,tac5411 + - ti,tac5412 + - ti,tad5112 + - ti,tad5212 + + reg: + maxItems: 1 + + ti,vref: + description: VREF required voltage. If node is omitted then VREF is powered down. + $ref: /schemas/types.yaml#/definitions/uint32 + oneOf: + - const: 0 + description: VREF output is powered to 2.75V. + - const: 1 + description: VREF output is powered to 2.5V. + - const: 2 + description: VREF output is powered to 1.375V. + + ti,micbias-vg: + description: MicBias required voltage. If node is omitted then MicBias is powered down. + $ref: /schemas/types.yaml#/definitions/uint32 + oneOf: + - const: 0 + description: MICBIAS output is same as the VREF output + - const: 1 + description: MICBIAS output is 0.5 times the VREF output + - const: 3 + description: MICBIAS output is same as the AVDD + + avdd-supply: + description: Analog DAC voltage. + + iovdd-supply: + description: I/O voltage. + + ti,gpios-func: + description: | + Array indicating the GPIO1, GPIO2, GPO1 Functionality in the same order. + Each integer elemnent in the array represent the following + - 0 TAC5X1X_GPIO_DISABLE - GPIO is Disabled + - 1 TAC5X1X_GPIO_GPI - General Purpose Input + - 2 ADC3XXX_GPIO_GPO - General Purpose Output + - 3 TAC5X1X_GPIO_IRQ - Chip Interrupt + - 4 TAC5X1X_GPIO_PDMCLK - PDM CLK Output + - 5 TAC5X1X_GPIO_P_DOUT - Primary ASI DOUT + - 6 TAC5X1X_GPIO_P_DOUT2 - Primary ASI DOUT2 + - 7 TAC5X1X_GPIO_S_DOUT - Secondary ASI DOUT + - 8 TAC5X1X_GPIO_S_DOUT2 - Secondary ASI DOUT2 + - 9 TAC5X1X_GPIO_S_BCLK - Secondary BCLK Output + - 10 TAC5X1X_GPIO_S_FSYNC - Secondary FSYNC Output + - 11 TAC5X1X_GPIO_CLKOUT - General Purpose Output + - 12 TAC5X1X_GPIO_DOUT_MUX + - 13 TAC5X1X_GPIO_DAISY_OUT + $ref: /schemas/types.yaml#/definitions/uint32-array + minItems: 3 + maxItems: 3 + + ti,gpios-drive: + description: | + Array indicating the GPIO1, GPIO2, GPO1 Driver values + Each number in the array indicate the following driver values. + - 0 # Hi-Z Output + - 1 # Drive active low and active High + - 2 # Drive active low and weak High + - 3 # Drive acive low and Hi-Z + - 4 # Drive weak low and active High + - 5 # Drive Hi-Z and active High + $ref: /schemas/types.yaml#/definitions/uint32-array + minItems: 3 + maxItems: 3 + + ti,pdm-input-pins: + description: | + Array indicating the PDM Data Input for "Ch1 & Ch2" and "Ch3 & Ch4" + respectively. Each number in the array indicate the following + - 0 # PDM input disabled + - 1 # PDM input GPIO1 + - 2 # PDM input GPIO2 + - 3 # PDM input GPI1 + $ref: /schemas/types.yaml#/definitions/uint32-array + minItems: 2 + maxItems: 2 + + ti,gpi1-func: + description: GPI1 Functionality + $ref: /schemas/types.yaml#/definitions/uint32 + enum: + - 0 # TAC5X1X_GPIO_DISABLE - I/O buffers powered down and not used + - 1 # TAC5X1X_GPIO_GPI - General purpose input + default: 0 + + '#sound-dai-cells': + const: 0 + + clocks: + maxItems: 1 + + ti,gpa-gpio: + description: GPA using GPIO1 configuration + $ref: /schemas/types.yaml#/definitions/uint32 + enum: + - 0 # GPA using GPIO1 is disabled + - 1 # GPA using GPIO1 + default: 0 + + ti,in-ch-en: + description: Enable Input channel diagnostics for TAC54XX and TAC53XX device. + $ref: /schemas/types.yaml#/definitions/uint32 + enum: + - 0 # Disable input channel diagnostics + - 1 # Enable input channel diagnostics + + ti,out-ch-en: + description: Enable Output channel diagnostics for TAC54XX and TAC53XX device + $ref: /schemas/types.yaml#/definitions/uint32 + enum: + - 0 # Disable Output channel diagnostics + - 1 # Enable Output channel Diagnostics + + ti,incl-se-inm: + description: INxM pin Diagnostics Scan Selection for Single Ended Configuration + $ref: /schemas/types.yaml#/definitions/uint32 + enum: + - 0 # INxM pin Diagnostics Scan Selection for Single Ended excluded for diagnosis + - 1 # INxM pin Diagnostics Scan Selection for Single Ended included for diagnosis + + ti,incl-ac-coup: + description: AC coupled channels pins Scan Selection for Diagnostics + $ref: /schemas/types.yaml#/definitions/uint32 + enum: + - 0 # AC coupled channels pins Scan Selection for Diagnostics exluded for diagnosis + - 1 # AC coupled channels pins Scan Selection for Diagnostics included for diagnosis + + ti,micbias-threshold: + description: Micbias Low and High threshold values for TAC54XX and TAC53XX series + $ref: /schemas/types.yaml#/definitions/uint32-array + maxItems: 2 + minItems: 2 + items: + minimum: 72 + maximum: 162 + + ti,gpa-threshold: + description: GPA Low and High threshold Values + $ref: /schemas/types.yaml#/definitions/uint32-array + maxItems: 2 + minItems: 2 + items: + minimum: 75 + maximum: 186 + + ti,adc1-impedance: + description: Channel 1 Input Impedance Value + $ref: /schemas/types.yaml#/definitions/uint32 + enum: + - 0 # 5 kOhm + - 1 # 10 kOhm + - 2 # 40 kOhm + default: 0 + + ti,adc2-impedance: + description: Channel 2 Input Impedance Value + $ref: /schemas/types.yaml#/definitions/uint32 + enum: + - 0 # 5 kOhm + - 1 # 10 kOhm + - 2 # 40 kOhm + default: 0 + + ti,out2x-vcom-cfg: + description: Channel OUT2x VCOM configuration + $ref: /schemas/types.yaml#/definitions/uint32 + enum: + - 0 # 0.6 * Vref + - 1 # AVDD by 2 + default: 0 + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + #include + + i2c { + #address-cells = <1>; + #size-cells = <0>; + + tac5x1x: tac5x1x@52 { + compatible = "ti,tac5212"; + reg = <0x52>; + #sound-dai-cells = <0>; + avdd-supply = <&vdd_3v3_reg>; + iovdd-supply = <&vdd_3v3_reg>; + ti,vref = <0>; + ti,micbias-vg = <3>; + ti,gpi1-func = <0>; + ti,gpios-func = <4>, <1>, <0>; + ti,gpios-drive = <0>, <0>, <0>; + ti,gpa-gpio = <0>; + ti,in-ch-en = <1>; + ti,out-ch-en = <1>; + ti,incl-ac-coup = <0>; + ti,incl-se-inm = <0>; + ti,gpa-threshold = <75>, <186>; + }; + }; +... diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 91ac99bc3edb..1c25338ce035 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -263,6 +263,7 @@ config SND_SOC_ALL_CODECS imply SND_SOC_STA529 imply SND_SOC_STAC9766 imply SND_SOC_STI_SAS + imply SND_SOC_TAC5X1X_I2C imply SND_SOC_TAS2552 imply SND_SOC_TAS2562 imply SND_SOC_TAS2764 @@ -2050,6 +2051,17 @@ config SND_SOC_STAC9766 config SND_SOC_STI_SAS tristate "codec Audio support for STI SAS codec" +config SND_SOC_TAC5X1X_I2C + tristate "Texas Instruments TAC5X1X family driver based on I2C" + depends on I2C + select REGMAP_I2C + help + Enable support for Texas Instruments TAC5X1X family Audio chips. + The family consists mono/stereo audio codecs, DACs and ADCs. + Includes support for TAC5311-Q1, TAC5411-Q1, TAC5111, TAC5211, + TAA5212, TAA5412-Q1, TAD5112, TAD5212, TAC5312, TAC5412-Q1, + TAC5112, TAC5212 + config SND_SOC_TAS2552 tristate "Texas Instruments TAS2552 Mono Audio amplifier" depends on I2C diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index da4077463278..9ddf13a2e5a1 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -309,6 +309,7 @@ snd-soc-sta350-y := sta350.o snd-soc-sta529-y := sta529.o snd-soc-stac9766-y := stac9766.o snd-soc-sti-sas-y := sti-sas.o +snd-soc-tac5x1x-i2c-y := tac5x1x-i2c.o snd-soc-tas5086-y := tas5086.o snd-soc-tas571x-y := tas571x.o snd-soc-tas5720-y := tas5720.o @@ -738,6 +739,7 @@ obj-$(CONFIG_SND_SOC_STA350) += snd-soc-sta350.o obj-$(CONFIG_SND_SOC_STA529) += snd-soc-sta529.o obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o obj-$(CONFIG_SND_SOC_STI_SAS) += snd-soc-sti-sas.o +obj-$(CONFIG_SND_SOC_TAC5X1X_I2C) += snd-soc-tac5x1x-i2c.o obj-$(CONFIG_SND_SOC_TAS2552) += snd-soc-tas2552.o obj-$(CONFIG_SND_SOC_TAS2562) += snd-soc-tas2562.o obj-$(CONFIG_SND_SOC_TAS2764) += snd-soc-tas2764.o diff --git a/sound/soc/codecs/tac5x1x-i2c.c b/sound/soc/codecs/tac5x1x-i2c.c new file mode 100644 index 000000000000..de7d3f3816fa --- /dev/null +++ b/sound/soc/codecs/tac5x1x-i2c.c @@ -0,0 +1,2449 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// tac5x1x.c +// +// Copyright (C) 2022 - 2025 Texas Instruments Incorporated +// +// Author: Kevin Lu +// Author: Kokila Karuppusamy +// Author: Niranjan H Y +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tac5x1x.h" + +struct tac5x1x_setup_gpio { + s32 gpio_func[3]; + s32 gpio_drive[3]; + s32 pdm_input_pins[2]; + s32 gpi1_func; + s32 gpa_gpio; +}; + +struct tac5x1x_input_diag_config { + s32 in_ch_en; + s32 out_ch_en; + s32 incl_se_inm; + s32 incl_ac_coup; +}; + +struct tac5x1x_irqinfo { + s32 irq_gpio; + s32 irq; + bool irq_enable; + u32 *latch_regs; + u8 *latch_data; +}; + +struct tac5x1x_priv { + struct snd_soc_component *component; + struct regmap *regmap; + struct device *dev; + enum tac5x1x_type codec_type; + s32 vref_vg; + s32 micbias_en; + s32 micbias_vg; + s32 uad_en; + s32 vad_en; + s32 uag_en; + s32 micbias_threshold[2]; + s32 gpa_threshold[2]; + s32 adc_impedance[2]; + s32 out2x_vcom_cfg; + u32 ch_enabled; + struct mutex ch_lock; + struct tac5x1x_setup_gpio *gpio_setup; + struct tac5x1x_irqinfo irqinfo; + struct tac5x1x_input_diag_config input_diag_config; + struct delayed_work powerup_work; +}; + +static int tac5x1x_num_regulators = 2; +static struct regulator_bulk_data tac5x1x_regulators[] = { + {.supply = "iovdd"}, + {.supply = "avdd"}, +}; + +struct mask_to_txt { + u8 mask; + const char *const name; +}; + +struct interrupt_info { + u32 reg; + u32 count; + const struct mask_to_txt *mask_str_map; +}; + +#define TAC5X1X_EVENT(bit, evt_txt) (\ + (struct mask_to_txt) { \ + .mask = BIT((bit)), \ + .name = evt_txt \ + }) + +static const struct mask_to_txt int_chx_latch[] = { + TAC5X1X_EVENT(7, "Input Channel1 fault"), + TAC5X1X_EVENT(6, "Input Channel2 fault"), + TAC5X1X_EVENT(5, "Output Channel1 fault"), + TAC5X1X_EVENT(4, "Output Channel2 fault"), + TAC5X1X_EVENT(3, "Short to VBAT_IN"), +}; + +static const struct mask_to_txt in_ch1_latch[] = { + TAC5X1X_EVENT(7, "IN_CH1 open Input"), + TAC5X1X_EVENT(6, "IN_CH1 Input shorted"), + TAC5X1X_EVENT(5, "IN_CH1 INP shorted to GND"), + TAC5X1X_EVENT(4, "IN_CH1 INM shorted to GND"), + TAC5X1X_EVENT(3, "IN_CH1 INP shorted to MICBIAS"), + TAC5X1X_EVENT(2, "IN_CH1 INM shorted to MICBIAS"), + TAC5X1X_EVENT(1, "IN_CH1 INP shorted to VBAT_IN"), + TAC5X1X_EVENT(0, "IN_CH1 INM shorted to VBAT_IN"), +}; + +static const struct mask_to_txt in_ch2_latch[] = { + TAC5X1X_EVENT(7, "IN_CH2 open Input"), + TAC5X1X_EVENT(6, "IN_CH2 Input shorted"), + TAC5X1X_EVENT(5, "IN_CH2 INP shorted to GND"), + TAC5X1X_EVENT(4, "IN_CH2 INM shorted to GND"), + TAC5X1X_EVENT(3, "IN_CH2 INP shorted to MICBIAS"), + TAC5X1X_EVENT(2, "IN_CH2 INM shorted to MICBIAS"), + TAC5X1X_EVENT(1, "IN_CH2 INP shorted to VBAT_IN"), + TAC5X1X_EVENT(0, "IN_CH2 INM shorted to VBAT_IN"), +}; + +static const struct mask_to_txt out_ch1_latch[] = { + TAC5X1X_EVENT(7, "OUT_CH1 OUT1P Short circuit Fault"), + TAC5X1X_EVENT(6, "OUT_CH1 OUT1M Short circuit Fault"), + TAC5X1X_EVENT(5, "OUT_CH1 DRVRP Virtual Ground Fault"), + TAC5X1X_EVENT(4, "OUT_CH1 DRVRM Virtual ground Fault"), + /* masks */ + TAC5X1X_EVENT(3, "OUT_CH1 ADC CH1 Mask"), + TAC5X1X_EVENT(2, "OUT_CH1 ADC CH2 MASK"), +}; + +static const struct mask_to_txt out_ch2_latch[] = { + TAC5X1X_EVENT(7, "OUT_CH2 OUT2P Short circuit Fault"), + TAC5X1X_EVENT(6, "OUT_CH2 OUT2M Short circuit Fault"), + TAC5X1X_EVENT(5, "OUT_CH2 DRVRP Virtual Ground Fault"), + TAC5X1X_EVENT(4, "OUT_CH2 DRVRM Virtual ground Fault"), + /* mask */ + TAC5X1X_EVENT(1, "AREG SC Fault Mask"), + TAC5X1X_EVENT(0, "AREG SC Fault"), +}; + +static const struct mask_to_txt int_latch1[] = { + TAC5X1X_EVENT(7, "CH1 INP Over Voltage"), + TAC5X1X_EVENT(6, "CH1 INM Over Voltage"), + TAC5X1X_EVENT(5, "CH2 INP over Voltage"), + TAC5X1X_EVENT(4, "CH2 INM Over Voltage"), + TAC5X1X_EVENT(3, "Headset Insert Detection"), + TAC5X1X_EVENT(2, "Headset Remove Detection"), + TAC5X1X_EVENT(1, "Headset Hook"), + TAC5X1X_EVENT(0, "MIPS Overload"), +}; + +static const struct mask_to_txt int_latch2[] = { + TAC5X1X_EVENT(7, "GPA Up threashold Fault"), + TAC5X1X_EVENT(6, "GPA low threashold Fault"), + TAC5X1X_EVENT(5, "VAD Power up detect"), + TAC5X1X_EVENT(4, "VAD power down detect"), + TAC5X1X_EVENT(3, "Micbias short circuit"), + TAC5X1X_EVENT(2, "Micbias high current fault"), + TAC5X1X_EVENT(1, "Micbias low current fault"), + TAC5X1X_EVENT(0, "Micbias Over voltage fault"), +}; + +static const struct mask_to_txt int_latch_0[] = { + TAC5X1X_EVENT(7, "Clock Error"), + TAC5X1X_EVENT(6, "PLL Lock"), + TAC5X1X_EVENT(5, "Boost Over Temperature"), + TAC5X1X_EVENT(4, "Boost Over Current"), + TAC5X1X_EVENT(3, "Boost MO"), +}; + +#define LTCH_TO_MASK_STR_MAP(latch_reg, str_map, map_size) (\ + (struct interrupt_info){ \ + .reg = (latch_reg), \ + .count = (map_size), \ + .mask_str_map = (str_map), \ + }) + +static const struct interrupt_info intr_info_list[] = { + LTCH_TO_MASK_STR_MAP(TAC5X1X_CHX_LTCH, int_chx_latch, + ARRAY_SIZE(int_chx_latch)), + LTCH_TO_MASK_STR_MAP(TAC5X1X_IN_CH1_LTCH, in_ch1_latch, + ARRAY_SIZE(in_ch1_latch)), + LTCH_TO_MASK_STR_MAP(TAC5X1X_IN_CH2_LTCH, in_ch2_latch, + ARRAY_SIZE(in_ch2_latch)), + LTCH_TO_MASK_STR_MAP(TAC5X1X_OUT_CH1_LTCH, out_ch1_latch, + ARRAY_SIZE(out_ch1_latch)), + LTCH_TO_MASK_STR_MAP(TAC5X1X_OUT_CH2_LTCH, out_ch2_latch, + ARRAY_SIZE(out_ch2_latch)), + LTCH_TO_MASK_STR_MAP(TAC5X1X_INT_LTCH1, int_latch1, + ARRAY_SIZE(int_latch1)), + LTCH_TO_MASK_STR_MAP(TAC5X1X_INT_LTCH2, int_latch2, + ARRAY_SIZE(int_latch2)), + /* This should be the last entry */ + LTCH_TO_MASK_STR_MAP(TAC5X1X_INT_LTCH0, int_latch_0, + ARRAY_SIZE(int_latch_0)), +}; + +static const struct regmap_range_cfg tac5x1x_ranges[] = { + { + .range_min = 0, + .range_max = 0xfe * 128, + .selector_reg = TAC_PAGE_SELECT, + .selector_mask = GENMASK(7, 0), + .selector_shift = 0, + .window_start = 0, + .window_len = 128, + }, +}; + +static bool tac5x1x_volatile_regs(struct device *dev, unsigned int reg) +{ + bool is_volatile; + + switch (reg) { + case TAC5X1X_RESET: + case TAC5X1X_INT_LTCH0 ... TAC5X1X_INT_LTCH2: + case TAC5X1X_TP_START ... TAC5X1X_TP_END: + is_volatile = true; + break; + + default: + is_volatile = false; + break; + } + + return is_volatile; +} + +static bool tac5x1x_precious_regs(struct device *dev, unsigned int reg) +{ + bool is_precious; + + switch (reg) { + /* self clearing register latches */ + case TAC5X1X_INT_LTCH0 ... TAC5X1X_INT_LTCH2: + is_precious = true; + break; + default: + is_precious = false; + break; + } + + return is_precious; +} + +static const struct regmap_config tac5x1x_regmap = { + .max_register = 0xfe * 128, + .reg_bits = 8, + .val_bits = 8, + .cache_type = REGCACHE_MAPLE, + .ranges = tac5x1x_ranges, + .volatile_reg = tac5x1x_volatile_regs, + .precious_reg = tac5x1x_precious_regs, + .num_ranges = ARRAY_SIZE(tac5x1x_ranges), +}; + + +#define IS_DAC_CH(ch) ((ch) & 0x0f) +#define IS_ADC_CH(ch) ((ch) & 0xf0) + +#define print_regs() \ + do { \ + int val1, ret1, val2, ret2; \ + ret1 = regmap_read(tac5x1x->regmap, TAC5X1X_PWR_CFG, &val1); \ + ret2 = regmap_read(tac5x1x->regmap, TAC5X1X_CH_EN, &val2); \ + dev_dbg(tac5x1x->dev, "REGS: PWR_CFG=0x%x CH_EN=0x%x", val1, val2); \ + } while (0); + +static void post_powerup_work(struct work_struct *work) +{ + u8 mask; + u8 pwr_cfg; + bool ch1_is_pdm; + bool ch2_is_pdm; + u32 input_mode = 0; + struct tac5x1x_priv *tac5x1x = + container_of(work, struct tac5x1x_priv, powerup_work.work); + struct snd_soc_component *component = tac5x1x->component; + + dev_dbg(tac5x1x->dev, "post_powerup: CH_EN 0x%02x 0x%02x", + TAC5X1X_CH_EN, tac5x1x->ch_enabled); + snd_soc_component_write(component, TAC5X1X_CH_EN, tac5x1x->ch_enabled); + + regmap_read(tac5x1x->regmap, TAC5X1X_INTF4, &input_mode); + + /* check if it pdm mode */ + ch1_is_pdm = (input_mode & BIT(7)) ? true : false; + ch2_is_pdm = (input_mode & BIT(6)) ? true : false; + dev_dbg(tac5x1x->dev, "Input mode: 0x%02x, CH1_PDM=%d, CH2_PDM=%d\n", + input_mode, ch1_is_pdm, ch2_is_pdm); + + mutex_lock(&tac5x1x->ch_lock); + mask = pwr_cfg = TAC5X1X_PWR_CFG_ADC_PDZ | + TAC5X1X_PWR_CFG_MICBIAS | TAC5X1X_PWR_CFG_DAC_PDZ; + + if (IS_DAC_CH(tac5x1x->ch_enabled) == 0) + pwr_cfg &= ~TAC5X1X_PWR_CFG_DAC_PDZ; + + if (ch1_is_pdm || ch2_is_pdm) { + /* PDM mode - need ADC_PDZ, no MICBIAS */ + pwr_cfg &= ~TAC5X1X_PWR_CFG_MICBIAS; + dev_dbg(tac5x1x->dev, "PDM: ADC_PDZ on, MICBIAS off, ch_en=0x%x", + tac5x1x->ch_enabled); + } else if (IS_ADC_CH(tac5x1x->ch_enabled)) { + /* Analog ADC mode - keep ADC_PDZ and MICBIAS */ + dev_dbg(tac5x1x->dev, "Analog: ADC_PDZ on, MICBIAS on"); + } else { + /* No ADC/PDM - disable ADC power */ + pwr_cfg &= ~TAC5X1X_PWR_CFG_ADC_PDZ; + pwr_cfg &= ~TAC5X1X_PWR_CFG_MICBIAS; + } + + snd_soc_component_write(component, TAC5X1X_CH_EN, tac5x1x->ch_enabled); + snd_soc_component_update_bits(component, TAC5X1X_PWR_CFG, mask, pwr_cfg); + print_regs(); + mutex_unlock(&tac5x1x->ch_lock); +} + +static int tac5x1x_enable_channel_unlocked(struct snd_soc_component *comp, + bool is_adc, s32 right) +{ + s32 ret; + u8 mask_dev; + u8 mask; + struct tac5x1x_priv *tac5x1x; + + tac5x1x = snd_soc_component_get_drvdata(comp); + if (right) { + mask_dev = TAC5X1X_CH_EN_ADC_CH2 | TAC5X1X_CH_EN_DAC_CH2; + mask = is_adc ? TAC5X1X_CH_EN_ADC_CH2 : TAC5X1X_CH_EN_DAC_CH2; + } else { + mask_dev = TAC5X1X_CH_EN_ADC_CH1 | TAC5X1X_CH_EN_DAC_CH1; + mask = is_adc ? TAC5X1X_CH_EN_ADC_CH1 : TAC5X1X_CH_EN_DAC_CH1; + } + tac5x1x->ch_enabled |= mask; + dev_dbg(tac5x1x->dev, "enable_ch: adc=%d r=%d mask=0x%x dev=0x%x en=0x%x", is_adc, right, mask, mask_dev, tac5x1x->ch_enabled); + ret = snd_soc_component_update_bits(comp, TAC5X1X_CH_EN, + mask_dev, mask_dev); + + return ret; +} + +static int tac5x1x_disable_channel_unlocked(struct snd_soc_component *comp, + bool is_adc, s32 right) +{ + u8 mask; + s32 ret; + struct tac5x1x_priv *tac5x1x; + + tac5x1x = snd_soc_component_get_drvdata(comp); + mask = is_adc ? + (right ? TAC5X1X_CH_EN_ADC_CH2 : TAC5X1X_CH_EN_ADC_CH1) : + (right ? TAC5X1X_CH_EN_DAC_CH2 : TAC5X1X_CH_EN_DAC_CH1); + tac5x1x->ch_enabled &= ~mask; + dev_dbg(tac5x1x->dev, "disable_ch: adc=%d r=%d mask=0x%x en=0x%x", is_adc, right, mask, tac5x1x->ch_enabled); + ret = snd_soc_component_update_bits(comp, TAC5X1X_CH_EN, mask, 0); + + return ret; +} + +/* + * When ADC and DAC are enabled with time delay between them + * the one which is started latter doesn't work because of HW bug. + * So DAC and ADC events with dealyed work is added to follow a + * particular powerup sequence. +*/ +static int tac5x1x_dac_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + u8 pwr_cfg; + int right = w->shift; + int ret = 0; + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct tac5x1x_priv *tac5x1x = snd_soc_component_get_drvdata(component); + + mutex_lock(&tac5x1x->ch_lock); + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + ret = tac5x1x_enable_channel_unlocked(component, false, right); + if (ret < 0) { + dev_err(component->dev, + "Failed to update enable DAC channels\n"); + break; + } + + pwr_cfg = TAC5X1X_PWR_CFG_DAC_PDZ | + TAC5X1X_PWR_CFG_ADC_PDZ | + TAC5X1X_PWR_CFG_MICBIAS; + ret = snd_soc_component_write(component, + TAC5X1X_PWR_CFG, + pwr_cfg); + if (ret) { + dev_err(component->dev, + "Failed to power up DAC\n"); + tac5x1x_disable_channel_unlocked(component, + false, right); + break; + } + print_regs(); + mod_delayed_work(system_wq, &tac5x1x->powerup_work, + msecs_to_jiffies(100)); + break; + + case SND_SOC_DAPM_PRE_PMD: + tac5x1x_disable_channel_unlocked(component, false, right); + if (IS_DAC_CH(tac5x1x->ch_enabled) == 0) + snd_soc_component_update_bits(component, TAC5X1X_PWR_CFG, + TAC5X1X_PWR_CFG_DAC_PDZ, 0); + print_regs(); + break; + } + mutex_unlock(&tac5x1x->ch_lock); + + return ret; +} + +static int tac5x1x_adc_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + u8 pwr_cfg; + u32 right = w->shift; + int ret = 0; + struct snd_soc_component *c = snd_soc_dapm_to_component(w->dapm); + struct tac5x1x_priv *tac5x1x = snd_soc_component_get_drvdata(c); + + mutex_lock(&tac5x1x->ch_lock); + switch (event) { + case SND_SOC_DAPM_POST_PMU: + ret = tac5x1x_enable_channel_unlocked(c, true, right); + if (ret < 0) { + dev_err(c->dev, + "Failed to enable ADC/PDM channel\n"); + break; + } + + pwr_cfg = TAC5X1X_PWR_CFG_ADC_PDZ | + TAC5X1X_PWR_CFG_MICBIAS | + TAC5X1X_PWR_CFG_DAC_PDZ; + ret = snd_soc_component_write(c, TAC5X1X_PWR_CFG, pwr_cfg); + if (ret) { + dev_err(c->dev, "Failed to power up\n"); + tac5x1x_disable_channel_unlocked(c, true, right); + break; + } + + print_regs(); + mod_delayed_work(system_wq, &tac5x1x->powerup_work, + msecs_to_jiffies(100)); + break; + + case SND_SOC_DAPM_PRE_PMD: + tac5x1x_disable_channel_unlocked(c, true, right); + if (IS_ADC_CH(tac5x1x->ch_enabled) == 0) + snd_soc_component_update_bits(c, TAC5X1X_PWR_CFG, + TAC5X1X_PWR_CFG_ADC_PDZ | + TAC5X1X_PWR_CFG_MICBIAS, + 0); + print_regs() + break; + } + mutex_unlock(&tac5x1x->ch_lock); + + return ret; +} + +static void process_one_interrupt(struct tac5x1x_priv *tac5x1x, s32 index, + s32 value) +{ + u32 map_count, i; + const struct mask_to_txt *map_items; + + map_count = intr_info_list[index].count; + map_items = intr_info_list[index].mask_str_map; + + for (i = 0; i < map_count; i++) { + if (value & map_items[i].mask) + dev_dbg(tac5x1x->dev, "Interrupt %s detected\n", + map_items[i].name); + } +} + +static irqreturn_t irq_thread_func(s32 irq, void *dev_id) +{ + u8 latch_set = 0; + u32 latch_count; + s32 i, ret; + struct tac5x1x_priv *tac5x1x = (struct tac5x1x_priv *)dev_id; + + latch_count = ARRAY_SIZE(intr_info_list); + + ret = regmap_multi_reg_read(tac5x1x->regmap, + tac5x1x->irqinfo.latch_regs, + tac5x1x->irqinfo.latch_data, latch_count); + if (ret) { + dev_err(tac5x1x->dev, + "interrupt: latch register read failed"); + return IRQ_NONE; + } + + for (i = 0; i < latch_count; i++) { + dev_dbg(tac5x1x->dev, "reg=0x%0x, val=0x%02x", + tac5x1x->irqinfo.latch_regs[i], + tac5x1x->irqinfo.latch_data[i]); + latch_set |= tac5x1x->irqinfo.latch_data[i] & 0xff; + } + + if (!latch_set) + return IRQ_NONE; + + for (i = 0; i < latch_count; i++) { + if (!tac5x1x->irqinfo.latch_data[i]) + continue; + process_one_interrupt(tac5x1x, i, + tac5x1x->irqinfo.latch_data[i]); + tac5x1x->irqinfo.latch_data[i] = 0; + } + + return IRQ_HANDLED; +} + +static s32 tac5x1x_register_interrupt(struct tac5x1x_priv *tac5x1x) +{ + struct device_node *np = tac5x1x->dev->of_node; + s32 ret, latch_count, i; + u32 *latch_regs; + u8 *latch_data; + + latch_count = ARRAY_SIZE(intr_info_list); + tac5x1x->irqinfo.irq = of_irq_get(np, 0); + if (tac5x1x->irqinfo.irq < 0) + return tac5x1x->irqinfo.irq; + + latch_regs = devm_kzalloc(tac5x1x->dev, latch_count * sizeof(u32), + GFP_KERNEL); + latch_data = devm_kzalloc(tac5x1x->dev, latch_count * sizeof(u8), + GFP_KERNEL); + if (!latch_data || !latch_regs) + return -ENOMEM; + + for (i = 0; i < latch_count; i++) + latch_regs[i] = intr_info_list[i].reg; + + tac5x1x->irqinfo.latch_regs = latch_regs; + tac5x1x->irqinfo.latch_data = latch_data; + + ret = devm_request_threaded_irq(tac5x1x->dev, tac5x1x->irqinfo.irq, + NULL, irq_thread_func, + IRQF_TRIGGER_FALLING | IRQF_ONESHOT, + "TAC-IRQ", tac5x1x); + if (ret) + dev_err(tac5x1x->dev, "request irq failed, irq=%d ret %d\n", + tac5x1x->irqinfo.irq, ret); + + return ret; +} + +/* Record */ +/* ADC Analog/PDM Selection */ +static const char *const tac5x1x_input_source_text[] = {"Analog", "PDM"}; + +static SOC_ENUM_SINGLE_DECL(tac5x1x_in1_source_enum, TAC5X1X_INTF4, 7, + tac5x1x_input_source_text); +static SOC_ENUM_SINGLE_DECL(tac5x1x_in2_source_enum, TAC5X1X_INTF4, 6, + tac5x1x_input_source_text); + +static const struct snd_kcontrol_new tac5x1x_dapm_in1_source_control[] = { + SOC_DAPM_ENUM("CH1 Source MUX", tac5x1x_in1_source_enum), +}; + +static const struct snd_kcontrol_new tac5x1x_dapm_in2_source_control[] = { + SOC_DAPM_ENUM("CH2 Source MUX", tac5x1x_in2_source_enum), +}; + +static const char *const tad5x1x_input_source_text[] = {"Disable", "PDM"}; +static SOC_ENUM_SINGLE_DECL(tad5x1x_in1_source_enum, TAC5X1X_INTF4, 7, + tad5x1x_input_source_text); +static SOC_ENUM_SINGLE_DECL(tad5x1x_in2_source_enum, TAC5X1X_INTF4, 6, + tad5x1x_input_source_text); + +static const struct snd_kcontrol_new tad5x1x_dapm_in1_source_control[] = { + SOC_DAPM_ENUM("CH1 Source MUX", tad5x1x_in1_source_enum), +}; + +static const struct snd_kcontrol_new tad5x1x_dapm_in2_source_control[] = { + SOC_DAPM_ENUM("CH2 Source MUX", tad5x1x_in2_source_enum), +}; + +/* ADC Analog source Selection */ +static const char *const tac5x1x_input_analog_sel_text[] = { + "Differential", + "Single-ended", + "Single-ended mux INxP", + "Single-ended mux INxM", +}; + +static const char *const tac5x1x_input_analog2_sel_text[] = { + "Differential", + "Single-ended", +}; + +static SOC_ENUM_SINGLE_DECL(tac5x1x_adc1_config_enum, TAC5X1X_ADCCH1C0, 6, + tac5x1x_input_analog_sel_text); +static SOC_ENUM_SINGLE_DECL(tac5x1x_adc2_config_enum, TAC5X1X_ADCCH2C0, 6, + tac5x1x_input_analog2_sel_text); + +static const struct snd_kcontrol_new tac5x1x_dapm_adc1_config_control[] = { + SOC_DAPM_ENUM("ADC1 Analog MUX", tac5x1x_adc1_config_enum), +}; + +static const struct snd_kcontrol_new tac5x1x_dapm_adc2_config_control[] = { + SOC_DAPM_ENUM("ADC2 Analog MUX", tac5x1x_adc2_config_enum), +}; + +/* + * ADC full-scale selection + * 2/10-VRMS is for TAX52xx/TAX51xx devices + * 4/5-VRMS is for TAX54xx/TAX53xx devices + */ +static const char *const tac5x1x_adc_fscale_text[] = {"2/10-VRMS", + "4/5-VRMS"}; + +static SOC_ENUM_SINGLE_DECL(tac5x1x_adc1_fscale_enum, TAC5X1X_ADCCH1C0, 1, + tac5x1x_adc_fscale_text); +static SOC_ENUM_SINGLE_DECL(tac5x1x_adc2_fscale_enum, TAC5X1X_ADCCH2C0, 1, + tac5x1x_adc_fscale_text); + +static const struct snd_kcontrol_new tac5x1x_dapm_adc1_fscale_control[] = { + SOC_DAPM_ENUM("ADC1 FSCALE MUX", tac5x1x_adc1_fscale_enum), +}; + +static const struct snd_kcontrol_new tac5x1x_dapm_adc2_fscale_control[] = { + SOC_DAPM_ENUM("ADC2 FSCALE MUX", tac5x1x_adc2_fscale_enum), +}; + +static const char *const pdmclk_text[] = { + "2.8224 MHz or 3.072 MHz", "1.4112 MHz or 1.536 MHz", + "705.6 kHz or 768 kHz", "5.6448 MHz or 6.144 MHz"}; + +static SOC_ENUM_SINGLE_DECL(pdmclk_select_enum, TAC5X1X_CNTCLK0, 6, + pdmclk_text); + +/* Digital Volume control. From -80 to 47 dB in 0.5 dB steps */ +static DECLARE_TLV_DB_SCALE(record_dig_vol_tlv, -8000, 50, 0); + +/* Gain Calibration control. From -0.8db to 0.7db dB in 0.1 dB steps */ +static DECLARE_TLV_DB_MINMAX(record_gain_cali_tlv, -80, 70); + +/* Analog Level control. From -12 to 24 dB in 6 dB steps */ +static DECLARE_TLV_DB_SCALE(playback_analog_level_tlv, -1200, 600, 0); + +/* Digital Volume control. From -100 to 27 dB in 0.5 dB steps */ +static DECLARE_TLV_DB_SCALE(dac_dig_vol_tlv, -10000, 50, 0); // mute ? + +/* Gain Calibration control. From -0.8db to 0.7db dB in 0.1 dB steps */ +static DECLARE_TLV_DB_MINMAX(playback_gain_cali_tlv, -80, 70); + +/* Output Source Selection */ +static const char *const tac5x1x_output_source_text[] = { + "Disabled", + "DAC Input", + "Analog Bypass", + "DAC + Analog Bypass Mix", + "DAC -> OUTxP, INxP -> OUTxM", + "INxM -> OUTxP, DAC -> OUTxM", +}; + +static SOC_ENUM_SINGLE_DECL(tac5x1x_out1_source_enum, TAC5X1X_OUT1CFG0, 5, + tac5x1x_output_source_text); +static SOC_ENUM_SINGLE_DECL(tac5x1x_out2_source_enum, TAC5X1X_OUT2CFG0, 5, + tac5x1x_output_source_text); + +static const struct snd_kcontrol_new tac5x1x_dapm_out1_source_control[] = { + SOC_DAPM_ENUM("OUT1X MUX", tac5x1x_out1_source_enum), +}; + +static const struct snd_kcontrol_new tac5x1x_dapm_out2_source_control[] = { + SOC_DAPM_ENUM("OUT2X MUX", tac5x1x_out2_source_enum), +}; + +/* Output Config Selection */ +static const char *const tac5x1x_output_config_text[] = { + "Differential", + "Stereo Single-ended", + "Mono Single-ended at OUTxP only", + "Mono Single-ended at OUTxM only", + "Pseudo differential with OUTxM as VCOM", + "Pseudo differential with OUTxM as external sensing", + "Pseudo differential with OUTxP as VCOM", +}; + +static const char *const tac5x1x_output2_config_text[] = { + "Differential", + "Stereo Single-ended", + "Mono Single-ended at OUTxP only", + "Mono Single-ended at OUTxM only", + "Pseudo differential with OUTxM as VCOM", + "Pseudo differential with OUTxP as VCOM", +}; + +static const s32 tac5x1x_output2_config_values[] = { + 0, 1, 2, 3, 4, 6 +}; + +static SOC_ENUM_SINGLE_DECL(tac5x1x_out1_config_enum, TAC5X1X_OUT1CFG0, 2, + tac5x1x_output_config_text); +static SOC_VALUE_ENUM_SINGLE_DECL(tac5x1x_out2_config_enum, + TAC5X1X_OUT2CFG0, 2, 0x7, + tac5x1x_output2_config_text, + tac5x1x_output2_config_values); + +static const struct snd_kcontrol_new tac5x1x_dapm_out1_config_control[] = { + SOC_DAPM_ENUM("OUT1X Config MUX", tac5x1x_out1_config_enum), +}; + +static const struct snd_kcontrol_new tac5x1x_dapm_out2_config_control[] = { + SOC_DAPM_ENUM("OUT2X Config MUX", tac5x1x_out2_config_enum), +}; + +static const char *const tac5x1x_wideband_text[] = { + "Audio BW 24-kHz", + "Wide BW 96-kHz", +}; + +static SOC_ENUM_SINGLE_DECL(tac5x1x_adc1_wideband_enum, TAC5X1X_ADCCH1C0, 0, + tac5x1x_wideband_text); +static SOC_ENUM_SINGLE_DECL(tac5x1x_adc2_wideband_enum, TAC5X1X_ADCCH2C0, 0, + tac5x1x_wideband_text); +static SOC_ENUM_SINGLE_DECL(tac5x1x_dac1_wideband_enum, TAC5X1X_OUT1CFG1, 0, + tac5x1x_wideband_text); +static SOC_ENUM_SINGLE_DECL(tac5x1x_dac2_wideband_enum, TAC5X1X_OUT2CFG1, 0, + tac5x1x_wideband_text); + +static const char *const tac5x1x_tolerance_text[] = { + "AC Coupled with 100mVpp", + "AC/DC Coupled with 1Vpp", + "AC/DC Coupled with Rail-to-rail", +}; + +static SOC_ENUM_SINGLE_DECL(tac5x1x_adc1_tolerance_enum, TAC5X1X_ADCCH1C0, 2, + tac5x1x_tolerance_text); +static SOC_ENUM_SINGLE_DECL(tac5x1x_adc2_tolerance_enum, TAC5X1X_ADCCH2C0, 2, + tac5x1x_tolerance_text); + +/* Output Drive Selection */ +static const char *const tac5x1x_output_driver_text[] = { + "Line-out", + "Headphone", + "4 ohm", + "FD Receiver/Debug", +}; + +static SOC_ENUM_SINGLE_DECL(out1p_driver_enum, TAC5X1X_OUT1CFG1, 6, + tac5x1x_output_driver_text); + +static SOC_ENUM_SINGLE_DECL(out2p_driver_enum, TAC5X1X_OUT2CFG1, 6, + tac5x1x_output_driver_text); + +static const struct snd_kcontrol_new tac5x1x_dapm_out1_driver_control[] = { + SOC_DAPM_ENUM("OUT1 driver MUX", out1p_driver_enum), +}; + +static const struct snd_kcontrol_new tac5x1x_dapm_out2_driver_control[] = { + SOC_DAPM_ENUM("OUT2 driver MUX", out2p_driver_enum), +}; + +/* Decimation Filter Selection */ +static const char *const decimation_filter_text[] = { + "Linear Phase", "Low Latency", "Ultra-low Latency"}; + +static SOC_ENUM_SINGLE_DECL(decimation_filter_record_enum, TAC5X1X_DSP0, 6, + decimation_filter_text); +static SOC_ENUM_SINGLE_DECL(decimation_filter_playback_enum, TAC5X1X_DSP1, 6, + decimation_filter_text); + +static const struct snd_kcontrol_new tx_ch1_asi_switch = + SOC_DAPM_SINGLE("Capture Switch", TAC5X1X_PASITXCH1, 5, 1, 0); +static const struct snd_kcontrol_new tx_ch2_asi_switch = + SOC_DAPM_SINGLE("Capture Switch", TAC5X1X_PASITXCH2, 5, 1, 0); +static const struct snd_kcontrol_new tx_ch3_asi_switch = + SOC_DAPM_SINGLE("Capture Switch", TAC5X1X_PASITXCH3, 5, 1, 0); +static const struct snd_kcontrol_new tx_ch4_asi_switch = + SOC_DAPM_SINGLE("Capture Switch", TAC5X1X_PASITXCH4, 5, 1, 0); + +static const struct snd_kcontrol_new rx_ch1_asi_switch = + SOC_DAPM_SINGLE("Switch", TAC5X1X_PASIRXCH1, 5, 1, 0); +static const struct snd_kcontrol_new rx_ch2_asi_switch = + SOC_DAPM_SINGLE("Switch", TAC5X1X_PASIRXCH2, 5, 1, 0); + +static const char *const rx_ch5_asi_cfg_text[] = { + "Disable", + "DAC channel data", + "ADC channel output loopback", +}; + +static const char *const rx_ch6_asi_cfg_text[] = { + "Disable", + "DAC channel data", + "ADC channel output loopback", + "Channel Input to ICLA device", +}; + +static const char *const tx_ch5_asi_cfg_text[] = { + "Tristate", + "Input Channel Loopback data", + "Echo reference Channel data", +}; + +static const char *const tx_ch7_asi_cfg_text[] = { + "Tristate", + "Vbat_Wlby2,Temp_Wlby2", + "echo_ref_ch1,echo_ref_ch2", +}; + +static const char *const tx_ch8_asi_cfg_text[] = { + "Tristate", + "ICLA data", +}; + +static const char *const diag_cfg_text[] = { + "0mv", "30mv", "60mv", "90mv", + "120mv", "150mv", "180mv", "210mv", + "240mv", "270mv", "300mv", "330mv", + "360mv", "390mv", "420mv", "450mv", +}; + +static const char *const diag_cfg_gnd_text[] = { + "0mv", "60mv", "120mv", "180mv", + "240mv", "300mv", "360mv", "420mv", + "480mv", "540mv", "600mv", "660mv", + "720mv", "780mv", "840mv", "900mv", +}; + +static const char *const tac5x1x_tdm_slot_text[] = { + "Slot0", "Slot1", "Slot2", "Slot3", + "Slot4", "Slot5", "Slot6", "Slot7", + "Slot8", "Slot9", "Slot10", "Slot11", + "Slot12", "Slot13", "Slot14", "Slot15", + "Slot16", "Slot17", "Slot18", "Slot19", + "Slot20", "Slot21", "Slot22", "Slot23", + "Slot24", "Slot25", "Slot26", "Slot27", + "Slot28", "Slot29", "Slot30", "Slot31", +}; + +static SOC_ENUM_SINGLE_DECL(tx_ch5_asi_cfg_enum, TAC5X1X_PASITXCH5, 5, + tx_ch5_asi_cfg_text); +static SOC_ENUM_SINGLE_DECL(tx_ch6_asi_cfg_enum, TAC5X1X_PASITXCH6, 5, + tx_ch5_asi_cfg_text); +static SOC_ENUM_SINGLE_DECL(tx_ch7_asi_cfg_enum, TAC5X1X_PASITXCH7, 5, + tx_ch7_asi_cfg_text); +static SOC_ENUM_SINGLE_DECL(tx_ch8_asi_cfg_enum, TAC5X1X_PASITXCH8, 5, + tx_ch8_asi_cfg_text); +static SOC_ENUM_SINGLE_DECL(rx_ch5_asi_cfg_enum, TAC5X1X_PASIRXCH5, 5, + rx_ch5_asi_cfg_text); +static SOC_ENUM_SINGLE_DECL(rx_ch6_asi_cfg_enum, TAC5X1X_PASIRXCH6, 5, + rx_ch6_asi_cfg_text); +static SOC_ENUM_SINGLE_DECL(rx_ch7_asi_cfg_enum, TAC5X1X_PASIRXCH7, 5, + rx_ch6_asi_cfg_text); +static SOC_ENUM_SINGLE_DECL(rx_ch8_asi_cfg_enum, TAC5X1X_PASIRXCH8, 5, + rx_ch6_asi_cfg_text); +static SOC_ENUM_SINGLE_DECL(diag_cfg1_sht_term_enum, TAC5X1X_DIAG_CFG1, 4, + diag_cfg_text); +static SOC_ENUM_SINGLE_DECL(diag_cfg1_vbat_in_enum, TAC5X1X_DIAG_CFG1, 0, + diag_cfg_text); +static SOC_ENUM_SINGLE_DECL(diag_cfg2_sht_gnd_enum, TAC5X1X_DIAG_CFG2, 4, + diag_cfg_gnd_text); +static SOC_ENUM_SINGLE_DECL(diag_cfg2_micbias, TAC5X1X_DIAG_CFG2, 0, + diag_cfg_text); + +static SOC_ENUM_SINGLE_DECL(rx_ch1_slot_enum, TAC5X1X_PASIRXCH1, 0, + tac5x1x_tdm_slot_text); +static SOC_ENUM_SINGLE_DECL(rx_ch2_slot_enum, TAC5X1X_PASIRXCH2, 0, + tac5x1x_tdm_slot_text); +static SOC_ENUM_SINGLE_DECL(rx_ch3_slot_enum, TAC5X1X_PASIRXCH3, 0, + tac5x1x_tdm_slot_text); +static SOC_ENUM_SINGLE_DECL(rx_ch4_slot_enum, TAC5X1X_PASIRXCH4, 0, + tac5x1x_tdm_slot_text); +static SOC_ENUM_SINGLE_DECL(tx_ch1_slot_enum, TAC5X1X_PASITXCH1, 0, + tac5x1x_tdm_slot_text); +static SOC_ENUM_SINGLE_DECL(tx_ch2_slot_enum, TAC5X1X_PASITXCH2, 0, + tac5x1x_tdm_slot_text); +static SOC_ENUM_SINGLE_DECL(tx_ch3_slot_enum, TAC5X1X_PASITXCH3, 0, + tac5x1x_tdm_slot_text); +static SOC_ENUM_SINGLE_DECL(tx_ch4_slot_enum, TAC5X1X_PASITXCH4, 0, + tac5x1x_tdm_slot_text); + +static const struct snd_kcontrol_new taa5x1x_controls[] = { + SOC_ENUM("Record Decimation Filter", + decimation_filter_record_enum), + SOC_ENUM("ADC1 Audio BW", tac5x1x_adc1_wideband_enum), + + SOC_SINGLE_TLV("ADC1 Digital Capture Volume", TAC5X1X_ADCCH1C2, + 0, 0xff, 0, record_dig_vol_tlv), + + SOC_SINGLE_TLV("ADC1 Fine Capture Volume", TAC5X1X_ADCCH1C3, + 0, 0xff, 0, record_gain_cali_tlv), + + SOC_SINGLE_RANGE("ADC1 Phase Capture Volume", TAC5X1X_ADCCH1C4, + 2, 0, 63, 0), + + SOC_ENUM("ASI_TX_CH5_CFG", tx_ch5_asi_cfg_enum), + SOC_ENUM("ASI_TX_CH6_CFG", tx_ch6_asi_cfg_enum), + SOC_ENUM("ASI_TX_CH7_CFG", tx_ch7_asi_cfg_enum), + SOC_ENUM("ASI_TX_CH8_CFG", tx_ch8_asi_cfg_enum), +}; + +static const struct snd_kcontrol_new tac5x1x_tdm_slot_controls[] = { + SOC_ENUM("ASI_RX_CH1 Slot", rx_ch1_slot_enum), + SOC_ENUM("ASI_RX_CH2 Slot", rx_ch2_slot_enum), + SOC_ENUM("ASI_RX_CH3 Slot", rx_ch3_slot_enum), + SOC_ENUM("ASI_RX_CH4 Slot", rx_ch4_slot_enum), + SOC_ENUM("ASI_TX_CH1 Slot", tx_ch1_slot_enum), + SOC_ENUM("ASI_TX_CH2 Slot", tx_ch2_slot_enum), + SOC_ENUM("ASI_TX_CH3 Slot", tx_ch3_slot_enum), + SOC_ENUM("ASI_TX_CH4 Slot", tx_ch4_slot_enum), +}; + +static const struct snd_kcontrol_new tad5x1x_controls[] = { + SOC_ENUM("Playback Decimation Filter", + decimation_filter_playback_enum), + SOC_ENUM("DAC1 Audio BW", tac5x1x_dac1_wideband_enum), + SOC_SINGLE_TLV("OUT1P Analog Level Playback Volume", TAC5X1X_OUT1CFG1, + 3, 6, 1, playback_analog_level_tlv), + SOC_SINGLE_TLV("OUT1M Analog Level Playback Volume", TAC5X1X_OUT1CFG2, + 3, 6, 1, playback_analog_level_tlv), + SOC_SINGLE_TLV("DAC1 CHA Digital Playback Volume", TAC5X1X_DACCH1A0, + 0, 0xff, 0, dac_dig_vol_tlv), + SOC_SINGLE_TLV("DAC1 CHB Digital Playback Volume", TAC5X1X_DACCH1B0, + 0, 0xff, 0, dac_dig_vol_tlv), + SOC_SINGLE_TLV("DAC1 CHA Gain Calibration Playback Volume", + TAC5X1X_DACCH1A1, 4, 0xf, 0, + playback_gain_cali_tlv), + SOC_SINGLE_TLV("DAC1 CHB Gain Calibration Playback Volume", + TAC5X1X_DACCH1B1, 4, 0xf, 0, + playback_gain_cali_tlv), + + SOC_SINGLE("ASI_RX_CH3_EN Playback Switch", + TAC5X1X_PASIRXCH3, 5, 1, 0), + SOC_SINGLE("ASI_RX_CH4_EN Playback Switch", + TAC5X1X_PASIRXCH4, 5, 1, 0), + SOC_ENUM("ASI_RX_CH5_EN Playback", rx_ch5_asi_cfg_enum), + SOC_ENUM("ASI_RX_CH6_EN Playback", rx_ch6_asi_cfg_enum), + SOC_ENUM("ASI_RX_CH7_EN Playback", rx_ch7_asi_cfg_enum), + SOC_ENUM("ASI_RX_CH8_EN Playback", rx_ch8_asi_cfg_enum), +}; + +static const struct snd_kcontrol_new tac5x11_controls[] = { + SOC_ENUM("ADC1 Common-mode Tolerance", tac5x1x_adc1_tolerance_enum), +}; + +static const struct snd_kcontrol_new tad5x12_controls[] = { + SOC_SINGLE_TLV("OUT2P Analog Level Playback Volume", TAC5X1X_OUT2CFG1, + 3, 6, 1, playback_analog_level_tlv), + SOC_SINGLE_TLV("OUT2M Analog Level Playback Volume", TAC5X1X_OUT2CFG2, + 3, 6, 1, playback_analog_level_tlv), + SOC_SINGLE_TLV("DAC2 CHA Digital Playback Volume", TAC5X1X_DACCH2A0, + 0, 0xff, 0, dac_dig_vol_tlv), + SOC_SINGLE_TLV("DAC2 CHB Digital Playback Volume", TAC5X1X_DACCH2B0, + 0, 0xff, 0, dac_dig_vol_tlv), + SOC_SINGLE_TLV("DAC2 CHA Gain Calibration Playback Volume", + TAC5X1X_DACCH2A1, 4, 0xf, 0, + playback_gain_cali_tlv), + SOC_SINGLE_TLV("DAC2 CHB Gain Calibration Playback Volume", + TAC5X1X_DACCH2B1, 4, 0xf, 0, + playback_gain_cali_tlv), + SOC_ENUM("DAC2 Audio BW", tac5x1x_dac2_wideband_enum), +}; + +static const struct snd_kcontrol_new taa5x12_controls[] = { + SOC_ENUM("ADC2 Audio BW", tac5x1x_adc2_wideband_enum), + + SOC_SINGLE_TLV("ADC2 Digital Capture Volume", TAC5X1X_ADCCH2C2, + 0, 0xff, 0, record_dig_vol_tlv), + + SOC_SINGLE_TLV("ADC2 Fine Capture Volume", TAC5X1X_ADCCH2C3, + 0, 0xff, 0, record_gain_cali_tlv), + + SOC_SINGLE_RANGE("ADC2 Phase Capture Volume", TAC5X1X_ADCCH2C4, + 2, 0, 63, 0), +}; + +static const struct snd_kcontrol_new tolerance_ctrls[] = { + SOC_ENUM("ADC1 Common-mode Tolerance", tac5x1x_adc1_tolerance_enum), + SOC_ENUM("ADC2 Common-mode Tolerance", tac5x1x_adc2_tolerance_enum), +}; + +static const struct snd_kcontrol_new tac5x1x_pdm_controls[] = { + SOC_ENUM("PDM Clk Divider", pdmclk_select_enum), + + SOC_SINGLE_TLV("PDM1 Digital Capture Volume", TAC5X1X_ADCCH1C2, + 0, 0xff, 0, record_dig_vol_tlv), + SOC_SINGLE_TLV("PDM2 Digital Capture Volume", TAC5X1X_ADCCH2C2, + 0, 0xff, 0, record_dig_vol_tlv), + SOC_SINGLE_TLV("PDM1 Fine Capture Volume", TAC5X1X_ADCCH1C3, + 0, 0xff, 0, record_gain_cali_tlv), + SOC_SINGLE_TLV("PDM2 Fine Capture Volume", TAC5X1X_ADCCH2C3, + 0, 0xff, 0, record_gain_cali_tlv), + SOC_SINGLE_RANGE("PDM1 Phase Capture Volume", TAC5X1X_ADCCH1C4, + 2, 0, 63, 0), + SOC_SINGLE_RANGE("PDM2 Phase Capture Volume", TAC5X1X_ADCCH2C4, + 2, 0, 63, 0), + SOC_SINGLE_TLV("PDM3 Digital Capture Volume", TAC5X1X_ADCCH3C2, + 0, 0xff, 0, record_dig_vol_tlv), + SOC_SINGLE_TLV("PDM4 Digital Capture Volume", TAC5X1X_ADCCH4C2, + 0, 0xff, 0, record_dig_vol_tlv), + SOC_SINGLE_TLV("PDM3 Fine Capture Volume", TAC5X1X_ADCCH3C3, + 0, 0xff, 0, record_gain_cali_tlv), + SOC_SINGLE_TLV("PDM4 Fine Capture Volume", TAC5X1X_ADCCH4C3, + 0, 0xff, 0, record_gain_cali_tlv), + SOC_SINGLE_RANGE("PDM3 Phase Capture Volume", TAC5X1X_ADCCH3C4, + 2, 0, 63, 0), + SOC_SINGLE_RANGE("PDM4 Phase Capture Volume", TAC5X1X_ADCCH4C4, + 2, 0, 63, 0), +}; + +static const struct snd_kcontrol_new taa_ip_controls[] = { + SOC_ENUM("DIAG_SHT_TERM", diag_cfg1_sht_term_enum), + SOC_ENUM("DIAG_SHT_VBAT_IN", diag_cfg1_vbat_in_enum), + SOC_ENUM("DIAG_SHT_GND", diag_cfg2_sht_gnd_enum), + SOC_ENUM("DIAG_SHT_MICBIAS", diag_cfg2_micbias), +}; + +static const struct snd_soc_dapm_widget taa5x1x_dapm_widgets[] = { + /* ADC1 */ + SND_SOC_DAPM_INPUT("AIN1"), + SND_SOC_DAPM_MUX("ADC1 Full-Scale", SND_SOC_NOPM, 0, 0, + tac5x1x_dapm_adc1_fscale_control), + SND_SOC_DAPM_MUX("ADC1 Config", SND_SOC_NOPM, 0, 0, + tac5x1x_dapm_adc1_config_control), + SND_SOC_DAPM_ADC_E("CH1_ADC_EN", "CH1 Capture", SND_SOC_NOPM, 0, 0, + tac5x1x_adc_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_SWITCH("ASI_TX_CH1_EN", SND_SOC_NOPM, 0, 0, + &tx_ch1_asi_switch), + SND_SOC_DAPM_MICBIAS("Mic Bias", SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_SWITCH("ASI_TX_CH2_EN", SND_SOC_NOPM, 0, 0, + &tx_ch2_asi_switch), +}; + +static const struct snd_soc_dapm_widget tad5xx_dapm_widgets[] = { + /* pdm capture */ + SND_SOC_DAPM_SWITCH("ASI_TX_CH1_EN", SND_SOC_NOPM, 0, 0, + &tx_ch1_asi_switch), + SND_SOC_DAPM_SWITCH("ASI_TX_CH2_EN", SND_SOC_NOPM, 0, 0, + &tx_ch2_asi_switch), +}; + +static const struct snd_soc_dapm_widget tad5x1x_dapm_widgets[] = { + /* DAC1 */ + SND_SOC_DAPM_AIF_IN("ASI IN1", "ASI Playback", 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_OUTPUT("OUT1"), + SND_SOC_DAPM_MUX("OUT1x Source", SND_SOC_NOPM, 0, 0, + tac5x1x_dapm_out1_source_control), + SND_SOC_DAPM_MUX("OUT1x Config", SND_SOC_NOPM, 0, 0, + tac5x1x_dapm_out1_config_control), + SND_SOC_DAPM_MUX("OUT1x Driver", SND_SOC_NOPM, 0, 0, + tac5x1x_dapm_out1_driver_control), + SND_SOC_DAPM_DAC_E("Left DAC Enable", "Left Playback", SND_SOC_NOPM, 0, 0, + tac5x1x_dac_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_SWITCH("ASI_RX_CH1_EN", SND_SOC_NOPM, 0, 0, + &rx_ch1_asi_switch), +}; + +static const struct snd_soc_dapm_widget taa5x12_dapm_widgets[] = { + /* ADC2 */ + SND_SOC_DAPM_INPUT("AIN2"), + SND_SOC_DAPM_MUX("ADC2 Full-Scale", SND_SOC_NOPM, 0, 0, + tac5x1x_dapm_adc2_fscale_control), + SND_SOC_DAPM_MUX("ADC2 Config", SND_SOC_NOPM, 0, 0, + tac5x1x_dapm_adc2_config_control), + SND_SOC_DAPM_ADC_E("CH2_ADC_EN", "CH2 Capture", SND_SOC_NOPM, 1, 0, + tac5x1x_adc_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), + +}; + +static const struct snd_soc_dapm_widget tad5x12_dapm_widgets[] = { + /* DAC2 */ + SND_SOC_DAPM_OUTPUT("OUT2"), + + SND_SOC_DAPM_AIF_IN("ASI IN2", "ASI Playback", 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_MUX("OUT2x Source", SND_SOC_NOPM, 0, 0, + tac5x1x_dapm_out2_source_control), + SND_SOC_DAPM_MUX("OUT2x Config", SND_SOC_NOPM, 0, 0, + tac5x1x_dapm_out2_config_control), + SND_SOC_DAPM_MUX("OUT2x Driver", SND_SOC_NOPM, 0, 0, + tac5x1x_dapm_out2_driver_control), + SND_SOC_DAPM_DAC_E("Right DAC Enable", "Right Playback", SND_SOC_NOPM, 1, 0, + tac5x1x_dac_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), + + SND_SOC_DAPM_SWITCH("ASI_RX_CH2_EN", SND_SOC_NOPM, 0, 0, + &rx_ch2_asi_switch), +}; + +static const struct snd_soc_dapm_widget tac5x1x_pdm_widgets[] = { + /* PDM */ + SND_SOC_DAPM_INPUT("DIN1"), + SND_SOC_DAPM_INPUT("DIN2"), + SND_SOC_DAPM_INPUT("DIN3"), + SND_SOC_DAPM_INPUT("DIN4"), + + SND_SOC_DAPM_ADC_E("CH1_PDM_EN", "PDM CH1 Capture", SND_SOC_NOPM, 0, 0, + tac5x1x_adc_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_ADC_E("CH2_PDM_EN", "PDM CH2 Capture", SND_SOC_NOPM, 1, 0, + tac5x1x_adc_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_ADC_E("CH3_PDM_EN", "PDM CH3 Capture", SND_SOC_NOPM, 2, 0, + tac5x1x_adc_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_ADC_E("CH4_PDM_EN", "PDM CH4 Capture", SND_SOC_NOPM, 3, 0, + tac5x1x_adc_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), + + SND_SOC_DAPM_SWITCH("ASI_TX_CH3_EN", SND_SOC_NOPM, 0, 0, + &tx_ch3_asi_switch), + SND_SOC_DAPM_SWITCH("ASI_TX_CH4_EN", SND_SOC_NOPM, 0, 0, + &tx_ch4_asi_switch), +}; + +static const struct snd_soc_dapm_widget tac5x1x_common_widgets[] = { + SND_SOC_DAPM_MUX("IN1 Source Mux", SND_SOC_NOPM, 0, 0, + tac5x1x_dapm_in1_source_control), + SND_SOC_DAPM_MUX("IN2 Source Mux", SND_SOC_NOPM, 0, 0, + tac5x1x_dapm_in2_source_control), + SND_SOC_DAPM_AIF_OUT("AIF OUT", "ASI Capture", 0, SND_SOC_NOPM, 0, 0), +}; + +static const struct snd_soc_dapm_widget tad_common_widgets[] = { + SND_SOC_DAPM_MUX("IN1 Source Mux", SND_SOC_NOPM, 0, 0, + tad5x1x_dapm_in1_source_control), + SND_SOC_DAPM_MUX("IN2 Source Mux", SND_SOC_NOPM, 0, 0, + tad5x1x_dapm_in2_source_control), + SND_SOC_DAPM_AIF_OUT("AIF OUT", "ASI Capture", 0, SND_SOC_NOPM, 0, 0), +}; + +static const struct snd_soc_dapm_route taa5x1x_dapm_routes[] = { + /* ADC channel1 */ + {"IN1 Source Mux", "Analog", "AIN1"}, + {"IN2 Source Mux", "Analog", "IN1 Source Mux"}, + {"CH1_ADC_EN", NULL, "IN2 Source Mux"}, + {"ASI_TX_CH1_EN", "Capture Switch", "CH1_ADC_EN"}, + {"ADC1 Config", "Differential", "ASI_TX_CH1_EN"}, + {"ADC1 Config", "Single-ended", "ASI_TX_CH1_EN"}, + {"ADC1 Config", "Single-ended mux INxP", + "ASI_TX_CH1_EN"}, + {"ADC1 Config", "Single-ended mux INxM", + "ASI_TX_CH1_EN"}, + + {"ADC1 Full-Scale", "2/10-VRMS", "ADC1 Config"}, + {"ADC1 Full-Scale", "4/5-VRMS", "ADC1 Config"}, + {"Mic Bias", NULL, "ADC1 Full-Scale"}, + +}; + +static const struct snd_soc_dapm_route tad5x1x_dapm_routes[] = { + /* Left Output */ + {"ASI_RX_CH1_EN", "Switch", "ASI IN1"}, + + {"OUT1x Source", "DAC + Analog Bypass Mix", "ASI_RX_CH1_EN"}, + {"OUT1x Source", "DAC -> OUTxP, INxP -> OUTxM", "ASI_RX_CH1_EN"}, + {"OUT1x Source", "INxM -> OUTxP, DAC -> OUTxM", "ASI_RX_CH1_EN"}, + + {"OUT1x Config", "Differential", "OUT1x Source"}, + // {"OUT1x Config", "Stereo Single-ended", "OUT1x Source"}, + {"OUT1x Config", "Mono Single-ended at OUTxP only", "OUT1x Source"}, + {"OUT1x Config", "Mono Single-ended at OUTxM only", "OUT1x Source"}, + {"OUT1x Config", "Pseudo differential with OUTxM as VCOM", + "OUT1x Source"}, + {"OUT1x Config", "Pseudo differential with OUTxM as external sensing", + "OUT1x Source"}, + {"OUT1x Config", "Pseudo differential with OUTxP as VCOM", + "OUT1x Source"}, + + {"OUT1x Driver", "Line-out", "OUT1x Config"}, + {"OUT1x Driver", "Headphone", "OUT1x Config"}, + + {"Left DAC Enable", NULL, "OUT1x Driver"}, + {"OUT1", NULL, "Left DAC Enable"}, +}; + +static const struct snd_soc_dapm_route taa5x12_dapm_routes[] = { + /* ADC channel2 */ + {"CH2_ADC_EN", NULL, "AIN2"}, + {"ASI_TX_CH2_EN", "Capture Switch", "CH2_ADC_EN"}, + {"ADC2 Config", "Differential", "ASI_TX_CH2_EN"}, + {"ADC2 Config", "Single-ended", "ASI_TX_CH2_EN"}, + {"ADC2 Full-Scale", "2/10-VRMS", + "ADC2 Config"}, + {"ADC2 Full-Scale", "4/5-VRMS", + "ADC2 Config"}, + + {"Mic Bias", NULL, "ADC2 Full-Scale"}, +}; + +static const struct snd_soc_dapm_route tad5x12_dapm_routes[] = { + /* Right Output */ + {"ASI_RX_CH2_EN", "Switch", "ASI IN2"}, + + {"OUT2x Source", "DAC + Analog Bypass Mix", "ASI_RX_CH1_EN"}, + {"OUT2x Source", "DAC -> OUTxP, INxP -> OUTxM", "ASI_RX_CH1_EN"}, + {"OUT2x Source", "INxM -> OUTxP, DAC -> OUTxM", "ASI_RX_CH1_EN"}, + + {"OUT2x Config", "Differential", "OUT2x Source"}, + // {"OUT2x Config", "Stereo Single-ended", "OUT2x Source"}, + {"OUT2x Config", "Mono Single-ended at OUTxP only", "OUT2x Source"}, + {"OUT2x Config", "Mono Single-ended at OUTxM only", "OUT2x Source"}, + {"OUT2x Config", "Pseudo differential with OUTxM as VCOM", + "OUT2x Source"}, + {"OUT2x Config", "Pseudo differential with OUTxP as VCOM", + "OUT2x Source"}, + {"OUT2x Driver", "Line-out", "OUT2x Config"}, + {"OUT2x Driver", "Headphone", "OUT2x Config"}, + {"Right DAC Enable", NULL, "OUT2x Driver"}, + {"OUT2", NULL, "Right DAC Enable"}, +}; + +static const struct snd_soc_dapm_route tac5x1x_pdm_routes[] = { + /* PDM channel1 & Channel2 */ + {"IN1 Source Mux", "PDM", "DIN1"}, + {"IN2 Source Mux", "PDM", "DIN2"}, + + {"ASI_TX_CH1_EN", "Capture Switch", + "IN1 Source Mux"}, + {"ASI_TX_CH2_EN", "Capture Switch", + "IN2 Source Mux"}, + + {"CH1_PDM_EN", NULL, "ASI_TX_CH1_EN"}, + {"CH2_PDM_EN", NULL, "ASI_TX_CH2_EN"}, + + {"AIF OUT", NULL, "CH1_PDM_EN"}, + {"AIF OUT", NULL, "CH2_PDM_EN"}, + + /* PDM channel3 & Channel4 */ + {"ASI_TX_CH3_EN", "Capture Switch", "DIN3"}, + {"ASI_TX_CH4_EN", "Capture Switch", "DIN4"}, + + {"CH3_PDM_EN", NULL, "ASI_TX_CH3_EN"}, + {"CH4_PDM_EN", NULL, "ASI_TX_CH4_EN"}, +}; + +static const struct snd_soc_dapm_route tac_common_routes[] = { + {"AIF OUT", NULL, "Mic Bias"}, +}; + +static s32 tac5x1x_pwr_ctrl(struct snd_soc_component *component, + bool power_state) +{ + struct tac5x1x_priv *tac5x1x = + snd_soc_component_get_drvdata(component); + s32 active_ctrl, ret; + s32 pwr_ctrl = 0; + + if (power_state) { + active_ctrl = TAC5X1X_VREF_SLEEP_ACTIVE_MASK; + snd_soc_component_update_bits(component, TAC5X1X_VREFCFG, + TAC5X1X_VREFCFG_MICBIAS_VAL_MASK, + tac5x1x->micbias_vg << 2); + snd_soc_component_update_bits(component, TAC5X1X_VREFCFG, + TAC5X1X_VREFCFG_VREF_FSCALE_MASK, + tac5x1x->vref_vg); + + if (tac5x1x->uad_en) + pwr_ctrl |= TAC5X1X_PWR_CFG_UAD_EN; + if (tac5x1x->vad_en) + pwr_ctrl |= TAC5X1X_PWR_CFG_VAD_EN; + if (tac5x1x->uag_en) + pwr_ctrl |= TAC5X1X_PWR_CFG_UAG_EN; + } else { + active_ctrl = 0x0; + } + + ret = snd_soc_component_update_bits(component, TAC5X1X_VREF, + TAC5X1X_VREF_SLEEP_EXIT_VREF_EN | + TAC5X1X_VREF_SLEEP_ACTIVE_MASK, + active_ctrl); + if (ret < 0) { + dev_err(tac5x1x->dev, + "%s, device active or sleep failed!, ret %d/n", + __func__, ret); + return ret; + } + + ret = snd_soc_component_update_bits(component, TAC5X1X_PWR_CFG, + TAC5X1X_PWR_CFG_UAD_EN | + TAC5X1X_PWR_CFG_UAG_EN | + TAC5X1X_PWR_CFG_VAD_EN, pwr_ctrl); + if (ret < 0) + dev_err(tac5x1x->dev, + "%s, Power control set failed!, ret %d/n", + __func__, ret); + return ret; +} + +static s32 tac5x1x_set_dai_fmt(struct snd_soc_dai *codec_dai, u32 fmt) +{ + struct snd_soc_component *component = codec_dai->component; + s32 iface_reg_1 = 0; + s32 iface_reg_2 = 0; + s32 iface_reg_3 = 0; + + int right_slot = 1; + + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_CBP_CFP: + iface_reg_1 |= TAC5X1X_PASI_MODE_MASK; + break; + case SND_SOC_DAIFMT_CBC_CFC: + break; + default: + dev_err(component->dev, + "%s: invalid DAI master/slave interface\n", + __func__); + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + iface_reg_2 |= TAC5X1X_PASI_FMT_I2S; + right_slot = 16; + break; + case SND_SOC_DAIFMT_DSP_A: + iface_reg_2 |= TAC5X1X_PASI_FMT_TDM; + iface_reg_3 |= BIT(0); /* add offset 1 */ + break; + case SND_SOC_DAIFMT_DSP_B: + iface_reg_2 |= TAC5X1X_PASI_FMT_TDM; + break; + case SND_SOC_DAIFMT_LEFT_J: + iface_reg_2 |= TAC5X1X_PASI_FMT_LJ; + right_slot = 16; + break; + default: + dev_err(component->dev, + "%s: invalid DAI interface format\n", __func__); + return -EINVAL; + } + + snd_soc_component_update_bits(component, TAC5X1X_CNTCLK2, + TAC5X1X_PASI_MODE_MASK, iface_reg_1); + snd_soc_component_update_bits(component, TAC5X1X_PASI0, + TAC5X1X_PASI_FMT_MASK, iface_reg_2); + snd_soc_component_update_bits(component, TAC5X1X_PASITX1, + TAC5X1X_PASITX_OFFSET_MASK, iface_reg_3); + snd_soc_component_update_bits(component, TAC5X1X_PASIRX0, + TAC5X1X_PASIRX_OFFSET_MASK, iface_reg_3); + snd_soc_component_update_bits(component, TAC5X1X_PASIRXCH2, + TAC5X1X_PASIRX_OFFSET_MASK, right_slot); + snd_soc_component_update_bits(component, TAC5X1X_PASITXCH2, + TAC5X1X_PASITX_OFFSET_MASK, right_slot); + + return 0; +} + +static s32 tac5x1x_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_component *component = dai->component; + struct tac5x1x_priv *tac5x1x = + snd_soc_component_get_drvdata(component); + s32 sample_rate, word_length = 0; + + switch (params_rate(params)) { + case 24000: + sample_rate = 25; + break; + case 32000: + sample_rate = 23; + break; + case 44100: + case 48000: + sample_rate = 20; + break; + case 64000: + sample_rate = 18; + break; + case 96000: + sample_rate = 15; + break; + case 192000: + sample_rate = 10; + break; + default: + /* Auto detect sample rate */ + sample_rate = 0; + break; + } + + switch (params_physical_width(params)) { + case 16: + word_length |= TAC5X1X_WORD_LEN_16BITS; + break; + case 20: + word_length |= TAC5X1X_WORD_LEN_20BITS; + break; + case 24: + word_length |= TAC5X1X_WORD_LEN_24BITS; + break; + case 32: + word_length |= TAC5X1X_WORD_LEN_32BITS; + break; + default: + dev_err(tac5x1x->dev, "%s, set word length failed\n", + __func__); + return -EINVAL; + } + + // snd_soc_component_update_bits(component, TAC5X1X_CLK0, + // TAC5X1X_PASI_SAMP_RATE_MASK, + // sample_rate << 2); + snd_soc_component_update_bits(component, TAC5X1X_PASI0, + TAC5X1X_PASI_DATALEN_MASK, word_length); + + tac5x1x_pwr_ctrl(component, true); + return 0; +} + +static s32 tac5x1x_set_bias_level(struct snd_soc_component *component, + enum snd_soc_bias_level level) +{ + s32 ret; + struct tac5x1x_priv *tac5x1x = + snd_soc_component_get_drvdata(component); + + switch (level) { + case SND_SOC_BIAS_ON: + ret = tac5x1x_pwr_ctrl(component, true); + if (ret < 0) + dev_err(tac5x1x->dev, + "%s, power up failed!/n", __func__); + break; + case SND_SOC_BIAS_PREPARE: + break; + case SND_SOC_BIAS_STANDBY: + break; + case SND_SOC_BIAS_OFF: + ret = tac5x1x_pwr_ctrl(component, false); + if (ret < 0) + dev_err(tac5x1x->dev, + "%s, power down failed!/n", __func__); + break; + } + + return ret; +} + +static const struct snd_soc_dai_ops tac5x1x_ops = { + .hw_params = tac5x1x_hw_params, + .set_fmt = tac5x1x_set_dai_fmt, + .no_capture_mute = 1, +}; + +static struct snd_soc_dai_driver tac5x1x_dai = { + .name = "tac5x1x-hifi", + .playback = { + .stream_name = "Playback", + .channels_min = 1, + .channels_max = 4, + .rates = TAC5X1X_RATES, + .formats = TAC5X1X_FORMATS,}, + .capture = { + .stream_name = "Capture", + .channels_min = 1, + .channels_max = 4, + .rates = TAC5X1X_RATES, + .formats = TAC5X1X_FORMATS, + }, + .ops = &tac5x1x_ops, + .symmetric_rate = 1, +}; + +static struct snd_soc_dai_driver taa5x1x_dai = { + .name = "taa5x1x-hifi", + .capture = { + .stream_name = "Capture", + .channels_min = 1, + .channels_max = 4, + .rates = TAC5X1X_RATES, + .formats = TAC5X1X_FORMATS, + }, + .ops = &tac5x1x_ops, + .symmetric_rate = 1, +}; + +static struct snd_soc_dai_driver tad5x1x_dai = { + .name = "tad5x1x-hifi", + .playback = { + .stream_name = "Playback", + .channels_min = 1, + .channels_max = 4, + .rates = TAC5X1X_RATES, + .formats = TAC5X1X_FORMATS, + }, + .capture = { + .stream_name = "Capture", + .channels_min = 1, + .channels_max = 4, + .rates = TAC5X1X_RATES, + .formats = TAC5X1X_FORMATS, + }, + .ops = &tac5x1x_ops, + .symmetric_rate = 1, +}; + +static s32 find_first_s32_in_s32arr(const s32 *arr, s32 val, size_t size) +{ + int i; + for (i = 0; i < size; i++) { + if (arr[i] == val) { + return i; + } + } + + return -1; +} + +static void tac5x1x_setup_gpios(struct snd_soc_component *component) +{ + struct tac5x1x_priv *tac5x1x = + snd_soc_component_get_drvdata(component); + s32 *gpio_drive = tac5x1x->gpio_setup->gpio_drive; + s32 *gpio_func = tac5x1x->gpio_setup->gpio_func; + s32 *pdm_input_pins = tac5x1x->gpio_setup->pdm_input_pins; + + /* setup GPIO functions */ + /* GPIO1 */ + if (gpio_func[0] <= TAC5X1X_GPIO_DAISY_OUT) { + snd_soc_component_update_bits(component, TAC5X1X_GPIO1, + TAC5X1X_GPIOX_CFG_MASK, + gpio_func[0] << 4); + snd_soc_component_update_bits(component, TAC5X1X_GPIO1, + TAC5X1X_GPIOX_DRV_MASK, + gpio_drive[0]); + } + /* GPIO2 */ + if (gpio_func[1] <= TAC5X1X_GPIO_DAISY_OUT) { + snd_soc_component_update_bits(component, TAC5X1X_GPIO2, + TAC5X1X_GPIOX_CFG_MASK, + gpio_func[1] << 4); + snd_soc_component_update_bits(component, TAC5X1X_GPIO2, + TAC5X1X_GPIOX_DRV_MASK, + gpio_drive[1]); + + } + /* GPO1 */ + if (gpio_func[2] <= TAC5X1X_GPIO_DAISY_OUT) { + snd_soc_component_update_bits(component, TAC5X1X_GPO1, + TAC5X1X_GPIOX_CFG_MASK, + gpio_func[2] << 4); + snd_soc_component_update_bits(component, TAC5X1X_GPO1, + TAC5X1X_GPIOX_DRV_MASK, + gpio_drive[2]); + } + + /* GPI1 */ + if (tac5x1x->gpio_setup->gpi1_func) + snd_soc_component_update_bits(component, TAC5X1X_GPI1, + TAC5X1X_GPI1_CFG_MASK, + TAC5X1X_GPI1_CFG_MASK); + /*GPA GPIO*/ + if (tac5x1x->gpio_setup->gpa_gpio) + snd_soc_component_update_bits(component, TAC5X1X_INTF5, + TAC5X1X_GPA_CFG_MASK, + TAC5X1X_GPA_CFG_MASK); + + /* PDM ch1 & ch2 Datain */ + if (pdm_input_pins[0]) + snd_soc_component_update_bits(component, TAC5X1X_INTF4, 0x0c, + pdm_input_pins[0] << 2); + /* PDM ch3 & ch4 Datain */ + if (pdm_input_pins[1]) + snd_soc_component_update_bits(component, TAC5X1X_INTF4, 0x03, + pdm_input_pins[1]); +} + +static const struct reg_sequence tac5x1x_init_reg_seq[] = { + /* ADC Channels input coupling configuration */ + REG_SEQ0(TAC5X1X_ADCCH1C0, 0x04), + REG_SEQ0(TAC5X1X_ADCCH2C0, 0x04), + /* Disable inputs and outputs */ + REG_SEQ0(TAC5X1X_CH_EN, 0x00), + REG_SEQ0(TAC5X1X_PASITXCH1, 0x00), + REG_SEQ0(TAC5X1X_PASITXCH2, 0x01), + REG_SEQ0(TAC5X1X_PASIRXCH1, 0x00), + REG_SEQ0(TAC5X1X_PASIRXCH2, 0x01), + /* misc writes */ + REG_SEQ0(TAC5X1X_TP_DREG, 0xD), + REG_SEQ0(TAC5X1X_TP_AREG, 0x08), + REG_SEQ0(TAC5X1X_TP_DREG, 0x0), + REG_SEQ0(TAC5X1X_DYN_PUPD, 0xa0), + /* clear latch irrespctive of live status */ + REG_SEQ0(TAC5X1X_INT, 0x11), +}; + +static s32 tac5x1x_init(struct tac5x1x_priv *tac5x1x) +{ + return regmap_multi_reg_write(tac5x1x->regmap, tac5x1x_init_reg_seq, + ARRAY_SIZE(tac5x1x_init_reg_seq)); +} + +static s32 tac5x1x_reset(struct tac5x1x_priv *tac5x1x) +{ + s32 ret; + + ret = regmap_write(tac5x1x->regmap, TAC5X1X_RESET, 1); + if (ret < 0) + return ret; + /* Wait >= 10 ms after entering sleep mode. */ + usleep_range(10000, 100000); + regcache_mark_dirty(tac5x1x->regmap); + + return ret; +} + +static s32 tac5x1x_add_controls(struct snd_soc_component *component) +{ + struct tac5x1x_priv *tac5x1x = + snd_soc_component_get_drvdata(component); + s32 *gpio_func = tac5x1x->gpio_setup->gpio_func; + s32 ret; + + switch (tac5x1x->codec_type) { + case TAA5212: + fallthrough; + case TAA5412: + ret = + snd_soc_add_component_controls(component, tolerance_ctrls, + ARRAY_SIZE(tolerance_ctrls)); + if (ret) + return ret; + ret = + snd_soc_add_component_controls(component, + taa_ip_controls, + ARRAY_SIZE(taa_ip_controls)); + if (ret) + return ret; + break; + /* For Mono */ + case TAC5111: + case TAC5211: + ret = + snd_soc_add_component_controls(component, + tac5x11_controls, + ARRAY_SIZE(tac5x11_controls)); + if (ret) + return ret; + fallthrough; + case TAC5311: + case TAC5411: + ret = + snd_soc_add_component_controls(component, tad5x1x_controls, + ARRAY_SIZE(tad5x1x_controls)); + if (ret) + return ret; + break; + /* For Stereo */ + case TAC5112: + case TAC5212: + fallthrough; + case TAC5312: + case TAC5412: + ret = + snd_soc_add_component_controls(component, tolerance_ctrls, + ARRAY_SIZE(tolerance_ctrls)); + if (ret) + return ret; + ret = + snd_soc_add_component_controls(component, tad5x1x_controls, + ARRAY_SIZE(tad5x1x_controls)); + if (ret) + return ret; + + ret = + snd_soc_add_component_controls(component, taa5x12_controls, + ARRAY_SIZE(taa5x12_controls)); + if (ret) + return ret; + + ret = + snd_soc_add_component_controls(component, tad5x12_controls, + ARRAY_SIZE(tad5x12_controls)); + if (ret) + return ret; + break; + case TAD5212: + case TAD5112: + ret = snd_soc_add_component_controls(component, tad5x12_controls, + ARRAY_SIZE(tad5x12_controls)); + if (ret) + return ret; + break; + default: + break; + } + + ret = snd_soc_add_component_controls(component, tac5x1x_tdm_slot_controls, + ARRAY_SIZE(tac5x1x_tdm_slot_controls)); + if (ret) + return ret; + + ret = find_first_s32_in_s32arr(gpio_func, TAC5X1X_GPIO_PDMCLK, + ARRAY_SIZE(tac5x1x->gpio_setup->gpio_func)); + /* If enabled PDM GPIO*/ + if (ret >= 0) { + ret = snd_soc_add_component_controls(component, tac5x1x_pdm_controls, + ARRAY_SIZE(tac5x1x_pdm_controls)); + if (ret) + return ret; + } + + return 0; +} + +static s32 tac5x1x_add_ip_diag_controls(struct snd_soc_component *component) +{ + struct tac5x1x_priv *tac5x1x = + snd_soc_component_get_drvdata(component); + s32 ret; + + switch (tac5x1x->codec_type) { + case TAA5212: + break; + case TAA5412: + case TAC5311: + case TAC5312: + case TAC5411: + case TAC5412: + if (tac5x1x->input_diag_config.in_ch_en) { + ret = + snd_soc_add_component_controls(component, + taa_ip_controls, + ARRAY_SIZE(taa_ip_controls)); + if (ret) + return ret; + snd_soc_component_update_bits(component, + TAC5X1X_DIAG_CFG0, + TAC5X1X_IN_CH_DIAG_EN_MASK, + TAC5X1X_IN_CH_DIAG_EN_MASK); + } + if (tac5x1x->input_diag_config.out_ch_en) { + snd_soc_component_update_bits(component, TAC5X1X_DIAG_CFG0, + TAC5X1X_OUT1P_DIAG_EN_MASK, + TAC5X1X_OUT1P_DIAG_EN_MASK); + } + if (tac5x1x->input_diag_config.incl_se_inm) { + snd_soc_component_update_bits(component, TAC5X1X_DIAG_CFG0, + TAC5X1X_INCL_SE_INM_MASK, + TAC5X1X_INCL_SE_INM_MASK); + } + if (tac5x1x->input_diag_config.incl_ac_coup) { + snd_soc_component_update_bits(component, TAC5X1X_DIAG_CFG0, + TAC5X1X_INCL_AC_COUP_MASK, + TAC5X1X_INCL_AC_COUP_MASK); + } + snd_soc_component_update_bits(component, TAC5X1X_DIAG_CFG7, + 0xff, + tac5x1x->micbias_threshold[0]); + snd_soc_component_update_bits(component, TAC5X1X_DIAG_CFG6, + 0xff, + tac5x1x->micbias_threshold[1]); + tac5x1x_register_interrupt(tac5x1x); + fallthrough; + case TAC5111: + case TAC5112: + case TAC5211: + case TAC5212: + case TAD5112: + case TAD5212: + snd_soc_component_update_bits(component, TAC5X1X_DIAG_CFG9, + 0xff, tac5x1x->gpa_threshold[0]); + snd_soc_component_update_bits(component, TAC5X1X_DIAG_CFG8, + 0xff, tac5x1x->gpa_threshold[1]); + break; + default: + break; + } + + return ret; +} + +static s32 tac5x1x_add_widgets(struct snd_soc_component *component) +{ + struct tac5x1x_priv *tac5x1x = + snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = + snd_soc_component_get_dapm(component); + s32 *gpio_func = tac5x1x->gpio_setup->gpio_func; + s32 ret; + + switch (tac5x1x->codec_type) { + case TAC5111: + case TAC5211: + case TAC5311: + case TAC5411: + ret = + snd_soc_dapm_new_controls(dapm, tad5x1x_dapm_widgets, + ARRAY_SIZE(tad5x1x_dapm_widgets)); + if (ret) + return ret; + ret = snd_soc_dapm_add_routes(dapm, tad5x1x_dapm_routes, + ARRAY_SIZE(tad5x1x_dapm_routes)); + if (ret) + return ret; + break; + case TAC5112: + case TAC5212: + case TAC5312: + case TAC5412: + ret = + snd_soc_dapm_new_controls(dapm, tad5x1x_dapm_widgets, + ARRAY_SIZE(tad5x1x_dapm_widgets)); + if (ret) + return ret; + ret = snd_soc_dapm_add_routes(dapm, tad5x1x_dapm_routes, + ARRAY_SIZE(tad5x1x_dapm_routes)); + if (ret) + return ret; + ret = + snd_soc_dapm_new_controls(dapm, tad5x12_dapm_widgets, + ARRAY_SIZE(tad5x12_dapm_widgets)); + if (ret) + return ret; + ret = snd_soc_dapm_add_routes(dapm, tad5x12_dapm_routes, + ARRAY_SIZE(tad5x12_dapm_routes)); + if (ret) + return ret; + fallthrough; + case TAA5212: + case TAA5412: + ret = + snd_soc_dapm_new_controls(dapm, taa5x12_dapm_widgets, + ARRAY_SIZE(taa5x12_dapm_widgets)); + if (ret) + return ret; + ret = snd_soc_dapm_add_routes(dapm, taa5x12_dapm_routes, + ARRAY_SIZE(taa5x12_dapm_routes)); + if (ret) + return ret; + break; + case TAD5212: + case TAD5112: + ret = + snd_soc_dapm_new_controls(dapm, tad5xx_dapm_widgets, + ARRAY_SIZE(tad5xx_dapm_widgets)); + if (ret) + return ret; + + ret = + snd_soc_dapm_new_controls(dapm, tad5x12_dapm_widgets, + ARRAY_SIZE(tad5x12_dapm_widgets)); + if (ret) + return ret; + ret = snd_soc_dapm_add_routes(dapm, tad5x12_dapm_routes, + ARRAY_SIZE(tad5x12_dapm_routes)); + if (ret) + return ret; + + break; + default: + break; + } + + switch (tac5x1x->codec_type) { + case TAD5212: + case TAD5112: + ret = + snd_soc_dapm_new_controls(dapm, tad_common_widgets, + ARRAY_SIZE(tad_common_widgets)); + if (ret) + return ret; + break; + default: + ret = + snd_soc_dapm_new_controls(dapm, tac5x1x_common_widgets, + ARRAY_SIZE(tac5x1x_common_widgets)); + if (ret) + return ret; + + ret = snd_soc_dapm_add_routes(dapm, tac_common_routes, + ARRAY_SIZE(tac_common_routes)); + if (ret) + return ret; + break; + } + + ret = find_first_s32_in_s32arr(gpio_func, TAC5X1X_GPIO_PDMCLK, + ARRAY_SIZE(tac5x1x->gpio_setup->gpio_func)); + /* If enabled PDM GPIO*/ + if (ret >= 0) { + ret = + snd_soc_dapm_new_controls(dapm, tac5x1x_pdm_widgets, + ARRAY_SIZE(tac5x1x_pdm_widgets)); + if (ret) + return ret; + ret = snd_soc_dapm_add_routes(dapm, tac5x1x_pdm_routes, + ARRAY_SIZE(tac5x1x_pdm_routes)); + if (ret) + return ret; + } + return 0; +} + +static int tac5x1x_setup_adc_impedance(struct device *dev, + struct tac5x1x_priv *tac5x1x) +{ + if (tac5x1x->adc_impedance[0] != -1) + snd_soc_component_update_bits(tac5x1x->component, + TAC5X1X_ADCCH1C0, + TAC5X1X_ADCCH1C0_IMPEDANCE_MASK, + tac5x1x->adc_impedance[0] << 4); + + if (tac5x1x->adc_impedance[1] != -1) + snd_soc_component_update_bits(tac5x1x->component, + TAC5X1X_ADCCH2C0, + TAC5X1X_ADCCH2C0_IMPEDANCE_MASK, + tac5x1x->adc_impedance[1] << 4); + + return 0; +} + +static s32 tac5x1x_component_probe(struct snd_soc_component *component) +{ + s32 ret; + struct tac5x1x_priv *tac5x1x = + snd_soc_component_get_drvdata(component); + + tac5x1x->component = component; + ret = tac5x1x_add_controls(component); + if (ret < 0) { + dev_err(tac5x1x->dev, + "%s, add control failed\n", __func__); + return ret; + } + + ret = tac5x1x_add_widgets(component); + if (ret < 0) { + dev_err(tac5x1x->dev, + "%s, device widget addition failed\n", __func__); + return ret; + } + + tac5x1x_setup_adc_impedance(tac5x1x->dev, tac5x1x); + + if (tac5x1x->gpio_setup) + tac5x1x_setup_gpios(component); + + ret = tac5x1x_add_ip_diag_controls(component); + if (ret < 0) { + dev_err(tac5x1x->dev, + "%s add diag control failed\n", __func__); + return ret; + } + return ret; +} + +static void tac5x1x_disable_regulators(struct tac5x1x_priv *tac5x1x) +{ + regulator_bulk_disable(tac5x1x_num_regulators, tac5x1x_regulators); +} + +#ifdef CONFIG_PM +static s32 tac5x1x_soc_suspend(struct snd_soc_component *component) +{ + struct tac5x1x_priv *tac5x1x = + snd_soc_component_get_drvdata(component); + + regcache_cache_only(tac5x1x->regmap, true); + regcache_mark_dirty(tac5x1x->regmap); + + tac5x1x_disable_regulators(tac5x1x); + + return 0; +} + +static s32 tac5x1x_soc_resume(struct snd_soc_component *component) +{ + struct tac5x1x_priv *tac5x1x = + snd_soc_component_get_drvdata(component); + s32 ret; + + ret = regulator_bulk_enable(tac5x1x_num_regulators, + tac5x1x_regulators); + if (ret) { + dev_err(tac5x1x->dev, "Failed to enable regulators\n"); + return ret; + } + + regcache_cache_only(tac5x1x->regmap, false); + snd_soc_component_cache_sync(component); + + return ret; +} +#else +#define tac5x1x_soc_suspend NULL +#define tac5x1x_soc_resume NULL +#endif /* CONFIG_PM */ + +static const struct snd_soc_component_driver component_tac5x1x = { + .probe = tac5x1x_component_probe, + .set_bias_level = tac5x1x_set_bias_level, + .suspend = tac5x1x_soc_suspend, + .resume = tac5x1x_soc_resume, + .controls = taa5x1x_controls, + .num_controls = ARRAY_SIZE(taa5x1x_controls), + .dapm_widgets = taa5x1x_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(taa5x1x_dapm_widgets), + .dapm_routes = taa5x1x_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(taa5x1x_dapm_routes), + .suspend_bias_off = 1, + .idle_bias_on = 1, + .use_pmdown_time = 1, + .endianness = 1, +}; + +static const struct snd_soc_component_driver component_taa5x1x = { + .probe = tac5x1x_component_probe, + .set_bias_level = tac5x1x_set_bias_level, + .suspend = tac5x1x_soc_suspend, + .resume = tac5x1x_soc_resume, + .controls = taa5x1x_controls, + .num_controls = ARRAY_SIZE(taa5x1x_controls), + .dapm_widgets = taa5x1x_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(taa5x1x_dapm_widgets), + .dapm_routes = taa5x1x_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(taa5x1x_dapm_routes), + .suspend_bias_off = 1, + .idle_bias_on = 1, + .use_pmdown_time = 1, + .endianness = 1, +}; + +static const struct snd_soc_component_driver component_tad5x1x = { + .probe = tac5x1x_component_probe, + .set_bias_level = tac5x1x_set_bias_level, + .suspend = tac5x1x_soc_suspend, + .resume = tac5x1x_soc_resume, + .controls = tad5x1x_controls, + .num_controls = ARRAY_SIZE(tad5x1x_controls), + .dapm_widgets = tad5x1x_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(tad5x1x_dapm_widgets), + .dapm_routes = tad5x1x_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(tad5x1x_dapm_routes), + .suspend_bias_off = 1, + .idle_bias_on = 1, + .use_pmdown_time = 1, + .endianness = 1, +}; + +static s32 tac5x1x_parse_dt(struct tac5x1x_priv *tac5x1x, + struct device_node *np) +{ + struct tac5x1x_input_diag_config input_config; + struct tac5x1x_setup_gpio *tac5x1x_setup; + s32 micbias_value = TAC5X1X_MICBIAS_VREF; + s32 vref_value = TAC5X1X_VERF_2_5V; + s32 ret; + + tac5x1x_setup = devm_kzalloc(tac5x1x->dev, sizeof(*tac5x1x_setup), + GFP_KERNEL); + if (!tac5x1x_setup) + return -ENOMEM; + + ret = fwnode_property_read_u32(tac5x1x->dev->fwnode, "ti,vref", + &vref_value); + if (ret) { + dev_err(tac5x1x->dev, "Fail to get verf E:%d\n", ret); + goto out; + } + ret = fwnode_property_read_u32(tac5x1x->dev->fwnode, + "ti,micbias-vg", &micbias_value); + if (ret) { + dev_err(tac5x1x->dev, "Fail to get micbias-vg E:%d\n", ret); + goto out; + } + + if (micbias_value == TAC5X1X_MICBIAS_AVDD) { + tac5x1x->micbias_vg = micbias_value; + tac5x1x->vref_vg = TAC5X1X_VERF_2_75V; + tac5x1x->micbias_en = true; + } else { + switch (vref_value) { + case TAC5X1X_VERF_2_75V: + case TAC5X1X_VERF_2_5V: + switch (micbias_value) { + case TAC5X1X_MICBIAS_VREF: + case TAC5X1X_MICBIAS_0_5VREF: + tac5x1x->micbias_vg = micbias_value; + break; + default: + dev_err(tac5x1x->dev, + "Bad tac5x1x-micbias-vg value %d\n", + micbias_value); + tac5x1x->micbias_vg = TAC5X1X_MICBIAS_AVDD; + break; + } + tac5x1x->vref_vg = vref_value; + tac5x1x->micbias_en = true; + break; + case TAC5X1X_VERF_1_375V: + if (micbias_value == TAC5X1X_MICBIAS_VREF) { + tac5x1x->micbias_vg = micbias_value; + } else { + dev_err(tac5x1x->dev, + "Bad tac5x1x-micbias-vg value %d\n", + micbias_value); + tac5x1x->micbias_vg = TAC5X1X_MICBIAS_AVDD; + } + tac5x1x->micbias_en = true; + tac5x1x->vref_vg = vref_value; + break; + default: + dev_err(tac5x1x->dev, + "Bad tac5x1x-vref-vg value %d\n", vref_value); + tac5x1x->vref_vg = TAC5X1X_VERF_2_5V; + tac5x1x->micbias_vg = TAC5X1X_MICBIAS_AVDD; + tac5x1x->micbias_en = true; + break; + } + } + + if (fwnode_property_read_u32(tac5x1x->dev->fwnode, "ti,gpi1-func", + &tac5x1x_setup->gpi1_func)) + dev_dbg(tac5x1x->dev, "Fail to get gpi1-func value\n"); + + if (fwnode_property_read_u32(tac5x1x->dev->fwnode, "ti,gpa-gpio", + &tac5x1x_setup->gpa_gpio)) + dev_dbg(tac5x1x->dev, "Fail to get gpa-gpio value\n"); + + if (fwnode_property_read_u32_array(tac5x1x->dev->fwnode, + "ti,gpios-func", + tac5x1x_setup->gpio_func, 3)) + dev_dbg(tac5x1x->dev, "Fail to get gpios-func value\n"); + + fwnode_property_read_u32_array(tac5x1x->dev->fwnode, + "ti,pdm-input-pins", + tac5x1x_setup->pdm_input_pins, 2); + + if (fwnode_property_read_u32_array(tac5x1x->dev->fwnode, + "ti,gpios-drive", + tac5x1x_setup->gpio_drive, 3)) + dev_dbg(tac5x1x->dev, "Fail to get gpios-drive value\n"); + + tac5x1x->gpa_threshold[0] = TAC5X1X_GPA_LOW_THRESHOLD; + tac5x1x->gpa_threshold[1] = TAC5X1X_GPA_HIGH_THRESHOLD; + if (fwnode_property_read_u32_array(tac5x1x->dev->fwnode, + "ti,gpa-threshold", + tac5x1x->gpa_threshold, 2)) + dev_dbg(tac5x1x->dev, "Fail to get ti,gpa-threshold value\n"); + + tac5x1x->gpio_setup = tac5x1x_setup; + tac5x1x->adc_impedance[0] = -1; + tac5x1x->adc_impedance[1] = -1; + tac5x1x->out2x_vcom_cfg = -1; + + fwnode_property_read_u32(tac5x1x->dev->fwnode, "ti,out2x-vcom-cfg", + &tac5x1x->out2x_vcom_cfg); + + switch (tac5x1x->codec_type) { + case TAA5212: + case TAC5212: + if (fwnode_property_read_u32(tac5x1x->dev->fwnode, + "ti,adc2-impedance", + &tac5x1x->adc_impedance[1])) + dev_dbg(tac5x1x->dev, + "Fail to get ti,adc2-impedance value\n"); + fallthrough; + case TAC5211: + case TAC5111: + if (fwnode_property_read_u32(tac5x1x->dev->fwnode, + "ti,adc1-impedance", + &tac5x1x->adc_impedance[0])) + dev_dbg(tac5x1x->dev, + "Fail to get ti,adc1-impedance value\n"); + + fallthrough; + case TAC5112: + case TAD5112: + case TAD5212: + break; + case TAA5412: + case TAC5411: + case TAC5412: + case TAC5311: + case TAC5312: + tac5x1x->input_diag_config.in_ch_en = 0; + if (fwnode_property_read_u32(tac5x1x->dev->fwnode, + "ti,in-ch-en", + &input_config.in_ch_en)) + dev_dbg(tac5x1x->dev, + "Fail to get ti,in-ch-en value\n"); + tac5x1x->input_diag_config.out_ch_en = 0; + if (fwnode_property_read_u32(tac5x1x->dev->fwnode, + "ti,out-ch-en", + &input_config.in_ch_en)) + dev_dbg(tac5x1x->dev, + "Fail to get ti,out-ch-en value\n"); + tac5x1x->input_diag_config.incl_se_inm = 0; + if (fwnode_property_read_u32(tac5x1x->dev->fwnode, + "ti,incl-se-inm", + &input_config.incl_se_inm)) + dev_dbg(tac5x1x->dev, + "Fail to get ti,incl-se-inm value\n"); + tac5x1x->input_diag_config.incl_ac_coup = 0; + if (fwnode_property_read_u32(tac5x1x->dev->fwnode, + "ti,incl-ac-coup", + &input_config.incl_ac_coup)) + dev_dbg(tac5x1x->dev, + "Fail to get ti,incl-ac-coup value\n"); + tac5x1x->input_diag_config = input_config; + + tac5x1x->micbias_threshold[0] = TAC5X1X_MICBIAS_LOW_THRESHOLD; + tac5x1x->micbias_threshold[1] = TAC5X1X_MICBIAS_HIGH_THRESHOLD; + if (fwnode_property_read_u32_array(tac5x1x->dev->fwnode, + "ti,micbias-threshold", + tac5x1x->micbias_threshold, + 2)) + dev_dbg(tac5x1x->dev, + "Fail to get ti,micbias-threshold value\n"); + break; + } +out: + return ret; +} + +static s32 tac5x1x_setup_regulators(struct device *dev, + struct tac5x1x_priv *tac5x1x) +{ + int ret; + + ret = devm_regulator_bulk_get(dev, tac5x1x_num_regulators, + tac5x1x_regulators); + if (ret) { + dev_err(dev, "Failed to get regulators\n"); + return ret; + } + + ret = regulator_bulk_enable(tac5x1x_num_regulators, + tac5x1x_regulators); + if (ret) { + dev_err(dev, "Failed to enable regulators\n"); + regulator_bulk_disable(tac5x1x_num_regulators, + tac5x1x_regulators); + return ret; + } + + return 0; +} + +static s32 tac5x1x_probe(struct device *dev, struct regmap *regmap, + enum tac5x1x_type type) +{ + struct device_node *np = dev->of_node; + struct tac5x1x_priv *tac5x1x; + s32 ret; + struct i2c_client *i2c = to_i2c_client(dev); + struct snd_soc_dai_driver *dai; + + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + tac5x1x = devm_kzalloc(dev, sizeof(struct tac5x1x_priv), + GFP_KERNEL); + if (!tac5x1x) + return -ENOMEM; + + tac5x1x->dev = dev; + tac5x1x->codec_type = type; + tac5x1x->regmap = regmap; + mutex_init(&tac5x1x->ch_lock); + INIT_DELAYED_WORK(&tac5x1x->powerup_work, post_powerup_work); + dev_set_drvdata(dev, tac5x1x); + + ret = tac5x1x_reset(tac5x1x); + if (ret) { + dev_err(dev, "Failed to reset device\n"); + return ret; + } + tac5x1x_init(tac5x1x); + + ret = tac5x1x_setup_regulators(dev, tac5x1x); + if (ret) { + dev_err(dev, "Failed to setup regulators\n"); + return ret; + } + + if (np) { + ret = tac5x1x_parse_dt(tac5x1x, np); + if (ret) { + dev_err(dev, "Failed to parse DT node\n"); + goto err_disable_regulators; + } + } else { + dev_err(dev, "%s: Fail to get device node\n", __func__); + goto err_disable_regulators; + } + + /* update if vcom property is found */ + if (tac5x1x->out2x_vcom_cfg != -1) { + snd_soc_component_update_bits(tac5x1x->component, + TAC5X1X_OUT2CFG0, + TAC5X1X_OUT2CFG0_VCOM_MASK, + tac5x1x->out2x_vcom_cfg); + } + + /* Allocate unique DAI for each codec instance to avoid naming conflicts */ + dai = devm_kzalloc(dev, sizeof(*dai), GFP_KERNEL); + if (!dai) { + ret = -ENOMEM; + goto err_disable_regulators; + } + + switch (tac5x1x->codec_type) { + case TAA5212: + case TAA5412: + /* Copy from TAA template */ + memcpy(dai, &taa5x1x_dai, sizeof(*dai)); + dai->name = devm_kasprintf(dev, GFP_KERNEL, "taa5x1x-hifi-%02x-%02x", + i2c->adapter->nr, i2c->addr); + if (!dai->name) { + ret = -ENOMEM; + goto err_disable_regulators; + } + ret = devm_snd_soc_register_component(dev, &component_taa5x1x, dai, 1); + break; + case TAC5111: + case TAC5112: + case TAC5211: + case TAC5212: + case TAC5311: + case TAC5312: + case TAC5411: + case TAC5412: + /* Copy from TAC template */ + memcpy(dai, &tac5x1x_dai, sizeof(*dai)); + dai->name = devm_kasprintf(dev, GFP_KERNEL, "taa5x1x-hifi-%02x-%02x", + i2c->adapter->nr, i2c->addr); + if (!dai->name) { + ret = -ENOMEM; + goto err_disable_regulators; + } + ret = devm_snd_soc_register_component(dev, &component_tac5x1x, dai, 1); + break; + case TAD5112: + case TAD5212: + /* Copy from TAD template */ + memcpy(dai, &tad5x1x_dai, sizeof(*dai)); + dai->name = devm_kasprintf(dev, GFP_KERNEL, "taa5x1x-hifi-%02x-%02x", + i2c->adapter->nr, i2c->addr); + if (!dai->name) { + ret = -ENOMEM; + goto err_disable_regulators; + } + ret = devm_snd_soc_register_component(dev, &component_tad5x1x, dai, 1); + break; + } + + if (ret) { + dev_err(dev, "Failed to register component\n"); + goto err_disable_regulators; + } + + return 0; + +err_disable_regulators: + tac5x1x_disable_regulators(tac5x1x); + + return ret; +} + +static s32 tac5x1x_remove(struct device *dev) +{ + struct tac5x1x_priv *tac5x1x = dev_get_drvdata(dev); + + tac5x1x_disable_regulators(tac5x1x); + return 0; +} + +static const struct of_device_id tac5x1x_of_match[] = { + { .compatible = "ti,taa5212", .data = (void *)TAA5212 }, + { .compatible = "ti,taa5412", .data = (void *)TAA5412 }, + { .compatible = "ti,tac5111", .data = (void *)TAC5111 }, + { .compatible = "ti,tac5112", .data = (void *)TAC5112 }, + { .compatible = "ti,tac5211", .data = (void *)TAC5211 }, + { .compatible = "ti,tac5212", .data = (void *)TAC5212 }, + { .compatible = "ti,tac5311", .data = (void *)TAC5311 }, + { .compatible = "ti,tac5312", .data = (void *)TAC5312 }, + { .compatible = "ti,tac5411", .data = (void *)TAC5411 }, + { .compatible = "ti,tac5412", .data = (void *)TAC5412 }, + { .compatible = "ti,tad5112", .data = (void *)TAD5112 }, + { .compatible = "ti,tad5212", .data = (void *)TAD5212 }, + {} +}; +MODULE_DEVICE_TABLE(of, tac5x1x_of_match); + +static const struct i2c_device_id tac5x1x_id[] = { + {"taa5212", TAA5212}, + {"taa5412", TAA5412}, + {"tac5111", TAC5111}, + {"tac5112", TAC5112}, + {"tac5211", TAC5211}, + {"tac5212", TAC5212}, + {"tac5311", TAC5311}, + {"tac5312", TAC5312}, + {"tac5411", TAC5411}, + {"tac5412", TAC5412}, + {"tad5112", TAD5112}, + {"tad5212", TAD5212}, + {} +}; +MODULE_DEVICE_TABLE(i2c, tac5x1x_id); + +static int tac5x1x_i2c_probe(struct i2c_client *i2c) +{ + int ret; + enum tac5x1x_type type; + struct regmap *regmap; + const struct regmap_config *config = &tac5x1x_regmap; + + regmap = devm_regmap_init_i2c(i2c, config); + type = (uintptr_t)i2c_get_match_data(i2c); + + ret = tac5x1x_probe(&i2c->dev, regmap, type); + if (ret) + dev_err(&i2c->dev, "probe failed"); + + return ret; +} + +static void tac5x1x_i2c_remove(struct i2c_client *client) +{ + tac5x1x_remove(&client->dev); +} + +static struct i2c_driver tac5x1x_i2c_driver = { + .driver = { + .name = "tac5x1x-codec", + .of_match_table = of_match_ptr(tac5x1x_of_match), + }, + .probe = tac5x1x_i2c_probe, + .remove = tac5x1x_i2c_remove, + .id_table = tac5x1x_id, +}; +module_i2c_driver(tac5x1x_i2c_driver); + +MODULE_DESCRIPTION("ASoC tac5x1x codec driver"); +MODULE_AUTHOR("Texas Instruments"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/tac5x1x.h b/sound/soc/codecs/tac5x1x.h new file mode 100644 index 000000000000..c388848f3c2b --- /dev/null +++ b/sound/soc/codecs/tac5x1x.h @@ -0,0 +1,304 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Audio Codec Driver Supporting Devices + * TAA5X1X, TAC5X1X, TAD5X1X + * + * Copyright (C) 2024-2025 Texas Instruments Incorporated - https://www.ti.com + * + * Author: Kevin Lu + * Author: Kokila Karuppusamy + * Author: Niranjan H Y + */ + +#ifndef _TAC5X1X_H +#define _TAC5X1X_H + +#define TAC5X1X_RATES SNDRV_PCM_RATE_8000_192000 +#define TAC5X1X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE \ + | SNDRV_PCM_FMTBIT_S20_3LE \ + | SNDRV_PCM_FMTBIT_S24_LE \ + | SNDRV_PCM_FMTBIT_S24_3LE \ + | SNDRV_PCM_FMTBIT_S32_LE) + +/*PAGE Control Register (available in page0 of each book) */ +#define TAC_PAGE_SELECT 0x00 +#define TAC_PAGE_ID(reg) ((reg) / 128) +#define TAC_PAGE_REG(reg) ((reg) % 128) +#define TAC5X1X_REG(page, reg) (((page) * 128) + (reg)) + +//#define TAC5X1X_PGSEL TAC5X1X_REG(0, 0x0) + +#define TAC5X1X_RESET TAC5X1X_REG(0, 0x1) +#define TAC5X1X_VREF TAC5X1X_REG(0, 0x2) +#define TAC5X1X_VDDSTS TAC5X1X_REG(0, 0x3) +#define TAC5X1X_MISC TAC5X1X_REG(0, 0x4) +#define TAC5X1X_MISC1 TAC5X1X_REG(0, 0x5) +#define TAC5X1X_DACA0 TAC5X1X_REG(0, 0x6) +#define TAC5X1X_MISC0 TAC5X1X_REG(0, 0x7) +#define TAC5X1X_GPIO1 TAC5X1X_REG(0, 0xa) +#define TAC5X1X_GPIO2 TAC5X1X_REG(0, 0xb) +#define TAC5X1X_GPO1 TAC5X1X_REG(0, 0xc) +#define TAC5X1X_GPI1 TAC5X1X_REG(0, 0xd) +#define TAC5X1X_GPIOVAL TAC5X1X_REG(0, 0xe) +#define TAC5X1X_INTF0 TAC5X1X_REG(0, 0xf) +#define TAC5X1X_INTF1 TAC5X1X_REG(0, 0x10) +#define TAC5X1X_INTF2 TAC5X1X_REG(0, 0x11) +#define TAC5X1X_INTF3 TAC5X1X_REG(0, 0x12) +#define TAC5X1X_INTF4 TAC5X1X_REG(0, 0x13) +#define TAC5X1X_INTF5 TAC5X1X_REG(0, 0x14) +#define TAC5X1X_INTF6 TAC5X1X_REG(0, 0x15) +#define TAC5X1X_ASI0 TAC5X1X_REG(0, 0x18) +#define TAC5X1X_ASI1 TAC5X1X_REG(0, 0x19) +#define TAC5X1X_PASI0 TAC5X1X_REG(0, 0x1a) +#define TAC5X1X_PASITX0 TAC5X1X_REG(0, 0x1b) +#define TAC5X1X_PASITX1 TAC5X1X_REG(0, 0x1c) +#define TAC5X1X_PASITX2 TAC5X1X_REG(0, 0x1d) +#define TAC5X1X_PASITXCH1 TAC5X1X_REG(0, 0x1e) +#define TAC5X1X_PASITXCH2 TAC5X1X_REG(0, 0x1f) +#define TAC5X1X_PASITXCH3 TAC5X1X_REG(0, 0x20) +#define TAC5X1X_PASITXCH4 TAC5X1X_REG(0, 0x21) +#define TAC5X1X_PASITXCH5 TAC5X1X_REG(0, 0x22) +#define TAC5X1X_PASITXCH6 TAC5X1X_REG(0, 0x23) +#define TAC5X1X_PASITXCH7 TAC5X1X_REG(0, 0x24) +#define TAC5X1X_PASITXCH8 TAC5X1X_REG(0, 0x25) +#define TAC5X1X_PASIRX0 TAC5X1X_REG(0, 0x26) +#define TAC5X1X_PASIRX1 TAC5X1X_REG(0, 0x27) +#define TAC5X1X_PASIRXCH1 TAC5X1X_REG(0, 0x28) +#define TAC5X1X_PASIRXCH2 TAC5X1X_REG(0, 0x29) +#define TAC5X1X_PASIRXCH3 TAC5X1X_REG(0, 0x2a) +#define TAC5X1X_PASIRXCH4 TAC5X1X_REG(0, 0x2b) +#define TAC5X1X_PASIRXCH5 TAC5X1X_REG(0, 0x2c) +#define TAC5X1X_PASIRXCH6 TAC5X1X_REG(0, 0x2d) +#define TAC5X1X_PASIRXCH7 TAC5X1X_REG(0, 0x2e) +#define TAC5X1X_PASIRXCH8 TAC5X1X_REG(0, 0x2f) +#define TAC5X1X_CLK0 TAC5X1X_REG(0, 0x32) +#define TAC5X1X_CLK1 TAC5X1X_REG(0, 0x33) +#define TAC5X1X_CLK2 TAC5X1X_REG(0, 0x34) +#define TAC5X1X_CNTCLK0 TAC5X1X_REG(0, 0x35) +#define TAC5X1X_CNTCLK1 TAC5X1X_REG(0, 0x36) +#define TAC5X1X_CNTCLK2 TAC5X1X_REG(0, 0x37) +#define TAC5X1X_CNTCLK3 TAC5X1X_REG(0, 0x38) +#define TAC5X1X_CNTCLK4 TAC5X1X_REG(0, 0x39) +#define TAC5X1X_CNTCLK5 TAC5X1X_REG(0, 0x3a) +#define TAC5X1X_CNTCLK6 TAC5X1X_REG(0, 0x3b) +#define TAC5X1X_CLKERRSTS0 TAC5X1X_REG(0, 0x3c) +#define TAC5X1X_CLKERRSTS1 TAC5X1X_REG(0, 0x3d) +#define TAC5X1X_CLKDETSTS0 TAC5X1X_REG(0, 0x3e) +#define TAC5X1X_CLKDETSTS1 TAC5X1X_REG(0, 0x3f) +#define TAC5X1X_CLKDETSTS2 TAC5X1X_REG(0, 0x40) +#define TAC5X1X_CLKDETSTS3 TAC5X1X_REG(0, 0x41) +#define TAC5X1X_INT TAC5X1X_REG(0, 0x42) +#define TAC5X1X_DAC_FLT TAC5X1X_REG(0, 0x43) +#define TAC5X1X_ADCDACMISC TAC5X1X_REG(0, 0x4b) +#define TAC5X1X_IADC TAC5X1X_REG(0, 0x4c) +#define TAC5X1X_VREFCFG TAC5X1X_REG(0, 0x4d) +#define TAC5X1X_PWRTUNE0 TAC5X1X_REG(0, 0x4e) +#define TAC5X1X_PWRTUNE1 TAC5X1X_REG(0, 0x4f) +#define TAC5X1X_ADCCH1C0 TAC5X1X_REG(0, 0x50) +#define TAC5X1X_ADCCH TAC5X1X_REG(0, 0x51) +#define TAC5X1X_ADCCH1C2 TAC5X1X_REG(0, 0x52) +#define TAC5X1X_ADCCH1C3 TAC5X1X_REG(0, 0x53) +#define TAC5X1X_ADCCH1C4 TAC5X1X_REG(0, 0x54) +#define TAC5X1X_ADCCH2C0 TAC5X1X_REG(0, 0x55) +#define TAC5X1X_ADCCH2C2 TAC5X1X_REG(0, 0x57) +#define TAC5X1X_ADCCH2C3 TAC5X1X_REG(0, 0x58) +#define TAC5X1X_ADCCH2C4 TAC5X1X_REG(0, 0x59) +#define TAC5X1X_ADCCH3C0 TAC5X1X_REG(0, 0x5a) +#define TAC5X1X_ADCCH3C2 TAC5X1X_REG(0, 0x5b) +#define TAC5X1X_ADCCH3C3 TAC5X1X_REG(0, 0x5c) +#define TAC5X1X_ADCCH3C4 TAC5X1X_REG(0, 0x5d) +#define TAC5X1X_ADCCH4C0 TAC5X1X_REG(0, 0x5e) +#define TAC5X1X_ADCCH4C2 TAC5X1X_REG(0, 0x5f) +#define TAC5X1X_ADCCH4C3 TAC5X1X_REG(0, 0x60) +#define TAC5X1X_ADCCH4C4 TAC5X1X_REG(0, 0x61) +#define TAC5X1X_ADCCFG1 TAC5X1X_REG(0, 0x62) +#define TAC5X1X_OUT1CFG0 TAC5X1X_REG(0, 0x64) +#define TAC5X1X_OUT1CFG1 TAC5X1X_REG(0, 0x65) +#define TAC5X1X_OUT1CFG2 TAC5X1X_REG(0, 0x66) +#define TAC5X1X_DACCH1A0 TAC5X1X_REG(0, 0x67) +#define TAC5X1X_DACCH1A1 TAC5X1X_REG(0, 0x68) +#define TAC5X1X_DACCH1B0 TAC5X1X_REG(0, 0x69) +#define TAC5X1X_DACCH1B1 TAC5X1X_REG(0, 0x6a) +#define TAC5X1X_OUT2CFG0 TAC5X1X_REG(0, 0x6b) +#define TAC5X1X_OUT2CFG1 TAC5X1X_REG(0, 0x6c) +#define TAC5X1X_OUT2CFG2 TAC5X1X_REG(0, 0x6d) +#define TAC5X1X_DACCH2A0 TAC5X1X_REG(0, 0x6e) +#define TAC5X1X_DACCH2A1 TAC5X1X_REG(0, 0x6f) +#define TAC5X1X_DACCH2B0 TAC5X1X_REG(0, 0x70) +#define TAC5X1X_DACCH2B1 TAC5X1X_REG(0, 0x71) +#define TAC5X1X_DSP0 TAC5X1X_REG(0, 0x72) +#define TAC5X1X_DSP1 TAC5X1X_REG(0, 0x73) +#define TAC5X1X_CH_EN TAC5X1X_REG(0, 0x76) +#define TAC5X1X_DYN_PUPD TAC5X1X_REG(0, 0x77) +#define TAC5X1X_PWR_CFG TAC5X1X_REG(0, 0x78) +#define TAC5X1X_DEVSTS0 TAC5X1X_REG(0, 0x79) +#define TAC5X1X_DEVSTS1 TAC5X1X_REG(0, 0x7a) + +#define TAC5X1X_CLKCFG0 TAC5X1X_REG(1, 0xd) +#define TAC5X1X_MICBIAS1 TAC5X1X_REG(1, 0x16) +#define TAC5X1X_AGC_DRC TAC5X1X_REG(1, 0x24) +#define TAC5X1X_PLIM TAC5X1X_REG(1, 0x2b) +#define TAC5X1X_MIXER TAC5X1X_REG(1, 0x2c) + +#define TAC5X1X_DIAG_CFG0 TAC5X1X_REG(1, 0x46) +#define TAC5X1X_DIAG_CFG1 TAC5X1X_REG(1, 0x47) +#define TAC5X1X_DIAG_CFG2 TAC5X1X_REG(1, 0x48) +#define TAC5X1X_DIAG_CFG8 TAC5X1X_REG(1, 0x4e) +#define TAC5X1X_DIAG_CFG9 TAC5X1X_REG(1, 0x4b) +#define TAC5X1X_DIAG_CFG6 TAC5X1X_REG(1, 0x4c) +#define TAC5X1X_DIAG_CFG7 TAC5X1X_REG(1, 0x4d) + +/* interrupt latches */ +#define TAC5X1X_INT_LTCH0 TAC5X1X_REG(0x1, 0x34) +#define TAC5X1X_CHX_LTCH TAC5X1X_REG(0x1, 0x35) +#define TAC5X1X_IN_CH1_LTCH TAC5X1X_REG(0x1, 0x36) +#define TAC5X1X_IN_CH2_LTCH TAC5X1X_REG(0x1, 0x37) +#define TAC5X1X_OUT_CH1_LTCH TAC5X1X_REG(0x1, 0x38) +#define TAC5X1X_OUT_CH2_LTCH TAC5X1X_REG(0x1, 0x39) +#define TAC5X1X_INT_LTCH1 TAC5X1X_REG(0x1, 0x3A) +#define TAC5X1X_INT_LTCH2 TAC5X1X_REG(0x1, 0x3B) +#define TAC5X1X_OVERLD_FLAG TAC5X1X_REG(0x1, 0x5B) + +#define TAC5X1X_TP_START TAC5X1X_REG(0xfd, 0x0) +#define TAC5X1X_TP_DREG TAC5X1X_REG(0xfd, 0xd) +#define TAC5X1X_TP_AREG TAC5X1X_REG(0xfd, 0x1a) +#define TAC5X1X_TP_END TAC5X1X_REG(0xfd, 0x7f) +/* Bits, masks, and shifts */ +/* TAC5X1X_CH_EN */ +#define TAC5X1X_CH_EN_ADC_MASK GENMASK(7, 4) +#define TAC5X1X_CH_EN_ADC_CH1 BIT(7) +#define TAC5X1X_CH_EN_ADC_CH2 BIT(6) +#define TAC5X1X_CH_EN_ADC_CH3 BIT(5) +#define TAC5X1X_CH_EN_ADC_CH4 BIT(4) + +#define TAC5X1X_CH_EN_DAC_MASK GENMASK(3, 0) +#define TAC5X1X_CH_EN_DAC_CH1 BIT(3) +#define TAC5X1X_CH_EN_DAC_CH2 BIT(2) +#define TAC5X1X_CH_EN_DAC_CH3 BIT(1) +#define TAC5X1X_CH_EN_DAC_CH4 BIT(0) + +/* TAC5X1X_GPIOVAL */ +#define TAC5X1X_GPIO1_VAL BIT(7) +#define TAC5X1X_GPIO2_VAL BIT(6) +#define TAC5X1X_GPO1_VAL BIT(5) +#define TAC5X1X_GPIO1_MON BIT(3) +#define TAC5X1X_GPIO2_MON BIT(2) +#define TAC5X1X_GPI1_MON BIT(1) + +/* TAC5X1X_DIAG_CFG0 */ +#define TAC5X1X_IN_CH_DIAG_EN_MASK 0xc0 +#define TAC5X1X_INCL_SE_INM_MASK 0x20 +#define TAC5X1X_INCL_AC_COUP_MASK 0x10 +#define TAC5X1X_OUT1P_DIAG_EN_MASK 0x0f +#define TAC5X1X_MICBIAS_LOW_THRESHOLD 0x48 +#define TAC5X1X_MICBIAS_HIGH_THRESHOLD 0xa2 +#define TAC5X1X_GPA_LOW_THRESHOLD 0x4b +#define TAC5X1X_GPA_HIGH_THRESHOLD 0xba + +/* TAC5X1X_PASI */ +#define TAC5X1X_PASI_SAMP_RATE_MASK GENMASK(7, 2) +#define TAC5X1X_PASI_FMT_MASK GENMASK(7, 6) +#define TAC5X1X_PASI_FMT_TDM 0x00 +#define TAC5X1X_PASI_FMT_I2S 0x40 +#define TAC5X1X_PASI_FMT_LJ 0x80 + +#define TAC5X1X_PASI_DATALEN_MASK GENMASK(5, 4) +#define TAC5X1X_WORD_LEN_16BITS 0x00 +#define TAC5X1X_WORD_LEN_20BITS 0x10 +#define TAC5X1X_WORD_LEN_24BITS 0x20 +#define TAC5X1X_WORD_LEN_32BITS 0x30 + +/* TAC5X1X_CNTCLK2 */ +#define TAC5X1X_PASI_MODE_MASK 0x10 +#define TAC5X1X_SASI_MODE_MASK 0x08 +#define TAC5X1X_ASI_RATE_MASK 0x01 + +#define TAC5X1X_PASI_RATE_48000 0x00 +#define TAC5X1X_PASI_RATE_44100 0x01 + +/* TAC5X1X_PASITX0 */ +#define TAC5X1X_PASITX_OFFSET_MASK 0x1f + +/* TAC5X1X_PASIRX0 */ +#define TAC5X1X_PASIRX_OFFSET_MASK 0x1f + +/* TAC5X1X_VREF */ +#define TAC5X1X_VREF_SLEEP_EXIT_VREF_EN 0x80 +#define TAC5X1X_VREF_SLEEP_ACTIVE_MASK 0x01 + +/* TAC5X1X_PWRCFG */ +#define TAC5X1X_PWR_CFG_ADC_PDZ BIT(7) +#define TAC5X1X_PWR_CFG_DAC_PDZ BIT(6) +#define TAC5X1X_PWR_CFG_MICBIAS BIT(5) +#define TAC5X1X_PWR_CFG_UAD_EN BIT(3) +#define TAC5X1X_PWR_CFG_VAD_EN BIT(2) +#define TAC5X1X_PWR_CFG_UAG_EN BIT(1) + +/* TAC5X1X_GPIOx */ +#define TAC5X1X_GPIO1_DEFAULT_VAL 0x32 +#define TAC5X1X_GPIO2_DEFAULT_VAL 0x00 +#define TAC5X1X_GPI1_DEFAULT_VAL 0x00 +#define TAC5X1X_GPO1_DEFAULT_VAL 0x00 + +#define TAC5X1X_GPIOX_CFG_MASK 0xf0 +#define TAC5X1X_GPIOX_DRV_MASK 0x07 + +#define TAC5X1X_GPIO_DISABLE 0 +#define TAC5X1X_GPIO_GPI 1 +#define TAC5X1X_GPIO_GPO 2 +#define TAC5X1X_GPIO_IRQ 3 +#define TAC5X1X_GPIO_PDMCLK 4 +#define TAC5X1X_GPIO_P_DOUT 5 +#define TAC5X1X_GPIO_P_DOUT2 6 +#define TAC5X1X_GPIO_S_DOUT 7 +#define TAC5X1X_GPIO_S_DOUT2 8 +#define TAC5X1X_GPIO_S_BCLK 9 +#define TAC5X1X_GPIO_S_FSYNC 10 +#define TAC5X1X_GPIO_CLKOUT 11 +#define TAC5X1X_GPIO_DOUT_MUX 12 +#define TAC5X1X_GPIO_DAISY_OUT 13 + +#define TAC5X1X_GPIO_DRV_HIZ 0 +#define TAC5X1X_GPIO_DRV_ALAH 1 +#define TAC5X1X_GPIO_DRV_ALWH 2 +#define TAC5X1X_GPIO_DRV_ALHIZ 3 +#define TAC5X1X_GPIO_DRV_WLAH 4 +#define TAC5X1X_GPIO_DRV_HIZAH 5 + +/* TAC5X1X_GPI1 */ +#define TAC5X1X_GPI1_CFG_MASK BIT(1) +#define TAC5X1X_GPA_CFG_MASK BIT(0) + +/* TAC5X1X_VREFCFG */ +#define TAC5X1X_VREFCFG_MICBIAS_VAL_MASK GENMASK(3, 2) +#define TAC5X1X_VREFCFG_VREF_FSCALE_MASK GENMASK(1, 0) + +#define TAC5X1X_ADCCH1C0_IMPEDANCE_MASK GENMASK(5, 4) +#define TAC5X1X_ADCCH2C0_IMPEDANCE_MASK GENMASK(5, 4) + +#define TAC5X1X_OUT2CFG0_VCOM_MASK BIT(1) + +#define TAC5X1X_MICBIAS_VREF 0 +#define TAC5X1X_MICBIAS_0_5VREF 1 +#define TAC5X1X_MICBIAS_AVDD 3 + +#define TAC5X1X_VERF_2_75V 0 +#define TAC5X1X_VERF_2_5V 1 +#define TAC5X1X_VERF_1_375V 2 + +enum tac5x1x_type { + TAA5212 = 0, + TAA5412, + TAC5111, + TAC5112, + TAC5211, + TAC5212, + TAC5311, + TAC5312, + TAC5411, + TAC5412, + TAD5112, + TAD5212, +}; + +#endif /* _TAC5X1X_H */ From 7f095e715bcf42ce43bc125048e87c39695acaa0 Mon Sep 17 00:00:00 2001 From: Aaron Brice Date: Mon, 1 Jun 2026 23:47:28 +0000 Subject: [PATCH 09/10] arm64: Adding TS-9370 device tree and config Device tree and kernel defconfig for the embeddedTS TS-9370 i.MX93 Single Board Computer. Signed-off-by: Aaron Brice --- arch/arm64/boot/dts/freescale/Makefile | 3 + .../boot/dts/freescale/imx93-ts9370-pinfunc.h | 76 + .../arm64/boot/dts/freescale/imx93-ts9370.dts | 1312 +++++++++++++++ arch/arm64/configs/tsimx93_defconfig | 1480 +++++++++++++++++ arch/arm64/configs/tsimx93_minimal_defconfig | 1014 +++++++++++ 5 files changed, 3885 insertions(+) create mode 100644 arch/arm64/boot/dts/freescale/imx93-ts9370-pinfunc.h create mode 100644 arch/arm64/boot/dts/freescale/imx93-ts9370.dts create mode 100644 arch/arm64/configs/tsimx93_defconfig create mode 100644 arch/arm64/configs/tsimx93_minimal_defconfig diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile index 525ef180481d..02de81af1828 100644 --- a/arch/arm64/boot/dts/freescale/Makefile +++ b/arch/arm64/boot/dts/freescale/Makefile @@ -382,6 +382,9 @@ imx95-19x19-evk-pcie1-ep-dtbs += imx95-19x19-evk.dtb imx-pcie1-ep.dtbo dtb-$(CONFIG_ARCH_MXC) += imx95-19x19-evk-pcie0-ep.dtb imx95-19x19-evk-pcie1-ep.dtb dtb-$(CONFIG_ARCH_MXC) += imx95-libra-rdk-fpsc.dtb +dtb-$(CONFIG_ARCH_MXC) += imx93-ts9370.dtb + + imx8mm-kontron-dl-dtbs := imx8mm-kontron-bl.dtb imx8mm-kontron-dl.dtbo imx8mm-kontron-bl-lte-dtbs := imx8mm-kontron-bl.dtb imx8mm-kontron-bl-lte.dtbo diff --git a/arch/arm64/boot/dts/freescale/imx93-ts9370-pinfunc.h b/arch/arm64/boot/dts/freescale/imx93-ts9370-pinfunc.h new file mode 100644 index 000000000000..9a57a8108bf4 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx93-ts9370-pinfunc.h @@ -0,0 +1,76 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2024-2026 Technologic Systems, Inc. (dba embeddedTS) + */ + +#ifndef __DTS_TS9370_PINFUNC_H +#define __DTS_TS9370_PINFUNC_H + +/* + * Tuple layout per pin-function: + * + * + * - mux_mode 0-7 : output selects function_index 0-7 + * - highz_en == 1 : set the companion pin to high-Z + */ + +#define TS9370_PAD_BT_RXD__UART6_TXD 0x000 0x1 0x000 0x0 +#define TS9370_PAD_BT_CTS__UART6_RTS 0x003 0x1 0x000 0x0 +#define TS9370_PAD_DP_19P2MHZ_CLK__DC_1 0x004 0x1 0x010 0x1 +#define TS9370_PAD_MIKRO_TXD__GPIO0_IO14 0x006 0x0 0x000 0x0 +#define TS9370_PAD_MIKRO_TXD__UART8_TXD 0x006 0x1 0x000 0x0 +#define TS9370_PAD_MIKRO_RXD__GPIO0_IO15 0x007 0x0 0x000 0x0 +#define TS9370_PAD_MIKRO_SPI_CLK__GPIO0_IO16 0x008 0x0 0x000 0x0 +#define TS9370_PAD_MIKRO_SPI_CLK__LPSPI4_CLK 0x008 0x1 0x000 0x0 +#define TS9370_PAD_MIKRO_SPI_CS___GPIO0_IO17 0x009 0x0 0x000 0x0 +#define TS9370_PAD_MIKRO_SPI_CS___LPSPI4_CS_MUX_1 0x009 0x1 0x000 0x0 +#define TS9370_PAD_MIKRO_SPI_MISO__GPIO0_IO18 0x00A 0x0 0x000 0x0 +#define TS9370_PAD_MIKRO_SPI_MOSI__GPIO0_IO19 0x00B 0x0 0x000 0x0 +#define TS9370_PAD_MIKRO_SPI_MOSI__LPSPI4_MOSI 0x00B 0x1 0x000 0x0 +#define TS9370_PAD_MIKRO_RESET___GPIO0_IO20 0x00C 0x0 0x000 0x0 +#define TS9370_PAD_MIKRO_AN__GPIO0_IO21 0x00D 0x0 0x000 0x0 +#define TS9370_PAD_MIKRO_PWM__GPIO0_IO22 0x00E 0x0 0x000 0x0 +#define TS9370_PAD_MIKRO_PWM__PWM0_OUT 0x00E 0x1 0x000 0x0 +#define TS9370_PAD_MIKRO_INT__GPIO0_IO23 0x00F 0x0 0x000 0x0 +#define TS9370_PAD_DC_1__GPIO2_IO27 0x010 0x0 0x000 0x0 +#define TS9370_PAD_DC_1__UART7_TX 0x010 0x1 0x000 0x0 +#define TS9370_PAD_DC_1__LPSPI4_CLK 0x010 0x2 0x000 0x0 +#define TS9370_PAD_DC_3__GPIO2_IO28 0x011 0x0 0x000 0x0 +#define TS9370_PAD_DC_5__GPIO2_IO29 0x012 0x0 0x000 0x0 +#define TS9370_PAD_DC_5__UART7_RTS 0x012 0x1 0x000 0x0 +#define TS9370_PAD_DC_5__LPSPI4_MOSI 0x012 0x2 0x000 0x0 +#define TS9370_PAD_DC_7__GPIO2_IO30 0x013 0x0 0x000 0x0 +#define TS9370_PAD_DC_7__LPSPI4_CS_MUX_2 0x013 0x1 0x000 0x0 +#define TS9370_PAD_DC_9__GPIO2_IO31 0x014 0x0 0x000 0x0 +#define TS9370_PAD_EN_LS_OUT_1__GPIO2_IO17 0x019 0x0 0x000 0x0 +#define TS9370_PAD_EN_LS_OUT_2__GPIO2_IO18 0x01A 0x0 0x000 0x0 +#define TS9370_PAD_EN_LS_OUT_3__GPIO2_IO19 0x01B 0x0 0x000 0x0 +#define TS9370_PAD_EN_LS_OUT_4__GPIO2_IO20 0x01C 0x0 0x000 0x0 +#define TS9370_PAD_EN_HS_SW__GPIO2_IO16 0x01D 0x0 0x000 0x0 +#define TS9370_PAD_PRIM_485_TXD__UART7_TXD 0x01E 0x1 0x000 0x0 +#define TS9370_PAD_PRIM_485_TXEN__UART7_RTS 0x01F 0x1 0x000 0x0 +#define TS9370_PAD_SEC_485_TXEN__UART3_RTS 0x021 0x1 0x000 0x0 +#define TS9370_PAD_SEC_UART_TX__UART3_TXD 0x023 0x1 0x000 0x0 +#define TS9370_PAD_EN_GREEN_LED___GPIO0_IO0 0x024 0x0 0x000 0x0 +#define TS9370_PAD_EN_RED_LED___GPIO0_IO2 0x025 0x0 0x000 0x0 +#define TS9370_PAD_CODEC_CLK__PLL_CLK_OUT 0x027 0x1 0x000 0x0 +#define TS9370_PAD_NIM_RESET___GPIO0_IO4 0x028 0x0 0x000 0x0 +#define TS9370_PAD_NIM_CTS___GPIO0_IO5 0x029 0x0 0x000 0x0 +#define TS9370_PAD_NIM_PWR_ON___GPIO0_IO6 0x02A 0x0 0x000 0x0 +#define TS9370_PAD_NIM_TXD__GPIO0_IO10 0x02C 0x0 0x000 0x0 +#define TS9370_PAD_NIM_TXD__UART5_TXD 0x02C 0x1 0x000 0x0 +#define TS9370_PAD_NIM_RXD__GPIO0_IO11 0x02D 0x0 0x000 0x0 +#define TS9370_PAD_UART3_RXD__SECOND_PORT_RXD_3V 0x031 0x1 0x000 0x0 +#define TS9370_PAD_UART5_RXD__NIM_RXD 0x033 0x1 0x02D 0x1 +#define TS9370_PAD_UART6_RXD__BT_TXD 0x034 0x1 0x001 0x1 +#define TS9370_PAD_UART6_CTS__BT_RTS 0x035 0x1 0x002 0x1 +#define TS9370_PAD_UART7_RXD__PRIM_485_RXD_3V 0x036 0x1 0x000 0x0 +#define TS9370_PAD_UART7_RXD__DC_3 0x036 0x2 0x011 0x1 +#define TS9370_PAD_UART7_RXD__SECOND_PORT_RXD_3V 0x036 0x3 0x000 0x0 +#define TS9370_PAD_UART7_CTS__DC_7 0x037 0x1 0x013 0x1 +#define TS9370_PAD_UART8_RXD__MIKRO_RXD 0x038 0x1 0x007 0x1 +#define TS9370_PAD_LPSPI4_MISO_MUX_1__MIKRO_SPI_MISO 0x039 0x1 0x00A 0x1 +#define TS9370_PAD_LPSPI4_MISO_MUX_2__DC_3 0x03A 0x1 0x011 0x1 +#define TS9370_PAD_EN_BLUE_LED__GPIO0_IO3 0x03B 0x0 0x000 0x0 + +#endif /* __DTS_TS9370_PINFUNC_H */ diff --git a/arch/arm64/boot/dts/freescale/imx93-ts9370.dts b/arch/arm64/boot/dts/freescale/imx93-ts9370.dts new file mode 100644 index 000000000000..ef2d56b1a2ad --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx93-ts9370.dts @@ -0,0 +1,1312 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2024-2026 Technologic Systems, Inc. (dba embeddedTS) + */ + +/dts-v1/; + +#include +#include "imx93.dtsi" + +#include "imx93-ts9370-pinfunc.h" + +/ { + model = "embeddedTS TS-9370"; + compatible = "technologic,ts9370", "fsl,imx93"; + + chosen { + bootargs = "console=ttyLP0,115200"; + stdout-path = &lpuart1; + }; + + aliases { + gpio0 = &gpio1; + gpio1 = &gpio2; + gpio2 = &gpio3; + gpio3 = &gpio4; + gpio4 = &fpga_gpio0; + gpio5 = &fpga_gpio1; + gpio6 = &fpga_gpio2; + i2c0 = &lpi2c1; + i2c1 = &lpi2c2; + i2c2 = &lpi2c3; + i2c3 = &lpi2c4; + i2c4 = &lpi2c5; + i2c5 = &lpi2c6; + i2c6 = &lpi2c7; + i2c7 = &lpi2c8; + i2c8 = &mikrobus_i2c_gpio; + ethernet0 = &fec; + ethernet1 = &eqos; + mmc0 = &usdhc1; + mmc1 = &usdhc2; + mmc2 = &usdhc3; + serial0 = &lpuart1; + serial1 = &lpuart2; + serial2 = &lpuart3; + serial3 = &lpuart4; + serial4 = &lpuart5; + serial5 = &lpuart6; + serial6 = &lpuart7; + serial7 = &lpuart8; + rtc0 = &bbnsm_rtc; + }; + + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + linux,cma { + compatible = "shared-dma-pool"; + reusable; + alloc-ranges = <0 0x80000000 0 0x40000000>; + size = <0 0x10000000>; + linux,cma-default; + }; + + vdev0vring0: vdev0vring0@a4000000 { + reg = <0 0xa4000000 0 0x8000>; + no-map; + }; + + vdev0vring1: vdev0vring1@a4008000 { + reg = <0 0xa4008000 0 0x8000>; + no-map; + }; + + vdev1vring0: vdev1vring0@a4010000 { + reg = <0 0xa4010000 0 0x8000>; + no-map; + }; + + vdev1vring1: vdev1vring1@a4018000 { + reg = <0 0xa4018000 0 0x8000>; + no-map; + }; + + rsc_table: rsc-table@2021e000 { + reg = <0 0x2021e000 0 0x1000>; + no-map; + }; + + vdevbuffer: vdevbuffer@a4020000 { + compatible = "shared-dma-pool"; + reg = <0 0xa4020000 0 0x100000>; + no-map; + }; + + ele_reserved: ele-reserved@a4120000 { + compatible = "shared-dma-pool"; + reg = <0 0xa4120000 0 0x100000>; + no-map; + }; + + }; + + spi_adc_mux: adc-mux { + compatible = "io-channel-mux"; + io-channels = <&spi_adc 0>; + io-channel-names = "parent"; + #io-channel-cells = <1>; + + mux-controls = <&mux_adc>; + settle-time-us = <1>; + + channels = "AN_1", + "AN_2", + "AN_3", + "AN_4", + "MIKRO_AN"; + }; + + an_1_voltage: an-1-voltage { + compatible = "voltage-divider"; + io-channels = <&spi_adc_mux 0>; + label = "AN_1"; + output-ohms = <2000>; /* R2: 2k */ + full-ohms = <8040>; /* R1 (6.04k) + R2 (2k) */ + #io-channel-cells = <0>; + }; + + an_2_voltage: an-2-voltage { + compatible = "voltage-divider"; + io-channels = <&spi_adc_mux 1>; + label = "AN_2"; + output-ohms = <2000>; /* R2: 2k */ + full-ohms = <8040>; /* R1 (6.04k) + R2 (2k) */ + #io-channel-cells = <0>; + }; + + an_3_voltage: an-3-voltage { + compatible = "voltage-divider"; + io-channels = <&spi_adc_mux 2>; + label = "AN_3"; + output-ohms = <2000>; /* R2: 2k */ + full-ohms = <8040>; /* R1 (6.04k) + R2 (2k) */ + #io-channel-cells = <0>; + }; + + an_4_voltage: an-4-voltage { + compatible = "voltage-divider"; + io-channels = <&spi_adc_mux 3>; + label = "AN_4"; + output-ohms = <3010>; /* R2: 3.01k */ + full-ohms = <50010>; /* R1 (47k) + R2 (3.01k) */ + #io-channel-cells = <0>; + }; + + clk_dp: clk-dp { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <19200000>; + }; + + leds { + compatible = "gpio-leds"; + + led-0 { + color = ; + function = LED_FUNCTION_POWER; + gpios = <&fpga_gpio0 0 GPIO_ACTIVE_LOW>; + default-state = "on"; + }; + + led-1 { + color = ; + function = LED_FUNCTION_STATUS; + gpios = <&fpga_gpio0 2 GPIO_ACTIVE_LOW>; + default-state = "off"; + }; + + led-2 { + color = ; + function = LED_FUNCTION_INDICATOR; + gpios = <&fpga_gpio0 1 GPIO_ACTIVE_LOW>; + default-state = "off"; + }; + + led-3 { + color = ; + function = LED_FUNCTION_INDICATOR; + gpios = <&fpga_gpio0 3 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + }; + + mux_spi: spi-mux-controller { + compatible = "gpio-mux"; + #mux-control-cells = <0>; + mux-gpios = <&fpga_gpio2 7 GPIO_ACTIVE_HIGH>, + <&fpga_gpio2 8 GPIO_ACTIVE_HIGH>, + <&fpga_gpio2 9 GPIO_ACTIVE_HIGH>; + }; + + mux_adc: adc-mux-controller { + compatible = "gpio-mux"; + #mux-control-cells = <0>; + mux-gpios = <&fpga_gpio1 18 GPIO_ACTIVE_HIGH>, + <&fpga_gpio1 19 GPIO_ACTIVE_HIGH>, + <&fpga_gpio1 20 GPIO_ACTIVE_HIGH>; + }; + + reg_can1_sw5v2: regulator-can1-en { + compatible = "regulator-fixed"; + regulator-name = "EN_CAN1_N"; + regulator-min-microvolt = <5200000>; + regulator-max-microvolt = <5200000>; + gpio = <&fpga_gpio1 1 GPIO_ACTIVE_LOW>; + }; + + reg_can2_sw5v2: regulator-can2-en { + compatible = "regulator-fixed"; + regulator-name = "EN_CAN2_N"; + regulator-min-microvolt = <5200000>; + regulator-max-microvolt = <5200000>; + gpio = <&fpga_gpio1 2 GPIO_ACTIVE_LOW>; + }; + + reg_usb_host1_vbus: regulator-host1-vbus { + compatible = "regulator-fixed"; + regulator-name = "EN_USB_HOST1_VBUS"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&fpga_gpio0 12 GPIO_ACTIVE_HIGH>; + enable-active-high; + regulator-always-on; + }; + + reg_usb_host2_vbus: regulator-host2-vbus { + compatible = "regulator-fixed"; + regulator-name = "EN_USB_HOST2_VBUS"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&fpga_gpio0 13 GPIO_ACTIVE_HIGH>; + enable-active-high; + regulator-always-on; + }; + + reg_usdhc2_vmmc: regulator-usdhc2 { + compatible = "regulator-fixed"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_reg_usdhc2_vmmc>; + regulator-name = "VSD_3V3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpio3 7 GPIO_ACTIVE_HIGH>; + off-on-delay-us = <12000>; + enable-active-high; + }; + + reg_usdhc3_vmmc: regulator-usdhc3 { + compatible = "regulator-fixed"; + regulator-name = "WLAN_EN"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&fpga_gpio1 30 GPIO_ACTIVE_LOW>; + startup-delay-us = <70000>; + enable-active-high; + }; + + reg_vref_1v8: regulator-adc-vref { + compatible = "regulator-fixed"; + regulator-name = "vref_1v8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + reg_vref_3v3: regulator-adc-vref { + compatible = "regulator-fixed"; + regulator-name = "vref_3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + an_vin: an-vin { + compatible = "voltage-divider"; + io-channels = <&wizard_adc 0>; + label = "VIN"; + output-ohms = <4990>; /* R2: 4.9k */ + full-ohms = <79990>; /* R1 (75k) + R2 (4.99k) */ + #io-channel-cells = <0>; + }; + + an_5p2va: an-5p2va { + compatible = "voltage-divider"; + io-channels = <&wizard_adc 1>; + label = "5.2V_A"; + output-ohms = <75000>; /* R2: 75k */ + full-ohms = <150000>; /* R1 (75k) + R2 (75k) */ + #io-channel-cells = <0>; + }; + + an_reg_5v: an-reg-5v { + compatible = "voltage-divider"; + io-channels = <&wizard_adc 2>; + label = "REG_5V"; + output-ohms = <75000>; /* R2: 75k */ + full-ohms = <150000>; /* R1 (75k) + R2 (75k) */ + #io-channel-cells = <0>; + }; + + an_vchrg: an-vchrg { + compatible = "voltage-divider"; + io-channels = <&wizard_adc 3>; + label = "VCHRG"; + output-ohms = <75000>; /* R2: 75k */ + full-ohms = <150000>; /* R1 (75k) + R2 (75k) */ + #io-channel-cells = <0>; + }; + + an_scap_plus: an-scap-plus { + compatible = "voltage-divider"; + io-channels = <&wizard_adc 4>; + label = "SCAP_PLUS"; + output-ohms = <75000>; /* R2: 75k */ + full-ohms = <150000>; /* R1 (75k) + R2 (75k) */ + #io-channel-cells = <0>; + }; + + mikrobus_i2c_gpio: i2c-gpio { + compatible = "i2c-gpio"; + #address-cells = <1>; + #size-cells = <0>; + gpios = < + &fpga_gpio0 24 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN) /* SDA */ + &fpga_gpio0 25 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN) /* SCL */ + >; + i2c-gpio,delay-us = <4>; + status = "okay"; + }; + + sound { + compatible = "simple-audio-card"; + simple-audio-card,name = "tsimx9"; + simple-audio-card,format = "i2s"; + simple-audio-card,bitclock-master = <&cpu_dai>; + simple-audio-card,frame-master = <&cpu_dai>; + simple-audio-card,mclk-fs = <256>; + + simple-audio-card,widgets = + "Line", "IN1P Line In", + "Line", "OUT1M Line Out"; + + simple-audio-card,routing = + "AIN1", "IN1P Line In", + "OUT1M Line Out", "OUT1"; + + cpu_dai: simple-audio-card,cpu { + sound-dai = <&sai1>; + }; + + codec_dai: simple-audio-card,codec { + sound-dai = <&tac5x1x>; + }; + }; +}; + +&adc1 { + vref-supply = <®_vref_1v8>; + status = "okay"; +}; + +&cm33 { + mbox-names = "tx", "rx", "rxdb"; + mboxes = <&mu1 0 1>, + <&mu1 1 1>, + <&mu1 3 1>; + memory-region = <&vdevbuffer>, <&vdev0vring0>, <&vdev0vring1>, + <&vdev1vring0>, <&vdev1vring1>, <&rsc_table>; + status = "okay"; +}; + +&aips2 { + fpga: fpga@425e0000 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "nxp,imx93-fspi-bus"; + reg = <0x425e0000 0x10000>; + interrupts = ; + clocks = <&clk IMX93_CLK_FLEXSPI1_GATE>, + <&clk IMX93_CLK_FLEXSPI1_GATE>; + clock-names = "fspi", "fspi_en"; + assigned-clocks = <&clk IMX93_CLK_FLEXSPI1>; + assigned-clock-parents = <&clk IMX93_CLK_SYS_PLL_PFD1>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_flexspi>; + //clock-frequency = <66666666>; + clock-frequency = <61000000>; + nxp,ahb-bus-only; + nxp,fspi-individual-mode; + ranges = <0 0x28000000 0x10000000>; + + fpga_irqc: irq@28000020 { + compatible = "technologic,ts9370-irqc"; + reg = <0x20 0x20>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fpga_irq>; + + interrupt-parent = <&gpio4>; + interrupts = <28 IRQ_TYPE_LEVEL_HIGH>; + + #interrupt-cells = <1>; + interrupt-controller; + }; + + fpga_xbar: pinctrl@28002000 { + compatible = "technologic,ts9370-xbar"; + reg = <0x2000 0x200>; + }; + + fpga_gpio0: gpio@28000040 { + compatible = "technologic,ts9370-gpio"; + reg = <0x40 0x40>; + + gpio-controller; + #gpio-cells = <2>; + + interrupt-parent = <&fpga_irqc>; + interrupts = <0>; + #interrupt-cells = <2>; + interrupt-controller; + + gpio-line-names = + "EN_GREEN_LED#", "EN_YEL_LED#", "EN_RED_LED#", "EN_BLUE_LED", + "NIM_RESET#", "NIM_CTS#", "NIM_PWR_ON#", "EN_NIM_USB#", + "EN_NIM_4V", "EN_NIM_3.3V", "NIM_TXD", "NIM_RXD", + "EN_USB_HOST1_VBUS", "EN_USB_HOST2_VBUS", "MIKRO_TXD", "MIKRO_RXD", + "MIKRO_SPI_CLK", "MIKRO_SPI_CS#", "MIKRO_SPI_MISO", "MIKRO_SPI_MOSI", + "MIKRO_RESET#", "MIKRO_AN", "MIKRO_PWM", "MIKRO_INT", + "MIKRO_I2C_SDA", "MIKRO_I2C_SCL", "", "", + "", "", "NIM_STATUS", ""; + }; + + fpga_gpio1: gpio@28000080 { + compatible = "technologic,ts9370-gpio"; + reg = <0x80 0x40>; + + gpio-controller; + #gpio-cells = <2>; + + interrupt-parent = <&fpga_irqc>; + interrupts = <1>; + #interrupt-cells = <2>; + interrupt-controller; + + gpio-line-names = + "EN_2ND_PORT_232", "EN_CAN_1#", "EN_CAN_2#", "", + "USB_HUB_RESET#", "PUSH_SW#", "", "", + "", "", "", "", + "", "", "", "", + "", "", "AN_SEL_0", "AN_SEL_1", + "AN_SEL_2", "EN_ADC_3_12V", "EN_ADC_1_2_12V", "", + "", "EN_CL_1_2", "EN_CL_3", "DP_RESET#", + "NO_SCAP_CHRG#", "EN_SPKR_AMP", "BT_EN", ""; + }; + + fpga_gpio2: gpio@280000c0 { + compatible = "technologic,ts9370-gpio"; + reg = <0xC0 0x40>; + + gpio-controller; + #gpio-cells = <2>; + + interrupt-parent = <&fpga_irqc>; + interrupts = <2>; + #interrupt-cells = <2>; + interrupt-controller; + + gpio-line-names = + "MAGNET_IRQ", "GYRO_IRQ", "", "", + "", "", "", "LPSPI4_SPIMUX_0", + "LPSPI4_SPIMUX_1", "LPSPI4_SPIMUX_2", "", "", + "", "", "", "CLEAR_FAULT", + "EN_HS_SW", "EN_LS_OUT_1", "EN_LS_OUT_2", "EN_LS_OUT_3", + "EN_LS_OUT_4", "CIRCUIT_BREAKER_FAULT", "", "DIO_1_IN", + "DIO_2_IN", "DIO_3_IN", "DIO_4_IN", "DC_1", + "DC_3", "DC_5", "DC_7", "DC_9"; + }; + + fpga_pwm0: pwm@28000400 { + compatible = "technologic,pwm32"; + reg = <0x400 0x20>; + clocks = <&clk IMX93_CLK_FLEXSPI1>; + clock-names = "fspi"; + #pwm-cells = <2>; + }; + }; +}; + +&bbnsm_rtc { + status = "disabled"; +}; + +&eqos { + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&pinctrl_eqos>; + pinctrl-1 = <&pinctrl_eqos_sleep>; + phy-mode = "rgmii-id"; + phy-handle = <ðphy1>; + status = "okay"; + + mdio { + compatible = "snps,dwmac-mdio"; + #address-cells = <1>; + #size-cells = <0>; + clock-frequency = <5000000>; + + ethphy1: ethernet-phy@1 { + //compatible = "ethernet-phy-ieee802.3-c22"; + reg = <1>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_eqos_phy>; + reset-gpios = <&gpio2 28 GPIO_ACTIVE_LOW>; + reset-assert-us = <6>; + reset-deassert-us = <50000>; + }; + }; +}; + +&fec { + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&pinctrl_fec>; + pinctrl-1 = <&pinctrl_fec_sleep>; + phy-mode = "rgmii-id"; + phy-handle = <ðphy2>; + fsl,magic-packet; + status = "okay"; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + clock-frequency = <5000000>; + + ethphy2: ethernet-phy@1 { + //compatible = "ethernet-phy-ieee802.3-c22"; + reg = <1>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fec_phy>; + eee-broken-1000t; + reset-gpios = <&gpio2 29 GPIO_ACTIVE_LOW>; + reset-assert-us = <6>; + reset-deassert-us = <50000>; + }; + }; +}; + +&flexcan1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_flexcan1>; + xceiver-supply = <®_can1_sw5v2>; + status = "okay"; +}; + +&flexcan2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_flexcan2>; + xceiver-supply = <®_can2_sw5v2>; + status = "okay"; +}; + +&lpi2c1 { + #address-cells = <1>; + #size-cells = <0>; + clock-frequency = <400000>; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&pinctrl_lpi2c1>; + pinctrl-1 = <&pinctrl_lpi2c1>; + status = "okay"; +}; + +&lpi2c2 { + #address-cells = <1>; + #size-cells = <0>; + clock-frequency = <400000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_lpi2c2>; + status = "okay"; + + pmic@25 { + compatible = "nxp,pca9451a"; + reg = <0x25>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pmic>; + interrupt-parent = <&gpio1>; + interrupts = <10 IRQ_TYPE_LEVEL_LOW>; + nxp,i2c-lt-enable; + + regulators { + buck1: BUCK1 { + regulator-name = "BUCK1"; + regulator-min-microvolt = <610000>; + regulator-max-microvolt = <950000>; + regulator-boot-on; + regulator-always-on; + regulator-ramp-delay = <3125>; + }; + + buck2: BUCK2 { + regulator-name = "BUCK2"; + regulator-min-microvolt = <600000>; + regulator-max-microvolt = <670000>; + regulator-boot-on; + regulator-always-on; + regulator-ramp-delay = <3125>; + }; + + buck4: BUCK4{ + regulator-name = "BUCK4"; + regulator-min-microvolt = <1620000>; + regulator-max-microvolt = <3400000>; + regulator-boot-on; + regulator-always-on; + }; + + buck5: BUCK5{ + regulator-name = "BUCK5"; + regulator-min-microvolt = <1620000>; + regulator-max-microvolt = <3400000>; + regulator-boot-on; + regulator-always-on; + }; + + buck6: BUCK6 { + regulator-name = "BUCK6"; + regulator-min-microvolt = <1060000>; + regulator-max-microvolt = <1140000>; + regulator-boot-on; + regulator-always-on; + }; + + ldo1: LDO1 { + regulator-name = "LDO1"; + regulator-min-microvolt = <1620000>; + regulator-max-microvolt = <1980000>; + regulator-boot-on; + regulator-always-on; + }; + + ldo4: LDO4 { + regulator-name = "LDO4"; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <840000>; + regulator-boot-on; + regulator-always-on; + }; + + ldo5: LDO5 { + regulator-name = "LDO5"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + }; + }; +}; + +&lpi2c4 { + #address-cells = <1>; + #size-cells = <0>; + clock-frequency = <400000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_lpi2c4>; + status = "okay"; + + magnet: magnetometer@1e { + compatible = "st,iis2mdc"; + reg = <0x1e>; + st,drdy-int-pin = <1>; + interrupt-parent = <&fpga_gpio2>; + interrupts = <0 IRQ_TYPE_EDGE_RISING>; + }; + + tac5x1x: tac5x1x@50 { + compatible = "ti,tac5111"; + reg = <0x50>; + #sound-dai-cells = <0>; + avdd-supply = <®_vref_3v3>; + iovdd-supply = <®_vref_3v3>; + ti,vref = <0>; + ti,adc1-impedance = <0>; + ti,micbias-vg = <3>; + ti,gpi1-func = <0>; + ti,gpios-func = <0>, <0>, <0>; + ti,gpios-drive = <0>, <0>, <0>; + ti,gpa-gpio = <0>; + ti,in-ch-en = <1>; + ti,out-ch-en = <1>; + ti,incl-ac-coup = <0>; + ti,incl-se-inm = <0>; + ti,gpa-threshold = <75>, <186>; + }; + + wizard: wizard@54 { + compatible = "technologic,wizard"; + reg = <0x54>; + + wizard_adc: adc { + compatible = "technologic,wizard-adc"; + #io-channel-cells = <1>; + }; + + wizard_irq: irq { + compatible = "technologic,wizard-irq"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_wizirq>; + + interrupt-parent = <&gpio4>; + interrupts = <29 IRQ_TYPE_LEVEL_HIGH>; + + #interrupt-cells = <1>; + interrupt-controller; + }; + + wizard_silo: ups { + compatible = "technologic,wizard-silo"; + interrupt-parent = <&wizard_irq>; + interrupts = <0>; + }; + + wizard_temp: temp { + compatible = "technologic,wizard-temp"; + #io-channel-cells = <0>; + }; + + wizard_reset: reset { + compatible = "technologic,wizard-reset"; + }; + }; + + wizard_rtc: rtc@60 { + compatible = "technologic,wizard-rtc"; + reg = <0x60>; + wakeup-source; + }; + + ism330: gyro@6a { + compatible = "st,ism330dhcx"; + reg = <0x6a>; + interrupt-parent = <&fpga_gpio2>; + interrupts = <1 IRQ_TYPE_EDGE_RISING>; + }; +}; + +&lpspi4 { + num-cs = <1>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_lpspi4>; + cs-gpios = <&gpio2 18 GPIO_ACTIVE_LOW>; + status = "okay"; + + spi_mux_bus: spi@0 { + compatible = "spi-mux"; + reg = <0>; + mux-controls = <&mux_spi>; + #address-cells = <1>; + #size-cells = <0>; + + spi_adc: adc@0 { + compatible = "ti,adc121s021"; + reg = <0>; + vref-supply = <®_vref_3v3>; + spi-max-frequency = <2000000>; + #io-channel-cells = <1>; + }; + + mikrobus_spi: spi@1 { + compatible = "technologic,spi-header"; + reg = <1>; + spi-max-frequency = <10000000>; + }; + + dc_header_spi: spi@2 { + compatible = "technologic,spi-header"; + reg = <2>; + spi-max-frequency = <10000000>; + }; + }; +}; + +&lpuart1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart1>; + status = "okay"; +}; + +&lpuart2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart2>; + status = "okay"; +}; + +&lpuart3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart3>; + uart-has-rtscts; + linux,rs485-enabled-at-boot-time; + status = "okay"; +}; + +&lpuart5 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart5>; + status = "okay"; +}; + +&lpuart6 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart6>; + uart-has-rtscts; + status = "okay"; + + bluetooth { + compatible = "nxp,88w8987-bt"; + fw-init-baudrate = <3000000>; + }; +}; + +&lpuart7 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart7>; + uart-has-rtscts; + linux,rs485-enabled-at-boot-time; + status = "okay"; +}; + +&lpuart8 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart8>; + status = "okay"; +}; + +&sai1 { + #sound-dai-cells = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sai1>; + + assigned-clocks = <&clk IMX93_CLK_SAI1>; + assigned-clock-parents = <&clk IMX93_CLK_AUDIO_PLL>; + assigned-clock-rates = <12288000>; + + fsl,sai-mclk-direction-output; + status = "okay"; +}; + +&usbotg1 { + dr_mode = "host"; + status = "okay"; +}; + +&usbotg2 { + #address-cells = <1>; + #size-cells = <0>; + dr_mode = "host"; + status = "okay"; + + usb@1 { + compatible = "usb424,2514"; + reg = <1>; + + reset-gpios = <&fpga_gpio1 4 GPIO_ACTIVE_LOW>; + + clocks = <&clk IMX93_CLK_CCM_CKO1>; + assigned-clocks = <&clk IMX93_CLK_CCM_CKO1>; + assigned-clock-parents = <&clk IMX93_CLK_24M>; + assigned-clock-rates = <24000000>; + }; +}; + +&usdhc1 { + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + pinctrl-0 = <&pinctrl_usdhc1>; + pinctrl-1 = <&pinctrl_usdhc1_100mhz>; + pinctrl-2 = <&pinctrl_usdhc1_200mhz>; + bus-width = <8>; + non-removable; + status = "okay"; +}; + +&usdhc2 { + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + pinctrl-0 = <&pinctrl_usdhc2>; + pinctrl-1 = <&pinctrl_usdhc2_100mhz>; + pinctrl-2 = <&pinctrl_usdhc2_200mhz>; + vmmc-supply = <®_usdhc2_vmmc>; + bus-width = <4>; + status = "okay"; + no-sdio; + no-mmc; + broken-cd; +}; + +&usdhc3 { + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + pinctrl-0 = <&pinctrl_usdhc3>; + pinctrl-1 = <&pinctrl_usdhc3_100mhz>; + pinctrl-2 = <&pinctrl_usdhc3_200mhz>; + vmmc-supply = <®_usdhc3_vmmc>; + bus-width = <4>; + keep-power-in-suspend; + non-removable; + wakeup-source; + status = "okay"; +}; + +&gpio4 { + gpio-line-names = + "", "", "", "", "", + "", "", "", "", "", + "", "", "", "", "", + "", "", "", "", "", + "", "", "", "", "", + "", "", "", "FPGA_CPU_IRQ", "WIZ_IRQ"; +}; + +&iomuxc { + pinctrl_eqos: eqosgrp { + fsl,pins = < + MX93_PAD_ENET1_MDC__ENET_QOS_MDC 0x57e + MX93_PAD_ENET1_MDIO__ENET_QOS_MDIO 0x57e + MX93_PAD_ENET1_RD0__ENET_QOS_RGMII_RD0 0x57e + MX93_PAD_ENET1_RD1__ENET_QOS_RGMII_RD1 0x57e + MX93_PAD_ENET1_RD2__ENET_QOS_RGMII_RD2 0x57e + MX93_PAD_ENET1_RD3__ENET_QOS_RGMII_RD3 0x57e + MX93_PAD_ENET1_RXC__CCM_ENET_QOS_CLOCK_GENERATE_RX_CLK 0x5fe + MX93_PAD_ENET1_RX_CTL__ENET_QOS_RGMII_RX_CTL 0x57e + MX93_PAD_ENET1_TD0__ENET_QOS_RGMII_TD0 0x57e + MX93_PAD_ENET1_TD1__ENET_QOS_RGMII_TD1 0x57e + MX93_PAD_ENET1_TD2__ENET_QOS_RGMII_TD2 0x57e + MX93_PAD_ENET1_TD3__ENET_QOS_RGMII_TD3 0x57e + MX93_PAD_ENET1_TXC__CCM_ENET_QOS_CLOCK_GENERATE_TX_CLK 0x5fe + MX93_PAD_ENET1_TX_CTL__ENET_QOS_RGMII_TX_CTL 0x57e + >; + }; + + pinctrl_eqos_phy: eqosphygrp { + fsl,pins = < + MX93_PAD_GPIO_IO28__GPIO2_IO28 0x1306 + >; + }; + + pinctrl_pmic: pmicgrp { + fsl,pins = < + MX93_PAD_PDM_BIT_STREAM1__GPIO1_IO10 0x40000b9e + >; + }; + + pinctrl_lpi2c1: lpi2c1grp { + fsl,pins = < + MX93_PAD_I2C1_SCL__LPI2C1_SCL 0x40000b9e + MX93_PAD_I2C1_SDA__LPI2C1_SDA 0x40000b9e + >; + }; + + pinctrl_lpi2c2: lpi2c2grp { + fsl,pins = < + MX93_PAD_I2C2_SCL__LPI2C2_SCL 0x40000b9e + MX93_PAD_I2C2_SDA__LPI2C2_SDA 0x40000b9e + >; + }; + + pinctrl_lpi2c4: lpi2c4grp { + fsl,pins = < + MX93_PAD_GPIO_IO02__LPI2C4_SDA 0x40000b9e + MX93_PAD_GPIO_IO03__LPI2C4_SCL 0x40000b9e + >; + }; + + pinctrl_lpspi4: spi4grp { + fsl,pins = < + MX93_PAD_GPIO_IO21__LPSPI4_SCK 0x3fe + MX93_PAD_GPIO_IO20__LPSPI4_SOUT 0x3fe + MX93_PAD_GPIO_IO19__LPSPI4_SIN 0x3fe + MX93_PAD_GPIO_IO18__GPIO2_IO18 0x3fe + >; + }; + + pinctrl_eqos_sleep: eqossleepgrp { + fsl,pins = < + MX93_PAD_ENET1_MDC__GPIO4_IO00 0x31e + MX93_PAD_ENET1_MDIO__GPIO4_IO01 0x31e + MX93_PAD_ENET1_RD0__GPIO4_IO10 0x31e + MX93_PAD_ENET1_RD1__GPIO4_IO11 0x31e + MX93_PAD_ENET1_RD2__GPIO4_IO12 0x31e + MX93_PAD_ENET1_RD3__GPIO4_IO13 0x31e + MX93_PAD_ENET1_RXC__GPIO4_IO09 0x31e + MX93_PAD_ENET1_RX_CTL__GPIO4_IO08 0x31e + MX93_PAD_ENET1_TD0__GPIO4_IO05 0x31e + MX93_PAD_ENET1_TD1__GPIO4_IO04 0x31e + MX93_PAD_ENET1_TD2__GPIO4_IO03 0x31e + MX93_PAD_ENET1_TD3__GPIO4_IO02 0x31e + MX93_PAD_ENET1_TXC__GPIO4_IO07 0x31e + MX93_PAD_ENET1_TX_CTL__GPIO4_IO06 0x31e + >; + }; + + pinctrl_flexcan1: flexcan1grp { + fsl,pins = < + MX93_PAD_PDM_CLK__CAN1_TX 0x139e + MX93_PAD_PDM_BIT_STREAM0__CAN1_RX 0x139e + >; + }; + + pinctrl_flexcan2: flexcan2grp { + fsl,pins = < + MX93_PAD_DAP_TDI__CAN2_TX 0x139e + MX93_PAD_DAP_TDO_TRACESWO__CAN2_RX 0x139e + >; + }; + + pinctrl_flexspi: flexspigrp { + fsl,pins = < + MX93_PAD_SD3_CMD__FLEXSPI1_A_SS0_B 0x42 + MX93_PAD_SD3_CLK__FLEXSPI1_A_SCLK 0x42 + MX93_PAD_SD3_DATA0__FLEXSPI1_A_DATA00 0x42 + MX93_PAD_SD3_DATA1__FLEXSPI1_A_DATA01 0x42 + MX93_PAD_SD3_DATA2__FLEXSPI1_A_DATA02 0x42 + MX93_PAD_SD3_DATA3__FLEXSPI1_A_DATA03 0x42 + >; + }; + + pinctrl_fec: fecgrp { + fsl,pins = < + MX93_PAD_ENET2_MDC__ENET1_MDC 0x57e + MX93_PAD_ENET2_MDIO__ENET1_MDIO 0x57e + MX93_PAD_ENET2_RD0__ENET1_RGMII_RD0 0x57e + MX93_PAD_ENET2_RD1__ENET1_RGMII_RD1 0x57e + MX93_PAD_ENET2_RD2__ENET1_RGMII_RD2 0x57e + MX93_PAD_ENET2_RD3__ENET1_RGMII_RD3 0x57e + MX93_PAD_ENET2_RXC__ENET1_RGMII_RXC 0x5fe + MX93_PAD_ENET2_RX_CTL__ENET1_RGMII_RX_CTL 0x57e + MX93_PAD_ENET2_TD0__ENET1_RGMII_TD0 0x57e + MX93_PAD_ENET2_TD1__ENET1_RGMII_TD1 0x57e + MX93_PAD_ENET2_TD2__ENET1_RGMII_TD2 0x57e + MX93_PAD_ENET2_TD3__ENET1_RGMII_TD3 0x57e + MX93_PAD_ENET2_TXC__ENET1_RGMII_TXC 0x5fe + MX93_PAD_ENET2_TX_CTL__ENET1_RGMII_TX_CTL 0x57e + >; + }; + + pinctrl_fec_phy: fecphygrp { + fsl,pins = < + MX93_PAD_GPIO_IO29__GPIO2_IO29 0x1306 + >; + }; + + pinctrl_fec_sleep: fecsleepgrp { + fsl,pins = < + MX93_PAD_ENET2_MDC__GPIO4_IO14 0x51e + MX93_PAD_ENET2_MDIO__GPIO4_IO15 0x51e + MX93_PAD_ENET2_RD0__GPIO4_IO24 0x51e + MX93_PAD_ENET2_RD1__GPIO4_IO25 0x51e + MX93_PAD_ENET2_RD2__GPIO4_IO26 0x51e + MX93_PAD_ENET2_RD3__GPIO4_IO27 0x51e + MX93_PAD_ENET2_RXC__GPIO4_IO23 0x51e + MX93_PAD_ENET2_RX_CTL__GPIO4_IO22 0x51e + MX93_PAD_ENET2_TD0__GPIO4_IO19 0x51e + MX93_PAD_ENET2_TD1__GPIO4_IO18 0x51e + MX93_PAD_ENET2_TD2__GPIO4_IO17 0x51e + MX93_PAD_ENET2_TD3__GPIO4_IO16 0x51e + MX93_PAD_ENET2_TXC__GPIO4_IO21 0x51e + MX93_PAD_ENET2_TX_CTL__GPIO4_IO20 0x51e + >; + }; + + pinctrl_fpga_irq: fpgairqgrp { + fsl,pins = < + MX93_PAD_CCM_CLKO3__GPIO4_IO28 0x40000b9e + >; + }; + + pinctrl_sai1: sai1grp { + fsl,pins = < + MX93_PAD_SAI1_TXFS__SAI1_TX_SYNC 0x302 + MX93_PAD_SAI1_TXC__SAI1_TX_BCLK 0x306 + MX93_PAD_SAI1_TXD0__SAI1_TX_DATA00 0x302 + MX93_PAD_SAI1_RXD0__SAI1_RX_DATA00 0x31e + >; + }; + + pinctrl_uart1: uart1grp { + fsl,pins = < + MX93_PAD_UART1_RXD__LPUART1_RX 0x31e + MX93_PAD_UART1_TXD__LPUART1_TX 0x31e + >; + }; + + pinctrl_uart2: uart2grp { + fsl,pins = < + MX93_PAD_UART2_RXD__LPUART2_RX 0x31e + MX93_PAD_UART2_TXD__LPUART2_TX 0x31e + >; + }; + + pinctrl_uart3: uart3grp { + fsl,pins = < + MX93_PAD_GPIO_IO15__LPUART3_RX 0x31e + MX93_PAD_GPIO_IO14__LPUART3_TX 0x31e + MX93_PAD_GPIO_IO17__LPUART3_RTS_B 0x31e + MX93_PAD_GPIO_IO16__LPUART3_CTS_B 0x31e + >; + }; + + pinctrl_uart5: uart5grp { + fsl,pins = < + MX93_PAD_GPIO_IO00__LPUART5_TX 0x31e + MX93_PAD_GPIO_IO01__LPUART5_RX 0x31e + >; + }; + + pinctrl_uart6: uart6grp { + fsl,pins = < + MX93_PAD_GPIO_IO04__LPUART6_TX 0x31e + MX93_PAD_GPIO_IO05__LPUART6_RX 0x31e + MX93_PAD_GPIO_IO06__LPUART6_CTS_B 0x31e + MX93_PAD_GPIO_IO07__LPUART6_RTS_B 0x31e + >; + }; + + pinctrl_uart7: uart7grp { + fsl,pins = < + MX93_PAD_GPIO_IO08__LPUART7_TX 0x31e + MX93_PAD_GPIO_IO09__LPUART7_RX 0x31e + MX93_PAD_GPIO_IO10__LPUART7_CTS_B 0x31e + MX93_PAD_GPIO_IO11__LPUART7_RTS_B 0x31e + >; + }; + + pinctrl_uart8: uart8grp { + fsl,pins = < + MX93_PAD_GPIO_IO12__LPUART8_TX 0x31e + MX93_PAD_GPIO_IO13__LPUART8_RX 0x31e + >; + }; + + /* need to config the SION for data and cmd pad, refer to ERR052021 */ + pinctrl_usdhc1: usdhc1grp { + fsl,pins = < + MX93_PAD_SD1_CLK__USDHC1_CLK 0x1582 + MX93_PAD_SD1_CMD__USDHC1_CMD 0x40001382 + MX93_PAD_SD1_DATA0__USDHC1_DATA0 0x40001382 + MX93_PAD_SD1_DATA1__USDHC1_DATA1 0x40001382 + MX93_PAD_SD1_DATA2__USDHC1_DATA2 0x40001382 + MX93_PAD_SD1_DATA3__USDHC1_DATA3 0x40001382 + MX93_PAD_SD1_DATA4__USDHC1_DATA4 0x40001382 + MX93_PAD_SD1_DATA5__USDHC1_DATA5 0x40001382 + MX93_PAD_SD1_DATA6__USDHC1_DATA6 0x40001382 + MX93_PAD_SD1_DATA7__USDHC1_DATA7 0x40001382 + MX93_PAD_SD1_STROBE__USDHC1_STROBE 0x1582 + >; + }; + + /* need to config the SION for data and cmd pad, refer to ERR052021 */ + pinctrl_usdhc1_100mhz: usdhc1-100mhzgrp { + fsl,pins = < + MX93_PAD_SD1_CLK__USDHC1_CLK 0x158e + MX93_PAD_SD1_CMD__USDHC1_CMD 0x4000138e + MX93_PAD_SD1_DATA0__USDHC1_DATA0 0x4000138e + MX93_PAD_SD1_DATA1__USDHC1_DATA1 0x4000138e + MX93_PAD_SD1_DATA2__USDHC1_DATA2 0x4000138e + MX93_PAD_SD1_DATA3__USDHC1_DATA3 0x4000138e + MX93_PAD_SD1_DATA4__USDHC1_DATA4 0x4000138e + MX93_PAD_SD1_DATA5__USDHC1_DATA5 0x4000138e + MX93_PAD_SD1_DATA6__USDHC1_DATA6 0x4000138e + MX93_PAD_SD1_DATA7__USDHC1_DATA7 0x4000138e + MX93_PAD_SD1_STROBE__USDHC1_STROBE 0x158e + >; + }; + + /* need to config the SION for data and cmd pad, refer to ERR052021 */ + pinctrl_usdhc1_200mhz: usdhc1-200mhzgrp { + fsl,pins = < + MX93_PAD_SD1_CLK__USDHC1_CLK 0x15fe + MX93_PAD_SD1_CMD__USDHC1_CMD 0x400013fe + MX93_PAD_SD1_DATA0__USDHC1_DATA0 0x400013fe + MX93_PAD_SD1_DATA1__USDHC1_DATA1 0x400013fe + MX93_PAD_SD1_DATA2__USDHC1_DATA2 0x400013fe + MX93_PAD_SD1_DATA3__USDHC1_DATA3 0x400013fe + MX93_PAD_SD1_DATA4__USDHC1_DATA4 0x400013fe + MX93_PAD_SD1_DATA5__USDHC1_DATA5 0x400013fe + MX93_PAD_SD1_DATA6__USDHC1_DATA6 0x400013fe + MX93_PAD_SD1_DATA7__USDHC1_DATA7 0x400013fe + MX93_PAD_SD1_STROBE__USDHC1_STROBE 0x15fe + >; + }; + + pinctrl_reg_usdhc2_vmmc: regusdhc2vmmcgrp { + fsl,pins = < + MX93_PAD_SD2_RESET_B__GPIO3_IO07 0x31e + >; + }; + + /* need to config the SION for data and cmd pad, refer to ERR052021 */ + pinctrl_usdhc2: usdhc2grp { + fsl,pins = < + MX93_PAD_SD2_CLK__USDHC2_CLK 0x1582 + MX93_PAD_SD2_CMD__USDHC2_CMD 0x40001382 + MX93_PAD_SD2_DATA0__USDHC2_DATA0 0x40001382 + MX93_PAD_SD2_DATA1__USDHC2_DATA1 0x40001382 + MX93_PAD_SD2_DATA2__USDHC2_DATA2 0x40001382 + MX93_PAD_SD2_DATA3__USDHC2_DATA3 0x40001382 + MX93_PAD_SD2_VSELECT__USDHC2_VSELECT 0x51e + >; + }; + + /* need to config the SION for data and cmd pad, refer to ERR052021 */ + pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp { + fsl,pins = < + MX93_PAD_SD2_CLK__USDHC2_CLK 0x158e + MX93_PAD_SD2_CMD__USDHC2_CMD 0x4000138e + MX93_PAD_SD2_DATA0__USDHC2_DATA0 0x4000138e + MX93_PAD_SD2_DATA1__USDHC2_DATA1 0x4000138e + MX93_PAD_SD2_DATA2__USDHC2_DATA2 0x4000138e + MX93_PAD_SD2_DATA3__USDHC2_DATA3 0x4000138e + MX93_PAD_SD2_VSELECT__USDHC2_VSELECT 0x51e + >; + }; + + /* need to config the SION for data and cmd pad, refer to ERR052021 */ + pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp { + fsl,pins = < + MX93_PAD_SD2_CLK__USDHC2_CLK 0x15fe + MX93_PAD_SD2_CMD__USDHC2_CMD 0x400013fe + MX93_PAD_SD2_DATA0__USDHC2_DATA0 0x400013fe + MX93_PAD_SD2_DATA1__USDHC2_DATA1 0x400013fe + MX93_PAD_SD2_DATA2__USDHC2_DATA2 0x400013fe + MX93_PAD_SD2_DATA3__USDHC2_DATA3 0x400013fe + MX93_PAD_SD2_VSELECT__USDHC2_VSELECT 0x51e + >; + }; + + /* need to config the SION for data and cmd pad, refer to ERR052021 */ + pinctrl_usdhc3: usdhc3grp { + fsl,pins = < + MX93_PAD_GPIO_IO22__USDHC3_CLK 0x1582 + MX93_PAD_GPIO_IO23__USDHC3_CMD 0x40001382 + MX93_PAD_GPIO_IO24__USDHC3_DATA0 0x40001382 + MX93_PAD_GPIO_IO25__USDHC3_DATA1 0x40001382 + MX93_PAD_GPIO_IO26__USDHC3_DATA2 0x40001382 + MX93_PAD_GPIO_IO27__USDHC3_DATA3 0x40001382 + >; + }; + + /* need to config the SION for data and cmd pad, refer to ERR052021 */ + pinctrl_usdhc3_100mhz: usdhc3-100mhzgrp { + fsl,pins = < + MX93_PAD_GPIO_IO22__USDHC3_CLK 0x158e + MX93_PAD_GPIO_IO23__USDHC3_CMD 0x4000138e + MX93_PAD_GPIO_IO24__USDHC3_DATA0 0x4000138e + MX93_PAD_GPIO_IO25__USDHC3_DATA1 0x4000138e + MX93_PAD_GPIO_IO26__USDHC3_DATA2 0x4000138e + MX93_PAD_GPIO_IO27__USDHC3_DATA3 0x4000138e + >; + }; + + /* need to config the SION for data and cmd pad, refer to ERR052021 */ + pinctrl_usdhc3_200mhz: usdhc3-200mhzgrp { + fsl,pins = < + MX93_PAD_GPIO_IO22__USDHC3_CLK 0x15fe + MX93_PAD_GPIO_IO23__USDHC3_CMD 0x400013fe + MX93_PAD_GPIO_IO24__USDHC3_DATA0 0x400013fe + MX93_PAD_GPIO_IO25__USDHC3_DATA1 0x400013fe + MX93_PAD_GPIO_IO26__USDHC3_DATA2 0x400013fe + MX93_PAD_GPIO_IO27__USDHC3_DATA3 0x400013fe + >; + }; + + pinctrl_wdog: wdoggrp { + fsl,pins = < + MX93_PAD_WDOG_ANY__WDOG1_WDOG_ANY 0x82 + >; + }; + + pinctrl_wizirq: wizard-irqgrp { + fsl,pins = < + MX93_PAD_CCM_CLKO4__GPIO4_IO29 0x4000019e + >; + }; +}; + +&wdog3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_wdog>; + status = "okay"; +}; + +&mu1 { + status = "okay"; +}; + +&mu2 { + status = "okay"; +}; + +&ocotp { + status = "disabled"; +}; + +&media_blk_ctrl { + status = "okay"; +}; diff --git a/arch/arm64/configs/tsimx93_defconfig b/arch/arm64/configs/tsimx93_defconfig new file mode 100644 index 000000000000..4fc0aa9ca57a --- /dev/null +++ b/arch/arm64/configs/tsimx93_defconfig @@ -0,0 +1,1480 @@ +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y +CONFIG_NO_HZ_IDLE=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_BPF_SYSCALL=y +CONFIG_BPF_JIT=y +CONFIG_PREEMPT=y +CONFIG_IRQ_TIME_ACCOUNTING=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_TASKSTATS=y +CONFIG_TASK_XACCT=y +CONFIG_TASK_IO_ACCOUNTING=y +CONFIG_PSI=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_NUMA_BALANCING=y +CONFIG_MEMCG=y +CONFIG_BLK_CGROUP=y +CONFIG_CFS_BANDWIDTH=y +CONFIG_CGROUP_PIDS=y +CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_HUGETLB=y +CONFIG_CPUSETS=y +CONFIG_CGROUP_DEVICE=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_CGROUP_PERF=y +CONFIG_CGROUP_BPF=y +CONFIG_USER_NS=y +CONFIG_CHECKPOINT_RESTORE=y +CONFIG_SCHED_AUTOGROUP=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_PROFILING=y +CONFIG_KEXEC=y +CONFIG_KEXEC_FILE=y +CONFIG_ARCH_NXP=y +CONFIG_ARCH_MXC=y +CONFIG_ARM64_VA_BITS_48=y +CONFIG_NUMA=y +CONFIG_HZ_1000=y +CONFIG_XEN=y +CONFIG_COMPAT=y +CONFIG_RANDOMIZE_BASE=y +CONFIG_PM_DEBUG=y +CONFIG_PM_TEST_SUSPEND=y +CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y +CONFIG_ENERGY_MODEL=y +CONFIG_ARM_PSCI_CPUIDLE=y +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_STAT=y +CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y +CONFIG_CPUFREQ_DT=y +CONFIG_ARM_SCPI_CPUFREQ=y +CONFIG_ARM_IMX_CPUFREQ_DT=y +CONFIG_ARM_SCMI_CPUFREQ=y +CONFIG_ACPI_CPPC_CPUFREQ=m +CONFIG_ACPI=y +CONFIG_ACPI_APEI=y +CONFIG_ACPI_APEI_GHES=y +CONFIG_ACPI_APEI_MEMORY_FAILURE=y +CONFIG_VIRTUALIZATION=y +CONFIG_KVM=y +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODVERSIONS=y +CONFIG_MODULE_COMPRESS=y +CONFIG_MODULE_COMPRESS_XZ=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_BINFMT_MISC=y +# CONFIG_COMPAT_BRK is not set +CONFIG_KSM=y +CONFIG_MEMORY_FAILURE=y +CONFIG_TRANSPARENT_HUGEPAGE=y +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_PACKET_DIAG=m +CONFIG_UNIX_DIAG=m +CONFIG_TLS=y +CONFIG_TLS_DEVICE=y +CONFIG_XFRM_USER=m +CONFIG_XFRM_INTERFACE=m +CONFIG_XFRM_SUB_POLICY=y +CONFIG_NET_KEY=m +CONFIG_NET_KEY_MIGRATE=y +CONFIG_XDP_SOCKETS=y +CONFIG_XDP_SOCKETS_DIAG=m +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE_DEMUX=m +CONFIG_NET_IPGRE=m +CONFIG_NET_IPGRE_BROADCAST=y +CONFIG_IP_MROUTE=y +CONFIG_IP_MROUTE_MULTIPLE_TABLES=y +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +CONFIG_NET_IPVTI=m +CONFIG_NET_FOU_IP_TUNNELS=y +CONFIG_INET_AH=m +CONFIG_INET_ESP=m +CONFIG_INET_ESPINTCP=y +CONFIG_INET_IPCOMP=m +CONFIG_INET_UDP_DIAG=m +CONFIG_INET_RAW_DIAG=m +CONFIG_INET_DIAG_DESTROY=y +CONFIG_TCP_CONG_ADVANCED=y +CONFIG_TCP_CONG_HSTCP=m +CONFIG_TCP_CONG_HYBLA=m +CONFIG_TCP_CONG_NV=m +CONFIG_TCP_CONG_SCALABLE=m +CONFIG_TCP_CONG_LP=m +CONFIG_TCP_CONG_VENO=m +CONFIG_TCP_CONG_YEAH=m +CONFIG_TCP_CONG_ILLINOIS=m +CONFIG_TCP_CONG_DCTCP=m +CONFIG_TCP_CONG_CDG=m +CONFIG_TCP_CONG_BBR=m +CONFIG_TCP_MD5SIG=y +CONFIG_IPV6_ROUTER_PREF=y +CONFIG_IPV6_ROUTE_INFO=y +CONFIG_IPV6_OPTIMISTIC_DAD=y +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_ESPINTCP=y +CONFIG_INET6_IPCOMP=m +CONFIG_IPV6_MIP6=m +CONFIG_IPV6_ILA=m +CONFIG_IPV6_VTI=m +CONFIG_IPV6_SIT=m +CONFIG_IPV6_SIT_6RD=y +CONFIG_IPV6_GRE=m +CONFIG_IPV6_SUBTREES=y +CONFIG_IPV6_MROUTE=y +CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y +CONFIG_IPV6_PIMSM_V2=y +CONFIG_IPV6_SEG6_LWTUNNEL=y +CONFIG_IPV6_SEG6_HMAC=y +CONFIG_IPV6_RPL_LWTUNNEL=y +CONFIG_MPTCP=y +CONFIG_NETWORK_SECMARK=y +CONFIG_NETFILTER=y +CONFIG_BRIDGE_NETFILTER=m +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CONNTRACK_SECMARK=y +CONFIG_NF_CONNTRACK_ZONES=y +CONFIG_NF_CONNTRACK_PROCFS=y +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CONNTRACK_TIMEOUT=y +CONFIG_NF_CONNTRACK_TIMESTAMP=y +CONFIG_NF_CONNTRACK_AMANDA=m +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_H323=m +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_SNMP=m +CONFIG_NF_CONNTRACK_PPTP=m +CONFIG_NF_CONNTRACK_SANE=m +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NF_CT_NETLINK=m +CONFIG_NF_CT_NETLINK_TIMEOUT=m +CONFIG_NF_CT_NETLINK_HELPER=m +CONFIG_NETFILTER_NETLINK_GLUE_CT=y +CONFIG_NF_TABLES=m +CONFIG_NF_TABLES_INET=y +CONFIG_NF_TABLES_NETDEV=y +CONFIG_NFT_NUMGEN=m +CONFIG_NFT_CT=m +CONFIG_NFT_FLOW_OFFLOAD=m +CONFIG_NFT_CONNLIMIT=m +CONFIG_NFT_LOG=m +CONFIG_NFT_LIMIT=m +CONFIG_NFT_MASQ=m +CONFIG_NFT_REDIR=m +CONFIG_NFT_NAT=m +CONFIG_NFT_TUNNEL=m +CONFIG_NFT_QUEUE=m +CONFIG_NFT_QUOTA=m +CONFIG_NFT_REJECT=m +CONFIG_NFT_COMPAT=m +CONFIG_NFT_HASH=m +CONFIG_NFT_FIB_INET=m +CONFIG_NFT_XFRM=m +CONFIG_NFT_SOCKET=m +CONFIG_NFT_OSF=m +CONFIG_NFT_TPROXY=m +CONFIG_NFT_SYNPROXY=m +CONFIG_NFT_DUP_NETDEV=m +CONFIG_NFT_FWD_NETDEV=m +CONFIG_NFT_FIB_NETDEV=m +CONFIG_NF_FLOW_TABLE_INET=m +CONFIG_NF_FLOW_TABLE=m +CONFIG_NETFILTER_XTABLES_LEGACY=y +CONFIG_NETFILTER_XT_SET=m +CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m +CONFIG_NETFILTER_XT_TARGET_CT=m +CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_HMARK=m +CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m +CONFIG_NETFILTER_XT_TARGET_LED=m +CONFIG_NETFILTER_XT_TARGET_LOG=m +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NETMAP=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_REDIRECT=m +CONFIG_NETFILTER_XT_TARGET_TEE=m +CONFIG_NETFILTER_XT_TARGET_TPROXY=m +CONFIG_NETFILTER_XT_TARGET_SECMARK=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m +CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m +CONFIG_NETFILTER_XT_MATCH_BPF=m +CONFIG_NETFILTER_XT_MATCH_CGROUP=m +CONFIG_NETFILTER_XT_MATCH_CLUSTER=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_CPU=m +CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m +CONFIG_NETFILTER_XT_MATCH_DSCP=m +CONFIG_NETFILTER_XT_MATCH_ESP=m +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_IPCOMP=m +CONFIG_NETFILTER_XT_MATCH_IPRANGE=m +CONFIG_NETFILTER_XT_MATCH_IPVS=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_NFACCT=m +CONFIG_NETFILTER_XT_MATCH_OSF=m +CONFIG_NETFILTER_XT_MATCH_OWNER=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_RATEEST=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_RECENT=m +CONFIG_NETFILTER_XT_MATCH_SCTP=m +CONFIG_NETFILTER_XT_MATCH_SOCKET=m +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_TIME=m +CONFIG_NETFILTER_XT_MATCH_U32=m +CONFIG_IP_SET=m +CONFIG_IP_SET_BITMAP_IP=m +CONFIG_IP_SET_BITMAP_IPMAC=m +CONFIG_IP_SET_BITMAP_PORT=m +CONFIG_IP_SET_HASH_IP=m +CONFIG_IP_SET_HASH_IPMARK=m +CONFIG_IP_SET_HASH_IPPORT=m +CONFIG_IP_SET_HASH_IPPORTIP=m +CONFIG_IP_SET_HASH_IPPORTNET=m +CONFIG_IP_SET_HASH_IPMAC=m +CONFIG_IP_SET_HASH_MAC=m +CONFIG_IP_SET_HASH_NETPORTNET=m +CONFIG_IP_SET_HASH_NET=m +CONFIG_IP_SET_HASH_NETNET=m +CONFIG_IP_SET_HASH_NETPORT=m +CONFIG_IP_SET_HASH_NETIFACE=m +CONFIG_IP_SET_LIST_SET=m +CONFIG_IP_VS=m +CONFIG_IP_VS_IPV6=y +CONFIG_IP_VS_DEBUG=y +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_IP_VS_PROTO_ESP=y +CONFIG_IP_VS_PROTO_AH=y +CONFIG_IP_VS_PROTO_SCTP=y +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_WRR=m +CONFIG_IP_VS_LC=m +CONFIG_IP_VS_WLC=m +CONFIG_IP_VS_FO=m +CONFIG_IP_VS_OVF=m +CONFIG_IP_VS_LBLC=m +CONFIG_IP_VS_LBLCR=m +CONFIG_IP_VS_DH=m +CONFIG_IP_VS_SH=m +CONFIG_IP_VS_MH=m +CONFIG_IP_VS_SED=m +CONFIG_IP_VS_NQ=m +CONFIG_IP_VS_FTP=m +CONFIG_IP_VS_PE_SIP=m +CONFIG_NFT_DUP_IPV4=m +CONFIG_NFT_FIB_IPV4=m +CONFIG_NF_TABLES_ARP=y +CONFIG_NF_LOG_ARP=m +CONFIG_NF_LOG_IPV4=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_RPFILTER=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_SYNPROXY=m +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_ARP_MANGLE=m +CONFIG_NFT_DUP_IPV6=m +CONFIG_NFT_FIB_IPV6=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_RPFILTER=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_MATCH_SRH=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IP6_NF_TARGET_SYNPROXY=m +CONFIG_IP6_NF_RAW=m +CONFIG_IP6_NF_NAT=m +CONFIG_IP6_NF_TARGET_MASQUERADE=m +CONFIG_IP6_NF_TARGET_NPT=m +CONFIG_NF_TABLES_BRIDGE=m +CONFIG_NFT_BRIDGE_META=m +CONFIG_NFT_BRIDGE_REJECT=m +CONFIG_NF_CONNTRACK_BRIDGE=m +CONFIG_BRIDGE_NF_EBTABLES=m +CONFIG_BRIDGE_EBT_802_3=m +CONFIG_BRIDGE_EBT_AMONG=m +CONFIG_BRIDGE_EBT_ARP=m +CONFIG_BRIDGE_EBT_IP=m +CONFIG_BRIDGE_EBT_IP6=m +CONFIG_BRIDGE_EBT_LIMIT=m +CONFIG_BRIDGE_EBT_MARK=m +CONFIG_BRIDGE_EBT_PKTTYPE=m +CONFIG_BRIDGE_EBT_STP=m +CONFIG_BRIDGE_EBT_VLAN=m +CONFIG_BRIDGE_EBT_ARPREPLY=m +CONFIG_BRIDGE_EBT_DNAT=m +CONFIG_BRIDGE_EBT_MARK_T=m +CONFIG_BRIDGE_EBT_REDIRECT=m +CONFIG_BRIDGE_EBT_SNAT=m +CONFIG_BRIDGE_EBT_LOG=m +CONFIG_BRIDGE_EBT_NFLOG=m +CONFIG_RDS=m +CONFIG_RDS_TCP=m +CONFIG_L2TP=m +CONFIG_L2TP_V3=y +CONFIG_L2TP_IP=m +CONFIG_L2TP_ETH=m +CONFIG_BRIDGE=y +CONFIG_BRIDGE_VLAN_FILTERING=y +CONFIG_BRIDGE_MRP=y +CONFIG_NET_DSA=m +CONFIG_VLAN_8021Q=y +CONFIG_VLAN_8021Q_GVRP=y +CONFIG_VLAN_8021Q_MVRP=y +CONFIG_LLC2=y +CONFIG_6LOWPAN=m +CONFIG_IEEE802154=m +CONFIG_IEEE802154_6LOWPAN=m +CONFIG_MAC802154=m +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_MULTIQ=y +CONFIG_NET_SCH_CBS=y +CONFIG_NET_SCH_ETF=y +CONFIG_NET_SCH_TAPRIO=y +CONFIG_NET_SCH_MQPRIO=y +CONFIG_NET_SCH_INGRESS=y +CONFIG_NET_CLS_BASIC=y +CONFIG_NET_CLS_U32=y +CONFIG_NET_CLS_FLOWER=y +CONFIG_NET_CLS_ACT=y +CONFIG_NET_ACT_POLICE=y +CONFIG_NET_ACT_GACT=y +CONFIG_NET_ACT_MIRRED=y +CONFIG_NET_ACT_SKBEDIT=y +CONFIG_NET_ACT_GATE=y +CONFIG_BATMAN_ADV=m +CONFIG_OPENVSWITCH=m +CONFIG_VSOCKETS=y +CONFIG_VIRTIO_VSOCKETS=y +CONFIG_NETLINK_DIAG=m +CONFIG_HSR=m +CONFIG_QRTR_SMD=m +CONFIG_QRTR_TUN=m +CONFIG_CGROUP_NET_PRIO=y +CONFIG_BPF_STREAM_PARSER=y +CONFIG_NET_PKTGEN=m +CONFIG_CAN=m +CONFIG_CAN_J1939=m +CONFIG_CAN_ISOTP=m +CONFIG_BT=m +CONFIG_BT_RFCOMM=y +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=y +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_HIDP=y +CONFIG_BT_6LOWPAN=m +CONFIG_BT_LEDS=y +CONFIG_BT_MSFTEXT=y +CONFIG_BT_HCIBTUSB=m +CONFIG_BT_HCIBTUSB_MTK=y +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_ATH3K=y +CONFIG_BT_HCIUART_LL=y +CONFIG_BT_HCIUART_INTEL=y +CONFIG_BT_HCIUART_BCM=y +CONFIG_BT_HCIUART_RTL=y +CONFIG_BT_HCIUART_QCA=y +CONFIG_BT_HCIUART_AG6XX=y +CONFIG_BT_HCIUART_MRVL=y +CONFIG_BT_HCIUART_AML=y +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBPA10X=m +CONFIG_BT_HCIBFUSB=m +CONFIG_BT_HCIVHCI=m +CONFIG_BT_MRVL=m +CONFIG_BT_ATH3K=m +CONFIG_BT_MTKUART=m +CONFIG_BT_NXPUART=m +CONFIG_CFG80211=m +CONFIG_NL80211_TESTMODE=y +# CONFIG_CFG80211_DEFAULT_PS is not set +CONFIG_CFG80211_WEXT=y +CONFIG_MAC80211=m +CONFIG_MAC80211_MESH=y +CONFIG_RFKILL=m +CONFIG_NET_9P=y +CONFIG_NET_9P_VIRTIO=y +CONFIG_NFC=m +CONFIG_NFC_NCI=m +CONFIG_NFC_S3FWRN5_I2C=m +CONFIG_PCI=y +CONFIG_PCIEPORTBUS=y +CONFIG_PCI_IOV=y +CONFIG_PCI_PASID=y +CONFIG_HOTPLUG_PCI=y +CONFIG_HOTPLUG_PCI_ACPI=y +CONFIG_PCIE_ALTERA=y +CONFIG_PCIE_ALTERA_MSI=y +CONFIG_PCI_HOST_THUNDER_PEM=y +CONFIG_PCI_HOST_THUNDER_ECAM=y +CONFIG_PCI_HOST_GENERIC=y +CONFIG_PCI_XGENE=y +CONFIG_PCI_MESON=m +CONFIG_PCI_IMX6_HOST=y +CONFIG_PCI_IMX6_EP=y +CONFIG_PCI_HISI=y +CONFIG_PCIE_KIRIN=y +CONFIG_PCI_ENDPOINT=y +CONFIG_PCI_ENDPOINT_CONFIGFS=y +CONFIG_PCI_EPF_TEST=y +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_NXP_FSPI_BUS=y +CONFIG_VEXPRESS_CONFIG=y +CONFIG_ARM_SCMI_PROTOCOL=y +CONFIG_ARM_SCMI_POWER_CONTROL=y +CONFIG_ARM_SCPI_PROTOCOL=y +CONFIG_EFI_CAPSULE_LOADER=y +CONFIG_IMX_DSP=y +CONFIG_IMX_SCU=y +CONFIG_GNSS=m +CONFIG_GNSS_MTK_SERIAL=m +CONFIG_MTD=y +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_BLOCK=y +CONFIG_MTD_CFI=y +CONFIG_MTD_CFI_ADV_OPTIONS=y +CONFIG_MTD_CFI_INTELEXT=y +CONFIG_MTD_CFI_AMDSTD=y +CONFIG_MTD_CFI_STAA=y +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_OF=y +CONFIG_MTD_DATAFLASH=y +CONFIG_MTD_SST25L=y +CONFIG_MTD_RAW_NAND=y +CONFIG_MTD_NAND_DENALI_DT=y +CONFIG_MTD_NAND_GPMI_NAND=y +CONFIG_MTD_SPI_NAND=y +CONFIG_MTD_SPI_NOR=y +# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set +CONFIG_MTD_UBI=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_NBD=m +CONFIG_XEN_BLKDEV_BACKEND=m +CONFIG_VIRTIO_BLK=y +CONFIG_BLK_DEV_NVME=y +CONFIG_SRAM=y +CONFIG_PCI_ENDPOINT_TEST=y +CONFIG_EEPROM_AT24=m +CONFIG_EEPROM_AT25=m +CONFIG_UACCE=m +# CONFIG_SCSI_PROC_FS is not set +CONFIG_BLK_DEV_SD=y +CONFIG_SCSI_SAS_ATA=y +CONFIG_SCSI_HISI_SAS=y +CONFIG_SCSI_HISI_SAS_PCI=y +CONFIG_MEGARAID_SAS=y +CONFIG_SCSI_MPT3SAS=m +CONFIG_ATA=y +CONFIG_SATA_AHCI=y +CONFIG_SATA_AHCI_PLATFORM=y +CONFIG_AHCI_IMX=y +CONFIG_AHCI_CEVA=y +CONFIG_SATA_SIL24=y +CONFIG_PATA_OF_PLATFORM=y +CONFIG_MD=y +CONFIG_BLK_DEV_MD=m +CONFIG_BLK_DEV_DM=m +CONFIG_DM_CRYPT=m +CONFIG_DM_THIN_PROVISIONING=m +CONFIG_DM_MIRROR=m +CONFIG_DM_ZERO=m +CONFIG_NETDEVICES=y +CONFIG_BONDING=m +CONFIG_DUMMY=m +CONFIG_WIREGUARD=m +CONFIG_EQUALIZER=m +CONFIG_NET_TEAM=m +CONFIG_NET_TEAM_MODE_BROADCAST=m +CONFIG_NET_TEAM_MODE_ROUNDROBIN=m +CONFIG_NET_TEAM_MODE_RANDOM=m +CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=m +CONFIG_NET_TEAM_MODE_LOADBALANCE=m +CONFIG_MACVLAN=m +CONFIG_MACVTAP=m +CONFIG_IPVLAN=m +CONFIG_IPVTAP=m +CONFIG_VXLAN=m +CONFIG_GENEVE=m +CONFIG_BAREUDP=m +CONFIG_MACSEC=y +CONFIG_TUN=y +CONFIG_VETH=m +CONFIG_VIRTIO_NET=y +CONFIG_NLMON=m +CONFIG_NET_VRF=m +CONFIG_NET_DSA_MSCC_FELIX=m +CONFIG_NET_DSA_SJA1105=m +CONFIG_NET_DSA_SJA1105_PTP=y +CONFIG_NET_DSA_SJA1105_TAS=y +CONFIG_NET_DSA_SJA1105_VL=y +CONFIG_AMD_XGBE=y +CONFIG_ATL1C=m +CONFIG_BCMGENET=m +CONFIG_BNX2X=m +CONFIG_SYSTEMPORT=m +CONFIG_MACB=y +CONFIG_THUNDER_NIC_PF=y +CONFIG_FEC=y +CONFIG_FSL_ENETC=y +CONFIG_FSL_ENETC_VF=y +CONFIG_FSL_ENETC_QOS=y +CONFIG_NXP_NETC_BLK_CTRL=y +CONFIG_HIX5HD2_GMAC=y +CONFIG_HNS_DSAF=y +CONFIG_HNS_ENET=y +CONFIG_HNS3=y +CONFIG_HNS3_HCLGE=y +CONFIG_HNS3_ENET=y +CONFIG_E1000=y +CONFIG_E1000E=y +CONFIG_IGB=y +CONFIG_IGBVF=y +CONFIG_MVMDIO=y +CONFIG_SKY2=y +CONFIG_MLX4_EN=m +CONFIG_MLX5_CORE=m +CONFIG_MLX5_CORE_EN=y +CONFIG_MSCC_OCELOT_SWITCH=y +CONFIG_QCOM_EMAC=m +CONFIG_RMNET=m +CONFIG_SMC91X=y +CONFIG_SMSC911X=y +CONFIG_STMMAC_ETH=y +CONFIG_DWMAC_GENERIC=m +CONFIG_AQUANTIA_PHY=y +CONFIG_BROADCOM_PHY=m +CONFIG_BCM54140_PHY=m +CONFIG_MARVELL_PHY=m +CONFIG_MARVELL_10G_PHY=m +CONFIG_MAXLINEAR_GPHY=y +CONFIG_MICREL_PHY=y +CONFIG_MICROSEMI_PHY=y +CONFIG_MOTORCOMM_PHY=y +CONFIG_NXP_C45_TJA11XX_PHY=y +CONFIG_NXP_TJA11XX_PHY=y +CONFIG_AT803X_PHY=y +CONFIG_REALTEK_PHY=y +CONFIG_ROCKCHIP_PHY=y +CONFIG_DP83848_PHY=y +CONFIG_VITESSE_PHY=y +CONFIG_CAN_VCAN=m +CONFIG_CAN_VXCAN=m +CONFIG_CAN_FLEXCAN=m +CONFIG_CAN_SLCAN=m +CONFIG_CAN_8DEV_USB=m +CONFIG_CAN_EMS_USB=m +CONFIG_CAN_ESD_USB=m +CONFIG_CAN_GS_USB=m +CONFIG_CAN_KVASER_USB=m +CONFIG_CAN_MCBA_USB=m +CONFIG_CAN_PEAK_USB=m +CONFIG_CAN_UCAN=m +CONFIG_MDIO_BITBANG=y +CONFIG_MDIO_BUS_MUX_MULTIPLEXER=y +CONFIG_MDIO_BUS_MUX_MMIOREG=y +CONFIG_PPP=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_FILTER=y +CONFIG_PPP_MPPE=m +CONFIG_PPP_MULTILINK=y +CONFIG_PPPOE=m +CONFIG_PPPOL2TP=m +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m +CONFIG_USB_PEGASUS=m +CONFIG_USB_RTL8150=m +CONFIG_USB_RTL8152=y +CONFIG_USB_LAN78XX=m +CONFIG_USB_USBNET=y +CONFIG_USB_NET_AX8817X=m +CONFIG_USB_NET_AX88179_178A=m +CONFIG_USB_NET_CDCETHER=m +CONFIG_USB_NET_CDC_EEM=m +CONFIG_USB_NET_CDC_NCM=m +CONFIG_USB_NET_HUAWEI_CDC_NCM=m +CONFIG_USB_NET_CDC_MBIM=m +CONFIG_USB_NET_DM9601=m +CONFIG_USB_NET_SR9700=m +CONFIG_USB_NET_SR9800=m +CONFIG_USB_NET_SMSC75XX=m +CONFIG_USB_NET_SMSC95XX=m +CONFIG_USB_NET_GL620A=m +CONFIG_USB_NET_NET1080=m +CONFIG_USB_NET_PLUSB=m +CONFIG_USB_NET_MCS7830=m +CONFIG_USB_NET_RNDIS_HOST=m +CONFIG_USB_NET_CDC_SUBSET=m +CONFIG_USB_NET_ZAURUS=m +CONFIG_USB_NET_CX82310_ETH=m +CONFIG_USB_NET_KALMIA=m +CONFIG_USB_NET_QMI_WWAN=m +CONFIG_USB_NET_INT51X1=m +CONFIG_USB_IPHETH=m +CONFIG_USB_NET_CH9200=m +CONFIG_USB_NET_AQC111=m +CONFIG_ATH9K=m +CONFIG_ATH9K_HTC=m +CONFIG_CARL9170=m +CONFIG_AR5523=m +CONFIG_ATH10K=m +CONFIG_ATH10K_PCI=m +CONFIG_ATH10K_SDIO=m +CONFIG_ATH10K_USB=m +CONFIG_ATH11K=m +CONFIG_ATH11K_PCI=m +CONFIG_AT76C50X_USB=m +CONFIG_BRCMSMAC=m +CONFIG_BRCMFMAC=m +# CONFIG_BRCMFMAC_SDIO is not set +CONFIG_BRCMFMAC_USB=y +CONFIG_BRCMFMAC_PCIE=y +CONFIG_IPW2100=m +CONFIG_IPW2200=m +CONFIG_IWL4965=m +CONFIG_IWL3945=m +CONFIG_IWLWIFI=m +CONFIG_IWLDVM=m +CONFIG_IWLMVM=m +CONFIG_MWIFIEX=m +CONFIG_MWIFIEX_PCIE=m +CONFIG_MWIFIEX_USB=m +CONFIG_MWL8K=m +CONFIG_MT7601U=m +CONFIG_MT76x0U=m +CONFIG_MT76x0E=m +CONFIG_MT76x2E=m +CONFIG_MT76x2U=m +CONFIG_MT7603E=m +CONFIG_MT7615E=m +CONFIG_MT7663U=m +CONFIG_MT7915E=m +CONFIG_MT7921U=m +CONFIG_MT7925U=m +CONFIG_RT2X00=m +CONFIG_RT2800PCI=m +CONFIG_RT2500USB=m +CONFIG_RT73USB=m +CONFIG_RT2800USB=m +CONFIG_RT2800USB_RT3573=y +CONFIG_RT2800USB_RT53XX=y +CONFIG_RT2800USB_RT55XX=y +CONFIG_RT2800USB_UNKNOWN=y +CONFIG_RTL8187=m +CONFIG_RTL8192CE=m +CONFIG_RTL8192SE=m +CONFIG_RTL8192DE=m +CONFIG_RTL8723AE=m +CONFIG_RTL8723BE=m +CONFIG_RTL8188EE=m +CONFIG_RTL8192EE=m +CONFIG_RTL8821AE=m +CONFIG_RTL8192CU=m +CONFIG_RTL8XXXU=m +CONFIG_RTL8XXXU_UNTESTED=y +CONFIG_RTW88=m +CONFIG_RTW88_8822BE=m +CONFIG_RTW88_8822CE=m +CONFIG_RTW88_8723DE=m +CONFIG_RTW88_8821CE=m +CONFIG_RTW89=m +CONFIG_RSI_91X=m +# CONFIG_RSI_SDIO is not set +CONFIG_WL18XX=m +CONFIG_WLCORE_SDIO=m +CONFIG_ZD1211RW=m +CONFIG_QTNFMAC_PCIE=m +CONFIG_XEN_NETDEV_BACKEND=m +CONFIG_INPUT_MOUSEDEV=m +CONFIG_INPUT_EVDEV=y +CONFIG_KEYBOARD_ADC=m +CONFIG_KEYBOARD_GPIO=y +CONFIG_KEYBOARD_SNVS_PWRKEY=y +CONFIG_KEYBOARD_IMX_SC_KEY=y +CONFIG_KEYBOARD_CROS_EC=y +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_ATMEL_MXT=m +CONFIG_TOUCHSCREEN_EXC3000=y +CONFIG_TOUCHSCREEN_GOODIX=m +CONFIG_TOUCHSCREEN_ILITEK=y +CONFIG_TOUCHSCREEN_EDT_FT5X06=m +CONFIG_TOUCHSCREEN_USB_COMPOSITE=m +CONFIG_INPUT_MISC=y +CONFIG_INPUT_BBNSM_PWRKEY=y +CONFIG_INPUT_PWM_BEEPER=m +CONFIG_INPUT_PWM_VIBRA=m +# CONFIG_SERIO_SERPORT is not set +CONFIG_SERIO_AMBAKMI=y +CONFIG_LEGACY_PTY_COUNT=16 +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_8250_DW=y +CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_SERIAL_AMBA_PL011=y +CONFIG_SERIAL_AMBA_PL011_CONSOLE=y +CONFIG_SERIAL_IMX=y +CONFIG_SERIAL_IMX_CONSOLE=y +CONFIG_SERIAL_XILINX_PS_UART=y +CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y +CONFIG_SERIAL_FSL_LPUART=y +CONFIG_SERIAL_FSL_LPUART_CONSOLE=y +CONFIG_SERIAL_FSL_LINFLEXUART=y +CONFIG_SERIAL_FSL_LINFLEXUART_CONSOLE=y +CONFIG_RPMSG_TTY=m +CONFIG_SERIAL_DEV_BUS=y +CONFIG_VIRTIO_CONSOLE=y +CONFIG_IPMI_HANDLER=m +CONFIG_IPMI_DEVICE_INTERFACE=m +CONFIG_IPMI_SI=m +CONFIG_TCG_TPM=y +CONFIG_TCG_TIS_I2C_INFINEON=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_MUX_GPIO=y +CONFIG_I2C_MUX_PCA954x=y +CONFIG_I2C_GPIO=m +CONFIG_I2C_IMX=y +CONFIG_I2C_IMX_LPI2C=y +CONFIG_I2C_RK3X=y +CONFIG_I2C_CROS_EC_TUNNEL=y +CONFIG_I2C_SLAVE_EEPROM=y +CONFIG_I3C=y +CONFIG_SVC_I3C_MASTER=y +CONFIG_SPI=y +CONFIG_SPI_CADENCE_QUADSPI=y +CONFIG_SPI_DESIGNWARE=m +CONFIG_SPI_DW_DMA=y +CONFIG_SPI_DW_MMIO=m +CONFIG_SPI_FSL_LPSPI=y +CONFIG_SPI_FSL_QUADSPI=y +CONFIG_SPI_NXP_FLEXSPI=y +CONFIG_SPI_IMX=y +CONFIG_SPI_PL022=y +CONFIG_SPI_MUX=y +CONFIG_SPI_SPIDEV=y +CONFIG_SPI_SLAVE=y +CONFIG_SPI_SLAVE_TIME=y +CONFIG_SPI_SLAVE_SYSTEM_CONTROL=y +CONFIG_SPMI=y +CONFIG_PPS_CLIENT_GPIO=y +CONFIG_PINCTRL=y +CONFIG_PINCTRL_MAX77620=y +CONFIG_PINCTRL_SCMI=y +CONFIG_PINCTRL_SINGLE=y +CONFIG_PINCTRL_IMX_SCMI=y +CONFIG_PINCTRL_TS9390=y +CONFIG_PINCTRL_TS9370=y +CONFIG_GPIO_DWAPB=y +CONFIG_GPIO_MB86S7X=y +CONFIG_GPIO_MXC=y +CONFIG_GPIO_PL061=y +CONFIG_GPIO_VF610=y +CONFIG_GPIO_WCD934X=m +CONFIG_GPIO_XGENE=y +CONFIG_GPIO_MAX732X=y +CONFIG_GPIO_PCA953X=y +CONFIG_GPIO_PCA953X_IRQ=y +CONFIG_GPIO_PCA9570=y +CONFIG_GPIO_PCF857X=y +CONFIG_GPIO_TS9370=y +CONFIG_GPIO_ADP5585=y +CONFIG_GPIO_BD9571MWV=m +CONFIG_GPIO_MAX77620=y +CONFIG_POWER_RESET_TS_WIZARD=y +CONFIG_POWER_RESET_XGENE=y +CONFIG_POWER_RESET_SYSCON=y +CONFIG_SYSCON_REBOOT_MODE=y +CONFIG_BATTERY_SBS=m +CONFIG_BATTERY_BQ27XXX=y +CONFIG_BATTERY_MAX17042=m +CONFIG_CHARGER_BQ25890=m +CONFIG_CHARGER_BQ25980=m +CONFIG_SENSORS_ARM_SCMI=y +CONFIG_SENSORS_ARM_SCPI=y +CONFIG_SENSORS_LM90=m +CONFIG_SENSORS_PWM_FAN=m +CONFIG_SENSORS_EMC2305=m +CONFIG_SENSORS_INA2XX=m +CONFIG_SENSORS_INA3221=m +CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y +CONFIG_CPU_THERMAL=y +CONFIG_THERMAL_EMULATION=y +CONFIG_IMX_SC_THERMAL=y +CONFIG_IMX8MM_THERMAL=y +CONFIG_QORIQ_THERMAL=y +CONFIG_WATCHDOG=y +CONFIG_ARM_SP805_WATCHDOG=y +CONFIG_ARM_SBSA_WATCHDOG=y +CONFIG_DW_WATCHDOG=y +CONFIG_IMX2_WDT=y +CONFIG_IMX_SC_WDT=y +CONFIG_IMX7ULP_WDT=y +CONFIG_ARM_SMC_WATCHDOG=y +CONFIG_XEN_WDT=y +CONFIG_MFD_ADP5585=y +CONFIG_MFD_BD9571MWV=y +CONFIG_MFD_AXP20X_I2C=y +CONFIG_MFD_HI6421_PMIC=y +CONFIG_MFD_MAX77620=y +CONFIG_MFD_MT6397=y +CONFIG_MFD_TS_WIZARD=y +CONFIG_MFD_ROHM_BD718XX=y +CONFIG_MFD_WCD934X=m +CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_AXP20X=y +CONFIG_REGULATOR_BD718XX=y +CONFIG_REGULATOR_BD9571MWV=y +CONFIG_REGULATOR_FAN53555=y +CONFIG_REGULATOR_GPIO=y +CONFIG_REGULATOR_HI6421V530=y +CONFIG_REGULATOR_MAX77620=y +CONFIG_REGULATOR_MAX8973=y +CONFIG_REGULATOR_MP8859=y +CONFIG_REGULATOR_MT6358=y +CONFIG_REGULATOR_MT6397=y +CONFIG_REGULATOR_PCA9450=y +CONFIG_REGULATOR_PF9453=y +CONFIG_REGULATOR_PF0900=y +CONFIG_REGULATOR_PF8X00=y +CONFIG_REGULATOR_PFUZE100=y +CONFIG_REGULATOR_PWM=y +CONFIG_REGULATOR_QCOM_SPMI=y +CONFIG_REGULATOR_TPS65132=m +CONFIG_REGULATOR_VCTRL=m +CONFIG_RC_CORE=m +CONFIG_RC_DECODERS=y +CONFIG_IR_IMON_DECODER=m +CONFIG_IR_JVC_DECODER=m +CONFIG_IR_MCE_KBD_DECODER=m +CONFIG_IR_NEC_DECODER=m +CONFIG_IR_RC5_DECODER=m +CONFIG_IR_RC6_DECODER=m +CONFIG_IR_RCMM_DECODER=m +CONFIG_IR_SANYO_DECODER=m +CONFIG_IR_SHARP_DECODER=m +CONFIG_IR_SONY_DECODER=m +CONFIG_IR_XMP_DECODER=m +CONFIG_RC_DEVICES=y +CONFIG_IR_GPIO_CIR=m +CONFIG_MEDIA_SUPPORT=y +CONFIG_MEDIA_CAMERA_SUPPORT=y +CONFIG_MEDIA_ANALOG_TV_SUPPORT=y +CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y +CONFIG_MEDIA_SDR_SUPPORT=y +CONFIG_MEDIA_PLATFORM_SUPPORT=y +# CONFIG_DVB_NET is not set +CONFIG_MEDIA_USB_SUPPORT=y +CONFIG_USB_VIDEO_CLASS=m +CONFIG_V4L_PLATFORM_DRIVERS=y +CONFIG_SDR_PLATFORM_DRIVERS=y +CONFIG_V4L_MEM2MEM_DRIVERS=y +CONFIG_VIDEO_AMPHION_VPU=y +CONFIG_VIDEO_IMX7_CSI=m +CONFIG_VIDEO_IMX8MQ_MIPI_CSI2=m +CONFIG_VIDEO_IMX_MIPI_CSIS=m +CONFIG_VIDEO_IMX8_ISI=y +CONFIG_VIDEO_IMX8_ISI_M2M=y +CONFIG_VIDEO_IMX8_JPEG=m +CONFIG_VIDEO_HANTRO=m +CONFIG_VIDEO_IMX219=m +CONFIG_VIDEO_OV5640=y +CONFIG_VIDEO_OV5645=m +CONFIG_VIDEO_RDACM20=y +CONFIG_VIDEO_DS90UB953=m +CONFIG_VIDEO_DS90UB960=m +CONFIG_DRM=y +CONFIG_DRM_MALI_DISPLAY=m +CONFIG_DRM_VIRTIO_GPU=y +CONFIG_DRM_PANEL_BOE_TV101WUM_NL6=m +CONFIG_DRM_PANEL_LVDS=y +CONFIG_DRM_PANEL_MANTIX_MLAF057WE51=m +CONFIG_DRM_PANEL_RAYDIUM_RM67191=y +CONFIG_DRM_PANEL_RAYDIUM_RM68200=y +CONFIG_DRM_PANEL_SEIKO_43WVF1G=y +CONFIG_DRM_PANEL_SITRONIX_ST7703=m +CONFIG_DRM_PANEL_SIMPLE=y +CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA=m +CONFIG_DRM_DISPLAY_CONNECTOR=y +CONFIG_DRM_FSL_LDB=y +CONFIG_DRM_I2C_NXP_TDA998X=m +CONFIG_DRM_ITE_IT6263=y +CONFIG_DRM_LONTIUM_LT8912B=m +CONFIG_DRM_LONTIUM_LT9611=m +CONFIG_DRM_LONTIUM_LT9611UXC=y +CONFIG_DRM_NWL_MIPI_DSI=y +CONFIG_DRM_PARADE_PS8640=m +CONFIG_DRM_SII902X=m +CONFIG_DRM_SIMPLE_BRIDGE=m +CONFIG_DRM_THINE_THC63LVD1024=m +CONFIG_DRM_TOSHIBA_TC358767=y +CONFIG_DRM_TI_SN65DSI83=y +CONFIG_DRM_TI_SN65DSI86=m +CONFIG_DRM_WAVESHARE_BRIDGE=y +CONFIG_DRM_I2C_ADV7511=y +CONFIG_DRM_I2C_ADV7511_AUDIO=y +CONFIG_DRM_IMX8QM_LDB=y +CONFIG_DRM_IMX8QXP_LDB=y +CONFIG_DRM_IMX_DCSS=y +CONFIG_DRM_ETNAVIV=m +CONFIG_DRM_HISI_HIBMC=m +CONFIG_DRM_HISI_KIRIN=m +CONFIG_DRM_MXSFB=y +CONFIG_DRM_PL111=m +CONFIG_DRM_XEN_FRONTEND=y +CONFIG_DRM_LIMA=m +CONFIG_DRM_PANFROST=m +CONFIG_FB=y +CONFIG_FB_EFI=y +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_PWM=y +CONFIG_BACKLIGHT_LP855X=m +CONFIG_BACKLIGHT_GPIO=y +CONFIG_BACKLIGHT_LED=y +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +CONFIG_SOUND=y +CONFIG_SND=y +CONFIG_SND_HRTIMER=m +CONFIG_SND_ALOOP=m +CONFIG_SND_USB_AUDIO=m +CONFIG_SND_SOC=y +CONFIG_SND_SOC_FSL_ASRC=m +CONFIG_SND_SOC_FSL_MQS=m +CONFIG_SND_SOC_FSL_MICFIL=m +CONFIG_SND_SOC_FSL_EASRC=m +CONFIG_SND_SOC_FSL_XCVR=m +CONFIG_SND_SOC_FSL_RPMSG=m +CONFIG_SND_IMX_SOC=m +CONFIG_SND_SOC_IMX_SGTL5000=m +CONFIG_SND_SOC_FSL_ASOC_CARD=m +CONFIG_SND_SOC_IMX_AUDMIX=m +CONFIG_SND_SOC_IMX_HDMI=m +CONFIG_SND_SOC_IMX_CARD=m +CONFIG_SND_SOC_SOF_TOPLEVEL=y +CONFIG_SND_SOC_SOF_OF=m +CONFIG_SND_SOC_SOF_IMX_TOPLEVEL=y +CONFIG_SND_SOC_SOF_IMX8=m +CONFIG_SND_SOC_AK4613=m +CONFIG_SND_SOC_BT_SCO=y +CONFIG_SND_SOC_CROS_EC_CODEC=m +CONFIG_SND_SOC_CS42XX8_I2C=y +CONFIG_SND_SOC_DMIC=m +CONFIG_SND_SOC_ES7134=m +CONFIG_SND_SOC_ES7241=m +CONFIG_SND_SOC_GTM601=m +CONFIG_SND_SOC_MAX98357A=m +CONFIG_SND_SOC_MAX98927=m +CONFIG_SND_SOC_MSM8916_WCD_ANALOG=m +CONFIG_SND_SOC_MSM8916_WCD_DIGITAL=m +CONFIG_SND_SOC_PCM3168A_I2C=m +CONFIG_SND_SOC_RT5659=m +CONFIG_SND_SOC_SIMPLE_AMPLIFIER=m +CONFIG_SND_SOC_SIMPLE_MUX=m +CONFIG_SND_SOC_SPDIF=m +CONFIG_SND_SOC_TAC5X1X_I2C=y +CONFIG_SND_SOC_TAS571X=m +CONFIG_SND_SOC_WCD934X=m +CONFIG_SND_SOC_WM8524=y +CONFIG_SND_SOC_WM8904=m +CONFIG_SND_SOC_WM8960=m +CONFIG_SND_SOC_WM8962=m +CONFIG_SND_SOC_WSA881X=m +CONFIG_SND_SOC_LPASS_WSA_MACRO=m +CONFIG_SND_SOC_LPASS_VA_MACRO=m +CONFIG_SND_SIMPLE_CARD=y +CONFIG_SND_AUDIO_GRAPH_CARD=y +CONFIG_SND_AUDIO_GRAPH_CARD2=m +CONFIG_SND_VIRTIO=y +CONFIG_HID_MULTITOUCH=m +CONFIG_I2C_HID_ACPI=m +CONFIG_I2C_HID_OF=m +CONFIG_USB_CONN_GPIO=y +CONFIG_USB=y +CONFIG_USB_OTG=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_PCI_RENESAS=m +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_HCD_PLATFORM=y +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_OHCI_HCD_PLATFORM=y +CONFIG_USB_HCD_TEST_MODE=y +CONFIG_USB_XEN_HCD=y +CONFIG_USB_ACM=m +CONFIG_USB_STORAGE=y +CONFIG_USB_UAS=y +CONFIG_USB_CDNS_SUPPORT=y +CONFIG_USB_CDNS3=y +CONFIG_USB_CDNS3_GADGET=y +CONFIG_USB_CDNS3_HOST=y +CONFIG_USB_MUSB_HDRC=y +CONFIG_USB_DWC3=y +CONFIG_USB_DWC2=y +CONFIG_USB_CHIPIDEA=y +CONFIG_USB_CHIPIDEA_UDC=y +CONFIG_USB_CHIPIDEA_HOST=y +CONFIG_USB_ISP1760=y +CONFIG_USB_SERIAL=y +CONFIG_USB_SERIAL_CONSOLE=y +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_SIMPLE=y +CONFIG_USB_SERIAL_AIRCABLE=m +CONFIG_USB_SERIAL_ARK3116=m +CONFIG_USB_SERIAL_BELKIN=m +CONFIG_USB_SERIAL_CH341=m +CONFIG_USB_SERIAL_WHITEHEAT=m +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +CONFIG_USB_SERIAL_CP210X=m +CONFIG_USB_SERIAL_CYPRESS_M8=m +CONFIG_USB_SERIAL_EMPEG=m +CONFIG_USB_SERIAL_FTDI_SIO=y +CONFIG_USB_SERIAL_VISOR=m +CONFIG_USB_SERIAL_IPAQ=m +CONFIG_USB_SERIAL_IR=m +CONFIG_USB_SERIAL_EDGEPORT=m +CONFIG_USB_SERIAL_EDGEPORT_TI=m +CONFIG_USB_SERIAL_F81232=m +CONFIG_USB_SERIAL_F8153X=m +CONFIG_USB_SERIAL_GARMIN=m +CONFIG_USB_SERIAL_IPW=m +CONFIG_USB_SERIAL_IUU=m +CONFIG_USB_SERIAL_KEYSPAN_PDA=m +CONFIG_USB_SERIAL_KEYSPAN=m +CONFIG_USB_SERIAL_KLSI=m +CONFIG_USB_SERIAL_KOBIL_SCT=m +CONFIG_USB_SERIAL_MCT_U232=m +CONFIG_USB_SERIAL_METRO=m +CONFIG_USB_SERIAL_MOS7720=m +CONFIG_USB_SERIAL_MOS7840=m +CONFIG_USB_SERIAL_MXUPORT=m +CONFIG_USB_SERIAL_NAVMAN=m +CONFIG_USB_SERIAL_PL2303=m +CONFIG_USB_SERIAL_OTI6858=m +CONFIG_USB_SERIAL_QCAUX=m +CONFIG_USB_SERIAL_QUALCOMM=m +CONFIG_USB_SERIAL_SPCP8X5=m +CONFIG_USB_SERIAL_SAFE=m +CONFIG_USB_SERIAL_SIERRAWIRELESS=m +CONFIG_USB_SERIAL_SYMBOL=m +CONFIG_USB_SERIAL_TI=m +CONFIG_USB_SERIAL_CYBERJACK=m +CONFIG_USB_SERIAL_OPTION=m +CONFIG_USB_SERIAL_OMNINET=m +CONFIG_USB_SERIAL_OPTICON=m +CONFIG_USB_SERIAL_XSENS_MT=m +CONFIG_USB_SERIAL_WISHBONE=m +CONFIG_USB_SERIAL_SSU100=m +CONFIG_USB_SERIAL_QT2=m +CONFIG_USB_SERIAL_UPD78F0730=m +CONFIG_USB_SERIAL_XR=m +CONFIG_USB_TEST=m +CONFIG_USB_EHSET_TEST_FIXTURE=y +CONFIG_USB_HSIC_USB3503=y +CONFIG_USB_ONBOARD_DEV=y +CONFIG_NOP_USB_XCEIV=y +CONFIG_USB_MXS_PHY=y +CONFIG_USB_ULPI=y +CONFIG_USB_GADGET=y +CONFIG_USB_SNP_UDC_PLAT=y +CONFIG_USB_BDC_UDC=y +CONFIG_USB_CONFIGFS=y +CONFIG_USB_CONFIGFS_SERIAL=y +CONFIG_USB_CONFIGFS_ACM=y +CONFIG_USB_CONFIGFS_OBEX=y +CONFIG_USB_CONFIGFS_NCM=y +CONFIG_USB_CONFIGFS_ECM=y +CONFIG_USB_CONFIGFS_ECM_SUBSET=y +CONFIG_USB_CONFIGFS_RNDIS=y +CONFIG_USB_CONFIGFS_EEM=y +CONFIG_USB_CONFIGFS_MASS_STORAGE=y +CONFIG_USB_CONFIGFS_F_LB_SS=y +CONFIG_USB_CONFIGFS_F_FS=y +CONFIG_USB_CONFIGFS_F_UAC1=y +CONFIG_USB_CONFIGFS_F_UAC1_LEGACY=y +CONFIG_USB_CONFIGFS_F_UAC2=y +CONFIG_USB_CONFIGFS_F_MIDI=y +CONFIG_USB_CONFIGFS_F_HID=y +CONFIG_USB_CONFIGFS_F_UVC=y +CONFIG_USB_ZERO=m +CONFIG_USB_AUDIO=m +CONFIG_USB_ETH=m +CONFIG_USB_G_NCM=m +CONFIG_USB_GADGETFS=m +CONFIG_USB_FUNCTIONFS=m +CONFIG_USB_MASS_STORAGE=m +CONFIG_USB_G_SERIAL=m +CONFIG_TYPEC=y +CONFIG_TYPEC_TCPM=y +CONFIG_TYPEC_TCPCI=y +CONFIG_TYPEC_FUSB302=m +CONFIG_TYPEC_TPS6598X=m +CONFIG_TYPEC_HD3SS3220=m +CONFIG_MMC=y +CONFIG_MMC_BLOCK_MINORS=32 +CONFIG_MMC_ARMMMCI=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_ACPI=y +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MMC_SDHCI_OF_ARASAN=y +CONFIG_MMC_SDHCI_OF_ESDHC=y +CONFIG_MMC_SDHCI_CADENCE=y +CONFIG_MMC_SDHCI_ESDHC_IMX=y +CONFIG_MMC_SDHCI_F_SDH30=y +CONFIG_MMC_SPI=y +CONFIG_MMC_DW=y +CONFIG_MMC_DW_EXYNOS=y +CONFIG_MMC_DW_HI3798CV200=y +CONFIG_MMC_DW_K3=y +CONFIG_MMC_MTK=y +CONFIG_MMC_SDHCI_XENON=y +CONFIG_SCSI_UFSHCD=y +CONFIG_SCSI_UFSHCD_PLATFORM=y +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_CLASS_MULTICOLOR=m +CONFIG_LEDS_LM3692X=m +CONFIG_LEDS_PCA9532=m +CONFIG_LEDS_GPIO=y +CONFIG_LEDS_PCA963X=y +CONFIG_LEDS_PCA995X=m +CONFIG_LEDS_PWM=y +CONFIG_LEDS_SYSCON=y +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEDS_TRIGGER_ONESHOT=m +CONFIG_LEDS_TRIGGER_DISK=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_LEDS_TRIGGER_CPU=y +CONFIG_LEDS_TRIGGER_ACTIVITY=m +CONFIG_LEDS_TRIGGER_DEFAULT_ON=y +CONFIG_LEDS_TRIGGER_TRANSIENT=m +CONFIG_LEDS_TRIGGER_PANIC=y +CONFIG_LEDS_TRIGGER_NETDEV=m +CONFIG_LEDS_TRIGGER_PATTERN=m +CONFIG_EDAC=y +CONFIG_EDAC_GHES=y +CONFIG_EDAC_SYNOPSYS=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_DS1307=m +CONFIG_RTC_DRV_HYM8563=m +CONFIG_RTC_DRV_MAX77686=y +CONFIG_RTC_DRV_PCF85363=m +CONFIG_RTC_DRV_M41T80=m +CONFIG_RTC_DRV_TSWIZARD=y +CONFIG_RTC_DRV_RX8581=m +CONFIG_RTC_DRV_RV3028=m +CONFIG_RTC_DRV_RV8803=m +CONFIG_RTC_DRV_DS3232=y +CONFIG_RTC_DRV_PCF2127=m +CONFIG_RTC_DRV_EFI=y +CONFIG_RTC_DRV_CROS_EC=y +CONFIG_RTC_DRV_PL031=y +CONFIG_RTC_DRV_SNVS=y +CONFIG_RTC_DRV_BBNSM=y +CONFIG_RTC_DRV_IMX_SC=y +CONFIG_DMADEVICES=y +CONFIG_BCM_SBA_RAID=m +CONFIG_FSL_EDMA=y +CONFIG_FSL_QDMA=m +CONFIG_IMX_SDMA=y +CONFIG_MV_XOR_V2=y +CONFIG_MXS_DMA=y +CONFIG_PL330_DMA=y +CONFIG_QCOM_HIDMA_MGMT=y +CONFIG_QCOM_HIDMA=y +CONFIG_DW_EDMA=y +CONFIG_DW_EDMA_PCIE=y +CONFIG_DMATEST=y +CONFIG_UDMABUF=y +CONFIG_DMABUF_HEAPS=y +CONFIG_DMABUF_HEAPS_SYSTEM=y +CONFIG_DMABUF_HEAPS_CMA=y +CONFIG_VFIO=y +CONFIG_VFIO_PCI=y +CONFIG_VIRTIO_PCI=y +CONFIG_VIRTIO_BALLOON=y +CONFIG_VIRTIO_INPUT=y +CONFIG_VIRTIO_MMIO=y +CONFIG_VHOST_NET=m +CONFIG_VHOST_VSOCK=y +CONFIG_XEN_GNTDEV=y +CONFIG_XEN_GNTDEV_DMABUF=y +CONFIG_XEN_GRANT_DEV_ALLOC=y +CONFIG_XEN_GRANT_DMA_ALLOC=y +CONFIG_XEN_PCIDEV_STUB=y +CONFIG_XEN_VIRTIO=y +CONFIG_XEN_VIRTIO_FORCE_GRANT=y +CONFIG_STAGING=y +CONFIG_STAGING_MEDIA=y +CONFIG_CHROME_PLATFORMS=y +CONFIG_CROS_EC=y +CONFIG_CROS_EC_I2C=y +CONFIG_CROS_EC_SPI=y +CONFIG_CROS_EC_CHARDEV=m +CONFIG_CLK_VEXPRESS_OSC=y +CONFIG_COMMON_CLK_SCMI=y +CONFIG_COMMON_CLK_SCPI=y +CONFIG_COMMON_CLK_CS2000_CP=y +CONFIG_COMMON_CLK_XGENE=y +CONFIG_COMMON_CLK_PWM=y +CONFIG_COMMON_CLK_VC5=y +CONFIG_CLK_IMX8MM=y +CONFIG_CLK_IMX8MN=y +CONFIG_CLK_IMX8MP=y +CONFIG_CLK_IMX8MQ=y +CONFIG_CLK_IMX8QXP=y +CONFIG_CLK_IMX8ULP=y +CONFIG_CLK_IMX93=y +CONFIG_CLK_IMX95_BLK_CTL=y +CONFIG_HWSPINLOCK=y +CONFIG_ARM_MHU=y +CONFIG_IMX_MBOX=y +CONFIG_PLATFORM_MHU=y +CONFIG_IOMMU_IO_PGTABLE_ARMV7S=y +CONFIG_ARM_SMMU=y +CONFIG_ARM_SMMU_V3=y +CONFIG_REMOTEPROC=y +CONFIG_IMX_REMOTEPROC=y +CONFIG_IMX_DSP_REMOTEPROC=m +CONFIG_RPMSG_CHAR=m +CONFIG_RPMSG_CTRL=m +CONFIG_RPMSG_QCOM_GLINK_RPM=y +CONFIG_SOUNDWIRE=m +CONFIG_SOUNDWIRE_QCOM=m +CONFIG_FSL_RCPM=y +CONFIG_SOC_TI=y +CONFIG_IMX_SCU_PD=y +CONFIG_DEVFREQ_GOV_PERFORMANCE=y +CONFIG_DEVFREQ_GOV_POWERSAVE=y +CONFIG_DEVFREQ_GOV_USERSPACE=y +CONFIG_DEVFREQ_GOV_PASSIVE=y +CONFIG_EXTCON_PTN5150=m +CONFIG_EXTCON_USB_GPIO=y +CONFIG_EXTCON_USBC_CROS_EC=y +CONFIG_IIO=y +CONFIG_FXLS8962AF_I2C=m +CONFIG_IIO_ST_ACCEL_3AXIS=m +CONFIG_IMX8QXP_ADC=y +CONFIG_IMX93_ADC=y +CONFIG_MAX9611=m +CONFIG_QCOM_SPMI_VADC=m +CONFIG_QCOM_SPMI_ADC5=m +CONFIG_TI_ADC128S052=y +CONFIG_TS_WIZARD_ADC=y +CONFIG_IIO_RESCALE=m +CONFIG_IIO_CROS_EC_SENSORS_CORE=m +CONFIG_IIO_CROS_EC_SENSORS=m +CONFIG_FXAS21002C=y +CONFIG_IIO_ST_GYRO_3AXIS=m +CONFIG_FXOS8700_I2C=y +CONFIG_INV_MPU6050_I2C=m +CONFIG_IIO_ST_LSM6DSX=y +CONFIG_IIO_CROS_EC_LIGHT_PROX=m +CONFIG_SENSORS_ISL29018=y +CONFIG_VCNL4000=m +CONFIG_VCNL4035=m +CONFIG_IIO_ST_MAGN_3AXIS=m +CONFIG_IIO_MUX=y +CONFIG_IIO_CROS_EC_BARO=m +CONFIG_MPL3115=y +CONFIG_MS5611=m +CONFIG_MS5611_I2C=m +CONFIG_TS_WIZARD_TEMP=y +CONFIG_PWM=y +CONFIG_PWM_ADP5585=y +CONFIG_PWM_CROS_EC=m +CONFIG_PWM_FSL_FTM=m +CONFIG_PWM_IMX27=y +CONFIG_PWM_IMX_TPM=y +CONFIG_PWM_TS=y +CONFIG_TS9370_IRQ=y +CONFIG_WIZARD_IRQ=y +CONFIG_RESET_IMX7=y +CONFIG_PHY_CADENCE_SALVO=y +CONFIG_PHY_MIXEL_MIPI_DPHY=y +CONFIG_PHY_FSL_IMX8M_PCIE=y +CONFIG_PHY_FSL_IMX8QM_HSIO=y +CONFIG_PHY_FSL_SAMSUNG_HDMI_PHY=y +CONFIG_PHY_QCOM_USB_HS=y +CONFIG_PHY_SAMSUNG_USB2=y +CONFIG_ARM_CCI_PMU=m +CONFIG_ARM_CCN=m +CONFIG_ARM_CMN=m +CONFIG_ARM_SMMU_V3_PMU=m +CONFIG_ARM_DSU_PMU=m +CONFIG_FSL_IMX8_DDR_PMU=y +CONFIG_FSL_IMX9_DDR_PMU=y +CONFIG_ARM_SPE_PMU=m +CONFIG_ARM_DMC620_PMU=m +CONFIG_HISI_PMU=y +CONFIG_NVMEM_IMX_OCOTP=y +CONFIG_NVMEM_IMX_OCOTP_SCU=y +CONFIG_NVMEM_RMEM=m +CONFIG_FPGA=y +CONFIG_FPGA_BRIDGE=m +CONFIG_ALTERA_FREEZE_BRIDGE=m +CONFIG_FPGA_REGION=m +CONFIG_OF_FPGA_REGION=m +CONFIG_TEE=y +CONFIG_OPTEE=y +CONFIG_MUX_GPIO=y +CONFIG_MUX_MMIO=y +CONFIG_EXT2_FS=y +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y +CONFIG_BTRFS_FS=m +CONFIG_BTRFS_FS_POSIX_ACL=y +CONFIG_F2FS_FS=m +CONFIG_F2FS_FS_SECURITY=y +CONFIG_FANOTIFY=y +CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y +CONFIG_QUOTA=y +CONFIG_AUTOFS_FS=y +CONFIG_FUSE_FS=m +CONFIG_CUSE=m +CONFIG_OVERLAY_FS=m +CONFIG_VFAT_FS=y +CONFIG_EXFAT_FS=m +CONFIG_NTFS3_FS=m +CONFIG_NTFS3_LZX_XPRESS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_HUGETLBFS=y +CONFIG_EFIVAR_FS=y +CONFIG_JFFS2_FS=y +CONFIG_UBIFS_FS=y +CONFIG_SQUASHFS=y +CONFIG_SQUASHFS_XZ=y +CONFIG_NFS_FS=y +CONFIG_NFS_V4=y +CONFIG_ROOT_NFS=y +CONFIG_NFSD=y +CONFIG_CIFS=m +CONFIG_9P_FS=y +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_ISO8859_1=y +CONFIG_TRUSTED_KEYS=m +# CONFIG_TRUSTED_KEYS_TPM is not set +# CONFIG_TRUSTED_KEYS_TEE is not set +CONFIG_SECURITY=y +CONFIG_CRYPTO_USER=y +CONFIG_CRYPTO_ECDH=y +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_ARIA=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_CAMELLIA=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_DES=m +CONFIG_CRYPTO_FCRYPT=m +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_SEED=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_CTS=m +CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_CHACHA20POLY1305=m +CONFIG_CRYPTO_CCM=y +CONFIG_CRYPTO_ECHAINIV=y +CONFIG_CRYPTO_CMAC=y +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MICHAEL_MIC=y +CONFIG_CRYPTO_RMD160=m +CONFIG_CRYPTO_SHA256=y +CONFIG_CRYPTO_STREEBOG=m +CONFIG_CRYPTO_WP512=m +CONFIG_CRYPTO_XCBC=m +CONFIG_CRYPTO_ANSI_CPRNG=y +CONFIG_CRYPTO_USER_API_HASH=m +CONFIG_CRYPTO_USER_API_SKCIPHER=m +CONFIG_CRYPTO_USER_API_RNG=m +CONFIG_CRYPTO_USER_API_AEAD=m +CONFIG_CRYPTO_GHASH_ARM64_CE=y +CONFIG_CRYPTO_SHA3_ARM64=m +CONFIG_CRYPTO_SM3_ARM64_CE=m +CONFIG_CRYPTO_POLYVAL_ARM64_CE=m +CONFIG_CRYPTO_AES_ARM64_BS=m +CONFIG_CRYPTO_AES_ARM64_CE_CCM=y +CONFIG_CRYPTO_DEV_FSL_CAAM=m +CONFIG_CRYPTO_DEV_CCREE=m +CONFIG_CRYPTO_DEV_HISI_SEC2=m +CONFIG_CRYPTO_DEV_HISI_ZIP=m +CONFIG_CRYPTO_DEV_HISI_HPRE=m +CONFIG_CRYPTO_DEV_HISI_TRNG=m +CONFIG_CRYPTO_DEV_AMLOGIC_GXL=m +CONFIG_INDIRECT_PIO=y +CONFIG_SWIOTLB_DYNAMIC=y +CONFIG_CMA_SIZE_MBYTES=32 +CONFIG_PRINTK_TIME=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_FS=y +CONFIG_SAMPLES=y +CONFIG_SAMPLE_RPMSG_CLIENT=m +CONFIG_CORESIGHT=y +CONFIG_CORESIGHT_LINK_AND_SINK_TMC=y +CONFIG_CORESIGHT_CATU=m +CONFIG_CORESIGHT_SINK_TPIU=m +CONFIG_CORESIGHT_SINK_ETBV10=m +CONFIG_CORESIGHT_SOURCE_ETM4X=y +CONFIG_CORESIGHT_STM=m +CONFIG_CORESIGHT_CTI=m +# CONFIG_RUNTIME_TESTING_MENU is not set diff --git a/arch/arm64/configs/tsimx93_minimal_defconfig b/arch/arm64/configs/tsimx93_minimal_defconfig new file mode 100644 index 000000000000..bca97bde9155 --- /dev/null +++ b/arch/arm64/configs/tsimx93_minimal_defconfig @@ -0,0 +1,1014 @@ +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y +CONFIG_AUDIT=y +CONFIG_NO_HZ_IDLE=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_BPF_SYSCALL=y +CONFIG_BPF_JIT=y +CONFIG_PREEMPT=y +CONFIG_IRQ_TIME_ACCOUNTING=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_TASKSTATS=y +CONFIG_TASK_XACCT=y +CONFIG_TASK_IO_ACCOUNTING=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_NUMA_BALANCING=y +CONFIG_MEMCG=y +CONFIG_BLK_CGROUP=y +CONFIG_CGROUP_PIDS=y +CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_HUGETLB=y +CONFIG_CPUSETS=y +CONFIG_CGROUP_DEVICE=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_CGROUP_PERF=y +CONFIG_CGROUP_BPF=y +CONFIG_USER_NS=y +CONFIG_SCHED_AUTOGROUP=y +CONFIG_RELAY=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_PROFILING=y +CONFIG_KEXEC=y +CONFIG_KEXEC_FILE=y +CONFIG_ARCH_NXP=y +CONFIG_ARCH_MXC=y +CONFIG_ARM64_VA_BITS_48=y +CONFIG_NUMA=y +CONFIG_HZ_1000=y +CONFIG_XEN=y +CONFIG_COMPAT=y +CONFIG_RANDOMIZE_BASE=y +CONFIG_PM_DEBUG=y +CONFIG_PM_TEST_SUSPEND=y +CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y +CONFIG_ENERGY_MODEL=y +CONFIG_ARM_PSCI_CPUIDLE=y +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_STAT=y +CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y +CONFIG_CPUFREQ_DT=y +CONFIG_ARM_SCPI_CPUFREQ=y +CONFIG_ARM_IMX_CPUFREQ_DT=y +CONFIG_ARM_SCMI_CPUFREQ=y +CONFIG_ACPI_CPPC_CPUFREQ=m +CONFIG_ACPI=y +CONFIG_ACPI_APEI=y +CONFIG_ACPI_APEI_GHES=y +CONFIG_ACPI_APEI_MEMORY_FAILURE=y +CONFIG_VIRTUALIZATION=y +CONFIG_KVM=y +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_COMPRESS=y +CONFIG_MODULE_COMPRESS_XZ=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_BINFMT_MISC=y +# CONFIG_SWAP is not set +# CONFIG_COMPAT_BRK is not set +CONFIG_KSM=y +CONFIG_MEMORY_FAILURE=y +CONFIG_TRANSPARENT_HUGEPAGE=y +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_TLS=y +CONFIG_TLS_DEVICE=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IPV6_SIT=m +CONFIG_NETFILTER=y +CONFIG_BRIDGE_NETFILTER=m +CONFIG_NETFILTER_NETLINK_OSF=m +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CT_NETLINK=m +CONFIG_NF_TABLES=y +CONFIG_NF_TABLES_INET=y +CONFIG_NF_TABLES_NETDEV=y +CONFIG_NFT_CT=m +CONFIG_NFT_MASQ=m +CONFIG_NFT_NAT=m +CONFIG_NFT_COMPAT=m +CONFIG_NFT_DUP_NETDEV=m +CONFIG_NFT_FWD_NETDEV=m +CONFIG_NF_FLOW_TABLE=m +CONFIG_NETFILTER_XT_MARK=m +CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m +CONFIG_NETFILTER_XT_TARGET_LOG=m +CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_IPVS=m +CONFIG_IP_VS=m +CONFIG_NF_SOCKET_IPV4=m +CONFIG_NF_TPROXY_IPV4=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_NF_SOCKET_IPV6=m +CONFIG_NF_TPROXY_IPV6=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_NF_TABLES_BRIDGE=m +CONFIG_BRIDGE_NF_EBTABLES=m +CONFIG_BRIDGE=y +CONFIG_BRIDGE_VLAN_FILTERING=y +CONFIG_NET_DSA=y +CONFIG_VLAN_8021Q=y +CONFIG_VLAN_8021Q_GVRP=y +CONFIG_VLAN_8021Q_MVRP=y +CONFIG_LLC2=y +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_MULTIQ=y +CONFIG_NET_SCH_CBS=y +CONFIG_NET_SCH_ETF=y +CONFIG_NET_SCH_TAPRIO=y +CONFIG_NET_SCH_MQPRIO=y +CONFIG_NET_SCH_INGRESS=y +CONFIG_NET_CLS_BASIC=y +CONFIG_NET_CLS_U32=y +CONFIG_NET_CLS_FLOWER=y +CONFIG_NET_CLS_ACT=y +CONFIG_NET_ACT_POLICE=y +CONFIG_NET_ACT_GACT=y +CONFIG_NET_ACT_MIRRED=y +CONFIG_NET_ACT_SKBEDIT=y +CONFIG_NET_ACT_GATE=y +CONFIG_DNS_RESOLVER=y +CONFIG_VSOCKETS=y +CONFIG_VIRTIO_VSOCKETS=y +CONFIG_QRTR=m +CONFIG_QRTR_SMD=m +CONFIG_QRTR_TUN=m +CONFIG_NET_PKTGEN=m +CONFIG_CAN=m +CONFIG_BT=y +CONFIG_BT_RFCOMM=y +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=y +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_HIDP=y +CONFIG_BT_LEDS=y +CONFIG_BT_HCIBTUSB=m +CONFIG_BT_HCIUART=y +CONFIG_BT_HCIUART_ATH3K=y +CONFIG_BT_HCIUART_LL=y +CONFIG_BT_HCIUART_3WIRE=y +CONFIG_BT_HCIUART_BCM=y +CONFIG_BT_HCIUART_QCA=y +CONFIG_BT_HCIVHCI=y +CONFIG_BT_NXPUART=m +CONFIG_CFG80211=y +CONFIG_NL80211_TESTMODE=y +# CONFIG_CFG80211_DEFAULT_PS is not set +CONFIG_CFG80211_WEXT=y +CONFIG_MAC80211=y +CONFIG_MAC80211_LEDS=y +CONFIG_NET_9P=y +CONFIG_NET_9P_VIRTIO=y +CONFIG_NFC=m +CONFIG_NFC_NCI=m +CONFIG_NFC_S3FWRN5_I2C=m +CONFIG_PCI=y +CONFIG_PCIEPORTBUS=y +CONFIG_PCI_IOV=y +CONFIG_PCI_PASID=y +CONFIG_HOTPLUG_PCI=y +CONFIG_HOTPLUG_PCI_ACPI=y +CONFIG_PCIE_ALTERA=y +CONFIG_PCIE_ALTERA_MSI=y +CONFIG_PCI_HOST_THUNDER_PEM=y +CONFIG_PCI_HOST_THUNDER_ECAM=y +CONFIG_PCI_HOST_GENERIC=y +CONFIG_PCI_XGENE=y +CONFIG_PCI_MESON=m +CONFIG_PCI_IMX6_HOST=y +CONFIG_PCI_IMX6_EP=y +CONFIG_PCI_HISI=y +CONFIG_PCIE_KIRIN=y +CONFIG_PCI_ENDPOINT=y +CONFIG_PCI_ENDPOINT_CONFIGFS=y +CONFIG_PCI_EPF_TEST=y +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_FW_LOADER_USER_HELPER=y +CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y +CONFIG_NXP_FSPI_BUS=y +CONFIG_VEXPRESS_CONFIG=y +CONFIG_ARM_SCMI_PROTOCOL=y +CONFIG_ARM_SCMI_POWER_CONTROL=y +CONFIG_ARM_SCPI_PROTOCOL=y +CONFIG_EFI_CAPSULE_LOADER=y +CONFIG_IMX_DSP=y +CONFIG_IMX_SCU=y +CONFIG_GNSS=m +CONFIG_GNSS_MTK_SERIAL=m +CONFIG_MTD=y +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_BLOCK=y +CONFIG_MTD_CFI=y +CONFIG_MTD_CFI_ADV_OPTIONS=y +CONFIG_MTD_CFI_INTELEXT=y +CONFIG_MTD_CFI_AMDSTD=y +CONFIG_MTD_CFI_STAA=y +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_OF=y +CONFIG_MTD_DATAFLASH=y +CONFIG_MTD_SST25L=y +CONFIG_MTD_RAW_NAND=y +CONFIG_MTD_NAND_DENALI_DT=y +CONFIG_MTD_NAND_GPMI_NAND=y +CONFIG_MTD_SPI_NAND=y +CONFIG_MTD_SPI_NOR=y +# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set +CONFIG_MTD_UBI=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_NBD=m +CONFIG_XEN_BLKDEV_BACKEND=m +CONFIG_VIRTIO_BLK=y +CONFIG_BLK_DEV_NVME=y +CONFIG_SRAM=y +CONFIG_PCI_ENDPOINT_TEST=y +CONFIG_EEPROM_AT24=m +CONFIG_EEPROM_AT25=m +CONFIG_UACCE=m +# CONFIG_SCSI_PROC_FS is not set +CONFIG_BLK_DEV_SD=y +CONFIG_SCSI_SAS_ATA=y +CONFIG_SCSI_HISI_SAS=y +CONFIG_SCSI_HISI_SAS_PCI=y +CONFIG_MEGARAID_SAS=y +CONFIG_SCSI_MPT3SAS=m +CONFIG_ATA=y +CONFIG_SATA_AHCI=y +CONFIG_SATA_AHCI_PLATFORM=y +CONFIG_AHCI_IMX=y +CONFIG_AHCI_CEVA=y +CONFIG_SATA_SIL24=y +CONFIG_PATA_OF_PLATFORM=y +CONFIG_MD=y +CONFIG_BLK_DEV_MD=m +CONFIG_BLK_DEV_DM=m +CONFIG_DM_CRYPT=m +CONFIG_DM_MIRROR=m +CONFIG_DM_ZERO=m +CONFIG_NETDEVICES=y +CONFIG_MACVLAN=m +CONFIG_MACVTAP=m +CONFIG_MACSEC=y +CONFIG_TUN=y +CONFIG_VETH=m +CONFIG_VIRTIO_NET=y +CONFIG_NET_DSA_MSCC_FELIX=m +CONFIG_NET_DSA_SJA1105=m +CONFIG_NET_DSA_SJA1105_PTP=y +CONFIG_NET_DSA_SJA1105_TAS=y +CONFIG_NET_DSA_SJA1105_VL=y +CONFIG_AMD_XGBE=y +CONFIG_ATL1C=m +CONFIG_BCMGENET=m +CONFIG_BNX2X=m +CONFIG_SYSTEMPORT=m +CONFIG_MACB=y +CONFIG_THUNDER_NIC_PF=y +CONFIG_FEC=y +CONFIG_FSL_ENETC=y +CONFIG_FSL_ENETC_VF=y +CONFIG_FSL_ENETC_QOS=y +CONFIG_NXP_NETC_BLK_CTRL=y +CONFIG_HIX5HD2_GMAC=y +CONFIG_HNS_DSAF=y +CONFIG_HNS_ENET=y +CONFIG_HNS3=y +CONFIG_HNS3_HCLGE=y +CONFIG_HNS3_ENET=y +CONFIG_E1000=y +CONFIG_E1000E=y +CONFIG_IGB=y +CONFIG_IGBVF=y +CONFIG_MVMDIO=y +CONFIG_SKY2=y +CONFIG_MLX4_EN=m +CONFIG_MLX5_CORE=m +CONFIG_MLX5_CORE_EN=y +CONFIG_MSCC_OCELOT_SWITCH=y +CONFIG_QCOM_EMAC=m +CONFIG_RMNET=m +CONFIG_SMC91X=y +CONFIG_SMSC911X=y +CONFIG_STMMAC_ETH=y +CONFIG_DWMAC_GENERIC=m +CONFIG_AQUANTIA_PHY=y +CONFIG_BROADCOM_PHY=m +CONFIG_BCM54140_PHY=m +CONFIG_MARVELL_PHY=m +CONFIG_MARVELL_10G_PHY=m +CONFIG_MAXLINEAR_GPHY=y +CONFIG_MICREL_PHY=y +CONFIG_MICROSEMI_PHY=y +CONFIG_MOTORCOMM_PHY=y +CONFIG_NXP_C45_TJA11XX_PHY=y +CONFIG_NXP_TJA11XX_PHY=y +CONFIG_AT803X_PHY=y +CONFIG_REALTEK_PHY=y +CONFIG_ROCKCHIP_PHY=y +CONFIG_DP83848_PHY=y +CONFIG_VITESSE_PHY=y +CONFIG_CAN_FLEXCAN=m +CONFIG_MDIO_BITBANG=y +CONFIG_MDIO_BUS_MUX_MULTIPLEXER=y +CONFIG_MDIO_BUS_MUX_MMIOREG=y +CONFIG_USB_PEGASUS=m +CONFIG_USB_RTL8150=m +CONFIG_USB_RTL8152=y +CONFIG_USB_LAN78XX=m +CONFIG_USB_USBNET=y +CONFIG_USB_NET_AX8817X=m +CONFIG_USB_NET_AX88179_178A=m +CONFIG_USB_NET_CDCETHER=m +CONFIG_USB_NET_CDC_NCM=m +CONFIG_USB_NET_DM9601=m +CONFIG_USB_NET_SR9800=m +CONFIG_USB_NET_SMSC75XX=m +CONFIG_USB_NET_SMSC95XX=m +CONFIG_USB_NET_NET1080=m +CONFIG_USB_NET_PLUSB=m +CONFIG_USB_NET_MCS7830=m +CONFIG_USB_NET_CDC_SUBSET=m +CONFIG_USB_NET_ZAURUS=m +CONFIG_WL18XX=m +CONFIG_WLCORE_SDIO=m +CONFIG_XEN_NETDEV_BACKEND=m +CONFIG_INPUT_EVDEV=y +CONFIG_KEYBOARD_ADC=m +CONFIG_KEYBOARD_GPIO=y +CONFIG_KEYBOARD_SNVS_PWRKEY=y +CONFIG_KEYBOARD_IMX_SC_KEY=y +CONFIG_KEYBOARD_CROS_EC=y +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_ATMEL_MXT=m +CONFIG_TOUCHSCREEN_EXC3000=y +CONFIG_TOUCHSCREEN_GOODIX=m +CONFIG_TOUCHSCREEN_ILITEK=y +CONFIG_TOUCHSCREEN_EDT_FT5X06=m +CONFIG_TOUCHSCREEN_USB_COMPOSITE=m +CONFIG_INPUT_MISC=y +CONFIG_INPUT_BBNSM_PWRKEY=y +CONFIG_INPUT_PWM_BEEPER=m +CONFIG_INPUT_PWM_VIBRA=m +# CONFIG_SERIO_SERPORT is not set +CONFIG_SERIO_AMBAKMI=y +CONFIG_LEGACY_PTY_COUNT=16 +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_8250_DW=y +CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_SERIAL_AMBA_PL011=y +CONFIG_SERIAL_AMBA_PL011_CONSOLE=y +CONFIG_SERIAL_IMX=y +CONFIG_SERIAL_IMX_CONSOLE=y +CONFIG_SERIAL_XILINX_PS_UART=y +CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y +CONFIG_SERIAL_FSL_LPUART=y +CONFIG_SERIAL_FSL_LPUART_CONSOLE=y +CONFIG_SERIAL_FSL_LINFLEXUART=y +CONFIG_SERIAL_FSL_LINFLEXUART_CONSOLE=y +CONFIG_RPMSG_TTY=m +CONFIG_SERIAL_DEV_BUS=y +CONFIG_VIRTIO_CONSOLE=y +CONFIG_IPMI_HANDLER=m +CONFIG_IPMI_DEVICE_INTERFACE=m +CONFIG_IPMI_SI=m +CONFIG_TCG_TPM=y +CONFIG_TCG_TIS_I2C_INFINEON=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_MUX_GPIO=y +CONFIG_I2C_MUX_PCA954x=y +CONFIG_I2C_GPIO=m +CONFIG_I2C_IMX=y +CONFIG_I2C_IMX_LPI2C=y +CONFIG_I2C_RK3X=y +CONFIG_I2C_CROS_EC_TUNNEL=y +CONFIG_I2C_SLAVE_EEPROM=y +CONFIG_I3C=y +CONFIG_SVC_I3C_MASTER=y +CONFIG_SPI=y +CONFIG_SPI_CADENCE_QUADSPI=y +CONFIG_SPI_DESIGNWARE=m +CONFIG_SPI_DW_DMA=y +CONFIG_SPI_DW_MMIO=m +CONFIG_SPI_FSL_LPSPI=y +CONFIG_SPI_FSL_QUADSPI=y +CONFIG_SPI_NXP_FLEXSPI=y +CONFIG_SPI_IMX=y +CONFIG_SPI_PL022=y +CONFIG_SPI_MUX=y +CONFIG_SPI_SPIDEV=y +CONFIG_SPI_SLAVE=y +CONFIG_SPI_SLAVE_TIME=y +CONFIG_SPI_SLAVE_SYSTEM_CONTROL=y +CONFIG_SPMI=y +CONFIG_PPS_CLIENT_GPIO=y +CONFIG_PINCTRL=y +CONFIG_PINCTRL_MAX77620=y +CONFIG_PINCTRL_SCMI=y +CONFIG_PINCTRL_SINGLE=y +CONFIG_PINCTRL_IMX_SCMI=y +CONFIG_PINCTRL_TS9390=y +CONFIG_PINCTRL_TS9370=y +CONFIG_GPIO_DWAPB=y +CONFIG_GPIO_MB86S7X=y +CONFIG_GPIO_MXC=y +CONFIG_GPIO_PL061=y +CONFIG_GPIO_VF610=y +CONFIG_GPIO_WCD934X=m +CONFIG_GPIO_XGENE=y +CONFIG_GPIO_MAX732X=y +CONFIG_GPIO_PCA953X=y +CONFIG_GPIO_PCA953X_IRQ=y +CONFIG_GPIO_PCA9570=y +CONFIG_GPIO_PCF857X=y +CONFIG_GPIO_TS9370=y +CONFIG_GPIO_ADP5585=y +CONFIG_GPIO_BD9571MWV=m +CONFIG_GPIO_MAX77620=y +CONFIG_POWER_RESET_TS_WIZARD=y +CONFIG_POWER_RESET_XGENE=y +CONFIG_POWER_RESET_SYSCON=y +CONFIG_SYSCON_REBOOT_MODE=y +CONFIG_BATTERY_SBS=m +CONFIG_BATTERY_BQ27XXX=y +CONFIG_BATTERY_MAX17042=m +CONFIG_CHARGER_BQ25890=m +CONFIG_CHARGER_BQ25980=m +CONFIG_SENSORS_ARM_SCMI=y +CONFIG_SENSORS_ARM_SCPI=y +CONFIG_SENSORS_LM90=m +CONFIG_SENSORS_PWM_FAN=m +CONFIG_SENSORS_EMC2305=m +CONFIG_SENSORS_INA2XX=m +CONFIG_SENSORS_INA3221=m +CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y +CONFIG_CPU_THERMAL=y +CONFIG_THERMAL_EMULATION=y +CONFIG_IMX_SC_THERMAL=y +CONFIG_IMX8MM_THERMAL=y +CONFIG_QORIQ_THERMAL=y +CONFIG_WATCHDOG=y +CONFIG_ARM_SP805_WATCHDOG=y +CONFIG_ARM_SBSA_WATCHDOG=y +CONFIG_DW_WATCHDOG=y +CONFIG_IMX2_WDT=y +CONFIG_IMX_SC_WDT=y +CONFIG_IMX7ULP_WDT=y +CONFIG_ARM_SMC_WATCHDOG=y +CONFIG_XEN_WDT=y +CONFIG_MFD_ADP5585=y +CONFIG_MFD_BD9571MWV=y +CONFIG_MFD_AXP20X_I2C=y +CONFIG_MFD_HI6421_PMIC=y +CONFIG_MFD_MAX77620=y +CONFIG_MFD_MT6397=y +CONFIG_MFD_TS_WIZARD=y +CONFIG_MFD_ROHM_BD718XX=y +CONFIG_MFD_WCD934X=m +CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_AXP20X=y +CONFIG_REGULATOR_BD718XX=y +CONFIG_REGULATOR_BD9571MWV=y +CONFIG_REGULATOR_FAN53555=y +CONFIG_REGULATOR_GPIO=y +CONFIG_REGULATOR_HI6421V530=y +CONFIG_REGULATOR_MAX77620=y +CONFIG_REGULATOR_MAX8973=y +CONFIG_REGULATOR_MP8859=y +CONFIG_REGULATOR_MT6358=y +CONFIG_REGULATOR_MT6397=y +CONFIG_REGULATOR_PCA9450=y +CONFIG_REGULATOR_PF9453=y +CONFIG_REGULATOR_PF0900=y +CONFIG_REGULATOR_PF8X00=y +CONFIG_REGULATOR_PFUZE100=y +CONFIG_REGULATOR_PWM=y +CONFIG_REGULATOR_QCOM_SPMI=y +CONFIG_REGULATOR_TPS65132=m +CONFIG_REGULATOR_VCTRL=m +CONFIG_RC_CORE=m +CONFIG_RC_DECODERS=y +CONFIG_IR_IMON_DECODER=m +CONFIG_IR_JVC_DECODER=m +CONFIG_IR_MCE_KBD_DECODER=m +CONFIG_IR_NEC_DECODER=m +CONFIG_IR_RC5_DECODER=m +CONFIG_IR_RC6_DECODER=m +CONFIG_IR_RCMM_DECODER=m +CONFIG_IR_SANYO_DECODER=m +CONFIG_IR_SHARP_DECODER=m +CONFIG_IR_SONY_DECODER=m +CONFIG_IR_XMP_DECODER=m +CONFIG_RC_DEVICES=y +CONFIG_IR_GPIO_CIR=m +CONFIG_MEDIA_SUPPORT=y +CONFIG_MEDIA_CAMERA_SUPPORT=y +CONFIG_MEDIA_ANALOG_TV_SUPPORT=y +CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y +CONFIG_MEDIA_SDR_SUPPORT=y +CONFIG_MEDIA_PLATFORM_SUPPORT=y +# CONFIG_DVB_NET is not set +CONFIG_MEDIA_USB_SUPPORT=y +CONFIG_USB_VIDEO_CLASS=m +CONFIG_V4L_PLATFORM_DRIVERS=y +CONFIG_SDR_PLATFORM_DRIVERS=y +CONFIG_V4L_MEM2MEM_DRIVERS=y +CONFIG_VIDEO_AMPHION_VPU=y +CONFIG_VIDEO_IMX7_CSI=m +CONFIG_VIDEO_IMX8MQ_MIPI_CSI2=m +CONFIG_VIDEO_IMX_MIPI_CSIS=m +CONFIG_VIDEO_IMX8_ISI=y +CONFIG_VIDEO_IMX8_ISI_M2M=y +CONFIG_VIDEO_IMX8_JPEG=m +CONFIG_VIDEO_HANTRO=m +CONFIG_VIDEO_IMX219=m +CONFIG_VIDEO_OV5640=y +CONFIG_VIDEO_OV5645=m +CONFIG_VIDEO_RDACM20=y +CONFIG_VIDEO_DS90UB953=m +CONFIG_VIDEO_DS90UB960=m +CONFIG_DRM=y +CONFIG_DRM_MALI_DISPLAY=m +CONFIG_DRM_VIRTIO_GPU=y +CONFIG_DRM_PANEL_BOE_TV101WUM_NL6=m +CONFIG_DRM_PANEL_LVDS=y +CONFIG_DRM_PANEL_MANTIX_MLAF057WE51=m +CONFIG_DRM_PANEL_RAYDIUM_RM67191=y +CONFIG_DRM_PANEL_RAYDIUM_RM68200=y +CONFIG_DRM_PANEL_SEIKO_43WVF1G=y +CONFIG_DRM_PANEL_SITRONIX_ST7703=m +CONFIG_DRM_PANEL_SIMPLE=y +CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA=m +CONFIG_DRM_DISPLAY_CONNECTOR=y +CONFIG_DRM_FSL_LDB=y +CONFIG_DRM_I2C_NXP_TDA998X=m +CONFIG_DRM_ITE_IT6263=y +CONFIG_DRM_LONTIUM_LT8912B=m +CONFIG_DRM_LONTIUM_LT9611=m +CONFIG_DRM_LONTIUM_LT9611UXC=y +CONFIG_DRM_NWL_MIPI_DSI=y +CONFIG_DRM_PARADE_PS8640=m +CONFIG_DRM_SII902X=m +CONFIG_DRM_SIMPLE_BRIDGE=m +CONFIG_DRM_THINE_THC63LVD1024=m +CONFIG_DRM_TOSHIBA_TC358767=y +CONFIG_DRM_TI_SN65DSI83=y +CONFIG_DRM_TI_SN65DSI86=m +CONFIG_DRM_WAVESHARE_BRIDGE=y +CONFIG_DRM_I2C_ADV7511=y +CONFIG_DRM_I2C_ADV7511_AUDIO=y +CONFIG_DRM_IMX8QM_LDB=y +CONFIG_DRM_IMX8QXP_LDB=y +CONFIG_DRM_IMX_DCSS=y +CONFIG_DRM_ETNAVIV=m +CONFIG_DRM_HISI_HIBMC=m +CONFIG_DRM_HISI_KIRIN=m +CONFIG_DRM_MXSFB=y +CONFIG_DRM_PL111=m +CONFIG_DRM_XEN_FRONTEND=y +CONFIG_DRM_LIMA=m +CONFIG_DRM_PANFROST=m +CONFIG_FB=y +CONFIG_FB_EFI=y +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_PWM=y +CONFIG_BACKLIGHT_LP855X=m +CONFIG_BACKLIGHT_GPIO=y +CONFIG_BACKLIGHT_LED=y +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +CONFIG_SOUND=y +CONFIG_SND=y +CONFIG_SND_ALOOP=m +CONFIG_SND_USB_AUDIO=m +CONFIG_SND_SOC=y +CONFIG_SND_SOC_FSL_ASRC=m +CONFIG_SND_SOC_FSL_MQS=m +CONFIG_SND_SOC_FSL_MICFIL=m +CONFIG_SND_SOC_FSL_EASRC=m +CONFIG_SND_SOC_FSL_XCVR=m +CONFIG_SND_SOC_FSL_RPMSG=m +CONFIG_SND_IMX_SOC=m +CONFIG_SND_SOC_IMX_SGTL5000=m +CONFIG_SND_SOC_FSL_ASOC_CARD=m +CONFIG_SND_SOC_IMX_AUDMIX=m +CONFIG_SND_SOC_IMX_HDMI=m +CONFIG_SND_SOC_IMX_CARD=m +CONFIG_SND_SOC_SOF_TOPLEVEL=y +CONFIG_SND_SOC_SOF_OF=m +CONFIG_SND_SOC_SOF_IMX_TOPLEVEL=y +CONFIG_SND_SOC_SOF_IMX8=m +CONFIG_SND_SOC_AK4613=m +CONFIG_SND_SOC_BT_SCO=y +CONFIG_SND_SOC_CROS_EC_CODEC=m +CONFIG_SND_SOC_CS42XX8_I2C=y +CONFIG_SND_SOC_DMIC=m +CONFIG_SND_SOC_ES7134=m +CONFIG_SND_SOC_ES7241=m +CONFIG_SND_SOC_GTM601=m +CONFIG_SND_SOC_MAX98357A=m +CONFIG_SND_SOC_MAX98927=m +CONFIG_SND_SOC_MSM8916_WCD_ANALOG=m +CONFIG_SND_SOC_MSM8916_WCD_DIGITAL=m +CONFIG_SND_SOC_PCM3168A_I2C=m +CONFIG_SND_SOC_RT5659=m +CONFIG_SND_SOC_SIMPLE_AMPLIFIER=m +CONFIG_SND_SOC_SIMPLE_MUX=m +CONFIG_SND_SOC_SPDIF=m +CONFIG_SND_SOC_TAC5X1X_I2C=y +CONFIG_SND_SOC_TAS571X=m +CONFIG_SND_SOC_WCD934X=m +CONFIG_SND_SOC_WM8524=y +CONFIG_SND_SOC_WM8904=m +CONFIG_SND_SOC_WM8960=m +CONFIG_SND_SOC_WM8962=m +CONFIG_SND_SOC_WSA881X=m +CONFIG_SND_SOC_LPASS_WSA_MACRO=m +CONFIG_SND_SOC_LPASS_VA_MACRO=m +CONFIG_SND_SIMPLE_CARD=y +CONFIG_SND_AUDIO_GRAPH_CARD=y +CONFIG_SND_AUDIO_GRAPH_CARD2=m +CONFIG_SND_VIRTIO=y +CONFIG_HID_MULTITOUCH=m +CONFIG_I2C_HID_ACPI=m +CONFIG_I2C_HID_OF=m +CONFIG_USB_CONN_GPIO=y +CONFIG_USB=y +CONFIG_USB_OTG=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_PCI_RENESAS=m +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_HCD_PLATFORM=y +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_OHCI_HCD_PLATFORM=y +CONFIG_USB_HCD_TEST_MODE=y +CONFIG_USB_XEN_HCD=y +CONFIG_USB_ACM=m +CONFIG_USB_STORAGE=y +CONFIG_USB_UAS=y +CONFIG_USB_CDNS_SUPPORT=y +CONFIG_USB_CDNS3=y +CONFIG_USB_CDNS3_GADGET=y +CONFIG_USB_CDNS3_HOST=y +CONFIG_USB_MUSB_HDRC=y +CONFIG_USB_DWC3=y +CONFIG_USB_DWC2=y +CONFIG_USB_CHIPIDEA=y +CONFIG_USB_CHIPIDEA_UDC=y +CONFIG_USB_CHIPIDEA_HOST=y +CONFIG_USB_ISP1760=y +CONFIG_USB_SERIAL=y +CONFIG_USB_SERIAL_CONSOLE=y +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_SIMPLE=y +CONFIG_USB_SERIAL_CP210X=m +CONFIG_USB_SERIAL_FTDI_SIO=y +CONFIG_USB_SERIAL_OPTION=m +CONFIG_USB_TEST=m +CONFIG_USB_EHSET_TEST_FIXTURE=y +CONFIG_USB_HSIC_USB3503=y +CONFIG_USB_ONBOARD_DEV=y +CONFIG_NOP_USB_XCEIV=y +CONFIG_USB_MXS_PHY=y +CONFIG_USB_ULPI=y +CONFIG_USB_GADGET=y +CONFIG_USB_SNP_UDC_PLAT=y +CONFIG_USB_BDC_UDC=y +CONFIG_USB_CONFIGFS=y +CONFIG_USB_CONFIGFS_SERIAL=y +CONFIG_USB_CONFIGFS_ACM=y +CONFIG_USB_CONFIGFS_OBEX=y +CONFIG_USB_CONFIGFS_NCM=y +CONFIG_USB_CONFIGFS_ECM=y +CONFIG_USB_CONFIGFS_ECM_SUBSET=y +CONFIG_USB_CONFIGFS_RNDIS=y +CONFIG_USB_CONFIGFS_EEM=y +CONFIG_USB_CONFIGFS_MASS_STORAGE=y +CONFIG_USB_CONFIGFS_F_LB_SS=y +CONFIG_USB_CONFIGFS_F_FS=y +CONFIG_USB_CONFIGFS_F_UAC1=y +CONFIG_USB_CONFIGFS_F_UAC1_LEGACY=y +CONFIG_USB_CONFIGFS_F_UAC2=y +CONFIG_USB_CONFIGFS_F_MIDI=y +CONFIG_USB_CONFIGFS_F_HID=y +CONFIG_USB_CONFIGFS_F_UVC=y +CONFIG_USB_ZERO=m +CONFIG_USB_AUDIO=m +CONFIG_USB_ETH=m +CONFIG_USB_MASS_STORAGE=m +CONFIG_USB_G_SERIAL=m +CONFIG_TYPEC=y +CONFIG_TYPEC_TCPM=y +CONFIG_TYPEC_TCPCI=y +CONFIG_TYPEC_FUSB302=m +CONFIG_TYPEC_TPS6598X=m +CONFIG_TYPEC_HD3SS3220=m +CONFIG_MMC=y +CONFIG_MMC_BLOCK_MINORS=32 +CONFIG_MMC_ARMMMCI=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_ACPI=y +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MMC_SDHCI_OF_ARASAN=y +CONFIG_MMC_SDHCI_OF_ESDHC=y +CONFIG_MMC_SDHCI_CADENCE=y +CONFIG_MMC_SDHCI_ESDHC_IMX=y +CONFIG_MMC_SDHCI_F_SDH30=y +CONFIG_MMC_SPI=y +CONFIG_MMC_DW=y +CONFIG_MMC_DW_EXYNOS=y +CONFIG_MMC_DW_HI3798CV200=y +CONFIG_MMC_DW_K3=y +CONFIG_MMC_MTK=y +CONFIG_MMC_SDHCI_XENON=y +CONFIG_SCSI_UFSHCD=y +CONFIG_SCSI_UFSHCD_PLATFORM=y +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_CLASS_MULTICOLOR=m +CONFIG_LEDS_LM3692X=m +CONFIG_LEDS_PCA9532=m +CONFIG_LEDS_GPIO=y +CONFIG_LEDS_PCA963X=y +CONFIG_LEDS_PCA995X=m +CONFIG_LEDS_PWM=y +CONFIG_LEDS_SYSCON=y +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEDS_TRIGGER_DISK=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_LEDS_TRIGGER_CPU=y +CONFIG_LEDS_TRIGGER_DEFAULT_ON=y +CONFIG_LEDS_TRIGGER_PANIC=y +CONFIG_EDAC=y +CONFIG_EDAC_GHES=y +CONFIG_EDAC_SYNOPSYS=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_DS1307=m +CONFIG_RTC_DRV_HYM8563=m +CONFIG_RTC_DRV_MAX77686=y +CONFIG_RTC_DRV_PCF85363=m +CONFIG_RTC_DRV_M41T80=m +CONFIG_RTC_DRV_TSWIZARD=y +CONFIG_RTC_DRV_RX8581=m +CONFIG_RTC_DRV_RV3028=m +CONFIG_RTC_DRV_RV8803=m +CONFIG_RTC_DRV_DS3232=y +CONFIG_RTC_DRV_PCF2127=m +CONFIG_RTC_DRV_EFI=y +CONFIG_RTC_DRV_CROS_EC=y +CONFIG_RTC_DRV_PL031=y +CONFIG_RTC_DRV_SNVS=y +CONFIG_RTC_DRV_BBNSM=y +CONFIG_RTC_DRV_IMX_SC=y +CONFIG_DMADEVICES=y +CONFIG_BCM_SBA_RAID=m +CONFIG_FSL_EDMA=y +CONFIG_FSL_QDMA=m +CONFIG_IMX_SDMA=y +CONFIG_MV_XOR_V2=y +CONFIG_MXS_DMA=y +CONFIG_PL330_DMA=y +CONFIG_QCOM_HIDMA_MGMT=y +CONFIG_QCOM_HIDMA=y +CONFIG_DW_EDMA=y +CONFIG_DW_EDMA_PCIE=y +CONFIG_DMATEST=y +CONFIG_UDMABUF=y +CONFIG_DMABUF_HEAPS=y +CONFIG_DMABUF_HEAPS_SYSTEM=y +CONFIG_DMABUF_HEAPS_CMA=y +CONFIG_VFIO=y +CONFIG_VFIO_PCI=y +CONFIG_VIRTIO_PCI=y +CONFIG_VIRTIO_BALLOON=y +CONFIG_VIRTIO_INPUT=y +CONFIG_VIRTIO_MMIO=y +CONFIG_VHOST_NET=m +CONFIG_VHOST_VSOCK=y +CONFIG_XEN_GNTDEV=y +CONFIG_XEN_GNTDEV_DMABUF=y +CONFIG_XEN_GRANT_DEV_ALLOC=y +CONFIG_XEN_GRANT_DMA_ALLOC=y +CONFIG_XEN_PCIDEV_STUB=y +CONFIG_XEN_VIRTIO=y +CONFIG_XEN_VIRTIO_FORCE_GRANT=y +CONFIG_STAGING=y +CONFIG_STAGING_MEDIA=y +CONFIG_CHROME_PLATFORMS=y +CONFIG_CROS_EC=y +CONFIG_CROS_EC_I2C=y +CONFIG_CROS_EC_SPI=y +CONFIG_CROS_EC_CHARDEV=m +CONFIG_CLK_VEXPRESS_OSC=y +CONFIG_COMMON_CLK_SCMI=y +CONFIG_COMMON_CLK_SCPI=y +CONFIG_COMMON_CLK_CS2000_CP=y +CONFIG_COMMON_CLK_XGENE=y +CONFIG_COMMON_CLK_PWM=y +CONFIG_COMMON_CLK_VC5=y +CONFIG_CLK_IMX8MM=y +CONFIG_CLK_IMX8MN=y +CONFIG_CLK_IMX8MP=y +CONFIG_CLK_IMX8MQ=y +CONFIG_CLK_IMX8QXP=y +CONFIG_CLK_IMX8ULP=y +CONFIG_CLK_IMX93=y +CONFIG_CLK_IMX95_BLK_CTL=y +CONFIG_HWSPINLOCK=y +CONFIG_ARM_MHU=y +CONFIG_IMX_MBOX=y +CONFIG_PLATFORM_MHU=y +CONFIG_IOMMU_IO_PGTABLE_ARMV7S=y +CONFIG_ARM_SMMU=y +CONFIG_ARM_SMMU_V3=y +CONFIG_REMOTEPROC=y +CONFIG_IMX_REMOTEPROC=y +CONFIG_IMX_DSP_REMOTEPROC=m +CONFIG_RPMSG_CHAR=m +CONFIG_RPMSG_CTRL=m +CONFIG_RPMSG_QCOM_GLINK_RPM=y +CONFIG_SOUNDWIRE=m +CONFIG_SOUNDWIRE_QCOM=m +CONFIG_FSL_RCPM=y +CONFIG_SOC_TI=y +CONFIG_IMX_SCU_PD=y +CONFIG_DEVFREQ_GOV_PERFORMANCE=y +CONFIG_DEVFREQ_GOV_POWERSAVE=y +CONFIG_DEVFREQ_GOV_USERSPACE=y +CONFIG_DEVFREQ_GOV_PASSIVE=y +CONFIG_EXTCON_PTN5150=m +CONFIG_EXTCON_USB_GPIO=y +CONFIG_EXTCON_USBC_CROS_EC=y +CONFIG_IIO=y +CONFIG_FXLS8962AF_I2C=m +CONFIG_IIO_ST_ACCEL_3AXIS=m +CONFIG_IMX8QXP_ADC=y +CONFIG_IMX93_ADC=y +CONFIG_MAX9611=m +CONFIG_QCOM_SPMI_VADC=m +CONFIG_QCOM_SPMI_ADC5=m +CONFIG_TI_ADC128S052=y +CONFIG_TS_WIZARD_ADC=y +CONFIG_IIO_RESCALE=m +CONFIG_IIO_CROS_EC_SENSORS_CORE=m +CONFIG_IIO_CROS_EC_SENSORS=m +CONFIG_FXAS21002C=y +CONFIG_IIO_ST_GYRO_3AXIS=m +CONFIG_FXOS8700_I2C=y +CONFIG_INV_MPU6050_I2C=m +CONFIG_IIO_ST_LSM6DSX=y +CONFIG_IIO_CROS_EC_LIGHT_PROX=m +CONFIG_SENSORS_ISL29018=y +CONFIG_VCNL4000=m +CONFIG_VCNL4035=m +CONFIG_IIO_ST_MAGN_3AXIS=m +CONFIG_IIO_MUX=y +CONFIG_IIO_CROS_EC_BARO=m +CONFIG_MPL3115=y +CONFIG_MS5611=m +CONFIG_MS5611_I2C=m +CONFIG_TS_WIZARD_TEMP=y +CONFIG_PWM=y +CONFIG_PWM_ADP5585=y +CONFIG_PWM_CROS_EC=m +CONFIG_PWM_FSL_FTM=m +CONFIG_PWM_IMX27=y +CONFIG_PWM_IMX_TPM=y +CONFIG_PWM_TS=y +CONFIG_TS9370_IRQ=y +CONFIG_WIZARD_IRQ=y +CONFIG_RESET_IMX7=y +CONFIG_PHY_CADENCE_SALVO=y +CONFIG_PHY_MIXEL_MIPI_DPHY=y +CONFIG_PHY_FSL_IMX8M_PCIE=y +CONFIG_PHY_FSL_IMX8QM_HSIO=y +CONFIG_PHY_FSL_SAMSUNG_HDMI_PHY=y +CONFIG_PHY_QCOM_USB_HS=y +CONFIG_PHY_SAMSUNG_USB2=y +CONFIG_ARM_CCI_PMU=m +CONFIG_ARM_CCN=m +CONFIG_ARM_CMN=m +CONFIG_ARM_SMMU_V3_PMU=m +CONFIG_ARM_DSU_PMU=m +CONFIG_FSL_IMX8_DDR_PMU=y +CONFIG_FSL_IMX9_DDR_PMU=y +CONFIG_ARM_SPE_PMU=m +CONFIG_ARM_DMC620_PMU=m +CONFIG_HISI_PMU=y +CONFIG_NVMEM_IMX_OCOTP=y +CONFIG_NVMEM_IMX_OCOTP_SCU=y +CONFIG_NVMEM_RMEM=m +CONFIG_FPGA=y +CONFIG_FPGA_BRIDGE=m +CONFIG_ALTERA_FREEZE_BRIDGE=m +CONFIG_FPGA_REGION=m +CONFIG_OF_FPGA_REGION=m +CONFIG_TEE=y +CONFIG_OPTEE=y +CONFIG_MUX_GPIO=y +CONFIG_MUX_MMIO=y +CONFIG_EXT2_FS=y +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y +CONFIG_BTRFS_FS=m +CONFIG_BTRFS_FS_POSIX_ACL=y +CONFIG_FANOTIFY=y +CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y +CONFIG_QUOTA=y +CONFIG_AUTOFS_FS=y +CONFIG_FUSE_FS=m +CONFIG_CUSE=m +CONFIG_OVERLAY_FS=m +CONFIG_VFAT_FS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_HUGETLBFS=y +CONFIG_EFIVAR_FS=y +CONFIG_JFFS2_FS=y +CONFIG_UBIFS_FS=y +CONFIG_SQUASHFS=y +CONFIG_SQUASHFS_XZ=y +CONFIG_NFS_FS=y +CONFIG_ROOT_NFS=y +CONFIG_NFSD=y +CONFIG_9P_FS=y +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_ISO8859_1=y +CONFIG_TRUSTED_KEYS=m +# CONFIG_TRUSTED_KEYS_TPM is not set +# CONFIG_TRUSTED_KEYS_TEE is not set +CONFIG_SECURITY=y +CONFIG_CRYPTO_USER=y +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_ARIA=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_CAMELLIA=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_DES=m +CONFIG_CRYPTO_FCRYPT=m +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_SEED=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_CTS=m +CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_CHACHA20POLY1305=m +CONFIG_CRYPTO_ECHAINIV=y +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MICHAEL_MIC=y +CONFIG_CRYPTO_RMD160=m +CONFIG_CRYPTO_STREEBOG=m +CONFIG_CRYPTO_WP512=m +CONFIG_CRYPTO_XCBC=m +CONFIG_CRYPTO_ANSI_CPRNG=y +CONFIG_CRYPTO_USER_API_HASH=m +CONFIG_CRYPTO_USER_API_SKCIPHER=m +CONFIG_CRYPTO_USER_API_RNG=m +CONFIG_CRYPTO_USER_API_AEAD=m +CONFIG_CRYPTO_GHASH_ARM64_CE=y +CONFIG_CRYPTO_SHA3_ARM64=m +CONFIG_CRYPTO_SM3_ARM64_CE=m +CONFIG_CRYPTO_POLYVAL_ARM64_CE=m +CONFIG_CRYPTO_AES_ARM64_BS=m +CONFIG_CRYPTO_AES_ARM64_CE_CCM=y +CONFIG_CRYPTO_DEV_FSL_CAAM=m +CONFIG_CRYPTO_DEV_CCREE=m +CONFIG_CRYPTO_DEV_HISI_SEC2=m +CONFIG_CRYPTO_DEV_HISI_ZIP=m +CONFIG_CRYPTO_DEV_HISI_HPRE=m +CONFIG_CRYPTO_DEV_HISI_TRNG=m +CONFIG_CRYPTO_DEV_AMLOGIC_GXL=m +CONFIG_INDIRECT_PIO=y +CONFIG_SWIOTLB_DYNAMIC=y +CONFIG_CMA_SIZE_MBYTES=32 +CONFIG_MAGIC_SYSRQ=y +CONFIG_SAMPLES=y +CONFIG_SAMPLE_RPMSG_CLIENT=m +CONFIG_CORESIGHT=y +CONFIG_CORESIGHT_LINK_AND_SINK_TMC=y +CONFIG_CORESIGHT_CATU=m +CONFIG_CORESIGHT_SINK_TPIU=m +CONFIG_CORESIGHT_SINK_ETBV10=m +CONFIG_CORESIGHT_SOURCE_ETM4X=y +CONFIG_CORESIGHT_STM=m +CONFIG_CORESIGHT_CTI=m +# CONFIG_RUNTIME_TESTING_MENU is not set From 6168314401109e4cb3c0476eda0e0bba57825bbb Mon Sep 17 00:00:00 2001 From: Aaron Brice Date: Tue, 2 Jun 2026 21:55:20 +0000 Subject: [PATCH 10/10] rtc: tswizard: Fix calibration offset calibration offset was using the wrong register. --- drivers/rtc/rtc-tswizard.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/rtc/rtc-tswizard.c b/drivers/rtc/rtc-tswizard.c index 0b7996403cc9..59783c47b523 100644 --- a/drivers/rtc/rtc-tswizard.c +++ b/drivers/rtc/rtc-tswizard.c @@ -120,7 +120,7 @@ static int wizard_rtc_set_offset(struct device *dev, long offset) if (offset >= 0) ctrl_reg |= RTC_PPB_CTL_SIGN; - return regmap_update_bits(wiz->regmap, RTC_FLAGS, + return regmap_update_bits(wiz->regmap, RTC_PPB_CTL, RTC_PPB_CTL_SIGN | RTC_PPB_CTL_EN, ctrl_reg); }