OSDN Git Service

ASoC: qcom: q6asm: add support to flac config
authorSrinivas Kandagatla <srinivas.kandagatla@linaro.org>
Fri, 15 Nov 2019 10:27:04 +0000 (15:57 +0530)
committerMark Brown <broonie@kernel.org>
Mon, 18 Nov 2019 13:02:34 +0000 (13:02 +0000)
Qualcomm DSPs expect flac config to be set for flac decoders, so add the
API to program the flac config to the DSP

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Link: https://lore.kernel.org/r/20191115102705.649976-3-vkoul@kernel.org
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/qcom/qdsp6/q6asm.c
sound/soc/qcom/qdsp6/q6asm.h

index e8141a3..36e0eab 100644 (file)
@@ -38,6 +38,7 @@
 #define ASM_SESSION_CMD_RUN_V2                 0x00010DAA
 #define ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V2     0x00010DA5
 #define ASM_MEDIA_FMT_MP3                      0x00010BE9
+#define ASM_MEDIA_FMT_FLAC                     0x00010C16
 #define ASM_DATA_CMD_WRITE_V2                  0x00010DAB
 #define ASM_DATA_CMD_READ_V2                   0x00010DAC
 #define ASM_SESSION_CMD_SUSPEND                        0x00010DEC
@@ -89,6 +90,20 @@ struct asm_multi_channel_pcm_fmt_blk_v2 {
        u8 channel_mapping[PCM_MAX_NUM_CHANNEL];
 } __packed;
 
+struct asm_flac_fmt_blk_v2 {
+       struct asm_data_cmd_media_fmt_update_v2 fmt_blk;
+       u16 is_stream_info_present;
+       u16 num_channels;
+       u16 min_blk_size;
+       u16 max_blk_size;
+       u16 md5_sum[8];
+       u32 sample_rate;
+       u32 min_frame_size;
+       u32 max_frame_size;
+       u16 sample_size;
+       u16 reserved;
+} __packed;
+
 struct asm_stream_cmd_set_encdec_param {
        u32                  param_id;
        u32                  param_size;
@@ -876,6 +891,9 @@ int q6asm_open_write(struct audio_client *ac, uint32_t format,
        case FORMAT_LINEAR_PCM:
                open->dec_fmt_id = ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V2;
                break;
+       case SND_AUDIOCODEC_FLAC:
+               open->dec_fmt_id = ASM_MEDIA_FMT_FLAC;
+               break;
        default:
                dev_err(ac->dev, "Invalid format 0x%x\n", format);
                rc = -EINVAL;
@@ -1021,6 +1039,42 @@ err:
 }
 EXPORT_SYMBOL_GPL(q6asm_media_format_block_multi_ch_pcm);
 
+
+int q6asm_stream_media_format_block_flac(struct audio_client *ac,
+                                        struct q6asm_flac_cfg *cfg)
+{
+       struct asm_flac_fmt_blk_v2 *fmt;
+       struct apr_pkt *pkt;
+       void *p;
+       int rc, pkt_size;
+
+       pkt_size = APR_HDR_SIZE + sizeof(*fmt);
+       p = kzalloc(pkt_size, GFP_KERNEL);
+       if (!p)
+               return -ENOMEM;
+
+       pkt = p;
+       fmt = p + APR_HDR_SIZE;
+
+       q6asm_add_hdr(ac, &pkt->hdr, pkt_size, true, ac->stream_id);
+
+       pkt->hdr.opcode = ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2;
+       fmt->fmt_blk.fmt_blk_size = sizeof(*fmt) - sizeof(fmt->fmt_blk);
+       fmt->is_stream_info_present = cfg->stream_info_present;
+       fmt->num_channels = cfg->ch_cfg;
+       fmt->min_blk_size = cfg->min_blk_size;
+       fmt->max_blk_size = cfg->max_blk_size;
+       fmt->sample_rate = cfg->sample_rate;
+       fmt->min_frame_size = cfg->min_frame_size;
+       fmt->max_frame_size = cfg->max_frame_size;
+       fmt->sample_size = cfg->sample_size;
+
+       rc = q6asm_ac_send_cmd_sync(ac, pkt);
+       kfree(pkt);
+
+       return rc;
+}
+EXPORT_SYMBOL_GPL(q6asm_stream_media_format_block_flac);
 /**
  * q6asm_enc_cfg_blk_pcm_format_support() - setup pcm configuration for capture
  *
@@ -1075,6 +1129,7 @@ err:
 }
 EXPORT_SYMBOL_GPL(q6asm_enc_cfg_blk_pcm_format_support);
 
+
 /**
  * q6asm_read() - read data of period size from audio client
  *
index 9f5fb57..6764f55 100644 (file)
@@ -32,6 +32,19 @@ enum {
 #define NO_TIMESTAMP    0xFF00
 #define FORMAT_LINEAR_PCM   0x0000
 
+struct q6asm_flac_cfg {
+        u32 sample_rate;
+        u32 ext_sample_rate;
+        u32 min_frame_size;
+        u32 max_frame_size;
+        u16 stream_info_present;
+        u16 min_blk_size;
+        u16 max_blk_size;
+        u16 ch_cfg;
+        u16 sample_size;
+        u16 md5_sum;
+};
+
 typedef void (*q6asm_cb) (uint32_t opcode, uint32_t token,
                          void *payload, void *priv);
 struct audio_client;
@@ -54,6 +67,8 @@ int q6asm_media_format_block_multi_ch_pcm(struct audio_client *ac,
                                          uint32_t rate, uint32_t channels,
                                          u8 channel_map[PCM_MAX_NUM_CHANNEL],
                                          uint16_t bits_per_sample);
+int q6asm_stream_media_format_block_flac(struct audio_client *ac,
+                                        struct q6asm_flac_cfg *cfg);
 int q6asm_run(struct audio_client *ac, uint32_t flags, uint32_t msw_ts,
              uint32_t lsw_ts);
 int q6asm_run_nowait(struct audio_client *ac, uint32_t flags, uint32_t msw_ts,