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:
Linux Build Service Account 2018-06-06 15:43:43 -07:00 committed by Gerrit - the friendly Code Review server
commit bfef6ec17f
6 changed files with 170 additions and 13 deletions

View file

@ -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;

View file

@ -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);

View file

@ -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[] = {

View file

@ -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

View file

@ -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 {

View file

@ -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);