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
|
||||
|
|
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_CLK_RST_CTRL_MCLK_CONTROL (0xD41)
|
||||
#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
|
|
@ -355,6 +355,7 @@ enum {
|
|||
ANC_MIC_AMIC4,
|
||||
ANC_MIC_AMIC5,
|
||||
ANC_MIC_AMIC6,
|
||||
CLASSH_CONFIG,
|
||||
};
|
||||
|
||||
enum {
|
||||
|
@ -4461,6 +4462,7 @@ static int tasha_codec_hphl_dac_event(struct snd_soc_dapm_widget *w,
|
|||
int hph_mode = tasha->hph_mode;
|
||||
u8 dem_inp;
|
||||
int ret = 0;
|
||||
uint32_t impedl = 0, impedr = 0;
|
||||
|
||||
dev_dbg(codec->dev, "%s wname: %s event: %d hph_mode: %d\n", __func__,
|
||||
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,
|
||||
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;
|
||||
case SND_SOC_DAPM_POST_PMU:
|
||||
/* 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,
|
||||
((hph_mode == CLS_H_LOHIFI) ?
|
||||
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;
|
||||
};
|
||||
|
||||
|
@ -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_RX_BIAS_FLYB_MID_RST, 0xF0, 0x10},
|
||||
{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_R_TEST, 0x01, 0x01},
|
||||
{WCD9335_CDC_BOOST0_BOOST_CFG1, 0x3F, 0x12},
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "wcd9xxx-common-v2.h"
|
||||
|
||||
#define WCD_USLEEP_RANGE 50
|
||||
#define MAX_IMPED_PARAMS 6
|
||||
|
||||
enum {
|
||||
DAC_GAIN_0DB = 0,
|
||||
|
@ -49,10 +50,161 @@ enum {
|
|||
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 *,
|
||||
struct wcd_clsh_cdc_data *,
|
||||
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)
|
||||
{
|
||||
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
|
||||
* 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];
|
||||
} __packed;
|
||||
|
||||
struct wcd_reg_mask_val {
|
||||
u16 reg;
|
||||
u8 mask;
|
||||
u8 val;
|
||||
};
|
||||
|
||||
extern void wcd_clsh_fsm(struct snd_soc_codec *codec,
|
||||
struct wcd_clsh_cdc_data *cdc_clsh_d,
|
||||
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 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 {
|
||||
RESERVED = 0,
|
||||
|
|
Loading…
Add table
Reference in a new issue