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>
30 "avdd", /* Analog power supply. Connect to 3.3-V supply. */
31 "dvdd", /* Digital power supply. Connect to 3.3-V supply. */
32 "iovdd", /* I/O power supply. Connect to 3.3-V or 1.8-V. */
45 static const DECLARE_TLV_DB_SCALE(pcm186x_pga_tlv, -1200, 50, 0);
49 PCM186X_PGA_VAL_CH1_R, 0, -24, 80, 7, 0,
55 PCM186X_PGA_VAL_CH1_R, 0, -24, 80, 7, 0,
58 PCM186X_PGA_VAL_CH2_R, 0, -24, 80, 7, 0,
265 struct snd_soc_component *component = dai->component; in pcm186x_hw_params()
276 dev_dbg(component->dev, "%s() rate=%u format=0x%x width=%u channels=%u\n", in pcm186x_hw_params()
305 return -EINVAL; in pcm186x_hw_params()
315 if (priv->is_tdm_mode) { in pcm186x_hw_params()
316 /* Select TDM transmission data */ in pcm186x_hw_params()
328 return -EINVAL; in pcm186x_hw_params()
334 /* In DSP/TDM mode, the LRCLK divider must be 256 */ in pcm186x_hw_params()
344 if (priv->is_provider_mode) { in pcm186x_hw_params()
345 div_bck = priv->sysclk / (div_lrck * rate); in pcm186x_hw_params()
347 dev_dbg(component->dev, in pcm186x_hw_params()
349 __func__, priv->sysclk, div_bck, div_lrck); in pcm186x_hw_params()
351 snd_soc_component_write(component, PCM186X_BCK_DIV, div_bck - 1); in pcm186x_hw_params()
352 snd_soc_component_write(component, PCM186X_LRK_DIV, div_lrck - 1); in pcm186x_hw_params()
360 struct snd_soc_component *component = dai->component; in pcm186x_set_fmt()
365 dev_dbg(component->dev, "%s() format=0x%x\n", __func__, format); in pcm186x_set_fmt()
369 if (!priv->sysclk) { in pcm186x_set_fmt()
370 dev_err(component->dev, "operating in provider mode requires sysclock to be configured\n"); in pcm186x_set_fmt()
371 return -EINVAL; in pcm186x_set_fmt()
374 priv->is_provider_mode = true; in pcm186x_set_fmt()
377 priv->is_provider_mode = false; in pcm186x_set_fmt()
380 dev_err(component->dev, "Invalid DAI master/slave interface\n"); in pcm186x_set_fmt()
381 return -EINVAL; in pcm186x_set_fmt()
389 dev_err(component->dev, "Inverted DAI clocks not supported\n"); in pcm186x_set_fmt()
390 return -EINVAL; in pcm186x_set_fmt()
402 priv->tdm_offset += 1; in pcm186x_set_fmt()
405 * except we need to shift the TDM output by one BCK cycle in pcm186x_set_fmt()
408 priv->is_tdm_mode = true; in pcm186x_set_fmt()
412 dev_err(component->dev, "Invalid DAI format\n"); in pcm186x_set_fmt()
413 return -EINVAL; in pcm186x_set_fmt()
419 snd_soc_component_write(component, PCM186X_TDM_TX_OFFSET, priv->tdm_offset); in pcm186x_set_fmt()
430 struct snd_soc_component *component = dai->component; in pcm186x_set_tdm_slot()
434 dev_dbg(component->dev, in pcm186x_set_tdm_slot()
439 dev_err(component->dev, "tdm tx mask must not be 0\n"); in pcm186x_set_tdm_slot()
440 return -EINVAL; in pcm186x_set_tdm_slot()
446 if (last_slot - first_slot != hweight32(tx_mask) - 1) { in pcm186x_set_tdm_slot()
447 dev_err(component->dev, "tdm tx mask must be contiguous\n"); in pcm186x_set_tdm_slot()
448 return -EINVAL; in pcm186x_set_tdm_slot()
454 dev_err(component->dev, "tdm tx slot selection out of bounds\n"); in pcm186x_set_tdm_slot()
455 return -EINVAL; in pcm186x_set_tdm_slot()
458 priv->tdm_offset = tdm_offset; in pcm186x_set_tdm_slot()
466 struct snd_soc_component *component = dai->component; in pcm186x_set_dai_sysclk()
469 dev_dbg(component->dev, "%s() clk_id=%d freq=%u dir=%d\n", in pcm186x_set_dai_sysclk()
472 priv->sysclk = freq; in pcm186x_set_dai_sysclk()
485 .name = "pcm1863-aif",
497 .name = "pcm1865-aif",
513 ret = regulator_bulk_enable(ARRAY_SIZE(priv->supplies), in pcm186x_power_on()
514 priv->supplies); in pcm186x_power_on()
518 regcache_cache_only(priv->regmap, false); in pcm186x_power_on()
519 ret = regcache_sync(priv->regmap); in pcm186x_power_on()
521 dev_err(component->dev, "Failed to restore cache\n"); in pcm186x_power_on()
522 regcache_cache_only(priv->regmap, true); in pcm186x_power_on()
523 regulator_bulk_disable(ARRAY_SIZE(priv->supplies), in pcm186x_power_on()
524 priv->supplies); in pcm186x_power_on()
541 regcache_cache_only(priv->regmap, true); in pcm186x_power_off()
543 return regulator_bulk_disable(ARRAY_SIZE(priv->supplies), in pcm186x_power_off()
544 priv->supplies); in pcm186x_power_off()
550 dev_dbg(component->dev, "## %s: %d -> %d\n", __func__, in pcm186x_set_bias_level()
645 return -ENOMEM; in pcm186x_probe()
648 priv->regmap = regmap; in pcm186x_probe()
650 for (i = 0; i < ARRAY_SIZE(priv->supplies); i++) in pcm186x_probe()
651 priv->supplies[i].supply = pcm186x_supply_names[i]; in pcm186x_probe()
653 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(priv->supplies), in pcm186x_probe()
654 priv->supplies); in pcm186x_probe()
660 ret = regulator_bulk_enable(ARRAY_SIZE(priv->supplies), in pcm186x_probe()
661 priv->supplies); in pcm186x_probe()
667 /* Reset device registers for a consistent power-on like state */ in pcm186x_probe()
674 ret = regulator_bulk_disable(ARRAY_SIZE(priv->supplies), in pcm186x_probe()
675 priv->supplies); in pcm186x_probe()