ASoC: msm: qdspv2: add support for MULTI_CHANNEL_PCM_V3 command
Driver changes to use ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V3 command. This command supports playback/record of both 32 bit (24 bit data in 32 bit word) and 24 bit packed. Update platform drivers to use this for SNDRV_PCM_FORMAT_S24_LE record and playback. CRs-Fixed: 1011048 Change-Id: I6f98bf3402a737bc21daff33b13b137850a690ea Signed-off-by: Manish Dewangan <manish@codeaurora.org>
This commit is contained in:
parent
e335b6b9da
commit
8b8d412617
6 changed files with 596 additions and 56 deletions
|
@ -3432,6 +3432,16 @@ struct asm_multi_channel_pcm_fmt_blk_v3 {
|
|||
*/
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* Payload of the multichannel PCM configuration parameters in
|
||||
* the ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V3 media format.
|
||||
*/
|
||||
struct asm_multi_channel_pcm_fmt_blk_param_v3 {
|
||||
struct apr_hdr hdr;
|
||||
struct asm_data_cmd_media_fmt_update_v2 fmt_blk;
|
||||
struct asm_multi_channel_pcm_fmt_blk_v3 param;
|
||||
} __packed;
|
||||
|
||||
struct asm_stream_cmd_set_encdec_param {
|
||||
u32 param_id;
|
||||
/* ID of the parameter. */
|
||||
|
@ -3467,6 +3477,66 @@ struct asm_dec_ddp_endp_param_v2 {
|
|||
int endp_param_value;
|
||||
} __packed;
|
||||
|
||||
|
||||
/*
|
||||
* Payload of the multichannel PCM encoder configuration parameters in
|
||||
* the ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V3 media format.
|
||||
*/
|
||||
|
||||
struct asm_multi_channel_pcm_enc_cfg_v3 {
|
||||
struct apr_hdr hdr;
|
||||
struct asm_stream_cmd_set_encdec_param encdec;
|
||||
struct asm_enc_cfg_blk_param_v2 encblk;
|
||||
uint16_t num_channels;
|
||||
/*
|
||||
* Number of PCM channels.
|
||||
* @values
|
||||
* - 0 -- Native mode
|
||||
* - 1 -- 8 channels
|
||||
* Native mode indicates that encoding must be performed with the number
|
||||
* of channels at the input.
|
||||
*/
|
||||
uint16_t bits_per_sample;
|
||||
/*
|
||||
* Number of bits per sample per channel.
|
||||
* @values 16, 24
|
||||
*/
|
||||
uint32_t sample_rate;
|
||||
/*
|
||||
* Number of samples per second.
|
||||
* @values 0, 8000 to 48000 Hz
|
||||
* A value of 0 indicates the native sampling rate. Encoding is
|
||||
* performed at the input sampling rate.
|
||||
*/
|
||||
uint16_t is_signed;
|
||||
/*
|
||||
* Flag that indicates the PCM samples are signed (1). Currently, only
|
||||
* signed PCM samples are supported.
|
||||
*/
|
||||
uint16_t sample_word_size;
|
||||
/*
|
||||
* The size in bits of the word that holds a sample of a channel.
|
||||
* @values 16, 24, 32
|
||||
* 16-bit samples are always placed in 16-bit words:
|
||||
* sample_word_size = 1.
|
||||
* 24-bit samples can be placed in 32-bit words or in consecutive
|
||||
* 24-bit words.
|
||||
* - If sample_word_size = 32, 24-bit samples are placed in the
|
||||
* most significant 24 bits of a 32-bit word.
|
||||
* - If sample_word_size = 24, 24-bit samples are placed in
|
||||
* 24-bit words. @tablebulletend
|
||||
*/
|
||||
uint8_t channel_mapping[8];
|
||||
/*
|
||||
* Channel mapping array expected at the encoder output.
|
||||
* Channel[i] mapping describes channel i inside the buffer, where
|
||||
* 0 @le i < num_channels. All valid used channels must be present at
|
||||
* the beginning of the array.
|
||||
* If Native mode is set for the channels, this field is ignored.
|
||||
* @values See Section @xref{dox:PcmChannelDefs}
|
||||
*/
|
||||
};
|
||||
|
||||
/* @brief Multichannel PCM encoder configuration structure used
|
||||
* in the #ASM_PARAM_ID_ENCDEC_ENC_CFG_BLK_V2 command.
|
||||
*/
|
||||
|
|
|
@ -241,6 +241,9 @@ int q6asm_open_read(struct audio_client *ac, uint32_t format
|
|||
int q6asm_open_read_v2(struct audio_client *ac, uint32_t format,
|
||||
uint16_t bits_per_sample);
|
||||
|
||||
int q6asm_open_read_v3(struct audio_client *ac, uint32_t format,
|
||||
uint16_t bits_per_sample);
|
||||
|
||||
int q6asm_open_write(struct audio_client *ac, uint32_t format
|
||||
/*, uint16_t bits_per_sample*/);
|
||||
|
||||
|
@ -250,9 +253,16 @@ int q6asm_open_write_v2(struct audio_client *ac, uint32_t format,
|
|||
int q6asm_open_shared_io(struct audio_client *ac,
|
||||
struct shared_io_config *c, int dir);
|
||||
|
||||
int q6asm_open_write_v3(struct audio_client *ac, uint32_t format,
|
||||
uint16_t bits_per_sample);
|
||||
|
||||
int q6asm_stream_open_write_v2(struct audio_client *ac, uint32_t format,
|
||||
uint16_t bits_per_sample, int32_t stream_id,
|
||||
bool is_gapless_mode);
|
||||
uint16_t bits_per_sample, int32_t stream_id,
|
||||
bool is_gapless_mode);
|
||||
|
||||
int q6asm_stream_open_write_v3(struct audio_client *ac, uint32_t format,
|
||||
uint16_t bits_per_sample, int32_t stream_id,
|
||||
bool is_gapless_mode);
|
||||
|
||||
int q6asm_open_write_compressed(struct audio_client *ac, uint32_t format,
|
||||
uint32_t passthrough_flag);
|
||||
|
@ -350,10 +360,21 @@ int q6asm_enc_cfg_blk_pcm_v2(struct audio_client *ac,
|
|||
bool use_default_chmap, bool use_back_flavor,
|
||||
u8 *channel_map);
|
||||
|
||||
int q6asm_enc_cfg_blk_pcm_v3(struct audio_client *ac,
|
||||
uint32_t rate, uint32_t channels,
|
||||
uint16_t bits_per_sample, bool use_default_chmap,
|
||||
bool use_back_flavor, u8 *channel_map,
|
||||
uint16_t sample_word_size);
|
||||
|
||||
int q6asm_enc_cfg_blk_pcm_format_support(struct audio_client *ac,
|
||||
uint32_t rate, uint32_t channels,
|
||||
uint16_t bits_per_sample);
|
||||
|
||||
int q6asm_enc_cfg_blk_pcm_format_support_v3(struct audio_client *ac,
|
||||
uint32_t rate, uint32_t channels,
|
||||
uint16_t bits_per_sample,
|
||||
uint16_t sample_word_size);
|
||||
|
||||
int q6asm_set_encdec_chan_map(struct audio_client *ac,
|
||||
uint32_t num_channels);
|
||||
|
||||
|
@ -394,6 +415,15 @@ int q6asm_media_format_block_pcm_format_support_v2(struct audio_client *ac,
|
|||
uint16_t bits_per_sample, int stream_id,
|
||||
bool use_default_chmap, char *channel_map);
|
||||
|
||||
int q6asm_media_format_block_pcm_format_support_v3(struct audio_client *ac,
|
||||
uint32_t rate,
|
||||
uint32_t channels,
|
||||
uint16_t bits_per_sample,
|
||||
int stream_id,
|
||||
bool use_default_chmap,
|
||||
char *channel_map,
|
||||
uint16_t sample_word_size);
|
||||
|
||||
int q6asm_media_format_block_multi_ch_pcm(struct audio_client *ac,
|
||||
uint32_t rate, uint32_t channels,
|
||||
bool use_default_chmap, char *channel_map);
|
||||
|
@ -404,6 +434,13 @@ int q6asm_media_format_block_multi_ch_pcm_v2(
|
|||
bool use_default_chmap, char *channel_map,
|
||||
uint16_t bits_per_sample);
|
||||
|
||||
int q6asm_media_format_block_multi_ch_pcm_v3(struct audio_client *ac,
|
||||
uint32_t rate, uint32_t channels,
|
||||
bool use_default_chmap,
|
||||
char *channel_map,
|
||||
uint16_t bits_per_sample,
|
||||
uint16_t sample_word_size);
|
||||
|
||||
int q6asm_media_format_block_aac(struct audio_client *ac,
|
||||
struct asm_aac_cfg *cfg);
|
||||
|
||||
|
|
|
@ -677,9 +677,10 @@ static int msm_compr_send_media_format_block(struct snd_compr_stream *cstream,
|
|||
union snd_codec_options *codec_options;
|
||||
|
||||
int ret = 0;
|
||||
uint16_t bit_width = 16;
|
||||
uint16_t bit_width;
|
||||
bool use_default_chmap = true;
|
||||
char *chmap = NULL;
|
||||
uint16_t sample_word_size;
|
||||
|
||||
pr_debug("%s: use_gapless_codec_options %d\n",
|
||||
__func__, use_gapless_codec_options);
|
||||
|
@ -703,15 +704,26 @@ static int msm_compr_send_media_format_block(struct snd_compr_stream *cstream,
|
|||
chmap =
|
||||
pdata->ch_map[rtd->dai_link->be_id]->channel_map;
|
||||
}
|
||||
if (prtd->codec_param.codec.format == SNDRV_PCM_FORMAT_S24_LE)
|
||||
|
||||
switch (prtd->codec_param.codec.format) {
|
||||
case SNDRV_PCM_FORMAT_S24_LE:
|
||||
bit_width = 24;
|
||||
ret = q6asm_media_format_block_pcm_format_support_v2(
|
||||
sample_word_size = 32;
|
||||
break;
|
||||
case SNDRV_PCM_FORMAT_S16_LE:
|
||||
default:
|
||||
bit_width = 16;
|
||||
sample_word_size = 16;
|
||||
break;
|
||||
}
|
||||
ret = q6asm_media_format_block_pcm_format_support_v3(
|
||||
prtd->audio_client,
|
||||
prtd->sample_rate,
|
||||
prtd->num_channels,
|
||||
bit_width, stream_id,
|
||||
use_default_chmap,
|
||||
chmap);
|
||||
chmap,
|
||||
sample_word_size);
|
||||
if (ret < 0)
|
||||
pr_err("%s: CMD Format block failed\n", __func__);
|
||||
|
||||
|
@ -977,7 +989,7 @@ static int msm_compr_configure_dsp(struct snd_compr_stream *cstream)
|
|||
} else {
|
||||
pr_debug("%s: stream_id %d bits_per_sample %d\n",
|
||||
__func__, ac->stream_id, bits_per_sample);
|
||||
ret = q6asm_stream_open_write_v2(ac,
|
||||
ret = q6asm_stream_open_write_v3(ac,
|
||||
prtd->codec, bits_per_sample,
|
||||
ac->stream_id,
|
||||
prtd->gapless_state.use_dsp_gapless_mode);
|
||||
|
@ -1897,7 +1909,7 @@ static int msm_compr_trigger(struct snd_compr_stream *cstream, int cmd)
|
|||
|
||||
pr_debug("%s: open_write stream_id %d bits_per_sample %d",
|
||||
__func__, stream_id, bits_per_sample);
|
||||
rc = q6asm_stream_open_write_v2(prtd->audio_client,
|
||||
rc = q6asm_stream_open_write_v3(prtd->audio_client,
|
||||
prtd->codec, bits_per_sample,
|
||||
stream_id,
|
||||
prtd->gapless_state.use_dsp_gapless_mode);
|
||||
|
|
|
@ -87,7 +87,8 @@ static struct snd_pcm_hardware msm_pcm_hardware_playback = {
|
|||
SNDRV_PCM_INFO_NO_PERIOD_WAKEUP |
|
||||
SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME),
|
||||
.formats = (SNDRV_PCM_FMTBIT_S16_LE |
|
||||
SNDRV_PCM_FMTBIT_S24_LE),
|
||||
SNDRV_PCM_FMTBIT_S24_LE |
|
||||
SNDRV_PCM_FMTBIT_S24_3LE),
|
||||
.rates = SNDRV_PCM_RATE_8000_192000,
|
||||
.rate_min = 8000,
|
||||
.rate_max = 192000,
|
||||
|
@ -110,7 +111,8 @@ static struct snd_pcm_hardware msm_pcm_hardware_capture = {
|
|||
SNDRV_PCM_INFO_NO_PERIOD_WAKEUP |
|
||||
SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME),
|
||||
.formats = (SNDRV_PCM_FMTBIT_S16_LE |
|
||||
SNDRV_PCM_FMTBIT_S24_LE),
|
||||
SNDRV_PCM_FMTBIT_S24_LE |
|
||||
SNDRV_PCM_FMTBIT_S24_3LE),
|
||||
.rates = SNDRV_PCM_RATE_8000_48000,
|
||||
.rate_min = 8000,
|
||||
.rate_max = 48000,
|
||||
|
@ -253,7 +255,7 @@ static int msm_pcm_hw_params(struct snd_pcm_substream *substream,
|
|||
struct audio_buffer *buf;
|
||||
struct shared_io_config config;
|
||||
uint16_t sample_word_size;
|
||||
uint16_t bits_per_sample = 16;
|
||||
uint16_t bits_per_sample;
|
||||
int ret;
|
||||
int dir = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? IN : OUT;
|
||||
|
||||
|
@ -280,16 +282,21 @@ static int msm_pcm_hw_params(struct snd_pcm_substream *substream,
|
|||
return 0;
|
||||
|
||||
switch (runtime->format) {
|
||||
case SNDRV_PCM_FORMAT_S16_LE:
|
||||
bits_per_sample = 16;
|
||||
break;
|
||||
case SNDRV_PCM_FORMAT_S24_LE:
|
||||
bits_per_sample = 24;
|
||||
sample_word_size = 32;
|
||||
break;
|
||||
case SNDRV_PCM_FORMAT_S24_3LE:
|
||||
bits_per_sample = 24;
|
||||
sample_word_size = 24;
|
||||
break;
|
||||
case SNDRV_PCM_FORMAT_S16_LE:
|
||||
default:
|
||||
bits_per_sample = 16;
|
||||
sample_word_size = 16;
|
||||
break;
|
||||
}
|
||||
|
||||
sample_word_size = (bits_per_sample == 16) ? 16 : 32;
|
||||
|
||||
config.format = FORMAT_LINEAR_PCM;
|
||||
config.bits_per_sample = bits_per_sample;
|
||||
config.rate = params_rate(params);
|
||||
|
|
|
@ -280,7 +280,8 @@ static int msm_pcm_playback_prepare(struct snd_pcm_substream *substream)
|
|||
struct msm_plat_data *pdata;
|
||||
struct snd_pcm_hw_params *params;
|
||||
int ret;
|
||||
uint16_t bits_per_sample = 16;
|
||||
uint16_t bits_per_sample;
|
||||
uint16_t sample_word_size;
|
||||
|
||||
pdata = (struct msm_plat_data *)
|
||||
dev_get_drvdata(soc_prtd->platform->dev);
|
||||
|
@ -308,11 +309,21 @@ static int msm_pcm_playback_prepare(struct snd_pcm_substream *substream)
|
|||
prtd->audio_client->perf_mode = pdata->perf_mode;
|
||||
pr_debug("%s: perf: %x\n", __func__, pdata->perf_mode);
|
||||
|
||||
if (params_format(params) == SNDRV_PCM_FORMAT_S24_LE)
|
||||
switch (params_format(params)) {
|
||||
case SNDRV_PCM_FORMAT_S24_LE:
|
||||
bits_per_sample = 24;
|
||||
sample_word_size = 32;
|
||||
break;
|
||||
case SNDRV_PCM_FORMAT_S16_LE:
|
||||
default:
|
||||
bits_per_sample = 16;
|
||||
sample_word_size = 16;
|
||||
break;
|
||||
}
|
||||
|
||||
ret = q6asm_open_write_v3(prtd->audio_client,
|
||||
FORMAT_LINEAR_PCM, bits_per_sample);
|
||||
|
||||
ret = q6asm_open_write_v2(prtd->audio_client,
|
||||
FORMAT_LINEAR_PCM, bits_per_sample);
|
||||
if (ret < 0) {
|
||||
pr_err("%s: q6asm_open_write_v2 failed\n", __func__);
|
||||
q6asm_audio_client_free(prtd->audio_client);
|
||||
|
@ -335,19 +346,11 @@ static int msm_pcm_playback_prepare(struct snd_pcm_substream *substream)
|
|||
return ret;
|
||||
}
|
||||
|
||||
switch (runtime->format) {
|
||||
case SNDRV_PCM_FORMAT_S16_LE:
|
||||
bits_per_sample = 16;
|
||||
break;
|
||||
case SNDRV_PCM_FORMAT_S24_LE:
|
||||
bits_per_sample = 24;
|
||||
break;
|
||||
}
|
||||
|
||||
ret = q6asm_media_format_block_multi_ch_pcm_v2(
|
||||
prtd->audio_client, runtime->rate,
|
||||
runtime->channels, !prtd->set_channel_map,
|
||||
prtd->channel_map, bits_per_sample);
|
||||
ret = q6asm_media_format_block_multi_ch_pcm_v3(
|
||||
prtd->audio_client, runtime->rate,
|
||||
runtime->channels, !prtd->set_channel_map,
|
||||
prtd->channel_map, bits_per_sample,
|
||||
sample_word_size);
|
||||
if (ret < 0)
|
||||
pr_info("%s: CMD Format block failed\n", __func__);
|
||||
|
||||
|
@ -371,6 +374,7 @@ static int msm_pcm_capture_prepare(struct snd_pcm_substream *substream)
|
|||
int ret = 0;
|
||||
int i = 0;
|
||||
uint16_t bits_per_sample = 16;
|
||||
uint16_t sample_word_size;
|
||||
|
||||
pdata = (struct msm_plat_data *)
|
||||
dev_get_drvdata(soc_prtd->platform->dev);
|
||||
|
@ -401,7 +405,7 @@ static int msm_pcm_capture_prepare(struct snd_pcm_substream *substream)
|
|||
__func__, params_channels(params),
|
||||
prtd->audio_client->perf_mode);
|
||||
|
||||
ret = q6asm_open_read_v2(prtd->audio_client, FORMAT_LINEAR_PCM,
|
||||
ret = q6asm_open_read_v3(prtd->audio_client, FORMAT_LINEAR_PCM,
|
||||
bits_per_sample);
|
||||
if (ret < 0) {
|
||||
pr_err("%s: q6asm_open_read failed\n", __func__);
|
||||
|
@ -447,18 +451,25 @@ static int msm_pcm_capture_prepare(struct snd_pcm_substream *substream)
|
|||
return 0;
|
||||
|
||||
switch (runtime->format) {
|
||||
case SNDRV_PCM_FORMAT_S16_LE:
|
||||
bits_per_sample = 16;
|
||||
break;
|
||||
case SNDRV_PCM_FORMAT_S24_LE:
|
||||
bits_per_sample = 24;
|
||||
sample_word_size = 32;
|
||||
break;
|
||||
case SNDRV_PCM_FORMAT_S16_LE:
|
||||
default:
|
||||
bits_per_sample = 16;
|
||||
sample_word_size = 16;
|
||||
break;
|
||||
}
|
||||
pr_debug("Samp_rate = %d\n", prtd->samp_rate);
|
||||
pr_debug("Channel = %d\n", prtd->channel_mode);
|
||||
ret = q6asm_enc_cfg_blk_pcm_format_support(prtd->audio_client,
|
||||
prtd->samp_rate, prtd->channel_mode,
|
||||
bits_per_sample);
|
||||
|
||||
pr_debug("%s: Samp_rate = %d Channel = %d bit width = %d, word size = %d\n",
|
||||
__func__, prtd->samp_rate, prtd->channel_mode,
|
||||
bits_per_sample, sample_word_size);
|
||||
ret = q6asm_enc_cfg_blk_pcm_format_support_v3(prtd->audio_client,
|
||||
prtd->samp_rate,
|
||||
prtd->channel_mode,
|
||||
bits_per_sample,
|
||||
sample_word_size);
|
||||
if (ret < 0)
|
||||
pr_debug("%s: cmd cfg pcm was block failed", __func__);
|
||||
|
||||
|
|
|
@ -2226,8 +2226,10 @@ static void q6asm_add_mmaphdr(struct audio_client *ac, struct apr_hdr *hdr,
|
|||
hdr->pkt_size = pkt_size;
|
||||
return;
|
||||
}
|
||||
|
||||
static int __q6asm_open_read(struct audio_client *ac,
|
||||
uint32_t format, uint16_t bits_per_sample)
|
||||
uint32_t format, uint16_t bits_per_sample,
|
||||
bool use_v3_format)
|
||||
{
|
||||
int rc = 0x00;
|
||||
struct asm_stream_cmd_open_read_v3 open;
|
||||
|
@ -2270,7 +2272,10 @@ static int __q6asm_open_read(struct audio_client *ac,
|
|||
switch (format) {
|
||||
case FORMAT_LINEAR_PCM:
|
||||
open.mode_flags |= 0x00;
|
||||
open.enc_cfg_id = ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V2;
|
||||
if (use_v3_format)
|
||||
open.enc_cfg_id = ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V3;
|
||||
else
|
||||
open.enc_cfg_id = ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V2;
|
||||
break;
|
||||
case FORMAT_MPEG4_AAC:
|
||||
open.mode_flags |= BUFFER_META_ENABLE;
|
||||
|
@ -2332,15 +2337,32 @@ fail_cmd:
|
|||
int q6asm_open_read(struct audio_client *ac,
|
||||
uint32_t format)
|
||||
{
|
||||
return __q6asm_open_read(ac, format, 16);
|
||||
return __q6asm_open_read(ac, format, 16,
|
||||
false /*use_v3_format*/);
|
||||
}
|
||||
|
||||
int q6asm_open_read_v2(struct audio_client *ac, uint32_t format,
|
||||
uint16_t bits_per_sample)
|
||||
{
|
||||
return __q6asm_open_read(ac, format, bits_per_sample);
|
||||
return __q6asm_open_read(ac, format, bits_per_sample,
|
||||
false /*use_v3_format*/);
|
||||
}
|
||||
|
||||
/*
|
||||
* asm_open_read_v3 - Opens audio capture session
|
||||
*
|
||||
* @ac: Client session handle
|
||||
* @format: encoder format
|
||||
* @bits_per_sample: bit width of capture session
|
||||
*/
|
||||
int q6asm_open_read_v3(struct audio_client *ac, uint32_t format,
|
||||
uint16_t bits_per_sample)
|
||||
{
|
||||
return __q6asm_open_read(ac, format, bits_per_sample,
|
||||
true /*use_v3_format*/);
|
||||
}
|
||||
EXPORT_SYMBOL(q6asm_open_read_v3);
|
||||
|
||||
int q6asm_open_write_compressed(struct audio_client *ac, uint32_t format,
|
||||
uint32_t passthrough_flag)
|
||||
{
|
||||
|
@ -2427,8 +2449,8 @@ fail_cmd:
|
|||
}
|
||||
|
||||
static int __q6asm_open_write(struct audio_client *ac, uint32_t format,
|
||||
uint16_t bits_per_sample, uint32_t stream_id,
|
||||
bool is_gapless_mode)
|
||||
uint16_t bits_per_sample, uint32_t stream_id,
|
||||
bool is_gapless_mode, bool use_v3_format)
|
||||
{
|
||||
int rc = 0x00;
|
||||
struct asm_stream_cmd_open_write_v3 open;
|
||||
|
@ -2504,7 +2526,11 @@ static int __q6asm_open_write(struct audio_client *ac, uint32_t format,
|
|||
}
|
||||
switch (format) {
|
||||
case FORMAT_LINEAR_PCM:
|
||||
open.dec_fmt_id = ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V2;
|
||||
if (use_v3_format)
|
||||
open.dec_fmt_id = ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V3;
|
||||
else
|
||||
open.dec_fmt_id = ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V2;
|
||||
|
||||
break;
|
||||
case FORMAT_MPEG4_AAC:
|
||||
open.dec_fmt_id = ASM_MEDIA_FMT_AAC_V2;
|
||||
|
@ -2579,23 +2605,61 @@ fail_cmd:
|
|||
int q6asm_open_write(struct audio_client *ac, uint32_t format)
|
||||
{
|
||||
return __q6asm_open_write(ac, format, 16, ac->stream_id,
|
||||
false /*gapless*/);
|
||||
false /*gapless*/,
|
||||
false /*use_v3_format*/);
|
||||
}
|
||||
|
||||
int q6asm_open_write_v2(struct audio_client *ac, uint32_t format,
|
||||
uint16_t bits_per_sample)
|
||||
uint16_t bits_per_sample)
|
||||
{
|
||||
return __q6asm_open_write(ac, format, bits_per_sample,
|
||||
ac->stream_id, false /*gapless*/);
|
||||
ac->stream_id, false /*gapless*/,
|
||||
false /*use_v3_format*/);
|
||||
}
|
||||
|
||||
int q6asm_stream_open_write_v2(struct audio_client *ac, uint32_t format,
|
||||
uint16_t bits_per_sample, int32_t stream_id,
|
||||
bool is_gapless_mode)
|
||||
/*
|
||||
* q6asm_open_write_v3 - Opens audio playback session
|
||||
*
|
||||
* @ac: Client session handle
|
||||
* @format: decoder format
|
||||
* @bits_per_sample: bit width of playback session
|
||||
*/
|
||||
int q6asm_open_write_v3(struct audio_client *ac, uint32_t format,
|
||||
uint16_t bits_per_sample)
|
||||
{
|
||||
return __q6asm_open_write(ac, format, bits_per_sample,
|
||||
stream_id, is_gapless_mode);
|
||||
ac->stream_id, false /*gapless*/,
|
||||
true /*use_v3_format*/);
|
||||
}
|
||||
EXPORT_SYMBOL(q6asm_open_write_v3);
|
||||
|
||||
int q6asm_stream_open_write_v2(struct audio_client *ac, uint32_t format,
|
||||
uint16_t bits_per_sample, int32_t stream_id,
|
||||
bool is_gapless_mode)
|
||||
{
|
||||
return __q6asm_open_write(ac, format, bits_per_sample,
|
||||
stream_id, is_gapless_mode,
|
||||
false /*use_v3_format*/);
|
||||
}
|
||||
|
||||
/*
|
||||
* q6asm_stream_open_write_v3 - Creates audio stream for playback
|
||||
*
|
||||
* @ac: Client session handle
|
||||
* @format: asm playback format
|
||||
* @bits_per_sample: bit width of requested stream
|
||||
* @stream_id: stream id of stream to be associated with this session
|
||||
* @is_gapless_mode: true if gapless mode needs to be enabled
|
||||
*/
|
||||
int q6asm_stream_open_write_v3(struct audio_client *ac, uint32_t format,
|
||||
uint16_t bits_per_sample, int32_t stream_id,
|
||||
bool is_gapless_mode)
|
||||
{
|
||||
return __q6asm_open_write(ac, format, bits_per_sample,
|
||||
stream_id, is_gapless_mode,
|
||||
true /*use_v3_format*/);
|
||||
}
|
||||
EXPORT_SYMBOL(q6asm_stream_open_write_v3);
|
||||
|
||||
static int __q6asm_open_read_write(struct audio_client *ac, uint32_t rd_format,
|
||||
uint32_t wr_format, bool is_meta_data_mode,
|
||||
|
@ -3416,6 +3480,103 @@ fail_cmd:
|
|||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* q6asm_enc_cfg_blk_pcm_v3 - sends encoder configuration parameters
|
||||
*
|
||||
* @ac: Client session handle
|
||||
* @rate: sample rate
|
||||
* @channels: number of channels
|
||||
* @bits_per_sample: bit width of encoder session
|
||||
* @use_default_chmap: true if default channel map to be used
|
||||
* @use_back_flavor: to configure back left and right channel
|
||||
* @channel_map: input channel map
|
||||
* @sample_word_size: Size in bits of the word that holds a sample of a channel
|
||||
*/
|
||||
int q6asm_enc_cfg_blk_pcm_v3(struct audio_client *ac,
|
||||
uint32_t rate, uint32_t channels,
|
||||
uint16_t bits_per_sample, bool use_default_chmap,
|
||||
bool use_back_flavor, u8 *channel_map,
|
||||
uint16_t sample_word_size)
|
||||
{
|
||||
struct asm_multi_channel_pcm_enc_cfg_v3 enc_cfg;
|
||||
struct asm_enc_cfg_blk_param_v2 enc_fg_blk;
|
||||
u8 *channel_mapping;
|
||||
u32 frames_per_buf = 0;
|
||||
int rc;
|
||||
|
||||
if (!use_default_chmap && (channel_map == NULL)) {
|
||||
pr_err("%s: No valid chan map and can't use default\n",
|
||||
__func__);
|
||||
rc = -EINVAL;
|
||||
goto fail_cmd;
|
||||
}
|
||||
|
||||
pr_debug("%s: session[%d]rate[%d]ch[%d]bps[%d]wordsize[%d]\n", __func__,
|
||||
ac->session, rate, channels,
|
||||
bits_per_sample, sample_word_size);
|
||||
|
||||
memset(&enc_cfg, 0, sizeof(enc_cfg));
|
||||
q6asm_add_hdr(ac, &enc_cfg.hdr, sizeof(enc_cfg), TRUE);
|
||||
atomic_set(&ac->cmd_state, -1);
|
||||
enc_cfg.hdr.opcode = ASM_STREAM_CMD_SET_ENCDEC_PARAM;
|
||||
enc_cfg.encdec.param_id = ASM_PARAM_ID_ENCDEC_ENC_CFG_BLK_V2;
|
||||
enc_cfg.encdec.param_size = sizeof(enc_cfg) - sizeof(enc_cfg.hdr) -
|
||||
sizeof(enc_cfg.encdec);
|
||||
enc_cfg.encblk.frames_per_buf = frames_per_buf;
|
||||
enc_cfg.encblk.enc_cfg_blk_size = enc_cfg.encdec.param_size -
|
||||
sizeof(enc_fg_blk);
|
||||
enc_cfg.num_channels = channels;
|
||||
enc_cfg.bits_per_sample = bits_per_sample;
|
||||
enc_cfg.sample_rate = rate;
|
||||
enc_cfg.is_signed = 1;
|
||||
enc_cfg.sample_word_size = sample_word_size;
|
||||
channel_mapping = enc_cfg.channel_mapping;
|
||||
|
||||
memset(channel_mapping, 0, PCM_FORMAT_MAX_NUM_CHANNEL);
|
||||
|
||||
if (use_default_chmap) {
|
||||
pr_debug("%s: setting default channel map for %d channels",
|
||||
__func__, channels);
|
||||
if (q6asm_map_channels(channel_mapping, channels,
|
||||
use_back_flavor)) {
|
||||
pr_err("%s: map channels failed %d\n",
|
||||
__func__, channels);
|
||||
rc = -EINVAL;
|
||||
goto fail_cmd;
|
||||
}
|
||||
} else {
|
||||
pr_debug("%s: Using pre-defined channel map", __func__);
|
||||
memcpy(channel_mapping, channel_map,
|
||||
PCM_FORMAT_MAX_NUM_CHANNEL);
|
||||
}
|
||||
|
||||
rc = apr_send_pkt(ac->apr, (uint32_t *) &enc_cfg);
|
||||
if (rc < 0) {
|
||||
pr_err("%s: Comamnd open 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 opcode[0x%x]\n",
|
||||
__func__, enc_cfg.hdr.opcode);
|
||||
rc = -ETIMEDOUT;
|
||||
goto fail_cmd;
|
||||
}
|
||||
if (atomic_read(&ac->cmd_state) > 0) {
|
||||
pr_err("%s: DSP returned error[%s]\n",
|
||||
__func__, adsp_err_get_err_str(
|
||||
atomic_read(&ac->cmd_state)));
|
||||
rc = adsp_err_get_lnx_err_code(
|
||||
atomic_read(&ac->cmd_state));
|
||||
goto fail_cmd;
|
||||
}
|
||||
return 0;
|
||||
fail_cmd:
|
||||
return rc;
|
||||
}
|
||||
EXPORT_SYMBOL(q6asm_enc_cfg_blk_pcm_v3);
|
||||
|
||||
int q6asm_enc_cfg_blk_pcm_v2(struct audio_client *ac,
|
||||
uint32_t rate, uint32_t channels, uint16_t bits_per_sample,
|
||||
bool use_default_chmap, bool use_back_flavor, u8 *channel_map)
|
||||
|
@ -3495,6 +3656,15 @@ fail_cmd:
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int __q6asm_enc_cfg_blk_pcm_v3(struct audio_client *ac,
|
||||
uint32_t rate, uint32_t channels,
|
||||
uint16_t bits_per_sample,
|
||||
uint16_t sample_word_size)
|
||||
{
|
||||
return q6asm_enc_cfg_blk_pcm_v3(ac, rate, channels,
|
||||
bits_per_sample, true, false, NULL,
|
||||
sample_word_size);
|
||||
}
|
||||
|
||||
static int __q6asm_enc_cfg_blk_pcm(struct audio_client *ac,
|
||||
uint32_t rate, uint32_t channels, uint16_t bits_per_sample)
|
||||
|
@ -3515,6 +3685,26 @@ int q6asm_enc_cfg_blk_pcm_format_support(struct audio_client *ac,
|
|||
return __q6asm_enc_cfg_blk_pcm(ac, rate, channels, bits_per_sample);
|
||||
}
|
||||
|
||||
/*
|
||||
* q6asm_enc_cfg_blk_pcm_format_support_v3 - sends encoder configuration
|
||||
* parameters
|
||||
*
|
||||
* @ac: Client session handle
|
||||
* @rate: sample rate
|
||||
* @channels: number of channels
|
||||
* @bits_per_sample: bit width of encoder session
|
||||
* @sample_word_size: Size in bits of the word that holds a sample of a channel
|
||||
*/
|
||||
int q6asm_enc_cfg_blk_pcm_format_support_v3(struct audio_client *ac,
|
||||
uint32_t rate, uint32_t channels,
|
||||
uint16_t bits_per_sample,
|
||||
uint16_t sample_word_size)
|
||||
{
|
||||
return __q6asm_enc_cfg_blk_pcm_v3(ac, rate, channels,
|
||||
bits_per_sample, sample_word_size);
|
||||
}
|
||||
EXPORT_SYMBOL(q6asm_enc_cfg_blk_pcm_format_support_v3);
|
||||
|
||||
int q6asm_enc_cfg_blk_pcm_native(struct audio_client *ac,
|
||||
uint32_t rate, uint32_t channels)
|
||||
{
|
||||
|
@ -4066,6 +4256,87 @@ fail_cmd:
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int __q6asm_media_format_block_pcm_v3(struct audio_client *ac,
|
||||
uint32_t rate, uint32_t channels,
|
||||
uint16_t bits_per_sample,
|
||||
int stream_id,
|
||||
bool use_default_chmap,
|
||||
char *channel_map,
|
||||
uint16_t sample_word_size)
|
||||
{
|
||||
struct asm_multi_channel_pcm_fmt_blk_param_v3 fmt;
|
||||
u8 *channel_mapping;
|
||||
int rc;
|
||||
|
||||
pr_debug("%s: session[%d]rate[%d]ch[%d]bps[%d]wordsize[%d]\n", __func__,
|
||||
ac->session, rate, channels,
|
||||
bits_per_sample, sample_word_size);
|
||||
|
||||
memset(&fmt, 0, sizeof(fmt));
|
||||
q6asm_stream_add_hdr(ac, &fmt.hdr, sizeof(fmt), TRUE, stream_id);
|
||||
atomic_set(&ac->cmd_state, -1);
|
||||
/*
|
||||
* Updated the token field with stream/session for compressed playback
|
||||
* Platform driver must know the the stream with which the command is
|
||||
* associated
|
||||
*/
|
||||
if (ac->io_mode & COMPRESSED_STREAM_IO)
|
||||
fmt.hdr.token = ((ac->session << 8) & 0xFFFF00) |
|
||||
(stream_id & 0xFF);
|
||||
|
||||
pr_debug("%s: token = 0x%x, stream_id %d, session 0x%x\n",
|
||||
__func__, fmt.hdr.token, stream_id, ac->session);
|
||||
|
||||
fmt.hdr.opcode = ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2;
|
||||
fmt.fmt_blk.fmt_blk_size = sizeof(fmt) - sizeof(fmt.hdr) -
|
||||
sizeof(fmt.fmt_blk);
|
||||
fmt.param.num_channels = channels;
|
||||
fmt.param.bits_per_sample = bits_per_sample;
|
||||
fmt.param.sample_rate = rate;
|
||||
fmt.param.is_signed = 1;
|
||||
fmt.param.sample_word_size = sample_word_size;
|
||||
channel_mapping = fmt.param.channel_mapping;
|
||||
|
||||
memset(channel_mapping, 0, PCM_FORMAT_MAX_NUM_CHANNEL);
|
||||
|
||||
if (use_default_chmap) {
|
||||
if (q6asm_map_channels(channel_mapping, channels, false)) {
|
||||
pr_err("%s: map channels failed %d\n",
|
||||
__func__, channels);
|
||||
rc = -EINVAL;
|
||||
goto fail_cmd;
|
||||
}
|
||||
} else {
|
||||
memcpy(channel_mapping, channel_map,
|
||||
PCM_FORMAT_MAX_NUM_CHANNEL);
|
||||
}
|
||||
|
||||
rc = apr_send_pkt(ac->apr, (uint32_t *) &fmt);
|
||||
if (rc < 0) {
|
||||
pr_err("%s: Comamnd open failed %d\n", __func__, rc);
|
||||
rc = -EINVAL;
|
||||
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;
|
||||
}
|
||||
if (atomic_read(&ac->cmd_state) > 0) {
|
||||
pr_err("%s: DSP returned error[%s]\n",
|
||||
__func__, adsp_err_get_err_str(
|
||||
atomic_read(&ac->cmd_state)));
|
||||
rc = adsp_err_get_lnx_err_code(
|
||||
atomic_read(&ac->cmd_state));
|
||||
goto fail_cmd;
|
||||
}
|
||||
return 0;
|
||||
fail_cmd:
|
||||
return rc;
|
||||
}
|
||||
|
||||
int q6asm_media_format_block_pcm(struct audio_client *ac,
|
||||
uint32_t rate, uint32_t channels)
|
||||
{
|
||||
|
@ -4098,6 +4369,41 @@ int q6asm_media_format_block_pcm_format_support_v2(struct audio_client *ac,
|
|||
use_default_chmap, channel_map);
|
||||
}
|
||||
|
||||
/*
|
||||
* q6asm_media_format_block_pcm_format_support_v3- sends pcm decoder
|
||||
* configuration parameters
|
||||
*
|
||||
* @ac: Client session handle
|
||||
* @rate: sample rate
|
||||
* @channels: number of channels
|
||||
* @bits_per_sample: bit width of encoder session
|
||||
* @stream_id: stream id of stream to be associated with this session
|
||||
* @use_default_chmap: true if default channel map to be used
|
||||
* @channel_map: input channel map
|
||||
* @sample_word_size: Size in bits of the word that holds a sample of a channel
|
||||
*/
|
||||
int q6asm_media_format_block_pcm_format_support_v3(struct audio_client *ac,
|
||||
uint32_t rate,
|
||||
uint32_t channels,
|
||||
uint16_t bits_per_sample,
|
||||
int stream_id,
|
||||
bool use_default_chmap,
|
||||
char *channel_map,
|
||||
uint16_t sample_word_size)
|
||||
{
|
||||
if (!use_default_chmap && (channel_map == NULL)) {
|
||||
pr_err("%s: No valid chan map and can't use default\n",
|
||||
__func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
return __q6asm_media_format_block_pcm_v3(ac, rate,
|
||||
channels, bits_per_sample, stream_id,
|
||||
use_default_chmap, channel_map,
|
||||
sample_word_size);
|
||||
|
||||
}
|
||||
EXPORT_SYMBOL(q6asm_media_format_block_pcm_format_support_v3);
|
||||
|
||||
static int __q6asm_media_format_block_multi_ch_pcm(struct audio_client *ac,
|
||||
uint32_t rate, uint32_t channels,
|
||||
bool use_default_chmap, char *channel_map,
|
||||
|
@ -4162,6 +4468,76 @@ fail_cmd:
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int __q6asm_media_format_block_multi_ch_pcm_v3(struct audio_client *ac,
|
||||
uint32_t rate,
|
||||
uint32_t channels,
|
||||
bool use_default_chmap,
|
||||
char *channel_map,
|
||||
uint16_t bits_per_sample,
|
||||
uint16_t sample_word_size)
|
||||
{
|
||||
struct asm_multi_channel_pcm_fmt_blk_param_v3 fmt;
|
||||
u8 *channel_mapping;
|
||||
int rc;
|
||||
|
||||
pr_debug("%s: session[%d]rate[%d]ch[%d]bps[%d]wordsize[%d]\n", __func__,
|
||||
ac->session, rate, channels,
|
||||
bits_per_sample, sample_word_size);
|
||||
|
||||
memset(&fmt, 0, sizeof(fmt));
|
||||
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.fmt_blk.fmt_blk_size = sizeof(fmt) - sizeof(fmt.hdr) -
|
||||
sizeof(fmt.fmt_blk);
|
||||
fmt.param.num_channels = channels;
|
||||
fmt.param.bits_per_sample = bits_per_sample;
|
||||
fmt.param.sample_rate = rate;
|
||||
fmt.param.is_signed = 1;
|
||||
fmt.param.sample_word_size = sample_word_size;
|
||||
channel_mapping = fmt.param.channel_mapping;
|
||||
|
||||
memset(channel_mapping, 0, PCM_FORMAT_MAX_NUM_CHANNEL);
|
||||
|
||||
if (use_default_chmap) {
|
||||
if (q6asm_map_channels(channel_mapping, channels, false)) {
|
||||
pr_err("%s: map channels failed %d\n",
|
||||
__func__, channels);
|
||||
rc = -EINVAL;
|
||||
goto fail_cmd;
|
||||
}
|
||||
} else {
|
||||
memcpy(channel_mapping, channel_map,
|
||||
PCM_FORMAT_MAX_NUM_CHANNEL);
|
||||
}
|
||||
|
||||
rc = apr_send_pkt(ac->apr, (uint32_t *) &fmt);
|
||||
if (rc < 0) {
|
||||
pr_err("%s: Comamnd open 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;
|
||||
}
|
||||
if (atomic_read(&ac->cmd_state) > 0) {
|
||||
pr_err("%s: DSP returned error[%s]\n",
|
||||
__func__, adsp_err_get_err_str(
|
||||
atomic_read(&ac->cmd_state)));
|
||||
rc = adsp_err_get_lnx_err_code(
|
||||
atomic_read(&ac->cmd_state));
|
||||
goto fail_cmd;
|
||||
}
|
||||
return 0;
|
||||
fail_cmd:
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
int q6asm_media_format_block_multi_ch_pcm(struct audio_client *ac,
|
||||
uint32_t rate, uint32_t channels,
|
||||
bool use_default_chmap, char *channel_map)
|
||||
|
@ -4181,6 +4557,33 @@ int q6asm_media_format_block_multi_ch_pcm_v2(
|
|||
bits_per_sample);
|
||||
}
|
||||
|
||||
/*
|
||||
* q6asm_media_format_block_multi_ch_pcm_v3 - sends pcm decoder configuration
|
||||
* parameters
|
||||
*
|
||||
* @ac: Client session handle
|
||||
* @rate: sample rate
|
||||
* @channels: number of channels
|
||||
* @bits_per_sample: bit width of encoder session
|
||||
* @use_default_chmap: true if default channel map to be used
|
||||
* @channel_map: input channel map
|
||||
* @sample_word_size: Size in bits of the word that holds a sample of a channel
|
||||
*/
|
||||
int q6asm_media_format_block_multi_ch_pcm_v3(struct audio_client *ac,
|
||||
uint32_t rate, uint32_t channels,
|
||||
bool use_default_chmap,
|
||||
char *channel_map,
|
||||
uint16_t bits_per_sample,
|
||||
uint16_t sample_word_size)
|
||||
{
|
||||
return __q6asm_media_format_block_multi_ch_pcm_v3(ac, rate, channels,
|
||||
use_default_chmap,
|
||||
channel_map,
|
||||
bits_per_sample,
|
||||
sample_word_size);
|
||||
}
|
||||
EXPORT_SYMBOL(q6asm_media_format_block_multi_ch_pcm_v3);
|
||||
|
||||
static int __q6asm_media_format_block_multi_aac(struct audio_client *ac,
|
||||
struct asm_aac_cfg *cfg, int stream_id)
|
||||
{
|
||||
|
|
Loading…
Add table
Reference in a new issue