diff options
author | Dhanalakshmi Siddani <dsiddani@codeaurora.org> | 2016-12-26 16:01:43 +0530 |
---|---|---|
committer | Dhanalakshmi Siddani <dsiddani@codeaurora.org> | 2017-01-20 18:03:29 +0530 |
commit | 9d558f7ecfa0c4cf393a60f6acbbd00f50b7455f (patch) | |
tree | 26851c91683d3041a7555c7bd834e33b059bd810 /sound | |
parent | 774228d053cc54c98fc0da712c5a36e4b816af7b (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.c | 31 | ||||
-rw-r--r-- | sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c | 30 | ||||
-rw-r--r-- | sound/soc/msm/qdsp6v2/q6asm.c | 117 |
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) { |