ASoc: msm: Add amr-wb/wb+ tunnel playback support
Update compress audio platform driver to support amr-wb/wb+ tunnel mode playback. Change-Id: I98d087db490441c57c8e2d4fe03a7e91b28e67fc Signed-off-by: Ajit Khare <ajitk@codeaurora.org>
This commit is contained in:
@@ -978,6 +978,16 @@ struct asm_aac_cfg {
|
||||
u32 sample_rate;
|
||||
};
|
||||
|
||||
struct asm_amrwbplus_cfg {
|
||||
u32 size_bytes;
|
||||
u32 version;
|
||||
u32 num_channels;
|
||||
u32 amr_band_mode;
|
||||
u32 amr_dtx_mode;
|
||||
u32 amr_frame_fmt;
|
||||
u32 amr_lsf_idx;
|
||||
};
|
||||
|
||||
struct asm_flac_cfg {
|
||||
u16 stream_info_present;
|
||||
u16 min_blk_size;
|
||||
@@ -1398,6 +1408,7 @@ struct asm_stream_media_format_update{
|
||||
struct asm_flac_cfg flac_cfg;
|
||||
struct asm_vorbis_cfg vorbis_cfg;
|
||||
struct asm_multi_channel_pcm_fmt_blk multi_ch_pcm_cfg;
|
||||
struct asm_amrwbplus_cfg amrwbplus_cfg;
|
||||
} __attribute__((packed)) write_cfg;
|
||||
} __attribute__((packed));
|
||||
|
||||
|
||||
@@ -288,6 +288,9 @@ int q6asm_media_format_block_multi_ch_pcm(struct audio_client *ac,
|
||||
int q6asm_media_format_block_aac(struct audio_client *ac,
|
||||
struct asm_aac_cfg *cfg);
|
||||
|
||||
int q6asm_media_format_block_amrwbplus(struct audio_client *ac,
|
||||
struct asm_amrwbplus_cfg *cfg);
|
||||
|
||||
int q6asm_media_format_block_multi_aac(struct audio_client *ac,
|
||||
struct asm_aac_cfg *cfg);
|
||||
|
||||
|
||||
@@ -86,10 +86,10 @@ static struct snd_pcm_hardware msm_compr_hardware_playback = {
|
||||
.channels_min = 1,
|
||||
.channels_max = 8,
|
||||
.buffer_bytes_max = 1200 * 1024 * 2,
|
||||
.period_bytes_min = 4800,
|
||||
.period_bytes_min = 2400,
|
||||
.period_bytes_max = 1200 * 1024,
|
||||
.periods_min = 2,
|
||||
.periods_max = 512,
|
||||
.periods_max = 1024,
|
||||
.fifo_size = 0,
|
||||
};
|
||||
|
||||
@@ -336,6 +336,7 @@ static int msm_compr_playback_prepare(struct snd_pcm_substream *substream)
|
||||
struct asm_aac_cfg aac_cfg;
|
||||
struct asm_wma_cfg wma_cfg;
|
||||
struct asm_wmapro_cfg wma_pro_cfg;
|
||||
struct asm_amrwbplus_cfg amrwb_cfg;
|
||||
int ret;
|
||||
|
||||
pr_debug("compressed stream prepare\n");
|
||||
@@ -433,6 +434,27 @@ static int msm_compr_playback_prepare(struct snd_pcm_substream *substream)
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
case SND_AUDIOCODEC_AMRWB:
|
||||
pr_debug("SND_AUDIOCODEC_AMRWB\n");
|
||||
ret = q6asm_media_format_block(prtd->audio_client,
|
||||
compr->codec);
|
||||
if (ret < 0) {
|
||||
pr_err("%s: CMD Format block failed\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
case SND_AUDIOCODEC_AMRWBPLUS:
|
||||
pr_debug("SND_AUDIOCODEC_AMRWBPLUS\n");
|
||||
memset(&amrwb_cfg, 0x0, sizeof(struct asm_amrwbplus_cfg));
|
||||
amrwb_cfg.size_bytes = sizeof(struct asm_amrwbplus_cfg);
|
||||
pr_debug("calling q6asm_media_format_block_amrwbplus");
|
||||
ret = q6asm_media_format_block_amrwbplus(prtd->audio_client,
|
||||
&amrwb_cfg);
|
||||
if (ret < 0) {
|
||||
pr_err("%s: CMD Format block failed\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -595,7 +617,7 @@ static void populate_codec_list(struct compr_audio *compr,
|
||||
{
|
||||
pr_debug("%s\n", __func__);
|
||||
/* MP3 Block */
|
||||
compr->info.compr_cap.num_codecs = 1;
|
||||
compr->info.compr_cap.num_codecs = 10;
|
||||
compr->info.compr_cap.min_fragment_size = runtime->hw.period_bytes_min;
|
||||
compr->info.compr_cap.max_fragment_size = runtime->hw.period_bytes_max;
|
||||
compr->info.compr_cap.min_fragments = runtime->hw.periods_min;
|
||||
@@ -608,7 +630,6 @@ static void populate_codec_list(struct compr_audio *compr,
|
||||
compr->info.compr_cap.codecs[5] = SND_AUDIOCODEC_DTS;
|
||||
compr->info.compr_cap.codecs[6] = SND_AUDIOCODEC_DTS_LBR;
|
||||
compr->info.compr_cap.codecs[7] = SND_AUDIOCODEC_DTS_PASS_THROUGH;
|
||||
/* Add new codecs here */
|
||||
compr->info.compr_cap.codecs[8] = SND_AUDIOCODEC_AMRWB;
|
||||
compr->info.compr_cap.codecs[9] = SND_AUDIOCODEC_AMRWBPLUS;
|
||||
/* Add new codecs here and update num_codecs*/
|
||||
@@ -1031,6 +1052,14 @@ static int msm_compr_ioctl(struct snd_pcm_substream *substream,
|
||||
pr_debug("SND_AUDIOCODEC_DTS\n");
|
||||
compr->codec = FORMAT_DTS_LBR;
|
||||
break;
|
||||
case SND_AUDIOCODEC_AMRWB:
|
||||
pr_debug("msm_compr_ioctl SND_AUDIOCODEC_AMRWB\n");
|
||||
compr->codec = FORMAT_AMRWB;
|
||||
break;
|
||||
case SND_AUDIOCODEC_AMRWBPLUS:
|
||||
pr_debug("msm_compr_ioctl SND_AUDIOCODEC_AMRWBPLUS\n");
|
||||
compr->codec = FORMAT_AMR_WB_PLUS;
|
||||
break;
|
||||
default:
|
||||
/*Needed for the HDMI IN compressed use case*/
|
||||
pr_debug("FORMAT_LINEAR_PCM\n");
|
||||
|
||||
@@ -1547,6 +1547,14 @@ int q6asm_open_write(struct audio_client *ac, uint32_t format)
|
||||
case FORMAT_DTS_LBR:
|
||||
open.format = DTS_LBR;
|
||||
break;
|
||||
case FORMAT_AMRWB:
|
||||
open.format = AMRWB_FS;
|
||||
pr_debug("q6asm_open_write FORMAT_AMRWB");
|
||||
break;
|
||||
case FORMAT_AMR_WB_PLUS:
|
||||
open.format = AMR_WB_PLUS;
|
||||
pr_debug("q6asm_open_write FORMAT_AMR_WB_PLUS");
|
||||
break;
|
||||
default:
|
||||
pr_err("%s: Invalid format[%d]\n", __func__, format);
|
||||
goto fail_cmd;
|
||||
@@ -2430,7 +2438,56 @@ fail_cmd:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int q6asm_media_format_block_amrwbplus(struct audio_client *ac,
|
||||
struct asm_amrwbplus_cfg *cfg)
|
||||
{
|
||||
struct asm_stream_media_format_update fmt;
|
||||
int rc = 0;
|
||||
pr_debug("q6asm_media_format_block_amrwbplus");
|
||||
|
||||
pr_debug("%s:session[%d]band-mode[%d]frame-fmt[%d]ch[%d]\n",
|
||||
__func__,
|
||||
ac->session,
|
||||
cfg->amr_band_mode,
|
||||
cfg->amr_frame_fmt,
|
||||
cfg->num_channels);
|
||||
|
||||
q6asm_add_hdr(ac, &fmt.hdr, sizeof(fmt), TRUE);
|
||||
|
||||
fmt.hdr.opcode = ASM_DATA_CMD_MEDIA_FORMAT_UPDATE;
|
||||
|
||||
fmt.format = AMR_WB_PLUS;
|
||||
fmt.cfg_size = cfg->size_bytes;
|
||||
|
||||
fmt.write_cfg.amrwbplus_cfg.size_bytes = cfg->size_bytes;
|
||||
fmt.write_cfg.amrwbplus_cfg.version = cfg->version;
|
||||
fmt.write_cfg.amrwbplus_cfg.num_channels = cfg->num_channels;
|
||||
fmt.write_cfg.amrwbplus_cfg.amr_band_mode = cfg->amr_band_mode;
|
||||
fmt.write_cfg.amrwbplus_cfg.amr_dtx_mode = cfg->amr_dtx_mode;
|
||||
fmt.write_cfg.amrwbplus_cfg.amr_frame_fmt = cfg->amr_frame_fmt;
|
||||
fmt.write_cfg.amrwbplus_cfg.amr_lsf_idx = cfg->amr_lsf_idx;
|
||||
|
||||
pr_debug("%s: num_channels=%x amr_band_mode=%d amr_frame_fmt=%d\n",
|
||||
__func__,
|
||||
cfg->num_channels,
|
||||
cfg->amr_band_mode,
|
||||
cfg->amr_frame_fmt);
|
||||
|
||||
rc = apr_send_pkt(ac->apr, (uint32_t *) &fmt);
|
||||
if (rc < 0) {
|
||||
pr_err("%s:Comamnd media format update failed..\n", __func__);
|
||||
goto fail_cmd;
|
||||
}
|
||||
rc = wait_event_timeout(ac->cmd_wait,
|
||||
(atomic_read(&ac->cmd_state) == 0), 5*HZ);
|
||||
if (!rc) {
|
||||
pr_err("%s:timeout. waited for FORMAT_UPDATE\n", __func__);
|
||||
goto fail_cmd;
|
||||
}
|
||||
return 0;
|
||||
fail_cmd:
|
||||
return -EINVAL;
|
||||
}
|
||||
int q6asm_media_format_block_multi_aac(struct audio_client *ac,
|
||||
struct asm_aac_cfg *cfg)
|
||||
{
|
||||
@@ -2502,6 +2559,9 @@ int q6asm_media_format_block(struct audio_client *ac, uint32_t format)
|
||||
case FORMAT_AMRWB:
|
||||
fmt.format = AMRWB_FS;
|
||||
break;
|
||||
case FORMAT_AMR_WB_PLUS:
|
||||
fmt.format = AMR_WB_PLUS;
|
||||
break;
|
||||
case FORMAT_AMRNB:
|
||||
fmt.format = AMRNB_FS;
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user