// SPDX-License-Identifier: GPL-2.0-only
//
// Components shared between ASoC and HDA CS35L56 drivers
//
// Copyright (C) 2023 Cirrus Logic, Inc. and
//                    Cirrus Logic International Semiconductor Ltd.

#include <linux/firmware/cirrus/wmfw.h>
#include <linux/gpio/consumer.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/types.h>
#include <sound/cs-amp-lib.h>

#include "cs35l56.h"

static const struct reg_sequence cs35l56_patch[] = {
	/*
	 * Firmware can change these to non-defaults to satisfy SDCA.
	 * Ensure that they are at known defaults.
	 */
	{ CS35L56_SWIRE_DP3_CH1_INPUT,		0x00000018 },
	{ CS35L56_SWIRE_DP3_CH2_INPUT,		0x00000019 },
	{ CS35L56_SWIRE_DP3_CH3_INPUT,		0x00000029 },
	{ CS35L56_SWIRE_DP3_CH4_INPUT,		0x00000028 },

	/* These are not reset by a soft-reset, so patch to defaults. */
	{ CS35L56_MAIN_RENDER_USER_MUTE,	0x00000000 },
	{ CS35L56_MAIN_RENDER_USER_VOLUME,	0x00000000 },
	{ CS35L56_MAIN_POSTURE_NUMBER,		0x00000000 },
};

int cs35l56_set_patch(struct cs35l56_base *cs35l56_base)
{
	return regmap_register_patch(cs35l56_base->regmap, cs35l56_patch,
				     ARRAY_SIZE(cs35l56_patch));
}
EXPORT_SYMBOL_NS_GPL(cs35l56_set_patch, SND_SOC_CS35L56_SHARED);

static const struct reg_default cs35l56_reg_defaults[] = {
	/* no defaults for OTP_MEM - first read populates cache */

	{ CS35L56_ASP1_ENABLES1,		0x00000000 },
	{ CS35L56_ASP1_CONTROL1,		0x00000028 },
	{ CS35L56_ASP1_CONTROL2,		0x18180200 },
	{ CS35L56_ASP1_CONTROL3,		0x00000002 },
	{ CS35L56_ASP1_FRAME_CONTROL1,		0x03020100 },
	{ CS35L56_ASP1_FRAME_CONTROL5,		0x00020100 },
	{ CS35L56_ASP1_DATA_CONTROL1,		0x00000018 },
	{ CS35L56_ASP1_DATA_CONTROL5,		0x00000018 },

	/* no defaults for ASP1TX mixer */

	{ CS35L56_SWIRE_DP3_CH1_INPUT,		0x00000018 },
	{ CS35L56_SWIRE_DP3_CH2_INPUT,		0x00000019 },
	{ CS35L56_SWIRE_DP3_CH3_INPUT,		0x00000029 },
	{ CS35L56_SWIRE_DP3_CH4_INPUT,		0x00000028 },
	{ CS35L56_IRQ1_MASK_1,			0x83ffffff },
	{ CS35L56_IRQ1_MASK_2,			0xffff7fff },
	{ CS35L56_IRQ1_MASK_4,			0xe0ffffff },
	{ CS35L56_IRQ1_MASK_8,			0xfc000fff },
	{ CS35L56_IRQ1_MASK_18,			0x1f7df0ff },
	{ CS35L56_IRQ1_MASK_20,			0x15c00000 },
	{ CS35L56_MAIN_RENDER_USER_MUTE,	0x00000000 },
	{ CS35L56_MAIN_RENDER_USER_VOLUME,	0x00000000 },
	{ CS35L56_MAIN_POSTURE_NUMBER,		0x00000000 },
};

static bool cs35l56_is_dsp_memory(unsigned int reg)
{
	switch (reg) {
	case CS35L56_DSP1_XMEM_PACKED_0 ... CS35L56_DSP1_XMEM_PACKED_6143:
	case CS35L56_DSP1_XMEM_UNPACKED32_0 ... CS35L56_DSP1_XMEM_UNPACKED32_4095:
	case CS35L56_DSP1_XMEM_UNPACKED24_0 ... CS35L56_DSP1_XMEM_UNPACKED24_8191:
	case CS35L56_DSP1_YMEM_PACKED_0 ... CS35L56_DSP1_YMEM_PACKED_4604:
	case CS35L56_DSP1_YMEM_UNPACKED32_0 ... CS35L56_DSP1_YMEM_UNPACKED32_3070:
	case CS35L56_DSP1_YMEM_UNPACKED24_0 ... CS35L56_DSP1_YMEM_UNPACKED24_6141:
	case CS35L56_DSP1_PMEM_0 ... CS35L56_DSP1_PMEM_5114:
		return true;
	default:
		return false;
	}
}

