Lines Matching +full:tdm +full:- +full:data +full:- +full:out

1 // SPDX-License-Identifier: GPL-2.0
3 // ak4613.c -- Asahi Kasei ALSA Soc Audio driver
14 * +-------+
16 * SDTO1 <-| |
18 * SDTI1 ->| |
19 * SDTI2 ->| |
20 * SDTI3 ->| |
21 * +-------+
23 * +---+
66 * Tested TDM is very limited.
68 * +-----+ +-----------+
70 * | |<-----|SDTO1 IN1|<-- Mic
73 * | |----->|SDTI1 OUT1|--> Headphone
74 * +-----+ |SDTI2 OUT2|
79 * +-----------+
91 * (*) it used 8ch data between SoC <-> AK4613 on TDM256 mode,
115 #define DEMP1 0x05 /* De-emphasis1 */
116 #define DEMP2 0x06 /* De-emphasis2 */
175 #define AK4613_CONFIG_SET(priv, x) priv->configs |= AK4613_CONFIG_##x
176 #define AK4613_CONFIG_GET(priv, x) (priv->configs & AK4613_CONFIG_##x##_MASK)
206 * Because of testable HW limitation, TDM256 8ch TDM was only tested.
242 * min : 0xFE : -127.0 dB
245 static const DECLARE_TLV_DB_SCALE(out_tlv, -12750, 50, 1);
288 #define AK4613_CTRL1_TO_MODE(priv) ((priv)->ctrl1 >> 6) /* AK4613_CONFIG_MODE_x */
300 { .compatible = "asahi-kasei,ak4613", .data = &ak4613_regmap_cfg },
383 struct snd_soc_component *component = dai->component; in ak4613_dai_shutdown()
385 struct device *dev = component->dev; in ak4613_dai_shutdown()
387 mutex_lock(&priv->lock); in ak4613_dai_shutdown()
388 priv->cnt--; in ak4613_dai_shutdown()
389 if (priv->cnt < 0) { in ak4613_dai_shutdown()
391 priv->cnt = 0; in ak4613_dai_shutdown()
393 if (!priv->cnt) in ak4613_dai_shutdown()
394 priv->ctrl1 = 0; in ak4613_dai_shutdown()
395 mutex_unlock(&priv->lock); in ak4613_dai_shutdown()
401 struct snd_pcm_runtime *runtime = substream->runtime; in ak4613_hw_constraints()
416 #define AK4613_CHANNEL_NONE -1 in ak4613_hw_constraints()
437 int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; in ak4613_hw_constraints()
441 constraint = &priv->constraint_rates; in ak4613_hw_constraints()
442 constraint->list = ak4613_rates; in ak4613_hw_constraints()
443 constraint->mask = 0; in ak4613_hw_constraints()
444 constraint->count = 0; in ak4613_hw_constraints()
461 if (priv->sysclk >= ak4613_rates[i] * fs) in ak4613_hw_constraints()
462 constraint->count = i + 1; in ak4613_hw_constraints()
473 if (priv->cnt) { in ak4613_hw_constraints()
496 constraint = &priv->constraint_channels; in ak4613_hw_constraints()
497 constraint->list = ak4613_channels; in ak4613_hw_constraints()
498 constraint->mask = mask; in ak4613_hw_constraints()
499 constraint->count = sizeof(ak4613_channels); in ak4613_hw_constraints()
507 struct snd_soc_component *component = dai->component; in ak4613_dai_startup()
510 mutex_lock(&priv->lock); in ak4613_dai_startup()
512 priv->cnt++; in ak4613_dai_startup()
513 mutex_unlock(&priv->lock); in ak4613_dai_startup()
521 struct snd_soc_component *component = codec_dai->component; in ak4613_dai_set_sysclk()
524 priv->sysclk = freq; in ak4613_dai_set_sysclk()
531 struct snd_soc_component *component = dai->component; in ak4613_dai_set_fmt()
539 priv->fmt = fmt; in ak4613_dai_set_fmt()
542 return -EINVAL; in ak4613_dai_set_fmt()
555 return -EINVAL; in ak4613_dai_set_fmt()
565 struct snd_soc_component *component = dai->component; in ak4613_dai_hw_params()
567 struct device *dev = component->dev; in ak4613_dai_hw_params()
569 unsigned int fmt = priv->fmt; in ak4613_dai_hw_params()
591 return -EINVAL; in ak4613_dai_hw_params()
593 priv->rate = rate; in ak4613_dai_hw_params()
598 * It doesn't have full TDM suppert yet in ak4613_dai_hw_params()
600 ret = -EINVAL; in ak4613_dai_hw_params()
602 mutex_lock(&priv->lock); in ak4613_dai_hw_params()
603 if (priv->cnt > 1) { in ak4613_dai_hw_params()
605 * If it was already working, use current priv->ctrl1 in ak4613_dai_hw_params()
613 u8 tdm; in ak4613_dai_hw_params() local
615 /* STEREO or TDM */ in ak4613_dai_hw_params()
617 tdm = AK4613_CONFIG_MODE_STEREO; in ak4613_dai_hw_params()
619 tdm = AK4613_CONFIG_GET(priv, MODE); in ak4613_dai_hw_params()
621 for (i = ARRAY_SIZE(ak4613_iface) - 1; i >= 0; i--) { in ak4613_dai_hw_params()
624 if ((iface->fmt == fmt) && (iface->width == width)) { in ak4613_dai_hw_params()
629 * < tdm > < iface->dif > in ak4613_dai_hw_params()
631 priv->ctrl1 = (tdm << 6) | (iface->dif << 3); in ak4613_dai_hw_params()
637 mutex_unlock(&priv->lock); in ak4613_dai_hw_params()
642 snd_soc_component_update_bits(component, CTRL1, FMT_MASK, priv->ctrl1); in ak4613_dai_hw_params()
645 snd_soc_component_update_bits(component, ICTRL, ICTRL_MASK, priv->ic); in ak4613_dai_hw_params()
646 snd_soc_component_update_bits(component, OCTRL, OCTRL_MASK, priv->oc); in ak4613_dai_hw_params()
650 dev_warn(dev, "unsupported data width/format combination\n"); in ak4613_dai_hw_params()
685 struct snd_soc_component *component = priv->component; in ak4613_dummy_write()
700 udelay(5000000 / priv->rate); in ak4613_dummy_write()
712 struct snd_soc_component *component = dai->component; in ak4613_dai_trigger()
742 if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK) in ak4613_dai_trigger()
745 priv->component = component; in ak4613_dai_trigger()
746 schedule_work(&priv->dummy_write_work); in ak4613_dai_trigger()
782 .name = "ak4613-hifi",
803 struct regmap *regmap = dev_get_regmap(component->dev, NULL); in ak4613_suspend()
812 struct regmap *regmap = dev_get_regmap(component->dev, NULL); in ak4613_resume()
835 struct device_node *np = dev->of_node; in ak4613_parse_of()
840 /* Input 1 - 2 */ in ak4613_parse_of()
842 snprintf(prop, sizeof(prop), "asahi-kasei,in%d-single-end", i + 1); in ak4613_parse_of()
844 priv->ic |= 1 << i; in ak4613_parse_of()
847 /* Output 1 - 6 */ in ak4613_parse_of()
849 snprintf(prop, sizeof(prop), "asahi-kasei,out%d-single-end", i + 1); in ak4613_parse_of()
851 priv->oc |= 1 << i; in ak4613_parse_of()
870 * TDM support is assuming it is probed via Audio-Graph-Card style here. in ak4613_parse_of()
871 * Default is SDTIx1 if it was probed via Simple-Audio-Card for now. in ak4613_parse_of()
882 struct device *dev = &i2c->dev; in ak4613_i2c_probe()
889 return -EINVAL; in ak4613_i2c_probe()
893 return -ENOMEM; in ak4613_i2c_probe()
897 priv->ctrl1 = 0; in ak4613_i2c_probe()
898 priv->cnt = 0; in ak4613_i2c_probe()
899 priv->sysclk = 0; in ak4613_i2c_probe()
900 INIT_WORK(&priv->dummy_write_work, ak4613_dummy_write); in ak4613_i2c_probe()
902 mutex_init(&priv->lock); in ak4613_i2c_probe()
916 .name = "ak4613-codec",