asoc: codecs: Add WSA884X DRE Settings

Conforms to latest hardware DRE documentation

Change-Id: Ia08b03f519697723e9e260451c5bc68b4b45724c
Signed-off-by: Matthew Rice <quic_mrice@quicinc.com>
This commit is contained in:
Matthew Rice
2021-11-15 10:29:31 -08:00
parent 1b69ddf3c3
commit b70a4759b3
4 changed files with 391 additions and 49 deletions

View File

@@ -32,21 +32,53 @@
#define WSA884X_VERSION_1_0 0 #define WSA884X_VERSION_1_0 0
enum { enum {
G_21DB = 0, G_21_DB = 0,
G_19P5DB, G_19P5_DB,
G_18DB, G_18_DB,
G_16P5DB, G_16P5_DB,
G_15DB, G_15_DB,
G_13P5DB, G_13P5_DB,
G_12DB, G_12_DB,
G_10P5DB, G_10P5_DB,
G_9DB, G_9_DB,
G_7P5DB, G_7P5_DB,
G_6DB, G_6_DB,
G_4P5DB, G_4P5_DB,
G_3DB, G_3_DB,
G_1P5DB, G_1P5_DB,
G_0DB, G_0_DB,
G_M1P5_DB,
G_M3_DB,
G_M4P5_DB,
G_M6_DB,
G_MAX_DB,
};
enum {
PA_AUX_DISABLE = 0,
PA_AUX_M6_DB = 3,
PA_AUX_M4P5_DB = 4,
PA_AUX_M3_DB = 5,
PA_AUX_M1P5_DB = 6,
PA_AUX_0_DB = 7,
PA_AUX_7P5_DB = 8,
PA_AUX_12_DB = 9,
PA_AUX_18_DB = 0xA,
};
enum {
ISENSE_6_DB = 0,
ISENSE_12_DB,
ISENSE_15_DB,
ISENSE_18_DB
};
enum {
VSENSE_M12_DB = 0,
VSENSE_M15_DB,
VSENSE_M18_DB,
VSENSE_M21_DB,
VSENSE_M24_DB
}; };
enum { enum {
@@ -55,7 +87,7 @@ enum {
}; };
enum { enum {
SWR_DAC_PORT, SWR_DAC_PORT = 0,
SWR_COMP_PORT, SWR_COMP_PORT,
SWR_BOOST_PORT, SWR_BOOST_PORT,
SWR_PBR_PORT, SWR_PBR_PORT,
@@ -109,6 +141,11 @@ struct wsa884x_priv {
int variant; int variant;
int version; int version;
u8 pa_gain; u8 pa_gain;
u8 bat_cfg;
u8 rload;
u8 system_gain;
int min_gain;
int pa_aux_gain;
struct irq_domain *virq; struct irq_domain *virq;
struct wcd_irq_info irq_info; struct wcd_irq_info irq_info;
#ifdef CONFIG_DEBUG_FS #ifdef CONFIG_DEBUG_FS

View File

@@ -22,6 +22,10 @@
#define WSA884X_VSENSE1_VSENSE_AMP_IQ_CTL_1_MASK 0x10 #define WSA884X_VSENSE1_VSENSE_AMP_IQ_CTL_1_MASK 0x10
#define WSA884X_VSENSE1_IDLE_MODE_CTL_MASK 0x0c #define WSA884X_VSENSE1_IDLE_MODE_CTL_MASK 0x0c
#define WSA884X_VSENSE1_VOCM_AMP_CTL_MASK 0x03 #define WSA884X_VSENSE1_VOCM_AMP_CTL_MASK 0x03
/* WSA884X_ISENSE2 Fields: */
#define WSA884X_ISENSE2_ISENSE_GAIN_CTL_MASK 0xe0
#define WSA884X_ISENSE2_SUMAMP_IQ_CTL_MASK 0x10
#define WSA884X_ISENSE2_SPARE_BITS_3_0_MASK 0x0f
/* WSA884X_ADC_2 Fields: */ /* WSA884X_ADC_2 Fields: */
#define WSA884X_ADC_2_ATEST_SEL_CAL_REF_MASK 0x80 #define WSA884X_ADC_2_ATEST_SEL_CAL_REF_MASK 0x80
#define WSA884X_ADC_2_ISNS_LOAD_STORED_MASK 0x40 #define WSA884X_ADC_2_ISNS_LOAD_STORED_MASK 0x40
@@ -123,6 +127,9 @@
/* WSA884X_TADC_VALUE_CTL Fields: */ /* WSA884X_TADC_VALUE_CTL Fields: */
#define WSA884X_TADC_VALUE_CTL_VBAT_VALUE_RD_EN_MASK 0x02 #define WSA884X_TADC_VALUE_CTL_VBAT_VALUE_RD_EN_MASK 0x02
#define WSA884X_TADC_VALUE_CTL_TEMP_VALUE_RD_EN_MASK 0x01 #define WSA884X_TADC_VALUE_CTL_TEMP_VALUE_RD_EN_MASK 0x01
/* WSA884X_CDC_PATH_MODE Fields: */
#define WSA884X_CDC_PATH_MODE_RXD_MODE_MASK 0x02
#define WSA884X_CDC_PATH_MODE_TXD_MODE_MASK 0x01
/* WSA884X_PA_FSM_BYP0 Fields: */ /* WSA884X_PA_FSM_BYP0 Fields: */
#define WSA884X_PA_FSM_BYP0_TSADC_EN_MASK 0x80 #define WSA884X_PA_FSM_BYP0_TSADC_EN_MASK 0x80
#define WSA884X_PA_FSM_BYP0_SPKR_PROT_EN_MASK 0x40 #define WSA884X_PA_FSM_BYP0_SPKR_PROT_EN_MASK 0x40
@@ -152,5 +159,48 @@
#define WSA884X_CHIP_ID2_BYTE_2_MASK 0xff #define WSA884X_CHIP_ID2_BYTE_2_MASK 0xff
/* WSA884X_CHIP_ID3 Fields: */ /* WSA884X_CHIP_ID3 Fields: */
#define WSA884X_CHIP_ID3_BYTE_3_MASK 0xff #define WSA884X_CHIP_ID3_BYTE_3_MASK 0xff
/* WSA884X_OCP_CTL Fields: */
#define WSA884X_OCP_CTL_OCP_EN_MASK 0x80
#define WSA884X_OCP_CTL_OCP_CURR_LIMIT_MASK 0x70
#define WSA884X_OCP_CTL_GLITCH_FILTER_MASK 0x0c
#define WSA884X_OCP_CTL_OCP_P_HS_DLY_CTL_MASK 0x03
/* WSA884X_ILIM_CTRL1 Fields: */
#define WSA884X_ILIM_CTRL1_EN_AUTO_MAXD_SEL_MASK 0x80
#define WSA884X_ILIM_CTRL1_EN_ILIM_SW_CLH_MASK 0x40
#define WSA884X_ILIM_CTRL1_ILIM_OFFSET_CLH_MASK 0x38
#define WSA884X_ILIM_CTRL1_ILIM_OFFSET_PB_MASK 0x07
/* WSA884X_CLSH_CTL_0 Fields: */
#define WSA884X_CLSH_CTL_0_CSR_GAIN_EN_MASK 0x80
#define WSA884X_CLSH_CTL_0_DLY_CODE_MASK 0x70
#define WSA884X_CLSH_CTL_0_DLY_RST_MASK 0x08
#define WSA884X_CLSH_CTL_0_DLY_EN_MASK 0x04
#define WSA884X_CLSH_CTL_0_INPUT_EN_MASK 0x02
#define WSA884X_CLSH_CTL_0_CLSH_EN_MASK 0x01
/* WSA884X_STB_CTRL1 Fields: */
#define WSA884X_STB_CTRL1_SLOPE_COMP_CURRENT_MASK 0xf8
#define WSA884X_STB_CTRL1_VOUT_FS_MASK 0x07
/* WSA884X_OTP_REG_38 Fields: */
#define WSA884X_OTP_REG_38_RESERVER_MASK 0xf0
#define WSA884X_OTP_REG_38_BST_CFG_SEL_MASK 0x08
#define WSA884X_OTP_REG_38_BOOST_ILIM_TUNE_MASK 0x07
/* WSA884X_OTP_REG_40 Fields: */
#define WSA884X_OTP_REG_40_SPARE_TYPE2_MASK 0xc0
#define WSA884X_OTP_REG_40_ISENSE_RESCAL_MASK 0x3c
#define WSA884X_OTP_REG_40_ATE_BOOST_RDSON_TEST_MASK 0x02
#define WSA884X_OTP_REG_40_ATE_CLASSD_RDSON_TEST_MASK 0x01
/* WSA884X_CURRENT_LIMIT Fields: */
#define WSA884X_CURRENT_LIMIT_CURRENT_LIMIT_OVRD_EN_MASK 0x80
#define WSA884X_CURRENT_LIMIT_CURRENT_LIMIT_MASK 0x7c
#define WSA884X_CURRENT_LIMIT_CLK_PHASE_MASK 0x03
/* WSA884X_PWM_CLK_CTL Fields: */
#define WSA884X_PWM_CLK_CTL_VCMO_INT1_IDLE_MODE_OVRT_MASK 0x80
#define WSA884X_PWM_CLK_CTL_REG_MCLK_DIV_RATIO_MASK 0x40
#define WSA884X_PWM_CLK_CTL_PWM_DEGLITCH_CLK_DELAY_CTRL_MASK 0x30
#define WSA884X_PWM_CLK_CTL_PWM_CLK_FREQ_SEL_MASK 0x08
#define WSA884X_PWM_CLK_CTL_PWM_CLK_DIV_RATIO_MASK 0x06
#define WSA884X_PWM_CLK_CTL_PWM_CLK_DIV_BYPASS_MASK 0x01
/* WSA884X_CKWD_CTL_1 Fields: */
#define WSA884X_CKWD_CTL_1_SPARE_BITS_7_6_MASK 0xc0
#define WSA884X_CKWD_CTL_1_VPP_SW_CTL_MASK 0x20
#define WSA884X_CKWD_CTL_1_CKWD_VCOMP_VREF_SEL_MASK 0x1f
#endif /* WSA884X_REG_MASKS_H */ #endif /* WSA884X_REG_MASKS_H */

View File

@@ -22,6 +22,10 @@
#define WSA884X_VSENSE1_VSENSE_AMP_IQ_CTL_1_SHIFT 0x04 #define WSA884X_VSENSE1_VSENSE_AMP_IQ_CTL_1_SHIFT 0x04
#define WSA884X_VSENSE1_IDLE_MODE_CTL_SHIFT 0x02 #define WSA884X_VSENSE1_IDLE_MODE_CTL_SHIFT 0x02
#define WSA884X_VSENSE1_VOCM_AMP_CTL_SHIFT 0x00 #define WSA884X_VSENSE1_VOCM_AMP_CTL_SHIFT 0x00
/* WSA884X_ISENSE2 Fields: */
#define WSA884X_ISENSE2_ISENSE_GAIN_CTL_SHIFT 0x05
#define WSA884X_ISENSE2_SUMAMP_IQ_CTL_SHIFT 0x04
#define WSA884X_ISENSE2_SPARE_BITS_3_0_SHIFT 0x00
/* WSA884X_ADC_2 Fields: */ /* WSA884X_ADC_2 Fields: */
#define WSA884X_ADC_2_ATEST_SEL_CAL_REF_SHIFT 0x07 #define WSA884X_ADC_2_ATEST_SEL_CAL_REF_SHIFT 0x07
#define WSA884X_ADC_2_ISNS_LOAD_STORED_SHIFT 0x06 #define WSA884X_ADC_2_ISNS_LOAD_STORED_SHIFT 0x06
@@ -123,6 +127,9 @@
/* WSA884X_TADC_VALUE_CTL Fields: */ /* WSA884X_TADC_VALUE_CTL Fields: */
#define WSA884X_TADC_VALUE_CTL_VBAT_VALUE_RD_EN_SHIFT 0x01 #define WSA884X_TADC_VALUE_CTL_VBAT_VALUE_RD_EN_SHIFT 0x01
#define WSA884X_TADC_VALUE_CTL_TEMP_VALUE_RD_EN_SHIFT 0x00 #define WSA884X_TADC_VALUE_CTL_TEMP_VALUE_RD_EN_SHIFT 0x00
/* WSA884X_CDC_PATH_MODE Fields: */
#define WSA884X_CDC_PATH_MODE_RXD_MODE_SHIFT 0x01
#define WSA884X_CDC_PATH_MODE_TXD_MODE_SHIFT 0x00
/* WSA884X_PA_FSM_BYP0 Fields: */ /* WSA884X_PA_FSM_BYP0 Fields: */
#define WSA884X_PA_FSM_BYP0_TSADC_EN_SHIFT 0x07 #define WSA884X_PA_FSM_BYP0_TSADC_EN_SHIFT 0x07
#define WSA884X_PA_FSM_BYP0_SPKR_PROT_EN_SHIFT 0x06 #define WSA884X_PA_FSM_BYP0_SPKR_PROT_EN_SHIFT 0x06
@@ -142,4 +149,48 @@
#define WSA884X_PA_FSM_BYP1_PA_AUX_EN_SHIFT 0x00 #define WSA884X_PA_FSM_BYP1_PA_AUX_EN_SHIFT 0x00
/* WSA884X_PA_FSM_EN Fields: */ /* WSA884X_PA_FSM_EN Fields: */
#define WSA884X_PA_FSM_EN_GLOBAL_PA_EN_SHIFT 0x00 #define WSA884X_PA_FSM_EN_GLOBAL_PA_EN_SHIFT 0x00
/* WSA884X_OCP_CTL Fields: */
#define WSA884X_OCP_CTL_OCP_EN_SHIFT 0x07
#define WSA884X_OCP_CTL_OCP_CURR_LIMIT_SHIFT 0x04
#define WSA884X_OCP_CTL_GLITCH_FILTER_SHIFT 0x02
#define WSA884X_OCP_CTL_OCP_P_HS_DLY_CTL_SHIFT 0x00
/* WSA884X_ILIM_CTRL1 Fields: */
#define WSA884X_ILIM_CTRL1_EN_AUTO_MAXD_SEL_SHIFT 0x07
#define WSA884X_ILIM_CTRL1_EN_ILIM_SW_CLH_SHIFT 0x06
#define WSA884X_ILIM_CTRL1_ILIM_OFFSET_CLH_SHIFT 0x03
#define WSA884X_ILIM_CTRL1_ILIM_OFFSET_PB_SHIFT 0x00
/* WSA884X_CLSH_CTL_0 Fields: */
#define WSA884X_CLSH_CTL_0_CSR_GAIN_EN_SHIFT 0x07
#define WSA884X_CLSH_CTL_0_DLY_CODE_SHIFT 0x04
#define WSA884X_CLSH_CTL_0_DLY_RST_SHIFT 0x03
#define WSA884X_CLSH_CTL_0_DLY_EN_SHIFT 0x02
#define WSA884X_CLSH_CTL_0_INPUT_EN_SHIFT 0x01
#define WSA884X_CLSH_CTL_0_CLSH_EN_SHIFT 0x00
/* WSA884X_STB_CTRL1 Fields: */
#define WSA884X_STB_CTRL1_SLOPE_COMP_CURRENT_SHIFT 0x03
#define WSA884X_STB_CTRL1_VOUT_FS_SHIFT 0x00
/* WSA884X_OTP_REG_38 Fields: */
#define WSA884X_OTP_REG_38_RESERVER_SHIFT 0x04
#define WSA884X_OTP_REG_38_BST_CFG_SEL_SHIFT 0x03
#define WSA884X_OTP_REG_38_BOOST_ILIM_TUNE_SHIFT 0x00
/* WSA884X_OTP_REG_40 Fields: */
#define WSA884X_OTP_REG_40_SPARE_TYPE2_SHIFT 0x06
#define WSA884X_OTP_REG_40_ISENSE_RESCAL_SHIFT 0x02
#define WSA884X_OTP_REG_40_ATE_BOOST_RDSON_TEST_SHIFT 0x01
#define WSA884X_OTP_REG_40_ATE_CLASSD_RDSON_TEST_SHIFT 0x00
/* WSA884X_CURRENT_LIMIT Fields: */
#define WSA884X_CURRENT_LIMIT_CURRENT_LIMIT_OVRD_EN_SHIFT 0x07
#define WSA884X_CURRENT_LIMIT_CURRENT_LIMIT_SHIFT 0x02
#define WSA884X_CURRENT_LIMIT_CLK_PHASE_SHIFT 0x00
/* WSA884X_PWM_CLK_CTL Fields: */
#define WSA884X_PWM_CLK_CTL_VCMO_INT1_IDLE_MODE_OVRT_SHIFT 0x07
#define WSA884X_PWM_CLK_CTL_REG_MCLK_DIV_RATIO_SHIFT 0x06
#define WSA884X_PWM_CLK_CTL_PWM_DEGLITCH_CLK_DELAY_CTRL_SHIFT 0x04
#define WSA884X_PWM_CLK_CTL_PWM_CLK_FREQ_SEL_SHIFT 0x03
#define WSA884X_PWM_CLK_CTL_PWM_CLK_DIV_RATIO_SHIFT 0x01
#define WSA884X_PWM_CLK_CTL_PWM_CLK_DIV_BYPASS_SHIFT 0x00
/* WSA884X_CKWD_CTL_1 Fields: */
#define WSA884X_CKWD_CTL_1_SPARE_BITS_7_6_SHIFT 0x06
#define WSA884X_CKWD_CTL_1_VPP_SW_CTL_SHIFT 0x05
#define WSA884X_CKWD_CTL_1_CKWD_VCOMP_VREF_SEL_SHIFT 0x00
#endif /* WSA884X_REG_SHIFTS_H */ #endif /* WSA884X_REG_SHIFTS_H */

View File

@@ -73,6 +73,96 @@ enum {
COMP_OFFSET4, COMP_OFFSET4,
}; };
enum {
EXT_ABOVE_3S,
CONFIG_1S,
CONFIG_2S,
CONFIG_3S,
EXT_1S,
EXT_2S,
EXT_3S,
};
enum {
WSA_4OHMS = 0,
WSA_6OHMS,
WSA_8OHMS,
WSA_32OHMS,
WSA_MAXOHMS,
};
/* Aux gain from system gain */
static const u8 pa_aux_no_comp[G_MAX_DB] = {
PA_AUX_18_DB, /* G_21_DB */
PA_AUX_18_DB, /* G_19P5_DB */
PA_AUX_18_DB, /* G_18_DB */
PA_AUX_18_DB, /* G_16P5_DB */
PA_AUX_18_DB, /* G_15_DB */
PA_AUX_12_DB, /* G_13P5_DB */
PA_AUX_12_DB, /* G_12_DB */
PA_AUX_12_DB, /* G_10P5_DB */
PA_AUX_7P5_DB, /* G_9_DB */
PA_AUX_7P5_DB, /* G_7P5_DB */
PA_AUX_7P5_DB, /* G_6_DB */
PA_AUX_7P5_DB, /* G_4P5_DB */
PA_AUX_0_DB, /* G_3_DB */
PA_AUX_0_DB, /* G_1P5_DB */
PA_AUX_0_DB, /* G_0_DB */
PA_AUX_M1P5_DB,/* G_M1P5_DB */
PA_AUX_M3_DB, /* G_M3_DB */
PA_AUX_M4P5_DB,/* G_M4P5_DB */
PA_AUX_M6_DB /* G_M6_DB */
};
/*
* Isense data indexed by system_gain and rload
* WSA_4OHMS, WSA_6OHMS, WSA_8OHMS, WSA_32OHMS
*/
static const u8 isense_gain_data[G_MAX_DB][WSA_MAXOHMS] = {
{ISENSE_18_DB, ISENSE_6_DB, ISENSE_12_DB, ISENSE_18_DB}, /*G_21_DB */
{ISENSE_18_DB, ISENSE_6_DB, ISENSE_12_DB, ISENSE_18_DB}, /*G_19P5_DB */
{ISENSE_18_DB, ISENSE_6_DB, ISENSE_15_DB, ISENSE_18_DB}, /*G_18_DB */
{ISENSE_18_DB, ISENSE_12_DB, ISENSE_15_DB, ISENSE_18_DB}, /*G_16P5_DB */
{ISENSE_18_DB, ISENSE_12_DB, ISENSE_18_DB, ISENSE_18_DB}, /*G_15_DB */
{ISENSE_18_DB, ISENSE_12_DB, ISENSE_18_DB, ISENSE_18_DB}, /*G_13P5_DB */
{ISENSE_18_DB, ISENSE_12_DB, ISENSE_18_DB, ISENSE_18_DB}, /*G_12_DB */
{ISENSE_18_DB, ISENSE_12_DB, ISENSE_18_DB, ISENSE_18_DB}, /*G_10P5_DB */
{ISENSE_18_DB, ISENSE_12_DB, ISENSE_18_DB, ISENSE_18_DB}, /*G_9_DB */
{ISENSE_18_DB, ISENSE_12_DB, ISENSE_18_DB, ISENSE_18_DB}, /*G_7P5_DB */
{ISENSE_18_DB, ISENSE_12_DB, ISENSE_18_DB, ISENSE_18_DB}, /*G_6_DB */
{ISENSE_18_DB, ISENSE_12_DB, ISENSE_18_DB, ISENSE_18_DB}, /*G_4P5_DB */
{ISENSE_18_DB, ISENSE_12_DB, ISENSE_18_DB, ISENSE_18_DB}, /*G_3_DB */
{ISENSE_18_DB, ISENSE_12_DB, ISENSE_18_DB, ISENSE_18_DB}, /*G_1P5_DB */
{ISENSE_18_DB, ISENSE_12_DB, ISENSE_18_DB, ISENSE_18_DB}, /*G_0_DB */
{ISENSE_18_DB, ISENSE_12_DB, ISENSE_18_DB, ISENSE_18_DB}, /*G_M1P5_DB */
{ISENSE_18_DB, ISENSE_12_DB, ISENSE_18_DB, ISENSE_18_DB}, /*G_M3_DB */
{ISENSE_18_DB, ISENSE_12_DB, ISENSE_18_DB, ISENSE_18_DB}, /*G_M4P5_DB */
{ISENSE_18_DB, ISENSE_12_DB, ISENSE_18_DB, ISENSE_18_DB}, /*G_M6_DB */
};
/* Vsense gain from system gain */
static const u8 vsense_gain_data[G_MAX_DB] = {
VSENSE_M24_DB, /* G_21_DB */
VSENSE_M24_DB, /* G_19P5_DB */
VSENSE_M21_DB, /* G_18_DB */
VSENSE_M18_DB, /* G_16P5_DB */
VSENSE_M18_DB, /* G_15_DB */
VSENSE_M15_DB, /* G_13P5_DB */
VSENSE_M15_DB, /* G_12_DB */
VSENSE_M12_DB, /* G_10P5_DB */
VSENSE_M12_DB, /* G_9_DB */
VSENSE_M12_DB, /* G_7P5_DB */
VSENSE_M12_DB, /* G_6_DB */
VSENSE_M12_DB, /* G_4P5_DB */
VSENSE_M12_DB, /* G_3_DB */
VSENSE_M12_DB, /* G_1P5_DB */
VSENSE_M12_DB, /* G_0_DB */
VSENSE_M12_DB, /* G_M1P5_DB */
VSENSE_M12_DB, /* G_M3_DB */
VSENSE_M12_DB, /* G_M4P5_DB */
VSENSE_M12_DB /* G_M6_DB */
};
struct wsa_reg_mask_val { struct wsa_reg_mask_val {
u16 reg; u16 reg;
u8 mask; u8 mask;
@@ -80,6 +170,7 @@ struct wsa_reg_mask_val {
}; };
static const struct wsa_reg_mask_val reg_init[] = { static const struct wsa_reg_mask_val reg_init[] = {
{REG_FIELD_VALUE(CKWD_CTL_1, VPP_SW_CTL, 0x00)},
{REG_FIELD_VALUE(CDC_SPK_DSM_A2_0, COEF_A2, 0x0A)}, {REG_FIELD_VALUE(CDC_SPK_DSM_A2_0, COEF_A2, 0x0A)},
{REG_FIELD_VALUE(CDC_SPK_DSM_A2_1, COEF_A2, 0x08)}, {REG_FIELD_VALUE(CDC_SPK_DSM_A2_1, COEF_A2, 0x08)},
{REG_FIELD_VALUE(CDC_SPK_DSM_A3_0, COEF_A3, 0xF3)}, {REG_FIELD_VALUE(CDC_SPK_DSM_A3_0, COEF_A3, 0xF3)},
@@ -99,15 +190,14 @@ static const struct wsa_reg_mask_val reg_init[] = {
{REG_FIELD_VALUE(CDC_SPK_DSM_R5, SAT_LIMIT_R5, 0x8B)}, {REG_FIELD_VALUE(CDC_SPK_DSM_R5, SAT_LIMIT_R5, 0x8B)},
{REG_FIELD_VALUE(CDC_SPK_DSM_R6, SAT_LIMIT_R6, 0x9B)}, {REG_FIELD_VALUE(CDC_SPK_DSM_R6, SAT_LIMIT_R6, 0x9B)},
{REG_FIELD_VALUE(CDC_SPK_DSM_R7, SAT_LIMIT_R7, 0x3F)}, {REG_FIELD_VALUE(CDC_SPK_DSM_R7, SAT_LIMIT_R7, 0x3F)},
{REG_FIELD_VALUE(DRE_CTL_0, PROG_DELAY, 0x00)},
{REG_FIELD_VALUE(BOP_DEGLITCH_CTL, BOP_DEGLITCH_SETTING, 0x08)}, {REG_FIELD_VALUE(BOP_DEGLITCH_CTL, BOP_DEGLITCH_SETTING, 0x08)},
{REG_FIELD_VALUE(GAIN_RAMPING_MIN, MIN_GAIN, 0x0E)}, {REG_FIELD_VALUE(CLSH_CTL_0, DLY_CODE, 0x06)},
{REG_FIELD_VALUE(CLSH_SOFT_MAX, SOFT_MAX, 0xFF)}, {REG_FIELD_VALUE(CLSH_SOFT_MAX, SOFT_MAX, 0xFF)},
{REG_FIELD_VALUE(CLSH_VTH1, CLSH_VTH1, 0xFF)}, {REG_FIELD_VALUE(OTP_REG_38, BOOST_ILIM_TUNE, 0x00)},
{REG_FIELD_VALUE(VSENSE1, GAIN_VSENSE_FE, 0x04)}, {REG_FIELD_VALUE(OTP_REG_40, ISENSE_RESCAL, 0x08)},
{REG_FIELD_VALUE(ADC_2, ISNS_LOAD_STORED, 0x00)}, {REG_FIELD_VALUE(STB_CTRL1, SLOPE_COMP_CURRENT, 0x0D)},
{REG_FIELD_VALUE(ADC_7, EN_AZ_REG, 0x01)}, {REG_FIELD_VALUE(ILIM_CTRL1, ILIM_OFFSET_PB, 0x03)},
{REG_FIELD_VALUE(ADC_7, EN_SAR_REG, 0x01)} {REG_FIELD_VALUE(CKWD_CTL_1, CKWD_VCOMP_VREF_SEL, 0x13)},
}; };
static int wsa884x_handle_post_irq(void *data); static int wsa884x_handle_post_irq(void *data);
@@ -116,7 +206,7 @@ static int wsa884x_get_temperature(struct snd_soc_component *component,
enum { enum {
WSA8840 = 0, WSA8840 = 0,
WSA8845 = 5, WSA8845 = 5,
WSA884H = 12, WSA8845H = 0xC,
}; };
enum { enum {
@@ -504,6 +594,13 @@ static const char * const wsa_dev_mode_text[] = {
"speaker", "receiver", "ultrasound" "speaker", "receiver", "ultrasound"
}; };
enum {
SPEAKER,
RECEIVER,
ULTRASOUND,
};
static const struct soc_enum wsa_dev_mode_enum = static const struct soc_enum wsa_dev_mode_enum =
SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(wsa_dev_mode_text), wsa_dev_mode_text); SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(wsa_dev_mode_text), wsa_dev_mode_text);
@@ -675,8 +772,8 @@ static ssize_t wsa884x_variant_read(struct snd_info_entry *entry,
case WSA8845: case WSA8845:
len = snprintf(buffer, sizeof(buffer), "WSA8845\n"); len = snprintf(buffer, sizeof(buffer), "WSA8845\n");
break; break;
case WSA884H: case WSA8845H:
len = snprintf(buffer, sizeof(buffer), "WSA884H\n"); len = snprintf(buffer, sizeof(buffer), "WSA8845H\n");
break; break;
default: default:
len = snprintf(buffer, sizeof(buffer), "UNDEFINED\n"); len = snprintf(buffer, sizeof(buffer), "UNDEFINED\n");
@@ -791,6 +888,11 @@ EXPORT_SYMBOL(wsa884x_codec_info_create_codec_entry);
int wsa884x_set_configuration(struct snd_soc_component *component, int wsa884x_set_configuration(struct snd_soc_component *component,
u8 rload, u8 bat_cfg, u8 system_gain) u8 rload, u8 bat_cfg, u8 system_gain)
{ {
struct wsa884x_priv *wsa884x = snd_soc_component_get_drvdata(component);
wsa884x->rload = rload;
wsa884x->bat_cfg = bat_cfg;
wsa884x->system_gain = system_gain;
return 0; return 0;
} }
EXPORT_SYMBOL(wsa884x_set_configuration); EXPORT_SYMBOL(wsa884x_set_configuration);
@@ -933,9 +1035,16 @@ static int wsa884x_set_pbr(struct snd_kcontrol *kcontrol,
struct wsa884x_priv *wsa884x = snd_soc_component_get_drvdata(component); struct wsa884x_priv *wsa884x = snd_soc_component_get_drvdata(component);
int value = ucontrol->value.integer.value[0]; int value = ucontrol->value.integer.value[0];
dev_dbg(component->dev, "%s: VIsense enable current %d, new %d\n", dev_dbg(component->dev, "%s: PBR enable current %d, new %d\n",
__func__, wsa884x->pbr_enable, value); __func__, wsa884x->pbr_enable, value);
wsa884x->pbr_enable = value; wsa884x->pbr_enable = value;
if (value) {
snd_soc_component_update_bits(component,
WSA884X_CLSH_VTH1,
0xFF, 0xFF);
}
return 0; return 0;
} }
@@ -1158,12 +1267,82 @@ static int wsa884x_enable_swr_dac_port(struct snd_soc_dapm_widget *w,
return 0; return 0;
} }
static int wsa884x_set_gain_parameters(struct snd_soc_component *component)
{
struct wsa884x_priv *wsa884x = snd_soc_component_get_drvdata(component);
switch (wsa884x->bat_cfg) {
case CONFIG_1S:
case EXT_1S:
switch (wsa884x->system_gain) {
case G_21_DB:
wsa884x->comp_offset = COMP_OFFSET0;
wsa884x->min_gain = G_0_DB;
wsa884x->pa_aux_gain = PA_AUX_0_DB;
break;
case G_19P5_DB:
wsa884x->comp_offset = COMP_OFFSET1;
wsa884x->min_gain = G_M1P5_DB;
wsa884x->pa_aux_gain = PA_AUX_M1P5_DB;
break;
case G_18_DB:
wsa884x->comp_offset = COMP_OFFSET2;
wsa884x->min_gain = G_M3_DB;
wsa884x->pa_aux_gain = PA_AUX_M3_DB;
break;
case G_16P5_DB:
wsa884x->comp_offset = COMP_OFFSET3;
wsa884x->min_gain = G_M4P5_DB;
wsa884x->pa_aux_gain = PA_AUX_M4P5_DB;
break;
default:
wsa884x->comp_offset = COMP_OFFSET4;
wsa884x->min_gain = G_M6_DB;
wsa884x->pa_aux_gain = PA_AUX_M6_DB;
break;
}
break;
case CONFIG_3S:
case EXT_3S:
wsa884x->comp_offset = COMP_OFFSET0;
wsa884x->min_gain = G_7P5_DB;
wsa884x->pa_aux_gain = PA_AUX_7P5_DB;
break;
case EXT_ABOVE_3S:
wsa884x->comp_offset = COMP_OFFSET0;
wsa884x->min_gain = G_12_DB;
wsa884x->pa_aux_gain = PA_AUX_12_DB;
break;
default:
wsa884x->comp_offset = COMP_OFFSET0;
wsa884x->min_gain = G_0_DB;
wsa884x->pa_aux_gain = PA_AUX_0_DB;
break;
}
if (!wsa884x->comp_enable)
wsa884x->pa_aux_gain = pa_aux_no_comp[wsa884x->system_gain];
snd_soc_component_update_bits(component,
REG_FIELD_VALUE(GAIN_RAMPING_MIN, MIN_GAIN, wsa884x->min_gain));
if (wsa884x->comp_enable)
snd_soc_component_update_bits(component,
REG_FIELD_VALUE(DRE_CTL_0, OFFSET,
wsa884x->comp_offset));
return 0;
}
static int wsa884x_spkr_event(struct snd_soc_dapm_widget *w, static int wsa884x_spkr_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event) struct snd_kcontrol *kcontrol, int event)
{ {
struct snd_soc_component *component = struct snd_soc_component *component =
snd_soc_dapm_to_component(w->dapm); snd_soc_dapm_to_component(w->dapm);
struct wsa884x_priv *wsa884x = snd_soc_component_get_drvdata(component); struct wsa884x_priv *wsa884x = snd_soc_component_get_drvdata(component);
u8 igain;
u8 vgain;
u8 ana_wo_ctl_0_value;
u8 pa_aux_shift = 0x02;
u8 vphx_shift = 0x06;
dev_dbg(component->dev, "%s: %s %d\n", __func__, w->name, event); dev_dbg(component->dev, "%s: %s %d\n", __func__, w->name, event);
switch (event) { switch (event) {
@@ -1171,24 +1350,51 @@ static int wsa884x_spkr_event(struct snd_soc_dapm_widget *w,
swr_slvdev_datapath_control(wsa884x->swr_slave, swr_slvdev_datapath_control(wsa884x->swr_slave,
wsa884x->swr_slave->dev_num, wsa884x->swr_slave->dev_num,
true); true);
/* Added delay as per HW sequence */ wsa884x_set_gain_parameters(component);
usleep_range(250, 300); /* Must write WO registers in a single write */
ana_wo_ctl_0_value = ((wsa884x->bat_cfg & 0x03) << vphx_shift) |
(wsa884x->pa_aux_gain << pa_aux_shift) |
wsa884x->dev_mode;
snd_soc_component_update_bits(component, snd_soc_component_update_bits(component,
REG_FIELD_VALUE(DRE_CTL_1, CSR_GAIN_EN, 0x01)); WSA884X_ANA_WO_CTL_0, 0xFF, ana_wo_ctl_0_value);
/* Added delay as per HW sequence */
usleep_range(250, 300);
if (wsa884x->comp_enable)
snd_soc_component_update_bits(component, snd_soc_component_update_bits(component,
REG_FIELD_VALUE(DRE_CTL_0, OFFSET, WSA884X_ANA_WO_CTL_1, 0xFF, 0);
wsa884x->comp_offset)); if (wsa884x->rload == WSA_4OHMS ||
wsa884x->rload == WSA_6OHMS)
snd_soc_component_update_bits(component,
REG_FIELD_VALUE(OCP_CTL, OCP_CURR_LIMIT, 0x07));
if (wsa884x->dev_mode == SPEAKER) {
snd_soc_component_update_bits(component,
REG_FIELD_VALUE(DRE_CTL_0, PROG_DELAY, 0x0F));
} else {
snd_soc_component_update_bits(component,
REG_FIELD_VALUE(DRE_CTL_0, PROG_DELAY, 0x03));
snd_soc_component_update_bits(component,
REG_FIELD_VALUE(CDC_PATH_MODE, RXD_MODE, 0x01));
snd_soc_component_update_bits(component,
REG_FIELD_VALUE(PWM_CLK_CTL,
PWM_CLK_FREQ_SEL, 0x01));
}
if (!wsa884x->pbr_enable) {
snd_soc_component_update_bits(component,
REG_FIELD_VALUE(CURRENT_LIMIT,
CURRENT_LIMIT_OVRD_EN, 0x01));
snd_soc_component_update_bits(component,
REG_FIELD_VALUE(CURRENT_LIMIT,
CURRENT_LIMIT, 0x09));
}
igain = isense_gain_data[wsa884x->system_gain][wsa884x->rload];
vgain = vsense_gain_data[wsa884x->system_gain];
snd_soc_component_update_bits(component,
REG_FIELD_VALUE(ISENSE2, ISENSE_GAIN_CTL, igain));
snd_soc_component_update_bits(component,
REG_FIELD_VALUE(VSENSE1, GAIN_VSENSE_FE, vgain));
wcd_enable_irq(&wsa884x->irq_info, WSA884X_IRQ_INT_UVLO); wcd_enable_irq(&wsa884x->irq_info, WSA884X_IRQ_INT_UVLO);
/* Force remove group */ /* Force remove group */
swr_remove_from_group(wsa884x->swr_slave, swr_remove_from_group(wsa884x->swr_slave,
wsa884x->swr_slave->dev_num); wsa884x->swr_slave->dev_num);
snd_soc_component_update_bits(component, snd_soc_component_update_bits(component,
REG_FIELD_VALUE(VBAT_THRM_FLT_CTL, VBAT_COEF_SEL, 0x03)); REG_FIELD_VALUE(VBAT_THRM_FLT_CTL, VBAT_COEF_SEL, 0x04));
snd_soc_component_update_bits(component,
REG_FIELD_VALUE(VBAT_THRM_FLT_CTL, VBAT_FLT_EN, 0x01));
if (test_bit(SPKR_ADIE_LB, &wsa884x->status_mask)) if (test_bit(SPKR_ADIE_LB, &wsa884x->status_mask))
snd_soc_component_update_bits(component, snd_soc_component_update_bits(component,
REG_FIELD_VALUE(PA_FSM_EN, GLOBAL_PA_EN, 0x01)); REG_FIELD_VALUE(PA_FSM_EN, GLOBAL_PA_EN, 0x01));
@@ -1197,10 +1403,6 @@ static int wsa884x_spkr_event(struct snd_soc_dapm_widget *w,
if (!test_bit(SPKR_ADIE_LB, &wsa884x->status_mask)) if (!test_bit(SPKR_ADIE_LB, &wsa884x->status_mask))
wcd_disable_irq(&wsa884x->irq_info, wcd_disable_irq(&wsa884x->irq_info,
WSA884X_IRQ_INT_PDM_WD); WSA884X_IRQ_INT_PDM_WD);
snd_soc_component_update_bits(component,
REG_FIELD_VALUE(VBAT_THRM_FLT_CTL, VBAT_FLT_EN, 0x00));
snd_soc_component_update_bits(component,
REG_FIELD_VALUE(VBAT_THRM_FLT_CTL, VBAT_COEF_SEL, 0x00));
snd_soc_component_update_bits(component, snd_soc_component_update_bits(component,
REG_FIELD_VALUE(PA_FSM_EN, GLOBAL_PA_EN, 0x00)); REG_FIELD_VALUE(PA_FSM_EN, GLOBAL_PA_EN, 0x00));
snd_soc_component_update_bits(component, snd_soc_component_update_bits(component,
@@ -1267,11 +1469,10 @@ static void wsa884x_codec_init(struct snd_soc_component *component)
snd_soc_component_update_bits(component, reg_init[i].reg, snd_soc_component_update_bits(component, reg_init[i].reg,
reg_init[i].mask, reg_init[i].val); reg_init[i].mask, reg_init[i].val);
if (wsa884x->variant == WSA8840 || wsa884x->variant == WSA8845) { if (wsa884x->variant == WSA8845H)
snd_soc_component_update_bits(component, snd_soc_component_update_bits(wsa884x->component,
REG_FIELD_VALUE(DRE_CTL_0, OFFSET, 0x03)); REG_FIELD_VALUE(DRE_CTL_1, CSR_GAIN_EN, 0x01));
wsa884x->comp_offset = COMP_OFFSET3;
}
} }
static int32_t wsa884x_temp_reg_read(struct snd_soc_component *component, static int32_t wsa884x_temp_reg_read(struct snd_soc_component *component,
@@ -1422,6 +1623,9 @@ static int wsa884x_codec_probe(struct snd_soc_component *component)
wsa884x->version = version; wsa884x->version = version;
wsa884x->comp_offset = COMP_OFFSET2; wsa884x->comp_offset = COMP_OFFSET2;
wsa884x->bat_cfg = CONFIG_1S;
wsa884x->rload = WSA_8OHMS;
wsa884x->system_gain = G_19P5_DB;
wsa884x_codec_init(component); wsa884x_codec_init(component);
wsa884x->global_pa_cnt = 0; wsa884x->global_pa_cnt = 0;