static bool cs35l56_readable_reg(struct device *dev, unsigned int reg)
{
	switch (reg) {
	case CS35L56_DEVID:
	case CS35L56_REVID:
	case CS35L56_RELID:
	case CS35L56_OTPID:
	case CS35L56_SFT_RESET:
	case CS35L56_GLOBAL_ENABLES:
	case CS35L56_BLOCK_ENABLES:
	case CS35L56_BLOCK_ENABLES2:
	case CS35L56_REFCLK_INPUT:
	case CS35L56_GLOBAL_SAMPLE_RATE:
	case CS35L56_OTP_MEM_53:
	case CS35L56_OTP_MEM_54:
	case CS35L56_OTP_MEM_55:
	case CS35L56_ASP1_ENABLES1:
	case CS35L56_ASP1_CONTROL1:
	case CS35L56_ASP1_CONTROL2:
	case CS35L56_ASP1_CONTROL3:
	case CS35L56_ASP1_FRAME_CONTROL1:
	case CS35L56_ASP1_FRAME_CONTROL5:
	case CS35L56_ASP1_DATA_CONTROL1:
	case CS35L56_ASP1_DATA_CONTROL5:
	case CS35L56_DACPCM1_INPUT:
	case CS35L56_DACPCM2_INPUT:
	case CS35L56_ASP1TX1_INPUT:
	case CS35L56_ASP1TX2_INPUT:
	case CS35L56_ASP1TX3_INPUT:
	case CS35L56_ASP1TX4_INPUT:
	case CS35L56_DSP1RX1_INPUT:
	case CS35L56_DSP1RX2_INPUT:
	case CS35L56_SWIRE_DP3_CH1_INPUT:
	case CS35L56_SWIRE_DP3_CH2_INPUT:
	case CS35L56_SWIRE_DP3_CH3_INPUT:
	case CS35L56_SWIRE_DP3_CH4_INPUT:
	case CS35L56_IRQ1_CFG:
	case CS35L56_IRQ1_STATUS:
	case CS35L56_IRQ1_EINT_1 ... CS35L56_IRQ1_EINT_8:
	case CS35L56_IRQ1_EINT_18:
	case CS35L56_IRQ1_EINT_20:
	case CS35L56_IRQ1_MASK_1:
	case CS35L56_IRQ1_MASK_2:
	case CS35L56_IRQ1_MASK_4:
	case CS35L56_IRQ1_MASK_8:
	case CS35L56_IRQ1_MASK_18:
	case CS35L56_IRQ1_MASK_20:
	case CS35L56_DSP_VIRTUAL1_MBOX_1:
	case CS35L56_DSP_VIRTUAL1_MBOX_2:
	case CS35L56_DSP_VIRTUAL1_MBOX_3:
	case CS35L56_DSP_VIRTUAL1_MBOX_4:
	case CS35L56_DSP_VIRTUAL1_MBOX_5:
	case CS35L56_DSP_VIRTUAL1_MBOX_6:
	case CS35L56_DSP_VIRTUAL1_MBOX_7:
	case CS35L56_DSP_VIRTUAL1_MBOX_8:
	case CS35L56_DSP_RESTRICT_STS1:
	case CS35L56_DSP1_SYS_INFO_ID ... CS35L56_DSP1_SYS_INFO_END:
	case CS35L56_DSP1_AHBM_WINDOW_DEBUG_0:
	case CS35L56_DSP1_AHBM_WINDOW_DEBUG_1:
	case CS35L56_DSP1_SCRATCH1:
	case CS35L56_DSP1_SCRATCH2:
	case CS35L56_DSP1_SCRATCH3:
	case CS35L56_DSP1_SCRATCH4:
		return true;
	default:
		return cs35l56_is_dsp_memory(reg);
	}
}

static bool cs35l56_precious_reg(struct device *dev, unsigned int reg)
{
	switch (reg) {
	case CS35L56_DSP1_XMEM_PACKED_0 ... CS35L56_DSP1_XMEM_PACKED_6143:
	case CS35L56_DSP1_YMEM_PACKED_0 ... CS35L56_DSP1_YMEM_PACKED_4604:
	case CS35L56_DSP1_PMEM_0 ... CS35L56_DSP1_PMEM_5114:
		return true;
	default:
		return false;
	}
}

static bool cs35l56_volatile_reg(struct device *dev, unsigned int reg)
{
	switch (reg) {
	case CS35L56_DEVID:
	case CS35L56_REVID:
	case CS35L56_RELID:
	case CS35L56_OTPID:
	case CS35L56_SFT_RESET:
	case CS35L56_GLOBAL_ENABLES:		   /* owned by firmware */
	case CS35L56_BLOCK_ENABLES:		   /* owned by firmware */
	case CS35L56_BLOCK_ENABLES2:		   /* owned by firmware */
	case CS35L56_REFCLK_INPUT:		   /* owned by firmware */
	case CS35L56_GLOBAL_SAMPLE_RATE:	   /* owned by firmware */
	case CS35L56_DACPCM1_INPUT:		   /* owned by firmware */
	case CS35L56_DACPCM2_INPUT:		   /* owned by firmware */
	case CS35L56_DSP1RX1_INPUT:		   /* owned by firmware */
	case CS35L56_DSP1RX2_INPUT:		   /* owned by firmware */
	case CS35L56_IRQ1_STATUS:
	case CS35L56_IRQ1_EINT_1 ... CS35L56_IRQ1_EINT_8:
	case CS35L56_IRQ1_EINT_18:
	case CS35L56_IRQ1_EINT_20:
	case CS35L56_DSP_VIRTUAL1_MBOX_1:
	case CS35L56_DSP_VIRTUAL1_MBOX_2:
	case CS35L56_DSP_VIRTUAL1_MBOX_3:
	case CS35L56_DSP_VIRTUAL1_MBOX_4:
	case CS35L56_DSP_VIRTUAL1_MBOX_5:
	case CS35L56_DSP_VIRTUAL1_MBOX_6:
	case CS35L56_DSP_VIRTUAL1_MBOX_7:
	case CS35L56_DSP_VIRTUAL1_MBOX_8:
	case CS35L56_DSP_RESTRICT_STS1:
	case CS35L56_DSP1_SYS_INFO_ID ... CS35L56_DSP1_SYS_INFO_END:
	case CS35L56_DSP1_AHBM_WINDOW_DEBUG_0:
	case CS35L56_DSP1_AHBM_WINDOW_DEBUG_1:
	case CS35L56_DSP1_SCRATCH1:
	case CS35L56_DSP1_SCRATCH2:
	case CS35L56_DSP1_SCRATCH3:
	case CS35L56_DSP1_SCRATCH4:
		return true;
	case CS35L56_MAIN_RENDER_USER_MUTE:
	case CS35L56_MAIN_RENDER_USER_VOLUME:
	case CS35L56_MAIN_POSTURE_NUMBER:
		return false;
	default:
		return cs35l56_is_dsp_memory(reg);
	}
}

