File Index
Files and directories
Sign in
FILE

cs35l56-shared.c

File preview with syntax highlighting.

linux-6.19.14/sound/soc/codecs/cs35l56-shared.c C
   1// SPDX-License-Identifier: GPL-2.0-only
   2//
   3// Components shared between ASoC and HDA CS35L56 drivers
   4//
   5// Copyright (C) 2023 Cirrus Logic, Inc. and
   6//                    Cirrus Logic International Semiconductor Ltd.
   7
   8#include <linux/array_size.h>
   9#include <linux/cleanup.h>
  10#include <linux/debugfs.h>
  11#include <linux/firmware/cirrus/wmfw.h>
  12#include <linux/fs.h>
  13#include <linux/gpio/consumer.h>
  14#include <linux/kstrtox.h>
  15#include <linux/regmap.h>
  16#include <linux/regulator/consumer.h>
  17#include <linux/spi/spi.h>
  18#include <linux/stddef.h>
  19#include <linux/string.h>
  20#include <linux/string_choices.h>
  21#include <linux/types.h>
  22#include <sound/cs-amp-lib.h>
  23
  24#include "cs35l56.h"
  25
  26static const struct reg_sequence cs35l56_asp_patch[] = {
  27	/*
  28	 * Firmware can change these to non-defaults to satisfy SDCA.
  29	 * Ensure that they are at known defaults.
  30	 */
  31	{ CS35L56_ASP1_ENABLES1,		0x00000000 },
  32	{ CS35L56_ASP1_CONTROL1,		0x00000028 },
  33	{ CS35L56_ASP1_CONTROL2,		0x18180200 },
  34	{ CS35L56_ASP1_CONTROL3,		0x00000002 },
  35	{ CS35L56_ASP1_FRAME_CONTROL1,		0x03020100 },
  36	{ CS35L56_ASP1_FRAME_CONTROL5,		0x00020100 },
  37	{ CS35L56_ASP1_DATA_CONTROL1,		0x00000018 },
  38	{ CS35L56_ASP1_DATA_CONTROL5,		0x00000018 },
  39	{ CS35L56_ASP1TX1_INPUT,		0x00000000 },
  40	{ CS35L56_ASP1TX2_INPUT,		0x00000000 },
  41	{ CS35L56_ASP1TX3_INPUT,		0x00000000 },
  42	{ CS35L56_ASP1TX4_INPUT,		0x00000000 },
  43};
  44
  45int cs35l56_set_asp_patch(struct cs35l56_base *cs35l56_base)
  46{
  47	return regmap_register_patch(cs35l56_base->regmap, cs35l56_asp_patch,
  48				     ARRAY_SIZE(cs35l56_asp_patch));
  49}
  50EXPORT_SYMBOL_NS_GPL(cs35l56_set_asp_patch, "SND_SOC_CS35L56_SHARED");
  51
  52static const struct reg_sequence cs35l56_patch[] = {
  53	/*
  54	 * Firmware can change these to non-defaults to satisfy SDCA.
  55	 * Ensure that they are at known defaults.
  56	 */
  57	{ CS35L56_SWIRE_DP3_CH1_INPUT,		0x00000018 },
  58	{ CS35L56_SWIRE_DP3_CH2_INPUT,		0x00000019 },
  59	{ CS35L56_SWIRE_DP3_CH3_INPUT,		0x00000029 },
  60	{ CS35L56_SWIRE_DP3_CH4_INPUT,		0x00000028 },
  61	{ CS35L56_IRQ1_MASK_18,			0x1f7df0ff },
  62};
  63
  64static const struct reg_sequence cs35l56_patch_fw[] = {
  65	/* These are not reset by a soft-reset, so patch to defaults. */
  66	{ CS35L56_MAIN_RENDER_USER_MUTE,	0x00000000 },
  67	{ CS35L56_MAIN_RENDER_USER_VOLUME,	0x00000000 },
  68	{ CS35L56_MAIN_POSTURE_NUMBER,		0x00000000 },
  69};
  70
  71static const struct reg_sequence cs35l63_patch_fw[] = {
  72	/* These are not reset by a soft-reset, so patch to defaults. */
  73	{ CS35L63_MAIN_RENDER_USER_MUTE,	0x00000000 },
  74	{ CS35L63_MAIN_RENDER_USER_VOLUME,	0x00000000 },
  75	{ CS35L63_MAIN_POSTURE_NUMBER,		0x00000000 },
  76};
  77
  78int cs35l56_set_patch(struct cs35l56_base *cs35l56_base)
  79{
  80	int ret;
  81
  82	ret = regmap_register_patch(cs35l56_base->regmap, cs35l56_patch,
  83				     ARRAY_SIZE(cs35l56_patch));
  84	if (ret)
  85		return ret;
  86
  87
  88	switch (cs35l56_base->type) {
  89	case 0x54:
  90	case 0x56:
  91	case 0x57:
  92		ret = regmap_register_patch(cs35l56_base->regmap, cs35l56_patch_fw,
  93					    ARRAY_SIZE(cs35l56_patch_fw));
  94		break;
  95	case 0x63:
  96		ret = regmap_register_patch(cs35l56_base->regmap, cs35l63_patch_fw,
  97					    ARRAY_SIZE(cs35l63_patch_fw));
  98		break;
  99	default:
 100		break;
 101	}
 102
 103	return ret;
 104}
 105EXPORT_SYMBOL_NS_GPL(cs35l56_set_patch, "SND_SOC_CS35L56_SHARED");
 106
 107static const struct reg_default cs35l56_reg_defaults[] = {
 108	/* no defaults for OTP_MEM - first read populates cache */
 109
 110	{ CS35L56_ASP1_ENABLES1,		0x00000000 },
 111	{ CS35L56_ASP1_CONTROL1,		0x00000028 },
 112	{ CS35L56_ASP1_CONTROL2,		0x18180200 },
 113	{ CS35L56_ASP1_CONTROL3,		0x00000002 },
 114	{ CS35L56_ASP1_FRAME_CONTROL1,		0x03020100 },
 115	{ CS35L56_ASP1_FRAME_CONTROL5,		0x00020100 },
 116	{ CS35L56_ASP1_DATA_CONTROL1,		0x00000018 },
 117	{ CS35L56_ASP1_DATA_CONTROL5,		0x00000018 },
 118	{ CS35L56_ASP1TX1_INPUT,		0x00000000 },
 119	{ CS35L56_ASP1TX2_INPUT,		0x00000000 },
 120	{ CS35L56_ASP1TX3_INPUT,		0x00000000 },
 121	{ CS35L56_ASP1TX4_INPUT,		0x00000000 },
 122	{ CS35L56_SWIRE_DP3_CH1_INPUT,		0x00000018 },
 123	{ CS35L56_SWIRE_DP3_CH2_INPUT,		0x00000019 },
 124	{ CS35L56_SWIRE_DP3_CH3_INPUT,		0x00000029 },
 125	{ CS35L56_SWIRE_DP3_CH4_INPUT,		0x00000028 },
 126	{ CS35L56_IRQ1_MASK_1,			0x83ffffff },
 127	{ CS35L56_IRQ1_MASK_2,			0xffff7fff },
 128	{ CS35L56_IRQ1_MASK_4,			0xe0ffffff },
 129	{ CS35L56_IRQ1_MASK_8,			0xfc000fff },
 130	{ CS35L56_IRQ1_MASK_18,			0x1f7df0ff },
 131	{ CS35L56_IRQ1_MASK_20,			0x15c00000 },
 132	{ CS35L56_MAIN_RENDER_USER_MUTE,	0x00000000 },
 133	{ CS35L56_MAIN_RENDER_USER_VOLUME,	0x00000000 },
 134	{ CS35L56_MAIN_POSTURE_NUMBER,		0x00000000 },
 135};
 136
 137static const struct reg_default cs35l63_reg_defaults[] = {
 138	/* no defaults for OTP_MEM - first read populates cache */
 139
 140	{ CS35L56_ASP1_ENABLES1,		0x00000000 },
 141	{ CS35L56_ASP1_CONTROL1,		0x00000028 },
 142	{ CS35L56_ASP1_CONTROL2,		0x18180200 },
 143	{ CS35L56_ASP1_CONTROL3,		0x00000002 },
 144	{ CS35L56_ASP1_FRAME_CONTROL1,		0x03020100 },
 145	{ CS35L56_ASP1_FRAME_CONTROL5,		0x00020100 },
 146	{ CS35L56_ASP1_DATA_CONTROL1,		0x00000018 },
 147	{ CS35L56_ASP1_DATA_CONTROL5,		0x00000018 },
 148	{ CS35L56_ASP1TX1_INPUT,		0x00000000 },
 149	{ CS35L56_ASP1TX2_INPUT,		0x00000000 },
 150	{ CS35L56_ASP1TX3_INPUT,		0x00000000 },
 151	{ CS35L56_ASP1TX4_INPUT,		0x00000000 },
 152	{ CS35L56_SWIRE_DP3_CH1_INPUT,		0x00000018 },
 153	{ CS35L56_SWIRE_DP3_CH2_INPUT,		0x00000019 },
 154	{ CS35L56_SWIRE_DP3_CH3_INPUT,		0x00000029 },
 155	{ CS35L56_SWIRE_DP3_CH4_INPUT,		0x00000028 },
 156	{ CS35L56_IRQ1_MASK_1,			0x8003ffff },
 157	{ CS35L56_IRQ1_MASK_2,			0xffff7fff },
 158	{ CS35L56_IRQ1_MASK_4,			0xe0ffffff },
 159	{ CS35L56_IRQ1_MASK_8,			0x8c000fff },
 160	{ CS35L56_IRQ1_MASK_18,			0x0760f000 },
 161	{ CS35L56_IRQ1_MASK_20,			0x15c00000 },
 162	{ CS35L63_MAIN_RENDER_USER_MUTE,	0x00000000 },
 163	{ CS35L63_MAIN_RENDER_USER_VOLUME,	0x00000000 },
 164	{ CS35L63_MAIN_POSTURE_NUMBER,		0x00000000 },
 165};
 166
 167static bool cs35l56_is_dsp_memory(unsigned int reg)
 168{
 169	switch (reg) {
 170	case CS35L56_DSP1_XMEM_PACKED_0 ... CS35L56_DSP1_XMEM_PACKED_6143:
 171	case CS35L56_DSP1_XMEM_UNPACKED32_0 ... CS35L56_DSP1_XMEM_UNPACKED32_4095:
 172	case CS35L56_DSP1_XMEM_UNPACKED24_0 ... CS35L56_DSP1_XMEM_UNPACKED24_8191:
 173	case CS35L56_DSP1_YMEM_PACKED_0 ... CS35L56_DSP1_YMEM_PACKED_4604:
 174	case CS35L56_DSP1_YMEM_UNPACKED32_0 ... CS35L56_DSP1_YMEM_UNPACKED32_3070:
 175	case CS35L56_DSP1_YMEM_UNPACKED24_0 ... CS35L56_DSP1_YMEM_UNPACKED24_6141:
 176	case CS35L56_DSP1_PMEM_0 ... CS35L56_DSP1_PMEM_5114:
 177		return true;
 178	default:
 179		return false;
 180	}
 181}
 182
 183static bool cs35l56_readable_reg(struct device *dev, unsigned int reg)
 184{
 185	switch (reg) {
 186	case CS35L56_DEVID:
 187	case CS35L56_REVID:
 188	case CS35L56_RELID:
 189	case CS35L56_OTPID:
 190	case CS35L56_SFT_RESET:
 191	case CS35L56_GLOBAL_ENABLES:
 192	case CS35L56_BLOCK_ENABLES:
 193	case CS35L56_BLOCK_ENABLES2:
 194	case CS35L56_REFCLK_INPUT:
 195	case CS35L56_GLOBAL_SAMPLE_RATE:
 196	case CS35L56_OTP_MEM_53:
 197	case CS35L56_OTP_MEM_54:
 198	case CS35L56_OTP_MEM_55:
 199	case CS35L56_ASP1_ENABLES1:
 200	case CS35L56_ASP1_CONTROL1:
 201	case CS35L56_ASP1_CONTROL2:
 202	case CS35L56_ASP1_CONTROL3:
 203	case CS35L56_ASP1_FRAME_CONTROL1:
 204	case CS35L56_ASP1_FRAME_CONTROL5:
 205	case CS35L56_ASP1_DATA_CONTROL1:
 206	case CS35L56_ASP1_DATA_CONTROL5:
 207	case CS35L56_DACPCM1_INPUT:
 208	case CS35L56_DACPCM2_INPUT:
 209	case CS35L56_ASP1TX1_INPUT:
 210	case CS35L56_ASP1TX2_INPUT:
 211	case CS35L56_ASP1TX3_INPUT:
 212	case CS35L56_ASP1TX4_INPUT:
 213	case CS35L56_DSP1RX1_INPUT:
 214	case CS35L56_DSP1RX2_INPUT:
 215	case CS35L56_SWIRE_DP3_CH1_INPUT:
 216	case CS35L56_SWIRE_DP3_CH2_INPUT:
 217	case CS35L56_SWIRE_DP3_CH3_INPUT:
 218	case CS35L56_SWIRE_DP3_CH4_INPUT:
 219	case CS35L56_IRQ1_CFG:
 220	case CS35L56_IRQ1_STATUS:
 221	case CS35L56_IRQ1_EINT_1 ... CS35L56_IRQ1_EINT_8:
 222	case CS35L56_IRQ1_EINT_18:
 223	case CS35L56_IRQ1_EINT_20:
 224	case CS35L56_IRQ1_MASK_1:
 225	case CS35L56_IRQ1_MASK_2:
 226	case CS35L56_IRQ1_MASK_4:
 227	case CS35L56_IRQ1_MASK_8:
 228	case CS35L56_IRQ1_MASK_18:
 229	case CS35L56_IRQ1_MASK_20:
 230	case CS35L56_MIXER_NGATE_CH1_CFG:
 231	case CS35L56_MIXER_NGATE_CH2_CFG:
 232	case CS35L56_DSP_VIRTUAL1_MBOX_1:
 233	case CS35L56_DSP_VIRTUAL1_MBOX_2:
 234	case CS35L56_DSP_VIRTUAL1_MBOX_3:
 235	case CS35L56_DSP_VIRTUAL1_MBOX_4:
 236	case CS35L56_DSP_VIRTUAL1_MBOX_5:
 237	case CS35L56_DSP_VIRTUAL1_MBOX_6:
 238	case CS35L56_DSP_VIRTUAL1_MBOX_7:
 239	case CS35L56_DSP_VIRTUAL1_MBOX_8:
 240	case CS35L56_DIE_STS1:
 241	case CS35L56_DIE_STS2:
 242	case CS35L56_DSP_RESTRICT_STS1:
 243	case CS35L56_DSP1_SYS_INFO_ID ... CS35L56_DSP1_SYS_INFO_END:
 244	case CS35L56_DSP1_AHBM_WINDOW_DEBUG_0:
 245	case CS35L56_DSP1_AHBM_WINDOW_DEBUG_1:
 246	case CS35L56_DSP1_SCRATCH1:
 247	case CS35L56_DSP1_SCRATCH2:
 248	case CS35L56_DSP1_SCRATCH3:
 249	case CS35L56_DSP1_SCRATCH4:
 250		return true;
 251	default:
 252		return cs35l56_is_dsp_memory(reg);
 253	}
 254}
 255
 256static bool cs35l56_precious_reg(struct device *dev, unsigned int reg)
 257{
 258	switch (reg) {
 259	case CS35L56_DSP1_XMEM_PACKED_0 ... CS35L56_DSP1_XMEM_PACKED_6143:
 260	case CS35L56_DSP1_YMEM_PACKED_0 ... CS35L56_DSP1_YMEM_PACKED_4604:
 261	case CS35L56_DSP1_PMEM_0 ... CS35L56_DSP1_PMEM_5114:
 262		return true;
 263	default:
 264		return false;
 265	}
 266}
 267
 268static bool cs35l56_common_volatile_reg(unsigned int reg)
 269{
 270	switch (reg) {
 271	case CS35L56_DEVID:
 272	case CS35L56_REVID:
 273	case CS35L56_RELID:
 274	case CS35L56_OTPID:
 275	case CS35L56_SFT_RESET:
 276	case CS35L56_GLOBAL_ENABLES:		   /* owned by firmware */
 277	case CS35L56_BLOCK_ENABLES:		   /* owned by firmware */
 278	case CS35L56_BLOCK_ENABLES2:		   /* owned by firmware */
 279	case CS35L56_REFCLK_INPUT:		   /* owned by firmware */
 280	case CS35L56_GLOBAL_SAMPLE_RATE:	   /* owned by firmware */
 281	case CS35L56_DACPCM1_INPUT:		   /* owned by firmware */
 282	case CS35L56_DACPCM2_INPUT:		   /* owned by firmware */
 283	case CS35L56_DSP1RX1_INPUT:		   /* owned by firmware */
 284	case CS35L56_DSP1RX2_INPUT:		   /* owned by firmware */
 285	case CS35L56_IRQ1_STATUS:
 286	case CS35L56_IRQ1_EINT_1 ... CS35L56_IRQ1_EINT_8:
 287	case CS35L56_IRQ1_EINT_18:
 288	case CS35L56_IRQ1_EINT_20:
 289	case CS35L56_MIXER_NGATE_CH1_CFG:
 290	case CS35L56_MIXER_NGATE_CH2_CFG:
 291	case CS35L56_DSP_VIRTUAL1_MBOX_1:
 292	case CS35L56_DSP_VIRTUAL1_MBOX_2:
 293	case CS35L56_DSP_VIRTUAL1_MBOX_3:
 294	case CS35L56_DSP_VIRTUAL1_MBOX_4:
 295	case CS35L56_DSP_VIRTUAL1_MBOX_5:
 296	case CS35L56_DSP_VIRTUAL1_MBOX_6:
 297	case CS35L56_DSP_VIRTUAL1_MBOX_7:
 298	case CS35L56_DSP_VIRTUAL1_MBOX_8:
 299	case CS35L56_DSP_RESTRICT_STS1:
 300	case CS35L56_DSP1_SYS_INFO_ID ... CS35L56_DSP1_SYS_INFO_END:
 301	case CS35L56_DSP1_AHBM_WINDOW_DEBUG_0:
 302	case CS35L56_DSP1_AHBM_WINDOW_DEBUG_1:
 303	case CS35L56_DSP1_SCRATCH1:
 304	case CS35L56_DSP1_SCRATCH2:
 305	case CS35L56_DSP1_SCRATCH3:
 306	case CS35L56_DSP1_SCRATCH4:
 307		return true;
 308	default:
 309		return cs35l56_is_dsp_memory(reg);
 310	}
 311}
 312
 313static bool cs35l56_volatile_reg(struct device *dev, unsigned int reg)
 314{
 315	switch (reg) {
 316	case CS35L56_MAIN_RENDER_USER_MUTE:
 317	case CS35L56_MAIN_RENDER_USER_VOLUME:
 318	case CS35L56_MAIN_POSTURE_NUMBER:
 319		return false;
 320	default:
 321		return cs35l56_common_volatile_reg(reg);
 322	}
 323}
 324
 325static bool cs35l63_volatile_reg(struct device *dev, unsigned int reg)
 326{
 327	switch (reg) {
 328	case CS35L63_MAIN_RENDER_USER_MUTE:
 329	case CS35L63_MAIN_RENDER_USER_VOLUME:
 330	case CS35L63_MAIN_POSTURE_NUMBER:
 331		return false;
 332	default:
 333		return cs35l56_common_volatile_reg(reg);
 334	}
 335}
 336
 337static const struct cs35l56_fw_reg cs35l56_fw_reg = {
 338	.fw_ver = CS35L56_DSP1_FW_VER,
 339	.halo_state = CS35L56_DSP1_HALO_STATE,
 340	.pm_cur_stat = CS35L56_DSP1_PM_CUR_STATE,
 341	.prot_sts = CS35L56_PROTECTION_STATUS,
 342	.transducer_actual_ps = CS35L56_TRANSDUCER_ACTUAL_PS,
 343	.user_mute = CS35L56_MAIN_RENDER_USER_MUTE,
 344	.user_volume = CS35L56_MAIN_RENDER_USER_VOLUME,
 345	.posture_number = CS35L56_MAIN_POSTURE_NUMBER,
 346};
 347
 348static const struct cs35l56_fw_reg cs35l56_b2_fw_reg = {
 349	.fw_ver = CS35L56_DSP1_FW_VER,
 350	.halo_state = CS35L56_B2_DSP1_HALO_STATE,
 351	.pm_cur_stat = CS35L56_B2_DSP1_PM_CUR_STATE,
 352	.prot_sts = CS35L56_PROTECTION_STATUS,
 353	.transducer_actual_ps = CS35L56_TRANSDUCER_ACTUAL_PS,
 354	.user_mute = CS35L56_MAIN_RENDER_USER_MUTE,
 355	.user_volume = CS35L56_MAIN_RENDER_USER_VOLUME,
 356	.posture_number = CS35L56_MAIN_POSTURE_NUMBER,
 357};
 358
 359static const struct cs35l56_fw_reg cs35l63_fw_reg = {
 360	.fw_ver = CS35L63_DSP1_FW_VER,
 361	.halo_state = CS35L63_DSP1_HALO_STATE,
 362	.pm_cur_stat = CS35L63_DSP1_PM_CUR_STATE,
 363	.prot_sts = CS35L63_PROTECTION_STATUS,
 364	.transducer_actual_ps = CS35L63_TRANSDUCER_ACTUAL_PS,
 365	.user_mute = CS35L63_MAIN_RENDER_USER_MUTE,
 366	.user_volume = CS35L63_MAIN_RENDER_USER_VOLUME,
 367	.posture_number = CS35L63_MAIN_POSTURE_NUMBER,
 368};
 369
 370static void cs35l56_set_fw_reg_table(struct cs35l56_base *cs35l56_base)
 371{
 372	switch (cs35l56_base->type) {
 373	default:
 374		switch (cs35l56_base->rev) {
 375		case 0xb0:
 376			cs35l56_base->fw_reg = &cs35l56_fw_reg;
 377			break;
 378		default:
 379			cs35l56_base->fw_reg = &cs35l56_b2_fw_reg;
 380			break;
 381		}
 382		break;
 383	case 0x63:
 384		cs35l56_base->fw_reg = &cs35l63_fw_reg;
 385		break;
 386	}
 387}
 388
 389int cs35l56_mbox_send(struct cs35l56_base *cs35l56_base, unsigned int command)
 390{
 391	unsigned int val;
 392	int ret;
 393
 394	regmap_write(cs35l56_base->regmap, CS35L56_DSP_VIRTUAL1_MBOX_1, command);
 395	ret = regmap_read_poll_timeout(cs35l56_base->regmap, CS35L56_DSP_VIRTUAL1_MBOX_1,
 396				       val, (val == 0),
 397				       CS35L56_MBOX_POLL_US, CS35L56_MBOX_TIMEOUT_US);
 398	if (ret) {
 399		dev_warn(cs35l56_base->dev, "MBOX command %#x failed: %d\n", command, ret);
 400		return ret;
 401	}
 402
 403	return 0;
 404}
 405EXPORT_SYMBOL_NS_GPL(cs35l56_mbox_send, "SND_SOC_CS35L56_SHARED");
 406
 407int cs35l56_firmware_shutdown(struct cs35l56_base *cs35l56_base)
 408{
 409	int ret;
 410	unsigned int val;
 411
 412	ret = cs35l56_mbox_send(cs35l56_base, CS35L56_MBOX_CMD_SHUTDOWN);
 413	if (ret)
 414		return ret;
 415
 416	ret = regmap_read_poll_timeout(cs35l56_base->regmap,
 417				       cs35l56_base->fw_reg->pm_cur_stat,
 418				       val, (val == CS35L56_HALO_STATE_SHUTDOWN),
 419				       CS35L56_HALO_STATE_POLL_US,
 420				       CS35L56_HALO_STATE_TIMEOUT_US);
 421	if (ret < 0)
 422		dev_err(cs35l56_base->dev, "Failed to poll PM_CUR_STATE to 1 is %d (ret %d)\n",
 423			val, ret);
 424	return ret;
 425}
 426EXPORT_SYMBOL_NS_GPL(cs35l56_firmware_shutdown, "SND_SOC_CS35L56_SHARED");
 427
 428int cs35l56_wait_for_firmware_boot(struct cs35l56_base *cs35l56_base)
 429{
 430	unsigned int val = 0;
 431	int read_ret, poll_ret;
 432
 433	/*
 434	 * The regmap must remain in cache-only until the chip has
 435	 * booted, so use a bypassed read of the status register.
 436	 */
 437	poll_ret = read_poll_timeout(regmap_read_bypassed, read_ret,
 438				     (val < 0xFFFF) && (val >= CS35L56_HALO_STATE_BOOT_DONE),
 439				     CS35L56_HALO_STATE_POLL_US,
 440				     CS35L56_HALO_STATE_TIMEOUT_US,
 441				     false,
 442				     cs35l56_base->regmap,
 443				     cs35l56_base->fw_reg->halo_state,
 444				     &val);
 445
 446	if (poll_ret) {
 447		dev_err(cs35l56_base->dev, "Firmware boot timed out(%d): HALO_STATE=%#x\n",
 448			read_ret, val);
 449		return -EIO;
 450	}
 451
 452	return 0;
 453}
 454EXPORT_SYMBOL_NS_GPL(cs35l56_wait_for_firmware_boot, "SND_SOC_CS35L56_SHARED");
 455
 456void cs35l56_wait_control_port_ready(void)
 457{
 458	/* Wait for control port to be ready (datasheet tIRS). */
 459	usleep_range(CS35L56_CONTROL_PORT_READY_US, 2 * CS35L56_CONTROL_PORT_READY_US);
 460}
 461EXPORT_SYMBOL_NS_GPL(cs35l56_wait_control_port_ready, "SND_SOC_CS35L56_SHARED");
 462
 463void cs35l56_wait_min_reset_pulse(void)
 464{
 465	/* Satisfy minimum reset pulse width spec */
 466	usleep_range(CS35L56_RESET_PULSE_MIN_US, 2 * CS35L56_RESET_PULSE_MIN_US);
 467}
 468EXPORT_SYMBOL_NS_GPL(cs35l56_wait_min_reset_pulse, "SND_SOC_CS35L56_SHARED");
 469
 470static const struct {
 471	u32 addr;
 472	u32 value;
 473} cs35l56_spi_system_reset_stages[] = {
 474	{ .addr = CS35L56_DSP_VIRTUAL1_MBOX_1, .value = CS35L56_MBOX_CMD_SYSTEM_RESET },
 475	/* The next write is necessary to delimit the soft reset */
 476	{ .addr = CS35L56_DSP_MBOX_1_RAW, .value = CS35L56_MBOX_CMD_PING },
 477};
 478
 479static void cs35l56_spi_issue_bus_locked_reset(struct cs35l56_base *cs35l56_base,
 480					       struct spi_device *spi)
 481{
 482	struct cs35l56_spi_payload *buf = cs35l56_base->spi_payload_buf;
 483	struct spi_transfer t = {
 484		.tx_buf		= buf,
 485		.len		= sizeof(*buf),
 486	};
 487	struct spi_message m;
 488	int i, ret;
 489
 490	for (i = 0; i < ARRAY_SIZE(cs35l56_spi_system_reset_stages); i++) {
 491		buf->addr = cpu_to_be32(cs35l56_spi_system_reset_stages[i].addr);
 492		buf->value = cpu_to_be32(cs35l56_spi_system_reset_stages[i].value);
 493		spi_message_init_with_transfers(&m, &t, 1);
 494		ret = spi_sync_locked(spi, &m);
 495		if (ret)
 496			dev_warn(cs35l56_base->dev, "spi_sync failed: %d\n", ret);
 497
 498		usleep_range(CS35L56_SPI_RESET_TO_PORT_READY_US,
 499			     2 * CS35L56_SPI_RESET_TO_PORT_READY_US);
 500	}
 501}
 502
 503static void cs35l56_spi_system_reset(struct cs35l56_base *cs35l56_base)
 504{
 505	struct spi_device *spi = to_spi_device(cs35l56_base->dev);
 506	unsigned int val;
 507	int read_ret, ret;
 508
 509	/*
 510	 * There must not be any other SPI bus activity while the amp is
 511	 * soft-resetting.
 512	 */
 513	ret = spi_bus_lock(spi->controller);
 514	if (ret) {
 515		dev_warn(cs35l56_base->dev, "spi_bus_lock failed: %d\n", ret);
 516		return;
 517	}
 518
 519	cs35l56_spi_issue_bus_locked_reset(cs35l56_base, spi);
 520	spi_bus_unlock(spi->controller);
 521
 522	/*
 523	 * Check firmware boot by testing for a response in MBOX_2.
 524	 * HALO_STATE cannot be trusted yet because the reset sequence
 525	 * can leave it with stale state. But MBOX is reset.
 526	 * The regmap must remain in cache-only until the chip has
 527	 * booted, so use a bypassed read.
 528	 */
 529	ret = read_poll_timeout(regmap_read_bypassed, read_ret,
 530				(val > 0) && (val < 0xffffffff),
 531				CS35L56_HALO_STATE_POLL_US,
 532				CS35L56_HALO_STATE_TIMEOUT_US,
 533				false,
 534				cs35l56_base->regmap,
 535				CS35L56_DSP_VIRTUAL1_MBOX_2,
 536				&val);
 537	if (ret) {
 538		dev_err(cs35l56_base->dev, "SPI reboot timed out(%d): MBOX2=%#x\n",
 539			read_ret, val);
 540	}
 541}
 542
 543static const struct reg_sequence cs35l56_system_reset_seq[] = {
 544	REG_SEQ0(CS35L56_DSP1_HALO_STATE, 0),
 545	REG_SEQ0(CS35L56_DSP_VIRTUAL1_MBOX_1, CS35L56_MBOX_CMD_SYSTEM_RESET),
 546};
 547
 548static const struct reg_sequence cs35l56_b2_system_reset_seq[] = {
 549	REG_SEQ0(CS35L56_B2_DSP1_HALO_STATE, 0),
 550	REG_SEQ0(CS35L56_DSP_VIRTUAL1_MBOX_1, CS35L56_MBOX_CMD_SYSTEM_RESET),
 551};
 552
 553static const struct reg_sequence cs35l63_system_reset_seq[] = {
 554	REG_SEQ0(CS35L63_DSP1_HALO_STATE, 0),
 555	REG_SEQ0(CS35L56_DSP_VIRTUAL1_MBOX_1, CS35L56_MBOX_CMD_SYSTEM_RESET),
 556};
 557
 558void cs35l56_system_reset(struct cs35l56_base *cs35l56_base, bool is_soundwire)
 559{
 560	/*
 561	 * Must enter cache-only first so there can't be any more register
 562	 * accesses other than the controlled system reset sequence below.
 563	 */
 564	regcache_cache_only(cs35l56_base->regmap, true);
 565
 566	if (cs35l56_is_spi(cs35l56_base)) {
 567		cs35l56_spi_system_reset(cs35l56_base);
 568		return;
 569	}
 570
 571	switch (cs35l56_base->type) {
 572	case 0x54:
 573	case 0x56:
 574	case 0x57:
 575		switch (cs35l56_base->rev) {
 576		case 0xb0:
 577			regmap_multi_reg_write_bypassed(cs35l56_base->regmap,
 578							cs35l56_system_reset_seq,
 579							ARRAY_SIZE(cs35l56_system_reset_seq));
 580			break;
 581		default:
 582			regmap_multi_reg_write_bypassed(cs35l56_base->regmap,
 583							cs35l56_b2_system_reset_seq,
 584							ARRAY_SIZE(cs35l56_b2_system_reset_seq));
 585			break;
 586		}
 587		break;
 588	case 0x63:
 589		regmap_multi_reg_write_bypassed(cs35l56_base->regmap,
 590						cs35l63_system_reset_seq,
 591						ARRAY_SIZE(cs35l63_system_reset_seq));
 592		break;
 593	default:
 594		break;
 595	}
 596
 597	/* On SoundWire the registers won't be accessible until it re-enumerates. */
 598	if (is_soundwire)
 599		return;
 600
 601	cs35l56_wait_control_port_ready();
 602
 603	/* Leave in cache-only. This will be revoked when the chip has rebooted. */
 604}
 605EXPORT_SYMBOL_NS_GPL(cs35l56_system_reset, "SND_SOC_CS35L56_SHARED");
 606
 607int cs35l56_irq_request(struct cs35l56_base *cs35l56_base, int irq)
 608{
 609	int ret;
 610
 611	if (irq < 1)
 612		return 0;
 613
 614	ret = devm_request_threaded_irq(cs35l56_base->dev, irq, NULL, cs35l56_irq,
 615					IRQF_ONESHOT | IRQF_SHARED | IRQF_TRIGGER_LOW,
 616					"cs35l56", cs35l56_base);
 617	if (!ret)
 618		cs35l56_base->irq = irq;
 619	else
 620		dev_err(cs35l56_base->dev, "Failed to get IRQ: %d\n", ret);
 621
 622	return ret;
 623}
 624EXPORT_SYMBOL_NS_GPL(cs35l56_irq_request, "SND_SOC_CS35L56_SHARED");
 625
 626irqreturn_t cs35l56_irq(int irq, void *data)
 627{
 628	struct cs35l56_base *cs35l56_base = data;
 629	unsigned int status1 = 0, status8 = 0, status20 = 0;
 630	unsigned int mask1, mask8, mask20;
 631	unsigned int val;
 632	int rv;
 633
 634	irqreturn_t ret = IRQ_NONE;
 635
 636	if (!cs35l56_base->init_done)
 637		return IRQ_NONE;
 638
 639	mutex_lock(&cs35l56_base->irq_lock);
 640
 641	rv = pm_runtime_resume_and_get(cs35l56_base->dev);
 642	if (rv < 0) {
 643		dev_err(cs35l56_base->dev, "irq: failed to get pm_runtime: %d\n", rv);
 644		goto err_unlock;
 645	}
 646
 647	regmap_read(cs35l56_base->regmap, CS35L56_IRQ1_STATUS, &val);
 648	if ((val & CS35L56_IRQ1_STS_MASK) == 0) {
 649		dev_dbg(cs35l56_base->dev, "Spurious IRQ: no pending interrupt\n");
 650		goto err;
 651	}
 652
 653	/* Ack interrupts */
 654	regmap_read(cs35l56_base->regmap, CS35L56_IRQ1_EINT_1, &status1);
 655	regmap_read(cs35l56_base->regmap, CS35L56_IRQ1_MASK_1, &mask1);
 656	status1 &= ~mask1;
 657	regmap_write(cs35l56_base->regmap, CS35L56_IRQ1_EINT_1, status1);
 658
 659	regmap_read(cs35l56_base->regmap, CS35L56_IRQ1_EINT_8, &status8);
 660	regmap_read(cs35l56_base->regmap, CS35L56_IRQ1_MASK_8, &mask8);
 661	status8 &= ~mask8;
 662	regmap_write(cs35l56_base->regmap, CS35L56_IRQ1_EINT_8, status8);
 663
 664	regmap_read(cs35l56_base->regmap, CS35L56_IRQ1_EINT_20, &status20);
 665	regmap_read(cs35l56_base->regmap, CS35L56_IRQ1_MASK_20, &mask20);
 666	status20 &= ~mask20;
 667	/* We don't want EINT20 but they default to unmasked: force mask */
 668	regmap_write(cs35l56_base->regmap, CS35L56_IRQ1_MASK_20, 0xffffffff);
 669
 670	dev_dbg(cs35l56_base->dev, "%s: %#x %#x\n", __func__, status1, status8);
 671
 672	/* Check to see if unmasked bits are active */
 673	if (!status1 && !status8 && !status20)
 674		goto err;
 675
 676	if (status1 & CS35L56_AMP_SHORT_ERR_EINT1_MASK)
 677		dev_crit(cs35l56_base->dev, "Amp short error\n");
 678
 679	if (status8 & CS35L56_TEMP_ERR_EINT1_MASK)
 680		dev_crit(cs35l56_base->dev, "Overtemp error\n");
 681
 682	ret = IRQ_HANDLED;
 683
 684err:
 685	pm_runtime_put(cs35l56_base->dev);
 686err_unlock:
 687	mutex_unlock(&cs35l56_base->irq_lock);
 688
 689	return ret;
 690}
 691EXPORT_SYMBOL_NS_GPL(cs35l56_irq, "SND_SOC_CS35L56_SHARED");
 692
 693int cs35l56_is_fw_reload_needed(struct cs35l56_base *cs35l56_base)
 694{
 695	unsigned int val;
 696	int ret;
 697
 698	/*
 699	 * In secure mode FIRMWARE_MISSING is cleared by the BIOS loader so
 700	 * can't be used here to test for memory retention.
 701	 * Assume that tuning must be re-loaded.
 702	 */
 703	if (cs35l56_base->secured)
 704		return true;
 705
 706	ret = pm_runtime_resume_and_get(cs35l56_base->dev);
 707	if (ret) {
 708		dev_err(cs35l56_base->dev, "Failed to runtime_get: %d\n", ret);
 709		return ret;
 710	}
 711
 712	ret = regmap_read(cs35l56_base->regmap,
 713			  cs35l56_base->fw_reg->prot_sts,
 714			  &val);
 715	if (ret)
 716		dev_err(cs35l56_base->dev, "Failed to read PROTECTION_STATUS: %d\n", ret);
 717	else
 718		ret = !!(val & CS35L56_FIRMWARE_MISSING);
 719
 720	pm_runtime_put_autosuspend(cs35l56_base->dev);
 721
 722	return ret;
 723}
 724EXPORT_SYMBOL_NS_GPL(cs35l56_is_fw_reload_needed, "SND_SOC_CS35L56_SHARED");
 725
 726static const struct reg_sequence cs35l56_hibernate_seq[] = {
 727	/* This must be the last register access */
 728	REG_SEQ0(CS35L56_DSP_VIRTUAL1_MBOX_1, CS35L56_MBOX_CMD_ALLOW_AUTO_HIBERNATE),
 729};
 730
 731static void cs35l56_issue_wake_event(struct cs35l56_base *cs35l56_base)
 732{
 733	unsigned int val;
 734
 735	/*
 736	 * Dummy transactions to trigger I2C/SPI auto-wake. Issue two
 737	 * transactions to meet the minimum required time from the rising edge
 738	 * to the last falling edge of wake.
 739	 *
 740	 * It uses bypassed read because we must wake the chip before
 741	 * disabling regmap cache-only.
 742	 */
 743	regmap_read_bypassed(cs35l56_base->regmap, CS35L56_IRQ1_STATUS, &val);
 744
 745	usleep_range(CS35L56_WAKE_HOLD_TIME_US, 2 * CS35L56_WAKE_HOLD_TIME_US);
 746
 747	regmap_read_bypassed(cs35l56_base->regmap, CS35L56_IRQ1_STATUS, &val);
 748
 749	cs35l56_wait_control_port_ready();
 750}
 751
 752static int cs35l56_wait_for_ps3(struct cs35l56_base *cs35l56_base)
 753{
 754	unsigned int val;
 755	int ret;
 756
 757	ret = regmap_read_poll_timeout(cs35l56_base->regmap,
 758				       cs35l56_base->fw_reg->transducer_actual_ps,
 759				       val, (val >= CS35L56_PS3),
 760				       CS35L56_PS3_POLL_US,
 761				       CS35L56_PS3_TIMEOUT_US);
 762	if (ret)
 763		dev_warn(cs35l56_base->dev, "PS3 wait failed: %d\n", ret);
 764
 765	return ret;
 766}
 767
 768int cs35l56_runtime_suspend_common(struct cs35l56_base *cs35l56_base)
 769{
 770	if (!cs35l56_base->init_done)
 771		return 0;
 772
 773	/* Firmware must have entered a power-save state */
 774	cs35l56_wait_for_ps3(cs35l56_base);
 775
 776	/* Clear BOOT_DONE so it can be used to detect a reboot */
 777	regmap_write(cs35l56_base->regmap, CS35L56_IRQ1_EINT_4, CS35L56_OTP_BOOT_DONE_MASK);
 778
 779	if (!cs35l56_base->can_hibernate) {
 780		regcache_cache_only(cs35l56_base->regmap, true);
 781		dev_dbg(cs35l56_base->dev, "Suspended: no hibernate");
 782
 783		return 0;
 784	}
 785
 786	/*
 787	 * Must enter cache-only first so there can't be any more register
 788	 * accesses other than the controlled hibernate sequence below.
 789	 */
 790	regcache_cache_only(cs35l56_base->regmap, true);
 791
 792	regmap_multi_reg_write_bypassed(cs35l56_base->regmap,
 793					cs35l56_hibernate_seq,
 794					ARRAY_SIZE(cs35l56_hibernate_seq));
 795
 796	dev_dbg(cs35l56_base->dev, "Suspended: hibernate");
 797
 798	return 0;
 799}
 800EXPORT_SYMBOL_NS_GPL(cs35l56_runtime_suspend_common, "SND_SOC_CS35L56_SHARED");
 801
 802int cs35l56_runtime_resume_common(struct cs35l56_base *cs35l56_base, bool is_soundwire)
 803{
 804	unsigned int val;
 805	int ret;
 806
 807	if (!cs35l56_base->init_done)
 808		return 0;
 809
 810	if (!cs35l56_base->can_hibernate)
 811		goto out_sync;
 812
 813	/* Must be done before releasing cache-only */
 814	if (!is_soundwire)
 815		cs35l56_issue_wake_event(cs35l56_base);
 816
 817out_sync:
 818	ret = cs35l56_wait_for_firmware_boot(cs35l56_base);
 819	if (ret) {
 820		dev_err(cs35l56_base->dev, "Hibernate wake failed: %d\n", ret);
 821		goto err;
 822	}
 823
 824	regcache_cache_only(cs35l56_base->regmap, false);
 825
 826	ret = cs35l56_mbox_send(cs35l56_base, CS35L56_MBOX_CMD_PREVENT_AUTO_HIBERNATE);
 827	if (ret)
 828		goto err;
 829
 830	/* BOOT_DONE will be 1 if the amp reset */
 831	regmap_read(cs35l56_base->regmap, CS35L56_IRQ1_EINT_4, &val);
 832	if (val & CS35L56_OTP_BOOT_DONE_MASK) {
 833		dev_dbg(cs35l56_base->dev, "Registers reset in suspend\n");
 834		regcache_mark_dirty(cs35l56_base->regmap);
 835	}
 836
 837	regcache_sync(cs35l56_base->regmap);
 838
 839	dev_dbg(cs35l56_base->dev, "Resumed");
 840
 841	return 0;
 842
 843err:
 844	regcache_cache_only(cs35l56_base->regmap, true);
 845
 846	regmap_multi_reg_write_bypassed(cs35l56_base->regmap,
 847					cs35l56_hibernate_seq,
 848					ARRAY_SIZE(cs35l56_hibernate_seq));
 849
 850	return ret;
 851}
 852EXPORT_SYMBOL_NS_GPL(cs35l56_runtime_resume_common, "SND_SOC_CS35L56_SHARED");
 853
 854static const struct cs_dsp_region cs35l56_dsp1_regions[] = {
 855	{ .type = WMFW_HALO_PM_PACKED,	.base = CS35L56_DSP1_PMEM_0 },
 856	{ .type = WMFW_HALO_XM_PACKED,	.base = CS35L56_DSP1_XMEM_PACKED_0 },
 857	{ .type = WMFW_HALO_YM_PACKED,	.base = CS35L56_DSP1_YMEM_PACKED_0 },
 858	{ .type = WMFW_ADSP2_XM,	.base = CS35L56_DSP1_XMEM_UNPACKED24_0 },
 859	{ .type = WMFW_ADSP2_YM,	.base = CS35L56_DSP1_YMEM_UNPACKED24_0 },
 860};
 861
 862void cs35l56_init_cs_dsp(struct cs35l56_base *cs35l56_base, struct cs_dsp *cs_dsp)
 863{
 864	cs_dsp->num = 1;
 865	cs_dsp->type = WMFW_HALO;
 866	cs_dsp->rev = 0;
 867	cs_dsp->dev = cs35l56_base->dev;
 868	cs_dsp->regmap = cs35l56_base->regmap;
 869	cs_dsp->base = CS35L56_DSP1_CORE_BASE;
 870	cs_dsp->base_sysinfo = CS35L56_DSP1_SYS_INFO_ID;
 871	cs_dsp->mem = cs35l56_dsp1_regions;
 872	cs_dsp->num_mems = ARRAY_SIZE(cs35l56_dsp1_regions);
 873	cs_dsp->no_core_startstop = true;
 874
 875	cs35l56_base->dsp = cs_dsp;
 876}
 877EXPORT_SYMBOL_NS_GPL(cs35l56_init_cs_dsp, "SND_SOC_CS35L56_SHARED");
 878
 879struct cs35l56_pte {
 880	u8 x;
 881	u8 wafer_id;
 882	u8 pte[2];
 883	u8 lot[3];
 884	u8 y;
 885	u8 unused[3];
 886	u8 dvs;
 887} __packed;
 888static_assert((sizeof(struct cs35l56_pte) % sizeof(u32)) == 0);
 889
 890static int cs35l56_read_silicon_uid(struct cs35l56_base *cs35l56_base)
 891{
 892	struct cs35l56_pte pte;
 893	u64 unique_id;
 894	int ret;
 895
 896	ret = regmap_raw_read(cs35l56_base->regmap, CS35L56_OTP_MEM_53, &pte, sizeof(pte));
 897	if (ret) {
 898		dev_err(cs35l56_base->dev, "Failed to read OTP: %d\n", ret);
 899		return ret;
 900	}
 901
 902	unique_id = (u32)pte.lot[2] | ((u32)pte.lot[1] << 8) | ((u32)pte.lot[0] << 16);
 903	unique_id <<= 32;
 904	unique_id |= (u32)pte.x | ((u32)pte.y << 8) | ((u32)pte.wafer_id << 16) |
 905		     ((u32)pte.dvs << 24);
 906
 907	cs35l56_base->silicon_uid = unique_id;
 908
 909	return 0;
 910}
 911
 912static int cs35l63_read_silicon_uid(struct cs35l56_base *cs35l56_base)
 913{
 914	u32 tmp[2];
 915	u64 unique_id;
 916	int ret;
 917
 918	ret = regmap_bulk_read(cs35l56_base->regmap, CS35L56_DIE_STS1, tmp, ARRAY_SIZE(tmp));
 919	if (ret) {
 920		dev_err(cs35l56_base->dev, "Cannot obtain CS35L56_DIE_STS: %d\n", ret);
 921		return ret;
 922	}
 923
 924	unique_id = tmp[1];
 925	unique_id <<= 32;
 926	unique_id |= tmp[0];
 927
 928	cs35l56_base->silicon_uid = unique_id;
 929
 930	return 0;
 931}
 932
 933/* Firmware calibration controls */
 934const struct cirrus_amp_cal_controls cs35l56_calibration_controls = {
 935	.alg_id =	0x9f210,
 936	.mem_region =	WMFW_ADSP2_YM,
 937	.ambient =	"CAL_AMBIENT",
 938	.calr =		"CAL_R",
 939	.status =	"CAL_STATUS",
 940	.checksum =	"CAL_CHECKSUM",
 941};
 942EXPORT_SYMBOL_NS_GPL(cs35l56_calibration_controls, "SND_SOC_CS35L56_SHARED");
 943
 944static const struct cirrus_amp_cal_controls cs35l63_calibration_controls = {
 945	.alg_id =	0xbf210,
 946	.mem_region =	WMFW_ADSP2_YM,
 947	.ambient =	"CAL_AMBIENT",
 948	.calr =		"CAL_R",
 949	.status =	"CAL_STATUS",
 950	.checksum =	"CAL_CHECKSUM",
 951};
 952
 953int cs35l56_get_calibration(struct cs35l56_base *cs35l56_base)
 954{
 955	int ret;
 956
 957	/* Driver can't apply calibration to a secured part, so skip */
 958	if (cs35l56_base->secured)
 959		return 0;
 960
 961	ret = cs_amp_get_efi_calibration_data(cs35l56_base->dev,
 962					      cs35l56_base->silicon_uid,
 963					      cs35l56_base->cal_index,
 964					      &cs35l56_base->cal_data);
 965
 966	/* Only return an error status if probe should be aborted */
 967	if ((ret == -ENOENT) || (ret == -EOVERFLOW))
 968		return 0;
 969
 970	if (ret < 0)
 971		return ret;
 972
 973	cs35l56_base->cal_data_valid = true;
 974
 975	return 0;
 976}
 977EXPORT_SYMBOL_NS_GPL(cs35l56_get_calibration, "SND_SOC_CS35L56_SHARED");
 978
 979int cs35l56_stash_calibration(struct cs35l56_base *cs35l56_base,
 980			      const struct cirrus_amp_cal_data *data)
 981{
 982
 983	/* Ignore if it is empty */
 984	if (!data->calTime[0] && !data->calTime[1])
 985		return -ENODATA;
 986
 987	if (cs_amp_cal_target_u64(data) != cs35l56_base->silicon_uid) {
 988		dev_err(cs35l56_base->dev, "cal_data not for this silicon ID\n");
 989		return -EINVAL;
 990	}
 991
 992	cs35l56_base->cal_data = *data;
 993	cs35l56_base->cal_data_valid = true;
 994
 995	return 0;
 996}
 997EXPORT_SYMBOL_NS_GPL(cs35l56_stash_calibration, "SND_SOC_CS35L56_SHARED");
 998
 999static int cs35l56_perform_calibration(struct cs35l56_base *cs35l56_base)
