Merge "ASoC: Bolero: Vote for LPASS HW core during register access"
diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c
index 217800a..a4f3c7d 100644
--- a/asoc/codecs/bolero/va-macro.c
+++ b/asoc/codecs/bolero/va-macro.c
@@ -248,6 +248,10 @@
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
ret = va_macro_mclk_enable(va_priv, 1, true);
+ ret = bolero_clk_rsc_request_clock(va_priv->dev,
+ va_priv->default_clk_id,
+ TX_CORE_CLK,
+ true);
break;
case SND_SOC_DAPM_POST_PMD:
va_macro_mclk_enable(va_priv, 0, true);
@@ -584,6 +588,10 @@
/* apply gain after decimator is enabled */
snd_soc_component_write(component, tx_gain_ctl_reg,
snd_soc_component_read32(component, tx_gain_ctl_reg));
+ bolero_clk_rsc_request_clock(va_priv->dev,
+ va_priv->default_clk_id,
+ TX_CORE_CLK,
+ false);
break;
case SND_SOC_DAPM_PRE_PMD:
hpf_cut_off_freq =
diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c
index 6412fd9..ca20bc4 100644
--- a/asoc/codecs/wcd938x/wcd938x.c
+++ b/asoc/codecs/wcd938x/wcd938x.c
@@ -39,8 +39,7 @@
enum {
WCD9380 = 0,
- WCD9385,
- WCD9385FX,
+ WCD9385 = 5,
};
enum {
@@ -1355,6 +1354,13 @@
__func__, micb_index);
return -EINVAL;
}
+
+ if (NULL == wcd938x) {
+ dev_err(component->dev,
+ "%s: wcd938x private data is NULL\n", __func__);
+ return -EINVAL;
+ }
+
switch (micb_num) {
case MIC_BIAS_1:
micb_reg = WCD938X_ANA_MICB1;
@@ -1755,6 +1761,14 @@
return 0;
}
+static const char * const tx_mode_mux_text_wcd9380[] = {
+ "ADC_INVALID", "ADC_HIFI", "ADC_LO_HIF", "ADC_NORMAL", "ADC_LP",
+};
+
+static const struct soc_enum tx_mode_mux_enum_wcd9380 =
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tx_mode_mux_text_wcd9380),
+ tx_mode_mux_text_wcd9380);
+
static const char * const tx_mode_mux_text[] = {
"ADC_INVALID", "ADC_HIFI", "ADC_LO_HIF", "ADC_NORMAL", "ADC_LP",
"ADC_ULP1", "ADC_ULP2",
@@ -1773,10 +1787,18 @@
SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rx_hph_mode_mux_text),
rx_hph_mode_mux_text);
-static const struct snd_kcontrol_new wcd938x_snd_controls[] = {
- SOC_ENUM_EXT("RX HPH Mode", rx_hph_mode_mux_enum,
- wcd938x_rx_hph_mode_get, wcd938x_rx_hph_mode_put),
+static const struct snd_kcontrol_new wcd9380_snd_controls[] = {
+ SOC_ENUM_EXT("TX0 MODE", tx_mode_mux_enum_wcd9380,
+ wcd938x_tx_mode_get, wcd938x_tx_mode_put),
+ SOC_ENUM_EXT("TX1 MODE", tx_mode_mux_enum_wcd9380,
+ wcd938x_tx_mode_get, wcd938x_tx_mode_put),
+ SOC_ENUM_EXT("TX2 MODE", tx_mode_mux_enum_wcd9380,
+ wcd938x_tx_mode_get, wcd938x_tx_mode_put),
+ SOC_ENUM_EXT("TX3 MODE", tx_mode_mux_enum_wcd9380,
+ wcd938x_tx_mode_get, wcd938x_tx_mode_put),
+};
+static const struct snd_kcontrol_new wcd9385_snd_controls[] = {
SOC_ENUM_EXT("TX0 MODE", tx_mode_mux_enum,
wcd938x_tx_mode_get, wcd938x_tx_mode_put),
SOC_ENUM_EXT("TX1 MODE", tx_mode_mux_enum,
@@ -1785,6 +1807,11 @@
wcd938x_tx_mode_get, wcd938x_tx_mode_put),
SOC_ENUM_EXT("TX3 MODE", tx_mode_mux_enum,
wcd938x_tx_mode_get, wcd938x_tx_mode_put),
+};
+
+static const struct snd_kcontrol_new wcd938x_snd_controls[] = {
+ SOC_ENUM_EXT("RX HPH Mode", rx_hph_mode_mux_enum,
+ wcd938x_rx_hph_mode_get, wcd938x_rx_hph_mode_put),
SOC_SINGLE_EXT("HPHL_COMP Switch", SND_SOC_NOPM, 0, 1, 0,
wcd938x_get_compander, wcd938x_set_compander),
@@ -2406,6 +2433,26 @@
wcd_cls_h_init(&wcd938x->clsh_info);
wcd938x_init_reg(component);
+ if (wcd938x->variant == WCD9380) {
+ ret = snd_soc_add_component_controls(component, wcd9380_snd_controls,
+ ARRAY_SIZE(wcd9380_snd_controls));
+ if (ret < 0) {
+ dev_err(component->dev,
+ "%s: Failed to add snd ctrls for variant: %d\n",
+ __func__, wcd938x->variant);
+ goto err_hwdep;
+ }
+ }
+ if (wcd938x->variant == WCD9385) {
+ ret = snd_soc_add_component_controls(component, wcd9385_snd_controls,
+ ARRAY_SIZE(wcd9385_snd_controls));
+ if (ret < 0) {
+ dev_err(component->dev,
+ "%s: Failed to add snd ctrls for variant: %d\n",
+ __func__, wcd938x->variant);
+ goto err_hwdep;
+ }
+ }
wcd938x->version = WCD938X_VERSION_1_0;
/* Register event notifier */
wcd938x->nblock.notifier_call = wcd938x_event_notify;
diff --git a/dsp/q6adm.c b/dsp/q6adm.c
index f081065..8848b22 100644
--- a/dsp/q6adm.c
+++ b/dsp/q6adm.c
@@ -1510,7 +1510,7 @@
}
adm_callback_debug_print(data);
- if (data->payload_size) {
+ if (data->payload_size >= sizeof(uint32_t)) {
copp_idx = (data->token) & 0XFF;
port_idx = ((data->token) >> 16) & 0xFF;
client_id = ((data->token) >> 8) & 0xFF;
@@ -1530,13 +1530,20 @@
return 0;
}
if (data->opcode == APR_BASIC_RSP_RESULT) {
- if (data->payload_size < (2 * sizeof(uint32_t))) {
- pr_err("%s: Invalid payload size %d\n", __func__,
- data->payload_size);
- return 0;
- }
pr_debug("%s: APR_BASIC_RSP_RESULT id 0x%x\n",
__func__, payload[0]);
+
+ if (!((client_id != ADM_CLIENT_ID_SOURCE_TRACKING) &&
+ ((payload[0] == ADM_CMD_SET_PP_PARAMS_V5) ||
+ (payload[0] == ADM_CMD_SET_PP_PARAMS_V6)))) {
+ if (data->payload_size <
+ (2 * sizeof(uint32_t))) {
+ pr_err("%s: Invalid payload size %d\n",
+ __func__, data->payload_size);
+ return 0;
+ }
+ }
+
if (payload[1] != 0) {
pr_err("%s: cmd = 0x%x returned error = 0x%x\n",
__func__, payload[0], payload[1]);
@@ -1718,21 +1725,28 @@
case ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST_V2:
pr_debug("%s: ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST\n",
__func__);
- num_modules = payload[1];
- pr_debug("%s: Num modules %d\n", __func__, num_modules);
- if (payload[0]) {
- pr_err("%s: ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST, error = %d\n",
- __func__, payload[0]);
- } else if (num_modules > MAX_MODULES_IN_TOPO) {
- pr_err("%s: ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST invalid num modules received, num modules = %d\n",
- __func__, num_modules);
+ if (data->payload_size >= (2 * sizeof(uint32_t))) {
+ num_modules = payload[1];
+ pr_debug("%s: Num modules %d\n", __func__,
+ num_modules);
+ if (payload[0]) {
+ pr_err("%s: ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST, error = %d\n",
+ __func__, payload[0]);
+ } else if (num_modules > MAX_MODULES_IN_TOPO) {
+ pr_err("%s: ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST invalid num modules received, num modules = %d\n",
+ __func__, num_modules);
+ } else {
+ ret = adm_process_get_topo_list_response(
+ data->opcode, copp_idx,
+ num_modules, payload,
+ data->payload_size);
+ if (ret)
+ pr_err("%s: Failed to process get topo modules list response, error %d\n",
+ __func__, ret);
+ }
} else {
- ret = adm_process_get_topo_list_response(
- data->opcode, copp_idx, num_modules,
- payload, data->payload_size);
- if (ret)
- pr_err("%s: Failed to process get topo modules list response, error %d\n",
- __func__, ret);
+ pr_err("%s: Invalid payload size %d\n",
+ __func__, data->payload_size);
}
atomic_set(&this_adm.copp.stat[port_idx][copp_idx],
payload[0]);
diff --git a/dsp/q6afe.c b/dsp/q6afe.c
index fd66571..0002d82 100644
--- a/dsp/q6afe.c
+++ b/dsp/q6afe.c
@@ -400,6 +400,11 @@
/* Set command specific details */
switch (opcode) {
case AFE_PORT_CMDRSP_GET_PARAM_V2:
+ if (payload_size < (5 * sizeof(uint32_t))) {
+ pr_err("%s: Error: size %d is less than expected\n",
+ __func__, payload_size);
+ return -EINVAL;
+ }
expected_size += sizeof(struct param_hdr_v1);
param_hdr.module_id = payload[1];
param_hdr.instance_id = INSTANCE_ID_0;
@@ -408,7 +413,17 @@
data_start = &payload[4];
break;
case AFE_PORT_CMDRSP_GET_PARAM_V3:
+ if (payload_size < (6 * sizeof(uint32_t))) {
+ pr_err("%s: Error: size %d is less than expected\n",
+ __func__, payload_size);
+ return -EINVAL;
+ }
expected_size += sizeof(struct param_hdr_v3);
+ if (payload_size < expected_size) {
+ pr_err("%s: Error: size %d is less than expected\n",
+ __func__, payload_size);
+ return -EINVAL;
+ }
memcpy(¶m_hdr, &payload[1], sizeof(struct param_hdr_v3));
data_start = &payload[5];
break;
@@ -597,6 +612,7 @@
data->opcode == AFE_PORT_CMDRSP_GET_PARAM_V3) {
uint32_t *payload = data->payload;
uint32_t param_id;
+ uint32_t param_id_pos = 0;
if (!payload || (data->token >= AFE_MAX_PORTS)) {
pr_err("%s: Error: size %d payload %pK token %d\n",
@@ -605,9 +621,23 @@
return -EINVAL;
}
- param_id = (data->opcode == AFE_PORT_CMDRSP_GET_PARAM_V3) ?
- payload[3] :
- payload[2];
+ if (rtac_make_afe_callback(data->payload,
+ data->payload_size))
+ return 0;
+
+ if (data->opcode == AFE_PORT_CMDRSP_GET_PARAM_V3)
+ param_id_pos = 4;
+ else
+ param_id_pos = 3;
+
+ if (data->payload_size >= param_id_pos * sizeof(uint32_t))
+ param_id = payload[param_id_pos - 1];
+ else {
+ pr_err("%s: Error: size %d is less than expected\n",
+ __func__, data->payload_size);
+ return -EINVAL;
+ }
+
if (param_id == AUDPROC_PARAM_ID_FFV_DOA_TRACKING_MONITOR) {
doa_tracking_mon_afe_cb_handler(data->opcode,
data->payload, data->payload_size);
@@ -615,10 +645,6 @@
av_dev_drift_afe_cb_handler(data->opcode, data->payload,
data->payload_size);
} else {
- if (rtac_make_afe_callback(data->payload,
- data->payload_size))
- return 0;
-
if (sp_make_afe_callback(data->opcode, data->payload,
data->payload_size))
return -EINVAL;
@@ -645,6 +671,11 @@
payload = data->payload;
if (data->opcode == APR_BASIC_RSP_RESULT) {
+ if (data->payload_size < (2 * sizeof(uint32_t))) {
+ pr_err("%s: Error: size %d is less than expected\n",
+ __func__, data->payload_size);
+ return -EINVAL;
+ }
pr_debug("%s:opcode = 0x%x cmd = 0x%x status = 0x%x token=%d\n",
__func__, data->opcode,
payload[0], payload[1], data->token);
diff --git a/dsp/q6core.c b/dsp/q6core.c
index 283f785..3f15f10 100644
--- a/dsp/q6core.c
+++ b/dsp/q6core.c
@@ -194,7 +194,7 @@
}
EXPORT_SYMBOL(q6core_send_uevent);
-static int parse_fwk_version_info(uint32_t *payload)
+static int parse_fwk_version_info(uint32_t *payload, uint16_t payload_size)
{
size_t ver_size;
int num_services;
@@ -207,6 +207,11 @@
* Based on this info, we copy the payload into core
* avcs version info structure.
*/
+ if (payload_size < 5 * sizeof(uint32_t)) {
+ pr_err("%s: payload has invalid size %d\n",
+ __func__, payload_size);
+ return -EINVAL;
+ }
num_services = payload[4];
if (num_services > VSS_MAX_AVCS_NUM_SERVICES) {
pr_err("%s: num_services: %d greater than max services: %d\n",
@@ -221,6 +226,12 @@
ver_size = sizeof(struct avcs_get_fwk_version) +
num_services * sizeof(struct avs_svc_api_info);
+ if (payload_size < ver_size) {
+ pr_err("%s: payload has invalid size %d, expected size %zu\n",
+ __func__, payload_size, ver_size);
+ return -EINVAL;
+ }
+
q6core_lcl.q6core_avcs_ver_info.ver_info =
kzalloc(ver_size, GFP_ATOMIC);
if (q6core_lcl.q6core_avcs_ver_info.ver_info == NULL)
@@ -257,6 +268,12 @@
payload1 = data->payload;
+ if (data->payload_size < 2 * sizeof(uint32_t)) {
+ pr_err("%s: payload has invalid size %d\n",
+ __func__, data->payload_size);
+ return -EINVAL;
+ }
+
switch (payload1[0]) {
case AVCS_CMD_SHARED_MEM_UNMAP_REGIONS:
@@ -347,6 +364,11 @@
break;
}
case AVCS_CMDRSP_SHARED_MEM_MAP_REGIONS:
+ if (data->payload_size < sizeof(uint32_t)) {
+ pr_err("%s: payload has invalid size %d\n",
+ __func__, data->payload_size);
+ return -EINVAL;
+ }
payload1 = data->payload;
pr_debug("%s: AVCS_CMDRSP_SHARED_MEM_MAP_REGIONS handle %d\n",
__func__, payload1[0]);
@@ -361,6 +383,11 @@
}
break;
case AVCS_CMDRSP_CREATE_LPASS_NPA_CLIENT:
+ if (data->payload_size < 2 * sizeof(uint32_t)) {
+ pr_err("%s: payload has invalid size %d\n",
+ __func__, data->payload_size);
+ return -EINVAL;
+ }
payload1 = data->payload;
pr_debug("%s: AVCS_CMDRSP_CREATE_LPASS_NPA_CLIENT handle %d\n",
__func__, payload1[1]);
@@ -370,6 +397,11 @@
wake_up(&q6core_lcl.lpass_npa_rsc_wait);
break;
case AVCS_CMDRSP_ADSP_EVENT_GET_STATE:
+ if (data->payload_size < sizeof(uint32_t)) {
+ pr_err("%s: payload has invalid size %d\n",
+ __func__, data->payload_size);
+ return -EINVAL;
+ }
payload1 = data->payload;
q6core_lcl.param = payload1[0];
pr_debug("%s: Received ADSP get state response 0x%x\n",
@@ -380,6 +412,11 @@
wake_up(&q6core_lcl.bus_bw_req_wait);
break;
case AVCS_CMDRSP_GET_LICENSE_VALIDATION_RESULT:
+ if (data->payload_size < sizeof(uint32_t)) {
+ pr_err("%s: payload has invalid size %d\n",
+ __func__, data->payload_size);
+ return -EINVAL;
+ }
payload1 = data->payload;
pr_debug("%s: cmd = LICENSE_VALIDATION_RESULT, result = 0x%x\n",
__func__, payload1[0]);
@@ -392,7 +429,7 @@
pr_debug("%s: Received AVCS_CMDRSP_GET_FWK_VERSION\n",
__func__);
payload1 = data->payload;
- ret = parse_fwk_version_info(payload1);
+ ret = parse_fwk_version_info(payload1, data->payload_size);
if (ret < 0) {
q6core_lcl.adsp_status = ret;
pr_err("%s: Failed to parse payload:%d\n",
diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c
index 8d82ff1..bddf30a 100644
--- a/soc/swr-mstr-ctrl.c
+++ b/soc/swr-mstr-ctrl.c
@@ -1441,6 +1441,8 @@
}
mutex_lock(&swrm->reslock);
+ if (swrm->lpass_core_hw_vote)
+ clk_prepare_enable(swrm->lpass_core_hw_vote);
swrm_clk_request(swrm, true);
mutex_unlock(&swrm->reslock);
@@ -1608,6 +1610,8 @@
mutex_lock(&swrm->reslock);
swrm_clk_request(swrm, false);
+ if (swrm->lpass_core_hw_vote)
+ clk_disable_unprepare(swrm->lpass_core_hw_vote);
mutex_unlock(&swrm->reslock);
swrm_unlock_sleep(swrm);
return ret;
@@ -1897,6 +1901,7 @@
u32 i, num_ports, port_num, port_type, ch_mask;
u32 *temp, map_size, map_length, ch_iter = 0, old_port_num = 0;
int ret = 0;
+ struct clk *lpass_core_hw_vote = NULL;
/* Allocate soundwire master driver structure */
swrm = devm_kzalloc(&pdev->dev, sizeof(struct swr_mstr_ctrl),
@@ -2055,6 +2060,7 @@
swrm->slave_status = 0;
swrm->num_rx_chs = 0;
swrm->clk_ref_count = 0;
+ swrm->swr_irq_wakeup_capable = 0;
swrm->mclk_freq = MCLK_FREQ;
swrm->dev_up = true;
swrm->state = SWR_MSTR_UP;
@@ -2107,7 +2113,15 @@
}
}
-
+ /* Make inband tx interrupts as wakeup capable for slave irq */
+ ret = of_property_read_u32(pdev->dev.of_node,
+ "qcom,swr-mstr-irq-wakeup-capable",
+ &swrm->swr_irq_wakeup_capable);
+ if (ret)
+ dev_dbg(swrm->dev, "%s: swrm irq wakeup capable not defined\n",
+ __func__);
+ if (swrm->swr_irq_wakeup_capable)
+ irq_set_irq_wake(swrm->irq, 1);
ret = swr_register_master(&swrm->master);
if (ret) {
dev_err(&pdev->dev, "%s: error adding swr master\n", __func__);
@@ -2136,6 +2150,17 @@
if (pdev->dev.of_node)
of_register_swr_devices(&swrm->master);
+ /* Register LPASS core hw vote */
+ lpass_core_hw_vote = devm_clk_get(&pdev->dev, "lpass_core_hw_vote");
+ if (IS_ERR(lpass_core_hw_vote)) {
+ ret = PTR_ERR(lpass_core_hw_vote);
+ dev_dbg(&pdev->dev, "%s: clk get %s failed %d\n",
+ __func__, "lpass_core_hw_vote", ret);
+ lpass_core_hw_vote = NULL;
+ ret = 0;
+ }
+ swrm->lpass_core_hw_vote = lpass_core_hw_vote;
+
dbgswrm = swrm;
debugfs_swrm_dent = debugfs_create_dir(dev_name(&pdev->dev), 0);
if (!IS_ERR(debugfs_swrm_dent)) {
@@ -2152,6 +2177,13 @@
(void *) "swrm_reg_dump",
&swrm_debug_ops);
}
+
+ ret = device_init_wakeup(swrm->dev, true);
+ if (ret) {
+ dev_err(swrm->dev, "Device wakeup init failed: %d\n", ret);
+ goto err_irq_wakeup_fail;
+ }
+
pm_runtime_set_autosuspend_delay(&pdev->dev, auto_suspend_timer);
pm_runtime_use_autosuspend(&pdev->dev);
pm_runtime_set_active(&pdev->dev);
@@ -2163,6 +2195,8 @@
msm_aud_evt_register_client(&swrm->event_notifier);
return 0;
+err_irq_wakeup_fail:
+ device_init_wakeup(swrm->dev, false);
err_mstr_fail:
if (swrm->reg_irq)
swrm->reg_irq(swrm->handle, swr_mstr_interrupt,
@@ -2194,11 +2228,14 @@
free_irq(swrm->irq, swrm);
else if (swrm->wake_irq > 0)
free_irq(swrm->wake_irq, swrm);
+ if (swrm->swr_irq_wakeup_capable)
+ irq_set_irq_wake(swrm->irq, 0);
cancel_work_sync(&swrm->wakeup_work);
pm_runtime_disable(&pdev->dev);
pm_runtime_set_suspended(&pdev->dev);
swr_unregister_master(&swrm->master);
msm_aud_evt_unregister_client(&swrm->event_notifier);
+ device_init_wakeup(swrm->dev, false);
mutex_destroy(&swrm->mlock);
mutex_destroy(&swrm->reslock);
mutex_destroy(&swrm->iolock);
@@ -2236,6 +2273,12 @@
__func__, swrm->state);
mutex_lock(&swrm->reslock);
+ if (swrm->lpass_core_hw_vote)
+ ret = clk_prepare_enable(swrm->lpass_core_hw_vote);
+ if (ret < 0)
+ dev_err(dev, "%s:lpass core hw enable failed\n",
+ __func__);
+
if ((swrm->state == SWR_MSTR_DOWN) ||
(swrm->state == SWR_MSTR_SSR && swrm->dev_up)) {
if (swrm->clk_stop_mode0_supp) {
@@ -2272,6 +2315,8 @@
swrm->state = SWR_MSTR_UP;
}
exit:
+ if (swrm->lpass_core_hw_vote)
+ clk_disable_unprepare(swrm->lpass_core_hw_vote);
pm_runtime_set_autosuspend_delay(&pdev->dev, auto_suspend_timer);
mutex_unlock(&swrm->reslock);
return ret;
@@ -2292,6 +2337,12 @@
mutex_lock(&swrm->force_down_lock);
current_state = swrm->state;
mutex_unlock(&swrm->force_down_lock);
+ if (swrm->lpass_core_hw_vote)
+ ret = clk_prepare_enable(swrm->lpass_core_hw_vote);
+ if (ret < 0)
+ dev_err(dev, "%s:lpass core hw enable failed\n",
+ __func__);
+
if ((current_state == SWR_MSTR_UP) ||
(current_state == SWR_MSTR_SSR)) {
@@ -2337,6 +2388,8 @@
if (current_state != SWR_MSTR_SSR)
swrm->state = SWR_MSTR_DOWN;
exit:
+ if (swrm->lpass_core_hw_vote)
+ clk_disable_unprepare(swrm->lpass_core_hw_vote);
mutex_unlock(&swrm->reslock);
return ret;
}
diff --git a/soc/swr-mstr-ctrl.h b/soc/swr-mstr-ctrl.h
index fab66c3..4a48571 100644
--- a/soc/swr-mstr-ctrl.h
+++ b/soc/swr-mstr-ctrl.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
- * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
*/
#ifndef _SWR_WCD_CTRL_H
@@ -154,7 +154,9 @@
int wlock_holders;
u32 intr_mask;
struct port_params **port_param;
+ struct clk *lpass_core_hw_vote;
u8 num_usecase;
+ u32 swr_irq_wakeup_capable;
};
#endif /* _SWR_WCD_CTRL_H */