ASoC: wcd: change classh settings as per impedance value
Depending on the impedance across HPHL and HPHR, set classh configurations so as to avoid false OCP events. Move wcd9xxx_registers.h to uapi folder, as this header file is used by userspace for wdc9330 codec. CRs-Fixed: 963843 Change-Id: Ie2fb4b75b7f74013580bd3912372c64ddefc734e Signed-off-by: Yeleswarapu Nagaradhesh <nagaradh@codeaurora.org> Signed-off-by: Neema Shetty <nshetty@codeaurora.org>
This commit is contained in:
parent
7eb20e5733
commit
2f2c350993
5 changed files with 193 additions and 2 deletions
|
@ -1 +1,2 @@
|
||||||
|
header-y += wcd9xxx_registers.h
|
||||||
header-y += wcd9320_registers.h
|
header-y += wcd9320_registers.h
|
||||||
|
|
9
include/linux/mfd/wcd9xxx/wcd9xxx_registers.h → include/uapi/linux/mfd/wcd9xxx/wcd9xxx_registers.h
Executable file → Normal file
9
include/linux/mfd/wcd9xxx/wcd9xxx_registers.h → include/uapi/linux/mfd/wcd9xxx/wcd9xxx_registers.h
Executable file → Normal file
|
@ -341,4 +341,13 @@
|
||||||
#define WCD9XXX_CDC_RX2_RX_PATH_CTL (0xB69)
|
#define WCD9XXX_CDC_RX2_RX_PATH_CTL (0xB69)
|
||||||
#define WCD9XXX_CDC_CLK_RST_CTRL_MCLK_CONTROL (0xD41)
|
#define WCD9XXX_CDC_CLK_RST_CTRL_MCLK_CONTROL (0xD41)
|
||||||
#define WCD9XXX_CLASSH_CTRL_CCL_1 (0x69C)
|
#define WCD9XXX_CLASSH_CTRL_CCL_1 (0x69C)
|
||||||
|
|
||||||
|
/* RX Gain control registers of codecs from and above WCD9335 */
|
||||||
|
#define WCD9XXX_CDC_RX1_RX_VOL_CTL (0xB59)
|
||||||
|
#define WCD9XXX_CDC_RX1_RX_VOL_MIX_CTL (0xB5C)
|
||||||
|
#define WCD9XXX_CDC_RX1_RX_PATH_SEC1 (0xB5E)
|
||||||
|
#define WCD9XXX_CDC_RX2_RX_VOL_CTL (0xB6D)
|
||||||
|
#define WCD9XXX_CDC_RX2_RX_VOL_MIX_CTL (0xB70)
|
||||||
|
#define WCD9XXX_CDC_RX2_RX_PATH_SEC1 (0xB72)
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -355,6 +355,7 @@ enum {
|
||||||
ANC_MIC_AMIC4,
|
ANC_MIC_AMIC4,
|
||||||
ANC_MIC_AMIC5,
|
ANC_MIC_AMIC5,
|
||||||
ANC_MIC_AMIC6,
|
ANC_MIC_AMIC6,
|
||||||
|
CLASSH_CONFIG,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
@ -4461,6 +4462,7 @@ static int tasha_codec_hphl_dac_event(struct snd_soc_dapm_widget *w,
|
||||||
int hph_mode = tasha->hph_mode;
|
int hph_mode = tasha->hph_mode;
|
||||||
u8 dem_inp;
|
u8 dem_inp;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
uint32_t impedl = 0, impedr = 0;
|
||||||
|
|
||||||
dev_dbg(codec->dev, "%s wname: %s event: %d hph_mode: %d\n", __func__,
|
dev_dbg(codec->dev, "%s wname: %s event: %d hph_mode: %d\n", __func__,
|
||||||
w->name, event, hph_mode);
|
w->name, event, hph_mode);
|
||||||
|
@ -4494,6 +4496,16 @@ static int tasha_codec_hphl_dac_event(struct snd_soc_dapm_widget *w,
|
||||||
snd_soc_update_bits(codec,
|
snd_soc_update_bits(codec,
|
||||||
WCD9335_CDC_RX1_RX_PATH_CFG0, 0x10, 0x10);
|
WCD9335_CDC_RX1_RX_PATH_CFG0, 0x10, 0x10);
|
||||||
|
|
||||||
|
ret = wcd_mbhc_get_impedance(&tasha->mbhc,
|
||||||
|
&impedl, &impedr);
|
||||||
|
if (!ret) {
|
||||||
|
wcd_clsh_imped_config(codec, impedl, false);
|
||||||
|
set_bit(CLASSH_CONFIG, &tasha->status_mask);
|
||||||
|
} else
|
||||||
|
dev_dbg(codec->dev, "%s: Failed to get mbhc impedance %d\n",
|
||||||
|
__func__, ret);
|
||||||
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case SND_SOC_DAPM_POST_PMU:
|
case SND_SOC_DAPM_POST_PMU:
|
||||||
/* 1000us required as per HW requirement */
|
/* 1000us required as per HW requirement */
|
||||||
|
@ -4523,6 +4535,15 @@ static int tasha_codec_hphl_dac_event(struct snd_soc_dapm_widget *w,
|
||||||
WCD_CLSH_STATE_HPHL,
|
WCD_CLSH_STATE_HPHL,
|
||||||
((hph_mode == CLS_H_LOHIFI) ?
|
((hph_mode == CLS_H_LOHIFI) ?
|
||||||
CLS_H_HIFI : hph_mode));
|
CLS_H_HIFI : hph_mode));
|
||||||
|
|
||||||
|
if (test_bit(CLASSH_CONFIG, &tasha->status_mask)) {
|
||||||
|
wcd_clsh_imped_config(codec, impedl, true);
|
||||||
|
clear_bit(CLASSH_CONFIG, &tasha->status_mask);
|
||||||
|
} else
|
||||||
|
dev_dbg(codec->dev, "%s: Failed to get mbhc impedance %d\n",
|
||||||
|
__func__, ret);
|
||||||
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -11888,7 +11909,7 @@ static const struct tasha_reg_mask_val tasha_codec_reg_init_val_2_0[] = {
|
||||||
{WCD9335_RCO_CTRL_2, 0x0F, 0x08},
|
{WCD9335_RCO_CTRL_2, 0x0F, 0x08},
|
||||||
{WCD9335_RX_BIAS_FLYB_MID_RST, 0xF0, 0x10},
|
{WCD9335_RX_BIAS_FLYB_MID_RST, 0xF0, 0x10},
|
||||||
{WCD9335_FLYBACK_CTRL_1, 0x20, 0x20},
|
{WCD9335_FLYBACK_CTRL_1, 0x20, 0x20},
|
||||||
{WCD9335_HPH_OCP_CTL, 0xFF, 0x5A},
|
{WCD9335_HPH_OCP_CTL, 0xFF, 0x7A},
|
||||||
{WCD9335_HPH_L_TEST, 0x01, 0x01},
|
{WCD9335_HPH_L_TEST, 0x01, 0x01},
|
||||||
{WCD9335_HPH_R_TEST, 0x01, 0x01},
|
{WCD9335_HPH_R_TEST, 0x01, 0x01},
|
||||||
{WCD9335_CDC_BOOST0_BOOST_CFG1, 0x3F, 0x12},
|
{WCD9335_CDC_BOOST0_BOOST_CFG1, 0x3F, 0x12},
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "wcd9xxx-common-v2.h"
|
#include "wcd9xxx-common-v2.h"
|
||||||
|
|
||||||
#define WCD_USLEEP_RANGE 50
|
#define WCD_USLEEP_RANGE 50
|
||||||
|
#define MAX_IMPED_PARAMS 6
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
DAC_GAIN_0DB = 0,
|
DAC_GAIN_0DB = 0,
|
||||||
|
@ -49,10 +50,161 @@ enum {
|
||||||
DELTA_I_50MA,
|
DELTA_I_50MA,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct wcd_imped_val {
|
||||||
|
u32 imped_val;
|
||||||
|
u8 index;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wcd_reg_mask_val imped_table[][MAX_IMPED_PARAMS] = {
|
||||||
|
{
|
||||||
|
{WCD9XXX_CDC_RX1_RX_VOL_CTL, 0xff, 0xf5},
|
||||||
|
{WCD9XXX_CDC_RX1_RX_VOL_MIX_CTL, 0xff, 0xf5},
|
||||||
|
{WCD9XXX_CDC_RX1_RX_PATH_SEC1, 0x01, 0x01},
|
||||||
|
{WCD9XXX_CDC_RX2_RX_VOL_CTL, 0xff, 0xf5},
|
||||||
|
{WCD9XXX_CDC_RX2_RX_VOL_MIX_CTL, 0xff, 0xf5},
|
||||||
|
{WCD9XXX_CDC_RX2_RX_PATH_SEC1, 0x01, 0x01},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{WCD9XXX_CDC_RX1_RX_VOL_CTL, 0xff, 0xf7},
|
||||||
|
{WCD9XXX_CDC_RX1_RX_VOL_MIX_CTL, 0xff, 0xf7},
|
||||||
|
{WCD9XXX_CDC_RX1_RX_PATH_SEC1, 0x01, 0x01},
|
||||||
|
{WCD9XXX_CDC_RX2_RX_VOL_CTL, 0xff, 0xf7},
|
||||||
|
{WCD9XXX_CDC_RX2_RX_VOL_MIX_CTL, 0xff, 0xf7},
|
||||||
|
{WCD9XXX_CDC_RX2_RX_PATH_SEC1, 0x01, 0x01},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{WCD9XXX_CDC_RX1_RX_VOL_CTL, 0xff, 0xf9},
|
||||||
|
{WCD9XXX_CDC_RX1_RX_VOL_MIX_CTL, 0xff, 0xf9},
|
||||||
|
{WCD9XXX_CDC_RX1_RX_PATH_SEC1, 0x01, 0x0},
|
||||||
|
{WCD9XXX_CDC_RX2_RX_VOL_CTL, 0xff, 0xf9},
|
||||||
|
{WCD9XXX_CDC_RX2_RX_VOL_MIX_CTL, 0xff, 0xf9},
|
||||||
|
{WCD9XXX_CDC_RX2_RX_PATH_SEC1, 0x01, 0x0},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{WCD9XXX_CDC_RX1_RX_VOL_CTL, 0xff, 0xfa},
|
||||||
|
{WCD9XXX_CDC_RX1_RX_VOL_MIX_CTL, 0xff, 0xfa},
|
||||||
|
{WCD9XXX_CDC_RX1_RX_PATH_SEC1, 0x01, 0x01},
|
||||||
|
{WCD9XXX_CDC_RX2_RX_VOL_CTL, 0xff, 0xfa},
|
||||||
|
{WCD9XXX_CDC_RX2_RX_VOL_MIX_CTL, 0xff, 0xfa},
|
||||||
|
{WCD9XXX_CDC_RX2_RX_PATH_SEC1, 0x01, 0x01},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{WCD9XXX_CDC_RX1_RX_VOL_CTL, 0xff, 0xfb},
|
||||||
|
{WCD9XXX_CDC_RX1_RX_VOL_MIX_CTL, 0xff, 0xfb},
|
||||||
|
{WCD9XXX_CDC_RX1_RX_PATH_SEC1, 0x01, 0x01},
|
||||||
|
{WCD9XXX_CDC_RX2_RX_VOL_CTL, 0xff, 0xfb},
|
||||||
|
{WCD9XXX_CDC_RX2_RX_VOL_MIX_CTL, 0xff, 0xfb},
|
||||||
|
{WCD9XXX_CDC_RX2_RX_PATH_SEC1, 0x01, 0x01},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{WCD9XXX_CDC_RX1_RX_VOL_CTL, 0xff, 0xfc},
|
||||||
|
{WCD9XXX_CDC_RX1_RX_VOL_MIX_CTL, 0xff, 0xfc},
|
||||||
|
{WCD9XXX_CDC_RX1_RX_PATH_SEC1, 0x01, 0x01},
|
||||||
|
{WCD9XXX_CDC_RX2_RX_VOL_CTL, 0xff, 0xfc},
|
||||||
|
{WCD9XXX_CDC_RX2_RX_VOL_MIX_CTL, 0xff, 0xfc},
|
||||||
|
{WCD9XXX_CDC_RX2_RX_PATH_SEC1, 0x01, 0x01},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{WCD9XXX_CDC_RX1_RX_VOL_CTL, 0xff, 0xfd},
|
||||||
|
{WCD9XXX_CDC_RX1_RX_VOL_MIX_CTL, 0xff, 0xfd},
|
||||||
|
{WCD9XXX_CDC_RX1_RX_PATH_SEC1, 0x01, 0x01},
|
||||||
|
{WCD9XXX_CDC_RX2_RX_VOL_CTL, 0xff, 0xfd},
|
||||||
|
{WCD9XXX_CDC_RX2_RX_VOL_MIX_CTL, 0xff, 0xfd},
|
||||||
|
{WCD9XXX_CDC_RX2_RX_PATH_SEC1, 0x01, 0x01},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{WCD9XXX_CDC_RX1_RX_VOL_CTL, 0xff, 0xfe},
|
||||||
|
{WCD9XXX_CDC_RX1_RX_VOL_MIX_CTL, 0xff, 0xfe},
|
||||||
|
{WCD9XXX_CDC_RX1_RX_PATH_SEC1, 0x01, 0x01},
|
||||||
|
{WCD9XXX_CDC_RX2_RX_VOL_CTL, 0xff, 0xfe},
|
||||||
|
{WCD9XXX_CDC_RX2_RX_VOL_MIX_CTL, 0xff, 0xfe},
|
||||||
|
{WCD9XXX_CDC_RX2_RX_PATH_SEC1, 0x01, 0x01},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{WCD9XXX_CDC_RX1_RX_VOL_CTL, 0xff, 0xff},
|
||||||
|
{WCD9XXX_CDC_RX1_RX_VOL_MIX_CTL, 0xff, 0xff},
|
||||||
|
{WCD9XXX_CDC_RX1_RX_PATH_SEC1, 0x01, 0x00},
|
||||||
|
{WCD9XXX_CDC_RX2_RX_VOL_CTL, 0xff, 0xff},
|
||||||
|
{WCD9XXX_CDC_RX2_RX_VOL_MIX_CTL, 0xff, 0xff},
|
||||||
|
{WCD9XXX_CDC_RX2_RX_PATH_SEC1, 0x01, 0x00},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wcd_imped_val imped_index[] = {
|
||||||
|
{4, 0},
|
||||||
|
{5, 1},
|
||||||
|
{6, 2},
|
||||||
|
{7, 3},
|
||||||
|
{8, 4},
|
||||||
|
{9, 5},
|
||||||
|
{10, 6},
|
||||||
|
{11, 7},
|
||||||
|
{12, 8},
|
||||||
|
{13, 9},
|
||||||
|
};
|
||||||
|
|
||||||
static void (*clsh_state_fp[NUM_CLSH_STATES_V2])(struct snd_soc_codec *,
|
static void (*clsh_state_fp[NUM_CLSH_STATES_V2])(struct snd_soc_codec *,
|
||||||
struct wcd_clsh_cdc_data *,
|
struct wcd_clsh_cdc_data *,
|
||||||
u8 req_state, bool en, int mode);
|
u8 req_state, bool en, int mode);
|
||||||
|
|
||||||
|
static int get_impedance_index(int imped)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
if (imped < imped_index[i].imped_val) {
|
||||||
|
pr_debug("%s, detected impedance is less than 4 Ohm\n",
|
||||||
|
__func__);
|
||||||
|
i = 0;
|
||||||
|
goto ret;
|
||||||
|
}
|
||||||
|
if (imped >= imped_index[ARRAY_SIZE(imped_index) - 1].imped_val) {
|
||||||
|
pr_debug("%s, detected impedance is greater than 12 Ohm\n",
|
||||||
|
__func__);
|
||||||
|
i = ARRAY_SIZE(imped_index) - 1;
|
||||||
|
goto ret;
|
||||||
|
}
|
||||||
|
for (i = 0; i < ARRAY_SIZE(imped_index) - 1; 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Function: wcd_clsh_imped_config
|
||||||
|
* Params: codec, imped, reset
|
||||||
|
* Description:
|
||||||
|
* This function updates HPHL and HPHR gain settings
|
||||||
|
* according to the impedance value.
|
||||||
|
*/
|
||||||
|
void wcd_clsh_imped_config(struct snd_soc_codec *codec, int imped, bool reset)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int index = 0;
|
||||||
|
|
||||||
|
/* reset = 1, which means request is to reset the register values */
|
||||||
|
if (reset) {
|
||||||
|
for (i = 0; i < MAX_IMPED_PARAMS; i++)
|
||||||
|
snd_soc_update_bits(codec, imped_table[index][i].reg,
|
||||||
|
imped_table[index][i].mask, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
index = get_impedance_index(imped);
|
||||||
|
if (index >= (ARRAY_SIZE(imped_index) - 1)) {
|
||||||
|
pr_debug("%s, impedance not in range = %d\n", __func__, imped);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (i = 0; i < MAX_IMPED_PARAMS; i++)
|
||||||
|
snd_soc_update_bits(codec, imped_table[index][i].reg,
|
||||||
|
imped_table[index][i].mask,
|
||||||
|
imped_table[index][i].val);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(wcd_clsh_imped_config);
|
||||||
|
|
||||||
static bool is_native_44_1_active(struct snd_soc_codec *codec)
|
static bool is_native_44_1_active(struct snd_soc_codec *codec)
|
||||||
{
|
{
|
||||||
bool native_active = false;
|
bool native_active = false;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License version 2 and
|
* it under the terms of the GNU General Public License version 2 and
|
||||||
|
@ -136,6 +136,12 @@ struct vbat_monitor_reg {
|
||||||
u32 writes[MAX_VBAT_MONITOR_WRITES];
|
u32 writes[MAX_VBAT_MONITOR_WRITES];
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
|
struct wcd_reg_mask_val {
|
||||||
|
u16 reg;
|
||||||
|
u8 mask;
|
||||||
|
u8 val;
|
||||||
|
};
|
||||||
|
|
||||||
extern void wcd_clsh_fsm(struct snd_soc_codec *codec,
|
extern void wcd_clsh_fsm(struct snd_soc_codec *codec,
|
||||||
struct wcd_clsh_cdc_data *cdc_clsh_d,
|
struct wcd_clsh_cdc_data *cdc_clsh_d,
|
||||||
u8 clsh_event, u8 req_state,
|
u8 clsh_event, u8 req_state,
|
||||||
|
@ -143,6 +149,8 @@ extern void wcd_clsh_fsm(struct snd_soc_codec *codec,
|
||||||
|
|
||||||
extern void wcd_clsh_init(struct wcd_clsh_cdc_data *clsh);
|
extern void wcd_clsh_init(struct wcd_clsh_cdc_data *clsh);
|
||||||
extern int wcd_clsh_get_clsh_state(struct wcd_clsh_cdc_data *clsh);
|
extern int wcd_clsh_get_clsh_state(struct wcd_clsh_cdc_data *clsh);
|
||||||
|
extern void wcd_clsh_imped_config(struct snd_soc_codec *codec, int imped,
|
||||||
|
bool reset);
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
RESERVED = 0,
|
RESERVED = 0,
|
||||||
|
|
Loading…
Add table
Reference in a new issue