Skip to content

Commit

Permalink
ASoC: msm: qdsp6v2: Add FLAC in compress offload path
Browse files Browse the repository at this point in the history
Add FLAC format in compress offload driver, and asm
module

Change-Id: I818ace8397e761b1acff7f9b2eab6e0103ed78c8
Signed-off-by: Apurupa Pattapu <apurupa@codeaurora.org>

Change-Id: I40310136eb980442eed4bd3b0739ed9ffeb8e033
  • Loading branch information
Apurupa Pattapu authored and javilonas committed May 14, 2015
1 parent 6c16390 commit db0f636
Show file tree
Hide file tree
Showing 6 changed files with 191 additions and 1 deletion.
81 changes: 81 additions & 0 deletions include/sound/apr_audio-v2.h
Expand Up @@ -2634,6 +2634,19 @@ struct asm_amrwbplus_cfg {
u32 amr_lsf_idx;
} __packed;

struct asm_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;
};

struct asm_softpause_params {
u32 enable;
u32 period;
Expand Down Expand Up @@ -2981,6 +2994,73 @@ struct asm_aac_enc_cfg_v2 {

} __packed;

struct asm_flac_fmt_blk_v2 {
struct apr_hdr hdr;
struct asm_data_cmd_media_fmt_update_v2 fmtblk;

u16 is_stream_info_present;
/* Specifies whether stream information is present in the FLAC format
* block.
*
* Supported values:
* - 0 -- Stream information is not present in this message
* - 1 -- Stream information is present in this message
*
* When set to 1, the FLAC bitstream was successfully parsed by the
* client, and other fields in the FLAC format block can be read by the
* decoder to get metadata stream information.
*/

u16 num_channels;
/* Number of channels for decoding.
* Supported values: 1 to 2
*/

u16 min_blk_size;
/* Minimum block size (in samples) used in the stream. It must be less
* than or equal to max_blk_size.
*/

u16 max_blk_size;
/* Maximum block size (in samples) used in the stream. If the
* minimum block size equals the maximum block size, a fixed block
* size stream is implied.
*/

u16 md5_sum[8];
/* MD5 signature array of the unencoded audio data. This allows the
* decoder to determine if an error exists in the audio data, even when
* the error does not result in an invalid bitstream.
*/

u32 sample_rate;
/* Number of samples per second.
* Supported values: 8000 to 48000 Hz
*/

u32 min_frame_size;
/* Minimum frame size used in the stream.
* Supported values:
* - > 0 bytes
* - 0 -- The value is unknown
*/

u32 max_frame_size;
/* Maximum frame size used in the stream.
* Supported values:
* -- > 0 bytes
* -- 0 . The value is unknown
*/

u16 sample_size;
/* Bits per sample.Supported values: 8, 16 */

u16 reserved;
/* Clients must set this field to zero
*/

} __packed;

#define ASM_MEDIA_FMT_AMRNB_FS 0x00010BEB

/* Enumeration for 4.75 kbps AMR-NB Encoding mode. */
Expand Down Expand Up @@ -3385,6 +3465,7 @@ struct asm_amrwbplus_fmt_blk_v2 {
#define ASM_MEDIA_FMT_EAC3_DEC 0x00010C3C
#define ASM_MEDIA_FMT_DTS 0x00010D88
#define ASM_MEDIA_FMT_MP2 0x00010DE9
#define ASM_MEDIA_FMT_FLAC 0x00010C16

/* Media format ID for adaptive transform acoustic coding. This
* ID is used by the #ASM_STREAM_CMD_OPEN_WRITE_COMPRESSED command
Expand Down
4 changes: 4 additions & 0 deletions include/sound/q6asm-v2.h
Expand Up @@ -45,6 +45,7 @@
#define FORMAT_AC3 0x0013
#define FORMAT_EAC3 0x0014
#define FORMAT_MP2 0x0015
#define FORMAT_FLAC 0x0016

#define ENCDEC_SBCBITRATE 0x0001
#define ENCDEC_IMMEDIATE_DECODE 0x0002
Expand Down Expand Up @@ -373,6 +374,9 @@ int q6asm_media_format_block_wmapro(struct audio_client *ac,
int q6asm_media_format_block_amrwbplus(struct audio_client *ac,
struct asm_amrwbplus_cfg *cfg);

int q6asm_stream_media_format_block_flac(struct audio_client *ac,
struct asm_flac_cfg *cfg, int stream_id);

int q6asm_ds1_set_endp_params(struct audio_client *ac,
int param_id, int param_value);

Expand Down
8 changes: 8 additions & 0 deletions include/uapi/sound/compress_params.h
Expand Up @@ -347,6 +347,13 @@ struct snd_dec_ddp {
__u32 params_id[18];
__u32 params_value[18];
};
struct snd_dec_flac {
__u16 sample_size;
__u16 min_blk_size;
__u16 max_blk_size;
__u16 min_frame_size;
__u16 max_frame_size;
};
union snd_codec_options {
struct snd_enc_wma wma;
struct snd_enc_vorbis vorbis;
Expand All @@ -355,6 +362,7 @@ union snd_codec_options {
struct snd_enc_generic generic;
struct snd_dec_dts dts;
struct snd_dec_ddp ddp;
struct snd_dec_flac flac_dec;
};

/** struct snd_codec_desc - description of codec capabilities
Expand Down
51 changes: 50 additions & 1 deletion sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c
Expand Up @@ -510,7 +510,7 @@ static void populate_codec_list(struct msm_compr_audio *prtd)
COMPR_PLAYBACK_MIN_NUM_FRAGMENTS;
prtd->compr_cap.max_fragments =
COMPR_PLAYBACK_MAX_NUM_FRAGMENTS;
prtd->compr_cap.num_codecs = 8;
prtd->compr_cap.num_codecs = 9;
prtd->compr_cap.codecs[0] = SND_AUDIOCODEC_MP3;
prtd->compr_cap.codecs[1] = SND_AUDIOCODEC_AAC;
prtd->compr_cap.codecs[2] = SND_AUDIOCODEC_AC3;
Expand All @@ -519,6 +519,7 @@ static void populate_codec_list(struct msm_compr_audio *prtd)
prtd->compr_cap.codecs[5] = SND_AUDIOCODEC_PCM;
prtd->compr_cap.codecs[6] = SND_AUDIOCODEC_WMA;
prtd->compr_cap.codecs[7] = SND_AUDIOCODEC_WMA_PRO;
prtd->compr_cap.codecs[8] = SND_AUDIOCODEC_FLAC;
}

static int msm_compr_send_media_format_block(struct snd_compr_stream *cstream,
Expand All @@ -529,6 +530,7 @@ static int msm_compr_send_media_format_block(struct snd_compr_stream *cstream,
struct asm_aac_cfg aac_cfg;
struct asm_wma_cfg wma_cfg;
struct asm_wmapro_cfg wma_pro_cfg;
struct asm_flac_cfg flac_cfg;
int ret = 0;
uint16_t bit_width = 16;

Expand Down Expand Up @@ -621,6 +623,30 @@ static int msm_compr_send_media_format_block(struct snd_compr_stream *cstream,
break;
case FORMAT_MP2:
pr_info("%s: SND_AUDIOCODEC_MP2\n", __func__);
break;
case FORMAT_FLAC:
pr_debug("%s: SND_AUDIOCODEC_FLAC\n", __func__);
memset(&flac_cfg, 0x0, sizeof(struct asm_flac_cfg));
flac_cfg.ch_cfg = prtd->num_channels;
flac_cfg.sample_rate = prtd->sample_rate;
flac_cfg.stream_info_present = 1;
flac_cfg.sample_size =
prtd->codec_param.codec.options.flac_dec.sample_size;
flac_cfg.min_blk_size =
prtd->codec_param.codec.options.flac_dec.min_blk_size;
flac_cfg.max_blk_size =
prtd->codec_param.codec.options.flac_dec.max_blk_size;
flac_cfg.max_frame_size =
prtd->codec_param.codec.options.flac_dec.max_frame_size;
flac_cfg.min_frame_size =
prtd->codec_param.codec.options.flac_dec.min_frame_size;

ret = q6asm_stream_media_format_block_flac(prtd->audio_client,
&flac_cfg, stream_id);
if (ret < 0)
pr_err("%s: CMD Format block failed ret %d\n",
__func__, ret);

break;
default:
pr_info("%s, unsupported format, skip", __func__);
Expand Down Expand Up @@ -650,6 +676,11 @@ static int msm_compr_configure_dsp(struct snd_compr_stream *cstream)
.rampingcurve = SOFT_VOLUME_CURVE_LINEAR,
};

if (prtd->codec_param.codec.format == SNDRV_PCM_FORMAT_S24_LE)
bits_per_sample = 24;
if (prtd->codec_param.codec.format == SNDRV_PCM_FORMAT_S32_LE)
bits_per_sample = 32;

if (prtd->compr_passthr != LEGACY_PCM) {
ret = q6asm_open_write_compressed(ac, prtd->codec,
prtd->compr_passthr);
Expand Down Expand Up @@ -991,9 +1022,18 @@ static int msm_compr_set_params(struct snd_compr_stream *cstream,
case SNDRV_PCM_RATE_48000:
prtd->sample_rate = 48000;
break;
case SNDRV_PCM_RATE_64000:
prtd->sample_rate = 64000;
break;
case SNDRV_PCM_RATE_88200:
prtd->sample_rate = 88200;
break;
case SNDRV_PCM_RATE_96000:
prtd->sample_rate = 96000;
break;
case SNDRV_PCM_RATE_176400:
prtd->sample_rate = 176400;
break;
case SNDRV_PCM_RATE_192000:
prtd->sample_rate = 192000;
break;
Expand Down Expand Up @@ -1067,6 +1107,12 @@ static int msm_compr_set_params(struct snd_compr_stream *cstream,
break;
}

case SND_AUDIOCODEC_FLAC: {
pr_debug("%s: SND_AUDIOCODEC_FLAC\n", __func__);
prtd->codec = FORMAT_FLAC;
break;
}

default:
pr_err("codec not supported, id =%d\n", params->codec.id);
return -EINVAL;
Expand Down Expand Up @@ -1766,6 +1812,8 @@ static int msm_compr_get_codec_caps(struct snd_compr_stream *cstream,
break;
case SND_AUDIOCODEC_EAC3:
break;
case SND_AUDIOCODEC_FLAC:
break;
default:
pr_err("%s: Unsupported audio codec %d\n",
__func__, codec->codec);
Expand Down Expand Up @@ -1956,6 +2004,7 @@ static int msm_compr_send_dec_params(struct snd_compr_stream *cstream,
switch (prtd->codec) {
case FORMAT_MP3:
case FORMAT_MPEG4_AAC:
case FORMAT_FLAC:
pr_debug("%s: no runtime parameters for codec: %d\n", __func__,
prtd->codec);
break;
Expand Down
2 changes: 2 additions & 0 deletions sound/soc/msm/qdsp6v2/q6adm.c
Expand Up @@ -34,6 +34,7 @@
/* 2 is to account for module & param ID in payload */
#define ADM_GET_PARAMETER_LENGTH (4096 - APR_HDR_SIZE - 2 * sizeof(uint32_t))

#define ULL_SUPPORTED_BITS_PER_SAMPLE 16
#define ULL_SUPPORTED_SAMPLE_RATE 48000


Expand Down Expand Up @@ -1442,6 +1443,7 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology,
if (perf_mode == ULTRA_LOW_LATENCY_PCM_MODE) {
open.topology_id = NULL_COPP_TOPOLOGY;
rate = ULL_SUPPORTED_SAMPLE_RATE;
open.bit_width = ULL_SUPPORTED_BITS_PER_SAMPLE;
} else if (perf_mode == LOW_LATENCY_PCM_MODE) {
if ((open.topology_id ==
DOLBY_ADM_COPP_TOPOLOGY_ID) ||
Expand Down
46 changes: 46 additions & 0 deletions sound/soc/msm/qdsp6v2/q6asm.c
Expand Up @@ -2081,6 +2081,9 @@ static int __q6asm_open_write(struct audio_client *ac, uint32_t format,
case FORMAT_MP2:
open.dec_fmt_id = ASM_MEDIA_FMT_MP2;
break;
case FORMAT_FLAC:
open.dec_fmt_id = ASM_MEDIA_FMT_FLAC;
break;
default:
pr_err("%s: Invalid format 0x%x\n", __func__, format);
goto fail_cmd;
Expand Down Expand Up @@ -3289,6 +3292,49 @@ int q6asm_media_format_block_amrwbplus(struct audio_client *ac,
return -EINVAL;
}

int q6asm_stream_media_format_block_flac(struct audio_client *ac,
struct asm_flac_cfg *cfg, int stream_id)
{
struct asm_flac_fmt_blk_v2 fmt;
int rc = 0;

pr_debug("%s :session[%d]rate[%d]ch[%d]size[%d]\n", __func__,
ac->session, cfg->sample_rate, cfg->ch_cfg, cfg->sample_size);

q6asm_add_hdr(ac, &fmt.hdr, sizeof(fmt), TRUE);
atomic_set(&ac->cmd_state, 1);

fmt.hdr.opcode = ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2;
fmt.fmtblk.fmt_blk_size = sizeof(fmt) - sizeof(fmt.hdr) -
sizeof(fmt.fmtblk);

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 = apr_send_pkt(ac->apr, (uint32_t *) &fmt);
if (rc < 0) {
pr_err("%s :Comamnd media format update failed %d\n",
__func__, rc);
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__);
rc = -ETIMEDOUT;
goto fail_cmd;
}
return 0;
fail_cmd:
return rc;
}

static int __q6asm_ds1_set_endp_params(struct audio_client *ac, int param_id,
int param_value, int stream_id)
{
Expand Down

0 comments on commit db0f636

Please sign in to comment.