|
@@ -20,6 +20,7 @@
|
|
|
#include <asoc/wcdcal-hwdep.h>
|
|
|
#include <asoc/msm-cdc-pinctrl.h>
|
|
|
#include <asoc/msm-cdc-supply.h>
|
|
|
+#include <asoc/wcd-mbhc-v2-api.h>
|
|
|
#include <bindings/audio-codec-port-types.h>
|
|
|
#include <linux/qti-regmap-debugfs.h>
|
|
|
#include "wcd939x-registers.h"
|
|
@@ -28,6 +29,9 @@
|
|
|
#include "asoc/bolero-slave-internal.h"
|
|
|
#include "wcd939x-reg-masks.h"
|
|
|
#include "wcd939x-reg-shifts.h"
|
|
|
+#if IS_ENABLED(CONFIG_QCOM_WCD_USBSS_I2C)
|
|
|
+#include <linux/soc/qcom/wcd939x-i2c.h>
|
|
|
+#endif
|
|
|
|
|
|
|
|
|
#define NUM_SWRS_DT_PARAMS 5
|
|
@@ -43,6 +47,8 @@
|
|
|
#define ADC_MODE_VAL_ULP1 0x09
|
|
|
#define ADC_MODE_VAL_ULP2 0x0B
|
|
|
|
|
|
+#define HPH_IMPEDANCE_2VPK_MODE_OHMS 300
|
|
|
+
|
|
|
#define NUM_ATTEMPTS 5
|
|
|
#define COMP_MAX_COEFF 25
|
|
|
#define HPH_MODE_MAX 4
|
|
@@ -74,65 +80,6 @@ value << FIELD_SHIFT(register_name, field_name)
|
|
|
#define WCD939X_XTALK_OFFSET \
|
|
|
(WCD939X_HPHR_RX_PATH_SEC0 - WCD939X_HPHL_RX_PATH_SEC0)
|
|
|
|
|
|
-static struct comp_coeff_val
|
|
|
- comp_coeff_table [HPH_MODE_MAX][COMP_MAX_COEFF] = {
|
|
|
- {
|
|
|
- {0x40, 0x00},
|
|
|
- {0x4C, 0x00},
|
|
|
- {0x5A, 0x00},
|
|
|
- {0x6B, 0x00},
|
|
|
- {0x7F, 0x00},
|
|
|
- {0x97, 0x00},
|
|
|
- {0xB3, 0x00},
|
|
|
- {0xD5, 0x00},
|
|
|
- {0xFD, 0x00},
|
|
|
- {0x2D, 0x01},
|
|
|
- {0x66, 0x01},
|
|
|
- {0xA7, 0x01},
|
|
|
- {0xF8, 0x01},
|
|
|
- {0x57, 0x02},
|
|
|
- {0xC7, 0x02},
|
|
|
- {0x4B, 0x03},
|
|
|
- {0xE9, 0x03},
|
|
|
- {0xA3, 0x04},
|
|
|
- {0x7D, 0x05},
|
|
|
- {0x90, 0x06},
|
|
|
- {0xD1, 0x07},
|
|
|
- {0x49, 0x09},
|
|
|
- {0x00, 0x0B},
|
|
|
- {0x01, 0x0D},
|
|
|
- {0x59, 0x0F},
|
|
|
- },
|
|
|
- {
|
|
|
- /*HPH_HIFI, HPH_LOHIFI, HPH_LP*/
|
|
|
- {0x40, 0x00},
|
|
|
- {0x4C, 0x00},
|
|
|
- {0x5A, 0x00},
|
|
|
- {0x6B, 0x00},
|
|
|
- {0x80, 0x00},
|
|
|
- {0x98, 0x00},
|
|
|
- {0xB4, 0x00},
|
|
|
- {0xD5, 0x00},
|
|
|
- {0xFE, 0x00},
|
|
|
- {0x2E, 0x01},
|
|
|
- {0x66, 0x01},
|
|
|
- {0xA9, 0x01},
|
|
|
- {0xF8, 0x01},
|
|
|
- {0x56, 0x02},
|
|
|
- {0xC4, 0x02},
|
|
|
- {0x4F, 0x03},
|
|
|
- {0xF0, 0x03},
|
|
|
- {0xAE, 0x04},
|
|
|
- {0x8B, 0x05},
|
|
|
- {0x8E, 0x06},
|
|
|
- {0xBC, 0x07},
|
|
|
- {0x56, 0x09},
|
|
|
- {0x0F, 0x0B},
|
|
|
- {0x13, 0x0D},
|
|
|
- {0x6F, 0x0F},
|
|
|
- },
|
|
|
-};
|
|
|
-
|
|
|
enum {
|
|
|
CODEC_TX = 0,
|
|
|
CODEC_RX,
|
|
@@ -197,7 +144,6 @@ static const struct regmap_irq wcd939x_irqs[WCD939X_NUM_IRQS] = {
|
|
|
REGMAP_IRQ_REG(WCD939X_IRQ_HPHL_PDM_WD_INT, 1, 0x20),
|
|
|
REGMAP_IRQ_REG(WCD939X_IRQ_HPHR_PDM_WD_INT, 1, 0x40),
|
|
|
REGMAP_IRQ_REG(WCD939X_IRQ_EAR_PDM_WD_INT, 1, 0x80),
|
|
|
- REGMAP_IRQ_REG(WCD939X_IRQ_LDORT_SCD_INT, 2, 0x01),
|
|
|
REGMAP_IRQ_REG(WCD939X_IRQ_MBHC_MOISTURE_INT, 2, 0x02),
|
|
|
REGMAP_IRQ_REG(WCD939X_IRQ_HPHL_SURGE_DET_INT, 2, 0x04),
|
|
|
REGMAP_IRQ_REG(WCD939X_IRQ_HPHR_SURGE_DET_INT, 2, 0x08),
|
|
@@ -232,25 +178,6 @@ static int wcd939x_handle_post_irq(void *data)
|
|
|
|
|
|
return IRQ_HANDLED;
|
|
|
}
|
|
|
-int wcd939x_load_compander_coeff(struct snd_soc_component *component,
|
|
|
- u16 lsb_reg, u16 msb_reg,
|
|
|
- struct comp_coeff_val *comp_coeff_table,
|
|
|
- u16 arr_size)
|
|
|
-{
|
|
|
- int i = 0;
|
|
|
-
|
|
|
- /* Load Compander Coeff */
|
|
|
- for (i = 0; i < arr_size; i++) {
|
|
|
- snd_soc_component_write(component, lsb_reg,
|
|
|
- comp_coeff_table[i].lsb);
|
|
|
- snd_soc_component_write(component, msb_reg,
|
|
|
- comp_coeff_table[i].msb);
|
|
|
- }
|
|
|
-
|
|
|
- return 0;
|
|
|
-}
|
|
|
-EXPORT_SYMBOL(wcd939x_load_compander_coeff);
|
|
|
-
|
|
|
|
|
|
static int wcd939x_hph_compander_get(struct snd_kcontrol *kcontrol,
|
|
|
struct snd_ctl_elem_value *ucontrol)
|
|
@@ -474,10 +401,23 @@ static int wcd939x_init_reg(struct snd_soc_component *component)
|
|
|
snd_soc_component_update_bits(component,
|
|
|
REG_FIELD_VALUE(TEST_BLK_EN2, TXFE2_MBHC_CLKRST_EN, 0x00));
|
|
|
|
|
|
- snd_soc_component_update_bits(component,
|
|
|
+ if (of_find_property(component->card->dev->of_node, "qcom,wcd-disable-legacy-surge", NULL)) {
|
|
|
+ snd_soc_component_update_bits(component,
|
|
|
+ REG_FIELD_VALUE(HPHLR_SURGE_EN, EN_SURGE_PROTECTION_HPHL, 0x00));
|
|
|
+ snd_soc_component_update_bits(component,
|
|
|
+ REG_FIELD_VALUE(HPHLR_SURGE_EN, EN_SURGE_PROTECTION_HPHR, 0x00));
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ snd_soc_component_update_bits(component,
|
|
|
REG_FIELD_VALUE(HPHLR_SURGE_EN, EN_SURGE_PROTECTION_HPHL, 0x01));
|
|
|
- snd_soc_component_update_bits(component,
|
|
|
+ snd_soc_component_update_bits(component,
|
|
|
REG_FIELD_VALUE(HPHLR_SURGE_EN, EN_SURGE_PROTECTION_HPHR, 0x01));
|
|
|
+ }
|
|
|
+
|
|
|
+ snd_soc_component_update_bits(component,
|
|
|
+ REG_FIELD_VALUE(HPH_OCP_CTL, OCP_FSM_EN, 0x01));
|
|
|
+ snd_soc_component_update_bits(component,
|
|
|
+ REG_FIELD_VALUE(HPH_OCP_CTL, SCD_OP_EN, 0x01));
|
|
|
|
|
|
snd_soc_component_write(component, WCD939X_CFG0, 0x05);
|
|
|
|
|
@@ -955,11 +895,9 @@ static int wcd939x_enable_hph_pcm_index(struct snd_soc_component *component,
|
|
|
static int wcd939x_config_compander(struct snd_soc_component *component,
|
|
|
int event, int compander_indx)
|
|
|
{
|
|
|
- u16 comp_coeff_lsb_reg = 0, comp_coeff_msb_reg = 0;
|
|
|
- u16 comp_ctl7_reg = 0, comp_ctl0_reg = 0;
|
|
|
+ u16 comp_ctl7_reg = 0, comp_ctl0_reg = 0;
|
|
|
u16 comp_en_mask_val = 0;
|
|
|
struct wcd939x_priv *wcd939x;
|
|
|
- int hph_mode;
|
|
|
|
|
|
|
|
|
if (compander_indx >= WCD939X_HPH_MAX || compander_indx < 0) {
|
|
@@ -977,26 +915,20 @@ static int wcd939x_config_compander(struct snd_soc_component *component,
|
|
|
if (!wcd939x->compander_enabled[compander_indx])
|
|
|
return 0;
|
|
|
|
|
|
- hph_mode = wcd939x->hph_mode;
|
|
|
- dev_dbg(component->dev, "%s compander_index = %d hph mode = %d\n",
|
|
|
- __func__, compander_indx, wcd939x->hph_mode);
|
|
|
+ dev_dbg(component->dev, "%s compander_index = %d\n", __func__, compander_indx);
|
|
|
|
|
|
- if (compander_indx == WCD939X_HPHL) {
|
|
|
- comp_coeff_lsb_reg = WCD939X_HPHL_COMP_WR_LSB;
|
|
|
- comp_coeff_msb_reg = WCD939X_HPHL_COMP_WR_MSB;
|
|
|
+ if (compander_indx == WCD939X_HPHL)
|
|
|
comp_en_mask_val = 1 << 1;
|
|
|
- } else if (compander_indx == WCD939X_HPHR) {
|
|
|
- comp_coeff_lsb_reg = WCD939X_HPHR_COMP_WR_LSB;
|
|
|
- comp_coeff_msb_reg = WCD939X_HPHR_COMP_WR_MSB;
|
|
|
+ else if (compander_indx == WCD939X_HPHR)
|
|
|
comp_en_mask_val = 1 << 0;
|
|
|
- } else {
|
|
|
+ else
|
|
|
return 0;
|
|
|
- }
|
|
|
+
|
|
|
|
|
|
comp_ctl0_reg = WCD939X_CTL0 + (compander_indx * WCD939X_COMP_OFFSET);
|
|
|
comp_ctl7_reg = WCD939X_CTL7 + (compander_indx * WCD939X_COMP_OFFSET);
|
|
|
|
|
|
- if (SND_SOC_DAPM_EVENT_ON(event)){
|
|
|
+ if (SND_SOC_DAPM_EVENT_ON(event)) {
|
|
|
|
|
|
snd_soc_component_update_bits(component,
|
|
|
comp_ctl7_reg, 0x1E, 0x00);
|
|
@@ -1011,26 +943,15 @@ static int wcd939x_config_compander(struct snd_soc_component *component,
|
|
|
snd_soc_component_update_bits(component,
|
|
|
comp_ctl0_reg , 0x02, 0x00);
|
|
|
|
|
|
- /* Compander coeff values are same for below modes */
|
|
|
- if (wcd939x->hph_mode == CLS_H_HIFI || wcd939x->hph_mode == CLS_H_LOHIFI
|
|
|
- || wcd939x->hph_mode == CLS_H_LP)
|
|
|
- hph_mode = 1;
|
|
|
- else if (wcd939x->hph_mode == CLS_H_ULP)
|
|
|
- hph_mode = 0;
|
|
|
-
|
|
|
- wcd939x_load_compander_coeff(component, comp_coeff_lsb_reg,
|
|
|
- comp_coeff_msb_reg, comp_coeff_table[hph_mode],
|
|
|
- COMP_MAX_COEFF);
|
|
|
-
|
|
|
/* Enable compander*/
|
|
|
snd_soc_component_update_bits(component,
|
|
|
WCD939X_CDC_COMP_CTL_0, comp_en_mask_val, comp_en_mask_val);
|
|
|
|
|
|
- } if (SND_SOC_DAPM_EVENT_OFF(event)) {
|
|
|
+ } else if (SND_SOC_DAPM_EVENT_OFF(event)) {
|
|
|
snd_soc_component_update_bits(component,
|
|
|
WCD939X_CDC_COMP_CTL_0, comp_en_mask_val, 0x00);
|
|
|
snd_soc_component_update_bits(component,
|
|
|
- comp_ctl0_reg , 0x01, 0x00);
|
|
|
+ comp_ctl0_reg , 0x01, 0x00);
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
@@ -1127,6 +1048,28 @@ static int wcd939x_rx_mux(struct snd_soc_dapm_widget *w,
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static void wcd939x_config_2Vpk_mode(struct snd_soc_component *component,
|
|
|
+ struct wcd939x_priv *wcd939x)
|
|
|
+{
|
|
|
+ uint32_t zl = 0, zr = 0;
|
|
|
+ int rc = wcd_mbhc_get_impedance(&wcd939x->mbhc->wcd_mbhc, &zl, &zr);
|
|
|
+
|
|
|
+ if (rc) {
|
|
|
+ dev_err_ratelimited(component->dev, "%s: Unable to get impedance for 2Vpk mode", __func__);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ snd_soc_component_update_bits(component,
|
|
|
+ REG_FIELD_VALUE(PA_GAIN_CTL_L, RX_SUPPLY_LEVEL, 0x01));
|
|
|
+
|
|
|
+ if (zl < HPH_IMPEDANCE_2VPK_MODE_OHMS)
|
|
|
+ snd_soc_component_update_bits(component,
|
|
|
+ REG_FIELD_VALUE(PA_GAIN_CTL_L, EN_HPHPA_2VPK, 0x00));
|
|
|
+ else
|
|
|
+ snd_soc_component_update_bits(component,
|
|
|
+ REG_FIELD_VALUE(PA_GAIN_CTL_L, EN_HPHPA_2VPK, 0x01));
|
|
|
+}
|
|
|
+
|
|
|
static int wcd939x_codec_hphl_dac_event(struct snd_soc_dapm_widget *w,
|
|
|
struct snd_kcontrol *kcontrol,
|
|
|
int event)
|
|
@@ -1142,6 +1085,9 @@ static int wcd939x_codec_hphl_dac_event(struct snd_soc_dapm_widget *w,
|
|
|
if (!wcd939x->hph_pcm_enabled)
|
|
|
snd_soc_component_update_bits(component,
|
|
|
REG_FIELD_VALUE(RDAC_CLK_CTL1, OPAMP_CHOP_CLK_EN, 0x00));
|
|
|
+ if (wcd939x->in_2Vpk_mode)
|
|
|
+ wcd939x_config_2Vpk_mode(component, wcd939x);
|
|
|
+
|
|
|
snd_soc_component_update_bits(component,
|
|
|
REG_FIELD_VALUE(CDC_HPH_GAIN_CTL, HPHL_RX_EN, 0x01));
|
|
|
break;
|
|
@@ -1196,6 +1142,9 @@ static int wcd939x_codec_hphr_dac_event(struct snd_soc_dapm_widget *w,
|
|
|
if (!wcd939x->hph_pcm_enabled)
|
|
|
snd_soc_component_update_bits(component,
|
|
|
REG_FIELD_VALUE(RDAC_CLK_CTL1, OPAMP_CHOP_CLK_EN, 0x00));
|
|
|
+ if (wcd939x->in_2Vpk_mode)
|
|
|
+ wcd939x_config_2Vpk_mode(component, wcd939x);
|
|
|
+
|
|
|
snd_soc_component_update_bits(component,
|
|
|
REG_FIELD_VALUE(CDC_HPH_GAIN_CTL, HPHR_RX_EN, 0x01));
|
|
|
break;
|
|
@@ -3073,6 +3022,22 @@ static int wcd939x_rx_hph_mode_put(struct snd_kcontrol *kcontrol,
|
|
|
mode_val = CLS_H_ULP;
|
|
|
}
|
|
|
wcd939x->hph_mode = mode_val;
|
|
|
+
|
|
|
+ switch (mode_val) {
|
|
|
+ case CLS_H_HIFI:
|
|
|
+ case CLS_H_LOHIFI:
|
|
|
+ mode_val = 0x4;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ /* set default mode to ULP */
|
|
|
+ mode_val = 0x2;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+#if IS_ENABLED(CONFIG_QCOM_WCD_USBSS_I2C)
|
|
|
+ wcd_usbss_audio_config(NULL, WCD_USBSS_CONFIG_TYPE_POWER_MODE, mode_val);
|
|
|
+#endif
|
|
|
+
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -4351,6 +4316,10 @@ static int wcd939x_soc_codec_probe(struct snd_soc_component *component)
|
|
|
/*Harmonium contains only one variant i.e wcd9395*/
|
|
|
wcd939x->variant = WCD9395;
|
|
|
|
|
|
+ /* Check device tree to see if 2Vpk flag is enabled, this value should not be changed */
|
|
|
+ wcd939x->in_2Vpk_mode = of_find_property(wcd939x->dev->of_node,
|
|
|
+ "qcom,hph-2p15v-mode", NULL) != NULL;
|
|
|
+
|
|
|
wcd939x->fw_data = devm_kzalloc(component->dev,
|
|
|
sizeof(*(wcd939x->fw_data)),
|
|
|
GFP_KERNEL);
|