ASoC: wcd937x: Enable watchdog interrupt
Handle PDM watchdog interrupt. Enable watchdog before analog PA is enabled and disable it after analog PA is disabled so as to prevent false alarms. CRs-Fixed: 2336526 Change-Id: I3c16a9dcd0f4f84bf8ad0bfde9560330c143cdf9 Signed-off-by: Vatsal Bucha <vbucha@codeaurora.org>
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
|
/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _WCD937X_INTERNAL_H
|
#ifndef _WCD937X_INTERNAL_H
|
||||||
@@ -82,6 +82,7 @@ struct wcd937x_priv {
|
|||||||
/* Entry for version info */
|
/* Entry for version info */
|
||||||
struct snd_info_entry *entry;
|
struct snd_info_entry *entry;
|
||||||
struct snd_info_entry *version_entry;
|
struct snd_info_entry *version_entry;
|
||||||
|
int ear_rx_path;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wcd937x_micbias_setting {
|
struct wcd937x_micbias_setting {
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
@@ -34,6 +34,7 @@
|
|||||||
|
|
||||||
#define WCD937X_VERSION_1_0 1
|
#define WCD937X_VERSION_1_0 1
|
||||||
#define WCD937X_VERSION_ENTRY_SIZE 32
|
#define WCD937X_VERSION_ENTRY_SIZE 32
|
||||||
|
#define EAR_RX_PATH_AUX 1
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
CODEC_TX = 0,
|
CODEC_TX = 0,
|
||||||
@@ -653,6 +654,11 @@ static int wcd937x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
|
|||||||
0x10, 0x10);
|
0x10, 0x10);
|
||||||
usleep_range(100, 110);
|
usleep_range(100, 110);
|
||||||
set_bit(HPH_PA_DELAY, &wcd937x->status_mask);
|
set_bit(HPH_PA_DELAY, &wcd937x->status_mask);
|
||||||
|
ret = swr_slvdev_datapath_control(wcd937x->rx_swr_dev,
|
||||||
|
wcd937x->rx_swr_dev->dev_num,
|
||||||
|
true);
|
||||||
|
snd_soc_component_update_bits(component,
|
||||||
|
WCD937X_DIGITAL_PDM_WD_CTL1, 0x17, 0x13);
|
||||||
break;
|
break;
|
||||||
case SND_SOC_DAPM_POST_PMU:
|
case SND_SOC_DAPM_POST_PMU:
|
||||||
/*
|
/*
|
||||||
@@ -691,6 +697,8 @@ static int wcd937x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
|
|||||||
break;
|
break;
|
||||||
case SND_SOC_DAPM_POST_PMD:
|
case SND_SOC_DAPM_POST_PMD:
|
||||||
usleep_range(7000, 7010);
|
usleep_range(7000, 7010);
|
||||||
|
snd_soc_component_update_bits(component,
|
||||||
|
WCD937X_DIGITAL_PDM_WD_CTL1, 0x17, 0x00);
|
||||||
blocking_notifier_call_chain(&wcd937x->mbhc->notifier,
|
blocking_notifier_call_chain(&wcd937x->mbhc->notifier,
|
||||||
WCD_EVENT_POST_HPHR_PA_OFF,
|
WCD_EVENT_POST_HPHR_PA_OFF,
|
||||||
&wcd937x->mbhc->wcd_mbhc);
|
&wcd937x->mbhc->wcd_mbhc);
|
||||||
@@ -731,6 +739,8 @@ static int wcd937x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
|
|||||||
0x20, 0x20);
|
0x20, 0x20);
|
||||||
usleep_range(100, 110);
|
usleep_range(100, 110);
|
||||||
set_bit(HPH_PA_DELAY, &wcd937x->status_mask);
|
set_bit(HPH_PA_DELAY, &wcd937x->status_mask);
|
||||||
|
snd_soc_component_update_bits(component,
|
||||||
|
WCD937X_DIGITAL_PDM_WD_CTL0, 0x17, 0x13);
|
||||||
break;
|
break;
|
||||||
case SND_SOC_DAPM_POST_PMU:
|
case SND_SOC_DAPM_POST_PMU:
|
||||||
/*
|
/*
|
||||||
@@ -769,6 +779,8 @@ static int wcd937x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
|
|||||||
break;
|
break;
|
||||||
case SND_SOC_DAPM_POST_PMD:
|
case SND_SOC_DAPM_POST_PMD:
|
||||||
usleep_range(7000, 7010);
|
usleep_range(7000, 7010);
|
||||||
|
snd_soc_component_update_bits(component,
|
||||||
|
WCD937X_DIGITAL_PDM_WD_CTL0, 0x17, 0x00);
|
||||||
blocking_notifier_call_chain(&wcd937x->mbhc->notifier,
|
blocking_notifier_call_chain(&wcd937x->mbhc->notifier,
|
||||||
WCD_EVENT_POST_HPHL_PA_OFF,
|
WCD_EVENT_POST_HPHL_PA_OFF,
|
||||||
&wcd937x->mbhc->wcd_mbhc);
|
&wcd937x->mbhc->wcd_mbhc);
|
||||||
@@ -801,6 +813,8 @@ static int wcd937x_codec_enable_aux_pa(struct snd_soc_dapm_widget *w,
|
|||||||
ret = swr_slvdev_datapath_control(wcd937x->rx_swr_dev,
|
ret = swr_slvdev_datapath_control(wcd937x->rx_swr_dev,
|
||||||
wcd937x->rx_swr_dev->dev_num,
|
wcd937x->rx_swr_dev->dev_num,
|
||||||
true);
|
true);
|
||||||
|
snd_soc_component_update_bits(component,
|
||||||
|
WCD937X_DIGITAL_PDM_WD_CTL2, 0x05, 0x05);
|
||||||
break;
|
break;
|
||||||
case SND_SOC_DAPM_POST_PMU:
|
case SND_SOC_DAPM_POST_PMU:
|
||||||
usleep_range(1000, 1010);
|
usleep_range(1000, 1010);
|
||||||
@@ -820,12 +834,14 @@ static int wcd937x_codec_enable_aux_pa(struct snd_soc_dapm_widget *w,
|
|||||||
(WCD_RX3 << 0x10 | 0x1));
|
(WCD_RX3 << 0x10 | 0x1));
|
||||||
break;
|
break;
|
||||||
case SND_SOC_DAPM_POST_PMD:
|
case SND_SOC_DAPM_POST_PMD:
|
||||||
usleep_range(1000, 1010);
|
/* Add delay as per hw requirement */
|
||||||
usleep_range(1000, 1010);
|
usleep_range(2000, 2010);
|
||||||
wcd_cls_h_fsm(component, &wcd937x->clsh_info,
|
wcd_cls_h_fsm(component, &wcd937x->clsh_info,
|
||||||
WCD_CLSH_EVENT_POST_PA,
|
WCD_CLSH_EVENT_POST_PA,
|
||||||
WCD_CLSH_STATE_AUX,
|
WCD_CLSH_STATE_AUX,
|
||||||
hph_mode);
|
hph_mode);
|
||||||
|
snd_soc_component_update_bits(component,
|
||||||
|
WCD937X_DIGITAL_PDM_WD_CTL2, 0x05, 0x00);
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
return ret;
|
return ret;
|
||||||
@@ -849,6 +865,21 @@ static int wcd937x_codec_enable_ear_pa(struct snd_soc_dapm_widget *w,
|
|||||||
ret = swr_slvdev_datapath_control(wcd937x->rx_swr_dev,
|
ret = swr_slvdev_datapath_control(wcd937x->rx_swr_dev,
|
||||||
wcd937x->rx_swr_dev->dev_num,
|
wcd937x->rx_swr_dev->dev_num,
|
||||||
true);
|
true);
|
||||||
|
/*
|
||||||
|
* Enable watchdog interrupt for HPHL or AUX
|
||||||
|
* depending on mux value
|
||||||
|
*/
|
||||||
|
wcd937x->ear_rx_path =
|
||||||
|
snd_soc_component_read32(
|
||||||
|
component, WCD937X_DIGITAL_CDC_EAR_PATH_CTL);
|
||||||
|
if (wcd937x->ear_rx_path & EAR_RX_PATH_AUX)
|
||||||
|
snd_soc_component_update_bits(component,
|
||||||
|
WCD937X_DIGITAL_PDM_WD_CTL2,
|
||||||
|
0x05, 0x05);
|
||||||
|
else
|
||||||
|
snd_soc_component_update_bits(component,
|
||||||
|
WCD937X_DIGITAL_PDM_WD_CTL0,
|
||||||
|
0x17, 0x13);
|
||||||
break;
|
break;
|
||||||
case SND_SOC_DAPM_POST_PMU:
|
case SND_SOC_DAPM_POST_PMU:
|
||||||
usleep_range(6000, 6010);
|
usleep_range(6000, 6010);
|
||||||
@@ -873,6 +904,14 @@ static int wcd937x_codec_enable_ear_pa(struct snd_soc_dapm_widget *w,
|
|||||||
WCD_CLSH_EVENT_POST_PA,
|
WCD_CLSH_EVENT_POST_PA,
|
||||||
WCD_CLSH_STATE_EAR,
|
WCD_CLSH_STATE_EAR,
|
||||||
hph_mode);
|
hph_mode);
|
||||||
|
if (wcd937x->ear_rx_path & EAR_RX_PATH_AUX)
|
||||||
|
snd_soc_component_update_bits(component,
|
||||||
|
WCD937X_DIGITAL_PDM_WD_CTL2,
|
||||||
|
0x05, 0x00);
|
||||||
|
else
|
||||||
|
snd_soc_component_update_bits(component,
|
||||||
|
WCD937X_DIGITAL_PDM_WD_CTL0,
|
||||||
|
0x17, 0x00);
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
return ret;
|
return ret;
|
||||||
@@ -2445,6 +2484,13 @@ static int wcd937x_wakeup(void *handle, bool enable)
|
|||||||
return swr_device_wakeup_unvote(priv->tx_swr_dev);
|
return swr_device_wakeup_unvote(priv->tx_swr_dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static irqreturn_t wcd937x_wd_handle_irq(int irq, void *data)
|
||||||
|
{
|
||||||
|
pr_err_ratelimited("%s: Watchdog interrupt for irq =%d triggered\n",
|
||||||
|
__func__, irq);
|
||||||
|
return IRQ_HANDLED;
|
||||||
|
}
|
||||||
|
|
||||||
static int wcd937x_bind(struct device *dev)
|
static int wcd937x_bind(struct device *dev)
|
||||||
{
|
{
|
||||||
int ret = 0, i = 0;
|
int ret = 0, i = 0;
|
||||||
@@ -2575,6 +2621,18 @@ static int wcd937x_bind(struct device *dev)
|
|||||||
wcd937x->tx_swr_dev->slave_irq = wcd937x->virq;
|
wcd937x->tx_swr_dev->slave_irq = wcd937x->virq;
|
||||||
|
|
||||||
mutex_init(&wcd937x->micb_lock);
|
mutex_init(&wcd937x->micb_lock);
|
||||||
|
/* Request for watchdog interrupt */
|
||||||
|
wcd_request_irq(&wcd937x->irq_info, WCD937X_IRQ_HPHR_PDM_WD_INT,
|
||||||
|
"HPHR PDM WD INT", wcd937x_wd_handle_irq, NULL);
|
||||||
|
wcd_request_irq(&wcd937x->irq_info, WCD937X_IRQ_HPHL_PDM_WD_INT,
|
||||||
|
"HPHL PDM WD INT", wcd937x_wd_handle_irq, NULL);
|
||||||
|
wcd_request_irq(&wcd937x->irq_info, WCD937X_IRQ_AUX_PDM_WD_INT,
|
||||||
|
"AUX PDM WD INT", wcd937x_wd_handle_irq, NULL);
|
||||||
|
/* Enable watchdog interrupt for HPH and AUX */
|
||||||
|
wcd_enable_irq(&wcd937x->irq_info, WCD937X_IRQ_HPHR_PDM_WD_INT);
|
||||||
|
wcd_enable_irq(&wcd937x->irq_info, WCD937X_IRQ_HPHL_PDM_WD_INT);
|
||||||
|
wcd_enable_irq(&wcd937x->irq_info, WCD937X_IRQ_AUX_PDM_WD_INT);
|
||||||
|
|
||||||
ret = snd_soc_register_component(dev, &soc_codec_dev_wcd937x,
|
ret = snd_soc_register_component(dev, &soc_codec_dev_wcd937x,
|
||||||
NULL, 0);
|
NULL, 0);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
Reference in New Issue
Block a user