Loading asoc/codecs/bolero/rx-macro.c +16 −10 Original line number Diff line number Diff line Loading @@ -1413,8 +1413,6 @@ static int rx_macro_config_compander(struct snd_soc_codec *codec, if (SND_SOC_DAPM_EVENT_OFF(event)) { 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, 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, 0x04, 0x00); } Loading Loading @@ -2021,7 +2019,7 @@ static void rx_macro_hphdelay_lutbypass(struct snd_soc_codec *codec, static int rx_macro_enable_interp_clk(struct snd_soc_codec *codec, 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 rx_macro_priv *rx_priv = NULL; Loading @@ -2035,13 +2033,19 @@ static int rx_macro_enable_interp_clk(struct snd_soc_codec *codec, main_reg = BOLERO_CDC_RX_RX0_RX_PATH_CTL + (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 (rx_priv->main_clk_users[interp_idx] == 0) { snd_soc_update_bits(codec, dsm_reg, 0x01, 0x01); /* Main path PGA mute enable */ snd_soc_update_bits(codec, main_reg, 0x10, 0x10); /* Clk enable */ 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, interp_idx, event); if (rx_priv->hph_hd2_mode) Loading @@ -2063,6 +2067,15 @@ static int rx_macro_enable_interp_clk(struct snd_soc_codec *codec, rx_priv->main_clk_users[interp_idx]--; if (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, interp_idx, event); rx_macro_config_compander(codec, rx_priv, Loading @@ -2076,13 +2089,6 @@ static int rx_macro_enable_interp_clk(struct snd_soc_codec *codec, rx_macro_hd2_control(codec, interp_idx, event); rx_macro_idle_detect_control(codec, rx_priv, 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); } } Loading asoc/codecs/wcd937x/internal.h +2 −0 Original line number Diff line number Diff line Loading @@ -68,6 +68,8 @@ struct wcd937x_priv { struct wcd_irq_info irq_info; u32 rx_clk_cnt; int num_irq_regs; /* to track the status */ unsigned long status_mask; u8 num_tx_ports; u8 num_rx_ports; Loading asoc/codecs/wcd937x/wcd937x.c +165 −67 Original line number Diff line number Diff line Loading @@ -18,10 +18,11 @@ #include <linux/delay.h> #include <linux/kernel.h> #include <linux/component.h> #include <linux/regmap.h> #include <linux/pm_runtime.h> #include <sound/soc.h> #include <sound/tlv.h> #include <soc/soundwire.h> #include <linux/regmap.h> #include <sound/soc.h> #include <sound/soc-dapm.h> #include "internal.h" Loading @@ -45,6 +46,12 @@ enum { CODEC_RX, }; enum { ALLOW_BUCK_DISABLE, HPH_COMP_DELAY, HPH_PA_DELAY, }; static const DECLARE_TLV_DB_SCALE(line_gain, 0, 7, 1); static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1); Loading Loading @@ -374,7 +381,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 wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); int hph_mode = wcd937x->hph_mode; int ret = 0; dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, w->name, event); Loading @@ -388,6 +394,7 @@ static int wcd937x_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, 0x04, 0x04); snd_soc_update_bits(codec, WCD937X_HPH_RDAC_CLK_CTL1, 0x80, 0x00); set_bit(HPH_COMP_DELAY, &wcd937x->status_mask); break; case SND_SOC_DAPM_POST_PMU: if (hph_mode == CLS_AB_HIFI || hph_mode == CLS_H_HIFI) Loading @@ -404,6 +411,22 @@ static int wcd937x_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, 0x02, 0x02); snd_soc_update_bits(codec, WCD937X_HPH_L_EN, 0x20, 0x00); if (wcd937x->comp2_enable) { snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_COMP_CTL_0, 0x01, 0x01); snd_soc_update_bits(codec, WCD937X_HPH_R_EN, 0x20, 0x00); } /* * 5ms sleep is required after COMP is enabled as per * HW requirement */ if (test_bit(HPH_COMP_DELAY, &wcd937x->status_mask)) { usleep_range(5000, 5100); clear_bit(HPH_COMP_DELAY, &wcd937x->status_mask); } } else { snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_COMP_CTL_0, Loading @@ -411,25 +434,17 @@ static int wcd937x_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, snd_soc_update_bits(codec, WCD937X_HPH_L_EN, 0x20, 0x20); } usleep_range(5000, 5010); snd_soc_update_bits(codec, WCD937X_HPH_NEW_INT_HPH_TIMER1, 0x02, 0x00); wcd_cls_h_fsm(codec, &wcd937x->clsh_info, WCD_CLSH_EVENT_PRE_DAC, WCD_CLSH_STATE_HPHL, hph_mode); break; case SND_SOC_DAPM_POST_PMD: snd_soc_update_bits(codec, WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_L, 0x0F, 0x01); ret = swr_slvdev_datapath_control(wcd937x->rx_swr_dev, wcd937x->rx_swr_dev->dev_num, false); break; } return ret; return 0; } static int wcd937x_codec_hphr_dac_event(struct snd_soc_dapm_widget *w, Loading @@ -439,8 +454,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 wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); int hph_mode = wcd937x->hph_mode; int ret = 0; dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, w->name, event); Loading @@ -454,6 +467,7 @@ static int wcd937x_codec_hphr_dac_event(struct snd_soc_dapm_widget *w, 0x08, 0x08); snd_soc_update_bits(codec, WCD937X_HPH_RDAC_CLK_CTL1, 0x80, 0x00); set_bit(HPH_COMP_DELAY, &wcd937x->status_mask); break; case SND_SOC_DAPM_POST_PMU: if (hph_mode == CLS_AB_HIFI || hph_mode == CLS_H_HIFI) Loading @@ -470,6 +484,22 @@ static int wcd937x_codec_hphr_dac_event(struct snd_soc_dapm_widget *w, 0x01, 0x01); snd_soc_update_bits(codec, WCD937X_HPH_R_EN, 0x20, 0x00); if (wcd937x->comp1_enable) { snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_COMP_CTL_0, 0x02, 0x02); snd_soc_update_bits(codec, WCD937X_HPH_L_EN, 0x20, 0x00); } /* * 5ms sleep is required after COMP is enabled as per * HW requirement */ if (test_bit(HPH_COMP_DELAY, &wcd937x->status_mask)) { usleep_range(5000, 5100); clear_bit(HPH_COMP_DELAY, &wcd937x->status_mask); } } else { snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_COMP_CTL_0, Loading @@ -477,25 +507,17 @@ static int wcd937x_codec_hphr_dac_event(struct snd_soc_dapm_widget *w, snd_soc_update_bits(codec, WCD937X_HPH_R_EN, 0x20, 0x20); } usleep_range(5000, 5010); snd_soc_update_bits(codec, WCD937X_HPH_NEW_INT_HPH_TIMER1, 0x02, 0x00); wcd_cls_h_fsm(codec, &wcd937x->clsh_info, WCD_CLSH_EVENT_PRE_DAC, WCD_CLSH_STATE_HPHR, hph_mode); break; case SND_SOC_DAPM_POST_PMD: snd_soc_update_bits(codec, WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_R, 0x0F, 0x01); ret = swr_slvdev_datapath_control(wcd937x->rx_swr_dev, wcd937x->rx_swr_dev->dev_num, false); break; } return ret; return 0; } static int wcd937x_codec_ear_dac_event(struct snd_soc_dapm_widget *w, Loading @@ -505,7 +527,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 wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); int hph_mode = wcd937x->hph_mode; int ret = 0; dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, w->name, event); Loading Loading @@ -540,12 +561,9 @@ static int wcd937x_codec_ear_dac_event(struct snd_soc_dapm_widget *w, snd_soc_update_bits(codec, WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_L, 0x0F, 0x01); ret = swr_slvdev_datapath_control(wcd937x->rx_swr_dev, wcd937x->rx_swr_dev->dev_num, false); break; }; return ret; return 0; } Loading @@ -556,7 +574,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 wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); int hph_mode = wcd937x->hph_mode; int ret = 0; dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, w->name, event); Loading @@ -577,15 +594,12 @@ static int wcd937x_codec_aux_dac_event(struct snd_soc_dapm_widget *w, break; 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); snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_ANA_CLK_CTL, 0x04, 0x00); break; }; return ret; return 0; } Loading @@ -603,14 +617,31 @@ static int wcd937x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, switch (event) { 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, wcd937x->rx_swr_dev->dev_num, 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); set_bit(HPH_PA_DELAY, &wcd937x->status_mask); break; case SND_SOC_DAPM_POST_PMU: usleep_range(7000, 7010); /* * 7ms sleep is required after PA is enabled as per * HW requirement. If compander is disabled, then * 20ms delay is required. */ if (test_bit(HPH_PA_DELAY, &wcd937x->status_mask)) { if (!wcd937x->comp2_enable) usleep_range(20000, 20100); else usleep_range(7000, 7100); clear_bit(HPH_PA_DELAY, &wcd937x->status_mask); } snd_soc_update_bits(codec, WCD937X_HPH_NEW_INT_HPH_TIMER1, 0x02, 0x02); if (hph_mode == CLS_AB || hph_mode == CLS_AB_HIFI) Loading Loading @@ -654,16 +685,36 @@ static int wcd937x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, int ret = 0; int hph_mode = wcd937x->hph_mode; dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, w->name, event); switch (event) { 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, wcd937x->rx_swr_dev->dev_num, 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); set_bit(HPH_PA_DELAY, &wcd937x->status_mask); break; case SND_SOC_DAPM_POST_PMU: usleep_range(7000, 7010); /* * 7ms sleep is required after PA is enabled as per * HW requirement. If compander is disabled, then * 20ms delay is required. */ if (test_bit(HPH_PA_DELAY, &wcd937x->status_mask)) { if (!wcd937x->comp1_enable) usleep_range(20000, 20100); else usleep_range(7000, 7100); clear_bit(HPH_PA_DELAY, &wcd937x->status_mask); } snd_soc_update_bits(codec, WCD937X_HPH_NEW_INT_HPH_TIMER1, 0x02, 0x02); if (hph_mode == CLS_AB || hph_mode == CLS_AB_HIFI) Loading Loading @@ -805,12 +856,12 @@ static int wcd937x_enable_clsh(struct snd_soc_dapm_widget *w, mode == CLS_H_HIFI || mode == CLS_H_LP) { wcd937x_rx_connect_port(codec, CLSH, SND_SOC_DAPM_EVENT_ON(event)); } if (SND_SOC_DAPM_EVENT_OFF(event)) ret = swr_slvdev_datapath_control( wcd937x->rx_swr_dev, wcd937x->rx_swr_dev->dev_num, false); } return ret; } Loading Loading @@ -1454,6 +1505,12 @@ static int wcd937x_codec_enable_vdd_buck(struct snd_soc_dapm_widget *w, switch (event) { 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, wcd937x->supplies, pdata->regulator, Loading @@ -1464,6 +1521,7 @@ static int wcd937x_codec_enable_vdd_buck(struct snd_soc_dapm_widget *w, __func__); return ret; } clear_bit(ALLOW_BUCK_DISABLE, &wcd937x->status_mask); /* * 200us sleep is required after LDO15 is enabled as per * HW requirement Loading @@ -1471,17 +1529,7 @@ static int wcd937x_codec_enable_vdd_buck(struct snd_soc_dapm_widget *w, usleep_range(200, 250); break; case SND_SOC_DAPM_POST_PMD: ret = msm_cdc_disable_ondemand_supply(wcd937x->dev, 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; } set_bit(ALLOW_BUCK_DISABLE, &wcd937x->status_mask); break; } return 0; Loading Loading @@ -1643,7 +1691,7 @@ static const struct snd_soc_dapm_widget wcd937x_dapm_widgets[] = { wcd937x_codec_enable_vdd_buck, 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, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), Loading Loading @@ -1792,7 +1840,6 @@ static const struct snd_soc_dapm_widget wcd9375_dapm_widgets[] = { }; static const struct snd_soc_dapm_route wcd937x_audio_map[] = { {"ADC1_OUTPUT", NULL, "ADC1_MIXER"}, {"ADC1_MIXER", "Switch", "ADC1 REQ"}, {"ADC1 REQ", NULL, "ADC1"}, Loading @@ -1805,18 +1852,24 @@ static const struct snd_soc_dapm_route wcd937x_audio_map[] = { {"ADC2 MUX", "INP3", "AMIC3"}, {"ADC2 MUX", "INP2", "AMIC2"}, {"IN1_HPHL", NULL, "VDD_BUCK"}, {"IN1_HPHL", NULL, "CLS_H_PORT"}, {"RX1", NULL, "IN1_HPHL"}, {"RDAC1", NULL, "RX1"}, {"HPHL_RDAC", "Switch", "RDAC1"}, {"HPHL PGA", NULL, "HPHL_RDAC"}, {"HPHL", NULL, "HPHL PGA"}, {"IN2_HPHR", NULL, "VDD_BUCK"}, {"IN2_HPHR", NULL, "CLS_H_PORT"}, {"RX2", NULL, "IN2_HPHR"}, {"RDAC2", NULL, "RX2"}, {"HPHR_RDAC", "Switch", "RDAC2"}, {"HPHR PGA", NULL, "HPHR_RDAC"}, {"HPHR", NULL, "HPHR PGA"}, {"IN3_AUX", NULL, "VDD_BUCK"}, {"IN3_AUX", NULL, "CLS_H_PORT"}, {"RX3", NULL, "IN3_AUX"}, {"RDAC4", NULL, "RX3"}, {"AUX_RDAC", "Switch", "RDAC4"}, Loading @@ -1829,16 +1882,6 @@ static const struct snd_soc_dapm_route wcd937x_audio_map[] = { {"EAR_RDAC", "Switch", "RDAC3"}, {"EAR PGA", NULL, "EAR_RDAC"}, {"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[] = { Loading Loading @@ -2097,6 +2140,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) { struct wcd937x_priv *wcd937x = NULL; Loading Loading @@ -2490,6 +2576,15 @@ static int wcd937x_remove(struct platform_device *pdev) 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 = { .probe = wcd937x_probe, .remove = wcd937x_remove, Loading @@ -2497,6 +2592,9 @@ static struct platform_driver wcd937x_codec_driver = { .name = "wcd937x_codec", .owner = THIS_MODULE, .of_match_table = of_match_ptr(wcd937x_dt_match), #ifdef CONFIG_PM_SLEEP .pm = &wcd937x_dev_pm_ops, #endif }, }; Loading Loading
asoc/codecs/bolero/rx-macro.c +16 −10 Original line number Diff line number Diff line Loading @@ -1413,8 +1413,6 @@ static int rx_macro_config_compander(struct snd_soc_codec *codec, if (SND_SOC_DAPM_EVENT_OFF(event)) { 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, 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, 0x04, 0x00); } Loading Loading @@ -2021,7 +2019,7 @@ static void rx_macro_hphdelay_lutbypass(struct snd_soc_codec *codec, static int rx_macro_enable_interp_clk(struct snd_soc_codec *codec, 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 rx_macro_priv *rx_priv = NULL; Loading @@ -2035,13 +2033,19 @@ static int rx_macro_enable_interp_clk(struct snd_soc_codec *codec, main_reg = BOLERO_CDC_RX_RX0_RX_PATH_CTL + (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 (rx_priv->main_clk_users[interp_idx] == 0) { snd_soc_update_bits(codec, dsm_reg, 0x01, 0x01); /* Main path PGA mute enable */ snd_soc_update_bits(codec, main_reg, 0x10, 0x10); /* Clk enable */ 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, interp_idx, event); if (rx_priv->hph_hd2_mode) Loading @@ -2063,6 +2067,15 @@ static int rx_macro_enable_interp_clk(struct snd_soc_codec *codec, rx_priv->main_clk_users[interp_idx]--; if (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, interp_idx, event); rx_macro_config_compander(codec, rx_priv, Loading @@ -2076,13 +2089,6 @@ static int rx_macro_enable_interp_clk(struct snd_soc_codec *codec, rx_macro_hd2_control(codec, interp_idx, event); rx_macro_idle_detect_control(codec, rx_priv, 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); } } Loading
asoc/codecs/wcd937x/internal.h +2 −0 Original line number Diff line number Diff line Loading @@ -68,6 +68,8 @@ struct wcd937x_priv { struct wcd_irq_info irq_info; u32 rx_clk_cnt; int num_irq_regs; /* to track the status */ unsigned long status_mask; u8 num_tx_ports; u8 num_rx_ports; Loading
asoc/codecs/wcd937x/wcd937x.c +165 −67 Original line number Diff line number Diff line Loading @@ -18,10 +18,11 @@ #include <linux/delay.h> #include <linux/kernel.h> #include <linux/component.h> #include <linux/regmap.h> #include <linux/pm_runtime.h> #include <sound/soc.h> #include <sound/tlv.h> #include <soc/soundwire.h> #include <linux/regmap.h> #include <sound/soc.h> #include <sound/soc-dapm.h> #include "internal.h" Loading @@ -45,6 +46,12 @@ enum { CODEC_RX, }; enum { ALLOW_BUCK_DISABLE, HPH_COMP_DELAY, HPH_PA_DELAY, }; static const DECLARE_TLV_DB_SCALE(line_gain, 0, 7, 1); static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1); Loading Loading @@ -374,7 +381,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 wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); int hph_mode = wcd937x->hph_mode; int ret = 0; dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, w->name, event); Loading @@ -388,6 +394,7 @@ static int wcd937x_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, 0x04, 0x04); snd_soc_update_bits(codec, WCD937X_HPH_RDAC_CLK_CTL1, 0x80, 0x00); set_bit(HPH_COMP_DELAY, &wcd937x->status_mask); break; case SND_SOC_DAPM_POST_PMU: if (hph_mode == CLS_AB_HIFI || hph_mode == CLS_H_HIFI) Loading @@ -404,6 +411,22 @@ static int wcd937x_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, 0x02, 0x02); snd_soc_update_bits(codec, WCD937X_HPH_L_EN, 0x20, 0x00); if (wcd937x->comp2_enable) { snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_COMP_CTL_0, 0x01, 0x01); snd_soc_update_bits(codec, WCD937X_HPH_R_EN, 0x20, 0x00); } /* * 5ms sleep is required after COMP is enabled as per * HW requirement */ if (test_bit(HPH_COMP_DELAY, &wcd937x->status_mask)) { usleep_range(5000, 5100); clear_bit(HPH_COMP_DELAY, &wcd937x->status_mask); } } else { snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_COMP_CTL_0, Loading @@ -411,25 +434,17 @@ static int wcd937x_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, snd_soc_update_bits(codec, WCD937X_HPH_L_EN, 0x20, 0x20); } usleep_range(5000, 5010); snd_soc_update_bits(codec, WCD937X_HPH_NEW_INT_HPH_TIMER1, 0x02, 0x00); wcd_cls_h_fsm(codec, &wcd937x->clsh_info, WCD_CLSH_EVENT_PRE_DAC, WCD_CLSH_STATE_HPHL, hph_mode); break; case SND_SOC_DAPM_POST_PMD: snd_soc_update_bits(codec, WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_L, 0x0F, 0x01); ret = swr_slvdev_datapath_control(wcd937x->rx_swr_dev, wcd937x->rx_swr_dev->dev_num, false); break; } return ret; return 0; } static int wcd937x_codec_hphr_dac_event(struct snd_soc_dapm_widget *w, Loading @@ -439,8 +454,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 wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); int hph_mode = wcd937x->hph_mode; int ret = 0; dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, w->name, event); Loading @@ -454,6 +467,7 @@ static int wcd937x_codec_hphr_dac_event(struct snd_soc_dapm_widget *w, 0x08, 0x08); snd_soc_update_bits(codec, WCD937X_HPH_RDAC_CLK_CTL1, 0x80, 0x00); set_bit(HPH_COMP_DELAY, &wcd937x->status_mask); break; case SND_SOC_DAPM_POST_PMU: if (hph_mode == CLS_AB_HIFI || hph_mode == CLS_H_HIFI) Loading @@ -470,6 +484,22 @@ static int wcd937x_codec_hphr_dac_event(struct snd_soc_dapm_widget *w, 0x01, 0x01); snd_soc_update_bits(codec, WCD937X_HPH_R_EN, 0x20, 0x00); if (wcd937x->comp1_enable) { snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_COMP_CTL_0, 0x02, 0x02); snd_soc_update_bits(codec, WCD937X_HPH_L_EN, 0x20, 0x00); } /* * 5ms sleep is required after COMP is enabled as per * HW requirement */ if (test_bit(HPH_COMP_DELAY, &wcd937x->status_mask)) { usleep_range(5000, 5100); clear_bit(HPH_COMP_DELAY, &wcd937x->status_mask); } } else { snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_COMP_CTL_0, Loading @@ -477,25 +507,17 @@ static int wcd937x_codec_hphr_dac_event(struct snd_soc_dapm_widget *w, snd_soc_update_bits(codec, WCD937X_HPH_R_EN, 0x20, 0x20); } usleep_range(5000, 5010); snd_soc_update_bits(codec, WCD937X_HPH_NEW_INT_HPH_TIMER1, 0x02, 0x00); wcd_cls_h_fsm(codec, &wcd937x->clsh_info, WCD_CLSH_EVENT_PRE_DAC, WCD_CLSH_STATE_HPHR, hph_mode); break; case SND_SOC_DAPM_POST_PMD: snd_soc_update_bits(codec, WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_R, 0x0F, 0x01); ret = swr_slvdev_datapath_control(wcd937x->rx_swr_dev, wcd937x->rx_swr_dev->dev_num, false); break; } return ret; return 0; } static int wcd937x_codec_ear_dac_event(struct snd_soc_dapm_widget *w, Loading @@ -505,7 +527,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 wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); int hph_mode = wcd937x->hph_mode; int ret = 0; dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, w->name, event); Loading Loading @@ -540,12 +561,9 @@ static int wcd937x_codec_ear_dac_event(struct snd_soc_dapm_widget *w, snd_soc_update_bits(codec, WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_L, 0x0F, 0x01); ret = swr_slvdev_datapath_control(wcd937x->rx_swr_dev, wcd937x->rx_swr_dev->dev_num, false); break; }; return ret; return 0; } Loading @@ -556,7 +574,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 wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); int hph_mode = wcd937x->hph_mode; int ret = 0; dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, w->name, event); Loading @@ -577,15 +594,12 @@ static int wcd937x_codec_aux_dac_event(struct snd_soc_dapm_widget *w, break; 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); snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_ANA_CLK_CTL, 0x04, 0x00); break; }; return ret; return 0; } Loading @@ -603,14 +617,31 @@ static int wcd937x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, switch (event) { 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, wcd937x->rx_swr_dev->dev_num, 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); set_bit(HPH_PA_DELAY, &wcd937x->status_mask); break; case SND_SOC_DAPM_POST_PMU: usleep_range(7000, 7010); /* * 7ms sleep is required after PA is enabled as per * HW requirement. If compander is disabled, then * 20ms delay is required. */ if (test_bit(HPH_PA_DELAY, &wcd937x->status_mask)) { if (!wcd937x->comp2_enable) usleep_range(20000, 20100); else usleep_range(7000, 7100); clear_bit(HPH_PA_DELAY, &wcd937x->status_mask); } snd_soc_update_bits(codec, WCD937X_HPH_NEW_INT_HPH_TIMER1, 0x02, 0x02); if (hph_mode == CLS_AB || hph_mode == CLS_AB_HIFI) Loading Loading @@ -654,16 +685,36 @@ static int wcd937x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, int ret = 0; int hph_mode = wcd937x->hph_mode; dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, w->name, event); switch (event) { 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, wcd937x->rx_swr_dev->dev_num, 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); set_bit(HPH_PA_DELAY, &wcd937x->status_mask); break; case SND_SOC_DAPM_POST_PMU: usleep_range(7000, 7010); /* * 7ms sleep is required after PA is enabled as per * HW requirement. If compander is disabled, then * 20ms delay is required. */ if (test_bit(HPH_PA_DELAY, &wcd937x->status_mask)) { if (!wcd937x->comp1_enable) usleep_range(20000, 20100); else usleep_range(7000, 7100); clear_bit(HPH_PA_DELAY, &wcd937x->status_mask); } snd_soc_update_bits(codec, WCD937X_HPH_NEW_INT_HPH_TIMER1, 0x02, 0x02); if (hph_mode == CLS_AB || hph_mode == CLS_AB_HIFI) Loading Loading @@ -805,12 +856,12 @@ static int wcd937x_enable_clsh(struct snd_soc_dapm_widget *w, mode == CLS_H_HIFI || mode == CLS_H_LP) { wcd937x_rx_connect_port(codec, CLSH, SND_SOC_DAPM_EVENT_ON(event)); } if (SND_SOC_DAPM_EVENT_OFF(event)) ret = swr_slvdev_datapath_control( wcd937x->rx_swr_dev, wcd937x->rx_swr_dev->dev_num, false); } return ret; } Loading Loading @@ -1454,6 +1505,12 @@ static int wcd937x_codec_enable_vdd_buck(struct snd_soc_dapm_widget *w, switch (event) { 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, wcd937x->supplies, pdata->regulator, Loading @@ -1464,6 +1521,7 @@ static int wcd937x_codec_enable_vdd_buck(struct snd_soc_dapm_widget *w, __func__); return ret; } clear_bit(ALLOW_BUCK_DISABLE, &wcd937x->status_mask); /* * 200us sleep is required after LDO15 is enabled as per * HW requirement Loading @@ -1471,17 +1529,7 @@ static int wcd937x_codec_enable_vdd_buck(struct snd_soc_dapm_widget *w, usleep_range(200, 250); break; case SND_SOC_DAPM_POST_PMD: ret = msm_cdc_disable_ondemand_supply(wcd937x->dev, 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; } set_bit(ALLOW_BUCK_DISABLE, &wcd937x->status_mask); break; } return 0; Loading Loading @@ -1643,7 +1691,7 @@ static const struct snd_soc_dapm_widget wcd937x_dapm_widgets[] = { wcd937x_codec_enable_vdd_buck, 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, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), Loading Loading @@ -1792,7 +1840,6 @@ static const struct snd_soc_dapm_widget wcd9375_dapm_widgets[] = { }; static const struct snd_soc_dapm_route wcd937x_audio_map[] = { {"ADC1_OUTPUT", NULL, "ADC1_MIXER"}, {"ADC1_MIXER", "Switch", "ADC1 REQ"}, {"ADC1 REQ", NULL, "ADC1"}, Loading @@ -1805,18 +1852,24 @@ static const struct snd_soc_dapm_route wcd937x_audio_map[] = { {"ADC2 MUX", "INP3", "AMIC3"}, {"ADC2 MUX", "INP2", "AMIC2"}, {"IN1_HPHL", NULL, "VDD_BUCK"}, {"IN1_HPHL", NULL, "CLS_H_PORT"}, {"RX1", NULL, "IN1_HPHL"}, {"RDAC1", NULL, "RX1"}, {"HPHL_RDAC", "Switch", "RDAC1"}, {"HPHL PGA", NULL, "HPHL_RDAC"}, {"HPHL", NULL, "HPHL PGA"}, {"IN2_HPHR", NULL, "VDD_BUCK"}, {"IN2_HPHR", NULL, "CLS_H_PORT"}, {"RX2", NULL, "IN2_HPHR"}, {"RDAC2", NULL, "RX2"}, {"HPHR_RDAC", "Switch", "RDAC2"}, {"HPHR PGA", NULL, "HPHR_RDAC"}, {"HPHR", NULL, "HPHR PGA"}, {"IN3_AUX", NULL, "VDD_BUCK"}, {"IN3_AUX", NULL, "CLS_H_PORT"}, {"RX3", NULL, "IN3_AUX"}, {"RDAC4", NULL, "RX3"}, {"AUX_RDAC", "Switch", "RDAC4"}, Loading @@ -1829,16 +1882,6 @@ static const struct snd_soc_dapm_route wcd937x_audio_map[] = { {"EAR_RDAC", "Switch", "RDAC3"}, {"EAR PGA", NULL, "EAR_RDAC"}, {"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[] = { Loading Loading @@ -2097,6 +2140,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) { struct wcd937x_priv *wcd937x = NULL; Loading Loading @@ -2490,6 +2576,15 @@ static int wcd937x_remove(struct platform_device *pdev) 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 = { .probe = wcd937x_probe, .remove = wcd937x_remove, Loading @@ -2497,6 +2592,9 @@ static struct platform_driver wcd937x_codec_driver = { .name = "wcd937x_codec", .owner = THIS_MODULE, .of_match_table = of_match_ptr(wcd937x_dt_match), #ifdef CONFIG_PM_SLEEP .pm = &wcd937x_dev_pm_ops, #endif }, }; Loading