Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 085b269d authored by Vatsal Bucha's avatar Vatsal Bucha
Browse files

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: default avatarVatsal Bucha <vbucha@codeaurora.org>
parent d940ad31
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -90,6 +90,7 @@ struct wcd937x_priv {
	/* Entry for version info */
	struct snd_info_entry *entry;
	struct snd_info_entry *version_entry;
	int ear_rx_path;
};

struct wcd937x_micbias_setting {
+55 −2
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@

#define WCD937X_VERSION_1_0 1
#define WCD937X_VERSION_ENTRY_SIZE 32
#define EAR_RX_PATH_AUX 1

enum {
	CODEC_TX = 0,
@@ -627,6 +628,11 @@ static int wcd937x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
		snd_soc_update_bits(codec, WCD937X_ANA_HPH, 0x10, 0x10);
		usleep_range(100, 110);
		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_update_bits(codec, WCD937X_DIGITAL_PDM_WD_CTL1,
				    0x17, 0x13);
		break;
	case SND_SOC_DAPM_POST_PMU:
		/*
@@ -663,6 +669,8 @@ static int wcd937x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
		break;
	case SND_SOC_DAPM_POST_PMD:
		usleep_range(7000, 7010);
		snd_soc_update_bits(codec, WCD937X_DIGITAL_PDM_WD_CTL1,
				    0x17, 0x00);
		blocking_notifier_call_chain(&wcd937x->mbhc->notifier,
					     WCD_EVENT_POST_HPHR_PA_OFF,
					     &wcd937x->mbhc->wcd_mbhc);
@@ -700,6 +708,8 @@ static int wcd937x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
		snd_soc_update_bits(codec, WCD937X_ANA_HPH, 0x20, 0x20);
		usleep_range(100, 110);
		set_bit(HPH_PA_DELAY, &wcd937x->status_mask);
		snd_soc_update_bits(codec, WCD937X_DIGITAL_PDM_WD_CTL0,
				    0x17, 0x13);
		break;
	case SND_SOC_DAPM_POST_PMU:
		/*
@@ -736,6 +746,8 @@ static int wcd937x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
		break;
	case SND_SOC_DAPM_POST_PMD:
		usleep_range(7000, 7010);
		snd_soc_update_bits(codec, WCD937X_DIGITAL_PDM_WD_CTL0,
				    0x17, 0x00);
		blocking_notifier_call_chain(&wcd937x->mbhc->notifier,
					     WCD_EVENT_POST_HPHL_PA_OFF,
					     &wcd937x->mbhc->wcd_mbhc);
@@ -766,6 +778,8 @@ static int wcd937x_codec_enable_aux_pa(struct snd_soc_dapm_widget *w,
		ret = swr_slvdev_datapath_control(wcd937x->rx_swr_dev,
			    wcd937x->rx_swr_dev->dev_num,
			    true);
		snd_soc_update_bits(codec, WCD937X_DIGITAL_PDM_WD_CTL2,
				    0x05, 0x05);
		break;
	case SND_SOC_DAPM_POST_PMU:
		usleep_range(1000, 1010);
@@ -784,12 +798,14 @@ static int wcd937x_codec_enable_aux_pa(struct snd_soc_dapm_widget *w,
						(WCD_RX3 << 0x10 | 0x1));
		break;
	case SND_SOC_DAPM_POST_PMD:
		usleep_range(1000, 1010);
		usleep_range(1000, 1010);
		/* Add delay as per hw requirement */
		usleep_range(2000, 2010);
		wcd_cls_h_fsm(codec, &wcd937x->clsh_info,
			     WCD_CLSH_EVENT_POST_PA,
			     WCD_CLSH_STATE_AUX,
			     hph_mode);
		snd_soc_update_bits(codec, WCD937X_DIGITAL_PDM_WD_CTL2,
				    0x05, 0x00);
		break;
	};
	return ret;
@@ -812,6 +828,18 @@ static int wcd937x_codec_enable_ear_pa(struct snd_soc_dapm_widget *w,
		ret = swr_slvdev_datapath_control(wcd937x->rx_swr_dev,
			    wcd937x->rx_swr_dev->dev_num,
			    true);
		/*
		 * Enable watchdog interrupt for HPHL or AUX
		 * depending on mux value
		 */
		wcd937x->ear_rx_path =
			snd_soc_read(codec, WCD937X_DIGITAL_CDC_EAR_PATH_CTL);
		if (wcd937x->ear_rx_path & EAR_RX_PATH_AUX)
			snd_soc_update_bits(codec, WCD937X_DIGITAL_PDM_WD_CTL2,
					    0x05, 0x05);
		else
			snd_soc_update_bits(codec, WCD937X_DIGITAL_PDM_WD_CTL0,
					    0x17, 0x13);
		break;
	case SND_SOC_DAPM_POST_PMU:
		usleep_range(6000, 6010);
@@ -835,6 +863,12 @@ static int wcd937x_codec_enable_ear_pa(struct snd_soc_dapm_widget *w,
			     WCD_CLSH_EVENT_POST_PA,
			     WCD_CLSH_STATE_EAR,
			     hph_mode);
		if (wcd937x->ear_rx_path & EAR_RX_PATH_AUX)
			snd_soc_update_bits(codec, WCD937X_DIGITAL_PDM_WD_CTL2,
					    0x05, 0x00);
		else
			snd_soc_update_bits(codec, WCD937X_DIGITAL_PDM_WD_CTL0,
					    0x17, 0x00);
		break;
	};
	return ret;
@@ -2370,6 +2404,13 @@ static int wcd937x_wakeup(void *handle, bool enable)
		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)
{
	int ret = 0, i = 0;
@@ -2500,6 +2541,18 @@ static int wcd937x_bind(struct device *dev)
	wcd937x->tx_swr_dev->slave_irq = wcd937x->virq;

	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_codec(dev, &soc_codec_dev_wcd937x,
				     NULL, 0);
	if (ret) {