diff --git a/asoc/msm_common.c b/asoc/msm_common.c index 9d183c63d6..8ef8d9246d 100644 --- a/asoc/msm_common.c +++ b/asoc/msm_common.c @@ -75,6 +75,7 @@ struct chmap_pdata { static int qos_vote_status; static bool lpi_pcm_logging_enable; +static bool vote_against_sleep_enable; static struct dev_pm_qos_request latency_pm_qos_req; /* pm_qos request */ static unsigned int qos_client_active_cnt; @@ -1001,15 +1002,38 @@ static int msm_lpi_logging_enable_get(struct snd_kcontrol *kcontrol, return 0; } +static int msm_vote_against_sleep_ctl_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + vote_against_sleep_enable = ucontrol->value.integer.value[0]; + pr_debug("%s: vote against sleep enable: %d", __func__, + vote_against_sleep_enable); + + audio_prm_set_vote_against_sleep((uint8_t)vote_against_sleep_enable); + + return 0; +} + +static int msm_vote_against_sleep_ctl_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = vote_against_sleep_enable; + return 0; +} + static const char *const qos_text[] = {"Disable", "Enable"}; +static const char *const against_sleep_text[] = {"Disable", "Enable"}; static SOC_ENUM_SINGLE_EXT_DECL(qos_vote, qos_text); +static SOC_ENUM_SINGLE_EXT_DECL(sleep_against, against_sleep_text); static const struct snd_kcontrol_new card_mixer_controls[] = { SOC_ENUM_EXT("PM_QOS Vote", qos_vote, msm_qos_ctl_get, msm_qos_ctl_put), SOC_SINGLE_EXT("LPI PCM Logging Enable", 0, 0, 1, 0, msm_lpi_logging_enable_get, msm_lpi_logging_enable_put), + SOC_ENUM_EXT("VOTE Against Sleep", sleep_against, + msm_vote_against_sleep_ctl_get, msm_vote_against_sleep_ctl_put), }; static int msm_register_pm_qos_latency_controls(struct snd_soc_pcm_runtime *rtd) diff --git a/dsp/audio_prm.c b/dsp/audio_prm.c index 3975186ddc..974c025a60 100644 --- a/dsp/audio_prm.c +++ b/dsp/audio_prm.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -405,6 +406,58 @@ int audio_prm_set_cdc_earpa_duty_cycling_req(struct prm_earpa_hw_intf_config *ea } EXPORT_SYMBOL(audio_prm_set_cdc_earpa_duty_cycling_req); +int audio_prm_set_vote_against_sleep(uint8_t enable) +{ + int ret = 0; + struct gpr_pkt *pkt; + prm_cmd_request_hw_core_t prm_rsc_request; + uint32_t size; + + size = GPR_HDR_SIZE + sizeof(prm_cmd_request_hw_core_t); + pkt = kzalloc(size, GFP_KERNEL); + if (!pkt) + return -ENOMEM; + + pkt->hdr.header = GPR_SET_FIELD(GPR_PKT_VERSION, GPR_PKT_VER) | + GPR_SET_FIELD(GPR_PKT_HEADER_SIZE, GPR_PKT_HEADER_WORD_SIZE_V) | + GPR_SET_FIELD(GPR_PKT_PACKET_SIZE, size); + + pkt->hdr.src_port = GPR_SVC_ASM; + pkt->hdr.dst_port = PRM_MODULE_INSTANCE_ID; + pkt->hdr.dst_domain_id = GPR_IDS_DOMAIN_ID_ADSP_V; + pkt->hdr.src_domain_id = GPR_IDS_DOMAIN_ID_APPS_V; + pkt->hdr.token = 0; /* TBD */ + + if (enable) + pkt->hdr.opcode = PRM_CMD_REQUEST_HW_RSC; + else + pkt->hdr.opcode = PRM_CMD_RELEASE_HW_RSC; + + prm_rsc_request.payload_header.payload_address_lsw = 0; + prm_rsc_request.payload_header.payload_address_msw = 0; + prm_rsc_request.payload_header.mem_map_handle = 0; + prm_rsc_request.payload_header.payload_size = sizeof(prm_cmd_request_hw_core_t) - sizeof(apm_cmd_header_t); + + /** Populate the param payload */ + prm_rsc_request.module_payload_0.module_instance_id = PRM_MODULE_INSTANCE_ID; + prm_rsc_request.module_payload_0.error_code = 0; + prm_rsc_request.module_payload_0.param_id = PARAM_ID_RSC_HW_CORE; + prm_rsc_request.module_payload_0.param_size = + sizeof(prm_cmd_request_hw_core_t) - sizeof(apm_cmd_header_t) - sizeof(apm_module_param_data_t); + + prm_rsc_request.hw_core_id = HW_CORE_ID_LPASS; + + memcpy(&pkt->payload, &prm_rsc_request, sizeof(prm_cmd_request_hw_core_t)); + ret = prm_gpr_send_pkt(pkt, &g_prm.wait); + if (ret < 0) { + pr_err("%s: Unable to send packet %d\n", __func__, ret); + } + + kfree(pkt); + return ret; +} +EXPORT_SYMBOL(audio_prm_set_vote_against_sleep); + int audio_prm_set_lpass_clk_cfg (struct clk_cfg *clk, uint8_t enable) { int ret = 0; diff --git a/include/dsp/audio_prm.h b/include/dsp/audio_prm.h index 6d4e1d06aa..50970f0cf5 100644 --- a/include/dsp/audio_prm.h +++ b/include/dsp/audio_prm.h @@ -1,4 +1,5 @@ /* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -206,6 +207,9 @@ typedef struct prm_cmd_request_hw_core_t #define PARAM_ID_RSC_LPASS_CORE 0x0800102B #define PARAM_ID_RSC_HW_CORE 0x08001032 +/* Param ID for island vote */ +#define PARAM_ID_RSC_VOTE_AGAINST_ISLAND 0x0800131D + #define HW_RSC_ID_AUDIO_HW_CLK 0x0800102C #define MAX_EARPA_REG 2 @@ -603,4 +607,5 @@ int audio_prm_set_lpass_hw_core_req(struct clk_cfg *cfg, uint32_t hw_core_id, ui int audio_prm_set_cdc_earpa_duty_cycling_req(struct prm_earpa_hw_intf_config *earpa_config, uint32_t enable); void audio_prm_set_lpi_logging_status(int lpi_pcm_logging_enable); +int audio_prm_set_vote_against_sleep(uint8_t enable); #endif