Merge "ASoc: Kona: Add support for group AFE"
This commit is contained in:

committed by
Gerrit - the friendly Code Review server

commit
40e928840f
293
asoc/kona.c
293
asoc/kona.c
@@ -75,6 +75,12 @@
|
|||||||
#define WCN_CDC_SLIM_TX_CH_MAX 2
|
#define WCN_CDC_SLIM_TX_CH_MAX 2
|
||||||
#define WCN_CDC_SLIM_TX_CH_MAX_LITO 3
|
#define WCN_CDC_SLIM_TX_CH_MAX_LITO 3
|
||||||
|
|
||||||
|
enum {
|
||||||
|
RX_PATH = 0,
|
||||||
|
TX_PATH,
|
||||||
|
MAX_PATH,
|
||||||
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
TDM_0 = 0,
|
TDM_0 = 0,
|
||||||
TDM_1,
|
TDM_1,
|
||||||
@@ -87,6 +93,9 @@ enum {
|
|||||||
TDM_PORT_MAX,
|
TDM_PORT_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define TDM_MAX_SLOTS 8
|
||||||
|
#define TDM_SLOT_WIDTH_BITS 32
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
TDM_PRI = 0,
|
TDM_PRI = 0,
|
||||||
TDM_SEC,
|
TDM_SEC,
|
||||||
@@ -176,6 +185,10 @@ struct tdm_port {
|
|||||||
u32 channel;
|
u32 channel;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct tdm_dev_config {
|
||||||
|
unsigned int tdm_slot_offset[TDM_MAX_SLOTS];
|
||||||
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
EXT_DISP_RX_IDX_DP = 0,
|
EXT_DISP_RX_IDX_DP = 0,
|
||||||
EXT_DISP_RX_IDX_DP1,
|
EXT_DISP_RX_IDX_DP1,
|
||||||
@@ -462,6 +475,153 @@ static struct dev_config mi2s_tx_cfg[] = {
|
|||||||
[SEN_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
|
[SEN_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct tdm_dev_config pri_tdm_dev_config[MAX_PATH][TDM_PORT_MAX] = {
|
||||||
|
{ /* PRI TDM */
|
||||||
|
{ {0, 4, 0xFFFF} }, /* RX_0 */
|
||||||
|
{ {8, 12, 0xFFFF} }, /* RX_1 */
|
||||||
|
{ {16, 20, 0xFFFF} }, /* RX_2 */
|
||||||
|
{ {24, 28, 0xFFFF} }, /* RX_3 */
|
||||||
|
{ {0xFFFF} }, /* RX_4 */
|
||||||
|
{ {0xFFFF} }, /* RX_5 */
|
||||||
|
{ {0xFFFF} }, /* RX_6 */
|
||||||
|
{ {0xFFFF} }, /* RX_7 */
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{ {0, 4, 8, 12, 0xFFFF} }, /* TX_0 */
|
||||||
|
{ {8, 12, 0xFFFF} }, /* TX_1 */
|
||||||
|
{ {16, 20, 0xFFFF} }, /* TX_2 */
|
||||||
|
{ {24, 28, 0xFFFF} }, /* TX_3 */
|
||||||
|
{ {0xFFFF} }, /* TX_4 */
|
||||||
|
{ {0xFFFF} }, /* TX_5 */
|
||||||
|
{ {0xFFFF} }, /* TX_6 */
|
||||||
|
{ {0xFFFF} }, /* TX_7 */
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct tdm_dev_config sec_tdm_dev_config[MAX_PATH][TDM_PORT_MAX] = {
|
||||||
|
{ /* SEC TDM */
|
||||||
|
{ {0, 4, 0xFFFF} }, /* RX_0 */
|
||||||
|
{ {8, 12, 0xFFFF} }, /* RX_1 */
|
||||||
|
{ {16, 20, 0xFFFF} }, /* RX_2 */
|
||||||
|
{ {24, 28, 0xFFFF} }, /* RX_3 */
|
||||||
|
{ {0xFFFF} }, /* RX_4 */
|
||||||
|
{ {0xFFFF} }, /* RX_5 */
|
||||||
|
{ {0xFFFF} }, /* RX_6 */
|
||||||
|
{ {0xFFFF} }, /* RX_7 */
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{ {0, 4, 0xFFFF} }, /* TX_0 */
|
||||||
|
{ {8, 12, 0xFFFF} }, /* TX_1 */
|
||||||
|
{ {16, 20, 0xFFFF} }, /* TX_2 */
|
||||||
|
{ {24, 28, 0xFFFF} }, /* TX_3 */
|
||||||
|
{ {0xFFFF} }, /* TX_4 */
|
||||||
|
{ {0xFFFF} }, /* TX_5 */
|
||||||
|
{ {0xFFFF} }, /* TX_6 */
|
||||||
|
{ {0xFFFF} }, /* TX_7 */
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct tdm_dev_config tert_tdm_dev_config[MAX_PATH][TDM_PORT_MAX] = {
|
||||||
|
{ /* TERT TDM */
|
||||||
|
{ {0, 4, 0xFFFF} }, /* RX_0 */
|
||||||
|
{ {8, 12, 0xFFFF} }, /* RX_1 */
|
||||||
|
{ {16, 20, 0xFFFF} }, /* RX_2 */
|
||||||
|
{ {24, 28, 0xFFFF} }, /* RX_3 */
|
||||||
|
{ {0xFFFF} }, /* RX_4 */
|
||||||
|
{ {0xFFFF} }, /* RX_5 */
|
||||||
|
{ {0xFFFF} }, /* RX_6 */
|
||||||
|
{ {0xFFFF} }, /* RX_7 */
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{ {0, 4, 0xFFFF} }, /* TX_0 */
|
||||||
|
{ {8, 12, 0xFFFF} }, /* TX_1 */
|
||||||
|
{ {16, 20, 0xFFFF} }, /* TX_2 */
|
||||||
|
{ {24, 28, 0xFFFF} }, /* TX_3 */
|
||||||
|
{ {0xFFFF} }, /* TX_4 */
|
||||||
|
{ {0xFFFF} }, /* TX_5 */
|
||||||
|
{ {0xFFFF} }, /* TX_6 */
|
||||||
|
{ {0xFFFF} }, /* TX_7 */
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct tdm_dev_config quat_tdm_dev_config[MAX_PATH][TDM_PORT_MAX] = {
|
||||||
|
{ /* QUAT TDM */
|
||||||
|
{ {0, 4, 0xFFFF} }, /* RX_0 */
|
||||||
|
{ {8, 12, 0xFFFF} }, /* RX_1 */
|
||||||
|
{ {16, 20, 0xFFFF} }, /* RX_2 */
|
||||||
|
{ {24, 28, 0xFFFF} }, /* RX_3 */
|
||||||
|
{ {0xFFFF} }, /* RX_4 */
|
||||||
|
{ {0xFFFF} }, /* RX_5 */
|
||||||
|
{ {0xFFFF} }, /* RX_6 */
|
||||||
|
{ {0xFFFF} }, /* RX_7 */
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{ {0, 4, 0xFFFF} }, /* TX_0 */
|
||||||
|
{ {8, 12, 0xFFFF} }, /* TX_1 */
|
||||||
|
{ {16, 20, 0xFFFF} }, /* TX_2 */
|
||||||
|
{ {24, 28, 0xFFFF} }, /* TX_3 */
|
||||||
|
{ {0xFFFF} }, /* TX_4 */
|
||||||
|
{ {0xFFFF} }, /* TX_5 */
|
||||||
|
{ {0xFFFF} }, /* TX_6 */
|
||||||
|
{ {0xFFFF} }, /* TX_7 */
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct tdm_dev_config quin_tdm_dev_config[MAX_PATH][TDM_PORT_MAX] = {
|
||||||
|
{ /* QUIN TDM */
|
||||||
|
{ {0, 4, 0xFFFF} }, /* RX_0 */
|
||||||
|
{ {8, 12, 0xFFFF} }, /* RX_1 */
|
||||||
|
{ {16, 20, 0xFFFF} }, /* RX_2 */
|
||||||
|
{ {24, 28, 0xFFFF} }, /* RX_3 */
|
||||||
|
{ {0xFFFF} }, /* RX_4 */
|
||||||
|
{ {0xFFFF} }, /* RX_5 */
|
||||||
|
{ {0xFFFF} }, /* RX_6 */
|
||||||
|
{ {0xFFFF} }, /* RX_7 */
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{ {0, 4, 0xFFFF} }, /* TX_0 */
|
||||||
|
{ {8, 12, 0xFFFF} }, /* TX_1 */
|
||||||
|
{ {16, 20, 0xFFFF} }, /* TX_2 */
|
||||||
|
{ {24, 28, 0xFFFF} }, /* TX_3 */
|
||||||
|
{ {0xFFFF} }, /* TX_4 */
|
||||||
|
{ {0xFFFF} }, /* TX_5 */
|
||||||
|
{ {0xFFFF} }, /* TX_6 */
|
||||||
|
{ {0xFFFF} }, /* TX_7 */
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct tdm_dev_config sen_tdm_dev_config[MAX_PATH][TDM_PORT_MAX] = {
|
||||||
|
{ /* SEN TDM */
|
||||||
|
{ {0, 4, 0xFFFF} }, /* RX_0 */
|
||||||
|
{ {8, 12, 0xFFFF} }, /* RX_1 */
|
||||||
|
{ {16, 20, 0xFFFF} }, /* RX_2 */
|
||||||
|
{ {24, 28, 0xFFFF} }, /* RX_3 */
|
||||||
|
{ {0xFFFF} }, /* RX_4 */
|
||||||
|
{ {0xFFFF} }, /* RX_5 */
|
||||||
|
{ {0xFFFF} }, /* RX_6 */
|
||||||
|
{ {0xFFFF} }, /* RX_7 */
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{ {0, 4, 0xFFFF} }, /* TX_0 */
|
||||||
|
{ {8, 12, 0xFFFF} }, /* TX_1 */
|
||||||
|
{ {16, 20, 0xFFFF} }, /* TX_2 */
|
||||||
|
{ {24, 28, 0xFFFF} }, /* TX_3 */
|
||||||
|
{ {0xFFFF} }, /* TX_4 */
|
||||||
|
{ {0xFFFF} }, /* TX_5 */
|
||||||
|
{ {0xFFFF} }, /* TX_6 */
|
||||||
|
{ {0xFFFF} }, /* TX_7 */
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static void *tdm_cfg[TDM_INTERFACE_MAX] = {
|
||||||
|
pri_tdm_dev_config,
|
||||||
|
sec_tdm_dev_config,
|
||||||
|
tert_tdm_dev_config,
|
||||||
|
quat_tdm_dev_config,
|
||||||
|
quin_tdm_dev_config,
|
||||||
|
sen_tdm_dev_config,
|
||||||
|
};
|
||||||
|
|
||||||
/* Default configuration of Codec DMA Interface RX */
|
/* Default configuration of Codec DMA Interface RX */
|
||||||
static struct dev_config cdc_dma_rx_cfg[] = {
|
static struct dev_config cdc_dma_rx_cfg[] = {
|
||||||
[WSA_CDC_DMA_RX_0] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2},
|
[WSA_CDC_DMA_RX_0] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2},
|
||||||
@@ -1789,6 +1949,45 @@ static int tdm_tx_ch_put(struct snd_kcontrol *kcontrol,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int tdm_slot_map_put(struct snd_kcontrol *kcontrol,
|
||||||
|
struct snd_ctl_elem_value *ucontrol)
|
||||||
|
{
|
||||||
|
int slot_index = 0;
|
||||||
|
int interface = ucontrol->value.integer.value[0];
|
||||||
|
int channel = ucontrol->value.integer.value[1];
|
||||||
|
unsigned int offset_val = 0;
|
||||||
|
unsigned int *slot_offset = NULL;
|
||||||
|
struct tdm_dev_config *config = NULL;
|
||||||
|
|
||||||
|
if (interface < 0 || interface >= (TDM_INTERFACE_MAX * MAX_PATH)) {
|
||||||
|
pr_err("%s: incorrect interface = %d\n", __func__, interface);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
if (channel < 0 || channel >= TDM_PORT_MAX) {
|
||||||
|
pr_err("%s: incorrect channel = %d\n", __func__, channel);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
pr_debug("%s: interface = %d, channel = %d\n", __func__,
|
||||||
|
interface, channel);
|
||||||
|
|
||||||
|
config = ((struct tdm_dev_config *) tdm_cfg[interface / MAX_PATH]) +
|
||||||
|
((interface % MAX_PATH) * TDM_PORT_MAX) + channel;
|
||||||
|
slot_offset = config->tdm_slot_offset;
|
||||||
|
|
||||||
|
for (slot_index = 0; slot_index < TDM_MAX_SLOTS; slot_index++) {
|
||||||
|
offset_val = ucontrol->value.integer.value[MAX_PATH +
|
||||||
|
slot_index];
|
||||||
|
/* Offset value can only be 0, 4, 8, ..28 */
|
||||||
|
if (offset_val % 4 == 0 && offset_val <= 28)
|
||||||
|
slot_offset[slot_index] = offset_val;
|
||||||
|
pr_debug("%s: slot offset[%d] = %d\n", __func__,
|
||||||
|
slot_index, slot_offset[slot_index]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int aux_pcm_get_port_idx(struct snd_kcontrol *kcontrol)
|
static int aux_pcm_get_port_idx(struct snd_kcontrol *kcontrol)
|
||||||
{
|
{
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
@@ -3744,6 +3943,8 @@ static const struct snd_kcontrol_new msm_common_snd_controls[] = {
|
|||||||
afe_loopback_tx_ch_get, afe_loopback_tx_ch_put),
|
afe_loopback_tx_ch_get, afe_loopback_tx_ch_put),
|
||||||
SOC_ENUM_EXT("VI_FEED_TX Channels", vi_feed_tx_chs,
|
SOC_ENUM_EXT("VI_FEED_TX Channels", vi_feed_tx_chs,
|
||||||
msm_vi_feed_tx_ch_get, msm_vi_feed_tx_ch_put),
|
msm_vi_feed_tx_ch_get, msm_vi_feed_tx_ch_put),
|
||||||
|
SOC_SINGLE_MULTI_EXT("TDM Slot Map", SND_SOC_NOPM, 0, 255, 0,
|
||||||
|
TDM_MAX_SLOTS + MAX_PATH, NULL, tdm_slot_map_put),
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct snd_kcontrol_new msm_snd_controls[] = {
|
static const struct snd_kcontrol_new msm_snd_controls[] = {
|
||||||
@@ -3813,8 +4014,9 @@ static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
|
|||||||
SNDRV_PCM_HW_PARAM_CHANNELS);
|
SNDRV_PCM_HW_PARAM_CHANNELS);
|
||||||
int idx = 0, rc = 0;
|
int idx = 0, rc = 0;
|
||||||
|
|
||||||
pr_debug("%s: format = %d, rate = %d\n",
|
pr_debug("%s: dai_id= %d, format = %d, rate = %d\n",
|
||||||
__func__, params_format(params), params_rate(params));
|
__func__, dai_link->id, params_format(params),
|
||||||
|
params_rate(params));
|
||||||
|
|
||||||
switch (dai_link->id) {
|
switch (dai_link->id) {
|
||||||
case MSM_BACKEND_DAI_USB_RX:
|
case MSM_BACKEND_DAI_USB_RX:
|
||||||
@@ -4280,65 +4482,51 @@ static int kona_tdm_snd_hw_params(struct snd_pcm_substream *substream,
|
|||||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||||
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
|
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int slot_width = 32;
|
int slot_width = TDM_SLOT_WIDTH_BITS;
|
||||||
int channels, slots;
|
int channels, slots = TDM_MAX_SLOTS;
|
||||||
unsigned int slot_mask, rate, clk_freq;
|
unsigned int slot_mask, rate, clk_freq;
|
||||||
unsigned int slot_offset[8] = {0, 4, 8, 12, 16, 20, 24, 28};
|
unsigned int *slot_offset;
|
||||||
|
struct tdm_dev_config *config;
|
||||||
|
unsigned int path_dir = 0, interface = 0, channel_interface = 0;
|
||||||
|
|
||||||
pr_debug("%s: dai id = 0x%x\n", __func__, cpu_dai->id);
|
pr_debug("%s: dai id = 0x%x\n", __func__, cpu_dai->id);
|
||||||
|
|
||||||
/* currently only supporting TDM_RX_0 and TDM_TX_0 */
|
if (cpu_dai->id < AFE_PORT_ID_TDM_PORT_RANGE_START) {
|
||||||
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_QUINARY_TDM_RX:
|
|
||||||
slots = tdm_rx_cfg[TDM_QUIN][TDM_0].channels;
|
|
||||||
break;
|
|
||||||
case AFE_PORT_ID_SENARY_TDM_RX:
|
|
||||||
slots = tdm_rx_cfg[TDM_SEN][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;
|
|
||||||
case AFE_PORT_ID_QUINARY_TDM_TX:
|
|
||||||
slots = tdm_tx_cfg[TDM_QUIN][TDM_0].channels;
|
|
||||||
break;
|
|
||||||
case AFE_PORT_ID_SENARY_TDM_TX:
|
|
||||||
slots = tdm_tx_cfg[TDM_SEN][TDM_0].channels;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
pr_err("%s: dai id 0x%x not supported\n",
|
pr_err("%s: dai id 0x%x not supported\n",
|
||||||
__func__, cpu_dai->id);
|
__func__, cpu_dai->id);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* RX or TX */
|
||||||
|
path_dir = cpu_dai->id % MAX_PATH;
|
||||||
|
|
||||||
|
/* PRI, SEC, TERT, QUAT, QUIN, ... */
|
||||||
|
interface = (cpu_dai->id - AFE_PORT_ID_TDM_PORT_RANGE_START)
|
||||||
|
/ (MAX_PATH * TDM_PORT_MAX);
|
||||||
|
|
||||||
|
/* 0, 1, 2, .. 7 */
|
||||||
|
channel_interface =
|
||||||
|
((cpu_dai->id - AFE_PORT_ID_TDM_PORT_RANGE_START) / MAX_PATH)
|
||||||
|
% TDM_PORT_MAX;
|
||||||
|
|
||||||
|
pr_debug("%s: path dir: %u, interface %u, channel interface %u\n",
|
||||||
|
__func__, path_dir, interface, channel_interface);
|
||||||
|
|
||||||
|
config = ((struct tdm_dev_config *) tdm_cfg[interface]) +
|
||||||
|
(path_dir * TDM_PORT_MAX) + channel_interface;
|
||||||
|
slot_offset = config->tdm_slot_offset;
|
||||||
|
|
||||||
|
if (path_dir)
|
||||||
|
channels = tdm_tx_cfg[interface][channel_interface].channels;
|
||||||
|
else
|
||||||
|
channels = tdm_rx_cfg[interface][channel_interface].channels;
|
||||||
|
|
||||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||||
/*2 slot config - bits 0 and 1 set for the first two slots */
|
/*2 slot config - bits 0 and 1 set for the first two slots */
|
||||||
slot_mask = 0x0000FFFF >> (16 - slots);
|
slot_mask = 0x0000FFFF >> (16 - slots);
|
||||||
channels = slots;
|
|
||||||
|
|
||||||
pr_debug("%s: tdm rx slot_width %d slots %d\n",
|
pr_debug("%s: tdm rx slot_width %d slots %d slot_mask %x\n",
|
||||||
__func__, slot_width, slots);
|
__func__, slot_width, slots, slot_mask);
|
||||||
|
|
||||||
ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0, slot_mask,
|
ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0, slot_mask,
|
||||||
slots, slot_width);
|
slots, slot_width);
|
||||||
@@ -4348,6 +4536,8 @@ static int kona_tdm_snd_hw_params(struct snd_pcm_substream *substream,
|
|||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pr_debug("%s: tdm rx channels: %d\n", __func__, channels);
|
||||||
|
|
||||||
ret = snd_soc_dai_set_channel_map(cpu_dai,
|
ret = snd_soc_dai_set_channel_map(cpu_dai,
|
||||||
0, NULL, channels, slot_offset);
|
0, NULL, channels, slot_offset);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
@@ -4358,10 +4548,9 @@ static int kona_tdm_snd_hw_params(struct snd_pcm_substream *substream,
|
|||||||
} else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
|
} else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
|
||||||
/*2 slot config - bits 0 and 1 set for the first two slots */
|
/*2 slot config - bits 0 and 1 set for the first two slots */
|
||||||
slot_mask = 0x0000FFFF >> (16 - slots);
|
slot_mask = 0x0000FFFF >> (16 - slots);
|
||||||
channels = slots;
|
|
||||||
|
|
||||||
pr_debug("%s: tdm tx slot_width %d slots %d\n",
|
pr_debug("%s: tdm tx slot_width %d slots %d slot_mask %x\n",
|
||||||
__func__, slot_width, slots);
|
__func__, slot_width, slots, slot_mask);
|
||||||
|
|
||||||
ret = snd_soc_dai_set_tdm_slot(cpu_dai, slot_mask, 0,
|
ret = snd_soc_dai_set_tdm_slot(cpu_dai, slot_mask, 0,
|
||||||
slots, slot_width);
|
slots, slot_width);
|
||||||
@@ -4371,6 +4560,8 @@ static int kona_tdm_snd_hw_params(struct snd_pcm_substream *substream,
|
|||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pr_debug("%s: tdm tx channels: %d\n", __func__, channels);
|
||||||
|
|
||||||
ret = snd_soc_dai_set_channel_map(cpu_dai,
|
ret = snd_soc_dai_set_channel_map(cpu_dai,
|
||||||
channels, slot_offset, 0, NULL);
|
channels, slot_offset, 0, NULL);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
@@ -9301,6 +9301,37 @@ static int msm_dai_q6_tdm_set_channel_map(struct snd_soc_dai *dai,
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned int tdm_param_set_slot_mask(u16 *slot_offset, int slot_width,
|
||||||
|
int slots_per_frame)
|
||||||
|
{
|
||||||
|
unsigned int i = 0;
|
||||||
|
unsigned int slot_index = 0;
|
||||||
|
unsigned long slot_mask = 0;
|
||||||
|
unsigned int slot_width_bytes = slot_width / 8;
|
||||||
|
|
||||||
|
if (slot_width_bytes == 0) {
|
||||||
|
pr_err("%s: slot width is zero\n", __func__);
|
||||||
|
return slot_mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < AFE_PORT_MAX_AUDIO_CHAN_CNT; i++) {
|
||||||
|
if (slot_offset[i] != AFE_SLOT_MAPPING_OFFSET_INVALID) {
|
||||||
|
slot_index = slot_offset[i] / slot_width_bytes;
|
||||||
|
if (slot_index < slots_per_frame)
|
||||||
|
set_bit(slot_index, &slot_mask);
|
||||||
|
else {
|
||||||
|
pr_err("%s: invalid slot map setting\n",
|
||||||
|
__func__);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return slot_mask;
|
||||||
|
}
|
||||||
|
|
||||||
static int msm_dai_q6_tdm_hw_params(struct snd_pcm_substream *substream,
|
static int msm_dai_q6_tdm_hw_params(struct snd_pcm_substream *substream,
|
||||||
struct snd_pcm_hw_params *params,
|
struct snd_pcm_hw_params *params,
|
||||||
struct snd_soc_dai *dai)
|
struct snd_soc_dai *dai)
|
||||||
@@ -9405,7 +9436,9 @@ static int msm_dai_q6_tdm_hw_params(struct snd_pcm_substream *substream,
|
|||||||
*/
|
*/
|
||||||
tdm->nslots_per_frame = tdm_group->nslots_per_frame;
|
tdm->nslots_per_frame = tdm_group->nslots_per_frame;
|
||||||
tdm->slot_width = tdm_group->slot_width;
|
tdm->slot_width = tdm_group->slot_width;
|
||||||
tdm->slot_mask = tdm_group->slot_mask;
|
tdm->slot_mask = tdm_param_set_slot_mask(slot_mapping->offset,
|
||||||
|
tdm_group->slot_width,
|
||||||
|
tdm_group->nslots_per_frame);
|
||||||
|
|
||||||
pr_debug("%s: TDM:\n"
|
pr_debug("%s: TDM:\n"
|
||||||
"num_channels=%d sample_rate=%d bit_width=%d\n"
|
"num_channels=%d sample_rate=%d bit_width=%d\n"
|
||||||
|
Reference in New Issue
Block a user