Merge "ASoC: msm: qdsp6v2: support for configurable bit format for AFE encoder"
This commit is contained in:
commit
36e5723b82
3 changed files with 90 additions and 12 deletions
|
@ -281,7 +281,7 @@ void afe_set_cal_mode(u16 port_id, enum afe_cal_mode afe_cal_mode);
|
||||||
int afe_port_start(u16 port_id, union afe_port_config *afe_config,
|
int afe_port_start(u16 port_id, union afe_port_config *afe_config,
|
||||||
u32 rate);
|
u32 rate);
|
||||||
int afe_port_start_v2(u16 port_id, union afe_port_config *afe_config,
|
int afe_port_start_v2(u16 port_id, union afe_port_config *afe_config,
|
||||||
u32 rate, u16 afe_in_channels,
|
u32 rate, u16 afe_in_channels, u16 afe_in_bit_width,
|
||||||
struct afe_enc_config *enc_config);
|
struct afe_enc_config *enc_config);
|
||||||
int afe_spk_prot_feed_back_cfg(int src_port, int dst_port,
|
int afe_spk_prot_feed_back_cfg(int src_port, int dst_port,
|
||||||
int l_ch, int r_ch, u32 enable);
|
int l_ch, int r_ch, u32 enable);
|
||||||
|
|
|
@ -173,6 +173,7 @@ struct msm_dai_q6_dai_data {
|
||||||
u32 bitwidth;
|
u32 bitwidth;
|
||||||
u32 cal_mode;
|
u32 cal_mode;
|
||||||
u32 afe_in_channels;
|
u32 afe_in_channels;
|
||||||
|
u16 afe_in_bitformat;
|
||||||
struct afe_enc_config enc_config;
|
struct afe_enc_config enc_config;
|
||||||
union afe_port_config port_config;
|
union afe_port_config port_config;
|
||||||
};
|
};
|
||||||
|
@ -1417,11 +1418,20 @@ static int msm_dai_q6_prepare(struct snd_pcm_substream *substream,
|
||||||
|
|
||||||
if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
|
if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
|
||||||
if (dai_data->enc_config.format != ENC_FMT_NONE) {
|
if (dai_data->enc_config.format != ENC_FMT_NONE) {
|
||||||
|
int bitwidth = 0;
|
||||||
|
|
||||||
|
if (dai_data->afe_in_bitformat ==
|
||||||
|
SNDRV_PCM_FORMAT_S24_LE)
|
||||||
|
bitwidth = 24;
|
||||||
|
else if (dai_data->afe_in_bitformat ==
|
||||||
|
SNDRV_PCM_FORMAT_S16_LE)
|
||||||
|
bitwidth = 16;
|
||||||
pr_debug("%s: calling AFE_PORT_START_V2 with enc_format: %d\n",
|
pr_debug("%s: calling AFE_PORT_START_V2 with enc_format: %d\n",
|
||||||
__func__, dai_data->enc_config.format);
|
__func__, dai_data->enc_config.format);
|
||||||
rc = afe_port_start_v2(dai->id, &dai_data->port_config,
|
rc = afe_port_start_v2(dai->id, &dai_data->port_config,
|
||||||
dai_data->rate,
|
dai_data->rate,
|
||||||
dai_data->afe_in_channels,
|
dai_data->afe_in_channels,
|
||||||
|
bitwidth,
|
||||||
&dai_data->enc_config);
|
&dai_data->enc_config);
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
pr_err("%s: afe_port_start_v2 failed error: %d\n",
|
pr_err("%s: afe_port_start_v2 failed error: %d\n",
|
||||||
|
@ -2145,6 +2155,12 @@ static const struct soc_enum afe_input_chs_enum[] = {
|
||||||
SOC_ENUM_SINGLE_EXT(3, afe_input_chs_text),
|
SOC_ENUM_SINGLE_EXT(3, afe_input_chs_text),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const char *const afe_input_bit_format_text[] = {"S16_LE", "S24_LE"};
|
||||||
|
|
||||||
|
static const struct soc_enum afe_input_bit_format_enum[] = {
|
||||||
|
SOC_ENUM_SINGLE_EXT(2, afe_input_bit_format_text),
|
||||||
|
};
|
||||||
|
|
||||||
static int msm_dai_q6_afe_input_channel_get(struct snd_kcontrol *kcontrol,
|
static int msm_dai_q6_afe_input_channel_get(struct snd_kcontrol *kcontrol,
|
||||||
struct snd_ctl_elem_value *ucontrol)
|
struct snd_ctl_elem_value *ucontrol)
|
||||||
{
|
{
|
||||||
|
@ -2173,6 +2189,58 @@ static int msm_dai_q6_afe_input_channel_put(struct snd_kcontrol *kcontrol,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int msm_dai_q6_afe_input_bit_format_get(
|
||||||
|
struct snd_kcontrol *kcontrol,
|
||||||
|
struct snd_ctl_elem_value *ucontrol)
|
||||||
|
{
|
||||||
|
struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data;
|
||||||
|
|
||||||
|
if (!dai_data) {
|
||||||
|
pr_err("%s: Invalid dai data\n", __func__);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (dai_data->afe_in_bitformat) {
|
||||||
|
case SNDRV_PCM_FORMAT_S24_LE:
|
||||||
|
ucontrol->value.integer.value[0] = 1;
|
||||||
|
break;
|
||||||
|
case SNDRV_PCM_FORMAT_S16_LE:
|
||||||
|
default:
|
||||||
|
ucontrol->value.integer.value[0] = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pr_debug("%s: afe input bit format : %ld\n",
|
||||||
|
__func__, ucontrol->value.integer.value[0]);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int msm_dai_q6_afe_input_bit_format_put(
|
||||||
|
struct snd_kcontrol *kcontrol,
|
||||||
|
struct snd_ctl_elem_value *ucontrol)
|
||||||
|
{
|
||||||
|
struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data;
|
||||||
|
|
||||||
|
if (!dai_data) {
|
||||||
|
pr_err("%s: Invalid dai data\n", __func__);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
switch (ucontrol->value.integer.value[0]) {
|
||||||
|
case 1:
|
||||||
|
dai_data->afe_in_bitformat = SNDRV_PCM_FORMAT_S24_LE;
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
default:
|
||||||
|
dai_data->afe_in_bitformat = SNDRV_PCM_FORMAT_S16_LE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pr_debug("%s: updating afe input bit format : %d\n",
|
||||||
|
__func__, dai_data->afe_in_bitformat);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static const struct snd_kcontrol_new afe_enc_config_controls[] = {
|
static const struct snd_kcontrol_new afe_enc_config_controls[] = {
|
||||||
{
|
{
|
||||||
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
|
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
|
||||||
|
@ -2186,6 +2254,9 @@ static const struct snd_kcontrol_new afe_enc_config_controls[] = {
|
||||||
SOC_ENUM_EXT("AFE Input Channels", afe_input_chs_enum[0],
|
SOC_ENUM_EXT("AFE Input Channels", afe_input_chs_enum[0],
|
||||||
msm_dai_q6_afe_input_channel_get,
|
msm_dai_q6_afe_input_channel_get,
|
||||||
msm_dai_q6_afe_input_channel_put),
|
msm_dai_q6_afe_input_channel_put),
|
||||||
|
SOC_ENUM_EXT("AFE Input Bit Format", afe_input_bit_format_enum[0],
|
||||||
|
msm_dai_q6_afe_input_bit_format_get,
|
||||||
|
msm_dai_q6_afe_input_bit_format_put),
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char * const afe_cal_mode_text[] = {
|
static const char * const afe_cal_mode_text[] = {
|
||||||
|
|
|
@ -2645,8 +2645,9 @@ exit:
|
||||||
}
|
}
|
||||||
|
|
||||||
static int q6afe_send_enc_config(u16 port_id,
|
static int q6afe_send_enc_config(u16 port_id,
|
||||||
union afe_enc_config_data *cfg, u32 format,
|
union afe_enc_config_data *cfg, u32 format,
|
||||||
union afe_port_config afe_config, u16 afe_in_channels)
|
union afe_port_config afe_config,
|
||||||
|
u16 afe_in_channels, u16 afe_in_bit_width)
|
||||||
{
|
{
|
||||||
struct afe_audioif_config_command config;
|
struct afe_audioif_config_command config;
|
||||||
int index;
|
int index;
|
||||||
|
@ -2728,8 +2729,13 @@ static int q6afe_send_enc_config(u16 port_id,
|
||||||
config.pdata.param_id = AFE_PARAM_ID_PORT_MEDIA_TYPE;
|
config.pdata.param_id = AFE_PARAM_ID_PORT_MEDIA_TYPE;
|
||||||
config.port.media_type.minor_version = AFE_API_VERSION_PORT_MEDIA_TYPE;
|
config.port.media_type.minor_version = AFE_API_VERSION_PORT_MEDIA_TYPE;
|
||||||
config.port.media_type.sample_rate = afe_config.slim_sch.sample_rate;
|
config.port.media_type.sample_rate = afe_config.slim_sch.sample_rate;
|
||||||
config.port.media_type.bit_width = afe_config.slim_sch.bit_width;
|
if (afe_in_bit_width)
|
||||||
if (afe_in_channels != 0)
|
config.port.media_type.bit_width = afe_in_bit_width;
|
||||||
|
else
|
||||||
|
config.port.media_type.bit_width =
|
||||||
|
afe_config.slim_sch.bit_width;
|
||||||
|
|
||||||
|
if (afe_in_channels)
|
||||||
config.port.media_type.num_channels = afe_in_channels;
|
config.port.media_type.num_channels = afe_in_channels;
|
||||||
else
|
else
|
||||||
config.port.media_type.num_channels =
|
config.port.media_type.num_channels =
|
||||||
|
@ -2749,8 +2755,8 @@ exit:
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __afe_port_start(u16 port_id, union afe_port_config *afe_config,
|
static int __afe_port_start(u16 port_id, union afe_port_config *afe_config,
|
||||||
u32 rate, u16 afe_in_channels,
|
u32 rate, u16 afe_in_channels, u16 afe_in_bit_width,
|
||||||
union afe_enc_config_data *cfg, u32 enc_format)
|
union afe_enc_config_data *cfg, u32 enc_format)
|
||||||
{
|
{
|
||||||
struct afe_audioif_config_command config;
|
struct afe_audioif_config_command config;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
@ -2989,7 +2995,8 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config,
|
||||||
pr_debug("%s: Found AFE encoder support for SLIMBUS enc_format = %d\n",
|
pr_debug("%s: Found AFE encoder support for SLIMBUS enc_format = %d\n",
|
||||||
__func__, enc_format);
|
__func__, enc_format);
|
||||||
ret = q6afe_send_enc_config(port_id, cfg, enc_format,
|
ret = q6afe_send_enc_config(port_id, cfg, enc_format,
|
||||||
*afe_config, afe_in_channels);
|
*afe_config, afe_in_channels,
|
||||||
|
afe_in_bit_width);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
pr_err("%s: AFE encoder config for port 0x%x failed %d\n",
|
pr_err("%s: AFE encoder config for port 0x%x failed %d\n",
|
||||||
__func__, port_id, ret);
|
__func__, port_id, ret);
|
||||||
|
@ -3043,7 +3050,7 @@ int afe_port_start(u16 port_id, union afe_port_config *afe_config,
|
||||||
u32 rate)
|
u32 rate)
|
||||||
{
|
{
|
||||||
return __afe_port_start(port_id, afe_config, rate,
|
return __afe_port_start(port_id, afe_config, rate,
|
||||||
0, NULL, ASM_MEDIA_FMT_NONE);
|
0, 0, NULL, ASM_MEDIA_FMT_NONE);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(afe_port_start);
|
EXPORT_SYMBOL(afe_port_start);
|
||||||
|
|
||||||
|
@ -3061,12 +3068,12 @@ EXPORT_SYMBOL(afe_port_start);
|
||||||
* Returns 0 on success or error value on port start failure.
|
* Returns 0 on success or error value on port start failure.
|
||||||
*/
|
*/
|
||||||
int afe_port_start_v2(u16 port_id, union afe_port_config *afe_config,
|
int afe_port_start_v2(u16 port_id, union afe_port_config *afe_config,
|
||||||
u32 rate, u16 afe_in_channels,
|
u32 rate, u16 afe_in_channels, u16 afe_in_bit_width,
|
||||||
struct afe_enc_config *enc_cfg)
|
struct afe_enc_config *enc_cfg)
|
||||||
{
|
{
|
||||||
return __afe_port_start(port_id, afe_config, rate,
|
return __afe_port_start(port_id, afe_config, rate,
|
||||||
afe_in_channels, &enc_cfg->data,
|
afe_in_channels, afe_in_bit_width,
|
||||||
enc_cfg->format);
|
&enc_cfg->data, enc_cfg->format);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(afe_port_start_v2);
|
EXPORT_SYMBOL(afe_port_start_v2);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue