mirror of
https://github.com/torvalds/linux.git
synced 2024-09-21 07:23:06 +00:00
ASoC: Intel: maxim-common: rewrite max_98373_hw_params function
Rewrite max_98373_hw_params() function to get tdm slot number from topology in runtime because earlier platforms use 4-slot setting instead of 8. Also check if the interface is configured in TDM mode before calling snd_soc_dai_set_tdm_slot() function. Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com> Signed-off-by: Brent Lu <brent.lu@intel.com> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Link: https://msgid.link/r/20240527193552.165567-17-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
97a9e9915c
commit
459d71f147
|
@ -9,6 +9,7 @@
|
|||
#include <sound/soc-acpi.h>
|
||||
#include <sound/soc-dai.h>
|
||||
#include <sound/soc-dapm.h>
|
||||
#include <sound/sof.h>
|
||||
#include <uapi/sound/asound.h>
|
||||
#include "../common/soc-intel-quirks.h"
|
||||
#include "sof_maxim_common.h"
|
||||
|
@ -72,26 +73,85 @@ static struct snd_soc_dai_link_component max_98373_components[] = {
|
|||
},
|
||||
};
|
||||
|
||||
/*
|
||||
* According to the definition of 'DAI Sel Mux' mixer in max98373.c, rx mask
|
||||
* should choose two channels from TDM slots, the LSB of rx mask is left channel
|
||||
* and the other one is right channel.
|
||||
*
|
||||
* For tx mask, each codec requires two channels: one for V-sense and the other
|
||||
* one for I-sense. Must match the device property "maxim,vmon-slot-no" and
|
||||
* "maxim,imon-slot-no" in ACPI table.
|
||||
*/
|
||||
static const struct {
|
||||
unsigned int tx;
|
||||
unsigned int rx;
|
||||
} max_98373_tdm_mask[] = {
|
||||
{.tx = 0x03, .rx = 0x3},
|
||||
{.tx = 0x0c, .rx = 0x3},
|
||||
};
|
||||
|
||||
static int max_98373_hw_params(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
|
||||
struct snd_soc_dai_link *dai_link = rtd->dai_link;
|
||||
struct snd_soc_dai *codec_dai;
|
||||
int i;
|
||||
int tdm_slots;
|
||||
int ret = 0;
|
||||
int j;
|
||||
|
||||
for_each_rtd_codec_dais(rtd, j, codec_dai) {
|
||||
if (!strcmp(codec_dai->component->name, MAX_98373_DEV0_NAME)) {
|
||||
/* DEV0 tdm slot configuration */
|
||||
ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x03, 3, 8, 32);
|
||||
} else if (!strcmp(codec_dai->component->name, MAX_98373_DEV1_NAME)) {
|
||||
/* DEV1 tdm slot configuration */
|
||||
ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x0C, 3, 8, 32);
|
||||
for_each_rtd_codec_dais(rtd, i, codec_dai) {
|
||||
if (i >= ARRAY_SIZE(max_98373_tdm_mask)) {
|
||||
dev_err(codec_dai->dev, "only 2 amps are supported\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (ret < 0) {
|
||||
dev_err(codec_dai->dev, "fail to set tdm slot, ret %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
|
||||
switch (dai_link->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
|
||||
case SND_SOC_DAIFMT_DSP_A:
|
||||
case SND_SOC_DAIFMT_DSP_B:
|
||||
/* get the tplg configured tdm slot number */
|
||||
tdm_slots = sof_dai_get_tdm_slots(rtd);
|
||||
if (tdm_slots <= 0) {
|
||||
dev_err(rtd->dev, "invalid tdm slots %d\n",
|
||||
tdm_slots);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* check if tdm slot number is too small for channel
|
||||
* allocation
|
||||
*/
|
||||
if (fls(max_98373_tdm_mask[i].tx) > tdm_slots) {
|
||||
dev_err(codec_dai->dev, "slot mismatch, tx %d slots %d\n",
|
||||
fls(max_98373_tdm_mask[i].tx), tdm_slots);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (fls(max_98373_tdm_mask[i].rx) > tdm_slots) {
|
||||
dev_err(codec_dai->dev, "slot mismatch, rx %d slots %d\n",
|
||||
fls(max_98373_tdm_mask[i].rx), tdm_slots);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dev_dbg(codec_dai->dev, "set tdm slot: tx 0x%x rx 0x%x slots %d width %d\n",
|
||||
max_98373_tdm_mask[i].tx,
|
||||
max_98373_tdm_mask[i].rx,
|
||||
tdm_slots, params_width(params));
|
||||
|
||||
ret = snd_soc_dai_set_tdm_slot(codec_dai,
|
||||
max_98373_tdm_mask[i].tx,
|
||||
max_98373_tdm_mask[i].rx,
|
||||
tdm_slots,
|
||||
params_width(params));
|
||||
if (ret < 0) {
|
||||
dev_err(codec_dai->dev, "fail to set tdm slot, ret %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
dev_dbg(codec_dai->dev, "codec is in I2S mode\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
|
Loading…
Reference in New Issue
Block a user