File Index
Files and directories
Sign in
FILE

cs48l32.c

File preview with syntax highlighting.

linux-6.19.14/sound/soc/codecs/cs48l32.c C
   1// SPDX-License-Identifier: GPL-2.0-only
   2//
   3// Cirrus Logic CS48L32 audio DSP.
   4//
   5// Copyright (C) 2016-2018, 2020, 2022, 2025 Cirrus Logic, Inc. and
   6//               Cirrus Logic International Semiconductor Ltd.
   7
   8#include <dt-bindings/sound/cs48l32.h>
   9#include <linux/array_size.h>
  10#include <linux/build_bug.h>
  11#include <linux/clk.h>
  12#include <linux/container_of.h>
  13#include <linux/delay.h>
  14#include <linux/err.h>
  15#include <linux/gcd.h>
  16#include <linux/gpio/consumer.h>
  17#include <linux/minmax.h>
  18#include <linux/module.h>
  19#include <linux/of.h>
  20#include <linux/pm_runtime.h>
  21#include <linux/property.h>
  22#include <linux/regmap.h>
  23#include <linux/regulator/consumer.h>
  24#include <linux/slab.h>
  25#include <linux/spi/spi.h>
  26#include <linux/string_choices.h>
  27#include <sound/cs48l32.h>
  28#include <sound/cs48l32_registers.h>
  29#include <sound/pcm.h>
  30#include <sound/pcm_params.h>
  31#include <sound/soc.h>
  32#include <sound/soc-component.h>
  33#include <sound/soc-dai.h>
  34#include <sound/soc-dapm.h>
  35#include <sound/tlv.h>
  36
  37#include "cs48l32.h"
  38
  39static const char * const cs48l32_core_supplies[] = { "vdd-a", "vdd-io" };
  40
  41static const struct cs_dsp_region cs48l32_dsp1_regions[] = {
  42	{ .type = WMFW_HALO_PM_PACKED, .base = 0x3800000 },
  43	{ .type = WMFW_HALO_XM_PACKED, .base = 0x2000000 },
  44	{ .type = WMFW_ADSP2_XM, .base = 0x2800000 },
  45	{ .type = WMFW_HALO_YM_PACKED, .base = 0x2C00000 },
  46	{ .type = WMFW_ADSP2_YM, .base = 0x3400000 },
  47};
  48
  49static const struct cs48l32_dsp_power_reg_block cs48l32_dsp1_sram_ext_regs[] = {
  50	{ CS48L32_DSP1_XM_SRAM_IBUS_SETUP_1, CS48L32_DSP1_XM_SRAM_IBUS_SETUP_24 },
  51	{ CS48L32_DSP1_YM_SRAM_IBUS_SETUP_1, CS48L32_DSP1_YM_SRAM_IBUS_SETUP_8 },
  52	{ CS48L32_DSP1_PM_SRAM_IBUS_SETUP_1, CS48L32_DSP1_PM_SRAM_IBUS_SETUP_7 },
  53};
  54
  55static const unsigned int cs48l32_dsp1_sram_pwd_regs[] = {
  56	CS48L32_DSP1_XM_SRAM_IBUS_SETUP_0,
  57	CS48L32_DSP1_YM_SRAM_IBUS_SETUP_0,
  58	CS48L32_DSP1_PM_SRAM_IBUS_SETUP_0,
  59};
  60
  61static const struct cs48l32_dsp_power_regs cs48l32_dsp_sram_regs = {
  62	.ext = cs48l32_dsp1_sram_ext_regs,
  63	.n_ext = ARRAY_SIZE(cs48l32_dsp1_sram_ext_regs),
  64	.pwd = cs48l32_dsp1_sram_pwd_regs,
  65	.n_pwd = ARRAY_SIZE(cs48l32_dsp1_sram_pwd_regs),
  66};
  67
  68static const char * const cs48l32_mixer_texts[] = {
  69	"None",
  70	"Tone Generator 1",
  71	"Tone Generator 2",
  72	"Noise Generator",
  73	"IN1L",
  74	"IN1R",
  75	"IN2L",
  76	"IN2R",
  77	"ASP1RX1",
  78	"ASP1RX2",
  79	"ASP1RX3",
  80	"ASP1RX4",
  81	"ASP1RX5",
  82	"ASP1RX6",
  83	"ASP1RX7",
  84	"ASP1RX8",
  85	"ASP2RX1",
  86	"ASP2RX2",
  87	"ASP2RX3",
  88	"ASP2RX4",
  89	"ISRC1INT1",
  90	"ISRC1INT2",
  91	"ISRC1INT3",
  92	"ISRC1INT4",
  93	"ISRC1DEC1",
  94	"ISRC1DEC2",
  95	"ISRC1DEC3",
  96	"ISRC1DEC4",
  97	"ISRC2INT1",
  98	"ISRC2INT2",
  99	"ISRC2DEC1",
 100	"ISRC2DEC2",
 101	"ISRC3INT1",
 102	"ISRC3INT2",
 103	"ISRC3DEC1",
 104	"ISRC3DEC2",
 105	"EQ1",
 106	"EQ2",
 107	"EQ3",
 108	"EQ4",
 109	"DRC1L",
 110	"DRC1R",
 111	"DRC2L",
 112	"DRC2R",
 113	"LHPF1",
 114	"LHPF2",
 115	"LHPF3",
 116	"LHPF4",
 117	"Ultrasonic 1",
 118	"Ultrasonic 2",
 119	"DSP1.1",
 120	"DSP1.2",
 121	"DSP1.3",
 122	"DSP1.4",
 123	"DSP1.5",
 124	"DSP1.6",
 125	"DSP1.7",
 126	"DSP1.8",
 127};
 128
 129static unsigned int cs48l32_mixer_values[] = {
 130	0x000, /* Silence (mute) */
 131	0x004, /* Tone generator 1 */
 132	0x005, /* Tone generator 2 */
 133	0x00C, /* Noise Generator */
 134	0x010, /* IN1L signal path */
 135	0x011, /* IN1R signal path */
 136	0x012, /* IN2L signal path */
 137	0x013, /* IN2R signal path */
 138	0x020, /* ASP1 RX1 */
 139	0x021, /* ASP1 RX2 */
 140	0x022, /* ASP1 RX3 */
 141	0x023, /* ASP1 RX4 */
 142	0x024, /* ASP1 RX5 */
 143	0x025, /* ASP1 RX6 */
 144	0x026, /* ASP1 RX7 */
 145	0x027, /* ASP1 RX8 */
 146	0x030, /* ASP2 RX1 */
 147	0x031, /* ASP2 RX2 */
 148	0x032, /* ASP2 RX3 */
 149	0x033, /* ASP2 RX4 */
 150	0x098, /* ISRC1 INT1 */
 151	0x099, /* ISRC1 INT2 */
 152	0x09a, /* ISRC1 INT3 */
 153	0x09b, /* ISRC1 INT4 */
 154	0x09C, /* ISRC1 DEC1 */
 155	0x09D, /* ISRC1 DEC2 */
 156	0x09e, /* ISRC1 DEC3 */
 157	0x09f, /* ISRC1 DEC4 */
 158	0x0A0, /* ISRC2 INT1 */
 159	0x0A1, /* ISRC2 INT2 */
 160	0x0A4, /* ISRC2 DEC1 */
 161	0x0A5, /* ISRC2 DEC2 */
 162	0x0A8, /* ISRC3 INT1 */
 163	0x0A9, /* ISRC3 INT2 */
 164	0x0AC, /* ISRC3 DEC1 */
 165	0x0AD, /* ISRC3 DEC2 */
 166	0x0B8, /* EQ1 */
 167	0x0B9, /* EQ2 */
 168	0x0BA, /* EQ3 */
 169	0x0BB, /* EQ4 */
 170	0x0C0, /* DRC1 Left */
 171	0x0C1, /* DRC1 Right */
 172	0x0C2, /* DRC2 Left */
 173	0x0C3, /* DRC2 Right */
 174	0x0C8, /* LHPF1 */
 175	0x0C9, /* LHPF2 */
 176	0x0CA, /* LHPF3 */
 177	0x0CB, /* LHPF4 */
 178	0x0D8, /* Ultrasonic 1 */
 179	0x0D9, /* Ultrasonic 2 */
 180	0x100, /* DSP1 channel 1 */
 181	0x101, /* DSP1 channel 2 */
 182	0x102, /* DSP1 channel 3 */
 183	0x103, /* DSP1 channel 4 */
 184	0x104, /* DSP1 channel 5 */
 185	0x105, /* DSP1 channel 6 */
 186	0x106, /* DSP1 channel 7 */
 187	0x107, /* DSP1 channel 8 */
 188};
 189static_assert(ARRAY_SIZE(cs48l32_mixer_texts) == ARRAY_SIZE(cs48l32_mixer_values));
 190#define CS48L32_NUM_MIXER_INPUTS	ARRAY_SIZE(cs48l32_mixer_values)
 191
 192static const DECLARE_TLV_DB_SCALE(cs48l32_ana_tlv, 0, 100, 0);
 193static const DECLARE_TLV_DB_SCALE(cs48l32_eq_tlv, -1200, 100, 0);
 194static const DECLARE_TLV_DB_SCALE(cs48l32_digital_tlv, -6400, 50, 0);
 195static const DECLARE_TLV_DB_SCALE(cs48l32_noise_tlv, -10800, 600, 0);
 196static const DECLARE_TLV_DB_SCALE(cs48l32_mixer_tlv, -3200, 100, 0);
 197static const DECLARE_TLV_DB_SCALE(cs48l32_us_tlv, 0, 600, 0);
 198
 199static void cs48l32_spin_sysclk(struct cs48l32_codec *cs48l32_codec)
 200{
 201	struct cs48l32 *cs48l32 = &cs48l32_codec->core;
 202	unsigned int val;
 203	int ret, i;
 204
 205	/* Skip this if the chip is down */
 206	if (pm_runtime_suspended(cs48l32->dev))
 207		return;
 208
 209	/*
 210	 * Just read a register a few times to ensure the internal
 211	 * oscillator sends out some clocks.
 212	 */
 213	for (i = 0; i < 4; i++) {
 214		ret = regmap_read(cs48l32->regmap, CS48L32_DEVID, &val);
 215		if (ret)
 216			dev_err(cs48l32_codec->core.dev, "%s Failed to read register: %d (%d)\n",
 217				__func__, ret, i);
 218	}
 219
 220	udelay(300);
 221}
 222
 223static const char * const cs48l32_rate_text[] = {
 224	"Sample Rate 1", "Sample Rate 2", "Sample Rate 3", "Sample Rate 4",
 225};
 226
 227static const unsigned int cs48l32_rate_val[] = {
 228	0x0, 0x1, 0x2, 0x3,
 229};
 230static_assert(ARRAY_SIZE(cs48l32_rate_val) == ARRAY_SIZE(cs48l32_rate_text));
 231
 232static int cs48l32_rate_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 233{
 234	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
 235	struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
 236	int ret;
 237
 238	/* Prevent any mixer mux changes while we do this */
 239	mutex_lock(&cs48l32_codec->rate_lock);
 240
 241	/* The write must be guarded by a number of SYSCLK cycles */
 242	cs48l32_spin_sysclk(cs48l32_codec);
 243	ret = snd_soc_put_enum_double(kcontrol, ucontrol);
 244	cs48l32_spin_sysclk(cs48l32_codec);
 245
 246	mutex_unlock(&cs48l32_codec->rate_lock);
 247
 248	return ret;
 249}
 250
 251static const char * const cs48l32_sample_rate_text[] = {
 252	"12kHz",
 253	"24kHz",
 254	"48kHz",
 255	"96kHz",
 256	"192kHz",
 257	"384kHz",
 258	"768kHz",
 259	"11.025kHz",
 260	"22.05kHz",
 261	"44.1kHz",
 262	"88.2kHz",
 263	"176.4kHz",
 264	"352.8kHz",
 265	"705.6kHz",
 266	"8kHz",
 267	"16kHz",
 268	"32kHz",
 269};
 270
 271static const unsigned int cs48l32_sample_rate_val[] = {
 272	0x01, /* 12kHz */
 273	0x02, /* 24kHz */
 274	0x03, /* 48kHz */
 275	0x04, /* 96kHz */
 276	0x05, /* 192kHz */
 277	0x06, /* 384kHz */
 278	0x07, /* 768kHz */
 279	0x09, /* 11.025kHz */
 280	0x0a, /* 22.05kHz */
 281	0x0b, /* 44.1kHz */
 282	0x0c, /* 88.2kHz */
 283	0x0d, /* 176.4kHz */
 284	0x0e, /* 352.8kHz */
 285	0x0f, /* 705.6kHz */
 286	0x11, /* 8kHz */
 287	0x12, /* 16kHz */
 288	0x13, /* 32kHz */
 289};
 290static_assert(ARRAY_SIZE(cs48l32_sample_rate_val) == ARRAY_SIZE(cs48l32_sample_rate_text));
 291#define CS48L32_SAMPLE_RATE_ENUM_SIZE	ARRAY_SIZE(cs48l32_sample_rate_val)
 292
 293static const struct soc_enum cs48l32_sample_rate[] = {
 294	SOC_VALUE_ENUM_SINGLE(CS48L32_SAMPLE_RATE1,
 295			      CS48L32_SAMPLE_RATE_1_SHIFT,
 296			      CS48L32_SAMPLE_RATE_1_MASK >> CS48L32_SAMPLE_RATE_1_SHIFT,
 297			      CS48L32_SAMPLE_RATE_ENUM_SIZE,
 298			      cs48l32_sample_rate_text,
 299			      cs48l32_sample_rate_val),
 300	SOC_VALUE_ENUM_SINGLE(CS48L32_SAMPLE_RATE2,
 301			      CS48L32_SAMPLE_RATE_1_SHIFT,
 302			      CS48L32_SAMPLE_RATE_1_MASK >> CS48L32_SAMPLE_RATE_1_SHIFT,
 303			      CS48L32_SAMPLE_RATE_ENUM_SIZE,
 304			      cs48l32_sample_rate_text,
 305			      cs48l32_sample_rate_val),
 306	SOC_VALUE_ENUM_SINGLE(CS48L32_SAMPLE_RATE3,
 307			      CS48L32_SAMPLE_RATE_1_SHIFT,
 308			      CS48L32_SAMPLE_RATE_1_MASK >> CS48L32_SAMPLE_RATE_1_SHIFT,
 309			      CS48L32_SAMPLE_RATE_ENUM_SIZE,
 310			      cs48l32_sample_rate_text,
 311			      cs48l32_sample_rate_val),
 312	SOC_VALUE_ENUM_SINGLE(CS48L32_SAMPLE_RATE4,
 313			      CS48L32_SAMPLE_RATE_1_SHIFT,
 314			      CS48L32_SAMPLE_RATE_1_MASK >> CS48L32_SAMPLE_RATE_1_SHIFT,
 315			      CS48L32_SAMPLE_RATE_ENUM_SIZE,
 316			      cs48l32_sample_rate_text,
 317			      cs48l32_sample_rate_val),
 318};
 319
 320static int cs48l32_inmux_put(struct snd_kcontrol *kcontrol,
 321			     struct snd_ctl_elem_value *ucontrol)
 322{
 323	struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol);
 324	struct snd_soc_component *component = snd_soc_dapm_to_component(dapm);
 325	struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
 326	struct soc_enum *e = (struct soc_enum *) kcontrol->private_value;
 327	unsigned int mux, src_val, in_type;
 328	int ret;
 329
 330	mux = ucontrol->value.enumerated.item[0];
 331	if (mux > 1)
 332		return -EINVAL;
 333
 334	switch (e->reg) {
 335	case CS48L32_IN1L_CONTROL1:
 336		in_type = cs48l32_codec->in_type[0][mux];
 337		break;
 338	case CS48L32_IN1R_CONTROL1:
 339		in_type = cs48l32_codec->in_type[1][mux];
 340		break;
 341	default:
 342		return -EINVAL;
 343	}
 344
 345	src_val = mux << e->shift_l;
 346
 347	if (in_type == CS48L32_IN_TYPE_SE)
 348		src_val |= 1 << CS48L32_INx_SRC_SHIFT;
 349
 350	ret = snd_soc_component_update_bits(component,
 351					    e->reg,
 352					    CS48L32_INx_SRC_MASK,
 353					    src_val);
 354	if (ret > 0)
 355		snd_soc_dapm_mux_update_power(dapm, kcontrol, mux, e, NULL);
 356
 357	return ret;
 358}
 359
 360static const char * const cs48l32_inmux_texts[] = {
 361	"Analog 1", "Analog 2",
 362};
 363
 364static SOC_ENUM_SINGLE_DECL(cs48l32_in1muxl_enum,
 365			    CS48L32_IN1L_CONTROL1,
 366			    CS48L32_INx_SRC_SHIFT + 1,
 367			    cs48l32_inmux_texts);
 368
 369static SOC_ENUM_SINGLE_DECL(cs48l32_in1muxr_enum,
 370			    CS48L32_IN1R_CONTROL1,
 371			    CS48L32_INx_SRC_SHIFT + 1,
 372			    cs48l32_inmux_texts);
 373
 374static const struct snd_kcontrol_new cs48l32_inmux[] = {
 375	SOC_DAPM_ENUM_EXT("IN1L Mux", cs48l32_in1muxl_enum,
 376			  snd_soc_dapm_get_enum_double, cs48l32_inmux_put),
 377	SOC_DAPM_ENUM_EXT("IN1R Mux", cs48l32_in1muxr_enum,
 378			  snd_soc_dapm_get_enum_double, cs48l32_inmux_put),
 379};
 380
 381static const char * const cs48l32_dmode_texts[] = {
 382	"Analog", "Digital",
 383};
 384
 385static int cs48l32_dmode_put(struct snd_kcontrol *kcontrol,
 386			     struct snd_ctl_elem_value *ucontrol)
 387{
 388	struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol);
 389	struct snd_soc_component *component = snd_soc_dapm_to_component(dapm);
 390	struct soc_enum *e = (struct soc_enum *) kcontrol->private_value;
 391	unsigned int mode;
 392	int ret, result;
 393
 394	mode = ucontrol->value.enumerated.item[0];
 395	switch (mode) {
 396	case 0:
 397		ret = snd_soc_component_update_bits(component,
 398						    CS48L32_ADC1L_ANA_CONTROL1,
 399						    CS48L32_ADC1x_INT_ENA_FRC_MASK,
 400						    CS48L32_ADC1x_INT_ENA_FRC_MASK);
 401		if (ret < 0) {
 402			dev_err(component->dev,
 403				"Failed to set ADC1L_INT_ENA_FRC: %d\n", ret);
 404			return ret;
 405		}
 406
 407		ret = snd_soc_component_update_bits(component,
 408						    CS48L32_ADC1R_ANA_CONTROL1,
 409						    CS48L32_ADC1x_INT_ENA_FRC_MASK,
 410						    CS48L32_ADC1x_INT_ENA_FRC_MASK);
 411		if (ret < 0) {
 412			dev_err(component->dev,
 413				"Failed to set ADC1R_INT_ENA_FRC: %d\n", ret);
 414			return ret;
 415		}
 416
 417		result = snd_soc_component_update_bits(component,
 418						       e->reg,
 419						       BIT(CS48L32_IN1_MODE_SHIFT),
 420						       0);
 421		if (result < 0) {
 422			dev_err(component->dev, "Failed to set input mode: %d\n", result);
 423			return result;
 424		}
 425
 426		usleep_range(200, 300);
 427
 428		ret = snd_soc_component_update_bits(component,
 429						    CS48L32_ADC1L_ANA_CONTROL1,
 430						    CS48L32_ADC1x_INT_ENA_FRC_MASK,
 431						    0);
 432		if (ret < 0) {
 433			dev_err(component->dev,
 434				"Failed to clear ADC1L_INT_ENA_FRC: %d\n", ret);
 435			return ret;
 436		}
 437
 438		ret = snd_soc_component_update_bits(component,
 439						    CS48L32_ADC1R_ANA_CONTROL1,
 440						    CS48L32_ADC1x_INT_ENA_FRC_MASK,
 441						    0);
 442		if (ret < 0) {
 443			dev_err(component->dev,
 444				"Failed to clear ADC1R_INT_ENA_FRC: %d\n", ret);
 445			return ret;
 446		}
 447
 448		if (result > 0)
 449			snd_soc_dapm_mux_update_power(dapm, kcontrol, mode, e, NULL);
 450
 451		return result;
 452	case 1:
 453		return snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
 454	default:
 455		return -EINVAL;
 456	}
 457}
 458
 459static SOC_ENUM_SINGLE_DECL(cs48l32_in1dmode_enum,
 460			    CS48L32_INPUT1_CONTROL1,
 461			    CS48L32_IN1_MODE_SHIFT,
 462			    cs48l32_dmode_texts);
 463
 464static const struct snd_kcontrol_new cs48l32_dmode_mux[] = {
 465	SOC_DAPM_ENUM_EXT("IN1 Mode", cs48l32_in1dmode_enum,
 466			  snd_soc_dapm_get_enum_double, cs48l32_dmode_put),
 467};
 468
 469static const char * const cs48l32_in_texts[] = {
 470	"IN1L", "IN1R", "IN2L", "IN2R",
 471};
 472static_assert(ARRAY_SIZE(cs48l32_in_texts) == CS48L32_MAX_INPUT);
 473
 474static const char * const cs48l32_us_freq_texts[] = {
 475	"16-24kHz", "20-28kHz",
 476};
 477
 478static const unsigned int cs48l32_us_freq_val[] = {
 479	0x2, 0x3,
 480};
 481
 482static const struct soc_enum cs48l32_us_freq[] = {
 483	SOC_VALUE_ENUM_SINGLE(CS48L32_US1_CONTROL,
 484			      CS48L32_US1_FREQ_SHIFT,
 485			      CS48L32_US1_FREQ_MASK >> CS48L32_US1_FREQ_SHIFT,
 486			      ARRAY_SIZE(cs48l32_us_freq_val),
 487			      cs48l32_us_freq_texts,
 488			      cs48l32_us_freq_val),
 489	SOC_VALUE_ENUM_SINGLE(CS48L32_US2_CONTROL,
 490			      CS48L32_US1_FREQ_SHIFT,
 491			      CS48L32_US1_FREQ_MASK >> CS48L32_US1_FREQ_SHIFT,
 492			      ARRAY_SIZE(cs48l32_us_freq_val),
 493			      cs48l32_us_freq_texts,
 494			      cs48l32_us_freq_val),
 495};
 496
 497static const unsigned int cs48l32_us_in_val[] = {
 498	0x0, 0x1, 0x2, 0x3,
 499};
 500
 501static const struct soc_enum cs48l32_us_inmux_enum[] = {
 502	SOC_VALUE_ENUM_SINGLE(CS48L32_US1_CONTROL,
 503			      CS48L32_US1_SRC_SHIFT,
 504			      CS48L32_US1_SRC_MASK >> CS48L32_US1_SRC_SHIFT,
 505			      ARRAY_SIZE(cs48l32_us_in_val),
 506			      cs48l32_in_texts,
 507			      cs48l32_us_in_val),
 508	SOC_VALUE_ENUM_SINGLE(CS48L32_US2_CONTROL,
 509			      CS48L32_US1_SRC_SHIFT,
 510			      CS48L32_US1_SRC_MASK >> CS48L32_US1_SRC_SHIFT,
 511			      ARRAY_SIZE(cs48l32_us_in_val),
 512			      cs48l32_in_texts,
 513			      cs48l32_us_in_val),
 514};
 515
 516static const struct snd_kcontrol_new cs48l32_us_inmux[] = {
 517	SOC_DAPM_ENUM("Ultrasonic 1 Input", cs48l32_us_inmux_enum[0]),
 518	SOC_DAPM_ENUM("Ultrasonic 2 Input", cs48l32_us_inmux_enum[1]),
 519};
 520
 521static const char * const cs48l32_us_det_thr_texts[] = {
 522	"-6dB", "-9dB", "-12dB", "-15dB", "-18dB", "-21dB", "-24dB", "-27dB",
 523};
 524
 525static const struct soc_enum cs48l32_us_det_thr[] = {
 526	SOC_ENUM_SINGLE(CS48L32_US1_DET_CONTROL,
 527			CS48L32_US1_DET_THR_SHIFT,
 528			ARRAY_SIZE(cs48l32_us_det_thr_texts),
 529			cs48l32_us_det_thr_texts),
 530	SOC_ENUM_SINGLE(CS48L32_US2_DET_CONTROL,
 531			CS48L32_US1_DET_THR_SHIFT,
 532			ARRAY_SIZE(cs48l32_us_det_thr_texts),
 533			cs48l32_us_det_thr_texts),
 534};
 535
 536static const char * const cs48l32_us_det_num_texts[] = {
 537	"1 Sample",
 538	"2 Samples",
 539	"4 Samples",
 540	"8 Samples",
 541	"16 Samples",
 542	"32 Samples",
 543	"64 Samples",
 544	"128 Samples",
 545	"256 Samples",
 546	"512 Samples",
 547	"1024 Samples",
 548	"2048 Samples",
 549	"4096 Samples",
 550	"8192 Samples",
 551	"16384 Samples",
 552	"32768 Samples",
 553};
 554
 555static const struct soc_enum cs48l32_us_det_num[] = {
 556	SOC_ENUM_SINGLE(CS48L32_US1_DET_CONTROL,
 557			CS48L32_US1_DET_NUM_SHIFT,
 558			ARRAY_SIZE(cs48l32_us_det_num_texts),
 559			cs48l32_us_det_num_texts),
 560	SOC_ENUM_SINGLE(CS48L32_US2_DET_CONTROL,
 561			CS48L32_US1_DET_NUM_SHIFT,
 562			ARRAY_SIZE(cs48l32_us_det_num_texts),
 563			cs48l32_us_det_num_texts),
 564};
 565
 566static const char * const cs48l32_us_det_hold_texts[] = {
 567	"0 Samples",
 568	"31 Samples",
 569	"63 Samples",
 570	"127 Samples",
 571	"255 Samples",
 572	"511 Samples",
 573	"1023 Samples",
 574	"2047 Samples",
 575	"4095 Samples",
 576	"8191 Samples",
 577	"16383 Samples",
 578	"32767 Samples",
 579	"65535 Samples",
 580	"131071 Samples",
 581	"262143 Samples",
 582	"524287 Samples",
 583};
 584
 585static const struct soc_enum cs48l32_us_det_hold[] = {
 586	SOC_ENUM_SINGLE(CS48L32_US1_DET_CONTROL,
 587			CS48L32_US1_DET_HOLD_SHIFT,
 588			ARRAY_SIZE(cs48l32_us_det_hold_texts),
 589			cs48l32_us_det_hold_texts),
 590	SOC_ENUM_SINGLE(CS48L32_US2_DET_CONTROL,
 591			CS48L32_US1_DET_HOLD_SHIFT,
 592			ARRAY_SIZE(cs48l32_us_det_hold_texts),
 593			cs48l32_us_det_hold_texts),
 594};
 595
 596static const struct soc_enum cs48l32_us_output_rate[] = {
 597	SOC_VALUE_ENUM_SINGLE(CS48L32_US1_CONTROL,
 598			      CS48L32_US1_RATE_SHIFT,
 599			      CS48L32_US1_RATE_MASK >> CS48L32_US1_RATE_SHIFT,
 600			      ARRAY_SIZE(cs48l32_rate_text),
 601			      cs48l32_rate_text,
 602			      cs48l32_rate_val),
 603	SOC_VALUE_ENUM_SINGLE(CS48L32_US2_CONTROL,
 604			      CS48L32_US1_RATE_SHIFT,
 605			      CS48L32_US1_RATE_MASK >> CS48L32_US1_RATE_SHIFT,
 606			      ARRAY_SIZE(cs48l32_rate_text),
 607			      cs48l32_rate_text,
 608			      cs48l32_rate_val),
 609};
 610
 611static const char * const cs48l32_us_det_lpf_cut_texts[] = {
 612	"1722Hz", "833Hz", "408Hz", "203Hz",
 613};
 614
 615static const struct soc_enum cs48l32_us_det_lpf_cut[] = {
 616	SOC_ENUM_SINGLE(CS48L32_US1_DET_CONTROL,
 617			CS48L32_US1_DET_LPF_CUT_SHIFT,
 618			ARRAY_SIZE(cs48l32_us_det_lpf_cut_texts),
 619			cs48l32_us_det_lpf_cut_texts),
 620	SOC_ENUM_SINGLE(CS48L32_US2_DET_CONTROL,
 621			CS48L32_US1_DET_LPF_CUT_SHIFT,
 622			ARRAY_SIZE(cs48l32_us_det_lpf_cut_texts),
 623			cs48l32_us_det_lpf_cut_texts),
 624};
 625
 626static const char * const cs48l32_us_det_dcy_texts[] = {
 627	"0 ms", "0.79 ms", "1.58 ms", "3.16 ms", "6.33 ms", "12.67 ms", "25.34 ms", "50.69 ms",
 628};
 629
 630static const struct soc_enum cs48l32_us_det_dcy[] = {
 631	SOC_ENUM_SINGLE(CS48L32_US1_DET_CONTROL,
 632			CS48L32_US1_DET_DCY_SHIFT,
 633			ARRAY_SIZE(cs48l32_us_det_dcy_texts),
 634			cs48l32_us_det_dcy_texts),
 635	SOC_ENUM_SINGLE(CS48L32_US2_DET_CONTROL,
 636			CS48L32_US1_DET_DCY_SHIFT,
 637			ARRAY_SIZE(cs48l32_us_det_dcy_texts),
 638			cs48l32_us_det_dcy_texts),
 639};
 640
 641static const struct snd_kcontrol_new cs48l32_us_switch[] = {
 642	SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0),
 643	SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0),
 644};
 645
 646static const char * const cs48l32_vol_ramp_text[] = {
 647	"0ms/6dB", "0.5ms/6dB", "1ms/6dB", "2ms/6dB", "4ms/6dB", "8ms/6dB", "16ms/6dB", "32ms/6dB",
 648};
 649
 650static SOC_ENUM_SINGLE_DECL(cs48l32_in_vd_ramp,
 651			    CS48L32_INPUT_VOL_CONTROL,
 652			    CS48L32_IN_VD_RAMP_SHIFT,
 653			    cs48l32_vol_ramp_text);
 654
 655static SOC_ENUM_SINGLE_DECL(cs48l32_in_vi_ramp,
 656			    CS48L32_INPUT_VOL_CONTROL,
 657			    CS48L32_IN_VI_RAMP_SHIFT,
 658			    cs48l32_vol_ramp_text);
 659
 660static const char * const cs48l32_in_hpf_cut_text[] = {
 661	"2.5Hz", "5Hz", "10Hz", "20Hz", "40Hz"
 662};
 663
 664static SOC_ENUM_SINGLE_DECL(cs48l32_in_hpf_cut_enum,
 665			    CS48L32_INPUT_HPF_CONTROL,
 666			    CS48L32_IN_HPF_CUT_SHIFT,
 667			    cs48l32_in_hpf_cut_text);
 668
 669static const char * const cs48l32_in_dmic_osr_text[] = {
 670	"384kHz", "768kHz", "1.536MHz", "2.048MHz", "2.4576MHz", "3.072MHz", "6.144MHz",
 671};
 672
 673static const struct soc_enum cs48l32_in_dmic_osr[] = {
 674	SOC_ENUM_SINGLE(CS48L32_INPUT1_CONTROL1,
 675			CS48L32_IN1_OSR_SHIFT,
 676			ARRAY_SIZE(cs48l32_in_dmic_osr_text),
 677			cs48l32_in_dmic_osr_text),
 678	SOC_ENUM_SINGLE(CS48L32_INPUT2_CONTROL1,
 679			CS48L32_IN1_OSR_SHIFT,
 680			ARRAY_SIZE(cs48l32_in_dmic_osr_text),
 681			cs48l32_in_dmic_osr_text),
 682};
 683
 684static bool cs48l32_is_input_enabled(struct snd_soc_component *component,
 685				     unsigned int reg)
 686{
 687	unsigned int input_active;
 688
 689	input_active = snd_soc_component_read(component, CS48L32_INPUT_CONTROL);
 690	switch (reg) {
 691	case CS48L32_IN1L_CONTROL1:
 692		return input_active & BIT(CS48L32_IN1L_EN_SHIFT);
 693	case CS48L32_IN1R_CONTROL1:
 694		return input_active & BIT(CS48L32_IN1R_EN_SHIFT);
 695	case CS48L32_IN2L_CONTROL1:
 696		return input_active & BIT(CS48L32_IN2L_EN_SHIFT);
 697	case CS48L32_IN2R_CONTROL1:
 698		return input_active & BIT(CS48L32_IN2R_EN_SHIFT);
 699	default:
 700		return false;
 701	}
 702}
 703
 704static int cs48l32_in_rate_put(struct snd_kcontrol *kcontrol,
 705			       struct snd_ctl_elem_value *ucontrol)
 706{
 707	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
 708	struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component);
 709	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
 710	int ret;
 711
 712	snd_soc_dapm_mutex_lock(dapm);
 713
 714	/* Cannot change rate on an active input */
 715	if (cs48l32_is_input_enabled(component, e->reg)) {
 716		ret = -EBUSY;
 717		goto exit;
 718	}
 719
 720	ret = snd_soc_put_enum_double(kcontrol, ucontrol);
 721exit:
 722	snd_soc_dapm_mutex_unlock(dapm);
 723
 724	return ret;
 725}
 726
 727static const struct soc_enum cs48l32_input_rate[] = {
 728	SOC_VALUE_ENUM_SINGLE(CS48L32_IN1L_CONTROL1,
 729			      CS48L32_INx_RATE_SHIFT,
 730			      CS48L32_INx_RATE_MASK >> CS48L32_INx_RATE_SHIFT,
 731			      ARRAY_SIZE(cs48l32_rate_text),
 732			      cs48l32_rate_text,
 733			      cs48l32_rate_val),
 734	SOC_VALUE_ENUM_SINGLE(CS48L32_IN1R_CONTROL1,
 735			      CS48L32_INx_RATE_SHIFT,
 736			      CS48L32_INx_RATE_MASK >> CS48L32_INx_RATE_SHIFT,
 737			      ARRAY_SIZE(cs48l32_rate_text),
 738			      cs48l32_rate_text,
 739			      cs48l32_rate_val),
 740	SOC_VALUE_ENUM_SINGLE(CS48L32_IN2L_CONTROL1,
 741			      CS48L32_INx_RATE_SHIFT,
 742			      CS48L32_INx_RATE_MASK >> CS48L32_INx_RATE_SHIFT,
 743			      ARRAY_SIZE(cs48l32_rate_text),
 744			      cs48l32_rate_text,
 745			      cs48l32_rate_val),
 746	SOC_VALUE_ENUM_SINGLE(CS48L32_IN2R_CONTROL1,
 747			      CS48L32_INx_RATE_SHIFT,
 748			      CS48L32_INx_RATE_MASK >> CS48L32_INx_RATE_SHIFT,
 749			      ARRAY_SIZE(cs48l32_rate_text),
 750			      cs48l32_rate_text,
 751			      cs48l32_rate_val),
 752};
 753
 754static int cs48l32_low_power_mode_put(struct snd_kcontrol *kcontrol,
 755				      struct snd_ctl_elem_value *ucontrol)
 756{
 757	struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value;
 758	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
 759	struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component);
 760	int ret;
 761
 762	snd_soc_dapm_mutex_lock(dapm);
 763
 764	/* Cannot change rate on an active input */
 765	if (cs48l32_is_input_enabled(component, mc->reg)) {
 766		ret = -EBUSY;
 767		goto exit;
 768	}
 769
 770	ret = snd_soc_put_volsw(kcontrol, ucontrol);
 771
 772exit:
 773	snd_soc_dapm_mutex_unlock(dapm);
 774	return ret;
 775}
 776
 777static const struct soc_enum noise_gen_rate =
 778	SOC_VALUE_ENUM_SINGLE(CS48L32_COMFORT_NOISE_GENERATOR,
 779			      CS48L32_NOISE_GEN_RATE_SHIFT,
 780			      CS48L32_NOISE_GEN_RATE_MASK >> CS48L32_NOISE_GEN_RATE_SHIFT,
 781			      ARRAY_SIZE(cs48l32_rate_text),
 782			      cs48l32_rate_text,
 783			      cs48l32_rate_val);
 784
 785static const char * const cs48l32_auxpdm_freq_texts[] = {
 786	"3.072MHz", "2.048MHz", "1.536MHz", "768kHz",
 787};
 788
 789static SOC_ENUM_SINGLE_DECL(cs48l32_auxpdm1_freq,
 790			    CS48L32_AUXPDM1_CONTROL1,
 791			    CS48L32_AUXPDM1_FREQ_SHIFT,
 792			    cs48l32_auxpdm_freq_texts);
 793
 794static SOC_ENUM_SINGLE_DECL(cs48l32_auxpdm2_freq,
 795			    CS48L32_AUXPDM2_CONTROL1,
 796			    CS48L32_AUXPDM1_FREQ_SHIFT,
 797			    cs48l32_auxpdm_freq_texts);
 798
 799static const char * const cs48l32_auxpdm_src_texts[] = {
 800	"Analog", "IN1 Digital", "IN2 Digital",
 801};
 802
 803static SOC_ENUM_SINGLE_DECL(cs48l32_auxpdm1_in,
 804			    CS48L32_AUXPDM_CTRL2,
 805			    CS48L32_AUXPDMDAT1_SRC_SHIFT,
 806			    cs48l32_auxpdm_src_texts);
 807
 808static SOC_ENUM_SINGLE_DECL(cs48l32_auxpdm2_in,
 809			    CS48L32_AUXPDM_CTRL2,
 810			    CS48L32_AUXPDMDAT2_SRC_SHIFT,
 811			    cs48l32_auxpdm_src_texts);
 812
 813static const struct snd_kcontrol_new cs48l32_auxpdm_inmux[] = {
 814	SOC_DAPM_ENUM("AUXPDM1 Input", cs48l32_auxpdm1_in),
 815	SOC_DAPM_ENUM("AUXPDM2 Input", cs48l32_auxpdm2_in),
 816};
 817
 818static const unsigned int cs48l32_auxpdm_analog_in_val[] = {
 819	0x0, 0x1,
 820};
 821
 822static const struct soc_enum cs48l32_auxpdm_analog_inmux_enum[] = {
 823	SOC_VALUE_ENUM_SINGLE(CS48L32_AUXPDM1_CONTROL1,
 824			      CS48L32_AUXPDM1_SRC_SHIFT,
 825			      CS48L32_AUXPDM1_SRC_MASK >> CS48L32_AUXPDM1_SRC_SHIFT,
 826			      ARRAY_SIZE(cs48l32_auxpdm_analog_in_val),
 827			      cs48l32_in_texts,
 828			      cs48l32_auxpdm_analog_in_val),
 829	SOC_VALUE_ENUM_SINGLE(CS48L32_AUXPDM2_CONTROL1,
 830			      CS48L32_AUXPDM1_SRC_SHIFT,
 831			      CS48L32_AUXPDM1_SRC_MASK >> CS48L32_AUXPDM1_SRC_SHIFT,
 832			      ARRAY_SIZE(cs48l32_auxpdm_analog_in_val),
 833			      cs48l32_in_texts,
 834			      cs48l32_auxpdm_analog_in_val),
 835};
 836
 837static const struct snd_kcontrol_new cs48l32_auxpdm_analog_inmux[] = {
 838	SOC_DAPM_ENUM("AUXPDM1 Analog Input", cs48l32_auxpdm_analog_inmux_enum[0]),
 839	SOC_DAPM_ENUM("AUXPDM2 Analog Input", cs48l32_auxpdm_analog_inmux_enum[1]),
 840};
 841
 842static const struct snd_kcontrol_new cs48l32_auxpdm_switch[] = {
 843	SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0),
 844	SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0),
 845};
 846
 847static const struct soc_enum cs48l32_isrc_fsh[] = {
 848	SOC_VALUE_ENUM_SINGLE(CS48L32_ISRC1_CONTROL1,
 849			      CS48L32_ISRC1_FSH_SHIFT,
 850			      CS48L32_ISRC1_FSH_MASK >> CS48L32_ISRC1_FSH_SHIFT,
 851			      ARRAY_SIZE(cs48l32_rate_text),
 852			      cs48l32_rate_text,
 853			      cs48l32_rate_val),
 854	SOC_VALUE_ENUM_SINGLE(CS48L32_ISRC2_CONTROL1,
 855			      CS48L32_ISRC1_FSH_SHIFT,
 856			      CS48L32_ISRC1_FSH_MASK >> CS48L32_ISRC1_FSH_SHIFT,
 857			      ARRAY_SIZE(cs48l32_rate_text),
 858			      cs48l32_rate_text,
 859			      cs48l32_rate_val),
 860	SOC_VALUE_ENUM_SINGLE(CS48L32_ISRC3_CONTROL1,
 861			      CS48L32_ISRC1_FSH_SHIFT,
 862			      CS48L32_ISRC1_FSH_MASK >> CS48L32_ISRC1_FSH_SHIFT,
 863			      ARRAY_SIZE(cs48l32_rate_text),
 864			      cs48l32_rate_text,
 865			      cs48l32_rate_val),
 866};
 867
 868static const struct soc_enum cs48l32_isrc_fsl[] = {
 869	SOC_VALUE_ENUM_SINGLE(CS48L32_ISRC1_CONTROL1,
 870			      CS48L32_ISRC1_FSL_SHIFT,
 871			      CS48L32_ISRC1_FSL_MASK >> CS48L32_ISRC1_FSL_SHIFT,
 872			      ARRAY_SIZE(cs48l32_rate_text),
 873			      cs48l32_rate_text,
 874			      cs48l32_rate_val),
 875	SOC_VALUE_ENUM_SINGLE(CS48L32_ISRC2_CONTROL1,
 876			      CS48L32_ISRC1_FSL_SHIFT,
 877			      CS48L32_ISRC1_FSL_MASK >> CS48L32_ISRC1_FSL_SHIFT,
 878			      ARRAY_SIZE(cs48l32_rate_text),
 879			      cs48l32_rate_text,
 880			      cs48l32_rate_val),
 881	SOC_VALUE_ENUM_SINGLE(CS48L32_ISRC3_CONTROL1,
 882			      CS48L32_ISRC1_FSL_SHIFT,
 883			      CS48L32_ISRC1_FSL_MASK >> CS48L32_ISRC1_FSL_SHIFT,
 884			      ARRAY_SIZE(cs48l32_rate_text),
 885			      cs48l32_rate_text,
 886			      cs48l32_rate_val),
 887};
 888
 889static const struct soc_enum cs48l32_fx_rate =
 890	SOC_VALUE_ENUM_SINGLE(CS48L32_FX_SAMPLE_RATE,
 891			      CS48L32_FX_RATE_SHIFT,
 892			      CS48L32_FX_RATE_MASK >> CS48L32_FX_RATE_SHIFT,
 893			      ARRAY_SIZE(cs48l32_rate_text),
 894			      cs48l32_rate_text,
 895			      cs48l32_rate_val);
 896
 897static const char * const cs48l32_lhpf_mode_text[] = {
 898	"Low-pass", "High-pass"
 899};
 900
 901static const struct soc_enum cs48l32_lhpf_mode[] = {
 902	SOC_ENUM_SINGLE(CS48L32_LHPF_CONTROL2, 0,
 903			ARRAY_SIZE(cs48l32_lhpf_mode_text), cs48l32_lhpf_mode_text),
 904	SOC_ENUM_SINGLE(CS48L32_LHPF_CONTROL2, 1,
 905			ARRAY_SIZE(cs48l32_lhpf_mode_text), cs48l32_lhpf_mode_text),
 906	SOC_ENUM_SINGLE(CS48L32_LHPF_CONTROL2, 2,
 907			ARRAY_SIZE(cs48l32_lhpf_mode_text), cs48l32_lhpf_mode_text),
 908	SOC_ENUM_SINGLE(CS48L32_LHPF_CONTROL2, 3,
 909			ARRAY_SIZE(cs48l32_lhpf_mode_text), cs48l32_lhpf_mode_text),
 910};
 911
 912static int cs48l32_lhpf_coeff_put(struct snd_kcontrol *kcontrol,
 913				  struct snd_ctl_elem_value *ucontrol)
 914{
 915	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
 916	struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
 917	__be32 *data = (__be32 *)ucontrol->value.bytes.data;
 918	s16 val = (s16)be32_to_cpu(*data);
 919
 920	if (abs(val) > CS48L32_LHPF_MAX_COEFF) {
 921		dev_err(cs48l32_codec->core.dev, "Rejecting unstable LHPF coefficients\n");
 922		return -EINVAL;
 923	}
 924
 925	return snd_soc_bytes_put(kcontrol, ucontrol);
 926}
 927
 928static const char * const cs48l32_eq_mode_text[] = {
 929	"Low-pass", "High-pass",
 930};
 931
 932static const struct soc_enum cs48l32_eq_mode[] = {
 933	SOC_ENUM_SINGLE(CS48L32_EQ_CONTROL2, 0,
 934			ARRAY_SIZE(cs48l32_eq_mode_text),
 935			cs48l32_eq_mode_text),
 936	SOC_ENUM_SINGLE(CS48L32_EQ_CONTROL2, 1,
 937			ARRAY_SIZE(cs48l32_eq_mode_text),
 938			cs48l32_eq_mode_text),
 939	SOC_ENUM_SINGLE(CS48L32_EQ_CONTROL2, 2,
 940			ARRAY_SIZE(cs48l32_eq_mode_text),
 941			cs48l32_eq_mode_text),
 942	SOC_ENUM_SINGLE(CS48L32_EQ_CONTROL2, 3,
 943			ARRAY_SIZE(cs48l32_eq_mode_text),
 944			cs48l32_eq_mode_text),
 945};
 946
 947static int cs48l32_eq_mode_get(struct snd_kcontrol *kcontrol,
 948			       struct snd_ctl_elem_value *ucontrol)
 949{
 950	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
 951	struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
 952	struct soc_enum *e = (struct soc_enum *) kcontrol->private_value;
 953	unsigned int item;
 954
 955	item = snd_soc_enum_val_to_item(e, cs48l32_codec->eq_mode[e->shift_l]);
 956	ucontrol->value.enumerated.item[0] = item;
 957
 958	return 0;
 959}
 960
 961static int cs48l32_eq_mode_put(struct snd_kcontrol *kcontrol,
 962			       struct snd_ctl_elem_value *ucontrol)
 963{
 964	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
 965	struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component);
 966	struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
 967	struct soc_enum *e = (struct soc_enum *) kcontrol->private_value;
 968	unsigned int *item = ucontrol->value.enumerated.item;
 969	unsigned int val;
 970	bool changed = false;
 971
 972	if (item[0] >= e->items)
 973		return -EINVAL;
 974
 975	val = snd_soc_enum_item_to_val(e, item[0]);
 976
 977	snd_soc_dapm_mutex_lock(dapm);
 978	if (cs48l32_codec->eq_mode[e->shift_l] != val) {
 979		cs48l32_codec->eq_mode[e->shift_l] = val;
 980		changed = true;
 981	}
 982	snd_soc_dapm_mutex_unlock(dapm);
 983
 984	return changed;
 985}
 986
 987static int cs48l32_eq_coeff_info(struct snd_kcontrol *kcontrol,
 988				 struct snd_ctl_elem_info *uinfo)
 989{
 990	struct cs48l32_eq_control *ctl = (void *) kcontrol->private_value;
 991
 992	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 993	uinfo->count = 1;
 994	uinfo->value.integer.min = 0;
 995	uinfo->value.integer.max = ctl->max;
 996
 997	return 0;
 998}
 999
