asoc: codecs: Fix CnP on HPH turnon and turnoff

On headphone(HPH) path, CnP spec is not met.
Handle sequences for bolero and tanggu codecs
as per HW sequences. Disable vdd_buck during
system suspend when no usecase is active.

CRs-Fixed: 2343436
Change-Id: I62f89d829715f07885a97531fdcb2cc3ca0822ef
Signed-off-by: Laxminath Kasam <lkasam@codeaurora.org>
This commit is contained in:
Laxminath Kasam
2018-11-14 20:36:08 +05:30
parent e95846085a
commit 35849ccf24
3 changed files with 119 additions and 73 deletions

View File

@@ -1407,8 +1407,6 @@ static int rx_macro_config_compander(struct snd_soc_codec *codec,
if (SND_SOC_DAPM_EVENT_OFF(event)) { if (SND_SOC_DAPM_EVENT_OFF(event)) {
snd_soc_update_bits(codec, comp_ctl0_reg, 0x04, 0x04); snd_soc_update_bits(codec, comp_ctl0_reg, 0x04, 0x04);
snd_soc_update_bits(codec, rx_path_cfg0_reg, 0x02, 0x00); snd_soc_update_bits(codec, rx_path_cfg0_reg, 0x02, 0x00);
snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x02);
snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x00);
snd_soc_update_bits(codec, comp_ctl0_reg, 0x01, 0x00); snd_soc_update_bits(codec, comp_ctl0_reg, 0x01, 0x00);
snd_soc_update_bits(codec, comp_ctl0_reg, 0x04, 0x00); snd_soc_update_bits(codec, comp_ctl0_reg, 0x04, 0x00);
} }
@@ -1987,7 +1985,7 @@ static void rx_macro_hphdelay_lutbypass(struct snd_soc_codec *codec,
static int rx_macro_enable_interp_clk(struct snd_soc_codec *codec, static int rx_macro_enable_interp_clk(struct snd_soc_codec *codec,
int event, int interp_idx) int event, int interp_idx)
{ {
u16 main_reg = 0; u16 main_reg = 0, dsm_reg = 0, rx_cfg2_reg = 0;
struct device *rx_dev = NULL; struct device *rx_dev = NULL;
struct rx_macro_priv *rx_priv = NULL; struct rx_macro_priv *rx_priv = NULL;
@@ -2001,13 +1999,19 @@ static int rx_macro_enable_interp_clk(struct snd_soc_codec *codec,
main_reg = BOLERO_CDC_RX_RX0_RX_PATH_CTL + main_reg = BOLERO_CDC_RX_RX0_RX_PATH_CTL +
(interp_idx * RX_MACRO_RX_PATH_OFFSET); (interp_idx * RX_MACRO_RX_PATH_OFFSET);
dsm_reg = BOLERO_CDC_RX_RX0_RX_PATH_DSM_CTL +
(interp_idx * RX_MACRO_RX_PATH_OFFSET);
rx_cfg2_reg = BOLERO_CDC_RX_RX0_RX_PATH_CFG2 +
(interp_idx * RX_MACRO_RX_PATH_OFFSET);
if (SND_SOC_DAPM_EVENT_ON(event)) { if (SND_SOC_DAPM_EVENT_ON(event)) {
if (rx_priv->main_clk_users[interp_idx] == 0) { if (rx_priv->main_clk_users[interp_idx] == 0) {
snd_soc_update_bits(codec, dsm_reg, 0x01, 0x01);
/* Main path PGA mute enable */ /* Main path PGA mute enable */
snd_soc_update_bits(codec, main_reg, 0x10, 0x10); snd_soc_update_bits(codec, main_reg, 0x10, 0x10);
/* Clk enable */ /* Clk enable */
snd_soc_update_bits(codec, main_reg, 0x20, 0x20); snd_soc_update_bits(codec, main_reg, 0x20, 0x20);
snd_soc_update_bits(codec, rx_cfg2_reg, 0x03, 0x03);
rx_macro_idle_detect_control(codec, rx_priv, rx_macro_idle_detect_control(codec, rx_priv,
interp_idx, event); interp_idx, event);
rx_macro_hd2_control(codec, interp_idx, event); rx_macro_hd2_control(codec, interp_idx, event);
@@ -2028,6 +2032,15 @@ static int rx_macro_enable_interp_clk(struct snd_soc_codec *codec,
rx_priv->main_clk_users[interp_idx]--; rx_priv->main_clk_users[interp_idx]--;
if (rx_priv->main_clk_users[interp_idx] <= 0) { if (rx_priv->main_clk_users[interp_idx] <= 0) {
rx_priv->main_clk_users[interp_idx] = 0; rx_priv->main_clk_users[interp_idx] = 0;
/* Clk Disable */
snd_soc_update_bits(codec, dsm_reg, 0x01, 0x00);
snd_soc_update_bits(codec, main_reg, 0x20, 0x00);
/* Reset enable and disable */
snd_soc_update_bits(codec, main_reg, 0x40, 0x40);
snd_soc_update_bits(codec, main_reg, 0x40, 0x00);
/* Reset rate to 48K*/
snd_soc_update_bits(codec, main_reg, 0x0F, 0x04);
snd_soc_update_bits(codec, rx_cfg2_reg, 0x03, 0x00);
rx_macro_config_classh(codec, rx_priv, rx_macro_config_classh(codec, rx_priv,
interp_idx, event); interp_idx, event);
rx_macro_config_compander(codec, rx_priv, rx_macro_config_compander(codec, rx_priv,
@@ -2040,13 +2053,6 @@ static int rx_macro_enable_interp_clk(struct snd_soc_codec *codec,
rx_macro_hd2_control(codec, interp_idx, event); rx_macro_hd2_control(codec, interp_idx, event);
rx_macro_idle_detect_control(codec, rx_priv, rx_macro_idle_detect_control(codec, rx_priv,
interp_idx, event); interp_idx, event);
/* Clk Disable */
snd_soc_update_bits(codec, main_reg, 0x20, 0x00);
/* Reset enable and disable */
snd_soc_update_bits(codec, main_reg, 0x40, 0x40);
snd_soc_update_bits(codec, main_reg, 0x40, 0x00);
/* Reset rate to 48K*/
snd_soc_update_bits(codec, main_reg, 0x0F, 0x04);
} }
} }

View File

@@ -68,6 +68,8 @@ struct wcd937x_priv {
struct wcd_irq_info irq_info; struct wcd_irq_info irq_info;
u32 rx_clk_cnt; u32 rx_clk_cnt;
int num_irq_regs; int num_irq_regs;
/* to track the status */
unsigned long status_mask;
u8 num_tx_ports; u8 num_tx_ports;
u8 num_rx_ports; u8 num_rx_ports;

View File

@@ -18,10 +18,11 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/component.h> #include <linux/component.h>
#include <linux/regmap.h>
#include <linux/pm_runtime.h>
#include <sound/soc.h> #include <sound/soc.h>
#include <sound/tlv.h> #include <sound/tlv.h>
#include <soc/soundwire.h> #include <soc/soundwire.h>
#include <linux/regmap.h>
#include <sound/soc.h> #include <sound/soc.h>
#include <sound/soc-dapm.h> #include <sound/soc-dapm.h>
#include "internal.h" #include "internal.h"
@@ -45,6 +46,10 @@ enum {
CODEC_RX, CODEC_RX,
}; };
enum {
ALLOW_BUCK_DISABLE,
};
static const DECLARE_TLV_DB_SCALE(line_gain, 0, 7, 1); static const DECLARE_TLV_DB_SCALE(line_gain, 0, 7, 1);
static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1); static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1);
@@ -374,7 +379,6 @@ static int wcd937x_codec_hphl_dac_event(struct snd_soc_dapm_widget *w,
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec);
int hph_mode = wcd937x->hph_mode; int hph_mode = wcd937x->hph_mode;
int ret = 0;
dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__,
w->name, event); w->name, event);
@@ -414,22 +418,15 @@ static int wcd937x_codec_hphl_dac_event(struct snd_soc_dapm_widget *w,
usleep_range(5000, 5010); usleep_range(5000, 5010);
snd_soc_update_bits(codec, WCD937X_HPH_NEW_INT_HPH_TIMER1, snd_soc_update_bits(codec, WCD937X_HPH_NEW_INT_HPH_TIMER1,
0x02, 0x00); 0x02, 0x00);
wcd_cls_h_fsm(codec, &wcd937x->clsh_info,
WCD_CLSH_EVENT_PRE_DAC,
WCD_CLSH_STATE_HPHL,
hph_mode);
break; break;
case SND_SOC_DAPM_POST_PMD: case SND_SOC_DAPM_POST_PMD:
snd_soc_update_bits(codec, snd_soc_update_bits(codec,
WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_L, WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_L,
0x0F, 0x01); 0x0F, 0x01);
ret = swr_slvdev_datapath_control(wcd937x->rx_swr_dev,
wcd937x->rx_swr_dev->dev_num,
false);
break; break;
} }
return ret; return 0;
} }
static int wcd937x_codec_hphr_dac_event(struct snd_soc_dapm_widget *w, static int wcd937x_codec_hphr_dac_event(struct snd_soc_dapm_widget *w,
@@ -439,8 +436,6 @@ static int wcd937x_codec_hphr_dac_event(struct snd_soc_dapm_widget *w,
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec);
int hph_mode = wcd937x->hph_mode; int hph_mode = wcd937x->hph_mode;
int ret = 0;
dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__,
w->name, event); w->name, event);
@@ -480,22 +475,15 @@ static int wcd937x_codec_hphr_dac_event(struct snd_soc_dapm_widget *w,
usleep_range(5000, 5010); usleep_range(5000, 5010);
snd_soc_update_bits(codec, WCD937X_HPH_NEW_INT_HPH_TIMER1, snd_soc_update_bits(codec, WCD937X_HPH_NEW_INT_HPH_TIMER1,
0x02, 0x00); 0x02, 0x00);
wcd_cls_h_fsm(codec, &wcd937x->clsh_info,
WCD_CLSH_EVENT_PRE_DAC,
WCD_CLSH_STATE_HPHR,
hph_mode);
break; break;
case SND_SOC_DAPM_POST_PMD: case SND_SOC_DAPM_POST_PMD:
snd_soc_update_bits(codec, snd_soc_update_bits(codec,
WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_R, WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_R,
0x0F, 0x01); 0x0F, 0x01);
ret = swr_slvdev_datapath_control(wcd937x->rx_swr_dev,
wcd937x->rx_swr_dev->dev_num,
false);
break; break;
} }
return ret; return 0;
} }
static int wcd937x_codec_ear_dac_event(struct snd_soc_dapm_widget *w, static int wcd937x_codec_ear_dac_event(struct snd_soc_dapm_widget *w,
@@ -505,7 +493,6 @@ static int wcd937x_codec_ear_dac_event(struct snd_soc_dapm_widget *w,
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec);
int hph_mode = wcd937x->hph_mode; int hph_mode = wcd937x->hph_mode;
int ret = 0;
dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__,
w->name, event); w->name, event);
@@ -540,12 +527,9 @@ static int wcd937x_codec_ear_dac_event(struct snd_soc_dapm_widget *w,
snd_soc_update_bits(codec, snd_soc_update_bits(codec,
WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_L, WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_L,
0x0F, 0x01); 0x0F, 0x01);
ret = swr_slvdev_datapath_control(wcd937x->rx_swr_dev,
wcd937x->rx_swr_dev->dev_num,
false);
break; break;
}; };
return ret; return 0;
} }
@@ -556,7 +540,6 @@ static int wcd937x_codec_aux_dac_event(struct snd_soc_dapm_widget *w,
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec);
int hph_mode = wcd937x->hph_mode; int hph_mode = wcd937x->hph_mode;
int ret = 0;
dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__,
w->name, event); w->name, event);
@@ -577,15 +560,12 @@ static int wcd937x_codec_aux_dac_event(struct snd_soc_dapm_widget *w,
break; break;
case SND_SOC_DAPM_POST_PMD: case SND_SOC_DAPM_POST_PMD:
ret = swr_slvdev_datapath_control(wcd937x->rx_swr_dev,
wcd937x->rx_swr_dev->dev_num,
false);
wcd937x_rx_clk_disable(codec); wcd937x_rx_clk_disable(codec);
snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_ANA_CLK_CTL, snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_ANA_CLK_CTL,
0x04, 0x00); 0x04, 0x00);
break; break;
}; };
return ret; return 0;
} }
@@ -603,11 +583,15 @@ static int wcd937x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
switch (event) { switch (event) {
case SND_SOC_DAPM_PRE_PMU: case SND_SOC_DAPM_PRE_PMU:
snd_soc_update_bits(codec, WCD937X_ANA_HPH, 0x10, 0x10);
usleep_range(100, 110);
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);
wcd_cls_h_fsm(codec, &wcd937x->clsh_info,
WCD_CLSH_EVENT_PRE_DAC,
WCD_CLSH_STATE_HPHR,
hph_mode);
snd_soc_update_bits(codec, WCD937X_ANA_HPH, 0x10, 0x10);
usleep_range(100, 110);
break; break;
case SND_SOC_DAPM_POST_PMU: case SND_SOC_DAPM_POST_PMU:
usleep_range(7000, 7010); usleep_range(7000, 7010);
@@ -654,13 +638,20 @@ static int wcd937x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
int ret = 0; int ret = 0;
int hph_mode = wcd937x->hph_mode; int hph_mode = wcd937x->hph_mode;
dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__,
w->name, event);
switch (event) { switch (event) {
case SND_SOC_DAPM_PRE_PMU: case SND_SOC_DAPM_PRE_PMU:
snd_soc_update_bits(codec, WCD937X_ANA_HPH, 0x20, 0x20);
usleep_range(100, 110);
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);
wcd_cls_h_fsm(codec, &wcd937x->clsh_info,
WCD_CLSH_EVENT_PRE_DAC,
WCD_CLSH_STATE_HPHL,
hph_mode);
snd_soc_update_bits(codec, WCD937X_ANA_HPH, 0x20, 0x20);
usleep_range(100, 110);
break; break;
case SND_SOC_DAPM_POST_PMU: case SND_SOC_DAPM_POST_PMU:
usleep_range(7000, 7010); usleep_range(7000, 7010);
@@ -805,12 +796,12 @@ static int wcd937x_enable_clsh(struct snd_soc_dapm_widget *w,
mode == CLS_H_HIFI || mode == CLS_H_LP) { mode == CLS_H_HIFI || mode == CLS_H_LP) {
wcd937x_rx_connect_port(codec, CLSH, wcd937x_rx_connect_port(codec, CLSH,
SND_SOC_DAPM_EVENT_ON(event)); SND_SOC_DAPM_EVENT_ON(event));
}
if (SND_SOC_DAPM_EVENT_OFF(event)) if (SND_SOC_DAPM_EVENT_OFF(event))
ret = swr_slvdev_datapath_control( ret = swr_slvdev_datapath_control(
wcd937x->rx_swr_dev, wcd937x->rx_swr_dev,
wcd937x->rx_swr_dev->dev_num, wcd937x->rx_swr_dev->dev_num,
false); false);
}
return ret; return ret;
} }
@@ -1449,6 +1440,12 @@ static int wcd937x_codec_enable_vdd_buck(struct snd_soc_dapm_widget *w,
switch (event) { switch (event) {
case SND_SOC_DAPM_PRE_PMU: case SND_SOC_DAPM_PRE_PMU:
if (test_bit(ALLOW_BUCK_DISABLE, &wcd937x->status_mask)) {
dev_dbg(codec->dev,
"%s: buck already in enabled state\n",
__func__);
return 0;
}
ret = msm_cdc_enable_ondemand_supply(wcd937x->dev, ret = msm_cdc_enable_ondemand_supply(wcd937x->dev,
wcd937x->supplies, wcd937x->supplies,
pdata->regulator, pdata->regulator,
@@ -1459,6 +1456,7 @@ static int wcd937x_codec_enable_vdd_buck(struct snd_soc_dapm_widget *w,
__func__); __func__);
return ret; return ret;
} }
clear_bit(ALLOW_BUCK_DISABLE, &wcd937x->status_mask);
/* /*
* 200us sleep is required after LDO15 is enabled as per * 200us sleep is required after LDO15 is enabled as per
* HW requirement * HW requirement
@@ -1466,17 +1464,7 @@ static int wcd937x_codec_enable_vdd_buck(struct snd_soc_dapm_widget *w,
usleep_range(200, 250); usleep_range(200, 250);
break; break;
case SND_SOC_DAPM_POST_PMD: case SND_SOC_DAPM_POST_PMD:
ret = msm_cdc_disable_ondemand_supply(wcd937x->dev, set_bit(ALLOW_BUCK_DISABLE, &wcd937x->status_mask);
wcd937x->supplies,
pdata->regulator,
pdata->num_supplies,
"cdc-vdd-buck");
if (ret == -EINVAL) {
dev_err(codec->dev, "%s: vdd buck is not enabled\n",
__func__);
return ret;
}
break; break;
} }
return 0; return 0;
@@ -1638,7 +1626,7 @@ static const struct snd_soc_dapm_widget wcd937x_dapm_widgets[] = {
wcd937x_codec_enable_vdd_buck, wcd937x_codec_enable_vdd_buck,
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_SUPPLY("CLS_H_PORT", SND_SOC_NOPM, 0, 0, SND_SOC_DAPM_SUPPLY_S("CLS_H_PORT", 1, SND_SOC_NOPM, 0, 0,
wcd937x_enable_clsh, wcd937x_enable_clsh,
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
@@ -1787,7 +1775,6 @@ static const struct snd_soc_dapm_widget wcd9375_dapm_widgets[] = {
}; };
static const struct snd_soc_dapm_route wcd937x_audio_map[] = { static const struct snd_soc_dapm_route wcd937x_audio_map[] = {
{"ADC1_OUTPUT", NULL, "ADC1_MIXER"}, {"ADC1_OUTPUT", NULL, "ADC1_MIXER"},
{"ADC1_MIXER", "Switch", "ADC1 REQ"}, {"ADC1_MIXER", "Switch", "ADC1 REQ"},
{"ADC1 REQ", NULL, "ADC1"}, {"ADC1 REQ", NULL, "ADC1"},
@@ -1800,18 +1787,24 @@ static const struct snd_soc_dapm_route wcd937x_audio_map[] = {
{"ADC2 MUX", "INP3", "AMIC3"}, {"ADC2 MUX", "INP3", "AMIC3"},
{"ADC2 MUX", "INP2", "AMIC2"}, {"ADC2 MUX", "INP2", "AMIC2"},
{"IN1_HPHL", NULL, "VDD_BUCK"},
{"IN1_HPHL", NULL, "CLS_H_PORT"},
{"RX1", NULL, "IN1_HPHL"}, {"RX1", NULL, "IN1_HPHL"},
{"RDAC1", NULL, "RX1"}, {"RDAC1", NULL, "RX1"},
{"HPHL_RDAC", "Switch", "RDAC1"}, {"HPHL_RDAC", "Switch", "RDAC1"},
{"HPHL PGA", NULL, "HPHL_RDAC"}, {"HPHL PGA", NULL, "HPHL_RDAC"},
{"HPHL", NULL, "HPHL PGA"}, {"HPHL", NULL, "HPHL PGA"},
{"IN2_HPHR", NULL, "VDD_BUCK"},
{"IN2_HPHR", NULL, "CLS_H_PORT"},
{"RX2", NULL, "IN2_HPHR"}, {"RX2", NULL, "IN2_HPHR"},
{"RDAC2", NULL, "RX2"}, {"RDAC2", NULL, "RX2"},
{"HPHR_RDAC", "Switch", "RDAC2"}, {"HPHR_RDAC", "Switch", "RDAC2"},
{"HPHR PGA", NULL, "HPHR_RDAC"}, {"HPHR PGA", NULL, "HPHR_RDAC"},
{"HPHR", NULL, "HPHR PGA"}, {"HPHR", NULL, "HPHR PGA"},
{"IN3_AUX", NULL, "VDD_BUCK"},
{"IN3_AUX", NULL, "CLS_H_PORT"},
{"RX3", NULL, "IN3_AUX"}, {"RX3", NULL, "IN3_AUX"},
{"RDAC4", NULL, "RX3"}, {"RDAC4", NULL, "RX3"},
{"AUX_RDAC", "Switch", "RDAC4"}, {"AUX_RDAC", "Switch", "RDAC4"},
@@ -1824,16 +1817,6 @@ static const struct snd_soc_dapm_route wcd937x_audio_map[] = {
{"EAR_RDAC", "Switch", "RDAC3"}, {"EAR_RDAC", "Switch", "RDAC3"},
{"EAR PGA", NULL, "EAR_RDAC"}, {"EAR PGA", NULL, "EAR_RDAC"},
{"EAR", NULL, "EAR PGA"}, {"EAR", NULL, "EAR PGA"},
{"EAR", NULL, "VDD_BUCK"},
{"HPHR", NULL, "VDD_BUCK"},
{"HPHL", NULL, "VDD_BUCK"},
{"AUX", NULL, "VDD_BUCK"},
{"EAR", NULL, "CLS_H_PORT"},
{"HPHR", NULL, "CLS_H_PORT"},
{"HPHL", NULL, "CLS_H_PORT"},
{"AUX", NULL, "CLS_H_PORT"},
}; };
static const struct snd_soc_dapm_route wcd9375_audio_map[] = { static const struct snd_soc_dapm_route wcd9375_audio_map[] = {
@@ -2092,6 +2075,49 @@ static struct snd_soc_codec_driver soc_codec_dev_wcd937x = {
}, },
}; };
#ifdef CONFIG_PM_SLEEP
static int wcd937x_suspend(struct device *dev)
{
struct wcd937x_priv *wcd937x = NULL;
int ret = 0;
struct wcd937x_pdata *pdata = NULL;
if (!dev)
return -ENODEV;
wcd937x = dev_get_drvdata(dev);
if (!wcd937x)
return -EINVAL;
pdata = dev_get_platdata(wcd937x->dev);
if (!pdata) {
dev_err(dev, "%s: pdata is NULL\n", __func__);
return -EINVAL;
}
if (test_bit(ALLOW_BUCK_DISABLE, &wcd937x->status_mask)) {
ret = msm_cdc_disable_ondemand_supply(wcd937x->dev,
wcd937x->supplies,
pdata->regulator,
pdata->num_supplies,
"cdc-vdd-buck");
if (ret == -EINVAL) {
dev_err(dev, "%s: vdd buck is not disabled\n",
__func__);
return 0;
}
clear_bit(ALLOW_BUCK_DISABLE, &wcd937x->status_mask);
}
return 0;
}
static int wcd937x_resume(struct device *dev)
{
return 0;
}
#endif
static int wcd937x_reset(struct device *dev) static int wcd937x_reset(struct device *dev)
{ {
struct wcd937x_priv *wcd937x = NULL; struct wcd937x_priv *wcd937x = NULL;
@@ -2485,6 +2511,15 @@ static int wcd937x_remove(struct platform_device *pdev)
return 0; return 0;
} }
#ifdef CONFIG_PM_SLEEP
static const struct dev_pm_ops wcd937x_dev_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(
wcd937x_suspend,
wcd937x_resume
)
};
#endif
static struct platform_driver wcd937x_codec_driver = { static struct platform_driver wcd937x_codec_driver = {
.probe = wcd937x_probe, .probe = wcd937x_probe,
.remove = wcd937x_remove, .remove = wcd937x_remove,
@@ -2492,6 +2527,9 @@ static struct platform_driver wcd937x_codec_driver = {
.name = "wcd937x_codec", .name = "wcd937x_codec",
.owner = THIS_MODULE, .owner = THIS_MODULE,
.of_match_table = of_match_ptr(wcd937x_dt_match), .of_match_table = of_match_ptr(wcd937x_dt_match),
#ifdef CONFIG_PM_SLEEP
.pm = &wcd937x_dev_pm_ops,
#endif
}, },
}; };