/*
 * The firmware boot sequence can overwrite the ASP1 config registers so that
 * they don't match regmap's view of their values. Rewrite the values from the
 * regmap cache into the hardware registers.
 */
int cs35l56_force_sync_asp1_registers_from_cache(struct cs35l56_base *cs35l56_base)
{
	struct reg_sequence asp1_regs[] = {
		{ .reg = CS35L56_ASP1_ENABLES1 },
		{ .reg = CS35L56_ASP1_CONTROL1 },
		{ .reg = CS35L56_ASP1_CONTROL2 },
		{ .reg = CS35L56_ASP1_CONTROL3 },
		{ .reg = CS35L56_ASP1_FRAME_CONTROL1 },
		{ .reg = CS35L56_ASP1_FRAME_CONTROL5 },
		{ .reg = CS35L56_ASP1_DATA_CONTROL1 },
		{ .reg = CS35L56_ASP1_DATA_CONTROL5 },
	};
	int i, ret;

	/* Read values from regmap cache into a write sequence */
	for (i = 0; i < ARRAY_SIZE(asp1_regs); ++i) {
		ret = regmap_read(cs35l56_base->regmap, asp1_regs[i].reg, &asp1_regs[i].def);
		if (ret)
			goto err;
	}

	/* Write the values cache-bypassed so that they will be written to silicon */
	ret = regmap_multi_reg_write_bypassed(cs35l56_base->regmap, asp1_regs,
					      ARRAY_SIZE(asp1_regs));
	if (ret)
		goto err;

	return 0;

err:
	dev_err(cs35l56_base->dev, "Failed to sync ASP1 registers: %d\n", ret);

	return ret;
}
EXPORT_SYMBOL_NS_GPL(cs35l56_force_sync_asp1_registers_from_cache, SND_SOC_CS35L56_SHARED);

int cs35l56_mbox_send(struct cs35l56_base *cs35l56_base, unsigned int command)
{
	unsigned int val;
	int ret;

	regmap_write(cs35l56_base->regmap, CS35L56_DSP_VIRTUAL1_MBOX_1, command);
	ret = regmap_read_poll_timeout(cs35l56_base->regmap, CS35L56_DSP_VIRTUAL1_MBOX_1,
				       val, (val == 0),
				       CS35L56_MBOX_POLL_US, CS35L56_MBOX_TIMEOUT_US);
	if (ret) {
		dev_warn(cs35l56_base->dev, "MBOX command %#x failed: %d\n", command, ret);
		return ret;
	}

	return 0;
}
EXPORT_SYMBOL_NS_GPL(cs35l56_mbox_send, SND_SOC_CS35L56_SHARED);

int cs35l56_firmware_shutdown(struct cs35l56_base *cs35l56_base)
{
	int ret;
	unsigned int reg;
	unsigned int val;

	ret = cs35l56_mbox_send(cs35l56_base, CS35L56_MBOX_CMD_SHUTDOWN);
	if (ret)
		return ret;

	if (cs35l56_base->rev < CS35L56_REVID_B0)
		reg = CS35L56_DSP1_PM_CUR_STATE_A1;
	else
		reg = CS35L56_DSP1_PM_CUR_STATE;

	ret = regmap_read_poll_timeout(cs35l56_base->regmap,  reg,
				       val, (val == CS35L56_HALO_STATE_SHUTDOWN),
				       CS35L56_HALO_STATE_POLL_US,
				       CS35L56_HALO_STATE_TIMEOUT_US);
	if (ret < 0)
		dev_err(cs35l56_base->dev, "Failed to poll PM_CUR_STATE to 1 is %d (ret %d)\n",
			val, ret);
	return ret;
}
EXPORT_SYMBOL_NS_GPL(cs35l56_firmware_shutdown, SND_SOC_CS35L56_SHARED);

int cs35l56_wait_for_firmware_boot(struct cs35l56_base *cs35l56_base)
{
	unsigned int reg;
	unsigned int val = 0;
	int read_ret, poll_ret;

	if (cs35l56_base->rev < CS35L56_REVID_B0)
		reg = CS35L56_DSP1_HALO_STATE_A1;
	else
		reg = CS35L56_DSP1_HALO_STATE;

	/*
	 * This can't be a regmap_read_poll_timeout() because cs35l56 will NAK
	 * I2C until it has booted which would terminate the poll
	 */
	poll_ret = read_poll_timeout(regmap_read, read_ret,
				     (val < 0xFFFF) && (val >= CS35L56_HALO_STATE_BOOT_DONE),
				     CS35L56_HALO_STATE_POLL_US,
				     CS35L56_HALO_STATE_TIMEOUT_US,
				     false,
				     cs35l56_base->regmap, reg, &val);

	if (poll_ret) {
		dev_err(cs35l56_base->dev, "Firmware boot timed out(%d): HALO_STATE=%#x\n",
			read_ret, val);
		return -EIO;
	}

	return 0;
}
EXPORT_SYMBOL_NS_GPL(cs35l56_wait_for_firmware_boot, SND_SOC_CS35L56_SHARED);

void cs35l56_wait_control_port_ready(void)
{
	/* Wait for control port to be ready (datasheet tIRS). */
	usleep_range(CS35L56_CONTROL_PORT_READY_US, 2 * CS35L56_CONTROL_PORT_READY_US);
}
EXPORT_SYMBOL_NS_GPL(cs35l56_wait_control_port_ready, SND_SOC_CS35L56_SHARED);

