Lines Matching +full:mux +full:- +full:ctrl +full:- +full:list

1 // SPDX-License-Identifier: GPL-2.0-only
5 // Copyright (C) 2016-2018, 2020, 2022, 2025 Cirrus Logic, Inc. and
8 #include <dt-bindings/sound/cs48l32.h>
32 #include <sound/soc-component.h>
33 #include <sound/soc-dai.h>
34 #include <sound/soc-dapm.h>
39 static const char * const cs48l32_core_supplies[] = { "vdd-a", "vdd-io" };
193 static const DECLARE_TLV_DB_SCALE(cs48l32_eq_tlv, -1200, 100, 0);
194 static const DECLARE_TLV_DB_SCALE(cs48l32_digital_tlv, -6400, 50, 0);
195 static const DECLARE_TLV_DB_SCALE(cs48l32_noise_tlv, -10800, 600, 0);
196 static const DECLARE_TLV_DB_SCALE(cs48l32_mixer_tlv, -3200, 100, 0);
201 struct cs48l32 *cs48l32 = &cs48l32_codec->core; in cs48l32_spin_sysclk()
206 if (pm_runtime_suspended(cs48l32->dev)) in cs48l32_spin_sysclk()
214 ret = regmap_read(cs48l32->regmap, CS48L32_DEVID, &val); in cs48l32_spin_sysclk()
216 dev_err(cs48l32_codec->core.dev, "%s Failed to read register: %d (%d)\n", in cs48l32_spin_sysclk()
238 /* Prevent any mixer mux changes while we do this */ in cs48l32_rate_put()
239 mutex_lock(&cs48l32_codec->rate_lock); in cs48l32_rate_put()
246 mutex_unlock(&cs48l32_codec->rate_lock); in cs48l32_rate_put()
326 struct soc_enum *e = (struct soc_enum *) kcontrol->private_value; in cs48l32_inmux_put()
327 unsigned int mux, src_val, in_type; in cs48l32_inmux_put() local
330 mux = ucontrol->value.enumerated.item[0]; in cs48l32_inmux_put()
331 if (mux > 1) in cs48l32_inmux_put()
332 return -EINVAL; in cs48l32_inmux_put()
334 switch (e->reg) { in cs48l32_inmux_put()
336 in_type = cs48l32_codec->in_type[0][mux]; in cs48l32_inmux_put()
339 in_type = cs48l32_codec->in_type[1][mux]; in cs48l32_inmux_put()
342 return -EINVAL; in cs48l32_inmux_put()
345 src_val = mux << e->shift_l; in cs48l32_inmux_put()
350 ret = snd_soc_component_update_bits(dapm->component, in cs48l32_inmux_put()
351 e->reg, in cs48l32_inmux_put()
355 snd_soc_dapm_mux_update_power(dapm, kcontrol, mux, e, NULL); in cs48l32_inmux_put()
375 SOC_DAPM_ENUM_EXT("IN1L Mux", cs48l32_in1muxl_enum,
377 SOC_DAPM_ENUM_EXT("IN1R Mux", cs48l32_in1muxr_enum,
390 struct soc_enum *e = (struct soc_enum *) kcontrol->private_value; in cs48l32_dmode_put()
394 mode = ucontrol->value.enumerated.item[0]; in cs48l32_dmode_put()
402 dev_err(component->dev, in cs48l32_dmode_put()
412 dev_err(component->dev, in cs48l32_dmode_put()
418 e->reg, in cs48l32_dmode_put()
422 dev_err(component->dev, "Failed to set input mode: %d\n", result); in cs48l32_dmode_put()
433 dev_err(component->dev, in cs48l32_dmode_put()
443 dev_err(component->dev, in cs48l32_dmode_put()
455 return -EINVAL; in cs48l32_dmode_put()
475 "16-24kHz", "20-28kHz",
522 "-6dB", "-9dB", "-12dB", "-15dB", "-18dB", "-21dB", "-24dB", "-27dB",
709 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; in cs48l32_in_rate_put()
715 if (cs48l32_is_input_enabled(component, e->reg)) { in cs48l32_in_rate_put()
716 ret = -EBUSY; in cs48l32_in_rate_put()
757 struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; in cs48l32_low_power_mode_put()
765 if (cs48l32_is_input_enabled(component, mc->reg)) { in cs48l32_low_power_mode_put()
766 ret = -EBUSY; in cs48l32_low_power_mode_put()
898 "Low-pass", "High-pass"
917 __be32 *data = (__be32 *)ucontrol->value.bytes.data; in cs48l32_lhpf_coeff_put()
921 dev_err(cs48l32_codec->core.dev, "Rejecting unstable LHPF coefficients\n"); in cs48l32_lhpf_coeff_put()
922 return -EINVAL; in cs48l32_lhpf_coeff_put()
929 "Low-pass", "High-pass",
952 struct soc_enum *e = (struct soc_enum *) kcontrol->private_value; in cs48l32_eq_mode_get()
955 item = snd_soc_enum_val_to_item(e, cs48l32_codec->eq_mode[e->shift_l]); in cs48l32_eq_mode_get()
956 ucontrol->value.enumerated.item[0] = item; in cs48l32_eq_mode_get()
967 struct soc_enum *e = (struct soc_enum *) kcontrol->private_value; in cs48l32_eq_mode_put()
968 unsigned int *item = ucontrol->value.enumerated.item; in cs48l32_eq_mode_put()
972 if (item[0] >= e->items) in cs48l32_eq_mode_put()
973 return -EINVAL; in cs48l32_eq_mode_put()
978 if (cs48l32_codec->eq_mode[e->shift_l] != val) { in cs48l32_eq_mode_put()
979 cs48l32_codec->eq_mode[e->shift_l] = val; in cs48l32_eq_mode_put()
990 struct cs48l32_eq_control *ctl = (void *) kcontrol->private_value; in cs48l32_eq_coeff_info()
992 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in cs48l32_eq_coeff_info()
993 uinfo->count = 1; in cs48l32_eq_coeff_info()
994 uinfo->value.integer.min = 0; in cs48l32_eq_coeff_info()
995 uinfo->value.integer.max = ctl->max; in cs48l32_eq_coeff_info()
1005 struct cs48l32_eq_control *params = (void *)kcontrol->private_value; in cs48l32_eq_coeff_get()
1010 block_idx = ((int) params->block_base - (int) CS48L32_EQ1_BAND1_COEFF1); in cs48l32_eq_coeff_get()
1011 block_idx /= (CS48L32_EQ2_BAND1_COEFF1 - CS48L32_EQ1_BAND1_COEFF1); in cs48l32_eq_coeff_get()
1013 coeffs = &cs48l32_codec->eq_coefficients[block_idx][0]; in cs48l32_eq_coeff_get()
1014 coeff_idx = (params->reg - params->block_base) / 2; in cs48l32_eq_coeff_get()
1017 if (params->shift == 0) in cs48l32_eq_coeff_get()
1020 ucontrol->value.integer.value[0] = be16_to_cpu(coeffs[coeff_idx]); in cs48l32_eq_coeff_get()
1031 struct cs48l32_eq_control *params = (void *)kcontrol->private_value; in cs48l32_eq_coeff_put()
1036 block_idx = ((int) params->block_base - (int) CS48L32_EQ1_BAND1_COEFF1); in cs48l32_eq_coeff_put()
1037 block_idx /= (CS48L32_EQ2_BAND1_COEFF1 - CS48L32_EQ1_BAND1_COEFF1); in cs48l32_eq_coeff_put()
1039 coeffs = &cs48l32_codec->eq_coefficients[block_idx][0]; in cs48l32_eq_coeff_put()
1040 coeff_idx = (params->reg - params->block_base) / 2; in cs48l32_eq_coeff_put()
1043 if (params->shift == 0) in cs48l32_eq_coeff_put()
1047 coeffs[coeff_idx] = cpu_to_be16(ucontrol->value.integer.value[0]); in cs48l32_eq_coeff_put()
1067 struct soc_enum *e = (struct soc_enum *) kcontrol->private_value; in cs48l32_dsp_rate_get()
1069 const unsigned int rate_num = e->mask; in cs48l32_dsp_rate_get()
1072 if (rate_num >= ARRAY_SIZE(cs48l32_codec->dsp_dma_rates)) in cs48l32_dsp_rate_get()
1073 return -EINVAL; in cs48l32_dsp_rate_get()
1075 cached_rate = cs48l32_codec->dsp_dma_rates[rate_num]; in cs48l32_dsp_rate_get()
1077 ucontrol->value.enumerated.item[0] = item; in cs48l32_dsp_rate_get()
1088 struct soc_enum *e = (struct soc_enum *) kcontrol->private_value; in cs48l32_dsp_rate_put()
1089 const unsigned int rate_num = e->mask; in cs48l32_dsp_rate_put()
1090 const unsigned int item = ucontrol->value.enumerated.item[0]; in cs48l32_dsp_rate_put()
1094 if (item >= e->items) in cs48l32_dsp_rate_put()
1095 return -EINVAL; in cs48l32_dsp_rate_put()
1097 if (rate_num >= ARRAY_SIZE(cs48l32_codec->dsp_dma_rates)) in cs48l32_dsp_rate_put()
1098 return -EINVAL; in cs48l32_dsp_rate_put()
1103 if (cs48l32_codec->dsp_dma_rates[rate_num] != val) { in cs48l32_dsp_rate_put()
1104 cs48l32_codec->dsp_dma_rates[rate_num] = val; in cs48l32_dsp_rate_put()
1185 const u8 *rate = cs48l32_codec->dsp_dma_rates; in cs48l32_dsp_pre_run()
1188 reg = dsp->cs_dsp.base + CS48L32_HALO_SAMPLE_RATE_RX1; in cs48l32_dsp_pre_run()
1190 regmap_update_bits(dsp->cs_dsp.regmap, reg, CS48L32_HALO_DSP_RATE_MASK, *rate); in cs48l32_dsp_pre_run()
1195 reg = dsp->cs_dsp.base + CS48L32_HALO_SAMPLE_RATE_TX1; in cs48l32_dsp_pre_run()
1197 regmap_update_bits(dsp->cs_dsp.regmap, reg, CS48L32_HALO_DSP_RATE_MASK, *rate); in cs48l32_dsp_pre_run()
1210 struct regmap *regmap = cs48l32_codec->core.regmap; in cs48l32_dsp_memory_disable()
1213 for (i = 0; i < regs->n_pwd; ++i) { in cs48l32_dsp_memory_disable()
1214 ret = regmap_write(regmap, regs->pwd[i], 0); in cs48l32_dsp_memory_disable()
1219 for (i = 0; i < regs->n_ext; ++i) { in cs48l32_dsp_memory_disable()
1220 for (j = regs->ext[i].start; j <= regs->ext[i].end; j += 4) { in cs48l32_dsp_memory_disable()
1230 dev_warn(cs48l32_codec->core.dev, "Failed to write SRAM enables (%d)\n", ret); in cs48l32_dsp_memory_disable()
1236 struct regmap *regmap = cs48l32_codec->core.regmap; in cs48l32_dsp_memory_enable()
1239 /* disable power-off */ in cs48l32_dsp_memory_enable()
1240 for (i = 0; i < regs->n_ext; ++i) { in cs48l32_dsp_memory_enable()
1241 for (j = regs->ext[i].start; j <= regs->ext[i].end; j += 4) { in cs48l32_dsp_memory_enable()
1248 /* power-up the banks in sequence */ in cs48l32_dsp_memory_enable()
1249 for (i = 0; i < regs->n_pwd; ++i) { in cs48l32_dsp_memory_enable()
1250 ret = regmap_write(regmap, regs->pwd[i], 0x1); in cs48l32_dsp_memory_enable()
1254 udelay(1); /* allow bank to power-up */ in cs48l32_dsp_memory_enable()
1256 ret = regmap_write(regmap, regs->pwd[i], 0x3); in cs48l32_dsp_memory_enable()
1260 udelay(1); /* allow bank to power-up */ in cs48l32_dsp_memory_enable()
1266 dev_err(cs48l32_codec->core.dev, "Failed to write SRAM enables (%d)\n", ret); in cs48l32_dsp_memory_enable()
1275 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); in cs48l32_dsp_freq_update()
1277 struct regmap *regmap = cs48l32_codec->core.regmap; in cs48l32_dsp_freq_update()
1278 struct wm_adsp *dsp = &cs48l32_codec->dsp; in cs48l32_dsp_freq_update()
1283 return -EINVAL; in cs48l32_dsp_freq_update()
1287 dev_err(component->dev, "Failed to read #%x: %d\n", freq_reg, ret); in cs48l32_dsp_freq_update()
1296 dev_err(component->dev, "Failed to read #%x: %d\n", freqsel_reg, ret); in cs48l32_dsp_freq_update()
1302 dev_err(component->dev, "SYSCLK FREQ (#%x) != FREQ STS (#%x)\n", in cs48l32_dsp_freq_update()
1304 return -ETIMEDOUT; in cs48l32_dsp_freq_update()
1311 ret = regmap_write(dsp->cs_dsp.regmap, in cs48l32_dsp_freq_update()
1312 dsp->cs_dsp.base + CS48L32_DSP_CLOCK_FREQ_OFFS, freq); in cs48l32_dsp_freq_update()
1314 dev_err(component->dev, "Failed to set HALO clock freq: %d\n", ret); in cs48l32_dsp_freq_update()
1340 struct regmap *regmap = cs48l32_codec->core.regmap; in cs48l32_irq()
1347 ret = pm_runtime_resume_and_get(cs48l32_codec->core.dev); in cs48l32_irq()
1349 dev_warn(cs48l32_codec->core.dev, "irq could not get pm runtime: %d\n", ret); in cs48l32_irq()
1355 dev_warn(cs48l32_codec->core.dev, "Read IRQ1_STATUS failed: %d\n", ret); in cs48l32_irq()
1363 dev_warn(cs48l32_codec->core.dev, "Read IRQ regs failed: %d\n", ret); in cs48l32_irq()
1373 wm_adsp_compr_handle_irq(&cs48l32_codec->dsp); in cs48l32_irq()
1376 dev_warn(cs48l32_codec->core.dev, "MPU err IRQ\n"); in cs48l32_irq()
1377 wm_halo_bus_error(irq, &cs48l32_codec->dsp); in cs48l32_irq()
1381 dev_warn(cs48l32_codec->core.dev, "WDT expire IRQ\n"); in cs48l32_irq()
1382 wm_halo_wdt_expire(irq, &cs48l32_codec->dsp); in cs48l32_irq()
1388 pm_runtime_put_autosuspend(cs48l32_codec->core.dev); in cs48l32_irq()
1422 return -EINVAL; in cs48l32_get_sysclk_setting()
1429 struct regmap *regmap = cs48l32_codec->core.regmap; in cs48l32_set_pdm_fllclk()
1442 dev_err(cs48l32_codec->core.dev, "Invalid PDM FLLCLK src %d\n", source); in cs48l32_set_pdm_fllclk()
1443 return -EINVAL; in cs48l32_set_pdm_fllclk()
1454 struct regmap *regmap = cs48l32_codec->core.regmap; in cs48l32_set_sysclk()
1465 clk = &cs48l32_codec->sysclk; in cs48l32_set_sysclk()
1472 clk = &cs48l32_codec->dspclk; in cs48l32_set_sysclk()
1479 return -EINVAL; in cs48l32_set_sysclk()
1483 dev_err(cs48l32_codec->core.dev, "Failed to get %s setting for %dHZ\n", name, freq); in cs48l32_set_sysclk()
1490 dev_dbg(cs48l32_codec->core.dev, "%s cleared\n", name); in cs48l32_set_sysclk()
1499 dev_dbg(cs48l32_codec->core.dev, "%s set to %uHz", name, freq); in cs48l32_set_sysclk()
1506 struct regmap *regmap = fll->codec->core.regmap; in cs48l32_is_enabled_fll()
1521 struct regmap *regmap = fll->codec->core.regmap; in cs48l32_wait_for_fll()
1528 regmap_read(regmap, fll->sts_addr, &val); in cs48l32_wait_for_fll()
1529 if (!!(val & fll->sts_mask) == requested) in cs48l32_wait_for_fll()
1547 return -ETIMEDOUT; in cs48l32_wait_for_fll()
1552 struct cs48l32 *cs48l32 = &fll->codec->core; in cs48l32_fllhj_disable()
1560 * again due to a control clock being required, the lock won't re-assert in cs48l32_fllhj_disable()
1564 regmap_set_bits(cs48l32->regmap, in cs48l32_fllhj_disable()
1565 fll->base + CS48L32_FLL_CONTROL1_OFFS, in cs48l32_fllhj_disable()
1567 regmap_clear_bits(cs48l32->regmap, in cs48l32_fllhj_disable()
1568 fll->base + CS48L32_FLL_CONTROL2_OFFS, in cs48l32_fllhj_disable()
1570 regmap_set_bits(cs48l32->regmap, in cs48l32_fllhj_disable()
1571 fll->base + CS48L32_FLL_CONTROL5_OFFS, in cs48l32_fllhj_disable()
1573 regmap_update_bits_check(cs48l32->regmap, in cs48l32_fllhj_disable()
1574 fll->base + CS48L32_FLL_CONTROL1_OFFS, in cs48l32_fllhj_disable()
1589 regmap_clear_bits(cs48l32->regmap, in cs48l32_fllhj_disable()
1590 fll->base + CS48L32_FLL_CONTROL1_OFFS, in cs48l32_fllhj_disable()
1594 pm_runtime_put_autosuspend(cs48l32->dev); in cs48l32_fllhj_disable()
1601 struct regmap *regmap = fll->codec->core.regmap; in cs48l32_fllhj_apply()
1607 cs48l32_fll_dbg(fll, "fin=%d, fout=%d\n", fin, fll->fout); in cs48l32_fllhj_apply()
1615 fout = fll->fout; in cs48l32_fllhj_apply()
1662 return -EINVAL; in cs48l32_fllhj_apply()
1669 return -EINVAL; in cs48l32_fllhj_apply()
1687 cs48l32_fll_err(fll, "N not in valid %s mode range %d-%d: %d\n", in cs48l32_fllhj_apply()
1689 return -EINVAL; in cs48l32_fllhj_apply()
1694 return -EINVAL; in cs48l32_fllhj_apply()
1699 fll->base + CS48L32_FLL_CONTROL2_OFFS, in cs48l32_fllhj_apply()
1711 fll->base + CS48L32_FLL_CONTROL3_OFFS, in cs48l32_fllhj_apply()
1718 fll->base + CS48L32_FLL_CONTROL4_OFFS, in cs48l32_fllhj_apply()
1731 struct cs48l32 *cs48l32 = &fll->codec->core; in cs48l32_fllhj_enable()
1732 int already_enabled = cs48l32_is_enabled_fll(fll, fll->base); in cs48l32_fllhj_enable()
1739 pm_runtime_get_sync(cs48l32->dev); in cs48l32_fllhj_enable()
1745 regmap_set_bits(cs48l32->regmap, in cs48l32_fllhj_enable()
1746 fll->base + CS48L32_FLL_CONTROL1_OFFS, in cs48l32_fllhj_enable()
1750 ret = cs48l32_fllhj_apply(fll, fll->ref_freq); in cs48l32_fllhj_enable()
1755 regmap_update_bits(cs48l32->regmap, in cs48l32_fllhj_enable()
1756 fll->base + CS48L32_FLL_CONTROL2_OFFS, in cs48l32_fllhj_enable()
1758 fll->ref_src << CS48L32_FLL_REFCLK_SRC_SHIFT); in cs48l32_fllhj_enable()
1760 regmap_set_bits(cs48l32->regmap, in cs48l32_fllhj_enable()
1761 fll->base + CS48L32_FLL_CONTROL1_OFFS, in cs48l32_fllhj_enable()
1765 regmap_set_bits(cs48l32->regmap, in cs48l32_fllhj_enable()
1766 fll->base + CS48L32_FLL_CONTROL2_OFFS, in cs48l32_fllhj_enable()
1769 regmap_set_bits(cs48l32->regmap, in cs48l32_fllhj_enable()
1770 fll->base + CS48L32_FLL_CONTROL1_OFFS, in cs48l32_fllhj_enable()
1774 regmap_clear_bits(cs48l32->regmap, in cs48l32_fllhj_enable()
1775 fll->base + CS48L32_FLL_CONTROL1_OFFS, in cs48l32_fllhj_enable()
1790 return -EINVAL; in cs48l32_fllhj_validate()
1793 if (fll->fout && fout != fll->fout) { in cs48l32_fllhj_validate()
1795 return -EINVAL; in cs48l32_fllhj_validate()
1800 return -EINVAL; in cs48l32_fllhj_validate()
1806 return -EINVAL; in cs48l32_fllhj_validate()
1817 if (fll->ref_src == source && fll->ref_freq == fin && fll->fout == fout) in cs48l32_fllhj_set_refclk()
1821 return -EINVAL; in cs48l32_fllhj_set_refclk()
1823 fll->ref_src = source; in cs48l32_fllhj_set_refclk()
1824 fll->ref_freq = fin; in cs48l32_fllhj_set_refclk()
1825 fll->fout = fout; in cs48l32_fllhj_set_refclk()
1837 fll->ref_src = CS48L32_FLL_SRC_NONE; in cs48l32_init_fll()
1851 return -EINVAL; in cs48l32_set_fll()
1854 return cs48l32_fllhj_set_refclk(&cs48l32_codec->fll, source, fref, fout); in cs48l32_set_fll()
1859 struct snd_soc_component *component = dai->component; in cs48l32_asp_dai_probe()
1861 struct regmap *regmap = cs48l32_codec->core.regmap; in cs48l32_asp_dai_probe()
1864 switch (dai->id) { in cs48l32_asp_dai_probe()
1874 return -EINVAL; in cs48l32_asp_dai_probe()
1880 /* DOUT high-impendance when not transmitting */ in cs48l32_asp_dai_probe()
1888 struct snd_soc_component *component = dai->component; in cs48l32_set_fmt()
1890 struct regmap *regmap = cs48l32_codec->core.regmap; in cs48l32_set_fmt()
1892 unsigned int base = dai->driver->base; in cs48l32_set_fmt()
1905 return -EINVAL; in cs48l32_set_fmt()
1915 return -EINVAL; in cs48l32_set_fmt()
1922 return -EINVAL; in cs48l32_set_fmt()
1941 return -EINVAL; in cs48l32_set_fmt()
1958 return -EINVAL; in cs48l32_set_fmt()
2024 .list = cs48l32_sr_vals,
2029 struct snd_soc_component *component = dai->component; in cs48l32_startup()
2031 struct cs48l32_dai_priv *dai_priv = &cs48l32_codec->dai[dai->id - 1]; in cs48l32_startup()
2034 if (!substream->runtime) in cs48l32_startup()
2037 switch (dai_priv->clk) { in cs48l32_startup()
2042 base_rate = cs48l32_codec->sysclk; in cs48l32_startup()
2049 dai_priv->constraint.mask = CS48L32_RATE_MASK; in cs48l32_startup()
2051 dai_priv->constraint.mask = CS48L32_44K1_RATE_MASK; in cs48l32_startup()
2053 dai_priv->constraint.mask = CS48L32_48K_RATE_MASK; in cs48l32_startup()
2055 return snd_pcm_hw_constraint_list(substream->runtime, 0, in cs48l32_startup()
2057 &dai_priv->constraint); in cs48l32_startup()
2064 struct snd_soc_component *component = dai->component; in cs48l32_hw_params_rate()
2066 struct cs48l32_dai_priv *dai_priv = &cs48l32_codec->dai[dai->id - 1]; in cs48l32_hw_params_rate()
2076 return -EINVAL; in cs48l32_hw_params_rate()
2079 switch (dai_priv->clk) { in cs48l32_hw_params_rate()
2093 return -EINVAL; in cs48l32_hw_params_rate()
2130 struct snd_soc_component *component = dai->component; in cs48l32_hw_params()
2132 struct regmap *regmap = cs48l32_codec->core.regmap; in cs48l32_hw_params()
2133 int base = dai->driver->base; in cs48l32_hw_params()
2134 int dai_id = dai->id - 1; in cs48l32_hw_params()
2148 if (cs48l32_codec->tdm_slots[dai_id]) { in cs48l32_hw_params()
2149 n_slots = cs48l32_codec->tdm_slots[dai_id]; in cs48l32_hw_params()
2150 slotw = cs48l32_codec->tdm_width[dai_id]; in cs48l32_hw_params()
2178 return -EINVAL; in cs48l32_hw_params()
2240 struct snd_soc_component *component = dai->component; in cs48l32_dai_set_sysclk()
2242 struct cs48l32_dai_priv *dai_priv = &cs48l32_codec->dai[dai->id - 1]; in cs48l32_dai_set_sysclk()
2243 unsigned int base = dai->driver->base; in cs48l32_dai_set_sysclk()
2248 if (clk_id == dai_priv->clk) in cs48l32_dai_set_sysclk()
2253 return -EBUSY; in cs48l32_dai_set_sysclk()
2270 return -EINVAL; in cs48l32_dai_set_sysclk()
2273 dai_priv->clk = clk_id; in cs48l32_dai_set_sysclk()
2277 ret = regmap_read(cs48l32_codec->core.regmap, in cs48l32_dai_set_sysclk()
2289 mutex_lock(&cs48l32_codec->rate_lock); in cs48l32_dai_set_sysclk()
2299 mutex_unlock(&cs48l32_codec->rate_lock); in cs48l32_dai_set_sysclk()
2310 struct snd_soc_component *component = dai->component; in cs48l32_set_channels_to_mask()
2312 struct regmap *regmap = cs48l32_codec->core.regmap; in cs48l32_set_channels_to_mask()
2317 slot = ffs(mask) - 1; in cs48l32_set_channels_to_mask()
2321 if (i - (j * 4) >= 4) { in cs48l32_set_channels_to_mask()
2327 shift = (8 * (i - j * 4)); in cs48l32_set_channels_to_mask()
2344 struct snd_soc_component *component = dai->component; in cs48l32_set_tdm_slot()
2346 int base = dai->driver->base; in cs48l32_set_tdm_slot()
2347 int rx_max_chan = dai->driver->playback.channels_max; in cs48l32_set_tdm_slot()
2348 int tx_max_chan = dai->driver->capture.channels_max; in cs48l32_set_tdm_slot()
2351 if (dai->id > CS48L32_MAX_ASP) in cs48l32_set_tdm_slot()
2352 return -EINVAL; in cs48l32_set_tdm_slot()
2355 tx_mask = (1 << tx_max_chan) - 1; in cs48l32_set_tdm_slot()
2356 rx_mask = (1 << rx_max_chan) - 1; in cs48l32_set_tdm_slot()
2364 cs48l32_codec->tdm_width[dai->id - 1] = slot_width; in cs48l32_set_tdm_slot()
2365 cs48l32_codec->tdm_slots[dai->id - 1] = slots; in cs48l32_set_tdm_slot()
2382 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); in cs48l32_sysclk_ev()
2392 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); in cs48l32_in_ev()
2396 if (w->shift % 2) in cs48l32_in_ev()
2401 reg += (w->shift / 2) * (CS48L32_IN2L_CONTROL2 - CS48L32_IN1L_CONTROL2); in cs48l32_in_ev()
2405 switch (w->shift) { in cs48l32_in_ev()
2421 cs48l32_codec->in_up_pending++; in cs48l32_in_ev()
2426 switch (w->shift) { in cs48l32_in_ev()
2443 cs48l32_codec->in_up_pending--; in cs48l32_in_ev()
2446 /* Uncached write-only register, no need for update_bits */ in cs48l32_in_ev()
2447 if (!cs48l32_codec->in_up_pending) { in cs48l32_in_ev()
2448 snd_soc_component_write(component, cs48l32_codec->in_vu_reg, in cs48l32_in_ev()
2455 snd_soc_component_write(component, cs48l32_codec->in_vu_reg, in cs48l32_in_ev()
2477 * Uncached write-only register, no need for update_bits. in cs48l32_in_put_volsw()
2480 snd_soc_component_write(component, cs48l32_codec->in_vu_reg, CS48L32_IN_VU); in cs48l32_in_put_volsw()
2496 if (abs((a << 16) / (CS48L32_EQ_MAX_COEFF + 1 - b)) >= ((CS48L32_EQ_MAX_COEFF + 1) << 4)) in cs48l32_eq_filter_unstable()
2505 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); in cs48l32_eq_ev()
2507 struct regmap *regmap = cs48l32_codec->core.regmap; in cs48l32_eq_ev()
2508 unsigned int mode = cs48l32_codec->eq_mode[w->shift]; in cs48l32_eq_ev()
2510 __be16 *data = &cs48l32_codec->eq_coefficients[w->shift][0]; in cs48l32_eq_ev()
2514 reg += w->shift * (CS48L32_EQ2_BAND1_COEFF1 - CS48L32_EQ1_BAND1_COEFF1); in cs48l32_eq_ev()
2523 dev_err(cs48l32_codec->core.dev, "Rejecting unstable EQ coefficients.\n"); in cs48l32_eq_ev()
2524 ret = -EINVAL; in cs48l32_eq_ev()
2528 dev_err(cs48l32_codec->core.dev, in cs48l32_eq_ev()
2535 w->mask, in cs48l32_eq_ev()
2536 mode << w->shift); in cs48l32_eq_ev()
2538 dev_err(cs48l32_codec->core.dev, in cs48l32_eq_ev()
2616 SOC_ENUM("Ultrasonic 1 Detect LPF Cut-off", cs48l32_us_det_lpf_cut[0]),
2617 SOC_ENUM("Ultrasonic 2 Detect LPF Cut-off", cs48l32_us_det_lpf_cut[1]),
2818 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); in cs48l32_dsp_mem_ev()
2836 SND_SOC_DAPM_REGULATOR_SUPPLY("vdd-cp", 20, 0),
2876 SND_SOC_DAPM_MUX("IN1L Mux", SND_SOC_NOPM, 0, 0, &cs48l32_inmux[0]),
2877 SND_SOC_DAPM_MUX("IN1R Mux", SND_SOC_NOPM, 0, 0, &cs48l32_inmux[1]),
2991 /* end of ordered widget list */
3090 { "Voice Ctrl DSP", NULL, "DSP1" },
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" },
3152 { "IN1L Mode", "Analog", "IN1L Mux" },
3153 { "IN1R Mode", "Analog", "IN1R Mux" },
3286 struct snd_soc_pcm_runtime *rtd = stream->private_data; in cs48l32_compr_open()
3289 if (strcmp(snd_soc_rtd_to_codec(rtd, 0)->name, "cs48l32-dsp-trace") && in cs48l32_compr_open()
3290 strcmp(snd_soc_rtd_to_codec(rtd, 0)->name, "cs48l32-dsp-voicectrl")) { in cs48l32_compr_open()
3291 dev_err(cs48l32_codec->core.dev, "No suitable compressed stream for DAI '%s'\n", in cs48l32_compr_open()
3292 snd_soc_rtd_to_codec(rtd, 0)->name); in cs48l32_compr_open()
3293 return -EINVAL; in cs48l32_compr_open()
3296 return wm_adsp_compr_open(&cs48l32_codec->dsp, stream); in cs48l32_compr_open()
3315 .name = "cs48l32-asp1",
3337 .name = "cs48l32-asp2",
3359 .name = "cs48l32-cpu-trace",
3371 .name = "cs48l32-dsp-trace",
3382 .name = "cs48l32-cpu-voicectrl",
3385 .stream_name = "Voice Ctrl CPU",
3394 .name = "cs48l32-dsp-voicectrl",
3397 .stream_name = "Voice Ctrl DSP",
3409 struct regmap *regmap = cs48l32_codec->core.regmap; in cs48l32_init_inputs()
3415 * B settings will be applied if the mux is changed in cs48l32_init_inputs()
3417 switch (cs48l32_codec->in_type[0][0]) { in cs48l32_init_inputs()
3427 switch (cs48l32_codec->in_type[1][0]) { in cs48l32_init_inputs()
3437 dev_dbg(cs48l32_codec->core.dev, "IN1_1 Analogue mode=#%x,#%x\n", in cs48l32_init_inputs()
3450 for (i = 0; i < ARRAY_SIZE(cs48l32_codec->pdm_sup); i++) { in cs48l32_init_inputs()
3451 dig_mode = cs48l32_codec->pdm_sup[i] << CS48L32_IN1_PDM_SUP_SHIFT; in cs48l32_init_inputs()
3453 dev_dbg(cs48l32_codec->core.dev, "IN%d PDM_SUP=#%x\n", i + 1, dig_mode); in cs48l32_init_inputs()
3465 struct cs48l32_dai_priv *dai_priv = &cs48l32_codec->dai[id]; in cs48l32_init_dai()
3467 dai_priv->clk = CS48L32_CLK_SYSCLK_1; in cs48l32_init_dai()
3468 dai_priv->constraint = cs48l32_constraint; in cs48l32_init_dai()
3475 struct regmap *regmap = cs48l32_codec->core.regmap; in cs48l32_init_eq()
3482 dev_err(cs48l32_codec->core.dev, "Error reading EQ mode: %d\n", ret); in cs48l32_init_eq()
3487 cs48l32_codec->eq_mode[i] = (mode >> i) & 0x1; in cs48l32_init_eq()
3489 data = &cs48l32_codec->eq_coefficients[i][0]; in cs48l32_init_eq()
3493 dev_err(cs48l32_codec->core.dev, in cs48l32_init_eq()
3508 snd_soc_component_init_regmap(component, cs48l32_codec->core.regmap); in cs48l32_component_probe()
3521 wm_adsp2_component_probe(&cs48l32_codec->dsp, component); in cs48l32_component_probe()
3524 regmap_clear_bits(cs48l32_codec->core.regmap, CS48L32_IRQ1_MASK_7, in cs48l32_component_probe()
3526 regmap_clear_bits(cs48l32_codec->core.regmap, CS48L32_IRQ1_MASK_9, in cs48l32_component_probe()
3537 regmap_set_bits(cs48l32_codec->core.regmap, CS48L32_IRQ1_MASK_7, in cs48l32_component_remove()
3539 regmap_set_bits(cs48l32_codec->core.regmap, CS48L32_IRQ1_MASK_9, in cs48l32_component_remove()
3542 wm_adsp2_component_remove(&cs48l32_codec->dsp, component); in cs48l32_component_remove()
3550 .name = "cs48l32-codec",
3567 struct cs48l32 *cs48l32 = &cs48l32_codec->core; in cs48l32_prop_read_u32_array()
3570 ret = device_property_read_u32_array(cs48l32->dev, propname, dest, n_max); in cs48l32_prop_read_u32_array()
3571 if (ret == -EINVAL) in cs48l32_prop_read_u32_array()
3572 return -ENOENT; in cs48l32_prop_read_u32_array()
3575 return dev_err_probe(cs48l32->dev, ret, "%s malformed\n", propname); in cs48l32_prop_read_u32_array()
3582 const char *propname = "cirrus,in-type"; in cs48l32_prop_get_in_type()
3587 ARRAY_SIZE(cs48l32_codec->in_type) * ARRAY_SIZE(cs48l32_codec->in_type[0])); in cs48l32_prop_get_in_type()
3599 cs48l32_codec->in_type[in_idx][mux_way_idx] = tmp[i]; in cs48l32_prop_get_in_type()
3602 dev_warn(cs48l32_codec->core.dev, "Illegal %s value %d ignored\n", in cs48l32_prop_get_in_type()
3611 if (++in_idx == ARRAY_SIZE(cs48l32_codec->in_type)) { in cs48l32_prop_get_in_type()
3620 const char *propname = "cirrus,pdm-sup"; in cs48l32_prop_get_pdm_sup()
3624 static_assert(ARRAY_SIZE(tmp) == ARRAY_SIZE(cs48l32_codec->pdm_sup)); in cs48l32_prop_get_pdm_sup()
3628 for (i = 0; i < ARRAY_SIZE(cs48l32_codec->pdm_sup); i++) { in cs48l32_prop_get_pdm_sup()
3632 cs48l32_codec->pdm_sup[i] = tmp[i]; in cs48l32_prop_get_pdm_sup()
3635 dev_warn(cs48l32_codec->core.dev, "Illegal %s value %d ignored\n", in cs48l32_prop_get_pdm_sup()
3636 propname, cs48l32_codec->pdm_sup[i]); in cs48l32_prop_get_pdm_sup()
3650 int irq = cs48l32_codec->core.irq; in cs48l32_request_interrupt()
3664 return dev_err_probe(cs48l32_codec->core.dev, ret, "Failed to get IRQ\n"); in cs48l32_request_interrupt()
3675 static_assert(ARRAY_SIZE(cs48l32_dai) == ARRAY_SIZE(cs48l32_codec->dai)); in cs48l32_create_codec_component()
3679 dsp = &cs48l32_codec->dsp; in cs48l32_create_codec_component()
3680 dsp->part = "cs48l32"; in cs48l32_create_codec_component()
3681 dsp->cs_dsp.num = 1; in cs48l32_create_codec_component()
3682 dsp->cs_dsp.type = WMFW_HALO; in cs48l32_create_codec_component()
3683 dsp->cs_dsp.rev = 0; in cs48l32_create_codec_component()
3684 dsp->cs_dsp.dev = cs48l32_codec->core.dev; in cs48l32_create_codec_component()
3685 dsp->cs_dsp.regmap = cs48l32_codec->core.regmap; in cs48l32_create_codec_component()
3686 dsp->cs_dsp.base = CS48L32_DSP1_CLOCK_FREQ; in cs48l32_create_codec_component()
3687 dsp->cs_dsp.base_sysinfo = CS48L32_DSP1_SYS_INFO_ID; in cs48l32_create_codec_component()
3688 dsp->cs_dsp.mem = cs48l32_dsp1_regions; in cs48l32_create_codec_component()
3689 dsp->cs_dsp.num_mems = ARRAY_SIZE(cs48l32_dsp1_regions); in cs48l32_create_codec_component()
3690 dsp->pre_run = cs48l32_dsp_pre_run; in cs48l32_create_codec_component()
3696 cs48l32_codec->fll.codec = cs48l32_codec; in cs48l32_create_codec_component()
3697 cs48l32_codec->fll.id = 1; in cs48l32_create_codec_component()
3698 cs48l32_codec->fll.base = CS48L32_FLL1_CONTROL1; in cs48l32_create_codec_component()
3699 cs48l32_codec->fll.sts_addr = CS48L32_IRQ1_STS_6; in cs48l32_create_codec_component()
3700 cs48l32_codec->fll.sts_mask = CS48L32_FLL1_LOCK_STS1_MASK; in cs48l32_create_codec_component()
3701 cs48l32_init_fll(&cs48l32_codec->fll); in cs48l32_create_codec_component()
3707 ret = devm_snd_soc_register_component(cs48l32_codec->core.dev, in cs48l32_create_codec_component()
3712 dev_err_probe(cs48l32_codec->core.dev, ret, "Failed to register component\n"); in cs48l32_create_codec_component()
3719 wm_adsp2_remove(&cs48l32_codec->dsp); in cs48l32_create_codec_component()
3729 ret = regmap_read_poll_timeout(cs48l32->regmap, CS48L32_IRQ1_EINT_2, val, in cs48l32_wait_for_boot()
3733 dev_err(cs48l32->dev, "BOOT_DONE timed out\n"); in cs48l32_wait_for_boot()
3734 return -ETIMEDOUT; in cs48l32_wait_for_boot()
3737 ret = regmap_read(cs48l32->regmap, CS48L32_MCU_CTRL1, &val); in cs48l32_wait_for_boot()
3739 dev_err(cs48l32->dev, "Failed to read MCU_CTRL1: %d\n", ret); in cs48l32_wait_for_boot()
3744 dev_err(cs48l32->dev, "MCU boot failed\n"); in cs48l32_wait_for_boot()
3745 return -EIO; in cs48l32_wait_for_boot()
3748 pm_runtime_mark_last_busy(cs48l32->dev); in cs48l32_wait_for_boot()
3757 ret = regmap_write(cs48l32->regmap, CS48L32_SFT_RESET, CS48L32_SFT_RESET_MAGIC); in cs48l32_soft_reset()
3759 dev_err(cs48l32->dev, "Failed to write soft reset: %d\n", ret); in cs48l32_soft_reset()
3770 if (cs48l32->reset_gpio) in cs48l32_enable_hard_reset()
3771 gpiod_set_raw_value_cansleep(cs48l32->reset_gpio, 0); in cs48l32_enable_hard_reset()
3776 if (cs48l32->reset_gpio) { in cs48l32_disable_hard_reset()
3777 gpiod_set_raw_value_cansleep(cs48l32->reset_gpio, 1); in cs48l32_disable_hard_reset()
3785 struct cs48l32 *cs48l32 = &cs48l32_codec->core; in cs48l32_runtime_resume()
3789 ret = regulator_enable(cs48l32->vdd_d); in cs48l32_runtime_resume()
3791 dev_err(cs48l32->dev, "Failed to enable VDD_D: %d\n", ret); in cs48l32_runtime_resume()
3797 regcache_cache_only(cs48l32->regmap, false); in cs48l32_runtime_resume()
3804 regmap_read(cs48l32->regmap, CS48L32_CTRL_IF_DEBUG3, &val); in cs48l32_runtime_resume()
3806 regcache_mark_dirty(cs48l32->regmap); in cs48l32_runtime_resume()
3808 dev_dbg(cs48l32->dev, "Did not reset during suspend\n"); in cs48l32_runtime_resume()
3810 ret = regcache_sync(cs48l32->regmap); in cs48l32_runtime_resume()
3812 dev_err(cs48l32->dev, "Failed to restore register cache\n"); in cs48l32_runtime_resume()
3819 regcache_cache_only(cs48l32->regmap, true); in cs48l32_runtime_resume()
3820 regulator_disable(cs48l32->vdd_d); in cs48l32_runtime_resume()
3828 struct cs48l32 *cs48l32 = &cs48l32_codec->core; in cs48l32_runtime_suspend()
3831 regmap_write(cs48l32->regmap, CS48L32_CTRL_IF_DEBUG3, 1); in cs48l32_runtime_suspend()
3833 regcache_cache_only(cs48l32->regmap, true); in cs48l32_runtime_suspend()
3834 regulator_disable(cs48l32->vdd_d); in cs48l32_runtime_suspend()
3847 ret = clk_prepare_enable(cs48l32->mclk1); in cs48l32_configure_clk32k()
3849 return dev_err_probe(cs48l32->dev, ret, "Failed to enable 32k clock\n"); in cs48l32_configure_clk32k()
3851 ret = regmap_update_bits(cs48l32->regmap, CS48L32_CLOCK32K, in cs48l32_configure_clk32k()
3855 clk_disable_unprepare(cs48l32->mclk1); in cs48l32_configure_clk32k()
3856 return dev_err_probe(cs48l32->dev, ret, "Failed to init 32k clock\n"); in cs48l32_configure_clk32k()
3864 cs48l32->mclk1 = devm_clk_get_optional(cs48l32->dev, "mclk1"); in cs48l32_get_clocks()
3865 if (IS_ERR(cs48l32->mclk1)) in cs48l32_get_clocks()
3866 return dev_err_probe(cs48l32->dev, PTR_ERR(cs48l32->mclk1), in cs48l32_get_clocks()
3876 reset = devm_gpiod_get_optional(cs48l32->dev, "reset", GPIOD_OUT_LOW); in cs48l32_get_reset_gpio()
3878 return dev_err_probe(cs48l32->dev, PTR_ERR(reset), "Failed to request /RESET\n"); in cs48l32_get_reset_gpio()
3883 cs48l32->reset_gpio = reset; in cs48l32_get_reset_gpio()
3890 struct device *dev = &spi->dev; in cs48l32_spi_probe()
3896 cs48l32_codec = devm_kzalloc(&spi->dev, sizeof(*cs48l32_codec), GFP_KERNEL); in cs48l32_spi_probe()
3898 return -ENOMEM; in cs48l32_spi_probe()
3900 cs48l32 = &cs48l32_codec->core; in cs48l32_spi_probe()
3901 cs48l32->dev = dev; in cs48l32_spi_probe()
3902 cs48l32->irq = spi->irq; in cs48l32_spi_probe()
3903 mutex_init(&cs48l32_codec->rate_lock); in cs48l32_spi_probe()
3904 cs48l32_codec->in_vu_reg = CS48L32_INPUT_CONTROL3; in cs48l32_spi_probe()
3906 dev_set_drvdata(cs48l32->dev, cs48l32_codec); in cs48l32_spi_probe()
3910 return dev_err_probe(&spi->dev, ret, "Failed to allocate regmap\n"); in cs48l32_spi_probe()
3912 regcache_cache_only(cs48l32->regmap, true); in cs48l32_spi_probe()
3922 static_assert(ARRAY_SIZE(cs48l32_core_supplies) == ARRAY_SIZE(cs48l32->core_supplies)); in cs48l32_spi_probe()
3923 for (i = 0; i < ARRAY_SIZE(cs48l32->core_supplies); i++) in cs48l32_spi_probe()
3924 cs48l32->core_supplies[i].supply = cs48l32_core_supplies[i]; in cs48l32_spi_probe()
3926 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(cs48l32->core_supplies), in cs48l32_spi_probe()
3927 cs48l32->core_supplies); in cs48l32_spi_probe()
3931 cs48l32->vdd_d = devm_regulator_get(cs48l32->dev, "vdd-d"); in cs48l32_spi_probe()
3932 if (IS_ERR(cs48l32->vdd_d)) in cs48l32_spi_probe()
3933 return dev_err_probe(dev, PTR_ERR(cs48l32->vdd_d), "Failed to request vdd-d\n"); in cs48l32_spi_probe()
3935 ret = regulator_bulk_enable(ARRAY_SIZE(cs48l32->core_supplies), cs48l32->core_supplies); in cs48l32_spi_probe()
3939 ret = regulator_enable(cs48l32->vdd_d); in cs48l32_spi_probe()
3941 dev_err(dev, "Failed to enable vdd-d: %d\n", ret); in cs48l32_spi_probe()
3947 regcache_cache_only(cs48l32->regmap, false); in cs48l32_spi_probe()
3950 if (!cs48l32->reset_gpio) { in cs48l32_spi_probe()
3958 dev_err(cs48l32->dev, "Device failed initial boot: %d\n", ret); in cs48l32_spi_probe()
3962 ret = regmap_read(cs48l32->regmap, CS48L32_DEVID, &hwid); in cs48l32_spi_probe()
3973 ret = -ENODEV; in cs48l32_spi_probe()
3974 dev_err_probe(cs48l32->dev, ret, "Unknown device ID: %#x\n", hwid); in cs48l32_spi_probe()
3978 ret = regmap_read(cs48l32->regmap, CS48L32_REVID, &rev); in cs48l32_spi_probe()
3985 ret = regmap_read(cs48l32->regmap, CS48L32_OTPID, &otp_rev); in cs48l32_spi_probe()
3998 dev_err(cs48l32->dev, "Failed to apply patch %d\n", ret); in cs48l32_spi_probe()
4003 ret = regmap_set_bits(cs48l32->regmap, CS48L32_IRQ1_MASK_2, CS48L32_BOOT_DONE_EINT1_MASK); in cs48l32_spi_probe()
4009 pm_runtime_set_active(cs48l32->dev); in cs48l32_spi_probe()
4010 pm_runtime_set_autosuspend_delay(cs48l32->dev, 100); in cs48l32_spi_probe()
4011 pm_runtime_use_autosuspend(cs48l32->dev); in cs48l32_spi_probe()
4012 pm_runtime_enable(cs48l32->dev); in cs48l32_spi_probe()
4021 clk_disable_unprepare(cs48l32->mclk1); in cs48l32_spi_probe()
4024 regulator_disable(cs48l32->vdd_d); in cs48l32_spi_probe()
4026 regulator_bulk_disable(ARRAY_SIZE(cs48l32->core_supplies), cs48l32->core_supplies); in cs48l32_spi_probe()
4034 struct cs48l32 *cs48l32 = &cs48l32_codec->core; in cs48l32_spi_remove()
4037 if (cs48l32->irq >= 1) in cs48l32_spi_remove()
4038 free_irq(cs48l32->irq, cs48l32_codec); in cs48l32_spi_remove()
4040 pm_runtime_disable(cs48l32->dev); in cs48l32_spi_remove()
4041 regulator_disable(cs48l32->vdd_d); in cs48l32_spi_remove()
4042 clk_disable_unprepare(cs48l32->mclk1); in cs48l32_spi_remove()
4044 regulator_bulk_disable(ARRAY_SIZE(cs48l32->core_supplies), cs48l32->core_supplies); in cs48l32_spi_remove()
4046 mutex_destroy(&cs48l32_codec->rate_lock); in cs48l32_spi_remove()