Qualcomm DSPs also supports the ALAC and APE decoders, so add support for these and convert the snd_codec_params to qdsp format.
Reviewed-by: Srinivas Kandagatla srinivas.kandagatla@linaro.org Signed-off-by: Vinod Koul vkoul@kernel.org --- sound/soc/qcom/qdsp6/q6asm-dai.c | 70 +++++++++++++++++++++++++++++++- 1 file changed, 69 insertions(+), 1 deletion(-)
diff --git a/sound/soc/qcom/qdsp6/q6asm-dai.c b/sound/soc/qcom/qdsp6/q6asm-dai.c index 53c250778eea..833486545d4b 100644 --- a/sound/soc/qcom/qdsp6/q6asm-dai.c +++ b/sound/soc/qcom/qdsp6/q6asm-dai.c @@ -41,6 +41,9 @@ #define Q6ASM_DAI_TX 1 #define Q6ASM_DAI_RX 2
+#define ALAC_CH_LAYOUT_MONO ((101 << 16) | 1) +#define ALAC_CH_LAYOUT_STEREO ((101 << 16) | 2) + enum stream_state { Q6ASM_STREAM_IDLE = 0, Q6ASM_STREAM_STOPPED, @@ -628,12 +631,16 @@ static int q6asm_dai_compr_set_params(struct snd_compr_stream *stream, struct q6asm_dai_data *pdata; struct q6asm_flac_cfg flac_cfg; struct q6asm_wma_cfg wma_cfg; + struct q6asm_alac_cfg alac_cfg; + struct q6asm_ape_cfg ape_cfg; unsigned int wma_v9 = 0; struct device *dev = c->dev; int ret; union snd_codec_options *codec_options; struct snd_dec_flac *flac; struct snd_dec_wma *wma; + struct snd_dec_alac *alac; + struct snd_dec_ape *ape;
codec_options = &(prtd->codec_param.codec.options);
@@ -756,6 +763,65 @@ static int q6asm_dai_compr_set_params(struct snd_compr_stream *stream, dev_err(dev, "WMA9 CMD failed:%d\n", ret); return -EIO; } + break; + + case SND_AUDIOCODEC_ALAC: + memset(&alac_cfg, 0x0, sizeof(alac_cfg)); + alac = &codec_options->alac_d; + + alac_cfg.sample_rate = params->codec.sample_rate; + alac_cfg.avg_bit_rate = params->codec.bit_rate; + alac_cfg.bit_depth = prtd->bits_per_sample; + alac_cfg.num_channels = params->codec.ch_in; + + alac_cfg.frame_length = alac->frame_length; + alac_cfg.pb = alac->pb; + alac_cfg.mb = alac->mb; + alac_cfg.kb = alac->kb; + alac_cfg.max_run = alac->max_run; + alac_cfg.compatible_version = alac->compatible_version; + alac_cfg.max_frame_bytes = alac->max_frame_bytes; + + switch (params->codec.ch_in) { + case 1: + alac_cfg.channel_layout_tag = ALAC_CH_LAYOUT_MONO; + break; + case 2: + alac_cfg.channel_layout_tag = ALAC_CH_LAYOUT_STEREO; + break; + } + ret = q6asm_stream_media_format_block_alac(prtd->audio_client, + &alac_cfg); + if (ret < 0) { + dev_err(dev, "ALAC CMD Format block failed:%d\n", ret); + return -EIO; + } + break; + + case SND_AUDIOCODEC_APE: + memset(&ape_cfg, 0x0, sizeof(ape_cfg)); + ape = &codec_options->ape_d; + + ape_cfg.sample_rate = params->codec.sample_rate; + ape_cfg.num_channels = params->codec.ch_in; + ape_cfg.bits_per_sample = prtd->bits_per_sample; + + ape_cfg.compatible_version = ape->compatible_version; + ape_cfg.compression_level = ape->compression_level; + ape_cfg.format_flags = ape->format_flags; + ape_cfg.blocks_per_frame = ape->blocks_per_frame; + ape_cfg.final_frame_blocks = ape->final_frame_blocks; + ape_cfg.total_frames = ape->total_frames; + ape_cfg.seek_table_present = ape->seek_table_present; + + ret = q6asm_stream_media_format_block_ape(prtd->audio_client, + &ape_cfg); + if (ret < 0) { + dev_err(dev, "APE CMD Format block failed:%d\n", ret); + return -EIO; + } + break; + default: break; } @@ -855,10 +921,12 @@ static int q6asm_dai_compr_get_caps(struct snd_compr_stream *stream, caps->max_fragment_size = COMPR_PLAYBACK_MAX_FRAGMENT_SIZE; caps->min_fragments = COMPR_PLAYBACK_MIN_NUM_FRAGMENTS; caps->max_fragments = COMPR_PLAYBACK_MAX_NUM_FRAGMENTS; - caps->num_codecs = 3; + caps->num_codecs = 5; caps->codecs[0] = SND_AUDIOCODEC_MP3; caps->codecs[1] = SND_AUDIOCODEC_FLAC; caps->codecs[2] = SND_AUDIOCODEC_WMA; + caps->codecs[3] = SND_AUDIOCODEC_ALAC; + caps->codecs[4] = SND_AUDIOCODEC_APE;
return 0; }