Lines Matching +full:tx +full:- +full:clk +full:- +full:10 +full:- +full:inverted

1 // SPDX-License-Identifier: GPL-2.0-only
3 * wm8960.c -- WM8960 ALSA SoC Audio driver
5 * Copyright 2007-11 Wolfson Microelectronics, plc
15 #include <linux/clk.h>
29 /* R25 - Power 1 */
33 /* R26 - Power 2 */
38 /* R28 - Anti-pop 1 */
45 /* R29 - Anti-pop 2 */
133 struct clk *mclk;
155 static const char *wm8960_polarity[] = {"No Inversion", "Left Inverted",
156 "Right Inverted", "Stereo Inversion"};
192 if (wm8960->deemph) {
195 if (abs(deemph_settings[i] - wm8960->lrclk) <
196 abs(deemph_settings[best] - wm8960->lrclk))
205 dev_dbg(component->dev, "Set deemphasis %d\n", val);
217 ucontrol->value.integer.value[0] = wm8960->deemph;
226 unsigned int deemph = ucontrol->value.integer.value[0];
229 return -EINVAL;
231 wm8960->deemph = deemph;
236 static const DECLARE_TLV_DB_SCALE(adc_tlv, -9750, 50, 1);
237 static const DECLARE_TLV_DB_SCALE(inpga_tlv, -1725, 75, 0);
238 static const DECLARE_TLV_DB_SCALE(dac_tlv, -12750, 50, 1);
239 static const DECLARE_TLV_DB_SCALE(bypass_tlv, -2100, 300, 0);
240 static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1);
241 static const DECLARE_TLV_DB_SCALE(lineinboost_tlv, -1500, 300, 1);
283 SOC_SINGLE("PCM Playback -6dB Switch", WM8960_DACCTL1, 7, 1, 0),
291 SOC_ENUM("3D Filter Upper Cut-Off", wm8960_enum[2]),
292 SOC_ENUM("3D Filter Lower Cut-Off", wm8960_enum[3]),
490 struct wm8960_data *pdata = &wm8960->pdata;
502 if (pdata && pdata->capless) {
521 list_for_each_entry(w, &component->card->widgets, list) {
522 if (w->dapm != dapm)
524 if (strcmp(w->name, "LOUT1 PGA") == 0)
525 wm8960->lout1 = w;
526 if (strcmp(w->name, "ROUT1 PGA") == 0)
527 wm8960->rout1 = w;
528 if (strcmp(w->name, "OUT3 VMID") == 0)
529 wm8960->out3 = w;
538 struct snd_soc_component *component = codec_dai->component;
549 return -EINVAL;
569 return -EINVAL;
586 return -EINVAL;
609 /* -1 for reserved value */
610 static const int sysclk_divs[] = { 1, -1, 2, -1 };
615 /* Multiply 10 to eliminate decimials */
617 10, 15, 20, 30, 40, 55, 60, 80, 110,
622 * wm8960_configure_sysclk - checks if there is a sysclk frequency available
624 * - sysclk = MCLK / sysclk_divs
625 * - lrclk = sysclk / dac_divs
626 * - 10 * bclk = sysclk / bclk_divs
635 * -1, in case no sysclk frequency available found
648 *bclk_idx = -1;
650 bclk = wm8960->bclk;
651 lrclk = wm8960->lrclk;
655 if (sysclk_divs[i] == -1)
662 diff = sysclk - bclk * bclk_divs[k] / 10;
680 * wm8960_configure_pll - checks if there is a PLL out frequency available
682 * - sysclk = lrclk * dac_divs
683 * - freq_out = sysclk * sysclk_divs
684 * - 10 * sysclk = bclk * bclk_divs
710 bclk = wm8960->bclk;
711 lrclk = wm8960->lrclk;
714 best_freq_out = -EINVAL;
715 *sysclk_idx = *dac_idx = *bclk_idx = -1;
723 for (i = ARRAY_SIZE(sysclk_divs) - 1; i >= 0; --i) {
724 if (sysclk_divs[i] == -1)
734 diff = sysclk - bclk * bclk_divs[k] / 10;
766 * compatible issue, just add '!wm8960->sysclk' condition in
769 if (!(iface1 & (1 << 6)) && !wm8960->sysclk) {
770 dev_warn(component->dev,
775 if (wm8960->clk_id != WM8960_SYSCLK_MCLK && !wm8960->freq_in) {
776 dev_err(component->dev, "No MCLK configured\n");
777 return -EINVAL;
780 freq_in = wm8960->freq_in;
787 if (wm8960->clk_id == WM8960_SYSCLK_AUTO) {
791 } else if (wm8960->sysclk) {
792 freq_out = wm8960->sysclk;
794 dev_err(component->dev, "No SYSCLK configured\n");
795 return -EINVAL;
798 if (wm8960->clk_id != WM8960_SYSCLK_PLL) {
802 } else if (wm8960->clk_id != WM8960_SYSCLK_AUTO) {
803 dev_err(component->dev, "failed to configure clock\n");
804 return -EINVAL;
810 dev_err(component->dev, "failed to configure clock via PLL\n");
833 struct snd_soc_component *component = dai->component;
836 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
839 wm8960->bclk = snd_soc_params_to_bclk(params);
841 wm8960->bclk *= 2;
861 dev_err(component->dev, "unsupported width %d\n",
863 return -EINVAL;
866 wm8960->lrclk = params_rate(params);
868 if (tx) {
881 wm8960->is_stream_in_use[tx] = true;
883 if (!wm8960->is_stream_in_use[!tx])
892 struct snd_soc_component *component = dai->component;
894 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
896 wm8960->is_stream_in_use[tx] = false;
903 struct snd_soc_component *component = dai->component;
927 if (!IS_ERR(wm8960->mclk)) {
928 ret = clk_prepare_enable(wm8960->mclk);
930 dev_err(component->dev,
950 if (wm8960->clk_id == WM8960_SYSCLK_AUTO && (pm2 & 0x1))
953 if (!IS_ERR(wm8960->mclk))
954 clk_disable_unprepare(wm8960->mclk);
966 tout = WM8960_DSCH_TOUT - ktime_ms_delta(ktime_get(), wm8960->dsch_start);
970 regcache_sync(wm8960->regmap);
972 /* Enable anti-pop features */
985 /* Disable anti-pop features */
994 /* Enable anti-pop features */
1001 wm8960->dsch_start = ktime_get();
1031 if (wm8960->lout1 && wm8960->lout1->power)
1033 if (wm8960->rout1 && wm8960->rout1->power)
1035 if (wm8960->out3 && wm8960->out3->power)
1055 if (!IS_ERR(wm8960->mclk)) {
1056 ret = clk_prepare_enable(wm8960->mclk);
1058 dev_err(component->dev,
1076 if (wm8960->clk_id == WM8960_SYSCLK_AUTO && (pm2 & 0x1))
1079 if (!IS_ERR(wm8960->mclk))
1080 clk_disable_unprepare(wm8960->mclk);
1082 /* Enable anti-pop mode */
1095 regcache_sync(wm8960->regmap);
1110 /* Disable anti-pop features */
1159 /* The size in bits of the pll divide multiplied by 10
1161 #define FIXED_PLL_SIZE ((1 << 24) * 10)
1169 pr_debug("WM8960 PLL: setting %dHz->%dHz\n", source, target);
1177 pll_div->pre_div = 1;
1180 pll_div->pre_div = 0;
1184 return -EINVAL;
1187 pll_div->n = Ndiv;
1196 if ((K % 10) >= 5)
1200 K /= 10;
1202 pll_div->k = K;
1205 pll_div->n, pll_div->k, pll_div->pre_div);
1255 struct snd_soc_component *component = codec_dai->component;
1258 wm8960->freq_in = freq_in;
1269 struct snd_soc_component *component = codec_dai->component;
1294 return -EINVAL;
1305 return wm8960->set_bias_level(component, level);
1311 struct snd_soc_component *component = dai->component;
1326 return -EINVAL;
1329 wm8960->sysclk = freq;
1330 wm8960->clk_id = clk_id;
1353 .name = "wm8960-hifi",
1373 struct wm8960_data *pdata = &wm8960->pdata;
1375 if (pdata->capless)
1376 wm8960->set_bias_level = wm8960_set_bias_level_capless;
1378 wm8960->set_bias_level = wm8960_set_bias_level_out3;
1411 const struct device_node *np = i2c->dev.of_node;
1414 pdata->capless = true;
1416 if (of_property_read_bool(np, "wlf,shared-lrclk"))
1417 pdata->shared_lrclk = true;
1419 of_property_read_u32_array(np, "wlf,gpio-cfg", pdata->gpio_cfg,
1420 ARRAY_SIZE(pdata->gpio_cfg));
1422 of_property_read_u32_array(np, "wlf,hp-cfg", pdata->hp_cfg,
1423 ARRAY_SIZE(pdata->hp_cfg));
1428 struct wm8960_data *pdata = dev_get_platdata(&i2c->dev);
1434 wm8960 = devm_kzalloc(&i2c->dev, sizeof(struct wm8960_priv),
1437 return -ENOMEM;
1439 wm8960->mclk = devm_clk_get(&i2c->dev, "mclk");
1440 if (IS_ERR(wm8960->mclk)) {
1441 if (PTR_ERR(wm8960->mclk) == -EPROBE_DEFER)
1442 return -EPROBE_DEFER;
1444 ret = clk_get_rate(wm8960->mclk);
1446 wm8960->freq_in = ret;
1448 dev_err(&i2c->dev, "Failed to read MCLK rate: %d\n",
1453 for (i = 0; i < ARRAY_SIZE(wm8960->supplies); i++)
1454 wm8960->supplies[i].supply = wm8960_supply_names[i];
1456 ret = devm_regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8960->supplies),
1457 wm8960->supplies);
1459 dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret);
1463 ret = regulator_bulk_enable(ARRAY_SIZE(wm8960->supplies),
1464 wm8960->supplies);
1466 dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret);
1470 wm8960->regmap = devm_regmap_init_i2c(i2c, &wm8960_regmap);
1471 if (IS_ERR(wm8960->regmap)) {
1472 ret = PTR_ERR(wm8960->regmap);
1477 memcpy(&wm8960->pdata, pdata, sizeof(struct wm8960_data));
1478 else if (i2c->dev.of_node)
1479 wm8960_set_pdata_from_of(i2c, &wm8960->pdata);
1483 dev_err(&i2c->dev, "Not wm8960, wm8960 reg can not read by i2c\n");
1484 ret = -EINVAL;
1488 ret = wm8960_reset(wm8960->regmap);
1490 dev_err(&i2c->dev, "Failed to issue reset\n");
1494 if (wm8960->pdata.shared_lrclk) {
1495 ret = regmap_update_bits(wm8960->regmap, WM8960_ADDCTL2,
1498 dev_err(&i2c->dev, "Failed to enable LRCM: %d\n",
1505 regmap_update_bits(wm8960->regmap, WM8960_LINVOL, 0x100, 0x100);
1506 regmap_update_bits(wm8960->regmap, WM8960_RINVOL, 0x100, 0x100);
1507 regmap_update_bits(wm8960->regmap, WM8960_LADC, 0x100, 0x100);
1508 regmap_update_bits(wm8960->regmap, WM8960_RADC, 0x100, 0x100);
1509 regmap_update_bits(wm8960->regmap, WM8960_LDAC, 0x100, 0x100);
1510 regmap_update_bits(wm8960->regmap, WM8960_RDAC, 0x100, 0x100);
1511 regmap_update_bits(wm8960->regmap, WM8960_LOUT1, 0x100, 0x100);
1512 regmap_update_bits(wm8960->regmap, WM8960_ROUT1, 0x100, 0x100);
1513 regmap_update_bits(wm8960->regmap, WM8960_LOUT2, 0x100, 0x100);
1514 regmap_update_bits(wm8960->regmap, WM8960_ROUT2, 0x100, 0x100);
1517 regmap_update_bits(wm8960->regmap, WM8960_IFACE2, 1 << 6,
1518 wm8960->pdata.gpio_cfg[0] << 6);
1519 regmap_update_bits(wm8960->regmap, WM8960_ADDCTL4, 0xF << 4,
1520 wm8960->pdata.gpio_cfg[1] << 4);
1523 regmap_update_bits(wm8960->regmap, WM8960_ADDCTL4, 3 << 2,
1524 wm8960->pdata.hp_cfg[0] << 2);
1525 regmap_update_bits(wm8960->regmap, WM8960_ADDCTL2, 3 << 5,
1526 wm8960->pdata.hp_cfg[1] << 5);
1527 regmap_update_bits(wm8960->regmap, WM8960_ADDCTL1, 3,
1528 wm8960->pdata.hp_cfg[2]);
1532 ret = devm_snd_soc_register_component(&i2c->dev,
1540 regulator_bulk_disable(ARRAY_SIZE(wm8960->supplies), wm8960->supplies);
1548 regulator_bulk_disable(ARRAY_SIZE(wm8960->supplies), wm8960->supplies);