void cs35l56_wait_min_reset_pulse(void)
{
	/* Satisfy minimum reset pulse width spec */
	usleep_range(CS35L56_RESET_PULSE_MIN_US, 2 * CS35L56_RESET_PULSE_MIN_US);
}
EXPORT_SYMBOL_NS_GPL(cs35l56_wait_min_reset_pulse, SND_SOC_CS35L56_SHARED);

static const struct reg_sequence cs35l56_system_reset_seq[] = {
	REG_SEQ0(CS35L56_DSP1_HALO_STATE, 0),
	REG_SEQ0(CS35L56_DSP_VIRTUAL1_MBOX_1, CS35L56_MBOX_CMD_SYSTEM_RESET),
};

void cs35l56_system_reset(struct cs35l56_base *cs35l56_base, bool is_soundwire)
{
	/*
	 * Must enter cache-only first so there can't be any more register
	 * accesses other than the controlled system reset sequence below.
	 */
	regcache_cache_only(cs35l56_base->regmap, true);
	regmap_multi_reg_write_bypassed(cs35l56_base->regmap,
					cs35l56_system_reset_seq,
					ARRAY_SIZE(cs35l56_system_reset_seq));

	/* On SoundWire the registers won't be accessible until it re-enumerates. */
	if (is_soundwire)
		return;

	cs35l56_wait_control_port_ready();
	regcache_cache_only(cs35l56_base->regmap, false);
}
EXPORT_SYMBOL_NS_GPL(cs35l56_system_reset, SND_SOC_CS35L56_SHARED);

int cs35l56_irq_request(struct cs35l56_base *cs35l56_base, int irq)
{
	int ret;

	if (!irq)
		return 0;

	ret = devm_request_threaded_irq(cs35l56_base->dev, irq, NULL, cs35l56_irq,
					IRQF_ONESHOT | IRQF_SHARED | IRQF_TRIGGER_LOW,
					"cs35l56", cs35l56_base);
	if (!ret)
		cs35l56_base->irq = irq;
	else
		dev_err(cs35l56_base->dev, "Failed to get IRQ: %d\n", ret);

	return ret;
}
EXPORT_SYMBOL_NS_GPL(cs35l56_irq_request, SND_SOC_CS35L56_SHARED);

irqreturn_t cs35l56_irq(int irq, void *data)
{
	struct cs35l56_base *cs35l56_base = data;
	unsigned int status1 = 0, status8 = 0, status20 = 0;
	unsigned int mask1, mask8, mask20;
	unsigned int val;
	int rv;

	irqreturn_t ret = IRQ_NONE;

	if (!cs35l56_base->init_done)
		return IRQ_NONE;

	mutex_lock(&cs35l56_base->irq_lock);

	rv = pm_runtime_resume_and_get(cs35l56_base->dev);
	if (rv < 0) {
		dev_err(cs35l56_base->dev, "irq: failed to get pm_runtime: %d\n", rv);
		goto err_unlock;
	}

	regmap_read(cs35l56_base->regmap, CS35L56_IRQ1_STATUS, &val);
	if ((val & CS35L56_IRQ1_STS_MASK) == 0) {
		dev_dbg(cs35l56_base->dev, "Spurious IRQ: no pending interrupt\n");
		goto err;
	}

	/* Ack interrupts */
	regmap_read(cs35l56_base->regmap, CS35L56_IRQ1_EINT_1, &status1);
	regmap_read(cs35l56_base->regmap, CS35L56_IRQ1_MASK_1, &mask1);
	status1 &= ~mask1;
	regmap_write(cs35l56_base->regmap, CS35L56_IRQ1_EINT_1, status1);

	regmap_read(cs35l56_base->regmap, CS35L56_IRQ1_EINT_8, &status8);
	regmap_read(cs35l56_base->regmap, CS35L56_IRQ1_MASK_8, &mask8);
	status8 &= ~mask8;
	regmap_write(cs35l56_base->regmap, CS35L56_IRQ1_EINT_8, status8);

	regmap_read(cs35l56_base->regmap, CS35L56_IRQ1_EINT_20, &status20);
	regmap_read(cs35l56_base->regmap, CS35L56_IRQ1_MASK_20, &mask20);
	status20 &= ~mask20;
	/* We don't want EINT20 but they default to unmasked: force mask */
	regmap_write(cs35l56_base->regmap, CS35L56_IRQ1_MASK_20, 0xffffffff);

	dev_dbg(cs35l56_base->dev, "%s: %#x %#x\n", __func__, status1, status8);

	/* Check to see if unmasked bits are active */
	if (!status1 && !status8 && !status20)
		goto err;

	if (status1 & CS35L56_AMP_SHORT_ERR_EINT1_MASK)
		dev_crit(cs35l56_base->dev, "Amp short error\n");

	if (status8 & CS35L56_TEMP_ERR_EINT1_MASK)
		dev_crit(cs35l56_base->dev, "Overtemp error\n");

	ret = IRQ_HANDLED;

err:
	pm_runtime_put(cs35l56_base->dev);
err_unlock:
	mutex_unlock(&cs35l56_base->irq_lock);

	return ret;
}
EXPORT_SYMBOL_NS_GPL(cs35l56_irq, SND_SOC_CS35L56_SHARED);

int cs35l56_is_fw_reload_needed(struct cs35l56_base *cs35l56_base)
{
	unsigned int val;
	int ret;

	/*
	 * In secure mode FIRMWARE_MISSING is cleared by the BIOS loader so
	 * can't be used here to test for memory retention.
	 * Assume that tuning must be re-loaded.
	 */
	if (cs35l56_base->secured)
		return true;

	ret = pm_runtime_resume_and_get(cs35l56_base->dev);
	if (ret) {
		dev_err(cs35l56_base->dev, "Failed to runtime_get: %d\n", ret);
		return ret;
	}

	ret = regmap_read(cs35l56_base->regmap, CS35L56_PROTECTION_STATUS, &val);
	if (ret)
		dev_err(cs35l56_base->dev, "Failed to read PROTECTION_STATUS: %d\n", ret);
	else
		ret = !!(val & CS35L56_FIRMWARE_MISSING);

	pm_runtime_put_autosuspend(cs35l56_base->dev);

	return ret;
}
EXPORT_SYMBOL_NS_GPL(cs35l56_is_fw_reload_needed, SND_SOC_CS35L56_SHARED);

