Merge "ASoC: msm: qdsp6v2: support for AFE encoder"
This commit is contained in:
commit
fb24f59004
4 changed files with 680 additions and 6 deletions
|
@ -2738,6 +2738,333 @@ struct afe_param_id_set_topology_cfg {
|
|||
u32 topology_id;
|
||||
} __packed;
|
||||
|
||||
|
||||
/*
|
||||
* Generic encoder module ID.
|
||||
* This module supports the following parameter IDs:
|
||||
* #AVS_ENCODER_PARAM_ID_ENC_FMT_ID (cannot be set run time)
|
||||
* #AVS_ENCODER_PARAM_ID_ENC_CFG_BLK (may be set run time)
|
||||
* #AVS_ENCODER_PARAM_ID_ENC_BITRATE (may be set run time)
|
||||
* #AVS_ENCODER_PARAM_ID_PACKETIZER_ID (cannot be set run time)
|
||||
* Opcode - AVS_MODULE_ID_ENCODER
|
||||
* AFE Command AFE_PORT_CMD_SET_PARAM_V2 supports this module ID.
|
||||
*/
|
||||
#define AFE_MODULE_ID_ENCODER 0x00013229
|
||||
|
||||
/* Macro for defining the packetizer ID: COP. */
|
||||
#define AFE_MODULE_ID_PACKETIZER_COP 0x0001322A
|
||||
|
||||
/*
|
||||
* Packetizer type parameter for the #AVS_MODULE_ID_ENCODER module.
|
||||
* This parameter cannot be set runtime.
|
||||
*/
|
||||
#define AFE_ENCODER_PARAM_ID_PACKETIZER_ID 0x0001322E
|
||||
|
||||
/*
|
||||
* Encoder config block parameter for the #AVS_MODULE_ID_ENCODER module.
|
||||
* This parameter may be set runtime.
|
||||
*/
|
||||
#define AFE_ENCODER_PARAM_ID_ENC_CFG_BLK 0x0001322C
|
||||
|
||||
/*
|
||||
* Encoder format ID parameter for the #AVS_MODULE_ID_ENCODER module.
|
||||
* This parameter cannot be set runtime.
|
||||
*/
|
||||
#define AFE_ENCODER_PARAM_ID_ENC_FMT_ID 0x0001322B
|
||||
|
||||
/*
|
||||
* Data format to send compressed data
|
||||
* is transmitted/received over Slimbus lines.
|
||||
*/
|
||||
#define AFE_SB_DATA_FORMAT_GENERIC_COMPRESSED 0x3
|
||||
|
||||
/*
|
||||
* ID for AFE port module. This will be used to define port properties.
|
||||
* This module supports following parameter IDs:
|
||||
* #AFE_PARAM_ID_PORT_MEDIA_TYPE
|
||||
* To configure the port property, the client must use the
|
||||
* #AFE_PORT_CMD_SET_PARAM_V2 command,
|
||||
* and fill the module ID with the respective parameter IDs as listed above.
|
||||
* @apr_hdr_fields
|
||||
* Opcode -- AFE_MODULE_PORT
|
||||
*/
|
||||
#define AFE_MODULE_PORT 0x000102a6
|
||||
|
||||
/*
|
||||
* ID of the parameter used by #AFE_MODULE_PORT to set the port media type.
|
||||
* parameter ID is currently supported using#AFE_PORT_CMD_SET_PARAM_V2 command.
|
||||
*/
|
||||
#define AFE_PARAM_ID_PORT_MEDIA_TYPE 0x000102a7
|
||||
|
||||
/*
|
||||
* Macros for defining the "data_format" field in the
|
||||
* #AFE_PARAM_ID_PORT_MEDIA_TYPE
|
||||
*/
|
||||
#define AFE_PORT_DATA_FORMAT_PCM 0x0
|
||||
#define AFE_PORT_DATA_FORMAT_GENERIC_COMPRESSED 0x1
|
||||
|
||||
/*
|
||||
* Macro for defining the "minor_version" field in the
|
||||
* #AFE_PARAM_ID_PORT_MEDIA_TYPE
|
||||
*/
|
||||
#define AFE_API_VERSION_PORT_MEDIA_TYPE 0x1
|
||||
|
||||
#define ASM_MEDIA_FMT_NONE 0x0
|
||||
|
||||
/*
|
||||
* Media format ID for SBC encode configuration.
|
||||
* @par SBC encode configuration (asm_sbc_enc_cfg_t)
|
||||
* @table{weak__asm__sbc__enc__cfg__t}
|
||||
*/
|
||||
#define ASM_MEDIA_FMT_SBC 0x00010BF2
|
||||
|
||||
/* SBC channel Mono mode.*/
|
||||
#define ASM_MEDIA_FMT_SBC_CHANNEL_MODE_MONO 1
|
||||
|
||||
/* SBC channel Stereo mode. */
|
||||
#define ASM_MEDIA_FMT_SBC_CHANNEL_MODE_STEREO 2
|
||||
|
||||
/* SBC channel Dual Mono mode. */
|
||||
#define ASM_MEDIA_FMT_SBC_CHANNEL_MODE_DUAL_MONO 8
|
||||
|
||||
/* SBC channel Joint Stereo mode. */
|
||||
#define ASM_MEDIA_FMT_SBC_CHANNEL_MODE_JOINT_STEREO 9
|
||||
|
||||
/* SBC bit allocation method = loudness. */
|
||||
#define ASM_MEDIA_FMT_SBC_ALLOCATION_METHOD_LOUDNESS 0
|
||||
|
||||
/* SBC bit allocation method = SNR. */
|
||||
#define ASM_MEDIA_FMT_SBC_ALLOCATION_METHOD_SNR 1
|
||||
|
||||
|
||||
/*
|
||||
* Payload of the SBC encoder configuration parameters in the
|
||||
* #ASM_MEDIA_FMT_SBC media format.
|
||||
*/
|
||||
struct asm_sbc_enc_cfg_t {
|
||||
/*
|
||||
* Number of subbands.
|
||||
* @values 4, 8
|
||||
*/
|
||||
uint32_t num_subbands;
|
||||
|
||||
/*
|
||||
* Size of the encoded block in samples.
|
||||
* @values 4, 8, 12, 16
|
||||
*/
|
||||
uint32_t blk_len;
|
||||
|
||||
/*
|
||||
* Mode used to allocate bits between channels.
|
||||
* @values
|
||||
* 0 (Native mode)
|
||||
* #ASM_MEDIA_FMT_SBC_CHANNEL_MODE_MONO
|
||||
* #ASM_MEDIA_FMT_SBC_CHANNEL_MODE_STEREO
|
||||
* #ASM_MEDIA_FMT_SBC_CHANNEL_MODE_DUAL_MONO
|
||||
* #ASM_MEDIA_FMT_SBC_CHANNEL_MODE_JOINT_STEREO
|
||||
* Native mode indicates that encoding must be performed with the number
|
||||
* of channels at the input.
|
||||
* If postprocessing outputs one-channel data, Mono mode is used. If
|
||||
* postprocessing outputs two-channel data, Stereo mode is used.
|
||||
* The number of channels must not change during encoding.
|
||||
*/
|
||||
uint32_t channel_mode;
|
||||
|
||||
/*
|
||||
* Encoder bit allocation method.
|
||||
* @values
|
||||
* #ASM_MEDIA_FMT_SBC_ALLOCATION_METHOD_LOUDNESS
|
||||
* #ASM_MEDIA_FMT_SBC_ALLOCATION_METHOD_SNR @tablebulletend
|
||||
*/
|
||||
uint32_t alloc_method;
|
||||
|
||||
/*
|
||||
* Number of encoded bits per second.
|
||||
* @values
|
||||
* Mono channel -- Maximum of 320 kbps
|
||||
* Stereo channel -- Maximum of 512 kbps @tablebulletend
|
||||
*/
|
||||
uint32_t bit_rate;
|
||||
|
||||
/*
|
||||
* Number of samples per second.
|
||||
* @values 0 (Native mode), 16000, 32000, 44100, 48000 Hz
|
||||
* Native mode indicates that encoding must be performed with the
|
||||
* sampling rate at the input.
|
||||
* The sampling rate must not change during encoding.
|
||||
*/
|
||||
uint32_t sample_rate;
|
||||
};
|
||||
|
||||
#define ASM_MEDIA_FMT_AAC_AOT_LC 2
|
||||
#define ASM_MEDIA_FMT_AAC_AOT_SBR 5
|
||||
#define ASM_MEDIA_FMT_AAC_AOT_PS 29
|
||||
#define ASM_MEDIA_FMT_AAC_FORMAT_FLAG_ADTS 0
|
||||
#define ASM_MEDIA_FMT_AAC_FORMAT_FLAG_RAW 3
|
||||
|
||||
struct asm_aac_enc_cfg_v2_t {
|
||||
|
||||
/* Encoding rate in bits per second.*/
|
||||
uint32_t bit_rate;
|
||||
|
||||
/*
|
||||
* Encoding mode.
|
||||
* Supported values:
|
||||
* #ASM_MEDIA_FMT_AAC_AOT_LC
|
||||
* #ASM_MEDIA_FMT_AAC_AOT_SBR
|
||||
* #ASM_MEDIA_FMT_AAC_AOT_PS
|
||||
*/
|
||||
uint32_t enc_mode;
|
||||
|
||||
/*
|
||||
* AAC format flag.
|
||||
* Supported values:
|
||||
* #ASM_MEDIA_FMT_AAC_FORMAT_FLAG_ADTS
|
||||
* #ASM_MEDIA_FMT_AAC_FORMAT_FLAG_RAW
|
||||
*/
|
||||
uint16_t aac_fmt_flag;
|
||||
|
||||
/*
|
||||
* Number of channels to encode.
|
||||
* Supported values:
|
||||
* 0 - Native mode
|
||||
* 1 - Mono
|
||||
* 2 - Stereo
|
||||
* Other values are not supported.
|
||||
* @note1hang The eAAC+ encoder mode supports only stereo.
|
||||
* Native mode indicates that encoding must be performed with the
|
||||
* number of channels at the input.
|
||||
* The number of channels must not change during encoding.
|
||||
*/
|
||||
uint32_t channel_cfg;
|
||||
|
||||
/*
|
||||
* Number of samples per second.
|
||||
* Supported values: - 0 -- Native mode - For other values,
|
||||
* Native mode indicates that encoding must be performed with the
|
||||
* sampling rate at the input.
|
||||
* The sampling rate must not change during encoding.
|
||||
*/
|
||||
uint32_t sample_rate;
|
||||
} __packed;
|
||||
|
||||
/* FMT ID for apt-X Classic */
|
||||
#define ASM_MEDIA_FMT_APTX 0x000131ff
|
||||
|
||||
/* FMT ID for apt-X HD */
|
||||
#define ASM_MEDIA_FMT_APTX_HD 0x00013200
|
||||
|
||||
#define PCM_CHANNEL_L 1
|
||||
#define PCM_CHANNEL_R 2
|
||||
#define PCM_CHANNEL_C 3
|
||||
|
||||
struct asm_custom_enc_cfg_aptx_t {
|
||||
uint32_t sample_rate;
|
||||
/* Mono or stereo */
|
||||
uint16_t num_channels;
|
||||
uint16_t reserved;
|
||||
/* num_ch == 1, then PCM_CHANNEL_C,
|
||||
* num_ch == 2, then {PCM_CHANNEL_L, PCM_CHANNEL_R}
|
||||
*/
|
||||
uint8_t channel_mapping[8];
|
||||
uint32_t custom_size;
|
||||
} __packed;
|
||||
|
||||
struct afe_enc_fmt_id_param_t {
|
||||
/*
|
||||
* Supported values:
|
||||
* #ASM_MEDIA_FMT_SBC
|
||||
* #ASM_MEDIA_FMT_AAC_V2
|
||||
* Any OpenDSP supported values
|
||||
*/
|
||||
uint32_t fmt_id;
|
||||
} __packed;
|
||||
|
||||
struct afe_port_media_type_t {
|
||||
/*
|
||||
* Minor version
|
||||
* @values #AFE_API_VERSION_PORT_MEDIA_TYPE.
|
||||
*/
|
||||
uint32_t minor_version;
|
||||
|
||||
/*
|
||||
* Sampling rate of the port.
|
||||
* @values
|
||||
* #AFE_PORT_SAMPLE_RATE_8K
|
||||
* #AFE_PORT_SAMPLE_RATE_11_025K
|
||||
* #AFE_PORT_SAMPLE_RATE_12K
|
||||
* #AFE_PORT_SAMPLE_RATE_16K
|
||||
* #AFE_PORT_SAMPLE_RATE_22_05K
|
||||
* #AFE_PORT_SAMPLE_RATE_24K
|
||||
* #AFE_PORT_SAMPLE_RATE_32K
|
||||
* #AFE_PORT_SAMPLE_RATE_44_1K
|
||||
* #AFE_PORT_SAMPLE_RATE_48K
|
||||
* #AFE_PORT_SAMPLE_RATE_88_2K
|
||||
* #AFE_PORT_SAMPLE_RATE_96K
|
||||
* #AFE_PORT_SAMPLE_RATE_176_4K
|
||||
* #AFE_PORT_SAMPLE_RATE_192K
|
||||
* #AFE_PORT_SAMPLE_RATE_352_8K
|
||||
* #AFE_PORT_SAMPLE_RATE_384K
|
||||
*/
|
||||
uint32_t sample_rate;
|
||||
|
||||
/*
|
||||
* Bit width of the sample.
|
||||
* @values 16, 24
|
||||
*/
|
||||
uint16_t bit_width;
|
||||
|
||||
/*
|
||||
* Number of channels.
|
||||
* @values 1 to #AFE_PORT_MAX_AUDIO_CHAN_CNT
|
||||
*/
|
||||
uint16_t num_channels;
|
||||
|
||||
/*
|
||||
* Data format supported by this port.
|
||||
* If the port media type and device media type are different,
|
||||
* it signifies a encoding/decoding use case
|
||||
* @values
|
||||
* #AFE_PORT_DATA_FORMAT_PCM
|
||||
* #AFE_PORT_DATA_FORMAT_GENERIC_COMPRESSED
|
||||
*/
|
||||
uint16_t data_format;
|
||||
|
||||
/*This field must be set to zero.*/
|
||||
uint16_t reserved;
|
||||
} __packed;
|
||||
|
||||
union afe_enc_config_data {
|
||||
struct asm_sbc_enc_cfg_t sbc_config;
|
||||
struct asm_aac_enc_cfg_v2_t aac_config;
|
||||
struct asm_custom_enc_cfg_aptx_t aptx_config;
|
||||
};
|
||||
|
||||
struct afe_enc_config {
|
||||
u32 format;
|
||||
union afe_enc_config_data data;
|
||||
};
|
||||
|
||||
struct afe_enc_cfg_blk_param_t {
|
||||
uint32_t enc_cfg_blk_size;
|
||||
/*
|
||||
*Size of the encoder configuration block that follows this member
|
||||
*/
|
||||
union afe_enc_config_data enc_blk_config;
|
||||
};
|
||||
|
||||
/*
|
||||
* Payload of the AVS_ENCODER_PARAM_ID_PACKETIZER_ID parameter.
|
||||
*/
|
||||
struct avs_enc_packetizer_id_param_t {
|
||||
/*
|
||||
* Supported values:
|
||||
* #AVS_MODULE_ID_PACKETIZER_COP
|
||||
* Any OpenDSP supported values
|
||||
*/
|
||||
uint32_t enc_packetizer_id;
|
||||
};
|
||||
|
||||
union afe_port_config {
|
||||
struct afe_param_id_pcm_cfg pcm;
|
||||
struct afe_param_id_i2s_cfg i2s;
|
||||
|
@ -2751,6 +3078,10 @@ union afe_port_config {
|
|||
struct afe_param_id_set_topology_cfg topology;
|
||||
struct afe_param_id_tdm_cfg tdm;
|
||||
struct afe_param_id_usb_audio_cfg usb_audio;
|
||||
struct afe_enc_fmt_id_param_t enc_fmt;
|
||||
struct afe_port_media_type_t media_type;
|
||||
struct afe_enc_cfg_blk_param_t enc_blk_param;
|
||||
struct avs_enc_packetizer_id_param_t enc_pkt_id_param;
|
||||
} __packed;
|
||||
|
||||
struct afe_audioif_config_command_no_payload {
|
||||
|
|
|
@ -274,6 +274,9 @@ int afe_rt_proxy_port_read(phys_addr_t buf_addr_p,
|
|||
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,
|
||||
u32 rate);
|
||||
int afe_port_start_v2(u16 port_id, union afe_port_config *afe_config,
|
||||
u32 rate, u16 afe_in_channels,
|
||||
struct afe_enc_config *enc_config);
|
||||
int afe_spk_prot_feed_back_cfg(int src_port, int dst_port,
|
||||
int l_ch, int r_ch, u32 enable);
|
||||
int afe_spk_prot_get_calib_data(struct afe_spkr_prot_get_vi_calib *calib);
|
||||
|
|
|
@ -37,6 +37,14 @@
|
|||
#define CHANNEL_STATUS_MASK 0x4
|
||||
#define AFE_API_VERSION_CLOCK_SET 1
|
||||
|
||||
enum {
|
||||
ENC_FMT_NONE,
|
||||
ENC_FMT_SBC = ASM_MEDIA_FMT_SBC,
|
||||
ENC_FMT_AAC_V2 = ASM_MEDIA_FMT_AAC_V2,
|
||||
ENC_FMT_APTX = ASM_MEDIA_FMT_APTX,
|
||||
ENC_FMT_APTX_HD = ASM_MEDIA_FMT_APTX_HD,
|
||||
};
|
||||
|
||||
static const struct afe_clk_set lpass_clk_set_default = {
|
||||
AFE_API_VERSION_CLOCK_SET,
|
||||
Q6AFE_LPASS_CLK_ID_PRI_PCM_IBIT,
|
||||
|
@ -157,6 +165,8 @@ struct msm_dai_q6_dai_data {
|
|||
u32 channels;
|
||||
u32 bitwidth;
|
||||
u32 cal_mode;
|
||||
u32 afe_in_channels;
|
||||
struct afe_enc_config enc_config;
|
||||
union afe_port_config port_config;
|
||||
};
|
||||
|
||||
|
@ -1330,9 +1340,20 @@ static int msm_dai_q6_prepare(struct snd_pcm_substream *substream,
|
|||
int rc = 0;
|
||||
|
||||
if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
|
||||
rc = afe_port_start(dai->id, &dai_data->port_config,
|
||||
dai_data->rate);
|
||||
|
||||
if (dai_data->enc_config.format != ENC_FMT_NONE) {
|
||||
pr_debug("%s: calling AFE_PORT_START_V2 with enc_format: %d\n",
|
||||
__func__, dai_data->enc_config.format);
|
||||
rc = afe_port_start_v2(dai->id, &dai_data->port_config,
|
||||
dai_data->rate,
|
||||
dai_data->afe_in_channels,
|
||||
&dai_data->enc_config);
|
||||
if (rc < 0)
|
||||
pr_err("%s: afe_port_start_v2 failed error: %d\n",
|
||||
__func__, rc);
|
||||
} else {
|
||||
rc = afe_port_start(dai->id, &dai_data->port_config,
|
||||
dai_data->rate);
|
||||
}
|
||||
if (IS_ERR_VALUE(rc))
|
||||
dev_err(dai->dev, "fail to open AFE port 0x%x\n",
|
||||
dai->id);
|
||||
|
@ -1941,6 +1962,151 @@ static int msm_dai_q6_usb_audio_cfg_get(struct snd_kcontrol *kcontrol,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int msm_dai_q6_afe_enc_cfg_info(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_info *uinfo)
|
||||
{
|
||||
uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
|
||||
uinfo->count = sizeof(struct afe_enc_config);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msm_dai_q6_afe_enc_cfg_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
int ret = 0;
|
||||
struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data;
|
||||
|
||||
if (dai_data) {
|
||||
int format_size = sizeof(dai_data->enc_config.format);
|
||||
|
||||
pr_debug("%s:encoder config for %d format\n",
|
||||
__func__, dai_data->enc_config.format);
|
||||
memcpy(ucontrol->value.bytes.data,
|
||||
&dai_data->enc_config.format,
|
||||
format_size);
|
||||
switch (dai_data->enc_config.format) {
|
||||
case ENC_FMT_SBC:
|
||||
memcpy(ucontrol->value.bytes.data + format_size,
|
||||
&dai_data->enc_config.data,
|
||||
sizeof(struct asm_sbc_enc_cfg_t));
|
||||
break;
|
||||
case ENC_FMT_AAC_V2:
|
||||
memcpy(ucontrol->value.bytes.data + format_size,
|
||||
&dai_data->enc_config.data,
|
||||
sizeof(struct asm_aac_enc_cfg_v2_t));
|
||||
break;
|
||||
case ENC_FMT_APTX:
|
||||
case ENC_FMT_APTX_HD:
|
||||
memcpy(ucontrol->value.bytes.data + format_size,
|
||||
&dai_data->enc_config.data,
|
||||
sizeof(struct asm_aac_enc_cfg_v2_t));
|
||||
break;
|
||||
default:
|
||||
pr_debug("%s: unknown format = %d\n",
|
||||
__func__, dai_data->enc_config.format);
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int msm_dai_q6_afe_enc_cfg_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
int ret = 0;
|
||||
struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data;
|
||||
|
||||
if (dai_data) {
|
||||
int format_size = sizeof(dai_data->enc_config.format);
|
||||
|
||||
memset(&dai_data->enc_config, 0x0,
|
||||
sizeof(struct afe_enc_config));
|
||||
memcpy(&dai_data->enc_config.format,
|
||||
ucontrol->value.bytes.data,
|
||||
format_size);
|
||||
pr_debug("%s: Received encoder config for %d format\n",
|
||||
__func__, dai_data->enc_config.format);
|
||||
switch (dai_data->enc_config.format) {
|
||||
case ENC_FMT_SBC:
|
||||
memcpy(&dai_data->enc_config.data,
|
||||
ucontrol->value.bytes.data + format_size,
|
||||
sizeof(struct asm_sbc_enc_cfg_t));
|
||||
break;
|
||||
case ENC_FMT_AAC_V2:
|
||||
memcpy(&dai_data->enc_config.data,
|
||||
ucontrol->value.bytes.data + format_size,
|
||||
sizeof(struct asm_aac_enc_cfg_v2_t));
|
||||
break;
|
||||
case ENC_FMT_APTX:
|
||||
case ENC_FMT_APTX_HD:
|
||||
memcpy(&dai_data->enc_config.data,
|
||||
ucontrol->value.bytes.data + format_size,
|
||||
sizeof(struct asm_custom_enc_cfg_aptx_t));
|
||||
break;
|
||||
default:
|
||||
pr_debug("%s: Ignore enc config for unknown format = %d\n",
|
||||
__func__, dai_data->enc_config.format);
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
} else
|
||||
ret = -EINVAL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const char *const afe_input_chs_text[] = {"Zero", "One", "Two"};
|
||||
|
||||
static const struct soc_enum afe_input_chs_enum[] = {
|
||||
SOC_ENUM_SINGLE_EXT(3, afe_input_chs_text),
|
||||
};
|
||||
|
||||
static int msm_dai_q6_afe_input_channel_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) {
|
||||
ucontrol->value.integer.value[0] = dai_data->afe_in_channels;
|
||||
pr_debug("%s:afe input channel = %d\n",
|
||||
__func__, dai_data->afe_in_channels);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msm_dai_q6_afe_input_channel_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) {
|
||||
dai_data->afe_in_channels = ucontrol->value.integer.value[0];
|
||||
pr_debug("%s: updating afe input channel : %d\n",
|
||||
__func__, dai_data->afe_in_channels);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct snd_kcontrol_new afe_enc_config_controls[] = {
|
||||
{
|
||||
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
|
||||
SNDRV_CTL_ELEM_ACCESS_INACTIVE),
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
|
||||
.name = "SLIM_7_RX Encoder Config",
|
||||
.info = msm_dai_q6_afe_enc_cfg_info,
|
||||
.get = msm_dai_q6_afe_enc_cfg_get,
|
||||
.put = msm_dai_q6_afe_enc_cfg_put,
|
||||
},
|
||||
SOC_ENUM_EXT("AFE Input Channels", afe_input_chs_enum[0],
|
||||
msm_dai_q6_afe_input_channel_get,
|
||||
msm_dai_q6_afe_input_channel_put),
|
||||
};
|
||||
|
||||
static const char * const afe_cal_mode_text[] = {
|
||||
"CAL_MODE_DEFAULT", "CAL_MODE_NONE"
|
||||
};
|
||||
|
@ -2020,6 +2186,17 @@ static int msm_dai_q6_dai_probe(struct snd_soc_dai *dai)
|
|||
snd_ctl_new1(&sb_config_controls[1],
|
||||
dai_data));
|
||||
break;
|
||||
case SLIMBUS_7_RX:
|
||||
rc = snd_ctl_add(dai->component->card->snd_card,
|
||||
snd_ctl_new1(&afe_enc_config_controls[0],
|
||||
dai_data));
|
||||
rc = snd_ctl_add(dai->component->card->snd_card,
|
||||
snd_ctl_new1(&afe_enc_config_controls[1],
|
||||
dai_data));
|
||||
rc = snd_ctl_add(dai->component->card->snd_card,
|
||||
snd_ctl_new1(&afe_enc_config_controls[2],
|
||||
dai_data));
|
||||
break;
|
||||
case RT_PROXY_DAI_001_RX:
|
||||
rc = snd_ctl_add(dai->component->card->snd_card,
|
||||
snd_ctl_new1(&rt_proxy_config_controls[0],
|
||||
|
|
|
@ -2632,8 +2632,113 @@ exit:
|
|||
return ret;
|
||||
}
|
||||
|
||||
int afe_port_start(u16 port_id, union afe_port_config *afe_config,
|
||||
u32 rate) /* This function is no blocking */
|
||||
static int q6afe_send_enc_config(u16 port_id,
|
||||
union afe_enc_config_data *cfg, u32 format,
|
||||
union afe_port_config afe_config, u16 afe_in_channels)
|
||||
{
|
||||
struct afe_audioif_config_command config;
|
||||
int index;
|
||||
int ret;
|
||||
int payload_size = sizeof(config) - sizeof(struct apr_hdr) -
|
||||
sizeof(config.param) - sizeof(config.port);
|
||||
|
||||
pr_debug("%s:update DSP for enc format = %d\n", __func__, format);
|
||||
if (format != ASM_MEDIA_FMT_SBC && format != ASM_MEDIA_FMT_AAC_V2 &&
|
||||
format != ASM_MEDIA_FMT_APTX && format != ASM_MEDIA_FMT_APTX_HD) {
|
||||
pr_err("%s:Unsuppported format Ignore AFE config\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
memset(&config, 0, sizeof(config));
|
||||
index = q6audio_get_port_index(port_id);
|
||||
config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
|
||||
APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
|
||||
config.hdr.pkt_size = sizeof(config);
|
||||
config.hdr.src_port = 0;
|
||||
config.hdr.dest_port = 0;
|
||||
config.hdr.token = index;
|
||||
|
||||
config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
|
||||
config.param.port_id = q6audio_get_port_id(port_id);
|
||||
config.param.payload_size = payload_size + sizeof(config.port.enc_fmt);
|
||||
config.param.payload_address_lsw = 0x00;
|
||||
config.param.payload_address_msw = 0x00;
|
||||
config.param.mem_map_handle = 0x00;
|
||||
config.pdata.module_id = AFE_MODULE_ID_ENCODER;
|
||||
config.pdata.param_id = AFE_ENCODER_PARAM_ID_ENC_FMT_ID;
|
||||
config.pdata.param_size = sizeof(config.port.enc_fmt);
|
||||
config.port.enc_fmt.fmt_id = format;
|
||||
pr_debug("%s:sending AFE_ENCODER_PARAM_ID_ENC_FMT_ID payload: %d\n",
|
||||
__func__, config.param.payload_size);
|
||||
ret = afe_apr_send_pkt(&config, &this_afe.wait[index]);
|
||||
if (ret) {
|
||||
pr_err("%s:unable to send AFE_ENCODER_PARAM_ID_ENC_FMT_ID",
|
||||
__func__);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
config.param.payload_size = payload_size
|
||||
+ sizeof(config.port.enc_blk_param);
|
||||
pr_debug("%s:send AFE_ENCODER_PARAM_ID_ENC_CFG_BLK to DSP payload:%d\n",
|
||||
__func__, config.param.payload_size);
|
||||
config.pdata.param_id = AFE_ENCODER_PARAM_ID_ENC_CFG_BLK;
|
||||
config.pdata.param_size = sizeof(config.port.enc_blk_param);
|
||||
config.port.enc_blk_param.enc_cfg_blk_size =
|
||||
sizeof(config.port.enc_blk_param.enc_blk_config);
|
||||
config.port.enc_blk_param.enc_blk_config = *cfg;
|
||||
ret = afe_apr_send_pkt(&config, &this_afe.wait[index]);
|
||||
if (ret) {
|
||||
pr_err("%s: AFE_ENCODER_PARAM_ID_ENC_CFG_BLK for port 0x%x failed %d\n",
|
||||
__func__, port_id, ret);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
config.param.payload_size =
|
||||
payload_size + sizeof(config.port.enc_pkt_id_param);
|
||||
pr_debug("%s:sending AFE_ENCODER_PARAM_ID_PACKETIZER to DSP payload = %d",
|
||||
__func__, config.param.payload_size);
|
||||
config.pdata.param_id = AFE_ENCODER_PARAM_ID_PACKETIZER_ID;
|
||||
config.pdata.param_size = sizeof(config.port.enc_pkt_id_param);
|
||||
config.port.enc_pkt_id_param.enc_packetizer_id =
|
||||
AFE_MODULE_ID_PACKETIZER_COP;
|
||||
ret = afe_apr_send_pkt(&config, &this_afe.wait[index]);
|
||||
if (ret) {
|
||||
pr_err("%s: AFE_ENCODER_PARAM_ID_PACKETIZER for port 0x%x failed %d\n",
|
||||
__func__, port_id, ret);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
config.param.payload_size =
|
||||
payload_size + sizeof(config.port.media_type);
|
||||
config.pdata.param_size = sizeof(config.port.media_type);
|
||||
|
||||
pr_debug("%s:Sending AFE_API_VERSION_PORT_MEDIA_TYPE to DSP", __func__);
|
||||
config.pdata.module_id = AFE_MODULE_PORT;
|
||||
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.sample_rate = afe_config.slim_sch.sample_rate;
|
||||
config.port.media_type.bit_width = afe_config.slim_sch.bit_width;
|
||||
if (afe_in_channels != 0)
|
||||
config.port.media_type.num_channels = afe_in_channels;
|
||||
else
|
||||
config.port.media_type.num_channels =
|
||||
afe_config.slim_sch.num_channels;
|
||||
config.port.media_type.data_format = AFE_PORT_DATA_FORMAT_PCM;
|
||||
config.port.media_type.reserved = 0;
|
||||
|
||||
ret = afe_apr_send_pkt(&config, &this_afe.wait[index]);
|
||||
if (ret) {
|
||||
pr_err("%s: AFE_API_VERSION_PORT_MEDIA_TYPE for port 0x%x failed %d\n",
|
||||
__func__, port_id, ret);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
exit:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __afe_port_start(u16 port_id, union afe_port_config *afe_config,
|
||||
u32 rate, u16 afe_in_channels,
|
||||
union afe_enc_config_data *cfg, u32 enc_format)
|
||||
{
|
||||
struct afe_audioif_config_command config;
|
||||
int ret = 0;
|
||||
|
@ -2850,7 +2955,11 @@ int afe_port_start(u16 port_id, union afe_port_config *afe_config,
|
|||
config.pdata.param_size = sizeof(config.port);
|
||||
|
||||
config.port = *afe_config;
|
||||
|
||||
if ((enc_format != ASM_MEDIA_FMT_NONE) &&
|
||||
(cfg_type == AFE_PARAM_ID_SLIMBUS_CONFIG)) {
|
||||
config.port.slim_sch.data_format =
|
||||
AFE_SB_DATA_FORMAT_GENERIC_COMPRESSED;
|
||||
}
|
||||
ret = afe_apr_send_pkt(&config, &this_afe.wait[index]);
|
||||
if (ret) {
|
||||
pr_err("%s: AFE enable for port 0x%x failed %d\n",
|
||||
|
@ -2858,6 +2967,19 @@ int afe_port_start(u16 port_id, union afe_port_config *afe_config,
|
|||
goto fail_cmd;
|
||||
}
|
||||
|
||||
if ((enc_format != ASM_MEDIA_FMT_NONE) &&
|
||||
(cfg_type == AFE_PARAM_ID_SLIMBUS_CONFIG)) {
|
||||
pr_debug("%s: Found AFE encoder support for SLIMBUS enc_format = %d\n",
|
||||
__func__, enc_format);
|
||||
ret = q6afe_send_enc_config(port_id, cfg, enc_format,
|
||||
*afe_config, afe_in_channels);
|
||||
if (ret) {
|
||||
pr_err("%s: AFE encoder config for port 0x%x failed %d\n",
|
||||
__func__, port_id, ret);
|
||||
goto fail_cmd;
|
||||
}
|
||||
}
|
||||
|
||||
port_index = afe_get_port_index(port_id);
|
||||
if ((port_index >= 0) && (port_index < AFE_MAX_PORTS)) {
|
||||
this_afe.afe_sample_rates[port_index] = rate;
|
||||
|
@ -2890,6 +3012,47 @@ fail_cmd:
|
|||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* afe_port_start - to configure AFE session with
|
||||
* specified port configuration
|
||||
*
|
||||
* @port_id: AFE port id number
|
||||
* @afe_config: port configutation
|
||||
* @rate: sampling rate of port
|
||||
*
|
||||
* Returns 0 on success or error value on port start failure.
|
||||
*/
|
||||
int afe_port_start(u16 port_id, union afe_port_config *afe_config,
|
||||
u32 rate)
|
||||
{
|
||||
return __afe_port_start(port_id, afe_config, rate,
|
||||
0, NULL, ASM_MEDIA_FMT_NONE);
|
||||
}
|
||||
EXPORT_SYMBOL(afe_port_start);
|
||||
|
||||
/**
|
||||
* afe_port_start_v2 - to configure AFE session with
|
||||
* specified port configuration and encoder params
|
||||
*
|
||||
* @port_id: AFE port id number
|
||||
* @afe_config: port configutation
|
||||
* @rate: sampling rate of port
|
||||
* @cfg: AFE encoder configuration information to setup encoder
|
||||
* @afe_in_channels: AFE input channel configuration, this needs
|
||||
* update only if input channel is differ from AFE output
|
||||
*
|
||||
* 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,
|
||||
u32 rate, u16 afe_in_channels,
|
||||
struct afe_enc_config *enc_cfg)
|
||||
{
|
||||
return __afe_port_start(port_id, afe_config, rate,
|
||||
afe_in_channels, &enc_cfg->data,
|
||||
enc_cfg->format);
|
||||
}
|
||||
EXPORT_SYMBOL(afe_port_start_v2);
|
||||
|
||||
int afe_get_port_index(u16 port_id)
|
||||
{
|
||||
switch (port_id) {
|
||||
|
|
Loading…
Add table
Reference in a new issue