Lines Matching +full:codec +full:- +full:aif3 +full:- +full:lrclk
1 // SPDX-License-Identifier: GPL-2.0-only
3 * wm8995.c -- WM8995 ALSA SoC Audio driver
26 #include <sound/soc-dapm.h>
400 regcache_mark_dirty(wm8995->regmap); \
414 static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1);
415 static const DECLARE_TLV_DB_SCALE(in1lr_pga_tlv, -1650, 150, 0);
417 static const DECLARE_TLV_DB_SCALE(sidetone_tlv, -3600, 150, 0);
420 "Differential", "Single-ended IN1LN", "Single-ended IN1LP"
427 "Differential", "Single-ended IN1RN", "Single-ended IN1RP"
495 dev_dbg(component->dev, "Class W source AIF2DAC\n"); in wm8995_update_class_w()
499 dev_dbg(component->dev, "Class W source AIF1DAC2\n"); in wm8995_update_class_w()
503 dev_dbg(component->dev, "Class W source AIF1DAC1\n"); in wm8995_update_class_w()
507 dev_dbg(component->dev, "DAC mixer setting: %x\n", reg); in wm8995_update_class_w()
514 dev_dbg(component->dev, "Left and right DAC mixers different\n"); in wm8995_update_class_w()
519 dev_dbg(component->dev, "Class W enabled\n"); in wm8995_update_class_w()
525 dev_dbg(component->dev, "Class W disabled\n"); in wm8995_update_class_w()
534 struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm); in check_clk_sys()
561 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); in hp_supply_event()
593 dev_dbg(component->dev, "%s: reg = %#x, val = %#x, mask = %#x\n", in dc_servo_cmd()
597 while (timeout--) { in dc_servo_cmd()
604 dev_err(component->dev, "Timed out waiting for DC Servo\n"); in dc_servo_cmd()
610 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); in hp_event()
683 switch (wm8995->sysclk[aif]) { in configure_aif_clock()
685 rate = wm8995->mclk[0]; in configure_aif_clock()
689 rate = wm8995->mclk[1]; in configure_aif_clock()
693 rate = wm8995->fll[0].out; in configure_aif_clock()
697 rate = wm8995->fll[1].out; in configure_aif_clock()
700 return -EINVAL; in configure_aif_clock()
707 dev_dbg(component->dev, "Dividing AIF%d clock to %dHz\n", in configure_aif_clock()
711 wm8995->aifclk[aif] = rate; in configure_aif_clock()
739 if (wm8995->aifclk[0] == wm8995->aifclk[1]) in configure_clock()
742 if (wm8995->aifclk[0] < wm8995->aifclk[1]) in configure_clock()
760 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); in clk_sys_event()
1422 struct snd_soc_component *component = dai->component; in wm8995_aif_mute()
1425 switch (dai->id) { in wm8995_aif_mute()
1433 return -EINVAL; in wm8995_aif_mute()
1447 component = dai->component; in wm8995_set_dai_fmt()
1457 dev_err(dai->dev, "Unknown master/slave configuration\n"); in wm8995_set_dai_fmt()
1458 return -EINVAL; in wm8995_set_dai_fmt()
1478 dev_err(dai->dev, "Unknown dai format\n"); in wm8995_set_dai_fmt()
1479 return -EINVAL; in wm8995_set_dai_fmt()
1493 return -EINVAL; in wm8995_set_dai_fmt()
1513 return -EINVAL; in wm8995_set_dai_fmt()
1517 return -EINVAL; in wm8995_set_dai_fmt()
1535 -1 /* reserved */,
1555 int lrclk, bclk; in wm8995_hw_params() local
1558 component = dai->component; in wm8995_hw_params()
1561 switch (dai->id) { in wm8995_hw_params()
1566 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK /* || in wm8995_hw_params()
1567 wm8995->lrclk_shared[0] */) { in wm8995_hw_params()
1571 dev_dbg(component->dev, "AIF1 using split LRCLK\n"); in wm8995_hw_params()
1578 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK /* || in wm8995_hw_params()
1579 wm8995->lrclk_shared[1] */) { in wm8995_hw_params()
1583 dev_dbg(component->dev, "AIF2 using split LRCLK\n"); in wm8995_hw_params()
1587 return -EINVAL; in wm8995_hw_params()
1608 dev_err(dai->dev, "Unsupported word length %u\n", in wm8995_hw_params()
1610 return -EINVAL; in wm8995_hw_params()
1618 dev_err(dai->dev, "Sample rate %d is not supported\n", in wm8995_hw_params()
1620 return -EINVAL; in wm8995_hw_params()
1624 dev_dbg(dai->dev, "Sample rate is %dHz\n", srs[i]); in wm8995_hw_params()
1625 dev_dbg(dai->dev, "AIF%dCLK is %dHz, target BCLK %dHz\n", in wm8995_hw_params()
1626 dai->id + 1, wm8995->aifclk[dai->id], bclk_rate); in wm8995_hw_params()
1631 - wm8995->aifclk[dai->id]); in wm8995_hw_params()
1634 - wm8995->aifclk[dai->id]); in wm8995_hw_params()
1642 dev_dbg(dai->dev, "Selected AIF%dCLK/fs = %d\n", in wm8995_hw_params()
1643 dai->id + 1, fs_ratios[best]); in wm8995_hw_params()
1654 cur_val = (wm8995->aifclk[dai->id] * 10 / bclk_divs[i]) - bclk_rate; in wm8995_hw_params()
1661 bclk_rate = wm8995->aifclk[dai->id] * 10 / bclk_divs[best]; in wm8995_hw_params()
1662 dev_dbg(dai->dev, "Using BCLK_DIV %d for actual BCLK %dHz\n", in wm8995_hw_params()
1665 lrclk = bclk_rate / params_rate(params); in wm8995_hw_params()
1666 dev_dbg(dai->dev, "Using LRCLK rate %d for actual LRCLK %dHz\n", in wm8995_hw_params()
1667 lrclk, bclk_rate / lrclk); in wm8995_hw_params()
1674 WM8995_AIF1DAC_RATE_MASK, lrclk); in wm8995_hw_params()
1683 struct snd_soc_component *component = codec_dai->component; in wm8995_set_tristate()
1686 switch (codec_dai->id) { in wm8995_set_tristate()
1700 return -EINVAL; in wm8995_set_tristate()
1732 fll->clk_ref_div = 0; in wm8995_get_fll_config()
1734 fll->clk_ref_div++; in wm8995_get_fll_config()
1737 if (fll->clk_ref_div > 3) in wm8995_get_fll_config()
1738 return -EINVAL; in wm8995_get_fll_config()
1740 pr_debug("CLK_REF_DIV=%d, Fref=%dHz\n", fll->clk_ref_div, freq_in); in wm8995_get_fll_config()
1743 fll->outdiv = 3; in wm8995_get_fll_config()
1744 while (freq_out * (fll->outdiv + 1) < 90000000) { in wm8995_get_fll_config()
1745 fll->outdiv++; in wm8995_get_fll_config()
1746 if (fll->outdiv > 63) in wm8995_get_fll_config()
1747 return -EINVAL; in wm8995_get_fll_config()
1749 freq_out *= fll->outdiv + 1; in wm8995_get_fll_config()
1750 pr_debug("OUTDIV=%d, Fvco=%dHz\n", fll->outdiv, freq_out); in wm8995_get_fll_config()
1753 fll->fll_fratio = 0; in wm8995_get_fll_config()
1755 fll->fll_fratio = 1; in wm8995_get_fll_config()
1758 fll->fll_fratio = 2; in wm8995_get_fll_config()
1761 fll->fll_fratio = 3; in wm8995_get_fll_config()
1764 fll->fll_fratio = 4; in wm8995_get_fll_config()
1767 pr_debug("FLL_FRATIO=%d, Fref=%dHz\n", fll->fll_fratio, freq_in); in wm8995_get_fll_config()
1772 fll->n = Ndiv; in wm8995_get_fll_config()
1776 /* Calculate fractional part - scale up so we can round. */ in wm8995_get_fll_config()
1787 fll->k = K / 10; in wm8995_get_fll_config()
1789 pr_debug("N=%x K=%x\n", fll->n, fll->k); in wm8995_get_fll_config()
1804 component = dai->component; in wm8995_set_fll()
1823 return -EINVAL; in wm8995_set_fll()
1830 return -EINVAL; in wm8995_set_fll()
1838 return -EINVAL; in wm8995_set_fll()
1842 if (wm8995->fll[id].src == src && in wm8995_set_fll()
1843 wm8995->fll[id].in == freq_in && wm8995->fll[id].out == freq_out) in wm8995_set_fll()
1846 /* If we're stopping the FLL redo the old config - no in wm8995_set_fll()
1853 ret = wm8995_get_fll_config(&fll, wm8995->fll[id].in, in wm8995_set_fll()
1854 wm8995->fll[id].out); in wm8995_set_fll()
1884 (src - 1)); in wm8995_set_fll()
1890 wm8995->fll[id].in = freq_in; in wm8995_set_fll()
1891 wm8995->fll[id].out = freq_out; in wm8995_set_fll()
1892 wm8995->fll[id].src = src; in wm8995_set_fll()
1911 component = dai->component; in wm8995_set_dai_sysclk()
1914 switch (dai->id) { in wm8995_set_dai_sysclk()
1919 /* AIF3 shares clocking with AIF1/2 */ in wm8995_set_dai_sysclk()
1920 return -EINVAL; in wm8995_set_dai_sysclk()
1925 wm8995->sysclk[dai->id] = WM8995_SYSCLK_MCLK1; in wm8995_set_dai_sysclk()
1926 wm8995->mclk[0] = freq; in wm8995_set_dai_sysclk()
1927 dev_dbg(dai->dev, "AIF%d using MCLK1 at %uHz\n", in wm8995_set_dai_sysclk()
1928 dai->id + 1, freq); in wm8995_set_dai_sysclk()
1931 wm8995->sysclk[dai->id] = WM8995_SYSCLK_MCLK2; in wm8995_set_dai_sysclk()
1932 wm8995->mclk[1] = freq; in wm8995_set_dai_sysclk()
1933 dev_dbg(dai->dev, "AIF%d using MCLK2 at %uHz\n", in wm8995_set_dai_sysclk()
1934 dai->id + 1, freq); in wm8995_set_dai_sysclk()
1937 wm8995->sysclk[dai->id] = WM8995_SYSCLK_FLL1; in wm8995_set_dai_sysclk()
1938 dev_dbg(dai->dev, "AIF%d using FLL1\n", dai->id + 1); in wm8995_set_dai_sysclk()
1941 wm8995->sysclk[dai->id] = WM8995_SYSCLK_FLL2; in wm8995_set_dai_sysclk()
1942 dev_dbg(dai->dev, "AIF%d using FLL2\n", dai->id + 1); in wm8995_set_dai_sysclk()
1946 dev_err(dai->dev, "Unknown clock source %d\n", clk_id); in wm8995_set_dai_sysclk()
1947 return -EINVAL; in wm8995_set_dai_sysclk()
1968 ret = regulator_bulk_enable(ARRAY_SIZE(wm8995->supplies), in wm8995_set_bias_level()
1969 wm8995->supplies); in wm8995_set_bias_level()
1973 ret = regcache_sync(wm8995->regmap); in wm8995_set_bias_level()
1975 dev_err(component->dev, in wm8995_set_bias_level()
1987 regulator_bulk_disable(ARRAY_SIZE(wm8995->supplies), in wm8995_set_bias_level()
1988 wm8995->supplies); in wm8995_set_bias_level()
2002 wm8995->component = component; in wm8995_probe()
2004 for (i = 0; i < ARRAY_SIZE(wm8995->supplies); i++) in wm8995_probe()
2005 wm8995->supplies[i].supply = wm8995_supply_names[i]; in wm8995_probe()
2007 ret = devm_regulator_bulk_get(component->dev, in wm8995_probe()
2008 ARRAY_SIZE(wm8995->supplies), in wm8995_probe()
2009 wm8995->supplies); in wm8995_probe()
2011 dev_err(component->dev, "Failed to request supplies: %d\n", ret); in wm8995_probe()
2015 wm8995->disable_nb[0].notifier_call = wm8995_regulator_event_0; in wm8995_probe()
2016 wm8995->disable_nb[1].notifier_call = wm8995_regulator_event_1; in wm8995_probe()
2017 wm8995->disable_nb[2].notifier_call = wm8995_regulator_event_2; in wm8995_probe()
2018 wm8995->disable_nb[3].notifier_call = wm8995_regulator_event_3; in wm8995_probe()
2019 wm8995->disable_nb[4].notifier_call = wm8995_regulator_event_4; in wm8995_probe()
2020 wm8995->disable_nb[5].notifier_call = wm8995_regulator_event_5; in wm8995_probe()
2021 wm8995->disable_nb[6].notifier_call = wm8995_regulator_event_6; in wm8995_probe()
2022 wm8995->disable_nb[7].notifier_call = wm8995_regulator_event_7; in wm8995_probe()
2025 for (i = 0; i < ARRAY_SIZE(wm8995->supplies); i++) { in wm8995_probe()
2027 wm8995->supplies[i].consumer, in wm8995_probe()
2028 &wm8995->disable_nb[i]); in wm8995_probe()
2030 dev_err(component->dev, in wm8995_probe()
2036 ret = regulator_bulk_enable(ARRAY_SIZE(wm8995->supplies), in wm8995_probe()
2037 wm8995->supplies); in wm8995_probe()
2039 dev_err(component->dev, "Failed to enable supplies: %d\n", ret); in wm8995_probe()
2045 dev_err(component->dev, "Failed to read device ID: %d\n", ret); in wm8995_probe()
2050 dev_err(component->dev, "Invalid device ID: %#x\n", ret); in wm8995_probe()
2051 ret = -EINVAL; in wm8995_probe()
2057 dev_err(component->dev, "Failed to issue reset: %d\n", ret); in wm8995_probe()
2086 regulator_bulk_disable(ARRAY_SIZE(wm8995->supplies), wm8995->supplies); in wm8995_probe()
2119 .name = "wm8995-aif1",
2137 .name = "wm8995-aif2",
2155 .name = "wm8995-aif3",
2157 .stream_name = "AIF3 Playback",
2164 .stream_name = "AIF3 Capture",
2205 wm8995 = devm_kzalloc(&spi->dev, sizeof(*wm8995), GFP_KERNEL); in wm8995_spi_probe()
2207 return -ENOMEM; in wm8995_spi_probe()
2211 wm8995->regmap = devm_regmap_init_spi(spi, &wm8995_regmap); in wm8995_spi_probe()
2212 if (IS_ERR(wm8995->regmap)) { in wm8995_spi_probe()
2213 ret = PTR_ERR(wm8995->regmap); in wm8995_spi_probe()
2214 dev_err(&spi->dev, "Failed to register regmap: %d\n", ret); in wm8995_spi_probe()
2218 ret = devm_snd_soc_register_component(&spi->dev, in wm8995_spi_probe()
2238 wm8995 = devm_kzalloc(&i2c->dev, sizeof(*wm8995), GFP_KERNEL); in wm8995_i2c_probe()
2240 return -ENOMEM; in wm8995_i2c_probe()
2244 wm8995->regmap = devm_regmap_init_i2c(i2c, &wm8995_regmap); in wm8995_i2c_probe()
2245 if (IS_ERR(wm8995->regmap)) { in wm8995_i2c_probe()
2246 ret = PTR_ERR(wm8995->regmap); in wm8995_i2c_probe()
2247 dev_err(&i2c->dev, "Failed to register regmap: %d\n", ret); in wm8995_i2c_probe()
2251 ret = devm_snd_soc_register_component(&i2c->dev, in wm8995_i2c_probe()
2255 dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret); in wm8995_i2c_probe()