static const struct reg_sequence cs35l56_hibernate_seq[] = {
	/* This must be the last register access */
	REG_SEQ0(CS35L56_DSP_VIRTUAL1_MBOX_1, CS35L56_MBOX_CMD_ALLOW_AUTO_HIBERNATE),
};

static const struct reg_sequence cs35l56_hibernate_wake_seq[] = {
	REG_SEQ0(CS35L56_DSP_VIRTUAL1_MBOX_1, CS35L56_MBOX_CMD_WAKEUP),
};

static void cs35l56_issue_wake_event(struct cs35l56_base *cs35l56_base)
{
	/*
	 * Dummy transactions to trigger I2C/SPI auto-wake. Issue two
	 * transactions to meet the minimum required time from the rising edge
	 * to the last falling edge of wake.
	 *
	 * It uses bypassed write because we must wake the chip before
	 * disabling regmap cache-only.
	 *
	 * This can NAK on I2C which will terminate the write sequence so the
	 * single-write sequence is issued twice.
	 */
	regmap_multi_reg_write_bypassed(cs35l56_base->regmap,
					cs35l56_hibernate_wake_seq,
					ARRAY_SIZE(cs35l56_hibernate_wake_seq));

	usleep_range(CS35L56_WAKE_HOLD_TIME_US, 2 * CS35L56_WAKE_HOLD_TIME_US);

	regmap_multi_reg_write_bypassed(cs35l56_base->regmap,
					cs35l56_hibernate_wake_seq,
					ARRAY_SIZE(cs35l56_hibernate_wake_seq));

	cs35l56_wait_control_port_ready();
}

int cs35l56_runtime_suspend_common(struct cs35l56_base *cs35l56_base)
{
	unsigned int val;
	int ret;

	if (!cs35l56_base->init_done)
		return 0;

	/* Firmware must have entered a power-save state */
	ret = regmap_read_poll_timeout(cs35l56_base->regmap,
				       CS35L56_TRANSDUCER_ACTUAL_PS,
				       val, (val >= CS35L56_PS3),
				       CS35L56_PS3_POLL_US,
				       CS35L56_PS3_TIMEOUT_US);
	if (ret)
		dev_warn(cs35l56_base->dev, "PS3 wait failed: %d\n", ret);

	/* Clear BOOT_DONE so it can be used to detect a reboot */
	regmap_write(cs35l56_base->regmap, CS35L56_IRQ1_EINT_4, CS35L56_OTP_BOOT_DONE_MASK);

	if (!cs35l56_base->can_hibernate) {
		regcache_cache_only(cs35l56_base->regmap, true);
		dev_dbg(cs35l56_base->dev, "Suspended: no hibernate");

		return 0;
	}

	/*
	 * Must enter cache-only first so there can't be any more register
	 * accesses other than the controlled hibernate sequence below.
	 */
	regcache_cache_only(cs35l56_base->regmap, true);

	regmap_multi_reg_write_bypassed(cs35l56_base->regmap,
					cs35l56_hibernate_seq,
					ARRAY_SIZE(cs35l56_hibernate_seq));

	dev_dbg(cs35l56_base->dev, "Suspended: hibernate");

	return 0;
}
EXPORT_SYMBOL_NS_GPL(cs35l56_runtime_suspend_common, SND_SOC_CS35L56_SHARED);

int cs35l56_runtime_resume_common(struct cs35l56_base *cs35l56_base, bool is_soundwire)
{
	unsigned int val;
	int ret;

	if (!cs35l56_base->init_done)
		return 0;

	if (!cs35l56_base->can_hibernate)
		goto out_sync;

	/* Must be done before releasing cache-only */
	if (!is_soundwire)
		cs35l56_issue_wake_event(cs35l56_base);

out_sync:
	regcache_cache_only(cs35l56_base->regmap, false);

	ret = cs35l56_wait_for_firmware_boot(cs35l56_base);
	if (ret) {
		dev_err(cs35l56_base->dev, "Hibernate wake failed: %d\n", ret);
		goto err;
	}

	ret = cs35l56_mbox_send(cs35l56_base, CS35L56_MBOX_CMD_PREVENT_AUTO_HIBERNATE);
	if (ret)
		goto err;

	/* BOOT_DONE will be 1 if the amp reset */
	regmap_read(cs35l56_base->regmap, CS35L56_IRQ1_EINT_4, &val);
	if (val & CS35L56_OTP_BOOT_DONE_MASK) {
		dev_dbg(cs35l56_base->dev, "Registers reset in suspend\n");
		regcache_mark_dirty(cs35l56_base->regmap);
	}

	regcache_sync(cs35l56_base->regmap);

	dev_dbg(cs35l56_base->dev, "Resumed");

	return 0;

err:
	regcache_cache_only(cs35l56_base->regmap, true);

	regmap_multi_reg_write_bypassed(cs35l56_base->regmap,
					cs35l56_hibernate_seq,
					ARRAY_SIZE(cs35l56_hibernate_seq));

	return ret;
}
EXPORT_SYMBOL_NS_GPL(cs35l56_runtime_resume_common, SND_SOC_CS35L56_SHARED);

