Merge changes I2a570ec9,I563c59eb into audio-drivers.lnx.3.0
* changes: asoc: sm8150: Add MultiMedia17 FE with capture support dsp: Add support for custom encoder
This commit is contained in:
commit
bfef6ec17f
6 changed files with 170 additions and 13 deletions
|
@ -1432,6 +1432,7 @@ static int msm_compr_configure_dsp_for_capture(struct snd_compr_stream *cstream)
|
||||||
int dir = OUT, ret = 0;
|
int dir = OUT, ret = 0;
|
||||||
struct audio_client *ac = prtd->audio_client;
|
struct audio_client *ac = prtd->audio_client;
|
||||||
uint32_t stream_index;
|
uint32_t stream_index;
|
||||||
|
uint32_t enc_cfg_id = ENC_CFG_ID_NONE;
|
||||||
|
|
||||||
switch (prtd->codec_param.codec.format) {
|
switch (prtd->codec_param.codec.format) {
|
||||||
case SNDRV_PCM_FORMAT_S24_LE:
|
case SNDRV_PCM_FORMAT_S24_LE:
|
||||||
|
@ -1450,6 +1451,9 @@ static int msm_compr_configure_dsp_for_capture(struct snd_compr_stream *cstream)
|
||||||
default:
|
default:
|
||||||
bits_per_sample = 16;
|
bits_per_sample = 16;
|
||||||
sample_word_size = 16;
|
sample_word_size = 16;
|
||||||
|
if (prtd->codec == FORMAT_BESPOKE)
|
||||||
|
enc_cfg_id =
|
||||||
|
prtd->codec_param.codec.options.generic.reserved[0];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1457,11 +1461,11 @@ static int msm_compr_configure_dsp_for_capture(struct snd_compr_stream *cstream)
|
||||||
__func__, ac->stream_id, bits_per_sample);
|
__func__, ac->stream_id, bits_per_sample);
|
||||||
|
|
||||||
if (prtd->codec_param.codec.flags & COMPRESSED_TIMESTAMP_FLAG) {
|
if (prtd->codec_param.codec.flags & COMPRESSED_TIMESTAMP_FLAG) {
|
||||||
ret = q6asm_open_read_v4(prtd->audio_client, FORMAT_LINEAR_PCM,
|
ret = q6asm_open_read_v4(prtd->audio_client, prtd->codec,
|
||||||
bits_per_sample, true);
|
bits_per_sample, true, enc_cfg_id);
|
||||||
} else {
|
} else {
|
||||||
ret = q6asm_open_read_v4(prtd->audio_client, FORMAT_LINEAR_PCM,
|
ret = q6asm_open_read_v4(prtd->audio_client, prtd->codec,
|
||||||
bits_per_sample, false);
|
bits_per_sample, false, enc_cfg_id);
|
||||||
}
|
}
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
pr_err("%s: q6asm_open_read failed:%d\n", __func__, ret);
|
pr_err("%s: q6asm_open_read failed:%d\n", __func__, ret);
|
||||||
|
@ -1521,10 +1525,20 @@ static int msm_compr_configure_dsp_for_capture(struct snd_compr_stream *cstream)
|
||||||
pr_debug("%s: sample_rate = %d channels = %d bps = %d sample_word_size = %d\n",
|
pr_debug("%s: sample_rate = %d channels = %d bps = %d sample_word_size = %d\n",
|
||||||
__func__, prtd->sample_rate, prtd->num_channels,
|
__func__, prtd->sample_rate, prtd->num_channels,
|
||||||
bits_per_sample, sample_word_size);
|
bits_per_sample, sample_word_size);
|
||||||
ret = q6asm_enc_cfg_blk_pcm_format_support_v4(prtd->audio_client,
|
if (prtd->codec == FORMAT_BESPOKE) {
|
||||||
|
/*
|
||||||
|
* For BESPOKE codec, encoder specific config params are
|
||||||
|
* included as part of generic.
|
||||||
|
*/
|
||||||
|
ret = q6asm_enc_cfg_blk_custom(prtd->audio_client, prtd->sample_rate,
|
||||||
|
prtd->num_channels, prtd->codec,
|
||||||
|
(void *)&prtd->codec_param.codec.options.generic);
|
||||||
|
} else {
|
||||||
|
ret = q6asm_enc_cfg_blk_pcm_format_support_v4(prtd->audio_client,
|
||||||
prtd->sample_rate, prtd->num_channels,
|
prtd->sample_rate, prtd->num_channels,
|
||||||
bits_per_sample, sample_word_size,
|
bits_per_sample, sample_word_size,
|
||||||
ASM_LITTLE_ENDIAN, DEFAULT_QF);
|
ASM_LITTLE_ENDIAN, DEFAULT_QF);
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -2043,6 +2057,12 @@ static int msm_compr_set_params(struct snd_compr_stream *cstream,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case SND_AUDIOCODEC_BESPOKE: {
|
||||||
|
pr_debug("%s: SND_AUDIOCODEC_BESPOKE\n", __func__);
|
||||||
|
prtd->codec = FORMAT_BESPOKE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
pr_err("codec not supported, id =%d\n", params->codec.id);
|
pr_err("codec not supported, id =%d\n", params->codec.id);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
|
@ -490,7 +490,7 @@ static int msm_pcm_capture_prepare(struct snd_pcm_substream *substream)
|
||||||
prtd->audio_client->perf_mode);
|
prtd->audio_client->perf_mode);
|
||||||
|
|
||||||
ret = q6asm_open_read_v4(prtd->audio_client, FORMAT_LINEAR_PCM,
|
ret = q6asm_open_read_v4(prtd->audio_client, FORMAT_LINEAR_PCM,
|
||||||
bits_per_sample, false);
|
bits_per_sample, false, ENC_CFG_ID_NONE);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
pr_err("%s: q6asm_open_read failed\n", __func__);
|
pr_err("%s: q6asm_open_read failed\n", __func__);
|
||||||
q6asm_audio_client_free(prtd->audio_client);
|
q6asm_audio_client_free(prtd->audio_client);
|
||||||
|
|
|
@ -5668,6 +5668,21 @@ static struct snd_soc_dai_link msm_common_misc_fe_dai_links[] = {
|
||||||
.codec_dai_name = "snd-soc-dummy-dai",
|
.codec_dai_name = "snd-soc-dummy-dai",
|
||||||
.codec_name = "snd-soc-dummy",
|
.codec_name = "snd-soc-dummy",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.name = "Compress Capture",
|
||||||
|
.stream_name = "Compress9",
|
||||||
|
.cpu_dai_name = "MultiMedia17",
|
||||||
|
.platform_name = "msm-compress-dsp",
|
||||||
|
.dynamic = 1,
|
||||||
|
.dpcm_capture = 1,
|
||||||
|
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
|
||||||
|
SND_SOC_DPCM_TRIGGER_POST},
|
||||||
|
.codec_dai_name = "snd-soc-dummy-dai",
|
||||||
|
.codec_name = "snd-soc-dummy",
|
||||||
|
.ignore_suspend = 1,
|
||||||
|
.ignore_pmdown_time = 1,
|
||||||
|
.id = MSM_FRONTEND_DAI_MULTIMEDIA17,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct snd_soc_dai_link msm_common_be_dai_links[] = {
|
static struct snd_soc_dai_link msm_common_be_dai_links[] = {
|
||||||
|
|
110
dsp/q6asm.c
110
dsp/q6asm.c
|
@ -46,6 +46,8 @@
|
||||||
#define FALSE 0x00
|
#define FALSE 0x00
|
||||||
#define SESSION_MAX 8
|
#define SESSION_MAX 8
|
||||||
|
|
||||||
|
#define ENC_FRAMES_PER_BUFFER 0x01
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
ASM_TOPOLOGY_CAL = 0,
|
ASM_TOPOLOGY_CAL = 0,
|
||||||
ASM_CUSTOM_TOP_CAL,
|
ASM_CUSTOM_TOP_CAL,
|
||||||
|
@ -2812,7 +2814,7 @@ EXPORT_SYMBOL(q6asm_set_soft_volume_module_instance_ids);
|
||||||
static int __q6asm_open_read(struct audio_client *ac,
|
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,
|
||||||
uint32_t pcm_format_block_ver,
|
uint32_t pcm_format_block_ver,
|
||||||
bool ts_mode)
|
bool ts_mode, uint32_t enc_cfg_id)
|
||||||
{
|
{
|
||||||
int rc = 0x00;
|
int rc = 0x00;
|
||||||
struct asm_stream_cmd_open_read_v3 open;
|
struct asm_stream_cmd_open_read_v3 open;
|
||||||
|
@ -2888,6 +2890,12 @@ static int __q6asm_open_read(struct audio_client *ac,
|
||||||
open.mode_flags |= BUFFER_META_ENABLE;
|
open.mode_flags |= BUFFER_META_ENABLE;
|
||||||
open.enc_cfg_id = ASM_MEDIA_FMT_AMRWB_FS;
|
open.enc_cfg_id = ASM_MEDIA_FMT_AMRWB_FS;
|
||||||
break;
|
break;
|
||||||
|
case FORMAT_BESPOKE:
|
||||||
|
open.mode_flags |= BUFFER_META_ENABLE;
|
||||||
|
open.enc_cfg_id = enc_cfg_id;
|
||||||
|
if (ts_mode)
|
||||||
|
open.mode_flags |= ABSOLUTE_TIMESTAMP_ENABLE;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
pr_err("%s: Invalid format 0x%x\n",
|
pr_err("%s: Invalid format 0x%x\n",
|
||||||
__func__, format);
|
__func__, format);
|
||||||
|
@ -2939,7 +2947,7 @@ int q6asm_open_read(struct audio_client *ac,
|
||||||
{
|
{
|
||||||
return __q6asm_open_read(ac, format, 16,
|
return __q6asm_open_read(ac, format, 16,
|
||||||
PCM_MEDIA_FORMAT_V2 /*media fmt block ver*/,
|
PCM_MEDIA_FORMAT_V2 /*media fmt block ver*/,
|
||||||
false/*ts_mode*/);
|
false/*ts_mode*/, ENC_CFG_ID_NONE);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(q6asm_open_read);
|
EXPORT_SYMBOL(q6asm_open_read);
|
||||||
|
|
||||||
|
@ -2948,7 +2956,7 @@ int q6asm_open_read_v2(struct audio_client *ac, uint32_t format,
|
||||||
{
|
{
|
||||||
return __q6asm_open_read(ac, format, bits_per_sample,
|
return __q6asm_open_read(ac, format, bits_per_sample,
|
||||||
PCM_MEDIA_FORMAT_V2 /*media fmt block ver*/,
|
PCM_MEDIA_FORMAT_V2 /*media fmt block ver*/,
|
||||||
false/*ts_mode*/);
|
false/*ts_mode*/, ENC_CFG_ID_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2963,7 +2971,7 @@ int q6asm_open_read_v3(struct audio_client *ac, uint32_t format,
|
||||||
{
|
{
|
||||||
return __q6asm_open_read(ac, format, bits_per_sample,
|
return __q6asm_open_read(ac, format, bits_per_sample,
|
||||||
PCM_MEDIA_FORMAT_V3/*media fmt block ver*/,
|
PCM_MEDIA_FORMAT_V3/*media fmt block ver*/,
|
||||||
false/*ts_mode*/);
|
false/*ts_mode*/, ENC_CFG_ID_NONE);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(q6asm_open_read_v3);
|
EXPORT_SYMBOL(q6asm_open_read_v3);
|
||||||
|
|
||||||
|
@ -2976,11 +2984,12 @@ EXPORT_SYMBOL(q6asm_open_read_v3);
|
||||||
* @ts_mode: timestamp mode
|
* @ts_mode: timestamp mode
|
||||||
*/
|
*/
|
||||||
int q6asm_open_read_v4(struct audio_client *ac, uint32_t format,
|
int q6asm_open_read_v4(struct audio_client *ac, uint32_t format,
|
||||||
uint16_t bits_per_sample, bool ts_mode)
|
uint16_t bits_per_sample, bool ts_mode,
|
||||||
|
uint32_t enc_cfg_id)
|
||||||
{
|
{
|
||||||
return __q6asm_open_read(ac, format, bits_per_sample,
|
return __q6asm_open_read(ac, format, bits_per_sample,
|
||||||
PCM_MEDIA_FORMAT_V4 /*media fmt block ver*/,
|
PCM_MEDIA_FORMAT_V4 /*media fmt block ver*/,
|
||||||
ts_mode);
|
ts_mode, enc_cfg_id);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(q6asm_open_read_v4);
|
EXPORT_SYMBOL(q6asm_open_read_v4);
|
||||||
|
|
||||||
|
@ -4287,6 +4296,95 @@ int q6asm_stream_run_nowait(struct audio_client *ac, uint32_t flags,
|
||||||
return __q6asm_run_nowait(ac, flags, msw_ts, lsw_ts, stream_id);
|
return __q6asm_run_nowait(ac, flags, msw_ts, lsw_ts, stream_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* q6asm_enc_cfg_blk_custom -
|
||||||
|
* command to set encode cfg block for custom
|
||||||
|
*
|
||||||
|
* @ac: Audio client handle
|
||||||
|
* @sample_rate: Sample rate
|
||||||
|
* @channels: number of ASM channels
|
||||||
|
* @format: custom format flag
|
||||||
|
* @cfg: generic encoder config
|
||||||
|
*
|
||||||
|
* Returns 0 on success or error on failure
|
||||||
|
*/
|
||||||
|
int q6asm_enc_cfg_blk_custom(struct audio_client *ac,
|
||||||
|
uint32_t sample_rate, uint32_t channels,
|
||||||
|
uint32_t format, void *cfg)
|
||||||
|
{
|
||||||
|
struct asm_custom_enc_cfg_t_v2 enc_cfg;
|
||||||
|
int rc = 0;
|
||||||
|
uint32_t custom_size;
|
||||||
|
struct snd_enc_generic *enc_generic = (struct snd_enc_generic *) cfg;
|
||||||
|
|
||||||
|
custom_size = enc_generic->reserved[1];
|
||||||
|
|
||||||
|
pr_debug("%s: session[%d] size[%d] res[2]=[%d] res[3]=[%d]\n",
|
||||||
|
__func__, ac->session, custom_size, enc_generic->reserved[2],
|
||||||
|
enc_generic->reserved[3]);
|
||||||
|
|
||||||
|
pr_debug("%s: res[4]=[%d] sr[%d] ch[%d] format[%d]\n",
|
||||||
|
__func__, enc_generic->reserved[4], sample_rate,
|
||||||
|
channels, format);
|
||||||
|
|
||||||
|
memset(&enc_cfg, 0, sizeof(struct asm_custom_enc_cfg_t_v2));
|
||||||
|
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(struct asm_custom_enc_cfg_t_v2) -
|
||||||
|
sizeof(struct asm_stream_cmd_set_encdec_param);
|
||||||
|
enc_cfg.encblk.frames_per_buf = ENC_FRAMES_PER_BUFFER;
|
||||||
|
enc_cfg.encblk.enc_cfg_blk_size = enc_cfg.encdec.param_size -
|
||||||
|
sizeof(struct asm_enc_cfg_blk_param_v2);
|
||||||
|
|
||||||
|
enc_cfg.num_channels = channels;
|
||||||
|
enc_cfg.sample_rate = sample_rate;
|
||||||
|
|
||||||
|
if (q6asm_map_channels(enc_cfg.channel_mapping, channels, false)) {
|
||||||
|
pr_err("%s: map channels failed %d\n",
|
||||||
|
__func__, channels);
|
||||||
|
rc = -EINVAL;
|
||||||
|
goto fail_cmd;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (format == FORMAT_BESPOKE && custom_size &&
|
||||||
|
custom_size <= sizeof(enc_cfg.custom_data)) {
|
||||||
|
memcpy(enc_cfg.custom_data, &enc_generic->reserved[2],
|
||||||
|
custom_size);
|
||||||
|
enc_cfg.custom_size = custom_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = apr_send_pkt(ac->apr, (uint32_t *) &enc_cfg);
|
||||||
|
if (rc < 0) {
|
||||||
|
pr_err("%s: Comamnd %d failed %d\n",
|
||||||
|
__func__, ASM_STREAM_CMD_SET_ENCDEC_PARAM, 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;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(q6asm_enc_cfg_blk_custom);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* q6asm_enc_cfg_blk_aac -
|
* q6asm_enc_cfg_blk_aac -
|
||||||
* command to set encode cfg block for aac
|
* command to set encode cfg block for aac
|
||||||
|
|
|
@ -4743,6 +4743,22 @@ struct asm_enc_cfg_blk_param_v2 {
|
||||||
|
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
|
struct asm_custom_enc_cfg_t_v2 {
|
||||||
|
struct apr_hdr hdr;
|
||||||
|
struct asm_stream_cmd_set_encdec_param encdec;
|
||||||
|
struct asm_enc_cfg_blk_param_v2 encblk;
|
||||||
|
uint32_t sample_rate;
|
||||||
|
|
||||||
|
uint16_t num_channels;
|
||||||
|
uint16_t reserved;
|
||||||
|
/* num_ch == 1, then PCM_CHANNEL_C,
|
||||||
|
* num_ch == 2, then {PCM_CHANNEL_L, PCM_CHANNEL_R}
|
||||||
|
*/
|
||||||
|
uint8_t channel_mapping[8];
|
||||||
|
uint32_t custom_size;
|
||||||
|
uint8_t custom_data[15];
|
||||||
|
} __packed;
|
||||||
|
|
||||||
/* @brief Dolby Digital Plus end point configuration structure
|
/* @brief Dolby Digital Plus end point configuration structure
|
||||||
*/
|
*/
|
||||||
struct asm_dec_ddp_endp_param_v2 {
|
struct asm_dec_ddp_endp_param_v2 {
|
||||||
|
|
|
@ -57,11 +57,14 @@
|
||||||
#define FORMAT_GEN_COMPR 0x001f
|
#define FORMAT_GEN_COMPR 0x001f
|
||||||
#define FORMAT_TRUEHD 0x0020
|
#define FORMAT_TRUEHD 0x0020
|
||||||
#define FORMAT_IEC61937 0x0021
|
#define FORMAT_IEC61937 0x0021
|
||||||
|
#define FORMAT_BESPOKE 0x0022
|
||||||
|
|
||||||
#define ENCDEC_SBCBITRATE 0x0001
|
#define ENCDEC_SBCBITRATE 0x0001
|
||||||
#define ENCDEC_IMMEDIATE_DECODE 0x0002
|
#define ENCDEC_IMMEDIATE_DECODE 0x0002
|
||||||
#define ENCDEC_CFG_BLK 0x0003
|
#define ENCDEC_CFG_BLK 0x0003
|
||||||
|
|
||||||
|
#define ENC_CFG_ID_NONE 0x0000
|
||||||
|
|
||||||
#define CMD_PAUSE 0x0001
|
#define CMD_PAUSE 0x0001
|
||||||
#define CMD_FLUSH 0x0002
|
#define CMD_FLUSH 0x0002
|
||||||
#define CMD_EOS 0x0003
|
#define CMD_EOS 0x0003
|
||||||
|
@ -290,7 +293,8 @@ int q6asm_open_read_v3(struct audio_client *ac, uint32_t format,
|
||||||
uint16_t bits_per_sample);
|
uint16_t bits_per_sample);
|
||||||
|
|
||||||
int q6asm_open_read_v4(struct audio_client *ac, uint32_t format,
|
int q6asm_open_read_v4(struct audio_client *ac, uint32_t format,
|
||||||
uint16_t bits_per_sample, bool ts_mode);
|
uint16_t bits_per_sample, bool ts_mode,
|
||||||
|
uint32_t enc_cfg_id);
|
||||||
|
|
||||||
int q6asm_open_write(struct audio_client *ac, uint32_t format
|
int q6asm_open_write(struct audio_client *ac, uint32_t format
|
||||||
/*, uint16_t bits_per_sample*/);
|
/*, uint16_t bits_per_sample*/);
|
||||||
|
@ -454,6 +458,10 @@ int q6asm_enc_cfg_blk_pcm_format_support_v4(struct audio_client *ac,
|
||||||
uint16_t endianness,
|
uint16_t endianness,
|
||||||
uint16_t mode);
|
uint16_t mode);
|
||||||
|
|
||||||
|
int q6asm_enc_cfg_blk_custom(struct audio_client *ac,
|
||||||
|
uint32_t sample_rate, uint32_t channels,
|
||||||
|
uint32_t format, void *cfg);
|
||||||
|
|
||||||
int q6asm_set_encdec_chan_map(struct audio_client *ac,
|
int q6asm_set_encdec_chan_map(struct audio_client *ac,
|
||||||
uint32_t num_channels);
|
uint32_t num_channels);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue