Loading include/sound/apr_audio-v2.h +331 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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 { Loading include/sound/q6afe-v2.h +3 −0 Original line number Diff line number Diff line Loading @@ -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); Loading sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c +180 −3 Original line number Diff line number Diff line Loading @@ -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, Loading Loading @@ -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; }; Loading Loading @@ -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)) { 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); Loading Loading @@ -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" }; Loading Loading @@ -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], Loading sound/soc/msm/qdsp6v2/q6afe.c +166 −3 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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", Loading @@ -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; Loading Loading @@ -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 Loading
include/sound/apr_audio-v2.h +331 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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 { Loading
include/sound/q6afe-v2.h +3 −0 Original line number Diff line number Diff line Loading @@ -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); Loading
sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c +180 −3 Original line number Diff line number Diff line Loading @@ -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, Loading Loading @@ -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; }; Loading Loading @@ -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)) { 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); Loading Loading @@ -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" }; Loading Loading @@ -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], Loading
sound/soc/msm/qdsp6v2/q6afe.c +166 −3 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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", Loading @@ -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; Loading Loading @@ -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