static const struct cs_dsp_region cs35l56_dsp1_regions[] = {
	{ .type = WMFW_HALO_PM_PACKED,	.base = CS35L56_DSP1_PMEM_0 },
	{ .type = WMFW_HALO_XM_PACKED,	.base = CS35L56_DSP1_XMEM_PACKED_0 },
	{ .type = WMFW_HALO_YM_PACKED,	.base = CS35L56_DSP1_YMEM_PACKED_0 },
	{ .type = WMFW_ADSP2_XM,	.base = CS35L56_DSP1_XMEM_UNPACKED24_0 },
	{ .type = WMFW_ADSP2_YM,	.base = CS35L56_DSP1_YMEM_UNPACKED24_0 },
};

void cs35l56_init_cs_dsp(struct cs35l56_base *cs35l56_base, struct cs_dsp *cs_dsp)
{
	cs_dsp->num = 1;
	cs_dsp->type = WMFW_HALO;
	cs_dsp->rev = 0;
	cs_dsp->dev = cs35l56_base->dev;
	cs_dsp->regmap = cs35l56_base->regmap;
	cs_dsp->base = CS35L56_DSP1_CORE_BASE;
	cs_dsp->base_sysinfo = CS35L56_DSP1_SYS_INFO_ID;
	cs_dsp->mem = cs35l56_dsp1_regions;
	cs_dsp->num_mems = ARRAY_SIZE(cs35l56_dsp1_regions);
	cs_dsp->no_core_startstop = true;
}
EXPORT_SYMBOL_NS_GPL(cs35l56_init_cs_dsp, SND_SOC_CS35L56_SHARED);

struct cs35l56_pte {
	u8 x;
	u8 wafer_id;
	u8 pte[2];
	u8 lot[3];
	u8 y;
	u8 unused[3];
	u8 dvs;
} __packed;
static_assert((sizeof(struct cs35l56_pte) % sizeof(u32)) == 0);

static int cs35l56_read_silicon_uid(struct cs35l56_base *cs35l56_base, u64 *uid)
{
	struct cs35l56_pte pte;
	u64 unique_id;
	int ret;

	ret = regmap_raw_read(cs35l56_base->regmap, CS35L56_OTP_MEM_53, &pte, sizeof(pte));
	if (ret) {
		dev_err(cs35l56_base->dev, "Failed to read OTP: %d\n", ret);
		return ret;
	}

	unique_id = (u32)pte.lot[2] | ((u32)pte.lot[1] << 8) | ((u32)pte.lot[0] << 16);
	unique_id <<= 32;
	unique_id |= (u32)pte.x | ((u32)pte.y << 8) | ((u32)pte.wafer_id << 16) |
		     ((u32)pte.dvs << 24);

	dev_dbg(cs35l56_base->dev, "UniqueID = %#llx\n", unique_id);

	*uid = unique_id;

	return 0;
}

/* Firmware calibration controls */
const struct cirrus_amp_cal_controls cs35l56_calibration_controls = {
	.alg_id =	0x9f210,
	.mem_region =	WMFW_ADSP2_YM,
	.ambient =	"CAL_AMBIENT",
	.calr =		"CAL_R",
	.status =	"CAL_STATUS",
	.checksum =	"CAL_CHECKSUM",
};
EXPORT_SYMBOL_NS_GPL(cs35l56_calibration_controls, SND_SOC_CS35L56_SHARED);

int cs35l56_get_calibration(struct cs35l56_base *cs35l56_base)
{
	u64 silicon_uid;
	int ret;

	/* Driver can't apply calibration to a secured part, so skip */
	if (cs35l56_base->secured)
		return 0;

	ret = cs35l56_read_silicon_uid(cs35l56_base, &silicon_uid);
	if (ret < 0)
		return ret;

	ret = cs_amp_get_efi_calibration_data(cs35l56_base->dev, silicon_uid,
					      cs35l56_base->cal_index,
					      &cs35l56_base->cal_data);

	/* Only return an error status if probe should be aborted */
	if ((ret == -ENOENT) || (ret == -EOVERFLOW))
		return 0;

	if (ret < 0)
		return ret;

	cs35l56_base->cal_data_valid = true;

	return 0;
}
EXPORT_SYMBOL_NS_GPL(cs35l56_get_calibration, SND_SOC_CS35L56_SHARED);

int cs35l56_read_prot_status(struct cs35l56_base *cs35l56_base,
			     bool *fw_missing, unsigned int *fw_version)
{
	unsigned int prot_status;
	int ret;

	ret = regmap_read(cs35l56_base->regmap, CS35L56_PROTECTION_STATUS, &prot_status);
	if (ret) {
		dev_err(cs35l56_base->dev, "Get PROTECTION_STATUS failed: %d\n", ret);
		return ret;
	}

	*fw_missing = !!(prot_status & CS35L56_FIRMWARE_MISSING);

	ret = regmap_read(cs35l56_base->regmap, CS35L56_DSP1_FW_VER, fw_version);
	if (ret) {
		dev_err(cs35l56_base->dev, "Get FW VER failed: %d\n", ret);
		return ret;
	}

	return 0;
}
EXPORT_SYMBOL_NS_GPL(cs35l56_read_prot_status, SND_SOC_CS35L56_SHARED);

