ASoC: wcd9xxx: Apply class H parameters based on impedance
Different headphones have different impedance that results in volume level
difference on ears as lower impedance headphone will have higher
volume with the same gain on PAs.
To get better output on headset configure class H controller
based on the impedance detected.
Change-Id: Ia4d62120e57122a52ec0030f7e883cbeb284631b
Signed-off-by: Santosh Mardi <gsantosh@codeaurora.org>
diff --git a/sound/soc/codecs/wcd9320.c b/sound/soc/codecs/wcd9320.c
index 03de4e0..59354a3 100644
--- a/sound/soc/codecs/wcd9320.c
+++ b/sound/soc/codecs/wcd9320.c
@@ -3096,6 +3096,8 @@
{
struct snd_soc_codec *codec = w->codec;
struct taiko_priv *taiko_p = snd_soc_codec_get_drvdata(codec);
+ uint32_t impedl, impedr;
+ int ret = 0;
pr_debug("%s %s %d\n", __func__, w->name, event);
@@ -3107,6 +3109,13 @@
WCD9XXX_CLSH_STATE_HPHL,
WCD9XXX_CLSH_REQ_ENABLE,
WCD9XXX_CLSH_EVENT_PRE_DAC);
+ ret = wcd9xxx_mbhc_get_impedance(&taiko_p->mbhc,
+ &impedl, &impedr);
+ if (!ret)
+ wcd9xxx_clsh_imped_config(codec, impedl);
+ else
+ dev_err(codec->dev, "Failed to get mbhc impedance %d\n",
+ ret);
break;
case SND_SOC_DAPM_POST_PMD:
snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_RDAC_CLK_EN_CTL,
diff --git a/sound/soc/codecs/wcd9xxx-common.c b/sound/soc/codecs/wcd9xxx-common.c
index bfd66ea..d00b843 100644
--- a/sound/soc/codecs/wcd9xxx-common.c
+++ b/sound/soc/codecs/wcd9xxx-common.c
@@ -30,6 +30,387 @@
#define BUCK_SETTLE_TIME_US 50
#define NCP_SETTLE_TIME_US 50
+#define MAX_IMPED_PARAMS 13
+
+struct wcd9xxx_imped_val {
+ u32 imped_val;
+ u8 index;
+};
+
+static const struct wcd9xxx_reg_mask_val imped_table[][MAX_IMPED_PARAMS] = {
+ {
+ {WCD9XXX_A_CDC_CLSH_I_PA_FACT_HPH_L, 0xff, 0x46},
+ {WCD9XXX_A_CDC_CLSH_I_PA_FACT_HPH_U, 0xff, 0x04},
+ {WCD9XXX_A_CDC_CLSH_K_ADDR, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x11},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x02},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x9B},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x02},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x15},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x01},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x1C},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x01},
+ {WCD9XXX_A_CDC_CLSH_IDLE_HPH_THSD, 0xff, 0x04},
+ {WCD9XXX_A_CDC_CLSH_FCLKONLY_HPH_THSD, 0xff, 0x0C},
+ },
+ {
+ {WCD9XXX_A_CDC_CLSH_I_PA_FACT_HPH_L, 0xff, 0x47},
+ {WCD9XXX_A_CDC_CLSH_I_PA_FACT_HPH_U, 0xff, 0x05},
+ {WCD9XXX_A_CDC_CLSH_K_ADDR, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x11},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x02},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x9B},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x02},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x15},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x01},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x1C},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x01},
+ {WCD9XXX_A_CDC_CLSH_IDLE_HPH_THSD, 0xff, 0x05},
+ {WCD9XXX_A_CDC_CLSH_FCLKONLY_HPH_THSD, 0xff, 0x0C},
+ },
+ {
+ {WCD9XXX_A_CDC_CLSH_I_PA_FACT_HPH_L, 0xff, 0x49},
+ {WCD9XXX_A_CDC_CLSH_I_PA_FACT_HPH_U, 0xff, 0x07},
+ {WCD9XXX_A_CDC_CLSH_K_ADDR, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x02},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x12},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x01},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x35},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x01},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x4E},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x01},
+ {WCD9XXX_A_CDC_CLSH_IDLE_HPH_THSD, 0xff, 0x06},
+ {WCD9XXX_A_CDC_CLSH_FCLKONLY_HPH_THSD, 0xff, 0x0E},
+ },
+ {
+ {WCD9XXX_A_CDC_CLSH_I_PA_FACT_HPH_L, 0xff, 0x49},
+ {WCD9XXX_A_CDC_CLSH_I_PA_FACT_HPH_U, 0xff, 0x16},
+ {WCD9XXX_A_CDC_CLSH_K_ADDR, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0xAC},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x02},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x17},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x01},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x5F},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x01},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0xCF},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x01},
+ {WCD9XXX_A_CDC_CLSH_IDLE_HPH_THSD, 0xff, 0x06},
+ {WCD9XXX_A_CDC_CLSH_FCLKONLY_HPH_THSD, 0xff, 0x0F},
+ },
+ {
+ {WCD9XXX_A_CDC_CLSH_I_PA_FACT_HPH_L, 0xff, 0x59},
+ {WCD9XXX_A_CDC_CLSH_I_PA_FACT_HPH_U, 0xff, 0x15},
+ {WCD9XXX_A_CDC_CLSH_K_ADDR, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x9C},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x02},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x1B},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x01},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0xCE},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x01},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0xBD},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x01},
+ {WCD9XXX_A_CDC_CLSH_IDLE_HPH_THSD, 0xff, 0x07},
+ {WCD9XXX_A_CDC_CLSH_FCLKONLY_HPH_THSD, 0xff, 0x10},
+ },
+ {
+ {WCD9XXX_A_CDC_CLSH_I_PA_FACT_HPH_L, 0xff, 0x66},
+ {WCD9XXX_A_CDC_CLSH_I_PA_FACT_HPH_U, 0xff, 0x04},
+ {WCD9XXX_A_CDC_CLSH_K_ADDR, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x9A},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x02},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x2E},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x01},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0xBD},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x01},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0xA6},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x01},
+ {WCD9XXX_A_CDC_CLSH_IDLE_HPH_THSD, 0xff, 0x07},
+ {WCD9XXX_A_CDC_CLSH_FCLKONLY_HPH_THSD, 0xff, 0x11},
+ },
+ {
+ {WCD9XXX_A_CDC_CLSH_I_PA_FACT_HPH_L, 0xff, 0x79},
+ {WCD9XXX_A_CDC_CLSH_I_PA_FACT_HPH_U, 0xff, 0x04},
+ {WCD9XXX_A_CDC_CLSH_K_ADDR, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x11},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x01},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x37},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x01},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0xA6},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x01},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0xAD},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x01},
+ {WCD9XXX_A_CDC_CLSH_IDLE_HPH_THSD, 0xff, 0x08},
+ {WCD9XXX_A_CDC_CLSH_FCLKONLY_HPH_THSD, 0xff, 0x12},
+ },
+ {
+ {WCD9XXX_A_CDC_CLSH_I_PA_FACT_HPH_L, 0xff, 0x76},
+ {WCD9XXX_A_CDC_CLSH_I_PA_FACT_HPH_U, 0xff, 0x04},
+ {WCD9XXX_A_CDC_CLSH_K_ADDR, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x11},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x01},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x4E},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x01},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0xAD},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x01},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0xAC},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x01},
+ {WCD9XXX_A_CDC_CLSH_IDLE_HPH_THSD, 0xff, 0x09},
+ {WCD9XXX_A_CDC_CLSH_FCLKONLY_HPH_THSD, 0xff, 0x12},
+ },
+ {
+ {WCD9XXX_A_CDC_CLSH_I_PA_FACT_HPH_L, 0xff, 0x78},
+ {WCD9XXX_A_CDC_CLSH_I_PA_FACT_HPH_U, 0xff, 0x05},
+ {WCD9XXX_A_CDC_CLSH_K_ADDR, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x12},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x01},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0xD0},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x01},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0xAC},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x01},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x13},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_IDLE_HPH_THSD, 0xff, 0x0A},
+ {WCD9XXX_A_CDC_CLSH_FCLKONLY_HPH_THSD, 0xff, 0x13},
+ },
+ {
+ {WCD9XXX_A_CDC_CLSH_I_PA_FACT_HPH_L, 0xff, 0x7A},
+ {WCD9XXX_A_CDC_CLSH_I_PA_FACT_HPH_U, 0xff, 0x06},
+ {WCD9XXX_A_CDC_CLSH_K_ADDR, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x14},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x01},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0xB7},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x01},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x13},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x01},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x14},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_IDLE_HPH_THSD, 0xff, 0x0B},
+ {WCD9XXX_A_CDC_CLSH_FCLKONLY_HPH_THSD, 0xff, 0x14},
+ },
+ {
+ {WCD9XXX_A_CDC_CLSH_I_PA_FACT_HPH_L, 0xff, 0x60},
+ {WCD9XXX_A_CDC_CLSH_I_PA_FACT_HPH_U, 0xff, 0x09},
+ {WCD9XXX_A_CDC_CLSH_K_ADDR, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x1C},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x01},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0xA4},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x01},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x14},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x1F},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_IDLE_HPH_THSD, 0xff, 0x0C},
+ {WCD9XXX_A_CDC_CLSH_FCLKONLY_HPH_THSD, 0xff, 0x14},
+ },
+ {
+ {WCD9XXX_A_CDC_CLSH_I_PA_FACT_HPH_L, 0xff, 0x79},
+ {WCD9XXX_A_CDC_CLSH_I_PA_FACT_HPH_U, 0xff, 0x17},
+ {WCD9XXX_A_CDC_CLSH_K_ADDR, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x25},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x01},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0xAE},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x01},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x1F},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x1D},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_IDLE_HPH_THSD, 0xff, 0x0D},
+ {WCD9XXX_A_CDC_CLSH_FCLKONLY_HPH_THSD, 0xff, 0x15},
+ },
+ {
+ {WCD9XXX_A_CDC_CLSH_I_PA_FACT_HPH_L, 0xff, 0x78},
+ {WCD9XXX_A_CDC_CLSH_I_PA_FACT_HPH_U, 0xff, 0x16},
+ {WCD9XXX_A_CDC_CLSH_K_ADDR, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x2C},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x01},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0xAC},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x01},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x1D},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x1C},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_IDLE_HPH_THSD, 0xff, 0x0E},
+ {WCD9XXX_A_CDC_CLSH_FCLKONLY_HPH_THSD, 0xff, 0x16},
+ },
+ {
+ {WCD9XXX_A_CDC_CLSH_I_PA_FACT_HPH_L, 0xff, 0x89},
+ {WCD9XXX_A_CDC_CLSH_I_PA_FACT_HPH_U, 0xff, 0x05},
+ {WCD9XXX_A_CDC_CLSH_K_ADDR, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x40},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x01},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x13},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x1C},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x1B},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_IDLE_HPH_THSD, 0xff, 0x10},
+ {WCD9XXX_A_CDC_CLSH_FCLKONLY_HPH_THSD, 0xff, 0x16},
+ },
+ {
+ {WCD9XXX_A_CDC_CLSH_I_PA_FACT_HPH_L, 0xff, 0x97},
+ {WCD9XXX_A_CDC_CLSH_I_PA_FACT_HPH_U, 0xff, 0x05},
+ {WCD9XXX_A_CDC_CLSH_K_ADDR, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0xD0},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x01},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x14},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x1B},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x1B},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_IDLE_HPH_THSD, 0xff, 0x12},
+ {WCD9XXX_A_CDC_CLSH_FCLKONLY_HPH_THSD, 0xff, 0x17},
+ },
+ {
+ {WCD9XXX_A_CDC_CLSH_I_PA_FACT_HPH_L, 0xff, 0x8A},
+ {WCD9XXX_A_CDC_CLSH_I_PA_FACT_HPH_U, 0xff, 0x06},
+ {WCD9XXX_A_CDC_CLSH_K_ADDR, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0xB7},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x01},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x10},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x1B},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x24},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_IDLE_HPH_THSD, 0xff, 0x13},
+ {WCD9XXX_A_CDC_CLSH_FCLKONLY_HPH_THSD, 0xff, 0x17},
+ },
+ {
+ {WCD9XXX_A_CDC_CLSH_I_PA_FACT_HPH_L, 0xff, 0x8A},
+ {WCD9XXX_A_CDC_CLSH_I_PA_FACT_HPH_U, 0xff, 0x07},
+ {WCD9XXX_A_CDC_CLSH_K_ADDR, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0xA4},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x01},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x1D},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x24},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x25},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_IDLE_HPH_THSD, 0xff, 0x15},
+ {WCD9XXX_A_CDC_CLSH_FCLKONLY_HPH_THSD, 0xff, 0x18},
+ },
+ {
+ {WCD9XXX_A_CDC_CLSH_I_PA_FACT_HPH_L, 0xff, 0x9A},
+ {WCD9XXX_A_CDC_CLSH_I_PA_FACT_HPH_U, 0xff, 0x08},
+ {WCD9XXX_A_CDC_CLSH_K_ADDR, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0xAE},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x01},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x1C},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x25},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x27},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_IDLE_HPH_THSD, 0xff, 0x18},
+ {WCD9XXX_A_CDC_CLSH_FCLKONLY_HPH_THSD, 0xff, 0x19},
+ },
+ {
+ {WCD9XXX_A_CDC_CLSH_I_PA_FACT_HPH_L, 0xff, 0x8B},
+ {WCD9XXX_A_CDC_CLSH_I_PA_FACT_HPH_U, 0xff, 0x18},
+ {WCD9XXX_A_CDC_CLSH_K_ADDR, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0xAC},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x01},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x1B},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x20},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x2E},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_IDLE_HPH_THSD, 0xff, 0x1A},
+ {WCD9XXX_A_CDC_CLSH_FCLKONLY_HPH_THSD, 0xff, 0x19},
+ },
+ {
+ {WCD9XXX_A_CDC_CLSH_I_PA_FACT_HPH_L, 0xff, 0x9A},
+ {WCD9XXX_A_CDC_CLSH_I_PA_FACT_HPH_U, 0xff, 0x17},
+ {WCD9XXX_A_CDC_CLSH_K_ADDR, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x13},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x1B},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x2E},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x2D},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_IDLE_HPH_THSD, 0xff, 0x1D},
+ {WCD9XXX_A_CDC_CLSH_FCLKONLY_HPH_THSD, 0xff, 0x1A},
+ },
+ {
+ {WCD9XXX_A_CDC_CLSH_I_PA_FACT_HPH_L, 0xff, 0xA9},
+ {WCD9XXX_A_CDC_CLSH_I_PA_FACT_HPH_U, 0xff, 0x06},
+ {WCD9XXX_A_CDC_CLSH_K_ADDR, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x14},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x24},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x2D},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x2C},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_IDLE_HPH_THSD, 0xff, 0x1F},
+ {WCD9XXX_A_CDC_CLSH_FCLKONLY_HPH_THSD, 0xff, 0x19},
+ },
+ {
+ {WCD9XXX_A_CDC_CLSH_I_PA_FACT_HPH_L, 0xff, 0xB9},
+ {WCD9XXX_A_CDC_CLSH_I_PA_FACT_HPH_U, 0xff, 0x06},
+ {WCD9XXX_A_CDC_CLSH_K_ADDR, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x10},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x25},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x2C},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x2C},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_IDLE_HPH_THSD, 0xff, 0x23},
+ {WCD9XXX_A_CDC_CLSH_FCLKONLY_HPH_THSD, 0xff, 0x18},
+ },
+ {
+ {WCD9XXX_A_CDC_CLSH_I_PA_FACT_HPH_L, 0xff, 0xA9},
+ {WCD9XXX_A_CDC_CLSH_I_PA_FACT_HPH_U, 0xff, 0x07},
+ {WCD9XXX_A_CDC_CLSH_K_ADDR, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x1D},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x27},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x2C},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x35},
+ {WCD9XXX_A_CDC_CLSH_K_DATA, 0xff, 0x00},
+ {WCD9XXX_A_CDC_CLSH_IDLE_HPH_THSD, 0xff, 0x26},
+ {WCD9XXX_A_CDC_CLSH_FCLKONLY_HPH_THSD, 0xff, 0x16},
+ },
+};
+
+static const struct wcd9xxx_imped_val imped_index[] = {
+ {4000, 0},
+ {4500, 1},
+ {5000, 2},
+ {5500, 3},
+ {6000, 4},
+ {6500, 5},
+ {7000, 6},
+ {7700, 7},
+ {8470, 8},
+ {9317, 9},
+ {10248, 10},
+ {11273, 11},
+ {12400, 12},
+ {13641, 13},
+ {15005, 14},
+ {16505, 15},
+ {18156, 16},
+ {19971, 17},
+ {21969, 18},
+ {24165, 19},
+ {26582, 20},
+ {29240, 21},
+ {32164, 22},
+};
+
static inline void wcd9xxx_enable_clsh_block(
struct snd_soc_codec *codec,
bool on)
@@ -165,6 +546,40 @@
}
}
+static int get_impedance_index(u32 imped)
+{
+ int i = 0;
+ if (imped < imped_index[i].imped_val) {
+ pr_debug("%s, detected impedance is less than 4 Ohm\n",
+ __func__);
+ goto ret;
+ }
+ for (i = 0; i < ARRAY_SIZE(imped_index); i++) {
+ if (imped >= imped_index[i].imped_val &&
+ imped < imped_index[i + 1].imped_val)
+ break;
+ }
+ret:
+ pr_debug("%s: selected impedance index = %d\n",
+ __func__, imped_index[i].index);
+ return imped_index[i].index;
+}
+
+void wcd9xxx_clsh_imped_config(struct snd_soc_codec *codec,
+ int imped)
+{
+ int i = 0;
+ int index = 0;
+ index = get_impedance_index(imped);
+ if (index > ARRAY_SIZE(imped_index)) {
+ pr_err("%s, invalid imped = %d\n", __func__, imped);
+ return;
+ }
+ for (i = 0; i < MAX_IMPED_PARAMS; i++)
+ snd_soc_write(codec, imped_table[index][i].reg,
+ imped_table[index][i].val);
+}
+
static void wcd9xxx_clsh_comp_req(struct snd_soc_codec *codec,
struct wcd9xxx_clsh_cdc_data *clsh_d,
int compute_pa, bool on)
diff --git a/sound/soc/codecs/wcd9xxx-common.h b/sound/soc/codecs/wcd9xxx-common.h
index 50381c9..654964e 100644
--- a/sound/soc/codecs/wcd9xxx-common.h
+++ b/sound/soc/codecs/wcd9xxx-common.h
@@ -74,6 +74,9 @@
extern void wcd9xxx_clsh_init(struct wcd9xxx_clsh_cdc_data *clsh,
struct wcd9xxx_resmgr *resmgr);
+extern void wcd9xxx_clsh_imped_config(struct snd_soc_codec *codec,
+ int imped);
+
enum wcd9xxx_codec_event {
WCD9XXX_CODEC_EVENT_CODEC_UP = 0,
};