Merge "ASoC: sdm845: update TDM configurations for TX and RX"
This commit is contained in:
commit
3d0e2dec05
2 changed files with 72 additions and 231 deletions
|
@ -6535,26 +6535,12 @@ static int msm_dai_q6_tdm_set_sysclk(struct snd_soc_dai *dai,
|
|||
struct msm_dai_q6_tdm_dai_data *dai_data =
|
||||
dev_get_drvdata(dai->dev);
|
||||
|
||||
switch (dai->id) {
|
||||
case AFE_PORT_ID_QUATERNARY_TDM_RX:
|
||||
case AFE_PORT_ID_QUATERNARY_TDM_RX_1:
|
||||
case AFE_PORT_ID_QUATERNARY_TDM_RX_2:
|
||||
case AFE_PORT_ID_QUATERNARY_TDM_RX_3:
|
||||
case AFE_PORT_ID_QUATERNARY_TDM_RX_4:
|
||||
case AFE_PORT_ID_QUATERNARY_TDM_RX_5:
|
||||
case AFE_PORT_ID_QUATERNARY_TDM_RX_6:
|
||||
case AFE_PORT_ID_QUATERNARY_TDM_RX_7:
|
||||
case AFE_PORT_ID_QUATERNARY_TDM_TX:
|
||||
case AFE_PORT_ID_QUATERNARY_TDM_TX_1:
|
||||
case AFE_PORT_ID_QUATERNARY_TDM_TX_2:
|
||||
case AFE_PORT_ID_QUATERNARY_TDM_TX_3:
|
||||
case AFE_PORT_ID_QUATERNARY_TDM_TX_4:
|
||||
case AFE_PORT_ID_QUATERNARY_TDM_TX_5:
|
||||
case AFE_PORT_ID_QUATERNARY_TDM_TX_6:
|
||||
case AFE_PORT_ID_QUATERNARY_TDM_TX_7:
|
||||
if ((dai->id >= AFE_PORT_ID_PRIMARY_TDM_RX) &&
|
||||
(dai->id <= AFE_PORT_ID_QUINARY_TDM_TX_7)) {
|
||||
dai_data->clk_set.clk_freq_in_hz = freq;
|
||||
break;
|
||||
default:
|
||||
} else {
|
||||
dev_err(dai->dev, "%s: invalid dai id 0x%x\n",
|
||||
__func__, dai->id);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
279
asoc/sdm845.c
279
asoc/sdm845.c
|
@ -70,7 +70,6 @@
|
|||
#define WCN_CDC_SLIM_TX_CH_MAX 3
|
||||
|
||||
#define TDM_CHANNEL_MAX 8
|
||||
#define TDM_SLOT_OFFSET_MAX 8
|
||||
|
||||
#define MSM_HIFI_ON 1
|
||||
|
||||
|
@ -311,17 +310,6 @@ static struct dev_config tdm_tx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = {
|
|||
}
|
||||
};
|
||||
|
||||
/*TDM default offset currently only supporting TDM_RX_0 and TDM_TX_0 */
|
||||
static unsigned int tdm_slot_offset[TDM_PORT_MAX][TDM_SLOT_OFFSET_MAX] = {
|
||||
{0, 4, 8, 12, 16, 20, 24, 28},/* TX_0 | RX_0 */
|
||||
{AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_1 | RX_1 */
|
||||
{AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_2 | RX_2 */
|
||||
{AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_3 | RX_3 */
|
||||
{AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_4 | RX_4 */
|
||||
{AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_5 | RX_5 */
|
||||
{AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_6 | RX_6 */
|
||||
{AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_7 | RX_7 */
|
||||
};
|
||||
|
||||
/* Default configuration of slimbus channels */
|
||||
static struct dev_config slim_rx_cfg[] = {
|
||||
|
@ -432,8 +420,8 @@ static char const *tdm_ch_text[] = {"One", "Two", "Three", "Four",
|
|||
"Five", "Six", "Seven", "Eight"};
|
||||
static char const *tdm_bit_format_text[] = {"S16_LE", "S24_LE", "S32_LE"};
|
||||
static char const *tdm_sample_rate_text[] = {"KHZ_8", "KHZ_16", "KHZ_32",
|
||||
"KHZ_44P1", "KHZ_48", "KHZ_96",
|
||||
"KHZ_192", "KHZ_352P8", "KHZ_384"};
|
||||
"KHZ_48", "KHZ_176P4",
|
||||
"KHZ_352P8"};
|
||||
static const char *const auxpcm_rate_text[] = {"KHZ_8", "KHZ_16"};
|
||||
static char const *mi2s_rate_text[] = {"KHZ_8", "KHZ_16",
|
||||
"KHZ_32", "KHZ_44P1", "KHZ_48",
|
||||
|
@ -1620,23 +1608,14 @@ static int tdm_get_sample_rate(int value)
|
|||
sample_rate = SAMPLING_RATE_32KHZ;
|
||||
break;
|
||||
case 3:
|
||||
sample_rate = SAMPLING_RATE_44P1KHZ;
|
||||
break;
|
||||
case 4:
|
||||
sample_rate = SAMPLING_RATE_48KHZ;
|
||||
break;
|
||||
case 4:
|
||||
sample_rate = SAMPLING_RATE_176P4KHZ;
|
||||
break;
|
||||
case 5:
|
||||
sample_rate = SAMPLING_RATE_96KHZ;
|
||||
break;
|
||||
case 6:
|
||||
sample_rate = SAMPLING_RATE_192KHZ;
|
||||
break;
|
||||
case 7:
|
||||
sample_rate = SAMPLING_RATE_352P8KHZ;
|
||||
break;
|
||||
case 8:
|
||||
sample_rate = SAMPLING_RATE_384KHZ;
|
||||
break;
|
||||
default:
|
||||
sample_rate = SAMPLING_RATE_48KHZ;
|
||||
break;
|
||||
|
@ -1674,26 +1653,17 @@ static int tdm_get_sample_rate_val(int sample_rate)
|
|||
case SAMPLING_RATE_32KHZ:
|
||||
sample_rate_val = 2;
|
||||
break;
|
||||
case SAMPLING_RATE_44P1KHZ:
|
||||
case SAMPLING_RATE_48KHZ:
|
||||
sample_rate_val = 3;
|
||||
break;
|
||||
case SAMPLING_RATE_48KHZ:
|
||||
case SAMPLING_RATE_176P4KHZ:
|
||||
sample_rate_val = 4;
|
||||
break;
|
||||
case SAMPLING_RATE_96KHZ:
|
||||
sample_rate_val = 5;
|
||||
break;
|
||||
case SAMPLING_RATE_192KHZ:
|
||||
sample_rate_val = 6;
|
||||
break;
|
||||
case SAMPLING_RATE_352P8KHZ:
|
||||
sample_rate_val = 7;
|
||||
break;
|
||||
case SAMPLING_RATE_384KHZ:
|
||||
sample_rate_val = 8;
|
||||
sample_rate_val = 5;
|
||||
break;
|
||||
default:
|
||||
sample_rate_val = 4;
|
||||
sample_rate_val = 3;
|
||||
break;
|
||||
}
|
||||
return sample_rate_val;
|
||||
|
@ -4497,15 +4467,46 @@ static int sdm845_tdm_snd_hw_params(struct snd_pcm_substream *substream,
|
|||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
|
||||
int ret = 0;
|
||||
int channels, slot_width, slots;
|
||||
int slot_width = 32;
|
||||
int channels, slots;
|
||||
unsigned int slot_mask, rate, clk_freq;
|
||||
unsigned int slot_offset[8] = {0, 4, 8, 12, 16, 20, 24, 28};
|
||||
|
||||
slot_width = 32;
|
||||
pr_debug("%s: dai id = 0x%x\n", __func__, cpu_dai->id);
|
||||
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||
/* currently only supporting TDM_RX_0 and TDM_TX_0 */
|
||||
switch (cpu_dai->id) {
|
||||
case AFE_PORT_ID_PRIMARY_TDM_RX:
|
||||
slots = tdm_rx_cfg[TDM_PRI][TDM_0].channels;
|
||||
break;
|
||||
case AFE_PORT_ID_SECONDARY_TDM_RX:
|
||||
slots = tdm_rx_cfg[TDM_SEC][TDM_0].channels;
|
||||
break;
|
||||
case AFE_PORT_ID_TERTIARY_TDM_RX:
|
||||
slots = tdm_rx_cfg[TDM_TERT][TDM_0].channels;
|
||||
break;
|
||||
case AFE_PORT_ID_QUATERNARY_TDM_RX:
|
||||
slots = tdm_rx_cfg[TDM_QUAT][TDM_0].channels;
|
||||
break;
|
||||
case AFE_PORT_ID_PRIMARY_TDM_TX:
|
||||
slots = tdm_tx_cfg[TDM_PRI][TDM_0].channels;
|
||||
break;
|
||||
case AFE_PORT_ID_SECONDARY_TDM_TX:
|
||||
slots = tdm_tx_cfg[TDM_SEC][TDM_0].channels;
|
||||
break;
|
||||
case AFE_PORT_ID_TERTIARY_TDM_TX:
|
||||
slots = tdm_tx_cfg[TDM_TERT][TDM_0].channels;
|
||||
break;
|
||||
case AFE_PORT_ID_QUATERNARY_TDM_TX:
|
||||
slots = tdm_tx_cfg[TDM_QUAT][TDM_0].channels;
|
||||
break;
|
||||
default:
|
||||
pr_err("%s: dai id 0x%x not supported\n",
|
||||
__func__, cpu_dai->id);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||
/*2 slot config - bits 0 and 1 set for the first two slots */
|
||||
slot_mask = 0x0000FFFF >> (16-slots);
|
||||
channels = slots;
|
||||
|
@ -4529,7 +4530,6 @@ static int sdm845_tdm_snd_hw_params(struct snd_pcm_substream *substream,
|
|||
goto end;
|
||||
}
|
||||
} else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
|
||||
slots = tdm_tx_cfg[TDM_QUAT][TDM_0].channels;
|
||||
/*2 slot config - bits 0 and 1 set for the first two slots */
|
||||
slot_mask = 0x0000FFFF >> (16-slots);
|
||||
channels = slots;
|
||||
|
@ -4574,14 +4574,19 @@ static int sdm845_tdm_snd_startup(struct snd_pcm_substream *substream)
|
|||
{
|
||||
int ret = 0;
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
|
||||
struct snd_soc_card *card = rtd->card;
|
||||
struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);
|
||||
struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info;
|
||||
|
||||
ret = msm_set_pinctrl(pinctrl_info, STATE_TDM_ACTIVE);
|
||||
if (ret)
|
||||
pr_err("%s: TDM TLMM pinctrl set failed with %d\n",
|
||||
__func__, ret);
|
||||
/* currently only supporting TDM_RX_0 and TDM_TX_0 */
|
||||
if ((cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_RX) ||
|
||||
(cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_TX)) {
|
||||
ret = msm_set_pinctrl(pinctrl_info, STATE_TDM_ACTIVE);
|
||||
if (ret)
|
||||
pr_err("%s: TDM TLMM pinctrl set failed with %d\n",
|
||||
__func__, ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -4590,15 +4595,19 @@ static void sdm845_tdm_snd_shutdown(struct snd_pcm_substream *substream)
|
|||
{
|
||||
int ret = 0;
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
|
||||
struct snd_soc_card *card = rtd->card;
|
||||
struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);
|
||||
struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info;
|
||||
|
||||
ret = msm_set_pinctrl(pinctrl_info, STATE_DISABLE);
|
||||
if (ret)
|
||||
pr_err("%s: TDM TLMM pinctrl set failed with %d\n",
|
||||
__func__, ret);
|
||||
|
||||
/* currently only supporting TDM_RX_0 and TDM_TX_0 */
|
||||
if ((cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_RX) ||
|
||||
(cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_TX)) {
|
||||
ret = msm_set_pinctrl(pinctrl_info, STATE_DISABLE);
|
||||
if (ret)
|
||||
pr_err("%s: TDM TLMM pinctrl set failed with %d\n",
|
||||
__func__, ret);
|
||||
}
|
||||
}
|
||||
|
||||
static struct snd_soc_ops sdm845_tdm_be_ops = {
|
||||
|
@ -4732,157 +4741,6 @@ static struct snd_soc_ops msm_aux_pcm_be_ops = {
|
|||
.shutdown = msm_aux_pcm_snd_shutdown,
|
||||
};
|
||||
|
||||
static unsigned int tdm_param_set_slot_mask(u16 port_id, int slot_width,
|
||||
int slots)
|
||||
{
|
||||
unsigned int slot_mask = 0;
|
||||
int i, j;
|
||||
unsigned int *slot_offset;
|
||||
|
||||
for (i = TDM_0; i < TDM_PORT_MAX; i++) {
|
||||
slot_offset = tdm_slot_offset[i];
|
||||
|
||||
for (j = 0; j < TDM_SLOT_OFFSET_MAX; j++) {
|
||||
if (slot_offset[j] != AFE_SLOT_MAPPING_OFFSET_INVALID)
|
||||
slot_mask |=
|
||||
(1 << ((slot_offset[j] * 8) / slot_width));
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return slot_mask;
|
||||
}
|
||||
|
||||
static int msm_tdm_snd_hw_params(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
|
||||
int ret = 0;
|
||||
int channels, slot_width, slots;
|
||||
unsigned int slot_mask;
|
||||
unsigned int *slot_offset;
|
||||
int offset_channels = 0;
|
||||
int i;
|
||||
|
||||
pr_debug("%s: dai id = 0x%x\n", __func__, cpu_dai->id);
|
||||
|
||||
channels = params_channels(params);
|
||||
switch (channels) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
case 8:
|
||||
switch (params_format(params)) {
|
||||
case SNDRV_PCM_FORMAT_S32_LE:
|
||||
case SNDRV_PCM_FORMAT_S24_LE:
|
||||
case SNDRV_PCM_FORMAT_S16_LE:
|
||||
/*
|
||||
* Up to 8 channels HW config should
|
||||
* use 32 bit slot width for max support of
|
||||
* stream bit width. (slot_width > bit_width)
|
||||
*/
|
||||
slot_width = 32;
|
||||
break;
|
||||
default:
|
||||
pr_err("%s: invalid param format 0x%x\n",
|
||||
__func__, params_format(params));
|
||||
return -EINVAL;
|
||||
}
|
||||
slots = 8;
|
||||
slot_mask = tdm_param_set_slot_mask(cpu_dai->id,
|
||||
slot_width,
|
||||
slots);
|
||||
if (!slot_mask) {
|
||||
pr_err("%s: invalid slot_mask 0x%x\n",
|
||||
__func__, slot_mask);
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
pr_err("%s: invalid param channels %d\n",
|
||||
__func__, channels);
|
||||
return -EINVAL;
|
||||
}
|
||||
/* currently only supporting TDM_RX_0 and TDM_TX_0 */
|
||||
switch (cpu_dai->id) {
|
||||
case AFE_PORT_ID_PRIMARY_TDM_RX:
|
||||
case AFE_PORT_ID_SECONDARY_TDM_RX:
|
||||
case AFE_PORT_ID_TERTIARY_TDM_RX:
|
||||
case AFE_PORT_ID_QUATERNARY_TDM_RX:
|
||||
case AFE_PORT_ID_PRIMARY_TDM_TX:
|
||||
case AFE_PORT_ID_SECONDARY_TDM_TX:
|
||||
case AFE_PORT_ID_TERTIARY_TDM_TX:
|
||||
case AFE_PORT_ID_QUATERNARY_TDM_TX:
|
||||
slot_offset = tdm_slot_offset[TDM_0];
|
||||
break;
|
||||
default:
|
||||
pr_err("%s: dai id 0x%x not supported\n",
|
||||
__func__, cpu_dai->id);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (i = 0; i < TDM_SLOT_OFFSET_MAX; i++) {
|
||||
if (slot_offset[i] != AFE_SLOT_MAPPING_OFFSET_INVALID)
|
||||
offset_channels++;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if (offset_channels == 0) {
|
||||
pr_err("%s: slot offset not supported, offset_channels %d\n",
|
||||
__func__, offset_channels);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (channels > offset_channels) {
|
||||
pr_err("%s: channels %d exceed offset_channels %d\n",
|
||||
__func__, channels, offset_channels);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||
ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0, slot_mask,
|
||||
slots, slot_width);
|
||||
if (ret < 0) {
|
||||
pr_err("%s: failed to set tdm slot, err:%d\n",
|
||||
__func__, ret);
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = snd_soc_dai_set_channel_map(cpu_dai, 0, NULL,
|
||||
channels, slot_offset);
|
||||
if (ret < 0) {
|
||||
pr_err("%s: failed to set channel map, err:%d\n",
|
||||
__func__, ret);
|
||||
goto err;
|
||||
}
|
||||
} else {
|
||||
ret = snd_soc_dai_set_tdm_slot(cpu_dai, slot_mask, 0,
|
||||
slots, slot_width);
|
||||
if (ret < 0) {
|
||||
pr_err("%s: failed to set tdm slot, err:%d\n",
|
||||
__func__, ret);
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = snd_soc_dai_set_channel_map(cpu_dai, channels,
|
||||
slot_offset, 0, NULL);
|
||||
if (ret < 0) {
|
||||
pr_err("%s: failed to set channel map, err:%d\n",
|
||||
__func__, ret);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct snd_soc_ops msm_be_ops = {
|
||||
.hw_params = msm_snd_hw_params,
|
||||
};
|
||||
|
@ -4895,9 +4753,6 @@ static struct snd_soc_ops msm_wcn_ops = {
|
|||
.hw_params = msm_wcn_hw_params,
|
||||
};
|
||||
|
||||
static struct snd_soc_ops msm_tdm_be_ops = {
|
||||
.hw_params = msm_tdm_snd_hw_params
|
||||
};
|
||||
|
||||
/* Digital audio interface glue - connects codec <---> CPU */
|
||||
static struct snd_soc_dai_link msm_common_dai_links[] = {
|
||||
|
@ -5676,7 +5531,7 @@ static struct snd_soc_dai_link msm_common_be_dai_links[] = {
|
|||
.dpcm_playback = 1,
|
||||
.id = MSM_BACKEND_DAI_PRI_TDM_RX_0,
|
||||
.be_hw_params_fixup = msm_be_hw_params_fixup,
|
||||
.ops = &msm_tdm_be_ops,
|
||||
.ops = &sdm845_tdm_be_ops,
|
||||
.ignore_suspend = 1,
|
||||
},
|
||||
{
|
||||
|
@ -5690,7 +5545,7 @@ static struct snd_soc_dai_link msm_common_be_dai_links[] = {
|
|||
.dpcm_capture = 1,
|
||||
.id = MSM_BACKEND_DAI_PRI_TDM_TX_0,
|
||||
.be_hw_params_fixup = msm_be_hw_params_fixup,
|
||||
.ops = &msm_tdm_be_ops,
|
||||
.ops = &sdm845_tdm_be_ops,
|
||||
.ignore_suspend = 1,
|
||||
},
|
||||
{
|
||||
|
@ -5704,7 +5559,7 @@ static struct snd_soc_dai_link msm_common_be_dai_links[] = {
|
|||
.dpcm_playback = 1,
|
||||
.id = MSM_BACKEND_DAI_SEC_TDM_RX_0,
|
||||
.be_hw_params_fixup = msm_be_hw_params_fixup,
|
||||
.ops = &msm_tdm_be_ops,
|
||||
.ops = &sdm845_tdm_be_ops,
|
||||
.ignore_suspend = 1,
|
||||
},
|
||||
{
|
||||
|
@ -5718,7 +5573,7 @@ static struct snd_soc_dai_link msm_common_be_dai_links[] = {
|
|||
.dpcm_capture = 1,
|
||||
.id = MSM_BACKEND_DAI_SEC_TDM_TX_0,
|
||||
.be_hw_params_fixup = msm_be_hw_params_fixup,
|
||||
.ops = &msm_tdm_be_ops,
|
||||
.ops = &sdm845_tdm_be_ops,
|
||||
.ignore_suspend = 1,
|
||||
},
|
||||
{
|
||||
|
@ -5732,7 +5587,7 @@ static struct snd_soc_dai_link msm_common_be_dai_links[] = {
|
|||
.dpcm_playback = 1,
|
||||
.id = MSM_BACKEND_DAI_TERT_TDM_RX_0,
|
||||
.be_hw_params_fixup = msm_be_hw_params_fixup,
|
||||
.ops = &msm_tdm_be_ops,
|
||||
.ops = &sdm845_tdm_be_ops,
|
||||
.ignore_suspend = 1,
|
||||
},
|
||||
{
|
||||
|
@ -5746,7 +5601,7 @@ static struct snd_soc_dai_link msm_common_be_dai_links[] = {
|
|||
.dpcm_capture = 1,
|
||||
.id = MSM_BACKEND_DAI_TERT_TDM_TX_0,
|
||||
.be_hw_params_fixup = msm_be_hw_params_fixup,
|
||||
.ops = &msm_tdm_be_ops,
|
||||
.ops = &sdm845_tdm_be_ops,
|
||||
.ignore_suspend = 1,
|
||||
},
|
||||
{
|
||||
|
|
Loading…
Add table
Reference in a new issue