// SPDX-License-Identifier: GPL-2.0
/*
* CS42L43 core driver
*
* Copyright (C) 2022-2023 Cirrus Logic, Inc. and
* Cirrus Logic International Semiconductor Ltd.
*/
#include <linux/bitops.h>
#include <linux/build_bug.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/errno.h>
#include <linux/firmware.h>
#include <linux/jiffies.h>
#include <linux/mfd/core.h>
#include <linux/mfd/cs42l43-regs.h>
#include <linux/module.h>
#include <linux/pm_runtime.h>
#include <linux/soundwire/sdw.h>
#include "cs42l43.h"
#define CS42L43_RESET_DELAY 20
#define CS42L43_SDW_ATTACH_TIMEOUT 500
#define CS42L43_SDW_DETACH_TIMEOUT 100
#define CS42L43_MCU_BOOT_STAGE1 1
#define CS42L43_MCU_BOOT_STAGE2 2
#define CS42L43_MCU_BOOT_STAGE3 3
#define CS42L43_MCU_BOOT_STAGE4 4
#define CS42L43_MCU_POLL 5000
#define CS42L43_MCU_CMD_TIMEOUT 20000
#define CS42L43_MCU_UPDATE_FORMAT 3
#define CS42L43_MCU_UPDATE_OFFSET 0x100000
#define CS42L43_MCU_UPDATE_TIMEOUT 500000
#define CS42L43_MCU_UPDATE_RETRIES 5
#define CS42L43_MCU_SUPPORTED_REV 0x2105
#define CS42L43_MCU_SHADOW_REGS_REQUIRED_REV 0x2200
#define CS42L43_MCU_SUPPORTED_BIOS_REV 0x0001
#define CS42L43_VDDP_DELAY 50
#define CS42L43_VDDD_DELAY 1000
#define CS42L43_AUTOSUSPEND_TIME 250
struct cs42l43_patch_header {
__le16 version;
__le16 size;
u8 reserved;
u8 secure;
__le16 bss_size;
__le32 apply_addr;
__le32 checksum;
__le32 sha;
__le16 swrev;
__le16 patchid;
__le16 ipxid;
__le16 romver;
__le32 load_addr;
} __packed;
static const struct reg_sequence cs42l43_reva_patch[] = {
{ 0x4000, 0x00000055 },
{ 0x4000, 0x000000AA },
{ 0x10084, 0x00000000 },
{ 0x1741C, 0x00CD2000 },
{ 0x1718C, 0x00000003 },
{ 0x4000, 0x00000000 },
{ CS42L43_CCM_BLK_CLK_CONTROL, 0x00000002 },
{ CS42L43_HPPATHVOL, 0x011B011B },
{ CS42L43_OSC_DIV_SEL, 0x00000001 },
{ CS42L43_DACCNFG2, 0x00000005 },
{ CS42L43_MIC_DETECT_CONTROL_ANDROID, 0x80790079 },
{ CS42L43_RELID, 0x0000000F },
};
const struct reg_default cs42l43_reg_default[CS42L43_N_DEFAULTS] = {
{ CS42L43_DRV_CTRL1, 0x000186C0 },
{ CS42L43_DRV_CTRL3, 0x286DB018 },
{ CS42L43_DRV_CTRL4, 0x000006D8 },
{ CS42L43_DRV_CTRL_5, 0x136C00C0 },
{ CS42L43_GPIO_CTRL1, 0x00000707 },
{ CS42L43_GPIO_CTRL2, 0x00000000 },
{ CS42L43_GPIO_FN_SEL, 0x00000000 },
{ CS42L43_MCLK_SRC_SEL, 0x00000000 },
{ CS42L43_SAMPLE_RATE1, 0x00000003 },
{ CS42L43_SAMPLE_RATE2, 0x00000003 },
{ CS42L43_SAMPLE_RATE3, 0x00000003 },
{ CS42L43_SAMPLE_RATE4, 0x00000003 },
{ CS42L43_PLL_CONTROL, 0x00000000 },
{ CS42L43_FS_SELECT1, 0x00000000 },
{ CS42L43_FS_SELECT2, 0x00000000 },
{ CS42L43_FS_SELECT3, 0x00000000 },
{ CS42L43_FS_SELECT4, 0x00000000 },
{ CS42L43_PDM_CONTROL, 0x00000000 },
{ CS42L43_ASP_CLK_CONFIG1, 0x00010001 },
{ CS42L43_ASP_CLK_CONFIG2, 0x00000000 },
{ CS42L43_OSC_DIV_SEL, 0x00000001 },
{ CS42L43_ADC_B_CTRL1, 0x00000000 },
{ CS42L43_ADC_B_CTRL2, 0x00000000 },
{ CS42L43_DECIM_HPF_WNF_CTRL1, 0x00000001 },
{ CS42L43_DECIM_HPF_WNF_CTRL2, 0x00000001 },
{ CS42L43_DECIM_HPF_WNF_CTRL3, 0x00000001 },
{ CS42L43_DECIM_HPF_WNF_CTRL4, 0x00000001 },
{ CS42L43_DMIC_PDM_CTRL, 0x00000000 },
{ CS42L43_DECIM_VOL_CTRL_CH1_CH2, 0x20122012 },
{ CS42L43_DECIM_VOL_CTRL_CH3_CH4, 0x20122012 },
{ CS42L43_INTP_VOLUME_CTRL1, 0x00000180 },
{ CS42L43_INTP_VOLUME_CTRL2, 0x00000180 },
{ CS42L43_AMP1_2_VOL_RAMP, 0x00000022 },
{ CS42L43_ASP_CTRL, 0x00000004 },
{ CS42L43_ASP_FSYNC_CTRL1, 0x000000FA },
{ CS42L43_ASP_FSYNC_CTRL2, 0x00000001 },
{ CS42L43_ASP_FSYNC_CTRL3, 0x00000000 },
{ CS42L43_ASP_FSYNC_CTRL4, 0x000001F4 },
{ CS42L43_ASP_DATA_CTRL, 0x0000003A },
{ CS42L43_ASP_RX_EN, 0x00000000 },
{ CS42L43_ASP_TX_EN, 0x00000000 },
{ CS42L43_ASP_RX_CH1_CTRL, 0x00170001 },
{ CS42L43_ASP_RX_CH2_CTRL, 0x00170031 },
{ CS42L43_ASP_RX_CH3_CTRL, 0x00170061 },
{ CS42L43_ASP_RX_CH4_CTRL, 0x00170091 },
{ CS42L43_ASP_RX_CH5_CTRL, 0x001700C1 },
{ CS42L43_ASP_RX_CH6_CTRL, 0x001700F1 },
{ CS42L43_ASP_TX_CH1_CTRL, 0x00170001 },
{ CS42L43_ASP_TX_CH2_CTRL, 0x00170031 },
{ CS42L43_ASP_TX_CH3_CTRL, 0x00170061 },
{ CS42L43_ASP_TX_CH4_CTRL, 0x00170091 },
{ CS42L43_ASP_TX_CH5_CTRL, 0x001700C1 },
{ CS42L43_ASP_TX_CH6_CTRL, 0x001700F1 },
{ CS42L43_ASPTX1_INPUT, 0x00800000 },
{ CS42L43_ASPTX2_INPUT, 0x00800000 },
{ CS42L43_ASPTX3_INPUT, 0x00800000 },
{ CS42L43_ASPTX4_INPUT, 0x00800000 },
{ CS42L43_ASPTX