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

Commit 5257151b authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "asoc: codecs: Change TX tuning and reduce RX click and pop"

parents 76413b65 b9d7807f
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -243,7 +243,14 @@ static void wcd_clsh_flyback_ctrl(struct snd_soc_component *component,
		__func__, clsh_d->flyback_users, enable, mode_to_str(mode));
}

static void wcd_clsh_set_hph_mode(struct snd_soc_component *component,
/*
 * Function: wcd_clsh_set_hph_mode
 * Params: soc component, hph mode class
 * Description:
 * This function updates class H mode configuration based on
 * the input mode.
 */
void wcd_clsh_set_hph_mode(struct snd_soc_component *component,
				  int mode)
{
	u8 val = 0;
@@ -273,6 +280,7 @@ static void wcd_clsh_set_hph_mode(struct snd_soc_component *component,

	snd_soc_component_update_bits(component, WCD9XXX_ANA_HPH, 0x0C, val);
}
EXPORT_SYMBOL(wcd_clsh_set_hph_mode);

static void wcd_clsh_set_flyback_current(struct snd_soc_component *component,
				int mode)
+1 −0
Original line number Diff line number Diff line
@@ -144,6 +144,7 @@ enum {
	WCD_BOLERO_EVT_RX_MUTE = 1,	/* for RX mute/unmute */
	WCD_BOLERO_EVT_IMPED_TRUE,	/* for imped true */
	WCD_BOLERO_EVT_IMPED_FALSE,	/* for imped false */
	WCD_BOLERO_EVT_RX_COMPANDER_SOFT_RST,
};

enum {
+129 −34
Original line number Diff line number Diff line
@@ -173,6 +173,16 @@ static int wcd938x_init_reg(struct snd_soc_component *component)
	snd_soc_component_update_bits(component,
				WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG2MAIN_ULP,
				0x1F, 0x08);
	snd_soc_component_update_bits(component,
				WCD938X_DIGITAL_TX_REQ_FB_CTL_0, 0xFF, 0x55);
	snd_soc_component_update_bits(component,
				WCD938X_DIGITAL_TX_REQ_FB_CTL_1, 0xFF, 0x44);
	snd_soc_component_update_bits(component,
				WCD938X_DIGITAL_TX_REQ_FB_CTL_2, 0xFF, 0x11);
	snd_soc_component_update_bits(component,
				WCD938X_DIGITAL_TX_REQ_FB_CTL_3, 0xFF, 0x00);
	snd_soc_component_update_bits(component,
				WCD938X_DIGITAL_TX_REQ_FB_CTL_4, 0xFF, 0x00);

	return 0;
}
@@ -618,6 +628,10 @@ static int wcd938x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,

	switch (event) {
	case SND_SOC_DAPM_PRE_PMU:
		if (wcd938x->update_wcd_event)
			wcd938x->update_wcd_event(wcd938x->handle,
						WCD_BOLERO_EVT_RX_MUTE,
						(WCD_RX2 << 0x10 | 0x1));
		ret = swr_slvdev_datapath_control(wcd938x->rx_swr_dev,
				    wcd938x->rx_swr_dev->dev_num,
				    true);
@@ -625,8 +639,10 @@ static int wcd938x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
			     WCD_CLSH_EVENT_PRE_DAC,
			     WCD_CLSH_STATE_HPHR,
			     hph_mode);
		wcd_clsh_set_hph_mode(component, CLS_H_HIFI);
		snd_soc_component_update_bits(component, WCD938X_ANA_HPH,
					      0x10, 0x10);
		wcd_clsh_set_hph_mode(component, hph_mode);
		/* 100 usec delay as per HW requirement */
		usleep_range(100, 110);
		set_bit(HPH_PA_DELAY, &wcd938x->status_mask);
@@ -656,26 +672,61 @@ static int wcd938x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
			wcd938x->update_wcd_event(wcd938x->handle,
						WCD_BOLERO_EVT_RX_MUTE,
						(WCD_RX2 << 0x10));
		wcd_enable_irq(&wcd938x->irq_info,
					WCD938X_IRQ_HPHR_PDM_WD_INT);
		break;
	case SND_SOC_DAPM_PRE_PMD:
		wcd_disable_irq(&wcd938x->irq_info,
					WCD938X_IRQ_HPHR_PDM_WD_INT);
		if (wcd938x->update_wcd_event)
			wcd938x->update_wcd_event(wcd938x->handle,
						WCD_BOLERO_EVT_RX_MUTE,
						(WCD_RX2 << 0x10 | 0x1));
		if (wcd938x->update_wcd_event)
			wcd938x->update_wcd_event(wcd938x->handle,
					WCD_BOLERO_EVT_RX_COMPANDER_SOFT_RST,
					(WCD_RX2 << 0x10));
		/* 7 msec delay as per HW requirement */
		usleep_range(7000, 7100);
		if (wcd938x->update_wcd_event)
			wcd938x->update_wcd_event(wcd938x->handle,
						WCD_BOLERO_EVT_RX_MUTE,
						(WCD_RX2 << 0x10 | 0x0));
		/* 20 msec delay as per HW requirement */
		usleep_range(21000, 21100);
		if (wcd938x->update_wcd_event)
			wcd938x->update_wcd_event(wcd938x->handle,
						WCD_BOLERO_EVT_RX_MUTE,
						(WCD_RX2 << 0x10 | 0x1));
		snd_soc_component_update_bits(component, WCD938X_ANA_HPH,
						0x40, 0x00);
		blocking_notifier_call_chain(&wcd938x->mbhc->notifier,
					     WCD_EVENT_PRE_HPHR_PA_OFF,
					     &wcd938x->mbhc->wcd_mbhc);
		set_bit(HPH_PA_DELAY, &wcd938x->status_mask);
		break;
	case SND_SOC_DAPM_POST_PMD:
		/* 7 msec delay as per HW requirement */
		usleep_range(7000, 7010);
		snd_soc_component_update_bits(component,
				WCD938X_DIGITAL_PDM_WD_CTL1, 0x17, 0x00);
		/*
		 * 7ms sleep is required if compander is enabled as per
		 * HW requirement. If compander is disabled, then
		 * 20ms delay is required.
		 */
		if (test_bit(HPH_PA_DELAY, &wcd938x->status_mask)) {
			if (!wcd938x->comp2_enable)
				usleep_range(20000, 20100);
			else
				usleep_range(7000, 7100);
			clear_bit(HPH_PA_DELAY, &wcd938x->status_mask);
		}
		blocking_notifier_call_chain(&wcd938x->mbhc->notifier,
					     WCD_EVENT_POST_HPHR_PA_OFF,
					     &wcd938x->mbhc->wcd_mbhc);
		snd_soc_component_update_bits(component, WCD938X_ANA_HPH,
						0x10, 0x00);
		/* 20 msec delay as per HW requirement */
		usleep_range(20000, 20100);
		snd_soc_component_update_bits(component,
				WCD938X_DIGITAL_PDM_WD_CTL1, 0x17, 0x00);
		wcd_cls_h_fsm(component, &wcd938x->clsh_info,
			     WCD_CLSH_EVENT_POST_PA,
			     WCD_CLSH_STATE_HPHR,
@@ -699,6 +750,10 @@ static int wcd938x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,

	switch (event) {
	case SND_SOC_DAPM_PRE_PMU:
		if (wcd938x->update_wcd_event)
			wcd938x->update_wcd_event(wcd938x->handle,
						WCD_BOLERO_EVT_RX_MUTE,
						(WCD_RX1 << 0x10 | 0x01));
		ret = swr_slvdev_datapath_control(wcd938x->rx_swr_dev,
				    wcd938x->rx_swr_dev->dev_num,
				    true);
@@ -706,8 +761,10 @@ static int wcd938x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
			     WCD_CLSH_EVENT_PRE_DAC,
			     WCD_CLSH_STATE_HPHL,
			     hph_mode);
		wcd_clsh_set_hph_mode(component, CLS_H_HIFI);
		snd_soc_component_update_bits(component, WCD938X_ANA_HPH,
						0x20, 0x20);
		wcd_clsh_set_hph_mode(component, hph_mode);
		/* 100 usec delay as per HW requirement */
		usleep_range(100, 110);
		set_bit(HPH_PA_DELAY, &wcd938x->status_mask);
@@ -737,26 +794,61 @@ static int wcd938x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
			wcd938x->update_wcd_event(wcd938x->handle,
						WCD_BOLERO_EVT_RX_MUTE,
						(WCD_RX1 << 0x10));
		wcd_enable_irq(&wcd938x->irq_info,
					WCD938X_IRQ_HPHL_PDM_WD_INT);
		break;
	case SND_SOC_DAPM_PRE_PMD:
		wcd_disable_irq(&wcd938x->irq_info,
					WCD938X_IRQ_HPHL_PDM_WD_INT);
		if (wcd938x->update_wcd_event)
			wcd938x->update_wcd_event(wcd938x->handle,
						WCD_BOLERO_EVT_RX_MUTE,
						(WCD_RX1 << 0x10 | 0x1));
		if (wcd938x->update_wcd_event)
			wcd938x->update_wcd_event(wcd938x->handle,
					WCD_BOLERO_EVT_RX_COMPANDER_SOFT_RST,
					(WCD_RX1 << 0x10));
		/* 7 msec delay as per HW requirement */
		usleep_range(7000, 7100);
		if (wcd938x->update_wcd_event)
			wcd938x->update_wcd_event(wcd938x->handle,
						WCD_BOLERO_EVT_RX_MUTE,
						(WCD_RX1 << 0x10 | 0x0));
		/* 20 msec delay as per HW requirement */
		usleep_range(21000, 21100);
		if (wcd938x->update_wcd_event)
			wcd938x->update_wcd_event(wcd938x->handle,
						WCD_BOLERO_EVT_RX_MUTE,
						(WCD_RX1 << 0x10 | 0x1));
		snd_soc_component_update_bits(component, WCD938X_ANA_HPH,
						0x80, 0x00);
		blocking_notifier_call_chain(&wcd938x->mbhc->notifier,
					     WCD_EVENT_PRE_HPHL_PA_OFF,
					     &wcd938x->mbhc->wcd_mbhc);
		set_bit(HPH_PA_DELAY, &wcd938x->status_mask);
		break;
	case SND_SOC_DAPM_POST_PMD:
		/* 7 msec delay as per HW requirement */
		usleep_range(7000, 7010);
		snd_soc_component_update_bits(component,
				WCD938X_DIGITAL_PDM_WD_CTL0, 0x17, 0x00);
		/*
		 * 7ms sleep is required if compander is enabled as per
		 * HW requirement. If compander is disabled, then
		 * 20ms delay is required.
		 */
		if (test_bit(HPH_PA_DELAY, &wcd938x->status_mask)) {
			if (!wcd938x->comp1_enable)
				usleep_range(21000, 21100);
			else
				usleep_range(7000, 7100);
			clear_bit(HPH_PA_DELAY, &wcd938x->status_mask);
		}
		blocking_notifier_call_chain(&wcd938x->mbhc->notifier,
					     WCD_EVENT_POST_HPHL_PA_OFF,
					     &wcd938x->mbhc->wcd_mbhc);
		snd_soc_component_update_bits(component, WCD938X_ANA_HPH,
						0x20, 0x00);
		/* 20 msec delay as per HW requirement */
		usleep_range(21000, 21100);
		snd_soc_component_update_bits(component,
				WCD938X_DIGITAL_PDM_WD_CTL0, 0x17, 0x00);
		wcd_cls_h_fsm(component, &wcd938x->clsh_info,
			     WCD_CLSH_EVENT_POST_PA,
			     WCD_CLSH_STATE_HPHL,
@@ -799,8 +891,11 @@ static int wcd938x_codec_enable_aux_pa(struct snd_soc_dapm_widget *w,
			wcd938x->update_wcd_event(wcd938x->handle,
						WCD_BOLERO_EVT_RX_MUTE,
						(WCD_RX3 << 0x10));
		wcd_enable_irq(&wcd938x->irq_info, WCD938X_IRQ_AUX_PDM_WD_INT);
		break;
	case SND_SOC_DAPM_PRE_PMD:
		wcd_disable_irq(&wcd938x->irq_info,
					WCD938X_IRQ_AUX_PDM_WD_INT);
		if (wcd938x->update_wcd_event)
			wcd938x->update_wcd_event(wcd938x->handle,
						WCD_BOLERO_EVT_RX_MUTE,
@@ -1684,10 +1779,10 @@ static int wcd938x_codec_enable_micbias(struct snd_soc_dapm_widget *w,
	return __wcd938x_codec_enable_micbias(w, event);
}

static inline int wcd938x_tx_path_get(const char *wname)
static inline int wcd938x_tx_path_get(const char *wname,
				      unsigned int *path_num)
{
	int ret = 0;
	unsigned int path_num;
	char *widget_name = NULL;
	char *w_name = NULL;
	char *path_num_char = NULL;
@@ -1706,7 +1801,6 @@ static inline int wcd938x_tx_path_get(const char *wname)
		ret = -EINVAL;
		goto err;
	}
	path_name = widget_name;
	path_num_char = strpbrk(path_name, "0123");
	if (!path_num_char) {
		pr_err("%s: tx path index not found\n",
@@ -1714,7 +1808,7 @@ static inline int wcd938x_tx_path_get(const char *wname)
		ret = -EINVAL;
		goto err;
	}
	ret = kstrtouint(path_num_char, 10, &path_num);
	ret = kstrtouint(path_num_char, 10, path_num);
	if (ret < 0)
		pr_err("%s: Invalid tx path = %s\n",
			__func__, w_name);
@@ -1727,24 +1821,23 @@ static inline int wcd938x_tx_path_get(const char *wname)
static int wcd938x_tx_mode_get(struct snd_kcontrol *kcontrol,
				 struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_dapm_widget *widget =
			snd_soc_dapm_kcontrol_widget(kcontrol);
	struct snd_soc_component *component =
			snd_soc_kcontrol_component(kcontrol);
	struct wcd938x_priv *wcd938x = NULL;
	int path = 0;
	int ret = 0;
	unsigned int path = 0;

	if (!component)
		return -EINVAL;

	wcd938x = snd_soc_component_get_drvdata(component);

	if (!widget || !widget->name || !wcd938x)
	if (!wcd938x)
		return -EINVAL;

	path = wcd938x_tx_path_get(widget->name);
	if (path < 0 || path >= TX_ADC_MAX)
		return -EINVAL;
	ret = wcd938x_tx_path_get(kcontrol->id.name, &path);
	if (ret < 0)
		return ret;

	ucontrol->value.integer.value[0] = wcd938x->tx_mode[path];

@@ -1754,25 +1847,24 @@ static int wcd938x_tx_mode_get(struct snd_kcontrol *kcontrol,
static int wcd938x_tx_mode_put(struct snd_kcontrol *kcontrol,
				 struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_dapm_widget *widget =
			snd_soc_dapm_kcontrol_widget(kcontrol);
	struct snd_soc_component *component =
			snd_soc_kcontrol_component(kcontrol);
	struct wcd938x_priv *wcd938x = NULL;
	u32 mode_val;
	int path = 0;
	unsigned int path = 0;
	int ret = 0;

	if (!component)
		return -EINVAL;

	wcd938x  = snd_soc_component_get_drvdata(component);

	if (!widget || !widget->name || !wcd938x)
	if (!wcd938x)
		return -EINVAL;

	path = wcd938x_tx_path_get(widget->name);
	if (path < 0 || path >= TX_ADC_MAX)
		return -EINVAL;
	ret = wcd938x_tx_path_get(kcontrol->id.name, &path);
	if (ret)
		return ret;

	mode_val = ucontrol->value.enumerated.item[0];

@@ -2199,19 +2291,19 @@ static const struct snd_soc_dapm_widget wcd938x_dapm_widgets[] = {
	SND_SOC_DAPM_PGA_E("EAR PGA", WCD938X_ANA_EAR, 7, 0, NULL, 0,
				wcd938x_codec_enable_ear_pa,
				SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
				SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
				SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
	SND_SOC_DAPM_PGA_E("AUX PGA", WCD938X_AUX_AUXPA, 7, 0, NULL, 0,
				wcd938x_codec_enable_aux_pa,
				SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
				SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
				SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
	SND_SOC_DAPM_PGA_E("HPHL PGA", WCD938X_ANA_HPH, 7, 0, NULL, 0,
				wcd938x_codec_enable_hphl_pa,
				SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
				SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
				SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
	SND_SOC_DAPM_PGA_E("HPHR PGA", WCD938X_ANA_HPH, 6, 0, NULL, 0,
				wcd938x_codec_enable_hphr_pa,
				SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
				SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
				SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),

	SND_SOC_DAPM_DAC_E("RDAC1", NULL, SND_SOC_NOPM, 0, 0,
				wcd938x_codec_hphl_dac_event,
@@ -2840,10 +2932,10 @@ static int wcd938x_bind(struct device *dev)
			"HPHL PDM WD INT", wcd938x_wd_handle_irq, NULL);
	wcd_request_irq(&wcd938x->irq_info, WCD938X_IRQ_AUX_PDM_WD_INT,
			"AUX PDM WD INT", wcd938x_wd_handle_irq, NULL);
	/* Enable watchdog interrupt for HPH and AUX */
	wcd_enable_irq(&wcd938x->irq_info, WCD938X_IRQ_HPHR_PDM_WD_INT);
	wcd_enable_irq(&wcd938x->irq_info, WCD938X_IRQ_HPHL_PDM_WD_INT);
	wcd_enable_irq(&wcd938x->irq_info, WCD938X_IRQ_AUX_PDM_WD_INT);
	/* Disable watchdog interrupt for HPH and AUX */
	wcd_disable_irq(&wcd938x->irq_info, WCD938X_IRQ_HPHR_PDM_WD_INT);
	wcd_disable_irq(&wcd938x->irq_info, WCD938X_IRQ_HPHL_PDM_WD_INT);
	wcd_disable_irq(&wcd938x->irq_info, WCD938X_IRQ_AUX_PDM_WD_INT);

	ret = snd_soc_register_component(dev, &soc_codec_dev_wcd938x,
				     NULL, 0);
@@ -2865,6 +2957,9 @@ static void wcd938x_unbind(struct device *dev)
{
	struct wcd938x_priv *wcd938x = dev_get_drvdata(dev);

	wcd_free_irq(&wcd938x->irq_info, WCD938X_IRQ_HPHR_PDM_WD_INT, NULL);
	wcd_free_irq(&wcd938x->irq_info, WCD938X_IRQ_HPHL_PDM_WD_INT, NULL);
	wcd_free_irq(&wcd938x->irq_info, WCD938X_IRQ_AUX_PDM_WD_INT, NULL);
	wcd_irq_exit(&wcd938x->irq_info, wcd938x->virq);
	snd_soc_unregister_component(dev);
	component_unbind_all(dev, wcd938x);
+9 −2
Original line number Diff line number Diff line
@@ -82,15 +82,22 @@ extern void wcd_cls_h_fsm(struct snd_soc_component *component,
		int int_mode);

extern void wcd_cls_h_init(struct wcd_clsh_cdc_info *clsh);
extern void wcd_clsh_set_hph_mode(struct snd_soc_component *component,
				  int mode);
#else
extern void wcd_cls_h_fsm(struct snd_soc_component *component,
static inline void wcd_cls_h_fsm(struct snd_soc_component *component,
		struct wcd_clsh_cdc_info *cdc_clsh_d,
		u8 clsh_event, u8 req_state,
		int int_mode)
{
}

extern void wcd_cls_h_init(struct wcd_clsh_cdc_info *clsh)
static inline extern void wcd_cls_h_init(struct wcd_clsh_cdc_info *clsh)
{
}

static inline extern void wcd_clsh_set_hph_mode(struct snd_soc_component *component,
				  int mode)
{
}
#endif /* CONFIG_SND_SOC_WCD9XXX_V2 */