1000{
1001	const struct cirrus_amp_cal_controls *calibration_controls =
1002		cs35l56_base->calibration_controls;
1003	struct cs_dsp *dsp = cs35l56_base->dsp;
1004	struct cirrus_amp_cal_data cal_data;
1005	struct cs_dsp_coeff_ctl *ctl;
1006	bool ngate_ch1_was_enabled = false;
1007	bool ngate_ch2_was_enabled = false;
1008	int cali_norm_en_alg_id, cali_norm_en_mem;
1009	int ret;
1010	__be32 val;
1011
1012	if (cs35l56_base->silicon_uid == 0) {
1013		dev_err(cs35l56_base->dev, "Cannot calibrate: no silicon UID\n");
1014		return -ENXIO;
1015	}
1016
1017	switch (cs35l56_base->type) {
1018	case 0x54:
1019	case 0x56:
1020	case 0x57:
1021		if (cs35l56_base->rev < 0xb2) {
1022			cali_norm_en_alg_id = 0x9f22f;
1023			cali_norm_en_mem = WMFW_ADSP2_YM;
1024		} else {
1025			cali_norm_en_alg_id = 0x9f210;
1026			cali_norm_en_mem = WMFW_ADSP2_XM;
1027		}
1028		break;
1029	default:
1030		cali_norm_en_alg_id = 0xbf210;
1031		cali_norm_en_mem = WMFW_ADSP2_XM;
1032		break;
1033	}
1034
1035	ret = pm_runtime_resume_and_get(cs35l56_base->dev);
1036	if (ret)
1037		return ret;
1038
1039	ret = cs35l56_wait_for_ps3(cs35l56_base);
1040	if (ret) {
1041		ret = -EBUSY;
1042		goto err_pm_put;
1043	}
1044
1045	regmap_update_bits_check(cs35l56_base->regmap, CS35L56_MIXER_NGATE_CH1_CFG,
1046				 CS35L56_AUX_NGATE_CHn_EN, 0, &ngate_ch1_was_enabled);
1047	regmap_update_bits_check(cs35l56_base->regmap, CS35L56_MIXER_NGATE_CH2_CFG,
1048				 CS35L56_AUX_NGATE_CHn_EN, 0, &ngate_ch2_was_enabled);
1049
1050	scoped_guard(mutex, &dsp->pwr_lock) {
1051		ctl = cs_dsp_get_ctl(dsp,
1052				     calibration_controls->status,
1053				     calibration_controls->mem_region,
1054				     calibration_controls->alg_id);
1055		if (!ctl) {
1056			dev_err(cs35l56_base->dev, "Could not get %s control\n",
1057				calibration_controls->status);
1058			ret = -EIO;
1059			goto err;
1060		}
1061
1062		val = cpu_to_be32(0);
1063		ret = cs_dsp_coeff_write_ctrl(cs_dsp_get_ctl(dsp,
1064					      "CALI_NORM_EN",
1065					      cali_norm_en_mem,
1066					      cali_norm_en_alg_id),
1067					      0, &val, sizeof(val));
1068		if (ret < 0) {
1069			dev_err(cs35l56_base->dev, "Could not write %s: %d\n", "CALI_NORM_EN", ret);
1070			ret = -EIO;
1071			goto err;
1072		}
1073
1074		ret = cs35l56_mbox_send(cs35l56_base, CS35L56_MBOX_CMD_AUDIO_CALIBRATION);
1075		if (ret) {
1076			ret = -EIO;
1077			goto err;
1078		}
1079
1080		if (read_poll_timeout(cs_dsp_coeff_read_ctrl, ret,
1081				      (val == cpu_to_be32(1)),
1082				      CS35L56_CALIBRATION_POLL_US,
1083				      CS35L56_CALIBRATION_TIMEOUT_US,
1084				      true,
1085				      ctl, 0, &val, sizeof(val))) {
1086			dev_err(cs35l56_base->dev, "Calibration timed out (CAL_STATUS: %u)\n",
1087				be32_to_cpu(val));
1088			switch (be32_to_cpu(val)) {
1089			case CS35L56_CAL_STATUS_OUT_OF_RANGE:
1090				ret = -ERANGE;
1091				goto err;
1092			default:
1093				ret = -ETIMEDOUT;
1094				goto err;
1095			}
1096		}
1097	}
1098
1099	cs35l56_base->cal_data_valid = false;
1100	memset(&cal_data, 0, sizeof(cal_data));
1101	ret = cs_amp_read_cal_coeffs(dsp, calibration_controls, &cal_data);
1102	if (ret) {
1103		ret = -EIO;
1104		goto err;
1105	}
1106
1107	dev_info(cs35l56_base->dev, "Cal status:%d calR:%d ambient:%d\n",
1108		 cal_data.calStatus, cal_data.calR, cal_data.calAmbient);
1109
1110	cal_data.calTarget[0] = (u32)cs35l56_base->silicon_uid;
1111	cal_data.calTarget[1] = (u32)(cs35l56_base->silicon_uid >> 32);
1112	cs35l56_base->cal_data = cal_data;
1113	cs35l56_base->cal_data_valid = true;
1114
1115	ret = 0;
1116
1117err:
1118	if (ngate_ch1_was_enabled) {
1119		regmap_set_bits(cs35l56_base->regmap, CS35L56_MIXER_NGATE_CH1_CFG,
1120				CS35L56_AUX_NGATE_CHn_EN);
1121	}
1122	if (ngate_ch2_was_enabled) {
1123		regmap_set_bits(cs35l56_base->regmap, CS35L56_MIXER_NGATE_CH2_CFG,
1124				CS35L56_AUX_NGATE_CHn_EN);
1125	}
1126err_pm_put:
1127	pm_runtime_put(cs35l56_base->dev);
1128
1129	return ret;
1130}
1131
1132ssize_t cs35l56_calibrate_debugfs_write(struct cs35l56_base *cs35l56_base,
1133					const char __user *from, size_t count,
1134					loff_t *ppos)
1135{
1136	static const char * const options[] = { "factory", "store_uefi" };
1137	char buf[11] = { 0 };
1138	int num_amps, ret;
1139
1140	if (!IS_ENABLED(CONFIG_SND_SOC_CS35L56_CAL_DEBUGFS_COMMON))
1141		return -ENXIO;
1142
1143	if (*ppos)
1144		return -EINVAL;
1145
1146	ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, from, count);
1147	if (ret < 0)
1148		return ret;
1149
1150	switch (sysfs_match_string(options, buf)) {
1151	case 0:
1152		ret = cs35l56_perform_calibration(cs35l56_base);
1153		if (ret < 0)
1154			return ret;
1155		break;
1156	case 1:
1157		if (!cs35l56_base->cal_data_valid)
1158			return -ENODATA;
1159
1160		num_amps = cs35l56_base->num_amps;
1161		if (num_amps == 0)
1162			num_amps = -1;
1163
1164		ret = cs_amp_set_efi_calibration_data(cs35l56_base->dev,
1165						      cs35l56_base->cal_index,
1166						      num_amps,
1167						      &cs35l56_base->cal_data);
1168		if (ret < 0)
1169			return ret;
1170		break;
1171	default:
1172		return -EOPNOTSUPP;
1173	}
1174
1175	return count;
1176}
1177EXPORT_SYMBOL_NS_GPL(cs35l56_calibrate_debugfs_write, "SND_SOC_CS35L56_SHARED");
1178
1179ssize_t cs35l56_cal_ambient_debugfs_write(struct cs35l56_base *cs35l56_base,
1180					  const char __user *from, size_t count,
1181					  loff_t *ppos)
1182{
1183	unsigned long val;
1184	int ret;
1185
1186	if (!IS_ENABLED(CONFIG_SND_SOC_CS35L56_CAL_DEBUGFS_COMMON))
1187		return -ENXIO;
1188
1189	if (*ppos)
1190		return -EINVAL;
1191
1192	ret = pm_runtime_resume_and_get(cs35l56_base->dev);
1193	if (ret)
1194		return ret;
1195
1196	ret = kstrtoul_from_user(from, count, 10, &val);
1197	if (ret < 0)
1198		goto out;
1199
1200	ret = cs_amp_write_ambient_temp(cs35l56_base->dsp, cs35l56_base->calibration_controls, val);
1201	if (ret)
1202		ret = -EIO;
1203out:
1204	pm_runtime_put(cs35l56_base->dev);
1205
1206	if (ret < 0)
1207		return ret;
1208
1209	return count;
1210}
1211EXPORT_SYMBOL_NS_GPL(cs35l56_cal_ambient_debugfs_write, "SND_SOC_CS35L56_SHARED");
1212
1213ssize_t cs35l56_cal_data_debugfs_read(struct cs35l56_base *cs35l56_base,
1214				      char __user *to, size_t count,
1215				      loff_t *ppos)
1216{
1217	if (!IS_ENABLED(CONFIG_SND_SOC_CS35L56_CAL_DEBUGFS_COMMON))
1218		return -ENXIO;
1219
1220	if (!cs35l56_base->cal_data_valid)
1221		return 0;
1222
1223	return simple_read_from_buffer(to, count, ppos, &cs35l56_base->cal_data,
1224				       sizeof(cs35l56_base->cal_data));
1225}
1226EXPORT_SYMBOL_NS_GPL(cs35l56_cal_data_debugfs_read, "SND_SOC_CS35L56_SHARED");
1227
1228ssize_t cs35l56_cal_data_debugfs_write(struct cs35l56_base *cs35l56_base,
1229				       const char __user *from, size_t count,
1230				       loff_t *ppos)
1231{
1232	struct cirrus_amp_cal_data cal_data;
1233	int ret;
1234
1235	if (!IS_ENABLED(CONFIG_SND_SOC_CS35L56_CAL_DEBUGFS_COMMON))
1236		return -ENXIO;
1237
1238	/* Only allow a full blob to be written */
1239	if (*ppos || (count != sizeof(cal_data)))
1240		return -EMSGSIZE;
1241
1242	ret = simple_write_to_buffer(&cal_data, sizeof(cal_data), ppos, from, count);
1243	if (ret)
1244		return ret;
1245
1246	ret = cs35l56_stash_calibration(cs35l56_base, &cal_data);
1247	if (ret)
1248		return ret;
1249
1250	return count;
1251}
1252EXPORT_SYMBOL_NS_GPL(cs35l56_cal_data_debugfs_write, "SND_SOC_CS35L56_SHARED");
1253
1254void cs35l56_create_cal_debugfs(struct cs35l56_base *cs35l56_base,
1255				const struct cs35l56_cal_debugfs_fops *fops)
1256{
1257	if (!IS_ENABLED(CONFIG_SND_SOC_CS35L56_CAL_DEBUGFS_COMMON))
1258		return;
1259
1260	cs35l56_base->debugfs = cs_amp_create_debugfs(cs35l56_base->dev);
1261
1262	debugfs_create_file("calibrate",
1263			    0200, cs35l56_base->debugfs, cs35l56_base,
1264			    &fops->calibrate);
1265	debugfs_create_file("cal_temperature",
1266			    0200, cs35l56_base->debugfs, cs35l56_base,
1267			    &fops->cal_temperature);
1268	debugfs_create_file("cal_data",
1269			    0644, cs35l56_base->debugfs, cs35l56_base,
1270			    &fops->cal_data);
1271}
1272EXPORT_SYMBOL_NS_GPL(cs35l56_create_cal_debugfs, "SND_SOC_CS35L56_SHARED");
1273
1274void cs35l56_remove_cal_debugfs(struct cs35l56_base *cs35l56_base)
1275{
1276	debugfs_remove_recursive(cs35l56_base->debugfs);
1277}
1278EXPORT_SYMBOL_NS_GPL(cs35l56_remove_cal_debugfs, "SND_SOC_CS35L56_SHARED");
1279
1280const char * const cs35l56_cal_set_status_text[] = {
1281	"Unknown", "Default", "Set",
1282};
1283EXPORT_SYMBOL_NS_GPL(cs35l56_cal_set_status_text, "SND_SOC_CS35L56_SHARED");
1284
1285int cs35l56_cal_set_status_get(struct cs35l56_base *cs35l56_base,
1286			       struct snd_ctl_elem_value *uvalue)
1287{
1288	struct cs_dsp *dsp = cs35l56_base->dsp;
1289	__be32 cal_set_status_be;
1290	int alg_id;
1291	int ret;
1292
1293	switch (cs35l56_base->type) {
1294	case 0x54:
1295	case 0x56:
1296	case 0x57:
1297		alg_id = 0x9f210;
1298		break;
1299	default:
1300		alg_id = 0xbf210;
1301		break;
1302	}
1303
1304	scoped_guard(mutex, &dsp->pwr_lock) {
1305		ret = cs_dsp_coeff_read_ctrl(cs_dsp_get_ctl(dsp,
1306							    "CAL_SET_STATUS",
1307							    WMFW_ADSP2_YM, alg_id),
1308					      0, &cal_set_status_be,
1309					      sizeof(cal_set_status_be));
1310	}
1311	if (ret) {
1312		uvalue->value.enumerated.item[0] = CS35L56_CAL_SET_STATUS_UNKNOWN;
1313		return 0;
1314	}
1315
1316	switch (be32_to_cpu(cal_set_status_be)) {
1317	case CS35L56_CAL_SET_STATUS_DEFAULT:
1318	case CS35L56_CAL_SET_STATUS_SET:
1319		uvalue->value.enumerated.item[0] = be32_to_cpu(cal_set_status_be);
1320		return 0;
1321	default:
1322		uvalue->value.enumerated.item[0] = CS35L56_CAL_SET_STATUS_UNKNOWN;
1323		return 0;
1324	}
1325}
1326EXPORT_SYMBOL_NS_GPL(cs35l56_cal_set_status_get, "SND_SOC_CS35L56_SHARED");
1327
1328int cs35l56_read_prot_status(struct cs35l56_base *cs35l56_base,
1329			     bool *fw_missing, unsigned int *fw_version)
1330{
1331	unsigned int prot_status;
1332	int ret;
1333
1334	ret = regmap_read(cs35l56_base->regmap,
1335			  cs35l56_base->fw_reg->prot_sts, &prot_status);
1336	if (ret) {
1337		dev_err(cs35l56_base->dev, "Get PROTECTION_STATUS failed: %d\n", ret);
1338		return ret;
1339	}
1340
1341	*fw_missing = !!(prot_status & CS35L56_FIRMWARE_MISSING);
1342
1343	ret = regmap_read(cs35l56_base->regmap,
1344			  cs35l56_base->fw_reg->fw_ver, fw_version);
1345	if (ret) {
1346		dev_err(cs35l56_base->dev, "Get FW VER failed: %d\n", ret);
1347		return ret;
1348	}
1349
1350	return 0;
1351}
1352EXPORT_SYMBOL_NS_GPL(cs35l56_read_prot_status, "SND_SOC_CS35L56_SHARED");
1353
1354void cs35l56_warn_if_firmware_missing(struct cs35l56_base *cs35l56_base)
1355{
1356	unsigned int firmware_version;
1357	bool firmware_missing;
1358	int ret;
1359
1360	ret = cs35l56_read_prot_status(cs35l56_base, &firmware_missing, &firmware_version);
1361	if (ret)
1362		return;
1363
1364	if (!firmware_missing)
1365		return;
1366
1367	dev_warn(cs35l56_base->dev, "FIRMWARE_MISSING\n");
1368}
1369EXPORT_SYMBOL_NS_GPL(cs35l56_warn_if_firmware_missing, "SND_SOC_CS35L56_SHARED");
1370
1371void cs35l56_log_tuning(struct cs35l56_base *cs35l56_base, struct cs_dsp *cs_dsp)
1372{
1373	__be32 pid, sid, tid;
1374	unsigned int alg_id;
1375	int ret;
1376
1377	switch (cs35l56_base->type) {
1378	case 0x54:
1379	case 0x56:
1380	case 0x57:
1381		alg_id = 0x9f212;
1382		break;
1383	default:
1384		alg_id = 0xbf212;
1385		break;
1386	}
1387
1388	scoped_guard(mutex, &cs_dsp->pwr_lock) {
1389		ret = cs_dsp_coeff_read_ctrl(cs_dsp_get_ctl(cs_dsp, "AS_PRJCT_ID",
1390							    WMFW_ADSP2_XM, alg_id),
1391					     0, &pid, sizeof(pid));
1392		if (!ret)
1393			ret = cs_dsp_coeff_read_ctrl(cs_dsp_get_ctl(cs_dsp, "AS_CHNNL_ID",
1394								    WMFW_ADSP2_XM, alg_id),
1395						     0, &sid, sizeof(sid));
1396		if (!ret)
1397			ret = cs_dsp_coeff_read_ctrl(cs_dsp_get_ctl(cs_dsp, "AS_SNPSHT_ID",
1398								    WMFW_ADSP2_XM, alg_id),
1399						     0, &tid, sizeof(tid));
1400	}
1401
1402	if (ret)
1403		dev_warn(cs35l56_base->dev, "Can't read tuning IDs");
1404	else
1405		dev_info(cs35l56_base->dev, "Tuning PID: %#x, SID: %#x, TID: %#x\n",
1406			 be32_to_cpu(pid), be32_to_cpu(sid), be32_to_cpu(tid));
1407}
1408EXPORT_SYMBOL_NS_GPL(cs35l56_log_tuning, "SND_SOC_CS35L56_SHARED");
1409
1410int cs35l56_hw_init(struct cs35l56_base *cs35l56_base)
1411{
1412	int ret;
1413	unsigned int devid, revid, otpid, secured, fw_ver;
1414	bool fw_missing;
1415
1416	/*
1417	 * When the system is not using a reset_gpio ensure the device is
1418	 * awake, otherwise the device has just been released from reset and
1419	 * the driver must wait for the control port to become usable.
1420	 */
1421	if (!cs35l56_base->reset_gpio)
1422		cs35l56_issue_wake_event(cs35l56_base);
1423	else
1424		cs35l56_wait_control_port_ready();
1425
1426	ret = regmap_read_bypassed(cs35l56_base->regmap, CS35L56_REVID, &revid);
1427	if (ret < 0) {
1428		dev_err(cs35l56_base->dev, "Get Revision ID failed\n");
1429		return ret;
1430	}
1431	cs35l56_base->rev = revid & (CS35L56_AREVID_MASK | CS35L56_MTLREVID_MASK);
1432	cs35l56_set_fw_reg_table(cs35l56_base);
1433
1434	ret = cs35l56_wait_for_firmware_boot(cs35l56_base);
1435	if (ret)
1436		return ret;
1437
1438	ret = regmap_read_bypassed(cs35l56_base->regmap, CS35L56_DEVID, &devid);
1439	if (ret < 0) {
1440		dev_err(cs35l56_base->dev, "Get Device ID failed\n");
1441		return ret;
1442	}
1443	devid &= CS35L56_DEVID_MASK;
1444
1445	switch (devid) {
1446	case 0x35A54:
1447	case 0x35A56:
1448	case 0x35A57:
1449		cs35l56_base->calibration_controls = &cs35l56_calibration_controls;
1450		break;
1451	case 0x35A630:
1452		cs35l56_base->calibration_controls = &cs35l63_calibration_controls;
1453		devid = devid >> 4;
1454		break;
1455	default:
1456		dev_err(cs35l56_base->dev, "Unknown device %x\n", devid);
1457		return -ENODEV;
1458	}
1459
1460	cs35l56_base->type = devid & 0xFF;
1461
1462	/* Silicon is now identified and booted so exit cache-only */
1463	regcache_cache_only(cs35l56_base->regmap, false);
1464
1465	ret = regmap_read(cs35l56_base->regmap, CS35L56_DSP_RESTRICT_STS1, &secured);
1466	if (ret) {
1467		dev_err(cs35l56_base->dev, "Get Secure status failed\n");
1468		return ret;
1469	}
1470
1471	/* When any bus is restricted treat the device as secured */
1472	if (secured & CS35L56_RESTRICTED_MASK)
1473		cs35l56_base->secured = true;
1474
1475	ret = regmap_read(cs35l56_base->regmap, CS35L56_OTPID, &otpid);
1476	if (ret < 0) {
1477		dev_err(cs35l56_base->dev, "Get OTP ID failed\n");
1478		return ret;
1479	}
1480
1481	ret = cs35l56_read_prot_status(cs35l56_base, &fw_missing, &fw_ver);
1482	if (ret)
1483		return ret;
1484
1485	dev_info(cs35l56_base->dev, "Cirrus Logic CS35L%02X%s Rev %02X OTP%d fw:%d.%d.%d (patched=%u)\n",
1486		 cs35l56_base->type, cs35l56_base->secured ? "s" : "", cs35l56_base->rev, otpid,
1487		 fw_ver >> 16, (fw_ver >> 8) & 0xff, fw_ver & 0xff, !fw_missing);
1488
1489	/* Wake source and *_BLOCKED interrupts default to unmasked, so mask them */
1490	regmap_write(cs35l56_base->regmap, CS35L56_IRQ1_MASK_20, 0xffffffff);
1491	regmap_update_bits(cs35l56_base->regmap, CS35L56_IRQ1_MASK_1,
1492			   CS35L56_AMP_SHORT_ERR_EINT1_MASK,
1493			   0);
1494	regmap_update_bits(cs35l56_base->regmap, CS35L56_IRQ1_MASK_8,
1495			   CS35L56_TEMP_ERR_EINT1_MASK,
1496			   0);
1497
1498	switch (cs35l56_base->type) {
1499	case 0x54:
1500	case 0x56:
1501	case 0x57:
1502		ret = cs35l56_read_silicon_uid(cs35l56_base);
1503		break;
1504	default:
1505		ret = cs35l63_read_silicon_uid(cs35l56_base);
1506		break;
1507	}
1508	if (ret)
1509		return ret;
1510
1511	dev_dbg(cs35l56_base->dev, "SiliconID = %#llx\n", cs35l56_base->silicon_uid);
1512
1513	return 0;
1514}
1515EXPORT_SYMBOL_NS_GPL(cs35l56_hw_init, "SND_SOC_CS35L56_SHARED");
1516
1517int cs35l56_get_speaker_id(struct cs35l56_base *cs35l56_base)
1518{
1519	struct gpio_descs *descs;
1520	u32 speaker_id;
1521	int i, ret;
1522
1523	/* Check for vendor-specific speaker ID method */
1524	ret = cs_amp_get_vendor_spkid(cs35l56_base->dev);
1525	if (ret >= 0) {
1526		dev_dbg(cs35l56_base->dev, "Vendor Speaker ID = %d\n", ret);
1527		return ret;
1528	} else if (ret != -ENOENT) {
1529		dev_err(cs35l56_base->dev, "Error getting vendor Speaker ID: %d\n", ret);
1530		return ret;
1531	}
1532
1533	/* Attempt to read the speaker type from a device property */
1534	ret = device_property_read_u32(cs35l56_base->dev, "cirrus,speaker-id", &speaker_id);
1535	if (!ret) {
1536		dev_dbg(cs35l56_base->dev, "Speaker ID = %d\n", speaker_id);
1537		return speaker_id;
1538	}
1539
1540	/* Read the speaker type qualifier from the motherboard GPIOs */
1541	descs = gpiod_get_array_optional(cs35l56_base->dev, "spk-id", GPIOD_IN);
1542	if (!descs) {
1543		return -ENOENT;
1544	} else if (IS_ERR(descs)) {
1545		ret = PTR_ERR(descs);
1546		return dev_err_probe(cs35l56_base->dev, ret, "Failed to get spk-id-gpios\n");
1547	}
1548
1549	speaker_id = 0;
1550	for (i = 0; i < descs->ndescs; i++) {
1551		ret = gpiod_get_value_cansleep(descs->desc[i]);
1552		if (ret < 0) {
1553			dev_err_probe(cs35l56_base->dev, ret, "Failed to read spk-id[%d]\n", i);
1554			goto err;
1555		}
1556
1557		speaker_id |= (ret << i);
1558	}
1559
1560	dev_dbg(cs35l56_base->dev, "Speaker ID = %d\n", speaker_id);
1561	ret = speaker_id;
1562err:
1563	gpiod_put_array(descs);
1564
1565	return ret;
1566}
1567EXPORT_SYMBOL_NS_GPL(cs35l56_get_speaker_id, "SND_SOC_CS35L56_SHARED");
1568
1569static const u32 cs35l56_bclk_valid_for_pll_freq_table[] = {
1570	[0x0C] = 128000,
1571	[0x0F] = 256000,
1572	[0x11] = 384000,
1573	[0x12] = 512000,
1574	[0x15] = 768000,
1575	[0x17] = 1024000,
1576	[0x1A] = 1500000,
1577	[0x1B] = 1536000,
1578	[0x1C] = 2000000,
1579	[0x1D] = 2048000,
1580	[0x1E] = 2400000,
1581	[0x20] = 3000000,
1582	[0x21] = 3072000,
1583	[0x23] = 4000000,
1584	[0x24] = 4096000,
1585	[0x25] = 4800000,
1586	[0x27] = 6000000,
1587	[0x28] = 6144000,
1588	[0x29] = 6250000,
1589	[0x2A] = 6400000,
1590	[0x2E] = 8000000,
1591	[0x2F] = 8192000,
1592	[0x30] = 9600000,
1593	[0x32] = 12000000,
1594	[0x33] = 12288000,
1595	[0x37] = 13500000,
1596	[0x38] = 19200000,
1597	[0x39] = 22579200,
1598	[0x3B] = 24576000,
1599};
1600
1601int cs35l56_get_bclk_freq_id(unsigned int freq)
1602{
1603	int i;
1604
1605	if (freq == 0)
1606		return -EINVAL;
1607
1608	/* The BCLK frequency must be a valid PLL REFCLK */
1609	for (i = 0; i < ARRAY_SIZE(cs35l56_bclk_valid_for_pll_freq_table); ++i) {
1610		if (cs35l56_bclk_valid_for_pll_freq_table[i] == freq)
1611			return i;
1612	}
1613
1614	return -EINVAL;
1615}
1616EXPORT_SYMBOL_NS_GPL(cs35l56_get_bclk_freq_id, "SND_SOC_CS35L56_SHARED");
1617
1618static const char * const cs35l56_supplies[/* auto-sized */] = {
1619	"VDD_P",
1620	"VDD_IO",
1621	"VDD_A",
1622};
1623
1624void cs35l56_fill_supply_names(struct regulator_bulk_data *data)
1625{
1626	int i;
1627
1628	BUILD_BUG_ON(ARRAY_SIZE(cs35l56_supplies) != CS35L56_NUM_BULK_SUPPLIES);
1629	for (i = 0; i < ARRAY_SIZE(cs35l56_supplies); i++)
1630		data[i].supply = cs35l56_supplies[i];
1631}
1632EXPORT_SYMBOL_NS_GPL(cs35l56_fill_supply_names, "SND_SOC_CS35L56_SHARED");
1633
1634const char * const cs35l56_tx_input_texts[] = {
1635	"None", "ASP1RX1", "ASP1RX2", "VMON", "IMON", "ERRVOL", "CLASSH",
1636	"VDDBMON", "VBSTMON", "DSP1TX1", "DSP1TX2", "DSP1TX3", "DSP1TX4",
1637	"DSP1TX5", "DSP1TX6", "DSP1TX7", "DSP1TX8", "TEMPMON",
1638	"INTERPOLATOR", "SDW1RX1", "SDW1RX2",
1639};
1640EXPORT_SYMBOL_NS_GPL(cs35l56_tx_input_texts, "SND_SOC_CS35L56_SHARED");
1641
1642const unsigned int cs35l56_tx_input_values[] = {
1643	CS35L56_INPUT_SRC_NONE,
1644	CS35L56_INPUT_SRC_ASP1RX1,
1645	CS35L56_INPUT_SRC_ASP1RX2,
1646	CS35L56_INPUT_SRC_VMON,
1647	CS35L56_INPUT_SRC_IMON,
1648	CS35L56_INPUT_SRC_ERR_VOL,
1649	CS35L56_INPUT_SRC_CLASSH,
1650	CS35L56_INPUT_SRC_VDDBMON,
1651	CS35L56_INPUT_SRC_VBSTMON,
1652	CS35L56_INPUT_SRC_DSP1TX1,
1653	CS35L56_INPUT_SRC_DSP1TX2,
1654	CS35L56_INPUT_SRC_DSP1TX3,
1655	CS35L56_INPUT_SRC_DSP1TX4,
1656	CS35L56_INPUT_SRC_DSP1TX5,
1657	CS35L56_INPUT_SRC_DSP1TX6,
1658	CS35L56_INPUT_SRC_DSP1TX7,
1659	CS35L56_INPUT_SRC_DSP1TX8,
1660	CS35L56_INPUT_SRC_TEMPMON,
1661	CS35L56_INPUT_SRC_INTERPOLATOR,
1662	CS35L56_INPUT_SRC_SWIRE_DP1_CHANNEL1,
1663	CS35L56_INPUT_SRC_SWIRE_DP1_CHANNEL2,
1664};
1665EXPORT_SYMBOL_NS_GPL(cs35l56_tx_input_values, "SND_SOC_CS35L56_SHARED");
1666
1667const struct regmap_config cs35l56_regmap_i2c = {
1668	.reg_bits = 32,
1669	.val_bits = 32,
1670	.reg_stride = 4,
1671	.reg_format_endian = REGMAP_ENDIAN_BIG,
1672	.val_format_endian = REGMAP_ENDIAN_BIG,
1673	.max_register = CS35L56_DSP1_PMEM_5114,
1674	.reg_defaults = cs35l56_reg_defaults,
1675	.num_reg_defaults = ARRAY_SIZE(cs35l56_reg_defaults),
1676	.volatile_reg = cs35l56_volatile_reg,
1677	.readable_reg = cs35l56_readable_reg,
1678	.precious_reg = cs35l56_precious_reg,
1679	.cache_type = REGCACHE_MAPLE,
1680};
1681EXPORT_SYMBOL_NS_GPL(cs35l56_regmap_i2c, "SND_SOC_CS35L56_SHARED");
1682
1683const struct regmap_config cs35l56_regmap_spi = {
1684	.reg_bits = 32,
1685	.val_bits = 32,
1686	.pad_bits = 16,
1687	.reg_stride = 4,
1688	.reg_format_endian = REGMAP_ENDIAN_BIG,
1689	.val_format_endian = REGMAP_ENDIAN_BIG,
1690	.max_register = CS35L56_DSP1_PMEM_5114,
1691	.reg_defaults = cs35l56_reg_defaults,
1692	.num_reg_defaults = ARRAY_SIZE(cs35l56_reg_defaults),
1693	.volatile_reg = cs35l56_volatile_reg,
1694	.readable_reg = cs35l56_readable_reg,
1695	.precious_reg = cs35l56_precious_reg,
1696	.cache_type = REGCACHE_MAPLE,
1697};
1698EXPORT_SYMBOL_NS_GPL(cs35l56_regmap_spi, "SND_SOC_CS35L56_SHARED");
1699
1700const struct regmap_config cs35l56_regmap_sdw = {
1701	.reg_bits = 32,
1702	.val_bits = 32,
1703	.reg_stride = 4,
1704	.reg_format_endian = REGMAP_ENDIAN_LITTLE,
1705	.val_format_endian = REGMAP_ENDIAN_BIG,
1706	.max_register = CS35L56_DSP1_PMEM_5114,
1707	.reg_defaults = cs35l56_reg_defaults,
1708	.num_reg_defaults = ARRAY_SIZE(cs35l56_reg_defaults),
1709	.volatile_reg = cs35l56_volatile_reg,
1710	.readable_reg = cs35l56_readable_reg,
1711	.precious_reg = cs35l56_precious_reg,
1712	.cache_type = REGCACHE_MAPLE,
1713};
1714EXPORT_SYMBOL_NS_GPL(cs35l56_regmap_sdw, "SND_SOC_CS35L56_SHARED");
1715
1716const struct regmap_config cs35l63_regmap_i2c = {
1717	.reg_bits = 32,
1718	.val_bits = 32,
1719	.reg_stride = 4,
1720	.reg_base = 0x8000,
1721	.reg_format_endian = REGMAP_ENDIAN_BIG,
1722	.val_format_endian = REGMAP_ENDIAN_BIG,
1723	.max_register = CS35L56_DSP1_PMEM_5114,
1724	.reg_defaults = cs35l63_reg_defaults,
1725	.num_reg_defaults = ARRAY_SIZE(cs35l63_reg_defaults),
1726	.volatile_reg = cs35l63_volatile_reg,
1727	.readable_reg = cs35l56_readable_reg,
1728	.precious_reg = cs35l56_precious_reg,
1729	.cache_type = REGCACHE_MAPLE,
1730};
1731EXPORT_SYMBOL_NS_GPL(cs35l63_regmap_i2c, "SND_SOC_CS35L56_SHARED");
1732
1733const struct regmap_config cs35l63_regmap_sdw = {
1734	.reg_bits = 32,
1735	.val_bits = 32,
1736	.reg_stride = 4,
1737	.reg_format_endian = REGMAP_ENDIAN_LITTLE,
1738	.val_format_endian = REGMAP_ENDIAN_BIG,
1739	.max_register = CS35L56_DSP1_PMEM_5114,
1740	.reg_defaults = cs35l63_reg_defaults,
1741	.num_reg_defaults = ARRAY_SIZE(cs35l63_reg_defaults),
1742	.volatile_reg = cs35l63_volatile_reg,
1743	.readable_reg = cs35l56_readable_reg,
1744	.precious_reg = cs35l56_precious_reg,
1745	.cache_type = REGCACHE_MAPLE,
1746};
1747EXPORT_SYMBOL_NS_GPL(cs35l63_regmap_sdw, "SND_SOC_CS35L56_SHARED");
1748
1749MODULE_DESCRIPTION("ASoC CS35L56 Shared");
1750MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>");
1751MODULE_AUTHOR("Simon Trimmer <simont@opensource.cirrus.com>");
1752MODULE_LICENSE("GPL");
1753MODULE_IMPORT_NS("SND_SOC_CS_AMP_LIB");
1754MODULE_IMPORT_NS("FW_CS_DSP");
~/ Read-only file preview.