int cs35l56_hw_init(struct cs35l56_base *cs35l56_base)
{
	int ret;
	unsigned int devid, revid, otpid, secured, fw_ver;
	bool fw_missing;

	/*
	 * When the system is not using a reset_gpio ensure the device is
	 * awake, otherwise the device has just been released from reset and
	 * the driver must wait for the control port to become usable.
	 */
	if (!cs35l56_base->reset_gpio)
		cs35l56_issue_wake_event(cs35l56_base);
	else
		cs35l56_wait_control_port_ready();

	/*
	 * The HALO_STATE register is in different locations on Ax and B0
	 * devices so the REVID needs to be determined before waiting for the
	 * firmware to boot.
	 */
	ret = regmap_read(cs35l56_base->regmap, CS35L56_REVID, &revid);
	if (ret < 0) {
		dev_err(cs35l56_base->dev, "Get Revision ID failed\n");
		return ret;
	}
	cs35l56_base->rev = revid & (CS35L56_AREVID_MASK | CS35L56_MTLREVID_MASK);

	ret = cs35l56_wait_for_firmware_boot(cs35l56_base);
	if (ret)
		return ret;

	ret = regmap_read(cs35l56_base->regmap, CS35L56_DEVID, &devid);
	if (ret < 0) {
		dev_err(cs35l56_base->dev, "Get Device ID failed\n");
		return ret;
	}
	devid &= CS35L56_DEVID_MASK;

	switch (devid) {
	case 0x35A54:
	case 0x35A56:
	case 0x35A57:
		break;
	default:
		dev_err(cs35l56_base->dev, "Unknown device %x\n", devid);
		return ret;
	}

	cs35l56_base->type = devid & 0xFF;

	ret = regmap_read(cs35l56_base->regmap, CS35L56_DSP_RESTRICT_STS1, &secured);
	if (ret) {
		dev_err(cs35l56_base->dev, "Get Secure status failed\n");
		return ret;
	}

	/* When any bus is restricted treat the device as secured */
	if (secured & CS35L56_RESTRICTED_MASK)
		cs35l56_base->secured = true;

	ret = regmap_read(cs35l56_base->regmap, CS35L56_OTPID, &otpid);
	if (ret < 0) {
		dev_err(cs35l56_base->dev, "Get OTP ID failed\n");
		return ret;
	}

	ret = cs35l56_read_prot_status(cs35l56_base, &fw_missing, &fw_ver);
	if (ret)
		return ret;

	dev_info(cs35l56_base->dev, "Cirrus Logic CS35L%02X%s Rev %02X OTP%d fw:%d.%d.%d (patched=%u)\n",
		 cs35l56_base->type, cs35l56_base->secured ? "s" : "", cs35l56_base->rev, otpid,
		 fw_ver >> 16, (fw_ver >> 8) & 0xff, fw_ver & 0xff, !fw_missing);

	/* Wake source and *_BLOCKED interrupts default to unmasked, so mask them */
	regmap_write(cs35l56_base->regmap, CS35L56_IRQ1_MASK_20, 0xffffffff);
	regmap_update_bits(cs35l56_base->regmap, CS35L56_IRQ1_MASK_1,
			   CS35L56_AMP_SHORT_ERR_EINT1_MASK,
			   0);
	regmap_update_bits(cs35l56_base->regmap, CS35L56_IRQ1_MASK_8,
			   CS35L56_TEMP_ERR_EINT1_MASK,
			   0);

	return 0;
}
EXPORT_SYMBOL_NS_GPL(cs35l56_hw_init, SND_SOC_CS35L56_SHARED);

int cs35l56_get_speaker_id(struct cs35l56_base *cs35l56_base)
{
	struct gpio_descs *descs;
	int speaker_id;
	int i, ret;

	/* Read the speaker type qualifier from the motherboard GPIOs */
	descs = gpiod_get_array_optional(cs35l56_base->dev, "spk-id", GPIOD_IN);
	if (!descs) {
		return -ENOENT;
	} else if (IS_ERR(descs)) {
		ret = PTR_ERR(descs);
		return dev_err_probe(cs35l56_base->dev, ret, "Failed to get spk-id-gpios\n");
	}

	speaker_id = 0;
	for (i = 0; i < descs->ndescs; i++) {
		ret = gpiod_get_value_cansleep(descs->desc[i]);
		if (ret < 0) {
			dev_err_probe(cs35l56_base->dev, ret, "Failed to read spk-id[%d]\n", i);
			goto err;
		}

		speaker_id |= (ret << i);
	}

	dev_dbg(cs35l56_base->dev, "Speaker ID = %d\n", speaker_id);
	ret = speaker_id;
err:
	gpiod_put_array(descs);

	return ret;
}
EXPORT_SYMBOL_NS_GPL(cs35l56_get_speaker_id, SND_SOC_CS35L56_SHARED);

static const u32 cs35l56_bclk_valid_for_pll_freq_table[] = {
	[0x0C] = 128000,
	[0x0F] = 256000,
	[0x11] = 384000,
	[0x12] = 512000,
	[0x15] = 768000,
	[0x17] = 1024000,
	[0x1A] = 1500000,
	[0x1B] = 1536000,
	[0x1C] = 2000000,
	[0x1D] = 2048000,
	[0x1E] = 2400000,
	[0x20] = 3000000,
	[0x21] = 3072000,
	[0x23] = 4000000,
	[0x24] = 4096000,
	[0x25] = 4800000,
	[0x27] = 6000000,
	[0x28] = 6144000,
	[0x29] = 6250000,
	[0x2A] = 6400000,
	[0x2E] = 8000000,
	[0x2F] = 8192000,
	[0x30] = 9600000,
	[0x32] = 12000000,
	[0x33] = 12288000,
	[0x37] = 13500000,
	[0x38] = 19200000,
	[0x39] = 22579200,
	[0x3B] = 24576000,
};

int cs35l56_get_bclk_freq_id(unsigned int freq)
{
	int i;

	if (freq == 0)
		return -EINVAL;

	/* The BCLK frequency must be a valid PLL REFCLK */
	for (i = 0; i < ARRAY_SIZE(cs35l56_bclk_valid_for_pll_freq_table); ++i) {
		if (cs35l56_bclk_valid_for_pll_freq_table[i] == freq)
			return i;
	}

	return -EINVAL;
}
EXPORT_SYMBOL_NS_GPL(cs35l56_get_bclk_freq_id, SND_SOC_CS35L56_SHARED);