1000static int cs48l32_eq_coeff_get(struct snd_kcontrol *kcontrol,
1001				struct snd_ctl_elem_value *ucontrol)
1002{
1003	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
1004	struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
1005	struct cs48l32_eq_control *params = (void *)kcontrol->private_value;
1006	__be16 *coeffs;
1007	unsigned int coeff_idx;
1008	int block_idx;
1009
1010	block_idx = ((int) params->block_base - (int) CS48L32_EQ1_BAND1_COEFF1);
1011	block_idx /= (CS48L32_EQ2_BAND1_COEFF1 - CS48L32_EQ1_BAND1_COEFF1);
1012
1013	coeffs = &cs48l32_codec->eq_coefficients[block_idx][0];
1014	coeff_idx = (params->reg - params->block_base) / 2;
1015
1016	/* High __be16 is in [coeff_idx] and low __be16 in [coeff_idx + 1] */
1017	if (params->shift == 0)
1018		coeff_idx++;
1019
1020	ucontrol->value.integer.value[0] = be16_to_cpu(coeffs[coeff_idx]);
1021
1022	return 0;
1023}
1024
1025static int cs48l32_eq_coeff_put(struct snd_kcontrol *kcontrol,
1026				struct snd_ctl_elem_value *ucontrol)
1027{
1028	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
1029	struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component);
1030	struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
1031	struct cs48l32_eq_control *params = (void *)kcontrol->private_value;
1032	__be16 *coeffs;
1033	unsigned int coeff_idx;
1034	int block_idx;
1035
1036	block_idx = ((int) params->block_base - (int) CS48L32_EQ1_BAND1_COEFF1);
1037	block_idx /= (CS48L32_EQ2_BAND1_COEFF1 - CS48L32_EQ1_BAND1_COEFF1);
1038
1039	coeffs = &cs48l32_codec->eq_coefficients[block_idx][0];
1040	coeff_idx = (params->reg - params->block_base) / 2;
1041
1042	/* Put high __be16 in [coeff_idx] and low __be16 in [coeff_idx + 1] */
1043	if (params->shift == 0)
1044		coeff_idx++;
1045
1046	snd_soc_dapm_mutex_lock(dapm);
1047	coeffs[coeff_idx] = cpu_to_be16(ucontrol->value.integer.value[0]);
1048	snd_soc_dapm_mutex_unlock(dapm);
1049
1050	return 0;
1051}
1052
1053static const struct snd_kcontrol_new cs48l32_drc_activity_output_mux[] = {
1054	SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0),
1055	SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0),
1056};
1057
1058static const struct snd_kcontrol_new cs48l32_dsp_trigger_output_mux[] = {
1059	SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0),
1060};
1061
1062static int cs48l32_dsp_rate_get(struct snd_kcontrol *kcontrol,
1063				struct snd_ctl_elem_value *ucontrol)
1064{
1065	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
1066	struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
1067	struct soc_enum *e = (struct soc_enum *) kcontrol->private_value;
1068	unsigned int cached_rate;
1069	const unsigned int rate_num = e->mask;
1070	int item;
1071
1072	if (rate_num >= ARRAY_SIZE(cs48l32_codec->dsp_dma_rates))
1073		return -EINVAL;
1074
1075	cached_rate = cs48l32_codec->dsp_dma_rates[rate_num];
1076	item = snd_soc_enum_val_to_item(e, cached_rate);
1077	ucontrol->value.enumerated.item[0] = item;
1078
1079	return 0;
1080}
1081
1082static int cs48l32_dsp_rate_put(struct snd_kcontrol *kcontrol,
1083				struct snd_ctl_elem_value *ucontrol)
1084{
1085	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
1086	struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component);
1087	struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
1088	struct soc_enum *e = (struct soc_enum *) kcontrol->private_value;
1089	const unsigned int rate_num = e->mask;
1090	const unsigned int item = ucontrol->value.enumerated.item[0];
1091	unsigned int val;
1092	bool changed = false;
1093
1094	if (item >= e->items)
1095		return -EINVAL;
1096
1097	if (rate_num >= ARRAY_SIZE(cs48l32_codec->dsp_dma_rates))
1098		return -EINVAL;
1099
1100	val = snd_soc_enum_item_to_val(e, item);
1101
1102	snd_soc_dapm_mutex_lock(dapm);
1103	if (cs48l32_codec->dsp_dma_rates[rate_num] != val) {
1104		cs48l32_codec->dsp_dma_rates[rate_num] = val;
1105		changed = true;
1106	}
1107	snd_soc_dapm_mutex_unlock(dapm);
1108
1109	return changed;
1110}
1111
1112static const struct soc_enum cs48l32_dsp_rate_enum[] = {
1113	/* RX rates */
1114	SOC_VALUE_ENUM_SINGLE(SND_SOC_NOPM, 0,
1115			      0,
1116			      ARRAY_SIZE(cs48l32_rate_text),
1117			      cs48l32_rate_text, cs48l32_rate_val),
1118	SOC_VALUE_ENUM_SINGLE(SND_SOC_NOPM, 0,
1119			      1,
1120			      ARRAY_SIZE(cs48l32_rate_text),
1121			      cs48l32_rate_text, cs48l32_rate_val),
1122	SOC_VALUE_ENUM_SINGLE(SND_SOC_NOPM, 0,
1123			      2,
1124			      ARRAY_SIZE(cs48l32_rate_text),
1125			      cs48l32_rate_text, cs48l32_rate_val),
1126	SOC_VALUE_ENUM_SINGLE(SND_SOC_NOPM, 0,
1127			      3,
1128			      ARRAY_SIZE(cs48l32_rate_text),
1129			      cs48l32_rate_text, cs48l32_rate_val),
1130	SOC_VALUE_ENUM_SINGLE(SND_SOC_NOPM, 0,
1131			      4,
1132			      ARRAY_SIZE(cs48l32_rate_text),
1133			      cs48l32_rate_text,  cs48l32_rate_val),
1134	SOC_VALUE_ENUM_SINGLE(SND_SOC_NOPM, 0,
1135			      5,
1136			      ARRAY_SIZE(cs48l32_rate_text),
1137			      cs48l32_rate_text, cs48l32_rate_val),
1138	SOC_VALUE_ENUM_SINGLE(SND_SOC_NOPM, 0,
1139			      6,
1140			      ARRAY_SIZE(cs48l32_rate_text),
1141			      cs48l32_rate_text, cs48l32_rate_val),
1142	SOC_VALUE_ENUM_SINGLE(SND_SOC_NOPM, 0,
1143			      7,
1144			      ARRAY_SIZE(cs48l32_rate_text),
1145			      cs48l32_rate_text, cs48l32_rate_val),
1146	/* TX rates */
1147	SOC_VALUE_ENUM_SINGLE(SND_SOC_NOPM, 0,
1148			      8,
1149			      ARRAY_SIZE(cs48l32_rate_text),
1150			      cs48l32_rate_text, cs48l32_rate_val),
1151	SOC_VALUE_ENUM_SINGLE(SND_SOC_NOPM, 0,
1152			      9,
1153			      ARRAY_SIZE(cs48l32_rate_text),
1154			      cs48l32_rate_text, cs48l32_rate_val),
1155	SOC_VALUE_ENUM_SINGLE(SND_SOC_NOPM, 0,
1156			      10,
1157			      ARRAY_SIZE(cs48l32_rate_text),
1158			      cs48l32_rate_text, cs48l32_rate_val),
1159	SOC_VALUE_ENUM_SINGLE(SND_SOC_NOPM, 0,
1160			      11,
1161			      ARRAY_SIZE(cs48l32_rate_text),
1162			      cs48l32_rate_text, cs48l32_rate_val),
1163	SOC_VALUE_ENUM_SINGLE(SND_SOC_NOPM, 0,
1164			      12,
1165			      ARRAY_SIZE(cs48l32_rate_text),
1166			      cs48l32_rate_text, cs48l32_rate_val),
1167	SOC_VALUE_ENUM_SINGLE(SND_SOC_NOPM, 0,
1168			      13,
1169			      ARRAY_SIZE(cs48l32_rate_text),
1170			      cs48l32_rate_text, cs48l32_rate_val),
1171	SOC_VALUE_ENUM_SINGLE(SND_SOC_NOPM, 0,
1172			      14,
1173			      ARRAY_SIZE(cs48l32_rate_text),
1174			      cs48l32_rate_text, cs48l32_rate_val),
1175	SOC_VALUE_ENUM_SINGLE(SND_SOC_NOPM, 0,
1176			      15,
1177			      ARRAY_SIZE(cs48l32_rate_text),
1178			      cs48l32_rate_text, cs48l32_rate_val),
1179};
1180
1181static int cs48l32_dsp_pre_run(struct wm_adsp *dsp)
1182{
1183	struct cs48l32_codec *cs48l32_codec = container_of(dsp, struct cs48l32_codec, dsp);
1184	unsigned int reg;
1185	const u8 *rate = cs48l32_codec->dsp_dma_rates;
1186	int i;
1187
1188	reg = dsp->cs_dsp.base + CS48L32_HALO_SAMPLE_RATE_RX1;
1189	for (i = 0; i < CS48L32_DSP_N_RX_CHANNELS; ++i) {
1190		regmap_update_bits(dsp->cs_dsp.regmap, reg, CS48L32_HALO_DSP_RATE_MASK, *rate);
1191		reg += 8;
1192		rate++;
1193	}
1194
1195	reg = dsp->cs_dsp.base + CS48L32_HALO_SAMPLE_RATE_TX1;
1196	for (i = 0; i < CS48L32_DSP_N_TX_CHANNELS; ++i) {
1197		regmap_update_bits(dsp->cs_dsp.regmap, reg, CS48L32_HALO_DSP_RATE_MASK, *rate);
1198		reg += 8;
1199		rate++;
1200	}
1201
1202	usleep_range(300, 600);
1203
1204	return 0;
1205}
1206
1207static void cs48l32_dsp_memory_disable(struct cs48l32_codec *cs48l32_codec,
1208				       const struct cs48l32_dsp_power_regs *regs)
1209{
1210	struct regmap *regmap = cs48l32_codec->core.regmap;
1211	int i, j, ret;
1212
1213	for (i = 0; i < regs->n_pwd; ++i) {
1214		ret = regmap_write(regmap, regs->pwd[i], 0);
1215		if (ret)
1216			goto err;
1217	}
1218
1219	for (i = 0; i < regs->n_ext; ++i) {
1220		for (j = regs->ext[i].start; j <= regs->ext[i].end; j += 4) {
1221			ret = regmap_write(regmap, j, 0);
1222			if (ret)
1223				goto err;
1224		}
1225	}
1226
1227	return;
1228
1229err:
1230	dev_warn(cs48l32_codec->core.dev, "Failed to write SRAM enables (%d)\n", ret);
1231}
1232
1233static int cs48l32_dsp_memory_enable(struct cs48l32_codec *cs48l32_codec,
1234				     const struct cs48l32_dsp_power_regs *regs)
1235{
1236	struct regmap *regmap = cs48l32_codec->core.regmap;
1237	int i, j, ret;
1238
1239	/* disable power-off */
1240	for (i = 0; i < regs->n_ext; ++i) {
1241		for (j = regs->ext[i].start; j <= regs->ext[i].end; j += 4) {
1242			ret = regmap_write(regmap, j, 0x3);
1243			if (ret)
1244				goto err;
1245		}
1246	}
1247
1248	/* power-up the banks in sequence */
1249	for (i = 0; i < regs->n_pwd; ++i) {
1250		ret = regmap_write(regmap, regs->pwd[i], 0x1);
1251		if (ret)
1252			goto err;
1253
1254		udelay(1); /* allow bank to power-up */
1255
1256		ret = regmap_write(regmap, regs->pwd[i], 0x3);
1257		if (ret)
1258			goto err;
1259
1260		udelay(1); /* allow bank to power-up */
1261	}
1262
1263	return 0;
1264
1265err:
1266	dev_err(cs48l32_codec->core.dev, "Failed to write SRAM enables (%d)\n", ret);
1267	cs48l32_dsp_memory_disable(cs48l32_codec, regs);
1268
1269	return ret;
1270}
1271
1272static int cs48l32_dsp_freq_update(struct snd_soc_dapm_widget *w, unsigned int freq_reg,
1273				   unsigned int freqsel_reg)
1274{
1275	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
1276	struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
1277	struct regmap *regmap = cs48l32_codec->core.regmap;
1278	struct wm_adsp *dsp = &cs48l32_codec->dsp;
1279	int ret;
1280	unsigned int freq, freq_sel, freq_sts;
1281
1282	if (!freq_reg)
1283		return -EINVAL;
1284
1285	ret = regmap_read(regmap, freq_reg, &freq);
1286	if (ret) {
1287		dev_err(component->dev, "Failed to read #%x: %d\n", freq_reg, ret);
1288		return ret;
1289	}
1290
1291	if (freqsel_reg) {
1292		freq_sts = (freq & CS48L32_SYSCLK_FREQ_STS_MASK) >> CS48L32_SYSCLK_FREQ_STS_SHIFT;
1293
1294		ret = regmap_read(regmap, freqsel_reg, &freq_sel);
1295		if (ret) {
1296			dev_err(component->dev, "Failed to read #%x: %d\n", freqsel_reg, ret);
1297			return ret;
1298		}
1299		freq_sel = (freq_sel & CS48L32_SYSCLK_FREQ_MASK) >> CS48L32_SYSCLK_FREQ_SHIFT;
1300
1301		if (freq_sts != freq_sel) {
1302			dev_err(component->dev, "SYSCLK FREQ (#%x) != FREQ STS (#%x)\n",
1303				freq_sel, freq_sts);
1304			return -ETIMEDOUT;
1305		}
1306	}
1307
1308	freq &= CS48L32_DSP_CLK_FREQ_MASK;
1309	freq >>= CS48L32_DSP_CLK_FREQ_SHIFT;
1310
1311	ret = regmap_write(dsp->cs_dsp.regmap,
1312			   dsp->cs_dsp.base + CS48L32_DSP_CLOCK_FREQ_OFFS, freq);
1313	if (ret) {
1314		dev_err(component->dev, "Failed to set HALO clock freq: %d\n", ret);
1315		return ret;
1316	}
1317
1318	return 0;
1319}
1320
1321static int cs48l32_dsp_freq_ev(struct snd_soc_dapm_widget *w,
1322			       struct snd_kcontrol *kcontrol, int event)
1323{
1324	switch (event) {
1325	case SND_SOC_DAPM_POST_PMU:
1326		return cs48l32_dsp_freq_update(w, CS48L32_SYSTEM_CLOCK2, CS48L32_SYSTEM_CLOCK1);
1327	default:
1328		return 0;
1329	}
1330}
1331
1332static irqreturn_t cs48l32_irq(int irq, void *data)
1333{
1334	static const unsigned int eint1_regs[] = {
1335		CS48L32_IRQ1_EINT_9, CS48L32_IRQ1_MASK_9,
1336		CS48L32_IRQ1_EINT_7, CS48L32_IRQ1_MASK_7
1337	};
1338	u32 reg_vals[4];
1339	struct cs48l32_codec *cs48l32_codec = data;
1340	struct regmap *regmap = cs48l32_codec->core.regmap;
1341	irqreturn_t result = IRQ_NONE;
1342	unsigned int eint_pending;
1343	int i, ret;
1344
1345	static_assert(ARRAY_SIZE(eint1_regs) == ARRAY_SIZE(reg_vals));
1346
1347	ret = pm_runtime_resume_and_get(cs48l32_codec->core.dev);
1348	if (ret) {
1349		dev_warn(cs48l32_codec->core.dev, "irq could not get pm runtime: %d\n", ret);
1350		return IRQ_NONE;
1351	}
1352
1353	ret = regmap_read(regmap, CS48L32_IRQ1_STATUS, &eint_pending);
1354	if (ret) {
1355		dev_warn(cs48l32_codec->core.dev, "Read IRQ1_STATUS failed: %d\n", ret);
1356		return IRQ_NONE;
1357	}
1358	if ((eint_pending & CS48L32_IRQ1_STS_MASK) == 0)
1359		goto out;
1360
1361	ret = regmap_multi_reg_read(regmap, eint1_regs, reg_vals, ARRAY_SIZE(reg_vals));
1362	if (ret) {
1363		dev_warn(cs48l32_codec->core.dev, "Read IRQ regs failed: %d\n", ret);
1364		return IRQ_NONE;
1365	}
1366
1367	for (i = 0; i < ARRAY_SIZE(reg_vals); i += 2) {
1368		reg_vals[i] &= ~reg_vals[i + 1];
1369		regmap_write(regmap, eint1_regs[i], reg_vals[i]);
1370	}
1371
1372	if (reg_vals[0] & CS48L32_DSP1_IRQ0_EINT1_MASK)
1373		wm_adsp_compr_handle_irq(&cs48l32_codec->dsp);
1374
1375	if (reg_vals[2] & CS48L32_DSP1_MPU_ERR_EINT1_MASK) {
1376		dev_warn(cs48l32_codec->core.dev, "MPU err IRQ\n");
1377		wm_halo_bus_error(irq, &cs48l32_codec->dsp);
1378	}
1379
1380	if (reg_vals[2] & CS48L32_DSP1_WDT_EXPIRE_EINT1_MASK) {
1381		dev_warn(cs48l32_codec->core.dev, "WDT expire IRQ\n");
1382		wm_halo_wdt_expire(irq, &cs48l32_codec->dsp);
1383	}
1384
1385	result = IRQ_HANDLED;
1386
1387out:
1388	pm_runtime_put_autosuspend(cs48l32_codec->core.dev);
1389
1390	return result;
1391}
1392
1393static int cs48l32_get_dspclk_setting(struct cs48l32_codec *cs48l32_codec, unsigned int freq,
1394				      int src, unsigned int *val)
1395{
1396	freq /= 15625; /* convert to 1/64ths of 1MHz */
1397	*val |= freq << CS48L32_DSP_CLK_FREQ_SHIFT;
1398
1399	return 0;
1400}
1401
1402static int cs48l32_get_sysclk_setting(unsigned int freq)
1403{
1404	switch (freq) {
1405	case 0:
1406	case 5644800:
1407	case 6144000:
1408		return CS48L32_SYSCLK_RATE_6MHZ;
1409	case 11289600:
1410	case 12288000:
1411		return CS48L32_SYSCLK_RATE_12MHZ << CS48L32_SYSCLK_FREQ_SHIFT;
1412	case 22579200:
1413	case 24576000:
1414		return CS48L32_SYSCLK_RATE_24MHZ << CS48L32_SYSCLK_FREQ_SHIFT;
1415	case 45158400:
1416	case 49152000:
1417		return CS48L32_SYSCLK_RATE_49MHZ << CS48L32_SYSCLK_FREQ_SHIFT;
1418	case 90316800:
1419	case 98304000:
1420		return CS48L32_SYSCLK_RATE_98MHZ << CS48L32_SYSCLK_FREQ_SHIFT;
1421	default:
1422		return -EINVAL;
1423	}
1424}
1425
1426static int cs48l32_set_pdm_fllclk(struct snd_soc_component *component, int source)
1427{
1428	struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
1429	struct regmap *regmap = cs48l32_codec->core.regmap;
1430	unsigned int val;
1431
1432	switch (source) {
1433	case CS48L32_PDMCLK_SRC_IN1_PDMCLK:
1434	case CS48L32_PDMCLK_SRC_IN2_PDMCLK:
1435	case CS48L32_PDMCLK_SRC_IN3_PDMCLK:
1436	case CS48L32_PDMCLK_SRC_IN4_PDMCLK:
1437	case CS48L32_PDMCLK_SRC_AUXPDM1_CLK:
1438	case CS48L32_PDMCLK_SRC_AUXPDM2_CLK:
1439		val = source << CS48L32_PDM_FLLCLK_SRC_SHIFT;
1440		break;
1441	default:
1442		dev_err(cs48l32_codec->core.dev, "Invalid PDM FLLCLK src %d\n", source);
1443		return -EINVAL;
1444	}
1445
1446	return regmap_update_bits(regmap, CS48L32_INPUT_CONTROL2,
1447				  CS48L32_PDM_FLLCLK_SRC_MASK, val);
1448}
1449
1450static int cs48l32_set_sysclk(struct snd_soc_component *component, int clk_id, int source,
1451			      unsigned int freq, int dir)
1452{
1453	struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
1454	struct regmap *regmap = cs48l32_codec->core.regmap;
1455	char *name;
1456	unsigned int reg;
1457	unsigned int mask = CS48L32_SYSCLK_SRC_MASK;
1458	unsigned int val = source << CS48L32_SYSCLK_SRC_SHIFT;
1459	int clk_freq_sel, *clk;
1460
1461	switch (clk_id) {
1462	case CS48L32_CLK_SYSCLK_1:
1463		name = "SYSCLK";
1464		reg = CS48L32_SYSTEM_CLOCK1;
1465		clk = &cs48l32_codec->sysclk;
1466		clk_freq_sel = cs48l32_get_sysclk_setting(freq);
1467		mask |= CS48L32_SYSCLK_FREQ_MASK | CS48L32_SYSCLK_FRAC_MASK;
1468		break;
1469	case CS48L32_CLK_DSPCLK:
1470		name = "DSPCLK";
1471		reg = CS48L32_DSP_CLOCK1;
1472		clk = &cs48l32_codec->dspclk;
1473		clk_freq_sel = cs48l32_get_dspclk_setting(cs48l32_codec, freq, source, &val);
1474		mask |= CS48L32_DSP_CLK_FREQ_MASK;
1475		break;
1476	case CS48L32_CLK_PDM_FLLCLK:
1477		return cs48l32_set_pdm_fllclk(component, source);
1478	default:
1479		return -EINVAL;
1480	}
1481
1482	if (clk_freq_sel < 0) {
1483		dev_err(cs48l32_codec->core.dev, "Failed to get %s setting for %dHZ\n", name, freq);
1484		return clk_freq_sel;
1485	}
1486
1487	*clk = freq;
1488
1489	if (freq == 0) {
1490		dev_dbg(cs48l32_codec->core.dev, "%s cleared\n", name);
1491		return 0;
1492	}
1493
1494	val |= clk_freq_sel;
1495
1496	if (freq % 6144000)
1497		val |= CS48L32_SYSCLK_FRAC_MASK;
1498
1499	dev_dbg(cs48l32_codec->core.dev, "%s set to %uHz", name, freq);
1500
1501	return regmap_update_bits(regmap, reg, mask, val);
1502}
1503
1504static int cs48l32_is_enabled_fll(struct cs48l32_fll *fll, int base)
1505{
1506	struct regmap *regmap = fll->codec->core.regmap;
1507	unsigned int reg;
1508	int ret;
1509
1510	ret = regmap_read(regmap, base + CS48L32_FLL_CONTROL1_OFFS, &reg);
1511	if (ret != 0) {
1512		cs48l32_fll_err(fll, "Failed to read current state: %d\n", ret);
1513		return ret;
1514	}
1515
1516	return reg & CS48L32_FLL_EN_MASK;
1517}
1518
1519static int cs48l32_wait_for_fll(struct cs48l32_fll *fll, bool requested)
1520{
1521	struct regmap *regmap = fll->codec->core.regmap;
1522	unsigned int val = 0;
1523	int i;
1524
1525	cs48l32_fll_dbg(fll, "Waiting for FLL...\n");
1526
1527	for (i = 0; i < 30; i++) {
1528		regmap_read(regmap, fll->sts_addr, &val);
1529		if (!!(val & fll->sts_mask) == requested)
1530			return 0;
1531
1532		switch (i) {
1533		case 0 ... 5:
1534			usleep_range(75, 125);
1535			break;
1536		case 6 ... 20:
1537			usleep_range(750, 1250);
1538			break;
1539		default:
1540			fsleep(20000);
1541			break;
1542		}
1543	}
1544
1545	cs48l32_fll_warn(fll, "Timed out waiting for %s\n", requested ? "lock" : "unlock");
1546
1547	return -ETIMEDOUT;
1548}
1549
1550static int cs48l32_fllhj_disable(struct cs48l32_fll *fll)
1551{
1552	struct cs48l32 *cs48l32 = &fll->codec->core;
1553	bool change;
1554
1555	cs48l32_fll_dbg(fll, "Disabling FLL\n");
1556
1557	/*
1558	 * Disable lockdet, but don't set ctrl_upd update bit. This allows the
1559	 * lock status bit to clear as normal, but should the FLL be enabled
1560	 * again due to a control clock being required, the lock won't re-assert
1561	 * as the FLL config registers are automatically applied when the FLL
1562	 * enables.
1563	 */
1564	regmap_set_bits(cs48l32->regmap,
1565			fll->base + CS48L32_FLL_CONTROL1_OFFS,
1566			CS48L32_FLL_HOLD_MASK);
1567	regmap_clear_bits(cs48l32->regmap,
1568			  fll->base + CS48L32_FLL_CONTROL2_OFFS,
1569			  CS48L32_FLL_LOCKDET_MASK);
1570	regmap_set_bits(cs48l32->regmap,
1571			fll->base + CS48L32_FLL_CONTROL5_OFFS,
1572			CS48L32_FLL_FRC_INTEG_UPD_MASK);
1573	regmap_update_bits_check(cs48l32->regmap,
1574				 fll->base + CS48L32_FLL_CONTROL1_OFFS,
1575				 CS48L32_FLL_EN_MASK,
1576				 0,
1577				 &change);
1578
1579	cs48l32_wait_for_fll(fll, false);
1580
1581	/*
1582	 * ctrl_up gates the writes to all the fll's registers, setting it to 0
1583	 * here ensures that after a runtime suspend/resume cycle when one
1584	 * enables the fll then ctrl_up is the last bit that is configured
1585	 * by the fll enable code rather than the cache sync operation which
1586	 * would have updated it much earlier before writing out all fll
1587	 * registers
1588	 */
1589	regmap_clear_bits(cs48l32->regmap,
1590			  fll->base + CS48L32_FLL_CONTROL1_OFFS,
1591			  CS48L32_FLL_CTRL_UPD_MASK);
1592
1593	if (change)
1594		pm_runtime_put_autosuspend(cs48l32->dev);
1595
1596	return 0;
1597}
1598
1599static int cs48l32_fllhj_apply(struct cs48l32_fll *fll, int fin)
1600{
1601	struct regmap *regmap = fll->codec->core.regmap;
1602	int refdiv, fref, fout, lockdet_thr, fbdiv, fllgcd;
1603	bool frac = false;
1604	unsigned int fll_n, min_n, max_n, ratio, theta, lambda, hp;
1605	unsigned int gains, num;
1606
1607	cs48l32_fll_dbg(fll, "fin=%d, fout=%d\n", fin, fll->fout);
1608
1609	for (refdiv = 0; refdiv < 4; refdiv++) {
1610		if ((fin / (1 << refdiv)) <= CS48L32_FLLHJ_MAX_THRESH)
1611			break;
1612	}
1613
1614	fref = fin / (1 << refdiv);
1615	fout = fll->fout;
1616	frac = fout % fref;
1617
1618	/*
1619	 * Use simple heuristic approach to find a configuration that
1620	 * should work for most input clocks.
1621	 */
1622	if (fref < CS48L32_FLLHJ_LOW_THRESH) {
1623		lockdet_thr = 2;
1624		gains = CS48L32_FLLHJ_LOW_GAINS;
1625
1626		if (frac)
1627			fbdiv = 256;
1628		else
1629			fbdiv = 4;
1630	} else if (fref < CS48L32_FLLHJ_MID_THRESH) {
1631		lockdet_thr = 8;
1632		gains = CS48L32_FLLHJ_MID_GAINS;
1633		fbdiv = (frac) ? 16 : 2;
1634	} else {
1635		lockdet_thr = 8;
1636		gains = CS48L32_FLLHJ_HIGH_GAINS;
1637		fbdiv = 1;
1638	}
1639	/* Use high performance mode for fractional configurations. */
1640	if (frac) {
1641		hp = 3;
1642		min_n = CS48L32_FLLHJ_FRAC_MIN_N;
1643		max_n = CS48L32_FLLHJ_FRAC_MAX_N;
1644	} else {
1645		if (fref < CS48L32_FLLHJ_LP_INT_MODE_THRESH)
1646			hp = 0;
1647		else
1648			hp = 1;
1649
1650		min_n = CS48L32_FLLHJ_INT_MIN_N;
1651		max_n = CS48L32_FLLHJ_INT_MAX_N;
1652	}
1653
1654	ratio = fout / fref;
1655
1656	cs48l32_fll_dbg(fll, "refdiv=%d, fref=%d, frac:%d\n", refdiv, fref, frac);
1657
1658	while (ratio / fbdiv < min_n) {
1659		fbdiv /= 2;
1660		if (fbdiv < min_n) {
1661			cs48l32_fll_err(fll, "FBDIV (%u) < minimum N (%u)\n", fbdiv, min_n);
1662			return -EINVAL;
1663		}
1664	}
1665	while (frac && (ratio / fbdiv > max_n)) {
1666		fbdiv *= 2;
1667		if (fbdiv >= 1024) {
1668			cs48l32_fll_err(fll, "FBDIV (%u) >= 1024\n", fbdiv);
1669			return -EINVAL;
1670		}
1671	}
1672
1673	cs48l32_fll_dbg(fll, "lockdet=%d, hp=#%x, fbdiv:%d\n", lockdet_thr, hp, fbdiv);
1674
1675	/* Calculate N.K values */
1676	fllgcd = gcd(fout, fbdiv * fref);
1677	num = fout / fllgcd;
1678	lambda = (fref * fbdiv) / fllgcd;
1679	fll_n = num / lambda;
1680	theta = num % lambda;
1681
1682	cs48l32_fll_dbg(fll, "fll_n=%d, gcd=%d, theta=%d, lambda=%d\n",
1683			fll_n, fllgcd, theta, lambda);
1684
1685	/* Some sanity checks before any registers are written. */
1686	if (fll_n < min_n || fll_n > max_n) {
1687		cs48l32_fll_err(fll, "N not in valid %s mode range %d-%d: %d\n",
1688				frac ? "fractional" : "integer", min_n, max_n, fll_n);
1689		return -EINVAL;
1690	}
1691	if (fbdiv < 1 || (frac && fbdiv >= 1024) || (!frac && fbdiv >= 256)) {
1692		cs48l32_fll_err(fll, "Invalid fbdiv for %s mode (%u)\n",
1693				frac ? "fractional" : "integer", fbdiv);
1694		return -EINVAL;
1695	}
1696
1697	/* clear the ctrl_upd bit to guarantee we write to it later. */
1698	regmap_update_bits(regmap,
1699			   fll->base + CS48L32_FLL_CONTROL2_OFFS,
1700			   CS48L32_FLL_LOCKDET_THR_MASK |
1701			   CS48L32_FLL_PHASEDET_MASK |
1702			   CS48L32_FLL_REFCLK_DIV_MASK |
1703			   CS48L32_FLL_N_MASK |
1704			   CS48L32_FLL_CTRL_UPD_MASK,
1705			   (lockdet_thr << CS48L32_FLL_LOCKDET_THR_SHIFT) |
1706			   (1 << CS48L32_FLL_PHASEDET_SHIFT) |
1707			   (refdiv << CS48L32_FLL_REFCLK_DIV_SHIFT) |
1708			   (fll_n << CS48L32_FLL_N_SHIFT));
1709
1710	regmap_update_bits(regmap,
1711			   fll->base + CS48L32_FLL_CONTROL3_OFFS,
1712			   CS48L32_FLL_LAMBDA_MASK |
1713			   CS48L32_FLL_THETA_MASK,
1714			   (lambda << CS48L32_FLL_LAMBDA_SHIFT) |
1715			   (theta << CS48L32_FLL_THETA_SHIFT));
1716
1717	regmap_update_bits(regmap,
1718			   fll->base + CS48L32_FLL_CONTROL4_OFFS,
1719			   (0xffff << CS48L32_FLL_FD_GAIN_COARSE_SHIFT) |
1720			   CS48L32_FLL_HP_MASK |
1721			   CS48L32_FLL_FB_DIV_MASK,
1722			   (gains << CS48L32_FLL_FD_GAIN_COARSE_SHIFT) |
1723			   (hp << CS48L32_FLL_HP_SHIFT) |
1724			   (fbdiv << CS48L32_FLL_FB_DIV_SHIFT));
1725
1726	return 0;
1727}
1728
1729static int cs48l32_fllhj_enable(struct cs48l32_fll *fll)
1730{
1731	struct cs48l32 *cs48l32 = &fll->codec->core;
1732	int already_enabled = cs48l32_is_enabled_fll(fll, fll->base);
1733	int ret;
1734
1735	if (already_enabled < 0)
1736		return already_enabled;
1737
1738	if (!already_enabled)
1739		pm_runtime_get_sync(cs48l32->dev);
1740
1741	cs48l32_fll_dbg(fll, "Enabling FLL, initially %s\n",
1742			str_enabled_disabled(already_enabled));
1743
1744	/* FLLn_HOLD must be set before configuring any registers */
1745	regmap_set_bits(cs48l32->regmap,
1746			fll->base + CS48L32_FLL_CONTROL1_OFFS,
1747			CS48L32_FLL_HOLD_MASK);
1748
1749	/* Apply refclk */
1750	ret = cs48l32_fllhj_apply(fll, fll->ref_freq);
1751	if (ret) {
1752		cs48l32_fll_err(fll, "Failed to set FLL: %d\n", ret);
1753		goto out;
1754	}
1755	regmap_update_bits(cs48l32->regmap,
1756			   fll->base + CS48L32_FLL_CONTROL2_OFFS,
1757			   CS48L32_FLL_REFCLK_SRC_MASK,
1758			   fll->ref_src << CS48L32_FLL_REFCLK_SRC_SHIFT);
1759
1760	regmap_set_bits(cs48l32->regmap,
1761			fll->base + CS48L32_FLL_CONTROL1_OFFS,
1762			CS48L32_FLL_EN_MASK);
1763
1764out:
1765	regmap_set_bits(cs48l32->regmap,
1766			fll->base + CS48L32_FLL_CONTROL2_OFFS,
1767			CS48L32_FLL_LOCKDET_MASK);
1768
1769	regmap_set_bits(cs48l32->regmap,
1770			fll->base + CS48L32_FLL_CONTROL1_OFFS,
1771			CS48L32_FLL_CTRL_UPD_MASK);
1772
1773	/* Release the hold so that flln locks to external frequency */
1774	regmap_clear_bits(cs48l32->regmap,
1775			  fll->base + CS48L32_FLL_CONTROL1_OFFS,
1776			  CS48L32_FLL_HOLD_MASK);
1777
1778	if (!already_enabled)
1779		cs48l32_wait_for_fll(fll, true);
1780
1781	return 0;
1782}
1783
1784static int cs48l32_fllhj_validate(struct cs48l32_fll *fll,
1785				  unsigned int ref_in,
1786				  unsigned int fout)
1787{
1788	if (fout && !ref_in) {
1789		cs48l32_fll_err(fll, "fllout set without valid input clk\n");
1790		return -EINVAL;
1791	}
1792
1793	if (fll->fout && fout != fll->fout) {
1794		cs48l32_fll_err(fll, "Can't change output on active FLL\n");
1795		return -EINVAL;
1796	}
1797
1798	if (ref_in / CS48L32_FLL_MAX_REFDIV > CS48L32_FLLHJ_MAX_THRESH) {
1799		cs48l32_fll_err(fll, "Can't scale %dMHz to <=13MHz\n", ref_in);
1800		return -EINVAL;
1801	}
1802
1803	if (fout > CS48L32_FLL_MAX_FOUT) {
1804		cs48l32_fll_err(fll, "Fout=%dMHz exceeds maximum %dMHz\n",
1805				fout, CS48L32_FLL_MAX_FOUT);
1806		return -EINVAL;
1807	}
1808
1809	return 0;
1810}
1811
1812static int cs48l32_fllhj_set_refclk(struct cs48l32_fll *fll, int source,
1813				    unsigned int fin, unsigned int fout)
1814{
1815	int ret = 0;
1816
1817	if (fll->ref_src == source && fll->ref_freq == fin && fll->fout == fout)
1818		return 0;
1819
1820	if (fin && fout && cs48l32_fllhj_validate(fll, fin, fout))
1821		return -EINVAL;
1822
1823	fll->ref_src = source;
1824	fll->ref_freq = fin;
1825	fll->fout = fout;
1826
1827	if (fout)
1828		ret = cs48l32_fllhj_enable(fll);
1829	else
1830		cs48l32_fllhj_disable(fll);
1831
1832	return ret;
1833}
1834
1835static int cs48l32_init_fll(struct cs48l32_fll *fll)
1836{
1837	fll->ref_src = CS48L32_FLL_SRC_NONE;
1838
1839	return 0;
1840}
1841
1842static int cs48l32_set_fll(struct snd_soc_component *component, int fll_id,
1843			   int source, unsigned int fref, unsigned int fout)
1844{
1845	struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
1846
1847	switch (fll_id) {
1848	case CS48L32_FLL1_REFCLK:
1849		break;
1850	default:
1851		return -EINVAL;
1852	}
1853
1854	return cs48l32_fllhj_set_refclk(&cs48l32_codec->fll, source, fref, fout);
1855}
1856
1857static int cs48l32_asp_dai_probe(struct snd_soc_dai *dai)
1858{
1859	struct snd_soc_component *component = dai->component;
1860	struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
1861	struct regmap *regmap = cs48l32_codec->core.regmap;
1862	unsigned int pin_reg, last_pin_reg, hiz_reg;
1863
1864	switch (dai->id) {
1865	case 1:
1866		pin_reg = CS48L32_GPIO3_CTRL1;
1867		hiz_reg = CS48L32_ASP1_CONTROL3;
1868		break;
1869	case 2:
1870		pin_reg = CS48L32_GPIO7_CTRL1;
1871		hiz_reg = CS48L32_ASP2_CONTROL3;
1872		break;
1873	default:
1874		return -EINVAL;
1875	}
1876
1877	for (last_pin_reg = pin_reg + 12; pin_reg <= last_pin_reg; ++pin_reg)
1878		regmap_clear_bits(regmap, pin_reg, CS48L32_GPIOX_CTRL1_FN_MASK);
1879
1880	/* DOUT high-impendance when not transmitting */
1881	regmap_set_bits(regmap, hiz_reg, CS48L32_ASP_DOUT_HIZ_MASK);
1882
1883	return 0;
1884}
1885
1886static int cs48l32_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
1887{
1888	struct snd_soc_component *component = dai->component;
1889	struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
1890	struct regmap *regmap = cs48l32_codec->core.regmap;
1891	unsigned int val = 0U;
1892	unsigned int base = dai->driver->base;
1893	unsigned int mask = CS48L32_ASP_FMT_MASK | CS48L32_ASP_BCLK_INV_MASK |
1894			    CS48L32_ASP_BCLK_MSTR_MASK |
1895			    CS48L32_ASP_FSYNC_INV_MASK |
1896			    CS48L32_ASP_FSYNC_MSTR_MASK;
1897
1898	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1899	case SND_SOC_DAIFMT_DSP_A:
1900		val |= (CS48L32_ASP_FMT_DSP_MODE_A << CS48L32_ASP_FMT_SHIFT);
1901		break;
1902	case SND_SOC_DAIFMT_DSP_B:
1903		if ((fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) != SND_SOC_DAIFMT_BP_FP) {
1904			cs48l32_asp_err(dai, "DSP_B cannot be clock consumer\n");
1905			return -EINVAL;
1906		}
1907		val |= (CS48L32_ASP_FMT_DSP_MODE_B << CS48L32_ASP_FMT_SHIFT);
1908		break;
1909	case SND_SOC_DAIFMT_I2S:
1910		val |= (CS48L32_ASP_FMT_I2S_MODE << CS48L32_ASP_FMT_SHIFT);
1911		break;
1912	case SND_SOC_DAIFMT_LEFT_J:
1913		if ((fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) != SND_SOC_DAIFMT_BP_FP) {
1914			cs48l32_asp_err(dai, "LEFT_J cannot be clock consumer\n");
1915			return -EINVAL;
1916		}
1917		val |= (CS48L32_ASP_FMT_LEFT_JUSTIFIED_MODE << CS48L32_ASP_FMT_SHIFT);
1918		break;
1919	default:
1920		cs48l32_asp_err(dai, "Unsupported DAI format %d\n",
1921				fmt & SND_SOC_DAIFMT_FORMAT_MASK);
1922		return -EINVAL;
1923	}
1924
1925	switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
1926	case SND_SOC_DAIFMT_BC_FC:
1927		break;
1928	case SND_SOC_DAIFMT_BC_FP:
1929		val |= CS48L32_ASP_FSYNC_MSTR_MASK;
1930		break;
1931	case SND_SOC_DAIFMT_BP_FC:
1932		val |= CS48L32_ASP_BCLK_MSTR_MASK;
1933		break;
1934	case SND_SOC_DAIFMT_BP_FP:
1935		val |= CS48L32_ASP_BCLK_MSTR_MASK;
1936		val |= CS48L32_ASP_FSYNC_MSTR_MASK;
1937		break;
1938	default:
1939		cs48l32_asp_err(dai, "Unsupported clock direction %d\n",
1940				fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK);
1941		return -EINVAL;
1942	}
1943
1944	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1945	case SND_SOC_DAIFMT_NB_NF:
1946		break;
1947	case SND_SOC_DAIFMT_IB_IF:
1948		val |= CS48L32_ASP_BCLK_INV_MASK;
1949		val |= CS48L32_ASP_FSYNC_INV_MASK;
1950		break;
1951	case SND_SOC_DAIFMT_IB_NF:
1952		val |= CS48L32_ASP_BCLK_INV_MASK;
1953		break;
1954	case SND_SOC_DAIFMT_NB_IF:
1955		val |= CS48L32_ASP_FSYNC_INV_MASK;
1956		break;
1957	default:
1958		return -EINVAL;
1959	}
1960
1961	regmap_update_bits(regmap, base + CS48L32_ASP_CONTROL2, mask, val);
1962
1963	return 0;
1964}
1965
1966static const struct {
1967	u32 freq;
1968	u32 id;
1969} cs48l32_sclk_rates[] = {
1970	{ 128000,   12 },
1971	{ 176400,   13 },
1972	{ 192000,   14 },
1973	{ 256000,   15 },
1974	{ 352800,   16 },
1975	{ 384000,   17 },
1976	{ 512000,   18 },
1977	{ 705600,   19 },
1978	{ 768000,   21 },
1979	{ 1024000,  23 },
1980	{ 1411200,  25 },
1981	{ 1536000,  27 },
1982	{ 2048000,  29 },
1983	{ 2822400,  31 },
1984	{ 3072000,  33 },
1985	{ 4096000,  36 },
1986	{ 5644800,  38 },
1987	{ 6144000,  40 },
1988	{ 8192000,  47 },
1989	{ 11289600, 49 },
1990	{ 12288000, 51 },
1991	{ 22579200, 57 },
1992	{ 24576000, 59 },
1993};
1994
1995#define CS48L32_48K_RATE_MASK	0x0e00fe
1996#define CS48L32_44K1_RATE_MASK	0x00fe00
1997#define CS48L32_RATE_MASK	(CS48L32_48K_RATE_MASK | CS48L32_44K1_RATE_MASK)
1998
1999static const unsigned int cs48l32_sr_vals[] = {
2000	0,
2001	12000,  /* CS48L32_48K_RATE_MASK */
2002	24000,  /* CS48L32_48K_RATE_MASK */
2003	48000,  /* CS48L32_48K_RATE_MASK */
2004	96000,  /* CS48L32_48K_RATE_MASK */
2005	192000, /* CS48L32_48K_RATE_MASK */
2006	384000, /* CS48L32_48K_RATE_MASK */
2007	768000, /* CS48L32_48K_RATE_MASK */
2008	0,
2009	11025,  /* CS48L32_44K1_RATE_MASK */
2010	22050,  /* CS48L32_44K1_RATE_MASK */
2011	44100,  /* CS48L32_44K1_RATE_MASK */
2012	88200,  /* CS48L32_44K1_RATE_MASK */
2013	176400, /* CS48L32_44K1_RATE_MASK */
2014	352800, /* CS48L32_44K1_RATE_MASK */
2015	705600, /* CS48L32_44K1_RATE_MASK */
2016	0,
2017	8000,   /* CS48L32_48K_RATE_MASK */
2018	16000,  /* CS48L32_48K_RATE_MASK */
2019	32000,  /* CS48L32_48K_RATE_MASK */
2020};
2021
2022static const struct snd_pcm_hw_constraint_list cs48l32_constraint = {
2023	.count	= ARRAY_SIZE(cs48l32_sr_vals),
2024	.list	= cs48l32_sr_vals,
2025};
2026
2027static int cs48l32_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
2028{
2029	struct snd_soc_component *component = dai->component;
2030	struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
2031	struct cs48l32_dai_priv *dai_priv = &cs48l32_codec->dai[dai->id - 1];
2032	unsigned int base_rate;
2033
2034	if (!substream->runtime)
2035		return 0;
2036
2037	switch (dai_priv->clk) {
2038	case CS48L32_CLK_SYSCLK_1:
2039	case CS48L32_CLK_SYSCLK_2:
2040	case CS48L32_CLK_SYSCLK_3:
2041	case CS48L32_CLK_SYSCLK_4:
2042		base_rate = cs48l32_codec->sysclk;
2043		break;
2044	default:
2045		return 0;
2046	}
2047
2048	if (base_rate == 0)
2049		dai_priv->constraint.mask = CS48L32_RATE_MASK;
2050	else if (base_rate % 4000)
2051		dai_priv->constraint.mask = CS48L32_44K1_RATE_MASK;
2052	else
2053		dai_priv->constraint.mask = CS48L32_48K_RATE_MASK;
2054
2055	return snd_pcm_hw_constraint_list(substream->runtime, 0,
2056					  SNDRV_PCM_HW_PARAM_RATE,
2057					  &dai_priv->constraint);
2058}
2059
2060static int cs48l32_hw_params_rate(struct snd_pcm_substream *substream,
2061				  struct snd_pcm_hw_params *params,
2062				  struct snd_soc_dai *dai)
2063{
2064	struct snd_soc_component *component = dai->component;
2065	struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
2066	struct cs48l32_dai_priv *dai_priv = &cs48l32_codec->dai[dai->id - 1];
2067	unsigned int sr_val, sr_reg, rate;
2068
2069	rate = params_rate(params);
2070	for (sr_val = 0; sr_val < ARRAY_SIZE(cs48l32_sr_vals); sr_val++)
2071		if (cs48l32_sr_vals[sr_val] == rate)
2072			break;
2073
2074	if (sr_val == ARRAY_SIZE(cs48l32_sr_vals)) {
2075		cs48l32_asp_err(dai, "Unsupported sample rate %dHz\n", rate);
2076		return -EINVAL;
2077	}
2078
2079	switch (dai_priv->clk) {
2080	case CS48L32_CLK_SYSCLK_1:
2081		sr_reg = CS48L32_SAMPLE_RATE1;
2082		break;
2083	case CS48L32_CLK_SYSCLK_2:
2084		sr_reg = CS48L32_SAMPLE_RATE2;
2085		break;
2086	case CS48L32_CLK_SYSCLK_3:
2087		sr_reg = CS48L32_SAMPLE_RATE3;
2088		break;
2089	case CS48L32_CLK_SYSCLK_4:
2090		sr_reg = CS48L32_SAMPLE_RATE4;
2091		break;
2092	default:
2093		return -EINVAL;
2094	}
2095
2096	snd_soc_component_update_bits(component, sr_reg, CS48L32_SAMPLE_RATE_1_MASK, sr_val);
2097
2098	return 0;
2099}
2100
2101static bool cs48l32_asp_cfg_changed(struct snd_soc_component *component,
2102				    unsigned int base, unsigned int sclk,
2103				    unsigned int slotws, unsigned int dataw)
2104{
2105	unsigned int val;
2106
2107	val = snd_soc_component_read(component, base + CS48L32_ASP_CONTROL1);
2108	if (sclk != (val & CS48L32_ASP_BCLK_FREQ_MASK))
2109		return true;
2110
2111	val = snd_soc_component_read(component, base + CS48L32_ASP_CONTROL2);
2112	if (slotws != (val & (CS48L32_ASP_RX_WIDTH_MASK | CS48L32_ASP_TX_WIDTH_MASK)))
2113		return true;
2114
2115	val = snd_soc_component_read(component, base + CS48L32_ASP_DATA_CONTROL1);
2116	if (dataw != (val & (CS48L32_ASP_TX_WL_MASK)))
2117		return true;
2118
2119	val = snd_soc_component_read(component, base + CS48L32_ASP_DATA_CONTROL5);
2120	if (dataw != (val & (CS48L32_ASP_RX_WL_MASK)))
2121		return true;
2122
2123	return false;
2124}
2125
2126static int cs48l32_hw_params(struct snd_pcm_substream *substream,
2127			     struct snd_pcm_hw_params *params,
2128			     struct snd_soc_dai *dai)
2129{
2130	struct snd_soc_component *component = dai->component;
2131	struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
2132	struct regmap *regmap = cs48l32_codec->core.regmap;
2133	int base = dai->driver->base;
2134	int dai_id = dai->id - 1;
2135	unsigned int rate = params_rate(params);
2136	unsigned int dataw = snd_pcm_format_width(params_format(params));
2137	unsigned int asp_state = 0;
2138	int sclk, sclk_target;
2139	unsigned int slotw, n_slots, n_slots_multiple, val;
2140	int i, ret;
2141
2142	cs48l32_asp_dbg(dai, "hwparams in: ch:%u dataw:%u rate:%u\n",
2143			params_channels(params), dataw, rate);
2144	/*
2145	 * The following calculations hold only under the assumption that
2146	 * symmetric_[rates|channels|samplebits] are set to 1
2147	 */
2148	if (cs48l32_codec->tdm_slots[dai_id]) {
2149		n_slots = cs48l32_codec->tdm_slots[dai_id];
2150		slotw = cs48l32_codec->tdm_width[dai_id];
2151	} else {
2152		n_slots = params_channels(params);
2153		slotw = dataw;
2154	}
2155
2156	val = snd_soc_component_read(component, base + CS48L32_ASP_CONTROL2);
2157	val = (val & CS48L32_ASP_FMT_MASK) >> CS48L32_ASP_FMT_SHIFT;
2158	if (val == CS48L32_ASP_FMT_I2S_MODE)
2159		n_slots_multiple = 2;
2160	else
2161		n_slots_multiple = 1;
2162
2163	sclk_target = snd_soc_tdm_params_to_bclk(params, slotw, n_slots, n_slots_multiple);
2164	if (sclk_target < 0) {
2165		cs48l32_asp_err(dai, "Invalid parameters\n");
2166		return sclk_target;
2167	}
2168
2169	for (i = 0; i < ARRAY_SIZE(cs48l32_sclk_rates); i++) {
2170		if ((cs48l32_sclk_rates[i].freq >= sclk_target) &&
2171		    (cs48l32_sclk_rates[i].freq % rate == 0)) {
2172			sclk = cs48l32_sclk_rates[i].id;
2173			break;
2174		}
2175	}
2176	if (i == ARRAY_SIZE(cs48l32_sclk_rates)) {
2177		cs48l32_asp_err(dai, "Unsupported sample rate %dHz\n", rate);
2178		return -EINVAL;
2179	}
2180
2181	cs48l32_asp_dbg(dai, "hwparams out: n_slots:%u dataw:%u slotw:%u bclk:%u bclkid:%u\n",
2182			n_slots, dataw, slotw, sclk_target, sclk);
2183
2184	slotw = (slotw << CS48L32_ASP_TX_WIDTH_SHIFT) |
2185		(slotw << CS48L32_ASP_RX_WIDTH_SHIFT);
2186
2187	if (!cs48l32_asp_cfg_changed(component, base, sclk, slotw, dataw))
2188		return cs48l32_hw_params_rate(substream, params, dai);
2189
2190	/* ASP must be disabled while changing configuration */
2191	asp_state = snd_soc_component_read(component, base + CS48L32_ASP_ENABLES1);
2192	regmap_clear_bits(regmap, base + CS48L32_ASP_ENABLES1, 0xff00ff);
2193
2194	ret = cs48l32_hw_params_rate(substream, params, dai);
2195	if (ret != 0)
2196		goto restore_asp;
2197
2198	regmap_update_bits_async(regmap,
2199				 base + CS48L32_ASP_CONTROL1,
2200				 CS48L32_ASP_BCLK_FREQ_MASK,
2201				 sclk);
2202	regmap_update_bits_async(regmap,
2203				 base + CS48L32_ASP_CONTROL2,
2204				 CS48L32_ASP_RX_WIDTH_MASK | CS48L32_ASP_TX_WIDTH_MASK,
2205				 slotw);
2206	regmap_update_bits_async(regmap,
2207				 base + CS48L32_ASP_DATA_CONTROL1,
2208				 CS48L32_ASP_TX_WL_MASK,
2209				 dataw);
2210	regmap_update_bits(regmap,
2211			   base + CS48L32_ASP_DATA_CONTROL5,
2212			   CS48L32_ASP_RX_WL_MASK,
2213			   dataw);
2214
2215restore_asp:
2216	/* Restore ASP TX/RX enable state */
2217	regmap_update_bits(regmap,
2218			   base + CS48L32_ASP_ENABLES1,
2219			   0xff00ff,
2220			   asp_state);
2221	return ret;
2222}
2223
2224static const char *cs48l32_dai_clk_str(int clk_id)
2225{
2226	switch (clk_id) {
2227	case CS48L32_CLK_SYSCLK_1:
2228	case CS48L32_CLK_SYSCLK_2:
2229	case CS48L32_CLK_SYSCLK_3:
2230	case CS48L32_CLK_SYSCLK_4:
2231		return "SYSCLK";
2232	default:
2233		return "Unknown clock";
2234	}
2235}
2236
2237static int cs48l32_dai_set_sysclk(struct snd_soc_dai *dai,
2238				  int clk_id, unsigned int freq, int dir)
2239{
2240	struct snd_soc_component *component = dai->component;
2241	struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
2242	struct cs48l32_dai_priv *dai_priv = &cs48l32_codec->dai[dai->id - 1];
2243	unsigned int base = dai->driver->base;
2244	unsigned int current_asp_rate, target_asp_rate;
2245	bool change_rate_domain = false;
2246	int ret;
2247
2248	if (clk_id == dai_priv->clk)
2249		return 0;
2250
2251	if (snd_soc_dai_active(dai)) {
2252		cs48l32_asp_err(dai, "Can't change clock on active DAI\n");
2253		return -EBUSY;
2254	}
2255
2256	switch (clk_id) {
2257	case CS48L32_CLK_SYSCLK_1:
2258		target_asp_rate = 0U << CS48L32_ASP_RATE_SHIFT;
2259		break;
2260	case CS48L32_CLK_SYSCLK_2:
2261		target_asp_rate = 1U << CS48L32_ASP_RATE_SHIFT;
2262		break;
2263	case CS48L32_CLK_SYSCLK_3:
2264		target_asp_rate = 2U << CS48L32_ASP_RATE_SHIFT;
2265		break;
2266	case CS48L32_CLK_SYSCLK_4:
2267		target_asp_rate = 3U << CS48L32_ASP_RATE_SHIFT;
2268		break;
2269	default:
2270		return -EINVAL;
2271	}
2272
2273	dai_priv->clk = clk_id;
2274	cs48l32_asp_dbg(dai, "Setting to %s\n", cs48l32_dai_clk_str(clk_id));
2275
2276	if (base) {
2277		ret = regmap_read(cs48l32_codec->core.regmap,
2278				  base + CS48L32_ASP_CONTROL1,
2279				  &current_asp_rate);
2280		if (ret != 0) {
2281			cs48l32_asp_err(dai, "Failed to check rate: %d\n", ret);
2282			return ret;
2283		}
2284
2285		if ((current_asp_rate & CS48L32_ASP_RATE_MASK) !=
2286		    (target_asp_rate & CS48L32_ASP_RATE_MASK)) {
2287			change_rate_domain = true;
2288
2289			mutex_lock(&cs48l32_codec->rate_lock);
2290			/* Guard the rate change with SYSCLK cycles */
2291			cs48l32_spin_sysclk(cs48l32_codec);
2292		}
2293
2294		snd_soc_component_update_bits(component, base + CS48L32_ASP_CONTROL1,
2295					      CS48L32_ASP_RATE_MASK, target_asp_rate);
2296
2297		if (change_rate_domain) {
2298			cs48l32_spin_sysclk(cs48l32_codec);
2299			mutex_unlock(&cs48l32_codec->rate_lock);
2300		}
2301	}
2302
2303	return 0;
2304}
2305
2306static void cs48l32_set_channels_to_mask(struct snd_soc_dai *dai,
2307					 unsigned int base,
2308					 int channels, unsigned int mask)
2309{
2310	struct snd_soc_component *component = dai->component;
2311	struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
2312	struct regmap *regmap = cs48l32_codec->core.regmap;
2313	int slot, i, j = 0, shift;
2314	unsigned int frame_ctls[2] = {0, 0};
2315
2316	for (i = 0; i < channels; ++i) {
2317		slot = ffs(mask) - 1;
2318		if (slot < 0)
2319			return;
2320
2321		if (i - (j * 4) >= 4) {
2322			++j;
2323			if (j >= 2)
2324				break;
2325		}
2326
2327		shift = (8 * (i - j * 4));
2328
2329		frame_ctls[j] |= slot << shift;
2330
2331		mask &= ~(1 << slot); /* ? mask ^= 1 << slot ? */
2332	}
2333
2334	regmap_write(regmap, base, frame_ctls[0]);
2335	regmap_write(regmap, base + 0x4, frame_ctls[1]);
2336
2337	if (mask)
2338		cs48l32_asp_warn(dai, "Too many channels in TDM mask\n");
2339}
2340
2341static int cs48l32_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
2342				unsigned int rx_mask, int slots, int slot_width)
2343{
2344	struct snd_soc_component *component = dai->component;
2345	struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
2346	int base = dai->driver->base;
2347	int rx_max_chan = dai->driver->playback.channels_max;
2348	int tx_max_chan = dai->driver->capture.channels_max;
2349
2350	/* Only support TDM for the physical ASPs */
2351	if (dai->id > CS48L32_MAX_ASP)
2352		return -EINVAL;
2353
2354	if (slots == 0) {
2355		tx_mask = (1 << tx_max_chan) - 1;
2356		rx_mask = (1 << rx_max_chan) - 1;
2357	}
2358
2359	cs48l32_set_channels_to_mask(dai, base + CS48L32_ASP_FRAME_CONTROL1,
2360				   tx_max_chan, tx_mask);
2361	cs48l32_set_channels_to_mask(dai, base + CS48L32_ASP_FRAME_CONTROL5,
2362				   rx_max_chan, rx_mask);
2363
2364	cs48l32_codec->tdm_width[dai->id - 1] = slot_width;
2365	cs48l32_codec->tdm_slots[dai->id - 1] = slots;
2366
2367	return 0;
2368}
2369
2370static const struct snd_soc_dai_ops cs48l32_dai_ops = {
2371	.probe = &cs48l32_asp_dai_probe,
2372	.startup = &cs48l32_startup,
2373	.set_fmt = &cs48l32_set_fmt,
2374	.set_tdm_slot = &cs48l32_set_tdm_slot,
2375	.hw_params = &cs48l32_hw_params,
2376	.set_sysclk = &cs48l32_dai_set_sysclk,
2377};
2378
2379static int cs48l32_sysclk_ev(struct snd_soc_dapm_widget *w,
2380			     struct snd_kcontrol *kcontrol, int event)
2381{
2382	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
2383	struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
2384
2385	cs48l32_spin_sysclk(cs48l32_codec);
2386
2387	return 0;
2388}
2389
2390static int cs48l32_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event)
2391{
2392	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
2393	struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
2394	unsigned int reg;
2395
2396	if (w->shift % 2)
2397		reg = CS48L32_IN1L_CONTROL2;
2398	else
2399		reg = CS48L32_IN1R_CONTROL2;
2400
2401	reg += (w->shift / 2) * (CS48L32_IN2L_CONTROL2 - CS48L32_IN1L_CONTROL2);
2402
2403	switch (event) {
2404	case SND_SOC_DAPM_PRE_PMU:
2405		switch (w->shift) {
2406		case CS48L32_IN1L_EN_SHIFT:
2407			snd_soc_component_update_bits(component,
2408						      CS48L32_ADC1L_ANA_CONTROL1,
2409						      CS48L32_ADC1x_INT_ENA_FRC_MASK,
2410						      CS48L32_ADC1x_INT_ENA_FRC_MASK);
2411			break;
2412		case CS48L32_IN1R_EN_SHIFT:
2413			snd_soc_component_update_bits(component,
2414						      CS48L32_ADC1R_ANA_CONTROL1,
2415						      CS48L32_ADC1x_INT_ENA_FRC_MASK,
2416						      CS48L32_ADC1x_INT_ENA_FRC_MASK);
2417			break;
2418		default:
2419			break;
2420		}
2421		cs48l32_codec->in_up_pending++;
2422		break;
2423	case SND_SOC_DAPM_POST_PMU:
2424		usleep_range(200, 300);
2425
2426		switch (w->shift) {
2427		case CS48L32_IN1L_EN_SHIFT:
2428			snd_soc_component_update_bits(component,
2429						      CS48L32_ADC1L_ANA_CONTROL1,
2430						      CS48L32_ADC1x_INT_ENA_FRC_MASK,
2431						      0);
2432			break;
2433		case CS48L32_IN1R_EN_SHIFT:
2434			snd_soc_component_update_bits(component,
2435						      CS48L32_ADC1R_ANA_CONTROL1,
2436						      CS48L32_ADC1x_INT_ENA_FRC_MASK,
2437						      0);
2438			break;
2439
2440		default:
2441			break;
2442		}
2443		cs48l32_codec->in_up_pending--;
2444		snd_soc_component_update_bits(component, reg, CS48L32_INx_MUTE_MASK, 0);
2445
2446		/* Uncached write-only register, no need for update_bits */
2447		if (!cs48l32_codec->in_up_pending) {
2448			snd_soc_component_write(component, cs48l32_codec->in_vu_reg,
2449						CS48L32_IN_VU_MASK);
2450		}
2451		break;
2452	case SND_SOC_DAPM_PRE_PMD:
2453		snd_soc_component_update_bits(component, reg,
2454					      CS48L32_INx_MUTE_MASK, CS48L32_INx_MUTE_MASK);
2455		snd_soc_component_write(component, cs48l32_codec->in_vu_reg,
2456					CS48L32_IN_VU_MASK);
2457		break;
2458	default:
2459		break;
2460	}
2461
2462	return 0;
2463}
2464
2465static int cs48l32_in_put_volsw(struct snd_kcontrol *kcontrol,
2466				struct snd_ctl_elem_value *ucontrol)
2467{
2468	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
2469	struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
2470	int ret;
2471
2472	ret = snd_soc_put_volsw(kcontrol, ucontrol);
2473	if (ret < 0)
2474		return ret;
2475
2476	/*
2477	 * Uncached write-only register, no need for update_bits.
2478	 * Will fail if codec is off but that will be handled by cs48l32_in_ev
2479	 */
2480	snd_soc_component_write(component, cs48l32_codec->in_vu_reg, CS48L32_IN_VU);
2481
2482	return ret;
2483}
2484
2485static bool cs48l32_eq_filter_unstable(bool mode, __be16 in_a, __be16 in_b)
2486{
2487	s16 a = be16_to_cpu(in_a);
2488	s16 b = be16_to_cpu(in_b);
2489
2490	if (!mode)
2491		return abs(a) > CS48L32_EQ_MAX_COEFF;
2492
2493	if (abs(b) > CS48L32_EQ_MAX_COEFF)
2494		return true;
2495
2496	if (abs((a << 16) / (CS48L32_EQ_MAX_COEFF + 1 - b)) >= ((CS48L32_EQ_MAX_COEFF + 1) << 4))
2497		return true;
2498
2499	return false;
2500}
2501
2502static int cs48l32_eq_ev(struct snd_soc_dapm_widget *w,
2503			 struct snd_kcontrol *kcontrol, int event)
2504{
2505	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
2506	struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
2507	struct regmap *regmap = cs48l32_codec->core.regmap;
2508	unsigned int mode = cs48l32_codec->eq_mode[w->shift];
2509	unsigned int reg;
2510	__be16 *data = &cs48l32_codec->eq_coefficients[w->shift][0];
2511	int ret = 0;
2512
2513	reg = CS48L32_EQ1_BAND1_COEFF1;
2514	reg += w->shift * (CS48L32_EQ2_BAND1_COEFF1 - CS48L32_EQ1_BAND1_COEFF1);
2515
2516	switch (event) {
2517	case SND_SOC_DAPM_PRE_PMU:
2518		if (cs48l32_eq_filter_unstable(!!mode, data[1], data[0]) ||
2519		    cs48l32_eq_filter_unstable(true, data[7], data[6]) ||
2520		    cs48l32_eq_filter_unstable(true, data[13], data[12]) ||
2521		    cs48l32_eq_filter_unstable(true, data[19], data[18]) ||
2522		    cs48l32_eq_filter_unstable(false, data[25], data[24])) {
2523			dev_err(cs48l32_codec->core.dev, "Rejecting unstable EQ coefficients.\n");
2524			ret = -EINVAL;
2525		} else {
2526			ret = regmap_raw_write(regmap, reg, data, CS48L32_EQ_BLOCK_SZ);
2527			if (ret < 0) {
2528				dev_err(cs48l32_codec->core.dev,
2529					"Error writing EQ coefficients: %d\n", ret);
2530				goto out;
2531			}
2532
2533			ret = snd_soc_component_update_bits(component,
2534							    CS48L32_EQ_CONTROL2,
2535							    w->mask,
2536							    mode << w->shift);
2537			if (ret < 0) {
2538				dev_err(cs48l32_codec->core.dev,
2539					"Error writing EQ mode: %d\n", ret);
2540			}
2541		}
2542		break;
2543	default:
2544		break;
2545	}
2546
2547out:
2548	return ret;
2549}
2550
2551static const struct snd_kcontrol_new cs48l32_snd_controls[] = {
2552SOC_ENUM("IN1 OSR", cs48l32_in_dmic_osr[0]),
2553SOC_ENUM("IN2 OSR", cs48l32_in_dmic_osr[1]),
2554
2555SOC_SINGLE_RANGE_TLV("IN1L Volume", CS48L32_IN1L_CONTROL2,
2556		     CS48L32_INx_PGA_VOL_SHIFT, 0x40, 0x5f, 0, cs48l32_ana_tlv),
2557SOC_SINGLE_RANGE_TLV("IN1R Volume", CS48L32_IN1R_CONTROL2,
2558		     CS48L32_INx_PGA_VOL_SHIFT, 0x40, 0x5f, 0, cs48l32_ana_tlv),
2559
2560SOC_ENUM("IN HPF Cutoff Frequency", cs48l32_in_hpf_cut_enum),
2561
2562SOC_SINGLE_EXT("IN1L LP Switch", CS48L32_IN1L_CONTROL1, CS48L32_INx_LP_MODE_SHIFT,
2563	       1, 0, snd_soc_get_volsw, cs48l32_low_power_mode_put),
2564SOC_SINGLE_EXT("IN1R LP Switch", CS48L32_IN1R_CONTROL1, CS48L32_INx_LP_MODE_SHIFT,
2565	       1, 0, snd_soc_get_volsw, cs48l32_low_power_mode_put),
2566
2567SOC_SINGLE("IN1L HPF Switch", CS48L32_IN1L_CONTROL1, CS48L32_INx_HPF_SHIFT, 1, 0),
2568SOC_SINGLE("IN1R HPF Switch", CS48L32_IN1R_CONTROL1, CS48L32_INx_HPF_SHIFT, 1, 0),
2569SOC_SINGLE("IN2L HPF Switch", CS48L32_IN2L_CONTROL1, CS48L32_INx_HPF_SHIFT, 1, 0),
2570SOC_SINGLE("IN2R HPF Switch", CS48L32_IN2R_CONTROL1, CS48L32_INx_HPF_SHIFT, 1, 0),
2571
2572SOC_SINGLE_EXT_TLV("IN1L Digital Volume", CS48L32_IN1L_CONTROL2,
2573		   CS48L32_INx_VOL_SHIFT, 0xbf, 0, snd_soc_get_volsw,
2574		   cs48l32_in_put_volsw, cs48l32_digital_tlv),
2575SOC_SINGLE_EXT_TLV("IN1R Digital Volume", CS48L32_IN1R_CONTROL2,
2576		   CS48L32_INx_VOL_SHIFT, 0xbf, 0, snd_soc_get_volsw,
2577		   cs48l32_in_put_volsw, cs48l32_digital_tlv),
2578SOC_SINGLE_EXT_TLV("IN2L Digital Volume", CS48L32_IN2L_CONTROL2,
2579		   CS48L32_INx_VOL_SHIFT, 0xbf, 0, snd_soc_get_volsw,
2580		   cs48l32_in_put_volsw, cs48l32_digital_tlv),
2581SOC_SINGLE_EXT_TLV("IN2R Digital Volume", CS48L32_IN2R_CONTROL2,
2582		   CS48L32_INx_VOL_SHIFT, 0xbf, 0, snd_soc_get_volsw,
2583		   cs48l32_in_put_volsw, cs48l32_digital_tlv),
2584
2585SOC_ENUM("Input Ramp Up", cs48l32_in_vi_ramp),
2586SOC_ENUM("Input Ramp Down", cs48l32_in_vd_ramp),
2587
2588CS48L32_RATE_ENUM("Ultrasonic 1 Rate", cs48l32_us_output_rate[0]),
2589CS48L32_RATE_ENUM("Ultrasonic 2 Rate", cs48l32_us_output_rate[1]),
2590
2591SOC_ENUM("Ultrasonic 1 Freq", cs48l32_us_freq[0]),
2592SOC_ENUM("Ultrasonic 2 Freq", cs48l32_us_freq[1]),
2593
2594SOC_SINGLE_TLV("Ultrasonic 1 Volume", CS48L32_US1_CONTROL, CS48L32_US1_GAIN_SHIFT,
2595	       3, 0, cs48l32_us_tlv),
2596SOC_SINGLE_TLV("Ultrasonic 2 Volume", CS48L32_US2_CONTROL, CS48L32_US1_GAIN_SHIFT,
2597	       3, 0, cs48l32_us_tlv),
2598
2599SOC_ENUM("Ultrasonic 1 Detect Threshold", cs48l32_us_det_thr[0]),
2600SOC_ENUM("Ultrasonic 2 Detect Threshold", cs48l32_us_det_thr[1]),
2601
2602SOC_ENUM("Ultrasonic 1 Detect Pulse Length", cs48l32_us_det_num[0]),
2603SOC_ENUM("Ultrasonic 2 Detect Pulse Length", cs48l32_us_det_num[1]),
2604
2605SOC_ENUM("Ultrasonic 1 Detect Hold", cs48l32_us_det_hold[0]),
2606SOC_ENUM("Ultrasonic 2 Detect Hold", cs48l32_us_det_hold[1]),
2607
2608SOC_ENUM("Ultrasonic 1 Detect Decay", cs48l32_us_det_dcy[0]),
2609SOC_ENUM("Ultrasonic 2 Detect Decay", cs48l32_us_det_dcy[1]),
2610
2611SOC_SINGLE("Ultrasonic 1 Detect LPF Switch",
2612	   CS48L32_US1_DET_CONTROL, CS48L32_US1_DET_LPF_SHIFT, 1, 0),
2613SOC_SINGLE("Ultrasonic 2 Detect LPF Switch",
2614	   CS48L32_US2_DET_CONTROL, CS48L32_US1_DET_LPF_SHIFT, 1, 0),
2615
2616SOC_ENUM("Ultrasonic 1 Detect LPF Cut-off", cs48l32_us_det_lpf_cut[0]),
2617SOC_ENUM("Ultrasonic 2 Detect LPF Cut-off", cs48l32_us_det_lpf_cut[1]),
2618
2619CS48L32_MIXER_CONTROLS("EQ1", CS48L32_EQ1_INPUT1),
2620CS48L32_MIXER_CONTROLS("EQ2", CS48L32_EQ2_INPUT1),
2621CS48L32_MIXER_CONTROLS("EQ3", CS48L32_EQ3_INPUT1),
2622CS48L32_MIXER_CONTROLS("EQ4", CS48L32_EQ4_INPUT1),
2623
2624SOC_ENUM_EXT("EQ1 Mode", cs48l32_eq_mode[0], cs48l32_eq_mode_get, cs48l32_eq_mode_put),
2625
2626CS48L32_EQ_COEFF_CONTROLS(EQ1),
2627
2628SOC_SINGLE_TLV("EQ1 B1 Volume", CS48L32_EQ1_GAIN1, 0, 24, 0, cs48l32_eq_tlv),
2629SOC_SINGLE_TLV("EQ1 B2 Volume", CS48L32_EQ1_GAIN1, 8, 24, 0, cs48l32_eq_tlv),
2630SOC_SINGLE_TLV("EQ1 B3 Volume", CS48L32_EQ1_GAIN1, 16, 24, 0, cs48l32_eq_tlv),
2631SOC_SINGLE_TLV("EQ1 B4 Volume", CS48L32_EQ1_GAIN1, 24, 24, 0, cs48l32_eq_tlv),
2632SOC_SINGLE_TLV("EQ1 B5 Volume", CS48L32_EQ1_GAIN2, 0,  24, 0, cs48l32_eq_tlv),
2633
2634SOC_ENUM_EXT("EQ2 Mode", cs48l32_eq_mode[1], cs48l32_eq_mode_get, cs48l32_eq_mode_put),
2635CS48L32_EQ_COEFF_CONTROLS(EQ2),
2636SOC_SINGLE_TLV("EQ2 B1 Volume", CS48L32_EQ2_GAIN1, 0, 24, 0, cs48l32_eq_tlv),
2637SOC_SINGLE_TLV("EQ2 B2 Volume", CS48L32_EQ2_GAIN1, 8, 24, 0, cs48l32_eq_tlv),
2638SOC_SINGLE_TLV("EQ2 B3 Volume", CS48L32_EQ2_GAIN1, 16, 24, 0, cs48l32_eq_tlv),
2639SOC_SINGLE_TLV("EQ2 B4 Volume", CS48L32_EQ2_GAIN1, 24, 24, 0, cs48l32_eq_tlv),
2640SOC_SINGLE_TLV("EQ2 B5 Volume", CS48L32_EQ2_GAIN2, 0,  24, 0, cs48l32_eq_tlv),
2641
2642SOC_ENUM_EXT("EQ3 Mode", cs48l32_eq_mode[2], cs48l32_eq_mode_get, cs48l32_eq_mode_put),
2643CS48L32_EQ_COEFF_CONTROLS(EQ3),
2644SOC_SINGLE_TLV("EQ3 B1 Volume", CS48L32_EQ3_GAIN1, 0, 24, 0, cs48l32_eq_tlv),
2645SOC_SINGLE_TLV("EQ3 B2 Volume", CS48L32_EQ3_GAIN1, 8, 24, 0, cs48l32_eq_tlv),
2646SOC_SINGLE_TLV("EQ3 B3 Volume", CS48L32_EQ3_GAIN1, 16, 24, 0, cs48l32_eq_tlv),
2647SOC_SINGLE_TLV("EQ3 B4 Volume", CS48L32_EQ3_GAIN1, 24, 24, 0, cs48l32_eq_tlv),
2648SOC_SINGLE_TLV("EQ3 B5 Volume", CS48L32_EQ3_GAIN2, 0,  24, 0, cs48l32_eq_tlv),
2649
2650SOC_ENUM_EXT("EQ4 Mode", cs48l32_eq_mode[3], cs48l32_eq_mode_get, cs48l32_eq_mode_put),
2651CS48L32_EQ_COEFF_CONTROLS(EQ4),
2652SOC_SINGLE_TLV("EQ4 B1 Volume", CS48L32_EQ4_GAIN1, 0, 24, 0, cs48l32_eq_tlv),
2653SOC_SINGLE_TLV("EQ4 B2 Volume", CS48L32_EQ4_GAIN1, 8, 24, 0, cs48l32_eq_tlv),
2654SOC_SINGLE_TLV("EQ4 B3 Volume", CS48L32_EQ4_GAIN1, 16, 24, 0, cs48l32_eq_tlv),
2655SOC_SINGLE_TLV("EQ4 B4 Volume", CS48L32_EQ4_GAIN1, 24, 24, 0, cs48l32_eq_tlv),
2656SOC_SINGLE_TLV("EQ4 B5 Volume", CS48L32_EQ4_GAIN2, 0,  24, 0, cs48l32_eq_tlv),
2657
2658CS48L32_MIXER_CONTROLS("DRC1L", CS48L32_DRC1L_INPUT1),
2659CS48L32_MIXER_CONTROLS("DRC1R", CS48L32_DRC1R_INPUT1),
2660CS48L32_MIXER_CONTROLS("DRC2L", CS48L32_DRC2L_INPUT1),
2661CS48L32_MIXER_CONTROLS("DRC2R", CS48L32_DRC2R_INPUT1),
2662
2663SND_SOC_BYTES_MASK("DRC1 Coefficients", CS48L32_DRC1_CONTROL1, 4,
2664		   BIT(CS48L32_DRC1R_EN_SHIFT) | BIT(CS48L32_DRC1L_EN_SHIFT)),
2665SND_SOC_BYTES_MASK("DRC2 Coefficients", CS48L32_DRC2_CONTROL1, 4,
2666		   BIT(CS48L32_DRC1R_EN_SHIFT) | BIT(CS48L32_DRC1L_EN_SHIFT)),
2667
2668CS48L32_MIXER_CONTROLS("LHPF1", CS48L32_LHPF1_INPUT1),
2669CS48L32_MIXER_CONTROLS("LHPF2", CS48L32_LHPF2_INPUT1),
2670CS48L32_MIXER_CONTROLS("LHPF3", CS48L32_LHPF3_INPUT1),
2671CS48L32_MIXER_CONTROLS("LHPF4", CS48L32_LHPF4_INPUT1),
2672
2673CS48L32_LHPF_CONTROL("LHPF1 Coefficients", CS48L32_LHPF1_COEFF),
2674CS48L32_LHPF_CONTROL("LHPF2 Coefficients", CS48L32_LHPF2_COEFF),
2675CS48L32_LHPF_CONTROL("LHPF3 Coefficients", CS48L32_LHPF3_COEFF),
2676CS48L32_LHPF_CONTROL("LHPF4 Coefficients", CS48L32_LHPF4_COEFF),
2677
2678SOC_ENUM("LHPF1 Mode", cs48l32_lhpf_mode[0]),
2679SOC_ENUM("LHPF2 Mode", cs48l32_lhpf_mode[1]),
2680SOC_ENUM("LHPF3 Mode", cs48l32_lhpf_mode[2]),
2681SOC_ENUM("LHPF4 Mode", cs48l32_lhpf_mode[3]),
2682
2683CS48L32_RATE_CONTROL("Sample Rate 1", 1),
2684CS48L32_RATE_CONTROL("Sample Rate 2", 2),
2685CS48L32_RATE_CONTROL("Sample Rate 3", 3),
2686CS48L32_RATE_CONTROL("Sample Rate 4", 4),
2687
2688CS48L32_RATE_ENUM("FX Rate", cs48l32_fx_rate),
2689
2690CS48L32_RATE_ENUM("ISRC1 FSL", cs48l32_isrc_fsl[0]),
2691CS48L32_RATE_ENUM("ISRC2 FSL", cs48l32_isrc_fsl[1]),
2692CS48L32_RATE_ENUM("ISRC3 FSL", cs48l32_isrc_fsl[2]),
2693CS48L32_RATE_ENUM("ISRC1 FSH", cs48l32_isrc_fsh[0]),
2694CS48L32_RATE_ENUM("ISRC2 FSH", cs48l32_isrc_fsh[1]),
2695CS48L32_RATE_ENUM("ISRC3 FSH", cs48l32_isrc_fsh[2]),
2696
2697SOC_ENUM("AUXPDM1 Rate", cs48l32_auxpdm1_freq),
2698SOC_ENUM("AUXPDM2 Rate", cs48l32_auxpdm2_freq),
2699
2700SOC_ENUM_EXT("IN1L Rate", cs48l32_input_rate[0], snd_soc_get_enum_double, cs48l32_in_rate_put),
2701SOC_ENUM_EXT("IN1R Rate", cs48l32_input_rate[1], snd_soc_get_enum_double, cs48l32_in_rate_put),
2702SOC_ENUM_EXT("IN2L Rate", cs48l32_input_rate[2], snd_soc_get_enum_double, cs48l32_in_rate_put),
2703SOC_ENUM_EXT("IN2R Rate", cs48l32_input_rate[3], snd_soc_get_enum_double, cs48l32_in_rate_put),
2704
2705CS48L32_RATE_ENUM("Noise Generator Rate", noise_gen_rate),
2706
2707SOC_SINGLE_TLV("Noise Generator Volume", CS48L32_COMFORT_NOISE_GENERATOR,
2708	       CS48L32_NOISE_GEN_GAIN_SHIFT, 0x12, 0, cs48l32_noise_tlv),
2709
2710CS48L32_MIXER_CONTROLS("ASP1TX1", CS48L32_ASP1TX1_INPUT1),
2711CS48L32_MIXER_CONTROLS("ASP1TX2", CS48L32_ASP1TX2_INPUT1),
2712CS48L32_MIXER_CONTROLS("ASP1TX3", CS48L32_ASP1TX3_INPUT1),
2713CS48L32_MIXER_CONTROLS("ASP1TX4", CS48L32_ASP1TX4_INPUT1),
2714CS48L32_MIXER_CONTROLS("ASP1TX5", CS48L32_ASP1TX5_INPUT1),
2715CS48L32_MIXER_CONTROLS("ASP1TX6", CS48L32_ASP1TX6_INPUT1),
2716CS48L32_MIXER_CONTROLS("ASP1TX7", CS48L32_ASP1TX7_INPUT1),
2717CS48L32_MIXER_CONTROLS("ASP1TX8", CS48L32_ASP1TX8_INPUT1),
2718
2719CS48L32_MIXER_CONTROLS("ASP2TX1", CS48L32_ASP2TX1_INPUT1),
2720CS48L32_MIXER_CONTROLS("ASP2TX2", CS48L32_ASP2TX2_INPUT1),
2721CS48L32_MIXER_CONTROLS("ASP2TX3", CS48L32_ASP2TX3_INPUT1),
2722CS48L32_MIXER_CONTROLS("ASP2TX4", CS48L32_ASP2TX4_INPUT1),
2723
2724WM_ADSP2_PRELOAD_SWITCH("DSP1", 1),
2725
2726CS48L32_MIXER_CONTROLS("DSP1RX1", CS48L32_DSP1RX1_INPUT1),
2727CS48L32_MIXER_CONTROLS("DSP1RX2", CS48L32_DSP1RX2_INPUT1),
2728CS48L32_MIXER_CONTROLS("DSP1RX3", CS48L32_DSP1RX3_INPUT1),
2729CS48L32_MIXER_CONTROLS("DSP1RX4", CS48L32_DSP1RX4_INPUT1),
2730CS48L32_MIXER_CONTROLS("DSP1RX5", CS48L32_DSP1RX5_INPUT1),
2731CS48L32_MIXER_CONTROLS("DSP1RX6", CS48L32_DSP1RX6_INPUT1),
2732CS48L32_MIXER_CONTROLS("DSP1RX7", CS48L32_DSP1RX7_INPUT1),
2733CS48L32_MIXER_CONTROLS("DSP1RX8", CS48L32_DSP1RX8_INPUT1),
2734
2735WM_ADSP_FW_CONTROL("DSP1", 0),
2736
2737CS48L32_DSP_RATE_CONTROL("DSP1RX1", 0),
2738CS48L32_DSP_RATE_CONTROL("DSP1RX2", 1),
2739CS48L32_DSP_RATE_CONTROL("DSP1RX3", 2),
2740CS48L32_DSP_RATE_CONTROL("DSP1RX4", 3),
2741CS48L32_DSP_RATE_CONTROL("DSP1RX5", 4),
2742CS48L32_DSP_RATE_CONTROL("DSP1RX6", 5),
2743CS48L32_DSP_RATE_CONTROL("DSP1RX7", 6),
2744CS48L32_DSP_RATE_CONTROL("DSP1RX8", 7),
2745CS48L32_DSP_RATE_CONTROL("DSP1TX1", 8),
2746CS48L32_DSP_RATE_CONTROL("DSP1TX2", 9),
2747CS48L32_DSP_RATE_CONTROL("DSP1TX3", 10),
2748CS48L32_DSP_RATE_CONTROL("DSP1TX4", 11),
2749CS48L32_DSP_RATE_CONTROL("DSP1TX5", 12),
2750CS48L32_DSP_RATE_CONTROL("DSP1TX6", 13),
2751CS48L32_DSP_RATE_CONTROL("DSP1TX7", 14),
2752CS48L32_DSP_RATE_CONTROL("DSP1TX8", 15),
2753};
2754
2755CS48L32_MIXER_ENUMS(EQ1, CS48L32_EQ1_INPUT1);
2756CS48L32_MIXER_ENUMS(EQ2, CS48L32_EQ2_INPUT1);
2757CS48L32_MIXER_ENUMS(EQ3, CS48L32_EQ3_INPUT1);
2758CS48L32_MIXER_ENUMS(EQ4, CS48L32_EQ4_INPUT1);
2759
2760CS48L32_MIXER_ENUMS(DRC1L, CS48L32_DRC1L_INPUT1);
2761CS48L32_MIXER_ENUMS(DRC1R, CS48L32_DRC1R_INPUT1);
2762CS48L32_MIXER_ENUMS(DRC2L, CS48L32_DRC2L_INPUT1);
2763CS48L32_MIXER_ENUMS(DRC2R, CS48L32_DRC2R_INPUT1);
2764
2765CS48L32_MIXER_ENUMS(LHPF1, CS48L32_LHPF1_INPUT1);
2766CS48L32_MIXER_ENUMS(LHPF2, CS48L32_LHPF2_INPUT1);
2767CS48L32_MIXER_ENUMS(LHPF3, CS48L32_LHPF3_INPUT1);
2768CS48L32_MIXER_ENUMS(LHPF4, CS48L32_LHPF4_INPUT1);
2769
2770CS48L32_MIXER_ENUMS(ASP1TX1, CS48L32_ASP1TX1_INPUT1);
2771CS48L32_MIXER_ENUMS(ASP1TX2, CS48L32_ASP1TX2_INPUT1);
2772CS48L32_MIXER_ENUMS(ASP1TX3, CS48L32_ASP1TX3_INPUT1);
2773CS48L32_MIXER_ENUMS(ASP1TX4, CS48L32_ASP1TX4_INPUT1);
2774CS48L32_MIXER_ENUMS(ASP1TX5, CS48L32_ASP1TX5_INPUT1);
2775CS48L32_MIXER_ENUMS(ASP1TX6, CS48L32_ASP1TX6_INPUT1);
2776CS48L32_MIXER_ENUMS(ASP1TX7, CS48L32_ASP1TX7_INPUT1);
2777CS48L32_MIXER_ENUMS(ASP1TX8, CS48L32_ASP1TX8_INPUT1);
2778
2779CS48L32_MIXER_ENUMS(ASP2TX1, CS48L32_ASP2TX1_INPUT1);
2780CS48L32_MIXER_ENUMS(ASP2TX2, CS48L32_ASP2TX2_INPUT1);
2781CS48L32_MIXER_ENUMS(ASP2TX3, CS48L32_ASP2TX3_INPUT1);
2782CS48L32_MIXER_ENUMS(ASP2TX4, CS48L32_ASP2TX4_INPUT1);
2783
2784CS48L32_MUX_ENUMS(ISRC1INT1, CS48L32_ISRC1INT1_INPUT1);
2785CS48L32_MUX_ENUMS(ISRC1INT2, CS48L32_ISRC1INT2_INPUT1);
2786CS48L32_MUX_ENUMS(ISRC1INT3, CS48L32_ISRC1INT3_INPUT1);
2787CS48L32_MUX_ENUMS(ISRC1INT4, CS48L32_ISRC1INT4_INPUT1);
2788
2789CS48L32_MUX_ENUMS(ISRC1DEC1, CS48L32_ISRC1DEC1_INPUT1);
2790CS48L32_MUX_ENUMS(ISRC1DEC2, CS48L32_ISRC1DEC2_INPUT1);
2791CS48L32_MUX_ENUMS(ISRC1DEC3, CS48L32_ISRC1DEC3_INPUT1);
2792CS48L32_MUX_ENUMS(ISRC1DEC4, CS48L32_ISRC1DEC4_INPUT1);
2793
2794CS48L32_MUX_ENUMS(ISRC2INT1, CS48L32_ISRC2INT1_INPUT1);
2795CS48L32_MUX_ENUMS(ISRC2INT2, CS48L32_ISRC2INT2_INPUT1);
2796
2797CS48L32_MUX_ENUMS(ISRC2DEC1, CS48L32_ISRC2DEC1_INPUT1);
2798CS48L32_MUX_ENUMS(ISRC2DEC2, CS48L32_ISRC2DEC2_INPUT1);
2799
2800CS48L32_MUX_ENUMS(ISRC3INT1, CS48L32_ISRC3INT1_INPUT1);
2801CS48L32_MUX_ENUMS(ISRC3INT2, CS48L32_ISRC3INT2_INPUT1);
2802
2803CS48L32_MUX_ENUMS(ISRC3DEC1, CS48L32_ISRC3DEC1_INPUT1);
2804CS48L32_MUX_ENUMS(ISRC3DEC2, CS48L32_ISRC3DEC2_INPUT1);
2805
2806CS48L32_MIXER_ENUMS(DSP1RX1, CS48L32_DSP1RX1_INPUT1);
2807CS48L32_MIXER_ENUMS(DSP1RX2, CS48L32_DSP1RX2_INPUT1);
2808CS48L32_MIXER_ENUMS(DSP1RX3, CS48L32_DSP1RX3_INPUT1);
2809CS48L32_MIXER_ENUMS(DSP1RX4, CS48L32_DSP1RX4_INPUT1);
2810CS48L32_MIXER_ENUMS(DSP1RX5, CS48L32_DSP1RX5_INPUT1);
2811CS48L32_MIXER_ENUMS(DSP1RX6, CS48L32_DSP1RX6_INPUT1);
2812CS48L32_MIXER_ENUMS(DSP1RX7, CS48L32_DSP1RX7_INPUT1);
2813CS48L32_MIXER_ENUMS(DSP1RX8, CS48L32_DSP1RX8_INPUT1);
2814
2815static int cs48l32_dsp_mem_ev(struct snd_soc_dapm_widget *w,
2816			      struct snd_kcontrol *kcontrol, int event)
2817{
2818	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
2819	struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
2820
2821	switch (event) {
2822	case SND_SOC_DAPM_POST_PMU:
2823		return cs48l32_dsp_memory_enable(cs48l32_codec, &cs48l32_dsp_sram_regs);
2824	case SND_SOC_DAPM_PRE_PMD:
2825		cs48l32_dsp_memory_disable(cs48l32_codec, &cs48l32_dsp_sram_regs);
2826		return 0;
2827	default:
2828		return 0;
2829	}
2830}
2831
2832static const struct snd_soc_dapm_widget cs48l32_dapm_widgets[] = {
2833SND_SOC_DAPM_SUPPLY("SYSCLK", CS48L32_SYSTEM_CLOCK1, CS48L32_SYSCLK_EN_SHIFT, 0,
2834		    cs48l32_sysclk_ev, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
2835
2836SND_SOC_DAPM_REGULATOR_SUPPLY("vdd-cp", 20, 0),
2837
2838SND_SOC_DAPM_SUPPLY("VOUT_MIC", CS48L32_CHARGE_PUMP1, CS48L32_CP2_EN_SHIFT, 0, NULL, 0),
2839SND_SOC_DAPM_SUPPLY("VOUT_MIC_REGULATED", CS48L32_CHARGE_PUMP1, CS48L32_CP2_BYPASS_SHIFT,
2840		    1, NULL, 0),
2841SND_SOC_DAPM_SUPPLY("MICBIAS1", CS48L32_MICBIAS_CTRL1, CS48L32_MICB1_EN_SHIFT, 0, NULL, 0),
2842SND_SOC_DAPM_SUPPLY("MICBIAS1A", CS48L32_MICBIAS_CTRL5, CS48L32_MICB1A_EN_SHIFT, 0, NULL, 0),
2843SND_SOC_DAPM_SUPPLY("MICBIAS1B", CS48L32_MICBIAS_CTRL5, CS48L32_MICB1B_EN_SHIFT, 0, NULL, 0),
2844SND_SOC_DAPM_SUPPLY("MICBIAS1C", CS48L32_MICBIAS_CTRL5, CS48L32_MICB1C_EN_SHIFT, 0, NULL, 0),
2845
2846SND_SOC_DAPM_SUPPLY("DSP1MEM", SND_SOC_NOPM, 0, 0, cs48l32_dsp_mem_ev,
2847		    SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
2848
2849CS48L32_DSP_FREQ_WIDGET_EV("DSP1", 0, cs48l32_dsp_freq_ev),
2850
2851SND_SOC_DAPM_SIGGEN("TONE"),
2852SND_SOC_DAPM_SIGGEN("NOISE"),
2853
2854SND_SOC_DAPM_INPUT("IN1LN_1"),
2855SND_SOC_DAPM_INPUT("IN1LN_2"),
2856SND_SOC_DAPM_INPUT("IN1LP_1"),
2857SND_SOC_DAPM_INPUT("IN1LP_2"),
2858SND_SOC_DAPM_INPUT("IN1RN_1"),
2859SND_SOC_DAPM_INPUT("IN1RN_2"),
2860SND_SOC_DAPM_INPUT("IN1RP_1"),
2861SND_SOC_DAPM_INPUT("IN1RP_2"),
2862SND_SOC_DAPM_INPUT("IN1_PDMCLK"),
2863SND_SOC_DAPM_INPUT("IN1_PDMDATA"),
2864
2865SND_SOC_DAPM_INPUT("IN2_PDMCLK"),
2866SND_SOC_DAPM_INPUT("IN2_PDMDATA"),
2867
2868SND_SOC_DAPM_MUX("Ultrasonic 1 Input", SND_SOC_NOPM, 0, 0, &cs48l32_us_inmux[0]),
2869SND_SOC_DAPM_MUX("Ultrasonic 2 Input", SND_SOC_NOPM, 0, 0, &cs48l32_us_inmux[1]),
2870
2871SND_SOC_DAPM_OUTPUT("DRC1 Signal Activity"),
2872SND_SOC_DAPM_OUTPUT("DRC2 Signal Activity"),
2873
2874SND_SOC_DAPM_OUTPUT("DSP Trigger Out"),
2875
2876SND_SOC_DAPM_MUX("IN1L Mux", SND_SOC_NOPM, 0, 0, &cs48l32_inmux[0]),
2877SND_SOC_DAPM_MUX("IN1R Mux", SND_SOC_NOPM, 0, 0, &cs48l32_inmux[1]),
2878
2879SND_SOC_DAPM_MUX("IN1L Mode", SND_SOC_NOPM, 0, 0, &cs48l32_dmode_mux[0]),
2880SND_SOC_DAPM_MUX("IN1R Mode", SND_SOC_NOPM, 0, 0, &cs48l32_dmode_mux[0]),
2881
2882SND_SOC_DAPM_AIF_OUT("ASP1TX1", NULL, 0, CS48L32_ASP1_ENABLES1, 0, 0),
2883SND_SOC_DAPM_AIF_OUT("ASP1TX2", NULL, 1, CS48L32_ASP1_ENABLES1, 1, 0),
2884SND_SOC_DAPM_AIF_OUT("ASP1TX3", NULL, 2, CS48L32_ASP1_ENABLES1, 2, 0),
2885SND_SOC_DAPM_AIF_OUT("ASP1TX4", NULL, 3, CS48L32_ASP1_ENABLES1, 3, 0),
2886SND_SOC_DAPM_AIF_OUT("ASP1TX5", NULL, 4, CS48L32_ASP1_ENABLES1, 4, 0),
2887SND_SOC_DAPM_AIF_OUT("ASP1TX6", NULL, 5, CS48L32_ASP1_ENABLES1, 5, 0),
2888SND_SOC_DAPM_AIF_OUT("ASP1TX7", NULL, 6, CS48L32_ASP1_ENABLES1, 6, 0),
2889SND_SOC_DAPM_AIF_OUT("ASP1TX8", NULL, 7, CS48L32_ASP1_ENABLES1, 7, 0),
2890
2891SND_SOC_DAPM_AIF_OUT("ASP2TX1", NULL, 0, CS48L32_ASP2_ENABLES1, 0, 0),
2892SND_SOC_DAPM_AIF_OUT("ASP2TX2", NULL, 1, CS48L32_ASP2_ENABLES1, 1, 0),
2893SND_SOC_DAPM_AIF_OUT("ASP2TX3", NULL, 2, CS48L32_ASP2_ENABLES1, 2, 0),
2894SND_SOC_DAPM_AIF_OUT("ASP2TX4", NULL, 3, CS48L32_ASP2_ENABLES1, 3, 0),
2895
2896SND_SOC_DAPM_SWITCH("AUXPDM1 Output", CS48L32_AUXPDM_CONTROL1, 0, 0, &cs48l32_auxpdm_switch[0]),
2897SND_SOC_DAPM_SWITCH("AUXPDM2 Output", CS48L32_AUXPDM_CONTROL1, 1, 0, &cs48l32_auxpdm_switch[1]),
2898
2899SND_SOC_DAPM_MUX("AUXPDM1 Input", SND_SOC_NOPM, 0, 0, &cs48l32_auxpdm_inmux[0]),
2900SND_SOC_DAPM_MUX("AUXPDM2 Input", SND_SOC_NOPM, 0, 0, &cs48l32_auxpdm_inmux[1]),
2901
2902SND_SOC_DAPM_MUX("AUXPDM1 Analog Input", SND_SOC_NOPM, 0, 0,
2903		 &cs48l32_auxpdm_analog_inmux[0]),
2904SND_SOC_DAPM_MUX("AUXPDM2 Analog Input", SND_SOC_NOPM, 0, 0,
2905		 &cs48l32_auxpdm_analog_inmux[1]),
2906
2907SND_SOC_DAPM_SWITCH("Ultrasonic 1 Detect", CS48L32_US_CONTROL,
2908		    CS48L32_US1_DET_EN_SHIFT, 0, &cs48l32_us_switch[0]),
2909SND_SOC_DAPM_SWITCH("Ultrasonic 2 Detect", CS48L32_US_CONTROL,
2910		    CS48L32_US1_DET_EN_SHIFT, 0, &cs48l32_us_switch[1]),
2911
2912/*
2913 * mux_in widgets : arranged in the order of sources
2914 * specified in CS48L32_MIXER_INPUT_ROUTES
2915 */
2916SND_SOC_DAPM_PGA("Tone Generator 1", CS48L32_TONE_GENERATOR1, 0, 0, NULL, 0),
2917SND_SOC_DAPM_PGA("Tone Generator 2", CS48L32_TONE_GENERATOR1, 1, 0, NULL, 0),
2918
2919SND_SOC_DAPM_PGA("Noise Generator", CS48L32_COMFORT_NOISE_GENERATOR,
2920		 CS48L32_NOISE_GEN_EN_SHIFT, 0, NULL, 0),
2921
2922SND_SOC_DAPM_PGA_E("IN1L PGA", CS48L32_INPUT_CONTROL, CS48L32_IN1L_EN_SHIFT,
2923		   0, NULL, 0, cs48l32_in_ev,
2924		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
2925SND_SOC_DAPM_PGA_E("IN1R PGA", CS48L32_INPUT_CONTROL, CS48L32_IN1R_EN_SHIFT,
2926		   0, NULL, 0, cs48l32_in_ev,
2927		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
2928SND_SOC_DAPM_PGA_E("IN2L PGA", CS48L32_INPUT_CONTROL, CS48L32_IN2L_EN_SHIFT,
2929		   0, NULL, 0, cs48l32_in_ev,
2930		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
2931SND_SOC_DAPM_PGA_E("IN2R PGA", CS48L32_INPUT_CONTROL, CS48L32_IN2R_EN_SHIFT,
2932		   0, NULL, 0, cs48l32_in_ev,
2933		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
2934
2935SND_SOC_DAPM_AIF_IN("ASP1RX1", NULL, 0, CS48L32_ASP1_ENABLES1, 16, 0),
2936SND_SOC_DAPM_AIF_IN("ASP1RX2", NULL, 1, CS48L32_ASP1_ENABLES1, 17, 0),
2937SND_SOC_DAPM_AIF_IN("ASP1RX3", NULL, 2, CS48L32_ASP1_ENABLES1, 18, 0),
2938SND_SOC_DAPM_AIF_IN("ASP1RX4", NULL, 3, CS48L32_ASP1_ENABLES1, 19, 0),
2939SND_SOC_DAPM_AIF_IN("ASP1RX5", NULL, 4, CS48L32_ASP1_ENABLES1, 20, 0),
2940SND_SOC_DAPM_AIF_IN("ASP1RX6", NULL, 5, CS48L32_ASP1_ENABLES1, 21, 0),
2941SND_SOC_DAPM_AIF_IN("ASP1RX7", NULL, 6, CS48L32_ASP1_ENABLES1, 22, 0),
2942SND_SOC_DAPM_AIF_IN("ASP1RX8", NULL, 7, CS48L32_ASP1_ENABLES1, 23, 0),
2943
2944SND_SOC_DAPM_AIF_IN("ASP2RX1", NULL, 0, CS48L32_ASP2_ENABLES1, 16, 0),
2945SND_SOC_DAPM_AIF_IN("ASP2RX2", NULL, 1, CS48L32_ASP2_ENABLES1, 17, 0),
2946SND_SOC_DAPM_AIF_IN("ASP2RX3", NULL, 2, CS48L32_ASP2_ENABLES1, 18, 0),
2947SND_SOC_DAPM_AIF_IN("ASP2RX4", NULL, 3, CS48L32_ASP2_ENABLES1, 19, 0),
2948
2949SND_SOC_DAPM_PGA("ISRC1DEC1", CS48L32_ISRC1_CONTROL2, CS48L32_ISRC1_DEC1_EN_SHIFT, 0, NULL, 0),
2950SND_SOC_DAPM_PGA("ISRC1DEC2", CS48L32_ISRC1_CONTROL2, CS48L32_ISRC1_DEC2_EN_SHIFT, 0, NULL, 0),
2951SND_SOC_DAPM_PGA("ISRC1DEC3", CS48L32_ISRC1_CONTROL2, CS48L32_ISRC1_DEC3_EN_SHIFT, 0, NULL, 0),
2952SND_SOC_DAPM_PGA("ISRC1DEC4", CS48L32_ISRC1_CONTROL2, CS48L32_ISRC1_DEC4_EN_SHIFT, 0, NULL, 0),
2953
2954SND_SOC_DAPM_PGA("ISRC1INT1", CS48L32_ISRC1_CONTROL2, CS48L32_ISRC1_INT1_EN_SHIFT, 0, NULL, 0),
2955SND_SOC_DAPM_PGA("ISRC1INT2", CS48L32_ISRC1_CONTROL2, CS48L32_ISRC1_INT2_EN_SHIFT, 0, NULL, 0),
2956SND_SOC_DAPM_PGA("ISRC1INT3", CS48L32_ISRC1_CONTROL2, CS48L32_ISRC1_INT3_EN_SHIFT, 0, NULL, 0),
2957SND_SOC_DAPM_PGA("ISRC1INT4", CS48L32_ISRC1_CONTROL2, CS48L32_ISRC1_INT4_EN_SHIFT, 0, NULL, 0),
2958
2959SND_SOC_DAPM_PGA("ISRC2DEC1", CS48L32_ISRC2_CONTROL2, CS48L32_ISRC1_DEC1_EN_SHIFT, 0, NULL, 0),
2960SND_SOC_DAPM_PGA("ISRC2DEC2", CS48L32_ISRC2_CONTROL2, CS48L32_ISRC1_DEC2_EN_SHIFT, 0, NULL, 0),
2961
2962SND_SOC_DAPM_PGA("ISRC2INT1", CS48L32_ISRC2_CONTROL2, CS48L32_ISRC1_INT1_EN_SHIFT, 0, NULL, 0),
2963SND_SOC_DAPM_PGA("ISRC2INT2", CS48L32_ISRC2_CONTROL2, CS48L32_ISRC1_INT2_EN_SHIFT, 0, NULL, 0),
2964
2965SND_SOC_DAPM_PGA("ISRC3DEC1", CS48L32_ISRC3_CONTROL2, CS48L32_ISRC1_DEC1_EN_SHIFT, 0, NULL, 0),
2966SND_SOC_DAPM_PGA("ISRC3DEC2", CS48L32_ISRC3_CONTROL2, CS48L32_ISRC1_DEC2_EN_SHIFT, 0, NULL, 0),
2967
2968SND_SOC_DAPM_PGA("ISRC3INT1", CS48L32_ISRC3_CONTROL2, CS48L32_ISRC1_INT1_EN_SHIFT, 0, NULL, 0),
2969SND_SOC_DAPM_PGA("ISRC3INT2", CS48L32_ISRC3_CONTROL2, CS48L32_ISRC1_INT2_EN_SHIFT, 0, NULL, 0),
2970
2971SND_SOC_DAPM_PGA_E("EQ1", CS48L32_EQ_CONTROL1, 0, 0, NULL, 0, cs48l32_eq_ev, SND_SOC_DAPM_PRE_PMU),
2972SND_SOC_DAPM_PGA_E("EQ2", CS48L32_EQ_CONTROL1, 1, 0, NULL, 0, cs48l32_eq_ev, SND_SOC_DAPM_PRE_PMU),
2973SND_SOC_DAPM_PGA_E("EQ3", CS48L32_EQ_CONTROL1, 2, 0, NULL, 0, cs48l32_eq_ev, SND_SOC_DAPM_PRE_PMU),
2974SND_SOC_DAPM_PGA_E("EQ4", CS48L32_EQ_CONTROL1, 3, 0, NULL, 0, cs48l32_eq_ev, SND_SOC_DAPM_PRE_PMU),
2975
2976SND_SOC_DAPM_PGA("DRC1L", CS48L32_DRC1_CONTROL1, CS48L32_DRC1L_EN_SHIFT, 0, NULL, 0),
2977SND_SOC_DAPM_PGA("DRC1R", CS48L32_DRC1_CONTROL1, CS48L32_DRC1R_EN_SHIFT, 0, NULL, 0),
2978SND_SOC_DAPM_PGA("DRC2L", CS48L32_DRC2_CONTROL1, CS48L32_DRC1L_EN_SHIFT, 0, NULL, 0),
2979SND_SOC_DAPM_PGA("DRC2R", CS48L32_DRC2_CONTROL1, CS48L32_DRC1R_EN_SHIFT, 0, NULL, 0),
2980
2981SND_SOC_DAPM_PGA("LHPF1", CS48L32_LHPF_CONTROL1, 0, 0, NULL, 0),
2982SND_SOC_DAPM_PGA("LHPF2", CS48L32_LHPF_CONTROL1, 1, 0, NULL, 0),
2983SND_SOC_DAPM_PGA("LHPF3", CS48L32_LHPF_CONTROL1, 2, 0, NULL, 0),
2984SND_SOC_DAPM_PGA("LHPF4", CS48L32_LHPF_CONTROL1, 3, 0, NULL, 0),
2985
2986SND_SOC_DAPM_PGA("Ultrasonic 1", CS48L32_US_CONTROL, 0, 0, NULL, 0),
2987SND_SOC_DAPM_PGA("Ultrasonic 2", CS48L32_US_CONTROL, 1, 0, NULL, 0),
2988
2989WM_ADSP2("DSP1", 0, wm_adsp_early_event),
2990
2991/* end of ordered widget list */
2992
2993CS48L32_MIXER_WIDGETS(EQ1, "EQ1"),
2994CS48L32_MIXER_WIDGETS(EQ2, "EQ2"),
2995CS48L32_MIXER_WIDGETS(EQ3, "EQ3"),
2996CS48L32_MIXER_WIDGETS(EQ4, "EQ4"),
2997
2998CS48L32_MIXER_WIDGETS(DRC1L, "DRC1L"),
2999CS48L32_MIXER_WIDGETS(DRC1R, "DRC1R"),
3000CS48L32_MIXER_WIDGETS(DRC2L, "DRC2L"),
3001CS48L32_MIXER_WIDGETS(DRC2R, "DRC2R"),
3002
3003SND_SOC_DAPM_SWITCH("DRC1 Activity Output", SND_SOC_NOPM, 0, 0,
3004		    &cs48l32_drc_activity_output_mux[0]),
3005SND_SOC_DAPM_SWITCH("DRC2 Activity Output", SND_SOC_NOPM, 0, 0,
3006		    &cs48l32_drc_activity_output_mux[1]),
3007
3008CS48L32_MIXER_WIDGETS(LHPF1, "LHPF1"),
3009CS48L32_MIXER_WIDGETS(LHPF2, "LHPF2"),
3010CS48L32_MIXER_WIDGETS(LHPF3, "LHPF3"),
3011CS48L32_MIXER_WIDGETS(LHPF4, "LHPF4"),
3012
3013CS48L32_MIXER_WIDGETS(ASP1TX1, "ASP1TX1"),
3014CS48L32_MIXER_WIDGETS(ASP1TX2, "ASP1TX2"),
3015CS48L32_MIXER_WIDGETS(ASP1TX3, "ASP1TX3"),
3016CS48L32_MIXER_WIDGETS(ASP1TX4, "ASP1TX4"),
3017CS48L32_MIXER_WIDGETS(ASP1TX5, "ASP1TX5"),
3018CS48L32_MIXER_WIDGETS(ASP1TX6, "ASP1TX6"),
3019CS48L32_MIXER_WIDGETS(ASP1TX7, "ASP1TX7"),
3020CS48L32_MIXER_WIDGETS(ASP1TX8, "ASP1TX8"),
3021
3022CS48L32_MIXER_WIDGETS(ASP2TX1, "ASP2TX1"),
3023CS48L32_MIXER_WIDGETS(ASP2TX2, "ASP2TX2"),
3024CS48L32_MIXER_WIDGETS(ASP2TX3, "ASP2TX3"),
3025CS48L32_MIXER_WIDGETS(ASP2TX4, "ASP2TX4"),
3026
3027CS48L32_MUX_WIDGETS(ISRC1DEC1, "ISRC1DEC1"),
3028CS48L32_MUX_WIDGETS(ISRC1DEC2, "ISRC1DEC2"),
3029CS48L32_MUX_WIDGETS(ISRC1DEC3, "ISRC1DEC3"),
3030CS48L32_MUX_WIDGETS(ISRC1DEC4, "ISRC1DEC4"),
3031
3032CS48L32_MUX_WIDGETS(ISRC1INT1, "ISRC1INT1"),
3033CS48L32_MUX_WIDGETS(ISRC1INT2, "ISRC1INT2"),
3034CS48L32_MUX_WIDGETS(ISRC1INT3, "ISRC1INT3"),
3035CS48L32_MUX_WIDGETS(ISRC1INT4, "ISRC1INT4"),
3036
3037CS48L32_MUX_WIDGETS(ISRC2DEC1, "ISRC2DEC1"),
3038CS48L32_MUX_WIDGETS(ISRC2DEC2, "ISRC2DEC2"),
3039
3040CS48L32_MUX_WIDGETS(ISRC2INT1, "ISRC2INT1"),
3041CS48L32_MUX_WIDGETS(ISRC2INT2, "ISRC2INT2"),
3042
3043CS48L32_MUX_WIDGETS(ISRC3DEC1, "ISRC3DEC1"),
3044CS48L32_MUX_WIDGETS(ISRC3DEC2, "ISRC3DEC2"),
3045
3046CS48L32_MUX_WIDGETS(ISRC3INT1, "ISRC3INT1"),
3047CS48L32_MUX_WIDGETS(ISRC3INT2, "ISRC3INT2"),
3048
3049CS48L32_MIXER_WIDGETS(DSP1RX1, "DSP1RX1"),
3050CS48L32_MIXER_WIDGETS(DSP1RX2, "DSP1RX2"),
3051CS48L32_MIXER_WIDGETS(DSP1RX3, "DSP1RX3"),
3052CS48L32_MIXER_WIDGETS(DSP1RX4, "DSP1RX4"),
3053CS48L32_MIXER_WIDGETS(DSP1RX5, "DSP1RX5"),
3054CS48L32_MIXER_WIDGETS(DSP1RX6, "DSP1RX6"),
3055CS48L32_MIXER_WIDGETS(DSP1RX7, "DSP1RX7"),
3056CS48L32_MIXER_WIDGETS(DSP1RX8, "DSP1RX8"),
3057
3058SND_SOC_DAPM_SWITCH("DSP1 Trigger Output", SND_SOC_NOPM, 0, 0,
3059		    &cs48l32_dsp_trigger_output_mux[0]),
3060
3061SND_SOC_DAPM_OUTPUT("AUXPDM1_CLK"),
3062SND_SOC_DAPM_OUTPUT("AUXPDM1_DOUT"),
3063SND_SOC_DAPM_OUTPUT("AUXPDM2_CLK"),
3064SND_SOC_DAPM_OUTPUT("AUXPDM2_DOUT"),
3065
3066SND_SOC_DAPM_OUTPUT("MICSUPP"),
3067
3068SND_SOC_DAPM_OUTPUT("Ultrasonic Dummy Output"),
3069};
3070
3071static const struct snd_soc_dapm_route cs48l32_dapm_routes[] = {
3072	{ "IN1LN_1", NULL, "SYSCLK" },
3073	{ "IN1LN_2", NULL, "SYSCLK" },
3074	{ "IN1LP_1", NULL, "SYSCLK" },
3075	{ "IN1LP_2", NULL, "SYSCLK" },
3076	{ "IN1RN_1", NULL, "SYSCLK" },
3077	{ "IN1RN_2", NULL, "SYSCLK" },
3078	{ "IN1RP_1", NULL, "SYSCLK" },
3079	{ "IN1RP_2", NULL, "SYSCLK" },
3080
3081	{ "IN1_PDMCLK", NULL, "SYSCLK" },
3082	{ "IN1_PDMDATA", NULL, "SYSCLK" },
3083	{ "IN2_PDMCLK", NULL, "SYSCLK" },
3084	{ "IN2_PDMDATA", NULL, "SYSCLK" },
3085
3086	{ "DSP1 Preloader", NULL, "DSP1MEM" },
3087	{ "DSP1", NULL, "DSP1FREQ" },
3088
3089	{ "Audio Trace DSP", NULL, "DSP1" },
3090	{ "Voice Ctrl DSP", NULL, "DSP1" },
3091
3092	{ "VOUT_MIC_REGULATED", NULL, "VOUT_MIC" },
3093	{ "MICBIAS1", NULL, "VOUT_MIC_REGULATED" },
3094	{ "MICBIAS1A", NULL, "MICBIAS1" },
3095	{ "MICBIAS1B", NULL, "MICBIAS1" },
3096	{ "MICBIAS1C", NULL, "MICBIAS1" },
3097
3098	{ "Tone Generator 1", NULL, "SYSCLK" },
3099	{ "Tone Generator 2", NULL, "SYSCLK" },
3100	{ "Noise Generator", NULL, "SYSCLK" },
3101
3102	{ "Tone Generator 1", NULL, "TONE" },
3103	{ "Tone Generator 2", NULL, "TONE" },
3104	{ "Noise Generator", NULL, "NOISE" },
3105
3106	{ "ASP1 Capture", NULL, "ASP1TX1" },
3107	{ "ASP1 Capture", NULL, "ASP1TX2" },
3108	{ "ASP1 Capture", NULL, "ASP1TX3" },
3109	{ "ASP1 Capture", NULL, "ASP1TX4" },
3110	{ "ASP1 Capture", NULL, "ASP1TX5" },
3111	{ "ASP1 Capture", NULL, "ASP1TX6" },
3112	{ "ASP1 Capture", NULL, "ASP1TX7" },
3113	{ "ASP1 Capture", NULL, "ASP1TX8" },
3114
3115	{ "ASP1RX1", NULL, "ASP1 Playback" },
3116	{ "ASP1RX2", NULL, "ASP1 Playback" },
3117	{ "ASP1RX3", NULL, "ASP1 Playback" },
3118	{ "ASP1RX4", NULL, "ASP1 Playback" },
3119	{ "ASP1RX5", NULL, "ASP1 Playback" },
3120	{ "ASP1RX6", NULL, "ASP1 Playback" },
3121	{ "ASP1RX7", NULL, "ASP1 Playback" },
3122	{ "ASP1RX8", NULL, "ASP1 Playback" },
3123
3124	{ "ASP2 Capture", NULL, "ASP2TX1" },
3125	{ "ASP2 Capture", NULL, "ASP2TX2" },
3126	{ "ASP2 Capture", NULL, "ASP2TX3" },
3127	{ "ASP2 Capture", NULL, "ASP2TX4" },
3128
3129	{ "ASP2RX1", NULL, "ASP2 Playback" },
3130	{ "ASP2RX2", NULL, "ASP2 Playback" },
3131	{ "ASP2RX3", NULL, "ASP2 Playback" },
3132	{ "ASP2RX4", NULL, "ASP2 Playback" },
3133
3134	{ "ASP1 Playback", NULL, "SYSCLK" },
3135	{ "ASP2 Playback", NULL, "SYSCLK" },
3136
3137	{ "ASP1 Capture", NULL, "SYSCLK" },
3138	{ "ASP2 Capture", NULL, "SYSCLK" },
3139
3140	{ "IN1L Mux", "Analog 1", "IN1LN_1" },
3141	{ "IN1L Mux", "Analog 2", "IN1LN_2" },
3142	{ "IN1L Mux", "Analog 1", "IN1LP_1" },
3143	{ "IN1L Mux", "Analog 2", "IN1LP_2" },
3144	{ "IN1R Mux", "Analog 1", "IN1RN_1" },
3145	{ "IN1R Mux", "Analog 2", "IN1RN_2" },
3146	{ "IN1R Mux", "Analog 1", "IN1RP_1" },
3147	{ "IN1R Mux", "Analog 2", "IN1RP_2" },
3148
3149	{ "IN1L PGA", NULL, "IN1L Mode" },
3150	{ "IN1R PGA", NULL, "IN1R Mode" },
3151
3152	{ "IN1L Mode", "Analog", "IN1L Mux" },
3153	{ "IN1R Mode", "Analog", "IN1R Mux" },
3154
3155	{ "IN1L Mode", "Digital", "IN1_PDMCLK" },
3156	{ "IN1L Mode", "Digital", "IN1_PDMDATA" },
3157	{ "IN1R Mode", "Digital", "IN1_PDMCLK" },
3158	{ "IN1R Mode", "Digital", "IN1_PDMDATA" },
3159
3160	{ "IN1L PGA", NULL, "VOUT_MIC" },
3161	{ "IN1R PGA", NULL, "VOUT_MIC" },
3162
3163	{ "IN2L PGA", NULL, "VOUT_MIC" },
3164	{ "IN2R PGA", NULL, "VOUT_MIC" },
3165
3166	{ "IN2L PGA", NULL, "IN2_PDMCLK" },
3167	{ "IN2R PGA", NULL, "IN2_PDMCLK" },
3168	{ "IN2L PGA", NULL, "IN2_PDMDATA" },
3169	{ "IN2R PGA", NULL, "IN2_PDMDATA" },
3170
3171	{ "Ultrasonic 1", NULL, "Ultrasonic 1 Input" },
3172	{ "Ultrasonic 2", NULL, "Ultrasonic 2 Input" },
3173
3174	{ "Ultrasonic 1 Input", "IN1L", "IN1L PGA" },
3175	{ "Ultrasonic 1 Input", "IN1R", "IN1R PGA" },
3176	{ "Ultrasonic 1 Input", "IN2L", "IN2L PGA" },
3177	{ "Ultrasonic 1 Input", "IN2R", "IN2R PGA" },
3178
3179	{ "Ultrasonic 2 Input", "IN1L", "IN1L PGA" },
3180	{ "Ultrasonic 2 Input", "IN1R", "IN1R PGA" },
3181	{ "Ultrasonic 2 Input", "IN2L", "IN2L PGA" },
3182	{ "Ultrasonic 2 Input", "IN2R", "IN2R PGA" },
3183
3184	{ "Ultrasonic 1 Detect", "Switch", "Ultrasonic 1 Input" },
3185	{ "Ultrasonic 2 Detect", "Switch", "Ultrasonic 2 Input" },
3186
3187	{ "Ultrasonic Dummy Output", NULL, "Ultrasonic 1 Detect" },
3188	{ "Ultrasonic Dummy Output", NULL, "Ultrasonic 2 Detect" },
3189
3190	CS48L32_MIXER_ROUTES("ASP1TX1", "ASP1TX1"),
3191	CS48L32_MIXER_ROUTES("ASP1TX2", "ASP1TX2"),
3192	CS48L32_MIXER_ROUTES("ASP1TX3", "ASP1TX3"),
3193	CS48L32_MIXER_ROUTES("ASP1TX4", "ASP1TX4"),
3194	CS48L32_MIXER_ROUTES("ASP1TX5", "ASP1TX5"),
3195	CS48L32_MIXER_ROUTES("ASP1TX6", "ASP1TX6"),
3196	CS48L32_MIXER_ROUTES("ASP1TX7", "ASP1TX7"),
3197	CS48L32_MIXER_ROUTES("ASP1TX8", "ASP1TX8"),
3198
3199	CS48L32_MIXER_ROUTES("ASP2TX1", "ASP2TX1"),
3200	CS48L32_MIXER_ROUTES("ASP2TX2", "ASP2TX2"),
3201	CS48L32_MIXER_ROUTES("ASP2TX3", "ASP2TX3"),
3202	CS48L32_MIXER_ROUTES("ASP2TX4", "ASP2TX4"),
3203
3204	CS48L32_MIXER_ROUTES("EQ1", "EQ1"),
3205	CS48L32_MIXER_ROUTES("EQ2", "EQ2"),
3206	CS48L32_MIXER_ROUTES("EQ3", "EQ3"),
3207	CS48L32_MIXER_ROUTES("EQ4", "EQ4"),
3208
3209	CS48L32_MIXER_ROUTES("DRC1L", "DRC1L"),
3210	CS48L32_MIXER_ROUTES("DRC1R", "DRC1R"),
3211	CS48L32_MIXER_ROUTES("DRC2L", "DRC2L"),
3212	CS48L32_MIXER_ROUTES("DRC2R", "DRC2R"),
3213
3214	CS48L32_MIXER_ROUTES("LHPF1", "LHPF1"),
3215	CS48L32_MIXER_ROUTES("LHPF2", "LHPF2"),
3216	CS48L32_MIXER_ROUTES("LHPF3", "LHPF3"),
3217	CS48L32_MIXER_ROUTES("LHPF4", "LHPF4"),
3218
3219	CS48L32_MUX_ROUTES("ISRC1INT1", "ISRC1INT1"),
3220	CS48L32_MUX_ROUTES("ISRC1INT2", "ISRC1INT2"),
3221	CS48L32_MUX_ROUTES("ISRC1INT3", "ISRC1INT3"),
3222	CS48L32_MUX_ROUTES("ISRC1INT4", "ISRC1INT4"),
3223
3224	CS48L32_MUX_ROUTES("ISRC1DEC1", "ISRC1DEC1"),
3225	CS48L32_MUX_ROUTES("ISRC1DEC2", "ISRC1DEC2"),
3226	CS48L32_MUX_ROUTES("ISRC1DEC3", "ISRC1DEC3"),
3227	CS48L32_MUX_ROUTES("ISRC1DEC4", "ISRC1DEC4"),
3228
3229	CS48L32_MUX_ROUTES("ISRC2INT1", "ISRC2INT1"),
3230	CS48L32_MUX_ROUTES("ISRC2INT2", "ISRC2INT2"),
3231
3232	CS48L32_MUX_ROUTES("ISRC2DEC1", "ISRC2DEC1"),
3233	CS48L32_MUX_ROUTES("ISRC2DEC2", "ISRC2DEC2"),
3234
3235	CS48L32_MUX_ROUTES("ISRC3INT1", "ISRC3INT1"),
3236	CS48L32_MUX_ROUTES("ISRC3INT2", "ISRC3INT2"),
3237
3238	CS48L32_MUX_ROUTES("ISRC3DEC1", "ISRC3DEC1"),
3239	CS48L32_MUX_ROUTES("ISRC3DEC2", "ISRC3DEC2"),
3240
3241	CS48L32_DSP_ROUTES_1_8_SYSCLK("DSP1"),
3242
3243	{ "DSP Trigger Out", NULL, "DSP1 Trigger Output" },
3244
3245	{ "DSP1 Trigger Output", "Switch", "DSP1" },
3246
3247	{ "AUXPDM1 Analog Input", "IN1L", "IN1L PGA" },
3248	{ "AUXPDM1 Analog Input", "IN1R", "IN1R PGA" },
3249
3250	{ "AUXPDM2 Analog Input", "IN1L", "IN1L PGA" },
3251	{ "AUXPDM2 Analog Input", "IN1R", "IN1R PGA" },
3252
3253	{ "AUXPDM1 Input", "Analog", "AUXPDM1 Analog Input" },
3254	{ "AUXPDM1 Input", "IN1 Digital", "IN1L PGA" },
3255	{ "AUXPDM1 Input", "IN1 Digital", "IN1R PGA" },
3256	{ "AUXPDM1 Input", "IN2 Digital", "IN2L PGA" },
3257	{ "AUXPDM1 Input", "IN2 Digital", "IN2R PGA" },
3258
3259	{ "AUXPDM2 Input", "Analog", "AUXPDM2 Analog Input" },
3260	{ "AUXPDM2 Input", "IN1 Digital", "IN1L PGA" },
3261	{ "AUXPDM2 Input", "IN1 Digital", "IN1R PGA" },
3262	{ "AUXPDM2 Input", "IN2 Digital", "IN2L PGA" },
3263	{ "AUXPDM2 Input", "IN2 Digital", "IN2R PGA" },
3264
3265	{ "AUXPDM1 Output", "Switch", "AUXPDM1 Input" },
3266	{ "AUXPDM1_CLK", NULL, "AUXPDM1 Output" },
3267	{ "AUXPDM1_DOUT", NULL, "AUXPDM1 Output" },
3268
3269	{ "AUXPDM2 Output", "Switch", "AUXPDM2 Input" },
3270	{ "AUXPDM2_CLK", NULL, "AUXPDM2 Output" },
3271	{ "AUXPDM2_DOUT", NULL, "AUXPDM2 Output" },
3272
3273	{ "MICSUPP", NULL, "SYSCLK" },
3274
3275	{ "DRC1 Signal Activity", NULL, "DRC1 Activity Output" },
3276	{ "DRC2 Signal Activity", NULL, "DRC2 Activity Output" },
3277	{ "DRC1 Activity Output", "Switch", "DRC1L" },
3278	{ "DRC1 Activity Output", "Switch", "DRC1R" },
3279	{ "DRC2 Activity Output", "Switch", "DRC2L" },
3280	{ "DRC2 Activity Output", "Switch", "DRC2R" },
3281};
3282
3283static int cs48l32_compr_open(struct snd_soc_component *component,
3284			      struct snd_compr_stream *stream)
3285{
3286	struct snd_soc_pcm_runtime *rtd = stream->private_data;
3287	struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
3288
3289	if (strcmp(snd_soc_rtd_to_codec(rtd, 0)->name, "cs48l32-dsp-trace") &&
3290	    strcmp(snd_soc_rtd_to_codec(rtd, 0)->name, "cs48l32-dsp-voicectrl")) {
3291		dev_err(cs48l32_codec->core.dev, "No suitable compressed stream for DAI '%s'\n",
3292			snd_soc_rtd_to_codec(rtd, 0)->name);
3293		return -EINVAL;
3294	}
3295
3296	return wm_adsp_compr_open(&cs48l32_codec->dsp, stream);
3297}
3298
3299static const struct snd_compress_ops cs48l32_compress_ops = {
3300	.open = &cs48l32_compr_open,
3301	.free = &wm_adsp_compr_free,
3302	.set_params = &wm_adsp_compr_set_params,
3303	.get_caps = &wm_adsp_compr_get_caps,
3304	.trigger = &wm_adsp_compr_trigger,
3305	.pointer = &wm_adsp_compr_pointer,
3306	.copy = &wm_adsp_compr_copy,
3307};
3308
3309static const struct snd_soc_dai_ops cs48l32_compress_dai_ops = {
3310	.compress_new = snd_soc_new_compress,
3311};
3312
3313static struct snd_soc_dai_driver cs48l32_dai[] = {
3314	{
3315		.name = "cs48l32-asp1",
3316		.id = 1,
3317		.base = CS48L32_ASP1_ENABLES1,
3318		.playback = {
3319			.stream_name = "ASP1 Playback",
3320			.channels_min = 1,
3321			.channels_max = 8,
3322			.rates = CS48L32_RATES,
3323			.formats = CS48L32_FORMATS,
3324		},
3325		.capture = {
3326			.stream_name = "ASP1 Capture",
3327			.channels_min = 1,
3328			.channels_max = 8,
3329			.rates = CS48L32_RATES,
3330			.formats = CS48L32_FORMATS,
3331		 },
3332		.ops = &cs48l32_dai_ops,
3333		.symmetric_rate = 1,
3334		.symmetric_sample_bits = 1,
3335	},
3336	{
3337		.name = "cs48l32-asp2",
3338		.id = 2,
3339		.base = CS48L32_ASP2_ENABLES1,
3340		.playback = {
3341			.stream_name = "ASP2 Playback",
3342			.channels_min = 1,
3343			.channels_max = 4,
3344			.rates = CS48L32_RATES,
3345			.formats = CS48L32_FORMATS,
3346		},
3347		.capture = {
3348			.stream_name = "ASP2 Capture",
3349			.channels_min = 1,
3350			.channels_max = 4,
3351			.rates = CS48L32_RATES,
3352			.formats = CS48L32_FORMATS,
3353		 },
3354		.ops = &cs48l32_dai_ops,
3355		.symmetric_rate = 1,
3356		.symmetric_sample_bits = 1,
3357	},
3358	{
3359		.name = "cs48l32-cpu-trace",
3360		.id = 3,
3361		.capture = {
3362			.stream_name = "Audio Trace CPU",
3363			.channels_min = 1,
3364			.channels_max = 8,
3365			.rates = CS48L32_RATES,
3366			.formats = CS48L32_FORMATS,
3367		},
3368		.ops = &cs48l32_compress_dai_ops,
3369	},
3370	{
3371		.name = "cs48l32-dsp-trace",
3372		.id = 4,
3373		.capture = {
3374			.stream_name = "Audio Trace DSP",
3375			.channels_min = 1,
3376			.channels_max = 8,
3377			.rates = CS48L32_RATES,
3378			.formats = CS48L32_FORMATS,
3379		},
3380	},
3381	{
3382		.name = "cs48l32-cpu-voicectrl",
3383		.id = 5,
3384		.capture = {
3385			.stream_name = "Voice Ctrl CPU",
3386			.channels_min = 1,
3387			.channels_max = 8,
3388			.rates = CS48L32_RATES,
3389			.formats = CS48L32_FORMATS,
3390		},
3391		.ops = &cs48l32_compress_dai_ops,
3392	},
3393	{
3394		.name = "cs48l32-dsp-voicectrl",
3395		.id = 6,
3396		.capture = {
3397			.stream_name = "Voice Ctrl DSP",
3398			.channels_min = 1,
3399			.channels_max = 8,
3400			.rates = CS48L32_RATES,
3401			.formats = CS48L32_FORMATS,
3402		},
3403	},
3404};
3405
3406static int cs48l32_init_inputs(struct snd_soc_component *component)
3407{
3408	struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
3409	struct regmap *regmap = cs48l32_codec->core.regmap;
3410	unsigned int ana_mode_l, ana_mode_r, dig_mode;
3411	int i;
3412
3413	/*
3414	 * Initialize input modes from the A settings. For muxed inputs the
3415	 * B settings will be applied if the mux is changed
3416	 */
3417	switch (cs48l32_codec->in_type[0][0]) {
3418	default:
3419	case CS48L32_IN_TYPE_DIFF:
3420		ana_mode_l = 0;
3421		break;
3422	case CS48L32_IN_TYPE_SE:
3423		ana_mode_l = 1 << CS48L32_INx_SRC_SHIFT;
3424		break;
3425	}
3426
3427	switch (cs48l32_codec->in_type[1][0]) {
3428	default:
3429	case CS48L32_IN_TYPE_DIFF:
3430		ana_mode_r = 0;
3431		break;
3432	case CS48L32_IN_TYPE_SE:
3433		ana_mode_r = 1 << CS48L32_INx_SRC_SHIFT;
3434		break;
3435	}
3436
3437	dev_dbg(cs48l32_codec->core.dev, "IN1_1 Analogue mode=#%x,#%x\n",
3438		ana_mode_l, ana_mode_r);
3439
3440	regmap_update_bits(regmap,
3441			   CS48L32_IN1L_CONTROL1,
3442			   CS48L32_INx_SRC_MASK,
3443			   ana_mode_l);
3444
3445	regmap_update_bits(regmap,
3446			   CS48L32_IN1R_CONTROL1,
3447			   CS48L32_INx_SRC_MASK,
3448			   ana_mode_r);
3449
3450	for (i = 0; i < ARRAY_SIZE(cs48l32_codec->pdm_sup); i++) {
3451		dig_mode = cs48l32_codec->pdm_sup[i] << CS48L32_IN1_PDM_SUP_SHIFT;
3452
3453		dev_dbg(cs48l32_codec->core.dev, "IN%d PDM_SUP=#%x\n", i + 1, dig_mode);
3454
3455		regmap_update_bits(regmap,
3456				   CS48L32_INPUT1_CONTROL1 + (i * 0x40),
3457				   CS48L32_IN1_PDM_SUP_MASK, dig_mode);
3458	}
3459
3460	return 0;
3461}
3462
3463static int cs48l32_init_dai(struct cs48l32_codec *cs48l32_codec, int id)
3464{
3465	struct cs48l32_dai_priv *dai_priv = &cs48l32_codec->dai[id];
3466
3467	dai_priv->clk = CS48L32_CLK_SYSCLK_1;
3468	dai_priv->constraint = cs48l32_constraint;
3469
3470	return 0;
3471}
3472
3473static int cs48l32_init_eq(struct cs48l32_codec *cs48l32_codec)
3474{
3475	struct regmap *regmap = cs48l32_codec->core.regmap;
3476	unsigned int reg = CS48L32_EQ1_BAND1_COEFF1, mode;
3477	__be16 *data;
3478	int i, ret;
3479
3480	ret = regmap_read(regmap, CS48L32_EQ_CONTROL2, &mode);
3481	if (ret < 0) {
3482		dev_err(cs48l32_codec->core.dev, "Error reading EQ mode: %d\n", ret);
3483		goto out;
3484	}
3485
3486	for (i = 0; i < 4; ++i) {
3487		cs48l32_codec->eq_mode[i] = (mode >> i) & 0x1;
3488
3489		data = &cs48l32_codec->eq_coefficients[i][0];
3490		ret = regmap_raw_read(regmap, reg + (i * 68), data,
3491				      CS48L32_EQ_BLOCK_SZ);
3492		if (ret < 0) {
3493			dev_err(cs48l32_codec->core.dev,
3494				"Error reading EQ coefficients: %d\n", ret);
3495			goto out;
3496		}
3497	}
3498
3499out:
3500	return ret;
3501}
3502
3503static int cs48l32_component_probe(struct snd_soc_component *component)
3504{
3505	struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
3506	int i, ret;
3507
3508	snd_soc_component_init_regmap(component, cs48l32_codec->core.regmap);
3509
3510	ret = cs48l32_init_inputs(component);
3511	if (ret)
3512		return ret;
3513
3514	for (i = 0; i < ARRAY_SIZE(cs48l32_dai); i++)
3515		cs48l32_init_dai(cs48l32_codec, i);
3516
3517	ret = cs48l32_init_eq(cs48l32_codec);
3518	if (ret)
3519		return ret;
3520
3521	wm_adsp2_component_probe(&cs48l32_codec->dsp, component);
3522
3523	/* Unmask DSP IRQs */
3524	regmap_clear_bits(cs48l32_codec->core.regmap, CS48L32_IRQ1_MASK_7,
3525			  CS48L32_DSP1_MPU_ERR_EINT1_MASK | CS48L32_DSP1_WDT_EXPIRE_EINT1_MASK);
3526	regmap_clear_bits(cs48l32_codec->core.regmap, CS48L32_IRQ1_MASK_9,
3527			  CS48L32_DSP1_IRQ0_EINT1_MASK);
3528
3529	return 0;
3530}
3531
3532static void cs48l32_component_remove(struct snd_soc_component *component)
3533{
3534	struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
3535
3536	/* Mask DSP IRQs */
3537	regmap_set_bits(cs48l32_codec->core.regmap, CS48L32_IRQ1_MASK_7,
3538			CS48L32_DSP1_MPU_ERR_EINT1_MASK | CS48L32_DSP1_WDT_EXPIRE_EINT1_MASK);
3539	regmap_set_bits(cs48l32_codec->core.regmap, CS48L32_IRQ1_MASK_9,
3540			CS48L32_DSP1_IRQ0_EINT1_MASK);
3541
3542	wm_adsp2_component_remove(&cs48l32_codec->dsp, component);
3543}
3544
3545static const struct snd_soc_component_driver cs48l32_soc_component_drv = {
3546	.probe			= &cs48l32_component_probe,
3547	.remove			= &cs48l32_component_remove,
3548	.set_sysclk		= &cs48l32_set_sysclk,
3549	.set_pll		= &cs48l32_set_fll,
3550	.name			= "cs48l32-codec",
3551	.compress_ops		= &cs48l32_compress_ops,
3552	.controls		= cs48l32_snd_controls,
3553	.num_controls		= ARRAY_SIZE(cs48l32_snd_controls),
3554	.dapm_widgets		= cs48l32_dapm_widgets,
3555	.num_dapm_widgets	= ARRAY_SIZE(cs48l32_dapm_widgets),
3556	.dapm_routes		= cs48l32_dapm_routes,
3557	.num_dapm_routes	= ARRAY_SIZE(cs48l32_dapm_routes),
3558	.use_pmdown_time	= 1,
3559	.endianness		= 1,
3560};
3561
3562static int cs48l32_prop_read_u32_array(struct cs48l32_codec *cs48l32_codec,
3563				       const char *propname,
3564				       u32 *dest,
3565				       int n_max)
3566{
3567	struct cs48l32 *cs48l32 = &cs48l32_codec->core;
3568	int ret;
3569
3570	ret = device_property_read_u32_array(cs48l32->dev, propname, dest, n_max);
3571	if (ret == -EINVAL)
3572		return -ENOENT;
3573
3574	if (ret < 0)
3575		return dev_err_probe(cs48l32->dev, ret, "%s malformed\n", propname);
3576
3577	return 0;
3578}
3579
3580static void cs48l32_prop_get_in_type(struct cs48l32_codec *cs48l32_codec)
3581{
3582	const char *propname = "cirrus,in-type";
3583	u32 tmp[CS48L32_MAX_ANALOG_INPUT * CS48L32_MAX_IN_MUX_WAYS];
3584	int i, in_idx, mux_way_idx, ret;
3585
3586	static_assert(ARRAY_SIZE(tmp) ==
3587		      ARRAY_SIZE(cs48l32_codec->in_type) * ARRAY_SIZE(cs48l32_codec->in_type[0]));
3588
3589	ret = cs48l32_prop_read_u32_array(cs48l32_codec, propname, tmp, ARRAY_SIZE(tmp));
3590	if (ret < 0)
3591		return;
3592
3593	in_idx = 0;
3594	mux_way_idx = 0;
3595	for (i = 0; i < ARRAY_SIZE(tmp); ++i) {
3596		switch (tmp[i]) {
3597		case CS48L32_IN_TYPE_DIFF:
3598		case CS48L32_IN_TYPE_SE:
3599			cs48l32_codec->in_type[in_idx][mux_way_idx] = tmp[i];
3600			break;
3601		default:
3602			dev_warn(cs48l32_codec->core.dev, "Illegal %s value %d ignored\n",
3603				 propname, tmp[i]);
3604			break;
3605		}
3606
3607		/*
3608		 * Property array is [mux_way][in_channel]. Swap to
3609		 * [in_channel][mux_way] for convenience.
3610		 */
3611		if (++in_idx == ARRAY_SIZE(cs48l32_codec->in_type)) {
3612			in_idx = 0;
3613			++mux_way_idx;
3614		}
3615	}
3616}
3617
3618static void cs48l32_prop_get_pdm_sup(struct cs48l32_codec *cs48l32_codec)
3619{
3620	const char *propname = "cirrus,pdm-sup";
3621	u32 tmp[CS48L32_MAX_ANALOG_INPUT];
3622	int i;
3623
3624	static_assert(ARRAY_SIZE(tmp) == ARRAY_SIZE(cs48l32_codec->pdm_sup));
3625
3626	cs48l32_prop_read_u32_array(cs48l32_codec, propname, tmp, ARRAY_SIZE(tmp));
3627
3628	for (i = 0; i < ARRAY_SIZE(cs48l32_codec->pdm_sup); i++) {
3629		switch (tmp[i]) {
3630		case CS48L32_PDM_SUP_VOUT_MIC:
3631		case CS48L32_PDM_SUP_MICBIAS1:
3632			cs48l32_codec->pdm_sup[i] = tmp[i];
3633			break;
3634		default:
3635			dev_warn(cs48l32_codec->core.dev, "Illegal %s value %d ignored\n",
3636				 propname, cs48l32_codec->pdm_sup[i]);
3637			break;
3638		}
3639	}
3640}
3641
3642static void cs48l32_handle_properties(struct cs48l32_codec *cs48l32_codec)
3643{
3644	cs48l32_prop_get_in_type(cs48l32_codec);
3645	cs48l32_prop_get_pdm_sup(cs48l32_codec);
3646}
3647
3648static int cs48l32_request_interrupt(struct cs48l32_codec *cs48l32_codec)
3649{
3650	int irq = cs48l32_codec->core.irq;
3651	int ret;
3652
3653	if (irq < 1)
3654		return 0;
3655
3656	/*
3657	 * Don't use devm because this must be freed before destroying the
3658	 * rest of the driver
3659	 */
3660	ret = request_threaded_irq(irq, NULL, cs48l32_irq,
3661				   IRQF_ONESHOT | IRQF_SHARED | IRQF_TRIGGER_LOW,
3662				   "cs48l32", cs48l32_codec);
3663	if (ret)
3664		return dev_err_probe(cs48l32_codec->core.dev, ret, "Failed to get IRQ\n");
3665
3666	return 0;
3667}
3668
3669static int cs48l32_create_codec_component(struct cs48l32_codec *cs48l32_codec)
3670{
3671	struct wm_adsp *dsp;
3672	int ret;
3673
3674	ASSERT_STRUCT_OFFSET(struct cs48l32_codec, dsp, 0);
3675	static_assert(ARRAY_SIZE(cs48l32_dai) == ARRAY_SIZE(cs48l32_codec->dai));
3676
3677	cs48l32_handle_properties(cs48l32_codec);
3678
3679	dsp = &cs48l32_codec->dsp;
3680	dsp->part = "cs48l32";
3681	dsp->cs_dsp.num = 1;
3682	dsp->cs_dsp.type = WMFW_HALO;
3683	dsp->cs_dsp.rev = 0;
3684	dsp->cs_dsp.dev = cs48l32_codec->core.dev;
3685	dsp->cs_dsp.regmap = cs48l32_codec->core.regmap;
3686	dsp->cs_dsp.base = CS48L32_DSP1_CLOCK_FREQ;
3687	dsp->cs_dsp.base_sysinfo = CS48L32_DSP1_SYS_INFO_ID;
3688	dsp->cs_dsp.mem = cs48l32_dsp1_regions;
3689	dsp->cs_dsp.num_mems = ARRAY_SIZE(cs48l32_dsp1_regions);
3690	dsp->pre_run = cs48l32_dsp_pre_run;
3691
3692	ret = wm_halo_init(dsp);
3693	if (ret != 0)
3694		return ret;
3695
3696	cs48l32_codec->fll.codec = cs48l32_codec;
3697	cs48l32_codec->fll.id = 1;
3698	cs48l32_codec->fll.base = CS48L32_FLL1_CONTROL1;
3699	cs48l32_codec->fll.sts_addr = CS48L32_IRQ1_STS_6;
3700	cs48l32_codec->fll.sts_mask = CS48L32_FLL1_LOCK_STS1_MASK;
3701	cs48l32_init_fll(&cs48l32_codec->fll);
3702
3703	ret = cs48l32_request_interrupt(cs48l32_codec);
3704	if (ret)
3705		goto err_dsp;
3706
3707	ret = devm_snd_soc_register_component(cs48l32_codec->core.dev,
3708					      &cs48l32_soc_component_drv,
3709					      cs48l32_dai,
3710					      ARRAY_SIZE(cs48l32_dai));
3711	if (ret < 0) {
3712		dev_err_probe(cs48l32_codec->core.dev, ret, "Failed to register component\n");
3713		goto err_dsp;
3714	}
3715
3716	return 0;
3717
3718err_dsp:
3719	wm_adsp2_remove(&cs48l32_codec->dsp);
3720
3721	return ret;
3722}
3723
3724static int cs48l32_wait_for_boot(struct cs48l32 *cs48l32)
3725{
3726	unsigned int val;
3727	int ret;
3728
3729	ret = regmap_read_poll_timeout(cs48l32->regmap, CS48L32_IRQ1_EINT_2, val,
3730				       ((val < 0xffffffff) && (val & CS48L32_BOOT_DONE_EINT1_MASK)),
3731				       1000, CS48L32_BOOT_TIMEOUT_US);
3732	if (ret) {
3733		dev_err(cs48l32->dev, "BOOT_DONE timed out\n");
3734		return -ETIMEDOUT;
3735	}
3736
3737	ret = regmap_read(cs48l32->regmap, CS48L32_MCU_CTRL1, &val);
3738	if (ret) {
3739		dev_err(cs48l32->dev, "Failed to read MCU_CTRL1: %d\n", ret);
3740		return ret;
3741	}
3742
3743	if (val & BIT(CS48L32_MCU_STS_SHIFT)) {
3744		dev_err(cs48l32->dev, "MCU boot failed\n");
3745		return -EIO;
3746	}
3747
3748	pm_runtime_mark_last_busy(cs48l32->dev);
3749
3750	return 0;
3751}
3752
3753static int cs48l32_soft_reset(struct cs48l32 *cs48l32)
3754{
3755	int ret;
3756
3757	ret = regmap_write(cs48l32->regmap, CS48L32_SFT_RESET, CS48L32_SFT_RESET_MAGIC);
3758	if (ret != 0) {
3759		dev_err(cs48l32->dev, "Failed to write soft reset: %d\n", ret);
3760		return ret;
3761	}
3762
3763	usleep_range(CS48L32_SOFT_RESET_US, CS48L32_SOFT_RESET_US + 1000);
3764
3765	return 0;
3766}
3767
3768static void cs48l32_enable_hard_reset(struct cs48l32 *cs48l32)
3769{
3770	if (cs48l32->reset_gpio)
3771		gpiod_set_raw_value_cansleep(cs48l32->reset_gpio, 0);
3772}
3773
3774static void cs48l32_disable_hard_reset(struct cs48l32 *cs48l32)
3775{
3776	if (cs48l32->reset_gpio) {
3777		gpiod_set_raw_value_cansleep(cs48l32->reset_gpio, 1);
3778		usleep_range(CS48L32_HARD_RESET_MIN_US, CS48L32_HARD_RESET_MIN_US + 1000);
3779	}
3780}
3781
3782static int cs48l32_runtime_resume(struct device *dev)
3783{
3784	struct cs48l32_codec *cs48l32_codec = dev_get_drvdata(dev);
3785	struct cs48l32 *cs48l32 = &cs48l32_codec->core;
3786	unsigned int val;
3787	int ret;
3788
3789	ret = regulator_enable(cs48l32->vdd_d);
3790	if (ret) {
3791		dev_err(cs48l32->dev, "Failed to enable VDD_D: %d\n", ret);
3792		return ret;
3793	}
3794
3795	usleep_range(CS48L32_SOFT_RESET_US, CS48L32_SOFT_RESET_US + 1000);
3796
3797	regcache_cache_only(cs48l32->regmap, false);
3798
3799	ret = cs48l32_wait_for_boot(cs48l32);
3800	if (ret)
3801		goto err;
3802
3803	/* Check whether registers reset during suspend */
3804	regmap_read(cs48l32->regmap, CS48L32_CTRL_IF_DEBUG3, &val);
3805	if (!val)
3806		regcache_mark_dirty(cs48l32->regmap);
3807	else
3808		dev_dbg(cs48l32->dev, "Did not reset during suspend\n");
3809
3810	ret = regcache_sync(cs48l32->regmap);
3811	if (ret) {
3812		dev_err(cs48l32->dev, "Failed to restore register cache\n");
3813		goto err;
3814	}
3815
3816	return 0;
3817
3818err:
3819	regcache_cache_only(cs48l32->regmap, true);
3820	regulator_disable(cs48l32->vdd_d);
3821
3822	return ret;
3823}
3824
3825static int cs48l32_runtime_suspend(struct device *dev)
3826{
3827	struct cs48l32_codec *cs48l32_codec = dev_get_drvdata(dev);
3828	struct cs48l32 *cs48l32 = &cs48l32_codec->core;
3829
3830	/* Flag to detect if the registers reset during suspend */
3831	regmap_write(cs48l32->regmap, CS48L32_CTRL_IF_DEBUG3, 1);
3832
3833	regcache_cache_only(cs48l32->regmap, true);
3834	regulator_disable(cs48l32->vdd_d);
3835
3836	return 0;
3837}
3838
3839static const struct dev_pm_ops cs48l32_pm_ops = {
3840	RUNTIME_PM_OPS(cs48l32_runtime_suspend, cs48l32_runtime_resume, NULL)
3841};
3842
3843static int cs48l32_configure_clk32k(struct cs48l32 *cs48l32)
3844{
3845	int ret = 0;
3846
3847	ret = clk_prepare_enable(cs48l32->mclk1);
3848	if (ret)
3849		return dev_err_probe(cs48l32->dev, ret, "Failed to enable 32k clock\n");
3850
3851	ret = regmap_update_bits(cs48l32->regmap, CS48L32_CLOCK32K,
3852				 CS48L32_CLK_32K_EN_MASK | CS48L32_CLK_32K_SRC_MASK,
3853				 CS48L32_CLK_32K_EN_MASK | CS48L32_32K_MCLK1);
3854	if (ret) {
3855		clk_disable_unprepare(cs48l32->mclk1);
3856		return dev_err_probe(cs48l32->dev, ret, "Failed to init 32k clock\n");
3857	}
3858
3859	return 0;
3860}
3861
3862static int cs48l32_get_clocks(struct cs48l32 *cs48l32)
3863{
3864	cs48l32->mclk1 = devm_clk_get_optional(cs48l32->dev, "mclk1");
3865	if (IS_ERR(cs48l32->mclk1))
3866		return dev_err_probe(cs48l32->dev, PTR_ERR(cs48l32->mclk1),
3867				     "Failed to get mclk1\n");
3868
3869	return 0;
3870}
3871
3872static int cs48l32_get_reset_gpio(struct cs48l32 *cs48l32)
3873{
3874	struct gpio_desc *reset;
3875
3876	reset = devm_gpiod_get_optional(cs48l32->dev, "reset", GPIOD_OUT_LOW);
3877	if (IS_ERR(reset))
3878		return dev_err_probe(cs48l32->dev, PTR_ERR(reset), "Failed to request /RESET\n");
3879
3880	/* ACPI can override the GPIOD_OUT_LOW so ensure it starts low */
3881	gpiod_set_raw_value_cansleep(reset, 0);
3882
3883	cs48l32->reset_gpio = reset;
3884
3885	return 0;
3886}
3887
3888static int cs48l32_spi_probe(struct spi_device *spi)
3889{
3890	struct device *dev = &spi->dev;
3891	struct cs48l32_codec *cs48l32_codec;
3892	struct cs48l32 *cs48l32;
3893	unsigned int hwid, rev, otp_rev;
3894	int i, ret;
3895
3896	cs48l32_codec = devm_kzalloc(&spi->dev, sizeof(*cs48l32_codec), GFP_KERNEL);
3897	if (!cs48l32_codec)
3898		return -ENOMEM;
3899
3900	cs48l32 = &cs48l32_codec->core;
3901	cs48l32->dev = dev;
3902	cs48l32->irq = spi->irq;
3903	mutex_init(&cs48l32_codec->rate_lock);
3904	cs48l32_codec->in_vu_reg = CS48L32_INPUT_CONTROL3;
3905
3906	dev_set_drvdata(cs48l32->dev, cs48l32_codec);
3907
3908	ret = cs48l32_create_regmap(spi, cs48l32);
3909	if (ret)
3910		return dev_err_probe(&spi->dev, ret, "Failed to allocate regmap\n");
3911
3912	regcache_cache_only(cs48l32->regmap, true);
3913
3914	ret = cs48l32_get_reset_gpio(cs48l32);
3915	if (ret)
3916		return ret;
3917
3918	ret = cs48l32_get_clocks(cs48l32);
3919	if (ret)
3920		return ret;
3921
3922	static_assert(ARRAY_SIZE(cs48l32_core_supplies) == ARRAY_SIZE(cs48l32->core_supplies));
3923	for (i = 0; i < ARRAY_SIZE(cs48l32->core_supplies); i++)
3924		cs48l32->core_supplies[i].supply = cs48l32_core_supplies[i];
3925
3926	ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(cs48l32->core_supplies),
3927				      cs48l32->core_supplies);
3928	if (ret)
3929		return dev_err_probe(dev, ret, "Failed to request core supplies\n");
3930
3931	cs48l32->vdd_d = devm_regulator_get(cs48l32->dev, "vdd-d");
3932	if (IS_ERR(cs48l32->vdd_d))
3933		return dev_err_probe(dev, PTR_ERR(cs48l32->vdd_d), "Failed to request vdd-d\n");
3934
3935	ret = regulator_bulk_enable(ARRAY_SIZE(cs48l32->core_supplies), cs48l32->core_supplies);
3936	if (ret)
3937		return dev_err_probe(dev, ret, "Failed to enable core supplies\n");
3938
3939	ret = regulator_enable(cs48l32->vdd_d);
3940	if (ret) {
3941		dev_err(dev, "Failed to enable vdd-d: %d\n", ret);
3942		goto err_enable;
3943	}
3944
3945	cs48l32_disable_hard_reset(cs48l32);
3946
3947	regcache_cache_only(cs48l32->regmap, false);
3948
3949	/* If we don't have a reset GPIO use a soft reset */
3950	if (!cs48l32->reset_gpio) {
3951		ret = cs48l32_soft_reset(cs48l32);
3952		if (ret)
3953			goto err_reset;
3954	}
3955
3956	ret = cs48l32_wait_for_boot(cs48l32);
3957	if (ret) {
3958		dev_err(cs48l32->dev, "Device failed initial boot: %d\n", ret);
3959		goto err_reset;
3960	}
3961
3962	ret = regmap_read(cs48l32->regmap, CS48L32_DEVID, &hwid);
3963	if (ret) {
3964		dev_err(dev, "Failed to read ID register: %d\n", ret);
3965		goto err_reset;
3966	}
3967	hwid &= CS48L32_DEVID_MASK;
3968
3969	switch (hwid) {
3970	case CS48L32_SILICON_ID:
3971		break;
3972	default:
3973		ret = -ENODEV;
3974		dev_err_probe(cs48l32->dev, ret, "Unknown device ID: %#x\n", hwid);
3975		goto err_reset;
3976	}
3977
3978	ret = regmap_read(cs48l32->regmap, CS48L32_REVID, &rev);
3979	if (ret) {
3980		dev_err(dev, "Failed to read revision register: %d\n", ret);
3981		goto err_reset;
3982	}
3983	rev &= CS48L32_AREVID_MASK | CS48L32_MTLREVID_MASK;
3984
3985	ret = regmap_read(cs48l32->regmap, CS48L32_OTPID, &otp_rev);
3986	if (ret) {
3987		dev_err(dev, "Failed to read OTP revision register: %d\n", ret);
3988		goto err_reset;
3989	}
3990	otp_rev &= CS48L32_OTPID_MASK;
3991
3992	dev_info(dev, "CS48L%x revision %X%u OTP%u\n", hwid & 0xff,
3993		 rev >> CS48L32_AREVID_SHIFT, rev & CS48L32_MTLREVID_MASK, otp_rev);
3994
3995	/* Apply hardware patch */
3996	ret = cs48l32_apply_patch(cs48l32);
3997	if (ret) {
3998		dev_err(cs48l32->dev, "Failed to apply patch %d\n", ret);
3999		goto err_reset;
4000	}
4001
4002	/* BOOT_DONE interrupt is unmasked by default, so mask it */
4003	ret = regmap_set_bits(cs48l32->regmap, CS48L32_IRQ1_MASK_2, CS48L32_BOOT_DONE_EINT1_MASK);
4004
4005	ret = cs48l32_configure_clk32k(cs48l32);
4006	if (ret)
4007		goto err_reset;
4008
4009	pm_runtime_set_active(cs48l32->dev);
4010	pm_runtime_set_autosuspend_delay(cs48l32->dev, 100);
4011	pm_runtime_use_autosuspend(cs48l32->dev);
4012	pm_runtime_enable(cs48l32->dev);
4013
4014	ret = cs48l32_create_codec_component(cs48l32_codec);
4015	if (ret)
4016		goto err_clk32k;
4017
4018	return 0;
4019
4020err_clk32k:
4021	clk_disable_unprepare(cs48l32->mclk1);
4022err_reset:
4023	cs48l32_enable_hard_reset(cs48l32);
4024	regulator_disable(cs48l32->vdd_d);
4025err_enable:
4026	regulator_bulk_disable(ARRAY_SIZE(cs48l32->core_supplies), cs48l32->core_supplies);
4027
4028	return ret;
4029}
4030
4031static void cs48l32_spi_remove(struct spi_device *spi)
4032{
4033	struct cs48l32_codec *cs48l32_codec = spi_get_drvdata(spi);
4034	struct cs48l32 *cs48l32 = &cs48l32_codec->core;
4035
4036	/* Remove IRQ handler before destroying anything else */
4037	if (cs48l32->irq >= 1)
4038		free_irq(cs48l32->irq, cs48l32_codec);
4039
4040	pm_runtime_disable(cs48l32->dev);
4041	regulator_disable(cs48l32->vdd_d);
4042	clk_disable_unprepare(cs48l32->mclk1);
4043	cs48l32_enable_hard_reset(cs48l32);
4044	regulator_bulk_disable(ARRAY_SIZE(cs48l32->core_supplies), cs48l32->core_supplies);
4045
4046	mutex_destroy(&cs48l32_codec->rate_lock);
4047}
4048
4049static const struct of_device_id cs48l32_of_match[] = {
4050	{ .compatible = "cirrus,cs48l32", },
4051	{},
4052};
4053
4054static const struct spi_device_id cs48l32_spi_ids[] = {
4055	{ "cs48l32", },
4056	{ },
4057};
4058MODULE_DEVICE_TABLE(spi, cs48l32_spi_ids);
4059
4060static struct spi_driver cs48l32_spi_driver = {
4061	.driver = {
4062		.name		= "cs48l32",
4063		.pm		= pm_ptr(&cs48l32_pm_ops),
4064		.of_match_table	= cs48l32_of_match,
4065	},
4066	.probe		= &cs48l32_spi_probe,
4067	.remove		= &cs48l32_spi_remove,
4068	.id_table	= cs48l32_spi_ids,
4069};
4070module_spi_driver(cs48l32_spi_driver);
4071
4072MODULE_DESCRIPTION("CS48L32 ASoC codec driver");
4073MODULE_AUTHOR("Stuart Henderson <stuarth@opensource.cirrus.com>");
4074MODULE_AUTHOR("Piotr Stankiewicz <piotrs@opensource.cirrus.com>");
4075MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>");
4076MODULE_LICENSE("GPL");
~/ Read-only file preview.