summaryrefslogtreecommitdiff
path: root/asoc
diff options
context:
space:
mode:
authorSudheer Papothi <spapothi@codeaurora.org>2020-09-24 11:15:42 +0530
committerGerrit - the friendly Code Review server <code-review@localhost>2020-12-09 22:06:19 -0800
commit8e3d6a8632f6eac48eacebb6939a3063ba0c2946 (patch)
tree7278317fc9dbed2a8d565b8989a3a5ae019766c4 /asoc
parentadeb331165b22dbdd8a7a20e0caf8fda9f40463b (diff)
downloadmsm-extra-8e3d6a8632f6eac48eacebb6939a3063ba0c2946.tar.gz
ASoC: wsa883x: Handle PA_ERR interrupt on WSA speaker
PA_ERR can happen during speaker path setup. Log the error status in the interrupt handler and clear the error status for next audio playback to resume properly on the speaker. Change-Id: I5800d9505a3036127097745aaa880b73b3e87f30 Signed-off-by: Sudheer Papothi <spapothi@codeaurora.org>
Diffstat (limited to 'asoc')
-rw-r--r--asoc/codecs/wsa883x/wsa883x.c44
1 files changed, 38 insertions, 6 deletions
diff --git a/asoc/codecs/wsa883x/wsa883x.c b/asoc/codecs/wsa883x/wsa883x.c
index f2f16daf..31ba5ba7 100644
--- a/asoc/codecs/wsa883x/wsa883x.c
+++ b/asoc/codecs/wsa883x/wsa883x.c
@@ -481,8 +481,33 @@ static irqreturn_t wsa883x_uvlo_handle_irq(int irq, void *data)
static irqreturn_t wsa883x_pa_on_err_handle_irq(int irq, void *data)
{
- pr_err_ratelimited("%s: interrupt for irq =%d triggered\n",
- __func__, irq);
+ u8 pa_fsm_sta = 0, pa_fsm_err = 0;
+ struct wsa883x_priv *wsa883x = data;
+ struct snd_soc_component *component = NULL;
+
+ if (!wsa883x)
+ return IRQ_NONE;
+
+ component = wsa883x->component;
+ if (!component)
+ return IRQ_NONE;
+
+ pa_fsm_sta = (snd_soc_component_read32(component, WSA883X_PA_FSM_STA)
+ & 0x70);
+
+ if (pa_fsm_sta)
+ pa_fsm_err = snd_soc_component_read32(component,
+ WSA883X_PA_FSM_ERR_COND);
+ pr_err_ratelimited("%s: irq: %d, pa_fsm_sta: %d, pa_fsm_err: %d\n",
+ __func__, irq, pa_fsm_sta, pa_fsm_err);
+
+ snd_soc_component_update_bits(component, WSA883X_PA_FSM_CTL,
+ 0x10, 0x00);
+ snd_soc_component_update_bits(component, WSA883X_PA_FSM_CTL,
+ 0x10, 0x10);
+ snd_soc_component_update_bits(component, WSA883X_PA_FSM_CTL,
+ 0x10, 0x00);
+
return IRQ_HANDLED;
}
@@ -1017,6 +1042,7 @@ static int wsa883x_spkr_event(struct snd_soc_dapm_widget *w,
0x01, 0x01);
/* Added delay as per HW sequence */
usleep_range(250, 300);
+ wcd_enable_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_PA_ON_ERR);
/* Force remove group */
swr_remove_from_group(wsa883x->swr_slave,
wsa883x->swr_slave->dev_num);
@@ -1042,9 +1068,15 @@ static int wsa883x_spkr_event(struct snd_soc_dapm_widget *w,
0x0E, 0x00);
snd_soc_component_update_bits(component, WSA883X_PA_FSM_CTL,
0x01, 0x00);
- snd_soc_component_update_bits(wsa883x->component,
- WSA883X_PDM_WD_CTL,
- 0x01, 0x00);
+ snd_soc_component_update_bits(component, WSA883X_PA_FSM_CTL,
+ 0x10, 0x00);
+ snd_soc_component_update_bits(component, WSA883X_PA_FSM_CTL,
+ 0x10, 0x10);
+ snd_soc_component_update_bits(component, WSA883X_PA_FSM_CTL,
+ 0x10, 0x00);
+ snd_soc_component_update_bits(wsa883x->component, WSA883X_PDM_WD_CTL,
+ 0x01, 0x00);
+ wcd_disable_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_PA_ON_ERR);
clear_bit(SPKR_STATUS, &wsa883x->status_mask);
clear_bit(SPKR_ADIE_LB, &wsa883x->status_mask);
break;
@@ -1594,7 +1626,7 @@ static int wsa883x_swr_probe(struct swr_device *pdev)
"WSA UVLO", wsa883x_uvlo_handle_irq, NULL);
wcd_request_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_PA_ON_ERR,
- "WSA PA ERR", wsa883x_pa_on_err_handle_irq, NULL);
+ "WSA PA ERR", wsa883x_pa_on_err_handle_irq, wsa883x);
wcd_disable_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_PA_ON_ERR);