Merge "ASoC: msm: qdsp6v2: Add IEC61937 compressed HDMI pass-though"

This commit is contained in:
Linux Build Service Account 2017-05-25 15:51:57 -07:00 committed by Gerrit - the friendly Code Review server
commit f95c3de80f
4 changed files with 127 additions and 4 deletions

View file

@ -4006,6 +4006,32 @@ struct asm_generic_compressed_fmt_blk_t {
} __packed;
/* Command to send sample rate & channels for IEC61937 (compressed) or IEC60958
* (pcm) streams. Both audio standards use the same format and are used for
* HDMI or SPDIF.
*/
#define ASM_DATA_CMD_IEC_60958_MEDIA_FMT 0x0001321E
struct asm_iec_compressed_fmt_blk_t {
struct apr_hdr hdr;
/*
* Nominal sampling rate of the incoming bitstream.
* Supported values: 8000, 11025, 16000, 22050, 24000, 32000,
* 44100, 48000, 88200, 96000, 176400, 192000,
* 352800, 384000
*/
uint32_t sampling_rate;
/*
* Number of channels of the incoming bitstream.
* Supported values: 1,2,3,4,5,6,7,8
*/
uint32_t num_channels;
} __packed;
struct asm_multi_channel_pcm_fmt_blk_v2 {
struct apr_hdr hdr;
struct asm_data_cmd_media_fmt_update_v2 fmt_blk;
@ -5071,6 +5097,11 @@ struct asm_amrwbplus_fmt_blk_v2 {
#define ASM_MEDIA_FMT_APE 0x00012F32
#define ASM_MEDIA_FMT_DSD 0x00012F3E
#define ASM_MEDIA_FMT_TRUEHD 0x00013215
/* 0x0 is used for fomat ID since ADSP dynamically determines the
* format encapsulated in the IEC61937 (compressed) or IEC60958
* (pcm) packets.
*/
#define ASM_MEDIA_FMT_IEC 0x00000000
/* Media format ID for adaptive transform acoustic coding. This
* ID is used by the #ASM_STREAM_CMD_OPEN_WRITE_COMPRESSED command
@ -10544,6 +10575,7 @@ enum {
COMPRESSED_PASSTHROUGH_DSD,
LISTEN,
COMPRESSED_PASSTHROUGH_GEN,
COMPRESSED_PASSTHROUGH_IEC61937
};
#define AUDPROC_MODULE_ID_COMPRESSED_MUTE 0x00010770

View file

@ -56,6 +56,7 @@
#define FORMAT_APTX 0x001e
#define FORMAT_GEN_COMPR 0x001f
#define FORMAT_TRUEHD 0x0020
#define FORMAT_IEC61937 0x0021
#define ENCDEC_SBCBITRATE 0x0001
#define ENCDEC_IMMEDIATE_DECODE 0x0002
@ -509,6 +510,10 @@ int q6asm_media_format_block_gen_compr(
bool use_default_chmap, char *channel_map,
uint16_t bits_per_sample);
int q6asm_media_format_block_iec(
struct audio_client *ac,
uint32_t rate, uint32_t channels);
int q6asm_media_format_block_multi_ch_pcm_v3(struct audio_client *ac,
uint32_t rate, uint32_t channels,
bool use_default_chmap,

View file

@ -177,7 +177,7 @@ struct msm_compr_audio {
const u32 compr_codecs[] = {
SND_AUDIOCODEC_AC3, SND_AUDIOCODEC_EAC3, SND_AUDIOCODEC_DTS,
SND_AUDIOCODEC_DSD, SND_AUDIOCODEC_TRUEHD};
SND_AUDIOCODEC_DSD, SND_AUDIOCODEC_TRUEHD, SND_AUDIOCODEC_IEC61937};
struct query_audio_effect {
uint32_t mod_id;
@ -921,7 +921,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 = 16;
prtd->compr_cap.num_codecs = 17;
prtd->compr_cap.codecs[0] = SND_AUDIOCODEC_MP3;
prtd->compr_cap.codecs[1] = SND_AUDIOCODEC_AAC;
prtd->compr_cap.codecs[2] = SND_AUDIOCODEC_AC3;
@ -938,6 +938,7 @@ static void populate_codec_list(struct msm_compr_audio *prtd)
prtd->compr_cap.codecs[13] = SND_AUDIOCODEC_DSD;
prtd->compr_cap.codecs[14] = SND_AUDIOCODEC_APTX;
prtd->compr_cap.codecs[15] = SND_AUDIOCODEC_TRUEHD;
prtd->compr_cap.codecs[16] = SND_AUDIOCODEC_IEC61937;
}
static int msm_compr_send_media_format_block(struct snd_compr_stream *cstream,
@ -1196,6 +1197,15 @@ static int msm_compr_send_media_format_block(struct snd_compr_stream *cstream,
pr_debug("SND_AUDIOCODEC_TRUEHD\n");
/* no media format block needed */
break;
case FORMAT_IEC61937:
pr_debug("SND_AUDIOCODEC_IEC61937\n");
ret = q6asm_media_format_block_iec(prtd->audio_client,
prtd->sample_rate,
prtd->num_channels);
if (ret < 0)
pr_err("%s: CMD IEC61937 Format block failed ret %d\n",
__func__, ret);
break;
case FORMAT_APTX:
pr_debug("SND_AUDIOCODEC_APTX\n");
memset(&aptx_cfg, 0x0, sizeof(struct aptx_dec_bt_addr_cfg));
@ -1857,8 +1867,11 @@ static int msm_compr_set_params(struct snd_compr_stream *cstream,
prtd->sample_rate = prtd->codec_param.codec.sample_rate;
pr_debug("%s: sample_rate %d\n", __func__, prtd->sample_rate);
if (prtd->codec_param.codec.compr_passthr >= LEGACY_PCM &&
prtd->codec_param.codec.compr_passthr <= COMPRESSED_PASSTHROUGH_DSD)
if ((prtd->codec_param.codec.compr_passthr >= LEGACY_PCM &&
prtd->codec_param.
codec.compr_passthr <= COMPRESSED_PASSTHROUGH_DSD) ||
(prtd->codec_param.
codec.compr_passthr == COMPRESSED_PASSTHROUGH_IEC61937))
prtd->compr_passthr = prtd->codec_param.codec.compr_passthr;
else
prtd->compr_passthr = LEGACY_PCM;
@ -1981,6 +1994,12 @@ static int msm_compr_set_params(struct snd_compr_stream *cstream,
break;
}
case SND_AUDIOCODEC_IEC61937: {
pr_debug("%s: SND_AUDIOCODEC_IEC61937\n", __func__);
prtd->codec = FORMAT_IEC61937;
break;
}
case SND_AUDIOCODEC_APTX: {
pr_debug("%s: SND_AUDIOCODEC_APTX\n", __func__);
prtd->codec = FORMAT_APTX;
@ -2853,6 +2872,7 @@ static int msm_compr_get_codec_caps(struct snd_compr_stream *cstream,
case SND_AUDIOCODEC_DTS:
case SND_AUDIOCODEC_DSD:
case SND_AUDIOCODEC_TRUEHD:
case SND_AUDIOCODEC_IEC61937:
case SND_AUDIOCODEC_APTX:
break;
default:
@ -3290,6 +3310,7 @@ static int msm_compr_send_dec_params(struct snd_compr_stream *cstream,
case FORMAT_MP3:
case FORMAT_MPEG4_AAC:
case FORMAT_TRUEHD:
case FORMAT_IEC61937:
case FORMAT_APTX:
pr_debug("%s: no runtime parameters for codec: %d\n", __func__,
prtd->codec);
@ -3358,6 +3379,7 @@ static int msm_compr_dec_params_put(struct snd_kcontrol *kcontrol,
case FORMAT_DTS:
case FORMAT_DSD:
case FORMAT_TRUEHD:
case FORMAT_IEC61937:
case FORMAT_APTX:
pr_debug("%s: no runtime parameters for codec: %d\n", __func__,
prtd->codec);

View file

@ -1792,6 +1792,7 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
case ASM_STREAM_CMD_OPEN_LOOPBACK_V2:
case ASM_STREAM_CMD_OPEN_TRANSCODE_LOOPBACK:
case ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2:
case ASM_DATA_CMD_IEC_60958_MEDIA_FMT:
case ASM_STREAM_CMD_SET_ENCDEC_PARAM:
case ASM_STREAM_CMD_SET_ENCDEC_PARAM_V2:
case ASM_STREAM_CMD_REGISTER_ENCDEC_EVENTS:
@ -2640,6 +2641,9 @@ int q6asm_open_write_compressed(struct audio_client *ac, uint32_t format,
case FORMAT_TRUEHD:
open.fmt_id = ASM_MEDIA_FMT_TRUEHD;
break;
case FORMAT_IEC61937:
open.fmt_id = ASM_MEDIA_FMT_IEC;
break;
default:
pr_err("%s: Invalid format[%d]\n", __func__, format);
rc = -EINVAL;
@ -2656,6 +2660,10 @@ int q6asm_open_write_compressed(struct audio_client *ac, uint32_t format,
open.flags = 0x8;
pr_debug("%s: Flag 8 - COMPRESSED_PASSTHROUGH_CONVERT\n",
__func__);
} else if (passthrough_flag == COMPRESSED_PASSTHROUGH_IEC61937) {
open.flags = 0x1;
pr_debug("%s: Flag 1 - COMPRESSED_PASSTHROUGH_IEC61937\n",
__func__);
} else {
pr_err("%s: Invalid passthrough type[%d]\n",
__func__, passthrough_flag);
@ -5424,6 +5432,62 @@ fail_cmd:
}
EXPORT_SYMBOL(q6asm_media_format_block_gen_compr);
/*
* q6asm_media_format_block_iec - set up IEC61937 (compressed) or IEC60958
* (pcm) format params. Both audio standards
* use the same format and are used for
* HDMI or SPDIF.
*
* @ac: Client session handle
* @rate: sample rate
* @channels: number of channels
*/
int q6asm_media_format_block_iec(struct audio_client *ac,
uint32_t rate, uint32_t channels)
{
struct asm_iec_compressed_fmt_blk_t fmt;
int rc = 0;
pr_debug("%s: session[%d]rate[%d]ch[%d]\n",
__func__, ac->session, rate,
channels);
memset(&fmt, 0, sizeof(fmt));
q6asm_add_hdr(ac, &fmt.hdr, sizeof(fmt), TRUE);
fmt.hdr.opcode = ASM_DATA_CMD_IEC_60958_MEDIA_FMT;
fmt.num_channels = channels;
fmt.sampling_rate = rate;
atomic_set(&ac->cmd_state, -1);
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));
}
return 0;
fail_cmd:
return rc;
}
EXPORT_SYMBOL(q6asm_media_format_block_iec);
static int __q6asm_media_format_block_multi_aac(struct audio_client *ac,
struct asm_aac_cfg *cfg, int stream_id)
{