summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorDhanalakshmi Siddani <dsiddani@codeaurora.org>2016-12-26 16:01:43 +0530
committerDhanalakshmi Siddani <dsiddani@codeaurora.org>2017-01-20 18:03:29 +0530
commit9d558f7ecfa0c4cf393a60f6acbbd00f50b7455f (patch)
tree26851c91683d3041a7555c7bd834e33b059bd810 /sound
parent774228d053cc54c98fc0da712c5a36e4b816af7b (diff)
ASoC: msm: Aptx decoder integration changes
Add changes to support aptx decoder in offload mode. Add support to set BT device address and add new mixer control to set license key. CRs-Fixed: 1106128 Change-Id: Idd4ec8ab829883ef4848be8b686e24101ccbed60 Signed-off-by: Dhanalakshmi Siddani <dsiddani@codeaurora.org>
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c31
-rw-r--r--sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c30
-rw-r--r--sound/soc/msm/qdsp6v2/q6asm.c117
3 files changed, 177 insertions, 1 deletions
diff --git a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c
index 9421d03f6a8d..f5b8c396717f 100644
--- a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c
@@ -754,7 +754,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 = 14;
+ prtd->compr_cap.num_codecs = 15;
prtd->compr_cap.codecs[0] = SND_AUDIOCODEC_MP3;
prtd->compr_cap.codecs[1] = SND_AUDIOCODEC_AAC;
prtd->compr_cap.codecs[2] = SND_AUDIOCODEC_AC3;
@@ -769,6 +769,7 @@ static void populate_codec_list(struct msm_compr_audio *prtd)
prtd->compr_cap.codecs[11] = SND_AUDIOCODEC_APE;
prtd->compr_cap.codecs[12] = SND_AUDIOCODEC_DTS;
prtd->compr_cap.codecs[13] = SND_AUDIOCODEC_DSD;
+ prtd->compr_cap.codecs[14] = SND_AUDIOCODEC_APTX;
}
static int msm_compr_send_media_format_block(struct snd_compr_stream *cstream,
@@ -788,6 +789,7 @@ static int msm_compr_send_media_format_block(struct snd_compr_stream *cstream,
struct asm_alac_cfg alac_cfg;
struct asm_ape_cfg ape_cfg;
struct asm_dsd_cfg dsd_cfg;
+ struct aptx_dec_bt_addr_cfg aptx_cfg;
union snd_codec_options *codec_options;
int ret = 0;
@@ -1022,6 +1024,24 @@ static int msm_compr_send_media_format_block(struct snd_compr_stream *cstream,
pr_err("%s: CMD DSD 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));
+ ret = q6asm_stream_media_format_block_aptx_dec(
+ prtd->audio_client,
+ prtd->sample_rate,
+ stream_id);
+ if (ret >= 0) {
+ aptx_cfg.nap = codec_options->aptx_dec.nap;
+ aptx_cfg.uap = codec_options->aptx_dec.uap;
+ aptx_cfg.lap = codec_options->aptx_dec.lap;
+ q6asm_set_aptx_dec_bt_addr(prtd->audio_client,
+ &aptx_cfg);
+ } else {
+ pr_err("%s: CMD Format block failed ret %d\n",
+ __func__, ret);
+ }
+ break;
default:
pr_debug("%s, unsupported format, skip", __func__);
break;
@@ -1789,6 +1809,12 @@ static int msm_compr_set_params(struct snd_compr_stream *cstream,
break;
}
+ case SND_AUDIOCODEC_APTX: {
+ pr_debug("%s: SND_AUDIOCODEC_APTX\n", __func__);
+ prtd->codec = FORMAT_APTX;
+ break;
+ }
+
default:
pr_err("codec not supported, id =%d\n", params->codec.id);
return -EINVAL;
@@ -2659,6 +2685,7 @@ static int msm_compr_get_codec_caps(struct snd_compr_stream *cstream,
case SND_AUDIOCODEC_DTS:
break;
case SND_AUDIOCODEC_DSD:
+ case SND_AUDIOCODEC_APTX:
break;
default:
pr_err("%s: Unsupported audio codec %d\n",
@@ -3071,6 +3098,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_APTX:
pr_debug("%s: no runtime parameters for codec: %d\n", __func__,
prtd->codec);
break;
@@ -3137,6 +3165,7 @@ static int msm_compr_dec_params_put(struct snd_kcontrol *kcontrol,
case FORMAT_APE:
case FORMAT_DTS:
case FORMAT_DSD:
+ case FORMAT_APTX:
pr_debug("%s: no runtime parameters for codec: %d\n", __func__,
prtd->codec);
break;
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
index 485ffa06f5bd..7d398440226c 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
@@ -12050,6 +12050,33 @@ static const struct snd_kcontrol_new device_pp_params_mixer_controls[] = {
msm_routing_put_device_pp_params_mixer),
};
+static int msm_aptx_dec_license_control_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ ucontrol->value.integer.value[0] =
+ core_get_license_status(ASM_MEDIA_FMT_APTX);
+ pr_debug("%s: status %ld\n", __func__,
+ ucontrol->value.integer.value[0]);
+ return 0;
+}
+
+static int msm_aptx_dec_license_control_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int32_t status = 0;
+
+ status = core_set_license(ucontrol->value.integer.value[0],
+ APTX_CLASSIC_DEC_LICENSE_ID);
+ pr_debug("%s: status %d\n", __func__, status);
+ return status;
+}
+
+static const struct snd_kcontrol_new aptx_dec_license_controls[] = {
+ SOC_SINGLE_EXT("APTX Dec License", SND_SOC_NOPM, 0,
+ 0xFFFF, 0, msm_aptx_dec_license_control_get,
+ msm_aptx_dec_license_control_put),
+};
+
static struct snd_pcm_ops msm_routing_pcm_ops = {
.hw_params = msm_pcm_routing_hw_params,
.close = msm_pcm_routing_close,
@@ -12102,6 +12129,9 @@ static int msm_routing_probe(struct snd_soc_platform *platform)
ARRAY_SIZE(msm_source_tracking_controls));
snd_soc_add_platform_controls(platform, adm_channel_config_controls,
ARRAY_SIZE(adm_channel_config_controls));
+
+ snd_soc_add_platform_controls(platform, aptx_dec_license_controls,
+ ARRAY_SIZE(aptx_dec_license_controls));
return 0;
}
diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c
index cfaa562fdaba..d15541548122 100644
--- a/sound/soc/msm/qdsp6v2/q6asm.c
+++ b/sound/soc/msm/qdsp6v2/q6asm.c
@@ -2661,6 +2661,9 @@ static int __q6asm_open_write(struct audio_client *ac, uint32_t format,
case FORMAT_DSD:
open.dec_fmt_id = ASM_MEDIA_FMT_DSD;
break;
+ case FORMAT_APTX:
+ open.dec_fmt_id = ASM_MEDIA_FMT_APTX;
+ break;
default:
pr_err("%s: Invalid format 0x%x\n", __func__, format);
rc = -EINVAL;
@@ -5773,6 +5776,57 @@ done:
}
EXPORT_SYMBOL(q6asm_media_format_block_dsd);
+int q6asm_stream_media_format_block_aptx_dec(struct audio_client *ac,
+ uint32_t srate, int stream_id)
+{
+ struct asm_aptx_dec_fmt_blk_v2 aptx_fmt;
+ int rc = 0;
+
+ if (!ac->session) {
+ pr_err("%s: ac session invalid\n", __func__);
+ rc = -EINVAL;
+ goto fail_cmd;
+ }
+ pr_debug("%s :session[%d] rate[%d] stream_id[%d]\n",
+ __func__, ac->session, srate, stream_id);
+
+ q6asm_stream_add_hdr(ac, &aptx_fmt.hdr, sizeof(aptx_fmt), TRUE,
+ stream_id);
+ atomic_set(&ac->cmd_state, -1);
+
+ aptx_fmt.hdr.opcode = ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2;
+ aptx_fmt.fmtblk.fmt_blk_size = sizeof(aptx_fmt) - sizeof(aptx_fmt.hdr) -
+ sizeof(aptx_fmt.fmtblk);
+
+ aptx_fmt.sample_rate = srate;
+
+ rc = apr_send_pkt(ac->apr, (uint32_t *) &aptx_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;
+ }
+
+ 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;
+ }
+ rc = 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)
{
@@ -6802,6 +6856,69 @@ int q6asm_set_volume_v2(struct audio_client *ac, int volume, int instance)
return __q6asm_set_volume(ac, volume, instance);
}
+int q6asm_set_aptx_dec_bt_addr(struct audio_client *ac,
+ struct aptx_dec_bt_addr_cfg *cfg)
+{
+ struct aptx_dec_bt_dev_addr paylod;
+ int sz = 0;
+ int rc = 0;
+
+ pr_debug("%s: BT addr nap %d, uap %d, lap %d\n", __func__, cfg->nap,
+ cfg->uap, cfg->lap);
+
+ if (ac == NULL) {
+ pr_err("%s: AC handle NULL\n", __func__);
+ rc = -EINVAL;
+ goto fail_cmd;
+ }
+ if (ac->apr == NULL) {
+ pr_err("%s: AC APR handle NULL\n", __func__);
+ rc = -EINVAL;
+ goto fail_cmd;
+ }
+
+ sz = sizeof(struct aptx_dec_bt_dev_addr);
+ q6asm_add_hdr_async(ac, &paylod.hdr, sz, TRUE);
+ atomic_set(&ac->cmd_state, -1);
+ paylod.hdr.opcode = ASM_STREAM_CMD_SET_ENCDEC_PARAM;
+ paylod.encdec.param_id = APTX_DECODER_BT_ADDRESS;
+ paylod.encdec.param_size = sz - sizeof(paylod.hdr)
+ - sizeof(paylod.encdec);
+ paylod.bt_addr_cfg.lap = cfg->lap;
+ paylod.bt_addr_cfg.uap = cfg->uap;
+ paylod.bt_addr_cfg.nap = cfg->nap;
+
+ rc = apr_send_pkt(ac->apr, (uint32_t *) &paylod);
+ if (rc < 0) {
+ pr_err("%s: set-params send failed paramid[0x%x] rc %d\n",
+ __func__, paylod.encdec.param_id, 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, set-params paramid[0x%x]\n", __func__,
+ paylod.encdec.param_id);
+ rc = -ETIMEDOUT;
+ goto fail_cmd;
+ }
+ if (atomic_read(&ac->cmd_state) > 0) {
+ pr_err("%s: DSP returned error[%s] set-params paramid[0x%x]\n",
+ __func__, adsp_err_get_err_str(
+ atomic_read(&ac->cmd_state)),
+ paylod.encdec.param_id);
+ rc = adsp_err_get_lnx_err_code(
+ atomic_read(&ac->cmd_state));
+ goto fail_cmd;
+ }
+ pr_debug("%s: set BT addr is success\n", __func__);
+ rc = 0;
+fail_cmd:
+ return rc;
+}
+
int q6asm_set_softpause(struct audio_client *ac,
struct asm_softpause_params *pause_param)
{