static const char * const cs35l56_supplies[/* auto-sized */] = {
	"VDD_P",
	"VDD_IO",
	"VDD_A",
};

void cs35l56_fill_supply_names(struct regulator_bulk_data *data)
{
	int i;

	BUILD_BUG_ON(ARRAY_SIZE(cs35l56_supplies) != CS35L56_NUM_BULK_SUPPLIES);
	for (i = 0; i < ARRAY_SIZE(cs35l56_supplies); i++)
		data[i].supply = cs35l56_supplies[i];
}
EXPORT_SYMBOL_NS_GPL(cs35l56_fill_supply_names, SND_SOC_CS35L56_SHARED);

const char * const cs35l56_tx_input_texts[] = {
	"None", "ASP1RX1", "ASP1RX2", "VMON", "IMON", "ERRVOL", "CLASSH",
	"VDDBMON", "VBSTMON", "DSP1TX1", "DSP1TX2", "DSP1TX3", "DSP1TX4",
	"DSP1TX5", "DSP1TX6", "DSP1TX7", "DSP1TX8", "TEMPMON",
	"INTERPOLATOR", "SDW1RX1", "SDW1RX2",
};
EXPORT_SYMBOL_NS_GPL(cs35l56_tx_input_texts, SND_SOC_CS35L56_SHARED);

const unsigned int cs35l56_tx_input_values[] = {
	CS35L56_INPUT_SRC_NONE,
	CS35L56_INPUT_SRC_ASP1RX1,
	CS35L56_INPUT_SRC_ASP1RX2,
	CS35L56_INPUT_SRC_VMON,
	CS35L56_INPUT_SRC_IMON,
	CS35L56_INPUT_SRC_ERR_VOL,
	CS35L56_INPUT_SRC_CLASSH,
	CS35L56_INPUT_SRC_VDDBMON,
	CS35L56_INPUT_SRC_VBSTMON,
	CS35L56_INPUT_SRC_DSP1TX1,
	CS35L56_INPUT_SRC_DSP1TX2,
	CS35L56_INPUT_SRC_DSP1TX3,
	CS35L56_INPUT_SRC_DSP1TX4,
	CS35L56_INPUT_SRC_DSP1TX5,
	CS35L56_INPUT_SRC_DSP1TX6,
	CS35L56_INPUT_SRC_DSP1TX7,
	CS35L56_INPUT_SRC_DSP1TX8,
	CS35L56_INPUT_SRC_TEMPMON,
	CS35L56_INPUT_SRC_INTERPOLATOR,
	CS35L56_INPUT_SRC_SWIRE_DP1_CHANNEL1,
	CS35L56_INPUT_SRC_SWIRE_DP1_CHANNEL2,
};
EXPORT_SYMBOL_NS_GPL(cs35l56_tx_input_values, SND_SOC_CS35L56_SHARED);

struct regmap_config cs35l56_regmap_i2c = {
	.reg_bits = 32,
	.val_bits = 32,
	.reg_stride = 4,
	.reg_format_endian = REGMAP_ENDIAN_BIG,
	.val_format_endian = REGMAP_ENDIAN_BIG,
	.max_register = CS35L56_DSP1_PMEM_5114,
	.reg_defaults = cs35l56_reg_defaults,
	.num_reg_defaults = ARRAY_SIZE(cs35l56_reg_defaults),
	.volatile_reg = cs35l56_volatile_reg,
	.readable_reg = cs35l56_readable_reg,
	.precious_reg = cs35l56_precious_reg,
	.cache_type = REGCACHE_MAPLE,
};
EXPORT_SYMBOL_NS_GPL(cs35l56_regmap_i2c, SND_SOC_CS35L56_SHARED);

struct regmap_config cs35l56_regmap_spi = {
	.reg_bits = 32,
	.val_bits = 32,
	.pad_bits = 16,
	.reg_stride = 4,
	.reg_format_endian = REGMAP_ENDIAN_BIG,
	.val_format_endian = REGMAP_ENDIAN_BIG,
	.max_register = CS35L56_DSP1_PMEM_5114,
	.reg_defaults = cs35l56_reg_defaults,
	.num_reg_defaults = ARRAY_SIZE(cs35l56_reg_defaults),
	.volatile_reg = cs35l56_volatile_reg,
	.readable_reg = cs35l56_readable_reg,
	.precious_reg = cs35l56_precious_reg,
	.cache_type = REGCACHE_MAPLE,
};
EXPORT_SYMBOL_NS_GPL(cs35l56_regmap_spi, SND_SOC_CS35L56_SHARED);

struct regmap_config cs35l56_regmap_sdw = {
	.reg_bits = 32,
	.val_bits = 32,
	.reg_stride = 4,
	.reg_format_endian = REGMAP_ENDIAN_LITTLE,
	.val_format_endian = REGMAP_ENDIAN_BIG,
	.max_register = CS35L56_DSP1_PMEM_5114,
	.reg_defaults = cs35l56_reg_defaults,
	.num_reg_defaults = ARRAY_SIZE(cs35l56_reg_defaults),
	.volatile_reg = cs35l56_volatile_reg,
	.readable_reg = cs35l56_readable_reg,
	.precious_reg = cs35l56_precious_reg,
	.cache_type = REGCACHE_MAPLE,
};
EXPORT_SYMBOL_NS_GPL(cs35l56_regmap_sdw, SND_SOC_CS35L56_SHARED);

MODULE_DESCRIPTION("ASoC CS35L56 Shared");
MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>");
MODULE_AUTHOR("Simon Trimmer <simont@opensource.cirrus.com>");
MODULE_LICENSE("GPL");
MODULE_IMPORT_NS(SND_SOC_CS_AMP_LIB);
