Lines Matching +full:tdm +full:- +full:data +full:- +full:delay
1 // SPDX-License-Identifier: GPL-2.0
5 * Copyright (C) 2015-2017 Texas Instruments Incorporated - https://www.ti.com
13 #include <linux/delay.h>
29 "avdd", /* Analog power supply. Connect to 3.3-V supply. */
30 "dvdd", /* Digital power supply. Connect to 3.3-V supply. */
31 "iovdd", /* I/O power supply. Connect to 3.3-V or 1.8-V. */
44 static const DECLARE_TLV_DB_SCALE(pcm186x_pga_tlv, -1200, 50, 0);
48 PCM186X_PGA_VAL_CH1_R, 0, -24, 80, 7, 0,
54 PCM186X_PGA_VAL_CH1_R, 0, -24, 80, 7, 0,
57 PCM186X_PGA_VAL_CH2_R, 0, -24, 80, 7, 0,
264 struct snd_soc_component *component = dai->component; in pcm186x_hw_params()
275 dev_dbg(component->dev, "%s() rate=%u format=0x%x width=%u channels=%u\n", in pcm186x_hw_params()
304 return -EINVAL; in pcm186x_hw_params()
314 if (priv->is_tdm_mode) { in pcm186x_hw_params()
315 /* Select TDM transmission data */ in pcm186x_hw_params()
327 return -EINVAL; in pcm186x_hw_params()
333 /* In DSP/TDM mode, the LRCLK divider must be 256 */ in pcm186x_hw_params()
343 if (priv->is_provider_mode) { in pcm186x_hw_params()
344 div_bck = priv->sysclk / (div_lrck * rate); in pcm186x_hw_params()
346 dev_dbg(component->dev, in pcm186x_hw_params()
348 __func__, priv->sysclk, div_bck, div_lrck); in pcm186x_hw_params()
350 snd_soc_component_write(component, PCM186X_BCK_DIV, div_bck - 1); in pcm186x_hw_params()
351 snd_soc_component_write(component, PCM186X_LRK_DIV, div_lrck - 1); in pcm186x_hw_params()
359 struct snd_soc_component *component = dai->component; in pcm186x_set_fmt()
364 dev_dbg(component->dev, "%s() format=0x%x\n", __func__, format); in pcm186x_set_fmt()
368 if (!priv->sysclk) { in pcm186x_set_fmt()
369 dev_err(component->dev, "operating in provider mode requires sysclock to be configured\n"); in pcm186x_set_fmt()
370 return -EINVAL; in pcm186x_set_fmt()
373 priv->is_provider_mode = true; in pcm186x_set_fmt()
376 priv->is_provider_mode = false; in pcm186x_set_fmt()
379 dev_err(component->dev, "Invalid DAI master/slave interface\n"); in pcm186x_set_fmt()
380 return -EINVAL; in pcm186x_set_fmt()
388 dev_err(component->dev, "Inverted DAI clocks not supported\n"); in pcm186x_set_fmt()
389 return -EINVAL; in pcm186x_set_fmt()
401 priv->tdm_offset += 1; in pcm186x_set_fmt()
404 * except we need to shift the TDM output by one BCK cycle in pcm186x_set_fmt()
407 priv->is_tdm_mode = true; in pcm186x_set_fmt()
411 dev_err(component->dev, "Invalid DAI format\n"); in pcm186x_set_fmt()
412 return -EINVAL; in pcm186x_set_fmt()
418 snd_soc_component_write(component, PCM186X_TDM_TX_OFFSET, priv->tdm_offset); in pcm186x_set_fmt()
429 struct snd_soc_component *component = dai->component; in pcm186x_set_tdm_slot()
433 dev_dbg(component->dev, in pcm186x_set_tdm_slot()
438 dev_err(component->dev, "tdm tx mask must not be 0\n"); in pcm186x_set_tdm_slot()
439 return -EINVAL; in pcm186x_set_tdm_slot()
445 if (last_slot - first_slot != hweight32(tx_mask) - 1) { in pcm186x_set_tdm_slot()
446 dev_err(component->dev, "tdm tx mask must be contiguous\n"); in pcm186x_set_tdm_slot()
447 return -EINVAL; in pcm186x_set_tdm_slot()
453 dev_err(component->dev, "tdm tx slot selection out of bounds\n"); in pcm186x_set_tdm_slot()
454 return -EINVAL; in pcm186x_set_tdm_slot()
457 priv->tdm_offset = tdm_offset; in pcm186x_set_tdm_slot()
465 struct snd_soc_component *component = dai->component; in pcm186x_set_dai_sysclk()
468 dev_dbg(component->dev, "%s() clk_id=%d freq=%u dir=%d\n", in pcm186x_set_dai_sysclk()
471 priv->sysclk = freq; in pcm186x_set_dai_sysclk()
484 .name = "pcm1863-aif",
496 .name = "pcm1865-aif",
512 ret = regulator_bulk_enable(ARRAY_SIZE(priv->supplies), in pcm186x_power_on()
513 priv->supplies); in pcm186x_power_on()
517 regcache_cache_only(priv->regmap, false); in pcm186x_power_on()
518 ret = regcache_sync(priv->regmap); in pcm186x_power_on()
520 dev_err(component->dev, "Failed to restore cache\n"); in pcm186x_power_on()
521 regcache_cache_only(priv->regmap, true); in pcm186x_power_on()
522 regulator_bulk_disable(ARRAY_SIZE(priv->supplies), in pcm186x_power_on()
523 priv->supplies); in pcm186x_power_on()
540 regcache_cache_only(priv->regmap, true); in pcm186x_power_off()
542 return regulator_bulk_disable(ARRAY_SIZE(priv->supplies), in pcm186x_power_off()
543 priv->supplies); in pcm186x_power_off()
549 dev_dbg(component->dev, "## %s: %d -> %d\n", __func__, in pcm186x_set_bias_level()
644 return -ENOMEM; in pcm186x_probe()
647 priv->regmap = regmap; in pcm186x_probe()
649 for (i = 0; i < ARRAY_SIZE(priv->supplies); i++) in pcm186x_probe()
650 priv->supplies[i].supply = pcm186x_supply_names[i]; in pcm186x_probe()
652 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(priv->supplies), in pcm186x_probe()
653 priv->supplies); in pcm186x_probe()
659 ret = regulator_bulk_enable(ARRAY_SIZE(priv->supplies), in pcm186x_probe()
660 priv->supplies); in pcm186x_probe()
666 /* Reset device registers for a consistent power-on like state */ in pcm186x_probe()
673 ret = regulator_bulk_disable(ARRAY_SIZE(priv->supplies), in pcm186x_probe()
674 priv->supplies); in pcm186x_probe()