|
@@ -1,7 +1,7 @@
|
|
|
// SPDX-License-Identifier: GPL-2.0-only
|
|
|
/*
|
|
|
* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
|
|
|
- * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
|
|
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
|
|
*/
|
|
|
#include <linux/module.h>
|
|
|
#include <linux/init.h>
|
|
@@ -24,9 +24,10 @@
|
|
|
|
|
|
#define WCD9378_ZDET_SUPPORTED true
|
|
|
/* Z value defined in milliohm */
|
|
|
+#define WCD9378_ZDET_VAL_0 0
|
|
|
#define WCD9378_ZDET_VAL_32 32000
|
|
|
#define WCD9378_ZDET_VAL_400 400000
|
|
|
-#define WCD9378_ZDET_VAL_1200 1200000
|
|
|
+#define WCD9378_ZDET_VAL_2500 2500000
|
|
|
#define WCD9378_ZDET_VAL_100K 100000000
|
|
|
/* Z floating defined in ohms */
|
|
|
#define WCD9378_ZDET_FLOATING_IMPEDANCE 0x0FFFFFFE
|
|
@@ -410,6 +411,7 @@ static inline void wcd9378_mbhc_get_result_params(struct wcd9378_priv *wcd9378,
|
|
|
regmap_update_bits(wcd9378->regmap, WCD9378_ANA_MBHC_ZDET, 0x20, 0x00);
|
|
|
x1 = WCD9378_MBHC_GET_X1(val);
|
|
|
c1 = WCD9378_MBHC_GET_C1(val);
|
|
|
+
|
|
|
/* If ramp is not complete, give additional 5ms */
|
|
|
if ((c1 < 2) && x1)
|
|
|
usleep_range(5000, 5050);
|
|
@@ -418,6 +420,7 @@ static inline void wcd9378_mbhc_get_result_params(struct wcd9378_priv *wcd9378,
|
|
|
dev_dbg(wcd9378->dev,
|
|
|
"%s: Impedance detect ramp error, c1=%d, x1=0x%x\n",
|
|
|
__func__, c1, x1);
|
|
|
+ *zdet = WCD9378_ZDET_VAL_0;
|
|
|
goto ramp_down;
|
|
|
}
|
|
|
d1 = d1_a[c1];
|
|
@@ -524,10 +527,10 @@ static void wcd9378_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl,
|
|
|
int zMono, z_diff1, z_diff2;
|
|
|
bool is_fsm_disable = false;
|
|
|
struct wcd9378_mbhc_zdet_param zdet_param[] = {
|
|
|
- {4, 0, 4, 0x08, 0x14, 0x18}, /* < 32ohm */
|
|
|
- {2, 0, 3, 0x18, 0x7C, 0x90}, /* 32ohm < Z < 400ohm */
|
|
|
- {1, 4, 5, 0x18, 0x7C, 0x90}, /* 400ohm < Z < 1200ohm */
|
|
|
- {1, 6, 7, 0x18, 0x7C, 0x90}, /* >1200ohm */
|
|
|
+ {4, 0, 4, 0x08, 0x14, 0x18}, /* 0ohm < Z < 32ohm */
|
|
|
+ {2, 0, 3, 0x20, 0x7C, 0x90}, /* 32ohm < Z < 400ohm */
|
|
|
+ {2, 4, 6, 0x20, 0x7C, 0x90}, /* 400ohm < Z < 2500ohm */
|
|
|
+ {2, 5, 7, 0x20, 0x7C, 0x90}, /* >2500ohm or < 0ohm */
|
|
|
};
|
|
|
struct wcd9378_mbhc_zdet_param *zdet_param_ptr = NULL;
|
|
|
s16 d1_a[][4] = {
|
|
@@ -578,14 +581,16 @@ static void wcd9378_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl,
|
|
|
goto left_ch_impedance;
|
|
|
|
|
|
/* Second ramp for left ch */
|
|
|
- if (z1L < WCD9378_ZDET_VAL_32) {
|
|
|
+ if ((z1L < WCD9378_ZDET_VAL_32) &&
|
|
|
+ (z1L >= WCD9378_ZDET_VAL_0)) {
|
|
|
zdet_param_ptr = &zdet_param[0];
|
|
|
d1 = d1_a[0];
|
|
|
} else if ((z1L > WCD9378_ZDET_VAL_400) &&
|
|
|
- (z1L <= WCD9378_ZDET_VAL_1200)) {
|
|
|
+ (z1L <= WCD9378_ZDET_VAL_2500)) {
|
|
|
zdet_param_ptr = &zdet_param[2];
|
|
|
d1 = d1_a[2];
|
|
|
- } else if (z1L > WCD9378_ZDET_VAL_1200) {
|
|
|
+ } else if ((z1L > WCD9378_ZDET_VAL_2500) ||
|
|
|
+ (z1L < WCD9378_ZDET_VAL_0)) {
|
|
|
zdet_param_ptr = &zdet_param[3];
|
|
|
d1 = d1_a[3];
|
|
|
}
|
|
@@ -607,19 +612,22 @@ left_ch_impedance:
|
|
|
/* Start of right impedance ramp and calculation */
|
|
|
wcd9378_mbhc_zdet_ramp(component, zdet_param_ptr, NULL, &z1R, d1);
|
|
|
if (WCD9378_MBHC_IS_SECOND_RAMP_REQUIRED(z1R)) {
|
|
|
- if (((z1R > WCD9378_ZDET_VAL_1200) &&
|
|
|
+ if ((((z1R > WCD9378_ZDET_VAL_2500) ||
|
|
|
+ (z1R < WCD9378_ZDET_VAL_0)) &&
|
|
|
(zdet_param_ptr->noff == 0x6)) ||
|
|
|
((*zl) != WCD9378_ZDET_FLOATING_IMPEDANCE))
|
|
|
goto right_ch_impedance;
|
|
|
/* Second ramp for right ch */
|
|
|
- if (z1R < WCD9378_ZDET_VAL_32) {
|
|
|
+ if ((z1R < WCD9378_ZDET_VAL_32) &&
|
|
|
+ (z1R >= WCD9378_ZDET_VAL_0)) {
|
|
|
zdet_param_ptr = &zdet_param[0];
|
|
|
d1 = d1_a[0];
|
|
|
} else if ((z1R > WCD9378_ZDET_VAL_400) &&
|
|
|
- (z1R <= WCD9378_ZDET_VAL_1200)) {
|
|
|
+ (z1R <= WCD9378_ZDET_VAL_2500)) {
|
|
|
zdet_param_ptr = &zdet_param[2];
|
|
|
d1 = d1_a[2];
|
|
|
- } else if (z1R > WCD9378_ZDET_VAL_1200) {
|
|
|
+ } else if ((z1L > WCD9378_ZDET_VAL_2500) ||
|
|
|
+ (z1L < WCD9378_ZDET_VAL_0)) {
|
|
|
zdet_param_ptr = &zdet_param[3];
|
|
|
d1 = d1_a[3];
|
|
|
}
|