Merge "asoc: codecs: Add default case for switch."
diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c
index 417b34d..fea1686 100644
--- a/asoc/codecs/bolero/bolero-cdc.c
+++ b/asoc/codecs/bolero/bolero-cdc.c
@@ -1078,7 +1078,7 @@
* Returns 0 on success or -EINVAL on error.
*/
int bolero_register_event_listener(struct snd_soc_component *component,
- bool enable)
+ bool enable, bool is_dmic_sva)
{
struct bolero_priv *priv = NULL;
int ret = 0;
@@ -1097,7 +1097,8 @@
if (priv->macro_params[TX_MACRO].reg_evt_listener)
ret = priv->macro_params[TX_MACRO].reg_evt_listener(component,
- enable);
+ enable,
+ is_dmic_sva);
return ret;
}
diff --git a/asoc/codecs/bolero/bolero-cdc.h b/asoc/codecs/bolero/bolero-cdc.h
index b37eeae..7528eae 100644
--- a/asoc/codecs/bolero/bolero-cdc.h
+++ b/asoc/codecs/bolero/bolero-cdc.h
@@ -88,7 +88,8 @@
u32 size, void *data);
int (*clk_div_get)(struct snd_soc_component *component);
int (*clk_switch)(struct snd_soc_component *component, int clk_src);
- int (*reg_evt_listener)(struct snd_soc_component *component, bool en);
+ int (*reg_evt_listener)(struct snd_soc_component *component,
+ bool en, bool is_dmic_sva);
int (*clk_enable)(struct snd_soc_component *c, bool en);
char __iomem *io_base;
u16 clk_id_req;
@@ -115,7 +116,7 @@
int bolero_set_port_map(struct snd_soc_component *component, u32 size, void *data);
int bolero_tx_clk_switch(struct snd_soc_component *component, int clk_src);
int bolero_register_event_listener(struct snd_soc_component *component,
- bool enable);
+ bool enable, bool is_dmic_sva);
void bolero_wsa_pa_on(struct device *dev);
bool bolero_check_core_votes(struct device *dev);
int bolero_tx_mclk_enable(struct snd_soc_component *c, bool enable);
@@ -189,7 +190,7 @@
static inline int bolero_register_event_listener(
struct snd_soc_component *component,
- bool enable)
+ bool enable, bool is_dmic_sva)
{
return 0;
}
diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c
index 121f56d..ff94198 100644
--- a/asoc/codecs/bolero/tx-macro.c
+++ b/asoc/codecs/bolero/tx-macro.c
@@ -2385,7 +2385,7 @@
};
static int tx_macro_register_event_listener(struct snd_soc_component *component,
- bool enable)
+ bool enable, bool is_dmic_sva)
{
struct device *tx_dev = NULL;
struct tx_macro_priv *tx_priv = NULL;
@@ -2412,10 +2412,12 @@
ret = swrm_wcd_notify(
tx_priv->swr_ctrl_data[0].tx_swr_pdev,
SWR_REGISTER_WAKEUP, NULL);
- msm_cdc_pinctrl_set_wakeup_capable(
+ if (!is_dmic_sva)
+ msm_cdc_pinctrl_set_wakeup_capable(
tx_priv->tx_swr_gpio_p, false);
} else {
- msm_cdc_pinctrl_set_wakeup_capable(
+ if (!is_dmic_sva)
+ msm_cdc_pinctrl_set_wakeup_capable(
tx_priv->tx_swr_gpio_p, true);
ret = swrm_wcd_notify(
tx_priv->swr_ctrl_data[0].tx_swr_pdev,
diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c
index a947a28..de834ad 100644
--- a/asoc/codecs/bolero/va-macro.c
+++ b/asoc/codecs/bolero/va-macro.c
@@ -457,14 +457,14 @@
dev_dbg(va_dev, "%s: clock switch failed\n",
__func__);
if (va_priv->lpi_enable) {
- bolero_register_event_listener(component, true);
+ bolero_register_event_listener(component, true, false);
va_priv->register_event_listener = true;
}
break;
case SND_SOC_DAPM_POST_PMD:
if (va_priv->register_event_listener) {
va_priv->register_event_listener = false;
- bolero_register_event_listener(component, false);
+ bolero_register_event_listener(component, false, false);
}
if (bolero_tx_clk_switch(component, CLK_SRC_TX_RCG))
dev_dbg(va_dev, "%s: clock switch failed\n",__func__);
@@ -480,6 +480,45 @@
return ret;
}
+static int va_macro_swr_intr_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_component *component =
+ snd_soc_dapm_to_component(w->dapm);
+ int ret = 0;
+ struct device *va_dev = NULL;
+ struct va_macro_priv *va_priv = NULL;
+
+ if (!va_macro_get_data(component, &va_dev, &va_priv, __func__))
+ return -EINVAL;
+
+ dev_dbg(va_dev, "%s: event = %d, lpi_enable = %d\n",
+ __func__, event, va_priv->lpi_enable);
+
+ if (!va_priv->lpi_enable)
+ return ret;
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ if (va_priv->lpi_enable) {
+ bolero_register_event_listener(component, true, true);
+ va_priv->register_event_listener = true;
+ }
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ if (va_priv->register_event_listener) {
+ va_priv->register_event_listener = false;
+ bolero_register_event_listener(component, false, true);
+ }
+ break;
+ default:
+ dev_err(va_priv->dev,
+ "%s: invalid DAPM event %d\n", __func__, event);
+ ret = -EINVAL;
+ }
+ return ret;
+}
+
static int va_macro_tx_swr_clk_event_v2(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
@@ -1962,6 +2001,10 @@
SND_SOC_DAPM_SUPPLY_S("VA_SWR_PWR", -1, SND_SOC_NOPM, 0, 0,
va_macro_swr_pwr_event,
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_SUPPLY_S("VA_SWR_INTR", 0, SND_SOC_NOPM, 0, 0,
+ va_macro_swr_intr_event,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
};
static const struct snd_soc_dapm_widget va_macro_dapm_widgets[] = {
@@ -2106,6 +2149,10 @@
SND_SOC_DAPM_SUPPLY_S("VA_MCLK", -1, SND_SOC_NOPM, 0, 0,
va_macro_mclk_event,
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_SUPPLY_S("VA_SWR_INTR", 0, SND_SOC_NOPM, 0, 0,
+ va_macro_swr_intr_event,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
};
static const struct snd_soc_dapm_widget va_macro_wod_dapm_widgets[] = {
@@ -2252,6 +2299,15 @@
{"VA SMIC MUX3", "SWR_MIC9", "VA SWR_MIC9"},
{"VA SMIC MUX3", "SWR_MIC10", "VA SWR_MIC10"},
{"VA SMIC MUX3", "SWR_MIC11", "VA SWR_MIC11"},
+
+ {"VA DMIC0", NULL, "VA_SWR_INTR"},
+ {"VA DMIC1", NULL, "VA_SWR_INTR"},
+ {"VA DMIC2", NULL, "VA_SWR_INTR"},
+ {"VA DMIC3", NULL, "VA_SWR_INTR"},
+ {"VA DMIC4", NULL, "VA_SWR_INTR"},
+ {"VA DMIC5", NULL, "VA_SWR_INTR"},
+ {"VA DMIC6", NULL, "VA_SWR_INTR"},
+ {"VA DMIC7", NULL, "VA_SWR_INTR"},
};
static const struct snd_soc_dapm_route va_audio_map_v2[] = {
@@ -2488,6 +2544,15 @@
{"VA SMIC MUX7", "SWR_DMIC6", "VA SWR_MIC6"},
{"VA SMIC MUX7", "SWR_DMIC7", "VA SWR_MIC7"},
+ {"VA DMIC0", NULL, "VA_SWR_INTR"},
+ {"VA DMIC1", NULL, "VA_SWR_INTR"},
+ {"VA DMIC2", NULL, "VA_SWR_INTR"},
+ {"VA DMIC3", NULL, "VA_SWR_INTR"},
+ {"VA DMIC4", NULL, "VA_SWR_INTR"},
+ {"VA DMIC5", NULL, "VA_SWR_INTR"},
+ {"VA DMIC6", NULL, "VA_SWR_INTR"},
+ {"VA DMIC7", NULL, "VA_SWR_INTR"},
+
{"VA SWR_ADC0", NULL, "VA_SWR_PWR"},
{"VA SWR_ADC1", NULL, "VA_SWR_PWR"},
{"VA SWR_ADC2", NULL, "VA_SWR_PWR"},
diff --git a/asoc/codecs/rouleur/internal.h b/asoc/codecs/rouleur/internal.h
index df8541e..233ca51 100644
--- a/asoc/codecs/rouleur/internal.h
+++ b/asoc/codecs/rouleur/internal.h
@@ -170,4 +170,6 @@
extern int rouleur_get_micb_vout_ctl_val(u32 micb_mv);
extern int rouleur_micbias_control(struct snd_soc_component *component,
int micb_num, int req, bool is_dapm);
+extern int rouleur_global_mbias_enable(struct snd_soc_component *component);
+extern int rouleur_global_mbias_disable(struct snd_soc_component *component);
#endif
diff --git a/asoc/codecs/rouleur/rouleur-mbhc.c b/asoc/codecs/rouleur/rouleur-mbhc.c
index 2f8e954..f0eea09 100644
--- a/asoc/codecs/rouleur/rouleur-mbhc.c
+++ b/asoc/codecs/rouleur/rouleur-mbhc.c
@@ -22,20 +22,15 @@
#define ROULEUR_ZDET_SUPPORTED true
/* Z value defined in milliohm */
-#define ROULEUR_ZDET_VAL_32 32000
-#define ROULEUR_ZDET_VAL_400 400000
-#define ROULEUR_ZDET_VAL_1200 1200000
#define ROULEUR_ZDET_VAL_100K 100000000
/* Z floating defined in ohms */
#define ROULEUR_ZDET_FLOATING_IMPEDANCE 0x0FFFFFFE
-#define ROULEUR_ZDET_NUM_MEASUREMENTS 900
-#define ROULEUR_MBHC_GET_C1(c) ((c & 0xC000) >> 14)
-#define ROULEUR_MBHC_GET_X1(x) (x & 0x3FFF)
-/* Z value compared in milliOhm */
-#define ROULEUR_MBHC_IS_SECOND_RAMP_REQUIRED(z) ((z > 400000) || (z < 32000))
-#define ROULEUR_MBHC_ZDET_CONST (86 * 16384)
-#define ROULEUR_MBHC_MOISTURE_RREF R_24_KOHM
+#define ROULEUR_ZDET_NUM_MEASUREMENTS 100
+#define ROULEUR_ZDET_RMAX 1280000
+#define ROULEUR_ZDET_C1 7500000
+#define ROULEUR_ZDET_C2 187
+#define ROULEUR_ZDET_C3 4500
/* Cross connection thresholds in mV */
#define ROULEUR_HPHL_CROSS_CONN_THRESHOLD 200
@@ -157,9 +152,6 @@
u16 ldo_ctl;
u16 noff;
u16 nshift;
- u16 btn5;
- u16 btn6;
- u16 btn7;
};
static int rouleur_mbhc_request_irq(struct snd_soc_component *component,
@@ -380,174 +372,180 @@
return rc;
}
-static inline void rouleur_mbhc_get_result_params(struct rouleur_priv *rouleur,
- s16 *d1_a, u16 noff,
- int32_t *zdet)
+static void rouleur_mbhc_get_result_params(struct rouleur_priv *rouleur,
+ struct snd_soc_component *component,
+ int32_t *zdet)
{
int i;
- int val = 0, val1 = 0;
- s16 c1 = 0;
- s32 x1 = 0, d1 = 0;
- int32_t denom;
- int minCode_param[] = {
- 3277, 1639, 820, 410, 205, 103, 52, 26
- };
+ int zcode = 0, zcode1 = 0, zdet_cal_result = 0, zdet_est_range = 0;
+ int noff = 0, ndac = 14;
+ int zdet_cal_coeff = 0, div_ratio = 0;
+ int num = 0, denom = 0;
+ /* Charge enable and wait for zcode to be updated */
regmap_update_bits(rouleur->regmap, ROULEUR_ANA_MBHC_ZDET, 0x20, 0x20);
for (i = 0; i < ROULEUR_ZDET_NUM_MEASUREMENTS; i++) {
- regmap_read(rouleur->regmap, ROULEUR_ANA_MBHC_RESULT_2, &val);
- if (val & 0x80)
+ regmap_read(rouleur->regmap, ROULEUR_ANA_MBHC_RESULT_2, &zcode);
+ if (zcode & 0x80)
break;
+ usleep_range(200, 210);
}
- val = val << 0x8;
- regmap_read(rouleur->regmap, ROULEUR_ANA_MBHC_RESULT_1, &val1);
- val |= val1;
- regmap_update_bits(rouleur->regmap, ROULEUR_ANA_MBHC_ZDET, 0x20, 0x00);
- x1 = ROULEUR_MBHC_GET_X1(val);
- c1 = ROULEUR_MBHC_GET_C1(val);
- /* If ramp is not complete, give additional 5ms */
- if ((c1 < 2) && x1)
- usleep_range(5000, 5050);
- if (!c1 || !x1) {
+ /* If zcode updation is not complete, give additional 10ms */
+ if (!(zcode & 0x80))
+ usleep_range(10000, 10100);
+
+ regmap_read(rouleur->regmap, ROULEUR_ANA_MBHC_RESULT_2, &zcode);
+ if (!(zcode & 0x80)) {
dev_dbg(rouleur->dev,
- "%s: Impedance detect ramp error, c1=%d, x1=0x%x\n",
- __func__, c1, x1);
- goto ramp_down;
+ "%s: Impedance detect calculation error, zcode=0x%x\n",
+ __func__, zcode);
+ regmap_update_bits(rouleur->regmap, ROULEUR_ANA_MBHC_ZDET,
+ 0x20, 0x00);
+ return;
}
- d1 = d1_a[c1];
- denom = (x1 * d1) - (1 << (14 - noff));
+ zcode = zcode << 0x8;
+ zcode = zcode & 0x3FFF;
+ regmap_read(rouleur->regmap, ROULEUR_ANA_MBHC_RESULT_1, &zcode1);
+ zcode |= zcode1;
+
+ dev_dbg(rouleur->dev,
+ "%s: zcode: %d, zcode1: %d\n", __func__, zcode, zcode1);
+
+ /* Calculate calibration coefficient */
+ zdet_cal_result = (snd_soc_component_read32(component,
+ ROULEUR_ANA_MBHC_ZDET_CALIB_RESULT)) & 0x1F;
+ zdet_cal_coeff = ROULEUR_ZDET_C1 /
+ ((ROULEUR_ZDET_C2 * zdet_cal_result) + ROULEUR_ZDET_C3);
+ /* Rload calculation */
+ zdet_est_range = (snd_soc_component_read32(component,
+ ROULEUR_ANA_MBHC_ZDET_CALIB_RESULT) & 0x60) >> 5;
+
+ dev_dbg(rouleur->dev,
+ "%s: zdet_cal_result: %d, zdet_cal_coeff: %d, zdet_est_range: %d\n",
+ __func__, zdet_cal_result, zdet_cal_coeff, zdet_est_range);
+ switch (zdet_est_range) {
+ case 0:
+ default:
+ noff = 0;
+ div_ratio = 320;
+ break;
+ case 1:
+ noff = 0;
+ div_ratio = 64;
+ break;
+ case 2:
+ noff = 4;
+ div_ratio = 64;
+ break;
+ case 3:
+ noff = 5;
+ div_ratio = 40;
+ break;
+ }
+
+ num = zdet_cal_coeff * ROULEUR_ZDET_RMAX;
+ denom = ((zcode * div_ratio * 100) - (1 << (ndac - noff)) * 1000);
+ dev_dbg(rouleur->dev,
+ "%s: num: %d, denom: %d\n", __func__, num, denom);
if (denom > 0)
- *zdet = (ROULEUR_MBHC_ZDET_CONST * 1000) / denom;
- else if (x1 < minCode_param[noff])
+ *zdet = (int32_t) ((num / denom) * 1000);
+ else
*zdet = ROULEUR_ZDET_FLOATING_IMPEDANCE;
- dev_dbg(rouleur->dev, "%s: d1=%d, c1=%d, x1=0x%x, z_val=%d(milliOhm)\n",
- __func__, d1, c1, x1, *zdet);
-ramp_down:
- i = 0;
- while (x1) {
- regmap_read(rouleur->regmap, ROULEUR_ANA_MBHC_RESULT_1, &val);
- regmap_read(rouleur->regmap, ROULEUR_ANA_MBHC_RESULT_2, &val1);
- val = val << 0x8;
- val |= val1;
- x1 = ROULEUR_MBHC_GET_X1(val);
- i++;
- if (i == ROULEUR_ZDET_NUM_MEASUREMENTS)
- break;
- }
+ dev_dbg(rouleur->dev, "%s: z_val=%d(milliOhm)\n",
+ __func__, *zdet);
+ /* Start discharge */
+ regmap_update_bits(rouleur->regmap, ROULEUR_ANA_MBHC_ZDET, 0x20, 0x00);
}
-#if 0
-static void rouleur_mbhc_zdet_ramp(struct snd_soc_component *component,
- struct rouleur_mbhc_zdet_param *zdet_param,
- int32_t *zl, int32_t *zr, s16 *d1_a)
+static void rouleur_mbhc_zdet_start(struct snd_soc_component *component,
+ int32_t *zl, int32_t *zr)
{
struct rouleur_priv *rouleur = dev_get_drvdata(component->dev);
int32_t zdet = 0;
- snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_ZDET_ANA_CTL,
- 0x70, zdet_param->ldo_ctl << 4);
- snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_BTN5, 0xFC,
- zdet_param->btn5);
- snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_BTN6, 0xFC,
- zdet_param->btn6);
- snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_BTN7, 0xFC,
- zdet_param->btn7);
- snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_ZDET_ANA_CTL,
- 0x0F, zdet_param->noff);
- snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_ZDET_RAMP_CTL,
- 0x0F, zdet_param->nshift);
-
if (!zl)
goto z_right;
- /* Start impedance measurement for HPH_L */
+
+ /* HPHL pull down switch to force OFF */
+ regmap_update_bits(rouleur->regmap,
+ ROULEUR_ANA_HPHPA_CNP_CTL_2, 0x30, 0x00);
+ /* Averaging enable for reliable results */
+ regmap_update_bits(rouleur->regmap,
+ ROULEUR_ANA_MBHC_ZDET_ANA_CTL, 0x80, 0x80);
+ /* ZDET left measurement enable */
regmap_update_bits(rouleur->regmap,
ROULEUR_ANA_MBHC_ZDET, 0x80, 0x80);
- dev_dbg(rouleur->dev, "%s: ramp for HPH_L, noff = %d\n",
- __func__, zdet_param->noff);
- rouleur_mbhc_get_result_params(rouleur, d1_a, zdet_param->noff, &zdet);
+ /* Calculate the left Rload result */
+ rouleur_mbhc_get_result_params(rouleur, component, &zdet);
+
regmap_update_bits(rouleur->regmap,
ROULEUR_ANA_MBHC_ZDET, 0x80, 0x00);
+ regmap_update_bits(rouleur->regmap,
+ ROULEUR_ANA_MBHC_ZDET_ANA_CTL, 0x80, 0x00);
+ regmap_update_bits(rouleur->regmap,
+ ROULEUR_ANA_HPHPA_CNP_CTL_2, 0x30, 0x20);
*zl = zdet;
z_right:
if (!zr)
return;
- /* Start impedance measurement for HPH_R */
+ /* HPHR pull down switch to force OFF */
+ regmap_update_bits(rouleur->regmap,
+ ROULEUR_ANA_HPHPA_CNP_CTL_2, 0x0C, 0x00);
+ /* Averaging enable for reliable results */
+ regmap_update_bits(rouleur->regmap,
+ ROULEUR_ANA_MBHC_ZDET_ANA_CTL, 0x80, 0x80);
+ /* ZDET right measurement enable */
regmap_update_bits(rouleur->regmap,
ROULEUR_ANA_MBHC_ZDET, 0x40, 0x40);
- dev_dbg(rouleur->dev, "%s: ramp for HPH_R, noff = %d\n",
- __func__, zdet_param->noff);
- rouleur_mbhc_get_result_params(rouleur, d1_a, zdet_param->noff, &zdet);
+
+ /* Calculate the right Rload result */
+ rouleur_mbhc_get_result_params(rouleur, component, &zdet);
+
regmap_update_bits(rouleur->regmap,
ROULEUR_ANA_MBHC_ZDET, 0x40, 0x00);
+ regmap_update_bits(rouleur->regmap,
+ ROULEUR_ANA_MBHC_ZDET_ANA_CTL, 0x80, 0x00);
+ regmap_update_bits(rouleur->regmap,
+ ROULEUR_ANA_HPHPA_CNP_CTL_2, 0x0C, 0x08);
*zr = zdet;
}
-static inline void rouleur_wcd_mbhc_qfuse_cal(
- struct snd_soc_component *component,
- int32_t *z_val, int flag_l_r)
-{
- s16 q1;
- int q1_cal;
-
- if (*z_val < (ROULEUR_ZDET_VAL_400/1000))
- q1 = snd_soc_component_read32(component,
- ROULEUR_DIGITAL_EFUSE_REG_23 + (2 * flag_l_r));
- else
- q1 = snd_soc_component_read32(component,
- ROULEUR_DIGITAL_EFUSE_REG_24 + (2 * flag_l_r));
- if (q1 & 0x80)
- q1_cal = (10000 - ((q1 & 0x7F) * 25));
- else
- q1_cal = (10000 + (q1 * 25));
- if (q1_cal > 0)
- *z_val = ((*z_val) * 10000) / q1_cal;
-}
-
static void rouleur_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl,
uint32_t *zr)
{
struct snd_soc_component *component = mbhc->component;
struct rouleur_priv *rouleur = dev_get_drvdata(component->dev);
- s16 reg0, reg1, reg2, reg3, reg4;
+ s16 reg0;
int32_t z1L, z1R, z1Ls;
int zMono, z_diff1, z_diff2;
bool is_fsm_disable = false;
- struct rouleur_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 */
- };
- struct rouleur_mbhc_zdet_param *zdet_param_ptr = NULL;
- s16 d1_a[][4] = {
- {0, 30, 90, 30},
- {0, 30, 30, 5},
- {0, 30, 30, 5},
- {0, 30, 30, 5},
- };
- s16 *d1 = NULL;
WCD_MBHC_RSC_ASSERT_LOCKED(mbhc);
- reg0 = snd_soc_component_read32(component, ROULEUR_ANA_MBHC_BTN5);
- reg1 = snd_soc_component_read32(component, ROULEUR_ANA_MBHC_BTN6);
- reg2 = snd_soc_component_read32(component, ROULEUR_ANA_MBHC_BTN7);
- reg3 = snd_soc_component_read32(component, ROULEUR_MBHC_CTL_CLK);
- reg4 = snd_soc_component_read32(component,
- ROULEUR_ANA_MBHC_ZDET_ANA_CTL);
+ reg0 = snd_soc_component_read32(component, ROULEUR_ANA_MBHC_ELECT);
- if (snd_soc_component_read32(component, ROULEUR_ANA_MBHC_ELECT) &
- 0x80) {
+ if (reg0 & 0x80) {
is_fsm_disable = true;
regmap_update_bits(rouleur->regmap,
ROULEUR_ANA_MBHC_ELECT, 0x80, 0x00);
}
+ /* Enable electrical bias */
+ snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_ELECT,
+ 0x01, 0x01);
+
+ /* Enable codec main bias */
+ rouleur_global_mbias_enable(component);
+
+ /* Enable RCO clock */
+ snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_CTL_1,
+ 0x80, 0x80);
+
/* For NO-jack, disable L_DET_EN before Z-det measurements */
if (mbhc->hphl_swh)
regmap_update_bits(rouleur->regmap,
@@ -557,79 +555,34 @@
regmap_update_bits(rouleur->regmap,
ROULEUR_ANA_MBHC_MECH, 0x01, 0x00);
- /* Disable surge protection before impedance detection.
+ /*
+ * Disable surge protection before impedance detection.
* This is done to give correct value for high impedance.
*/
- regmap_update_bits(rouleur->regmap,
- ROULEUR_HPH_SURGE_HPHLR_SURGE_EN, 0xC0, 0x00);
+ snd_soc_component_update_bits(component, ROULEUR_ANA_SURGE_EN,
+ 0xC0, 0x00);
/* 1ms delay needed after disable surge protection */
usleep_range(1000, 1010);
- /* First get impedance on Left */
- d1 = d1_a[1];
- zdet_param_ptr = &zdet_param[1];
- rouleur_mbhc_zdet_ramp(component, zdet_param_ptr, &z1L, NULL, d1);
-
- if (!ROULEUR_MBHC_IS_SECOND_RAMP_REQUIRED(z1L))
- goto left_ch_impedance;
-
- /* Second ramp for left ch */
- if (z1L < ROULEUR_ZDET_VAL_32) {
- zdet_param_ptr = &zdet_param[0];
- d1 = d1_a[0];
- } else if ((z1L > ROULEUR_ZDET_VAL_400) &&
- (z1L <= ROULEUR_ZDET_VAL_1200)) {
- zdet_param_ptr = &zdet_param[2];
- d1 = d1_a[2];
- } else if (z1L > ROULEUR_ZDET_VAL_1200) {
- zdet_param_ptr = &zdet_param[3];
- d1 = d1_a[3];
- }
- rouleur_mbhc_zdet_ramp(component, zdet_param_ptr, &z1L, NULL, d1);
-
-left_ch_impedance:
+ /* Start of left ch impedance calculation */
+ rouleur_mbhc_zdet_start(component, &z1L, NULL);
if ((z1L == ROULEUR_ZDET_FLOATING_IMPEDANCE) ||
- (z1L > ROULEUR_ZDET_VAL_100K)) {
+ (z1L > ROULEUR_ZDET_VAL_100K))
*zl = ROULEUR_ZDET_FLOATING_IMPEDANCE;
- zdet_param_ptr = &zdet_param[1];
- d1 = d1_a[1];
- } else {
+ else
*zl = z1L/1000;
- rouleur_wcd_mbhc_qfuse_cal(component, zl, 0);
- }
+
dev_dbg(component->dev, "%s: impedance on HPH_L = %d(ohms)\n",
__func__, *zl);
- /* Start of right impedance ramp and calculation */
- rouleur_mbhc_zdet_ramp(component, zdet_param_ptr, NULL, &z1R, d1);
- if (ROULEUR_MBHC_IS_SECOND_RAMP_REQUIRED(z1R)) {
- if (((z1R > ROULEUR_ZDET_VAL_1200) &&
- (zdet_param_ptr->noff == 0x6)) ||
- ((*zl) != ROULEUR_ZDET_FLOATING_IMPEDANCE))
- goto right_ch_impedance;
- /* Second ramp for right ch */
- if (z1R < ROULEUR_ZDET_VAL_32) {
- zdet_param_ptr = &zdet_param[0];
- d1 = d1_a[0];
- } else if ((z1R > ROULEUR_ZDET_VAL_400) &&
- (z1R <= ROULEUR_ZDET_VAL_1200)) {
- zdet_param_ptr = &zdet_param[2];
- d1 = d1_a[2];
- } else if (z1R > ROULEUR_ZDET_VAL_1200) {
- zdet_param_ptr = &zdet_param[3];
- d1 = d1_a[3];
- }
- rouleur_mbhc_zdet_ramp(component, zdet_param_ptr, NULL,
- &z1R, d1);
- }
-right_ch_impedance:
+ /* Start of right ch impedance calculation */
+ rouleur_mbhc_zdet_start(component, NULL, &z1R);
if ((z1R == ROULEUR_ZDET_FLOATING_IMPEDANCE) ||
- (z1R > ROULEUR_ZDET_VAL_100K)) {
+ (z1R > ROULEUR_ZDET_VAL_100K))
*zr = ROULEUR_ZDET_FLOATING_IMPEDANCE;
- } else {
+ else
*zr = z1R/1000;
- rouleur_wcd_mbhc_qfuse_cal(component, zr, 1);
- }
+
dev_dbg(component->dev, "%s: impedance on HPH_R = %d(ohms)\n",
__func__, *zr);
@@ -651,24 +604,10 @@
mbhc->hph_type = WCD_MBHC_HPH_MONO;
goto zdet_complete;
}
- snd_soc_component_update_bits(component, ROULEUR_HPH_R_ATEST,
- 0x02, 0x02);
- snd_soc_component_update_bits(component, ROULEUR_HPH_PA_CTL2,
- 0x40, 0x01);
- if (*zl < (ROULEUR_ZDET_VAL_32/1000))
- rouleur_mbhc_zdet_ramp(component, &zdet_param[0], &z1Ls,
- NULL, d1);
- else
- rouleur_mbhc_zdet_ramp(component, &zdet_param[1], &z1Ls,
- NULL, d1);
- snd_soc_component_update_bits(component, ROULEUR_HPH_PA_CTL2,
- 0x40, 0x00);
- snd_soc_component_update_bits(component, ROULEUR_HPH_R_ATEST,
- 0x02, 0x00);
- z1Ls /= 1000;
- rouleur_wcd_mbhc_qfuse_cal(component, &z1Ls, 0);
- /* Parallel of left Z and 9 ohm pull down resistor */
- zMono = ((*zl) * 9) / ((*zl) + 9);
+
+ z1Ls = z1L/1000;
+ /* Parallel of left Z and 20 ohm pull down resistor */
+ zMono = ((*zl) * 20) / ((*zl) + 20);
z_diff1 = (z1Ls > zMono) ? (z1Ls - zMono) : (zMono - z1Ls);
z_diff2 = ((*zl) > z1Ls) ? ((*zl) - z1Ls) : (z1Ls - (*zl));
if ((z_diff1 * (*zl + z1Ls)) > (z_diff2 * (z1Ls + zMono))) {
@@ -681,13 +620,10 @@
mbhc->hph_type = WCD_MBHC_HPH_MONO;
}
+zdet_complete:
/* Enable surge protection again after impedance detection */
regmap_update_bits(rouleur->regmap,
- ROULEUR_HPH_SURGE_HPHLR_SURGE_EN, 0xC0, 0xC0);
-zdet_complete:
- snd_soc_component_write(component, ROULEUR_ANA_MBHC_BTN5, reg0);
- snd_soc_component_write(component, ROULEUR_ANA_MBHC_BTN6, reg1);
- snd_soc_component_write(component, ROULEUR_ANA_MBHC_BTN7, reg2);
+ ROULEUR_ANA_SURGE_EN, 0xC0, 0xC0);
/* Turn on 100k pull down on HPHL */
regmap_update_bits(rouleur->regmap,
ROULEUR_ANA_MBHC_MECH, 0x01, 0x01);
@@ -697,13 +633,14 @@
regmap_update_bits(rouleur->regmap,
ROULEUR_ANA_MBHC_MECH, 0x80, 0x80);
- snd_soc_component_write(component, ROULEUR_ANA_MBHC_ZDET_ANA_CTL, reg4);
- snd_soc_component_write(component, ROULEUR_MBHC_CTL_CLK, reg3);
+ /* Restore electrical bias state */
+ snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_ELECT, 0x01,
+ reg0 >> 7);
if (is_fsm_disable)
regmap_update_bits(rouleur->regmap,
ROULEUR_ANA_MBHC_ELECT, 0x80, 0x80);
+ rouleur_global_mbias_disable(component);
}
-#endif
static void rouleur_mbhc_gnd_det_ctrl(struct snd_soc_component *component,
bool enable)
@@ -727,10 +664,10 @@
if (enable) {
snd_soc_component_update_bits(component,
ROULEUR_ANA_HPHPA_CNP_CTL_2,
- 0x30, 0x10);
+ 0x30, 0x20);
snd_soc_component_update_bits(component,
ROULEUR_ANA_HPHPA_CNP_CTL_2,
- 0x0C, 0x04);
+ 0x0C, 0x08);
} else {
snd_soc_component_update_bits(component,
ROULEUR_ANA_HPHPA_CNP_CTL_2,
@@ -843,10 +780,10 @@
{
if (az_enable)
snd_soc_component_update_bits(mbhc->component,
- ROULEUR_ANA_MBHC_MCLK, 0x08, 0x08);
+ ROULEUR_ANA_MBHC_CTL_CLK, 0x08, 0x08);
else
snd_soc_component_update_bits(mbhc->component,
- ROULEUR_ANA_MBHC_MCLK, 0x08, 0x00);
+ ROULEUR_ANA_MBHC_CTL_CLK, 0x08, 0x00);
}
@@ -889,7 +826,7 @@
.mbhc_micb_ramp_control = rouleur_mbhc_micb_ramp_control,
.get_hwdep_fw_cal = rouleur_get_hwdep_fw_cal,
.mbhc_micb_ctrl_thr_mic = rouleur_mbhc_micb_ctrl_threshold_mic,
- //.compute_impedance = rouleur_wcd_mbhc_calc_impedance,
+ .compute_impedance = rouleur_wcd_mbhc_calc_impedance,
.mbhc_gnd_det_ctrl = rouleur_mbhc_gnd_det_ctrl,
.hph_pull_down_ctrl = rouleur_mbhc_hph_pull_down_ctrl,
.mbhc_moisture_config = rouleur_mbhc_moisture_config,
diff --git a/asoc/codecs/rouleur/rouleur-registers.h b/asoc/codecs/rouleur/rouleur-registers.h
index 816e492..8cc0ae4 100644
--- a/asoc/codecs/rouleur/rouleur-registers.h
+++ b/asoc/codecs/rouleur/rouleur-registers.h
@@ -45,7 +45,7 @@
#define ROULEUR_ANA_MBHC_ZDET_RAMP_CTL (ROULEUR_ANA_BASE_ADDR+0x06A)
#define ROULEUR_ANA_MBHC_FSM_STATUS (ROULEUR_ANA_BASE_ADDR+0x06B)
#define ROULEUR_ANA_MBHC_ADC_RESULT (ROULEUR_ANA_BASE_ADDR+0x06C)
-#define ROULEUR_ANA_MBHC_MCLK (ROULEUR_ANA_BASE_ADDR+0x06D)
+#define ROULEUR_ANA_MBHC_CTL_CLK (ROULEUR_ANA_BASE_ADDR+0x06D)
#define ROULEUR_ANA_MBHC_ZDET_CALIB_RESULT (ROULEUR_ANA_BASE_ADDR+0x072)
#define ROULEUR_ANA_NCP_EN (ROULEUR_ANA_BASE_ADDR+0x077)
#define ROULEUR_ANA_HPHPA_CNP_CTL_1 (ROULEUR_ANA_BASE_ADDR+0x083)
diff --git a/asoc/codecs/rouleur/rouleur-regmap.c b/asoc/codecs/rouleur/rouleur-regmap.c
index 08b490d..23b8ddc 100644
--- a/asoc/codecs/rouleur/rouleur-regmap.c
+++ b/asoc/codecs/rouleur/rouleur-regmap.c
@@ -38,7 +38,7 @@
{ ROULEUR_ANA_MBHC_ZDET_RAMP_CTL, 0x00 },
{ ROULEUR_ANA_MBHC_FSM_STATUS, 0x00 },
{ ROULEUR_ANA_MBHC_ADC_RESULT, 0x00 },
- { ROULEUR_ANA_MBHC_MCLK, 0x30 },
+ { ROULEUR_ANA_MBHC_CTL_CLK, 0x30 },
{ ROULEUR_ANA_MBHC_ZDET_CALIB_RESULT, 0x00 },
{ ROULEUR_ANA_NCP_EN, 0x00 },
{ ROULEUR_ANA_HPHPA_CNP_CTL_1, 0x54 },
diff --git a/asoc/codecs/rouleur/rouleur-tables.c b/asoc/codecs/rouleur/rouleur-tables.c
index 59b7cf2..7912267 100644
--- a/asoc/codecs/rouleur/rouleur-tables.c
+++ b/asoc/codecs/rouleur/rouleur-tables.c
@@ -33,7 +33,7 @@
[ROULEUR_REG(ROULEUR_ANA_MBHC_ZDET_RAMP_CTL)] = RD_WR_REG,
[ROULEUR_REG(ROULEUR_ANA_MBHC_FSM_STATUS)] = RD_REG,
[ROULEUR_REG(ROULEUR_ANA_MBHC_ADC_RESULT)] = RD_REG,
- [ROULEUR_REG(ROULEUR_ANA_MBHC_MCLK)] = RD_WR_REG,
+ [ROULEUR_REG(ROULEUR_ANA_MBHC_CTL_CLK)] = RD_WR_REG,
[ROULEUR_REG(ROULEUR_ANA_MBHC_ZDET_CALIB_RESULT)] = RD_REG,
[ROULEUR_REG(ROULEUR_ANA_NCP_EN)] = RD_WR_REG,
[ROULEUR_REG(ROULEUR_ANA_HPHPA_CNP_CTL_1)] = RD_WR_REG,
diff --git a/asoc/codecs/rouleur/rouleur.c b/asoc/codecs/rouleur/rouleur.c
index e1ecdba..480e0ce 100644
--- a/asoc/codecs/rouleur/rouleur.c
+++ b/asoc/codecs/rouleur/rouleur.c
@@ -304,7 +304,7 @@
return ret;
}
-static int rouleur_global_mbias_enable(struct snd_soc_component *component)
+int rouleur_global_mbias_enable(struct snd_soc_component *component)
{
struct rouleur_priv *rouleur = snd_soc_component_get_drvdata(component);
@@ -322,7 +322,7 @@
return 0;
}
-static int rouleur_global_mbias_disable(struct snd_soc_component *component)
+int rouleur_global_mbias_disable(struct snd_soc_component *component)
{
struct rouleur_priv *rouleur = snd_soc_component_get_drvdata(component);
@@ -472,7 +472,7 @@
}
snd_soc_component_update_bits(component,
ROULEUR_DIG_SWR_CDC_RX0_CTL,
- 0x7C, 0x7C);
+ 0x80, 0x00);
snd_soc_component_update_bits(component,
ROULEUR_DIG_SWR_CDC_RX_GAIN_CTL,
0x04, 0x04);
@@ -486,6 +486,9 @@
snd_soc_component_update_bits(component,
ROULEUR_DIG_SWR_CDC_RX_GAIN_CTL,
0x04, 0x00);
+ snd_soc_component_update_bits(component,
+ ROULEUR_DIG_SWR_CDC_RX0_CTL,
+ 0x80, 0x80);
if (rouleur->comp1_enable)
snd_soc_component_update_bits(component,
ROULEUR_DIG_SWR_CDC_COMP_CTL_0,
@@ -544,7 +547,7 @@
}
snd_soc_component_update_bits(component,
ROULEUR_DIG_SWR_CDC_RX1_CTL,
- 0x7C, 0x7C);
+ 0x80, 0x00);
snd_soc_component_update_bits(component,
ROULEUR_DIG_SWR_CDC_RX_GAIN_CTL,
0x08, 0x08);
@@ -557,6 +560,9 @@
snd_soc_component_update_bits(component,
ROULEUR_DIG_SWR_CDC_RX_GAIN_CTL,
0x08, 0x00);
+ snd_soc_component_update_bits(component,
+ ROULEUR_DIG_SWR_CDC_RX1_CTL,
+ 0x80, 0x80);
if (rouleur->comp2_enable)
snd_soc_component_update_bits(component,
ROULEUR_DIG_SWR_CDC_COMP_CTL_0,
@@ -583,7 +589,7 @@
rouleur_rx_clk_enable(component);
snd_soc_component_update_bits(component,
ROULEUR_DIG_SWR_CDC_RX0_CTL,
- 0x7C, 0x7C);
+ 0x80, 0x00);
snd_soc_component_update_bits(component,
ROULEUR_DIG_SWR_CDC_RX_GAIN_CTL,
0x04, 0x04);
@@ -599,6 +605,9 @@
snd_soc_component_update_bits(component,
ROULEUR_DIG_SWR_CDC_RX_GAIN_CTL,
0x04, 0x00);
+ snd_soc_component_update_bits(component,
+ ROULEUR_DIG_SWR_CDC_RX0_CTL,
+ 0x80, 0x80);
break;
};
diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c
index abd3106..26174dc 100644
--- a/asoc/codecs/wcd938x/wcd938x.c
+++ b/asoc/codecs/wcd938x/wcd938x.c
@@ -1377,8 +1377,7 @@
/* enable clock scaling */
snd_soc_component_update_bits(component,
WCD938X_DIGITAL_CDC_DMIC_CTL, 0x06, 0x06);
- wcd938x_tx_connect_port(component, DMIC0 + (w->shift),
- SWR_CLK_RATE_2P4MHZ, true);
+ wcd938x_tx_connect_port(component, DMIC0 + (w->shift), 0, true);
break;
case SND_SOC_DAPM_POST_PMD:
wcd938x_tx_connect_port(component, DMIC0 + (w->shift), 0,
diff --git a/asoc/codecs/wsa883x/internal.h b/asoc/codecs/wsa883x/internal.h
index 1863aac..83cef64 100644
--- a/asoc/codecs/wsa883x/internal.h
+++ b/asoc/codecs/wsa883x/internal.h
@@ -125,7 +125,6 @@
void *handle;
int (*register_notifier)(void *handle,
struct notifier_block *nblock, bool enable);
- struct delayed_work vbat_work;
struct cdc_regulator *regulator;
int num_supplies;
struct regulator_bulk_data *supplies;
diff --git a/asoc/codecs/wsa883x/wsa883x.c b/asoc/codecs/wsa883x/wsa883x.c
index 9e25e53..8433185 100644
--- a/asoc/codecs/wsa883x/wsa883x.c
+++ b/asoc/codecs/wsa883x/wsa883x.c
@@ -36,11 +36,7 @@
#define HIGH_TEMP_THRESHOLD 45
#define TEMP_INVALID 0xFFFF
#define WSA883X_TEMP_RETRY 3
-#define WSA883X_VBAT_TIMER_SEC 2
-static int wsa883x_vbat_timer_sec = WSA883X_VBAT_TIMER_SEC;
-module_param(wsa883x_vbat_timer_sec, int, 0664);
-MODULE_PARM_DESC(wsa883x_vbat_timer_sec, "timer for VBAT monitor polling");
#define DRV_NAME "wsa-codec"
@@ -92,9 +88,10 @@
{WSA883X_DRE_CTL_0, 0xF0, 0x90},
{WSA883X_DRE_IDLE_DET_CTL, 0x10, 0x00},
{WSA883X_PDM_WD_CTL, 0x01, 0x01},
- {WSA883X_CURRENT_LIMIT, 0x78, 0x40},
+ {WSA883X_CURRENT_LIMIT, 0x78, 0x20},
{WSA883X_DRE_CTL_0, 0x07, 0x02},
- {WSA883X_VAGC_TIME, 0x03, 0x02},
+ {WSA883X_VAGC_TIME, 0x0F, 0x0F},
+ {WSA883X_VAGC_ATTN_LVL_3, 0x07, 0x02},
{WSA883X_VAGC_CTL, 0x01, 0x01},
{WSA883X_TAGC_CTL, 0x0E, 0x0A},
{WSA883X_TAGC_TIME, 0x0C, 0x0C},
@@ -985,24 +982,9 @@
/* Force remove group */
swr_remove_from_group(wsa883x->swr_slave,
wsa883x->swr_slave->dev_num);
- snd_soc_component_update_bits(component,
- WSA883X_VBAT_ADC_FLT_CTL,
- 0x0E, 0x06);
- snd_soc_component_update_bits(component,
- WSA883X_VBAT_ADC_FLT_CTL,
- 0x01, 0x01);
- schedule_delayed_work(&wsa883x->vbat_work,
- msecs_to_jiffies(wsa883x_vbat_timer_sec * 1000));
set_bit(SPKR_STATUS, &wsa883x->status_mask);
break;
case SND_SOC_DAPM_PRE_PMD:
- cancel_delayed_work_sync(&wsa883x->vbat_work);
- snd_soc_component_update_bits(component,
- WSA883X_VBAT_ADC_FLT_CTL,
- 0x01, 0x00);
- snd_soc_component_update_bits(component,
- WSA883X_VBAT_ADC_FLT_CTL,
- 0x0E, 0x00);
snd_soc_component_update_bits(component, WSA883X_PA_FSM_CTL,
0x01, 0x00);
wcd_disable_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_PDM_WD);
@@ -1172,37 +1154,6 @@
return ret;
}
-static void wsa883x_vbat_monitor_work(struct work_struct *work)
-{
- struct wsa883x_priv *wsa883x;
- struct delayed_work *dwork;
- struct snd_soc_component *component;
- u16 val = 0, vbat_code = 0;
- int vbat_val = 0;
-
- dwork = to_delayed_work(work);
- wsa883x = container_of(dwork, struct wsa883x_priv, vbat_work);
- component = wsa883x->component;
-
- val = snd_soc_component_read32(component, WSA883X_VBAT_DIN_MSB);
- vbat_code = (val << 2);
- val = (snd_soc_component_read32(component, WSA883X_VBAT_DIN_LSB)
- & 0xC0);
- vbat_code |= (val >> 6);
- vbat_val = ((vbat_code * 5) / 1023);
- dev_dbg(component->dev, "%s: instant vbat code = %d val = %d\n",
- __func__, vbat_code, vbat_val);
-
- val = snd_soc_component_read32(component, WSA883X_VBAT_DOUT);
- vbat_val = ((val * 5) / 255);
-
- dev_dbg(component->dev, "%s: low pass vbat code = %d val = %d\n",
- __func__, val, vbat_val);
-
- schedule_delayed_work(&wsa883x->vbat_work,
- msecs_to_jiffies(wsa883x_vbat_timer_sec * 1000));
-}
-
static int wsa883x_codec_probe(struct snd_soc_component *component)
{
struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component);
@@ -1226,7 +1177,6 @@
wsa883x_codec_init(component);
wsa883x->global_pa_cnt = 0;
- INIT_DELAYED_WORK(&wsa883x->vbat_work, wsa883x_vbat_monitor_work);
return 0;
}
@@ -1324,8 +1274,6 @@
switch (event) {
case BOLERO_WSA_EVT_PA_OFF_PRE_SSR:
- if (delayed_work_pending(&wsa883x->vbat_work))
- cancel_delayed_work_sync(&wsa883x->vbat_work);
snd_soc_component_update_bits(wsa883x->component,
WSA883X_PA_FSM_CTL,
0x01, 0x00);
diff --git a/asoc/msm-compress-q6-v2.c b/asoc/msm-compress-q6-v2.c
index fdf61cf..b34202c 100644
--- a/asoc/msm-compress-q6-v2.c
+++ b/asoc/msm-compress-q6-v2.c
@@ -225,7 +225,7 @@
int stream_id);
static int msm_compr_set_render_mode(struct msm_compr_audio *prtd,
- uint32_t render_mode) {
+ uint32_t render_mode, int dir) {
int ret = -EINVAL;
struct audio_client *ac = prtd->audio_client;
@@ -250,7 +250,7 @@
goto exit;
}
- ret = q6asm_send_mtmx_strtr_render_mode(ac, render_mode);
+ ret = q6asm_send_mtmx_strtr_render_mode(ac, render_mode, dir);
if (ret) {
pr_err("%s, Render mode can't be set error %d\n", __func__,
ret);
@@ -324,6 +324,29 @@
return ret;
}
+static int msm_compr_set_ttp_offset(struct audio_client *ac,
+ uint32_t offset_lsw, uint32_t offset_msw, int dir)
+{
+ int ret = -EINVAL;
+ struct asm_session_mtmx_strtr_param_ttp_offset_t ttp_offset;
+ uint32_t param_id;
+
+ pr_debug("%s, ttp offset lsw 0x%x ttp offset msw 0x%x\n",
+ __func__, offset_lsw, offset_msw);
+
+ memset(&ttp_offset, 0,
+ sizeof(struct asm_session_mtmx_strtr_param_ttp_offset_t));
+ ttp_offset.ttp_offset_lsw = offset_lsw;
+ ttp_offset.ttp_offset_msw = offset_msw;
+ param_id = ASM_SESSION_MTMX_STRTR_PARAM_TTP_OFFSET;
+ ret = q6asm_send_mtmx_strtr_ttp_offset(ac, &ttp_offset, param_id, dir);
+ if (ret)
+ pr_err("%s, ttp offset can't be set error %d\n", __func__,
+ ret);
+
+ return ret;
+}
+
static int msm_compr_enable_adjust_session_clock(struct audio_client *ac,
bool enable)
{
@@ -3221,7 +3244,8 @@
__func__, metadata->value[0]);
prtd->gapless_state.initial_samples_drop = metadata->value[0];
} else if (metadata->key == SNDRV_COMPRESS_RENDER_MODE) {
- return msm_compr_set_render_mode(prtd, metadata->value[0]);
+ return msm_compr_set_render_mode(prtd, metadata->value[0],
+ cstream->direction);
} else if (metadata->key == SNDRV_COMPRESS_CLK_REC_MODE) {
return msm_compr_set_clk_rec_mode(ac, metadata->value[0]);
} else if (metadata->key == SNDRV_COMPRESS_RENDER_WINDOW) {
@@ -3242,6 +3266,9 @@
return msm_compr_adjust_session_clock(ac,
metadata->value[0],
metadata->value[1]);
+ } else if (metadata->key == SNDRV_COMPRESS_IN_TTP_OFFSET) {
+ return msm_compr_set_ttp_offset(ac, metadata->value[0],
+ metadata->value[1], cstream->direction);
}
return 0;
diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c
index a0d9895..883d8d8 100644
--- a/asoc/msm-dai-q6-v2.c
+++ b/asoc/msm-dai-q6-v2.c
@@ -232,6 +232,7 @@
u16 afe_tx_out_bitformat;
struct afe_enc_config enc_config;
struct afe_dec_config dec_config;
+ struct afe_ttp_config ttp_config;
union afe_port_config port_config;
u16 vi_feed_mono;
u32 xt_logging_disable;
@@ -2230,6 +2231,7 @@
{
struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev);
int rc = 0;
+ uint16_t ttp_gen_enable = dai_data->ttp_config.ttp_gen_enable.enable;
if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
if (dai_data->enc_config.format != ENC_FMT_NONE) {
@@ -2279,13 +2281,27 @@
bitwidth = 0;
break;
}
- pr_debug("%s: calling AFE_PORT_START_V2 with dec format: %d\n",
- __func__, dai_data->dec_config.format);
- rc = afe_port_start_v2(dai->id, &dai_data->port_config,
- dai_data->rate,
- dai_data->afe_tx_out_channels,
- bitwidth,
- NULL, &dai_data->dec_config);
+
+ if (ttp_gen_enable == true) {
+ pr_debug("%s: calling AFE_PORT_START_V3 with dec format: %d\n",
+ __func__, dai_data->dec_config.format);
+ rc = afe_port_start_v3(dai->id,
+ &dai_data->port_config,
+ dai_data->rate,
+ dai_data->afe_tx_out_channels,
+ bitwidth,
+ NULL, &dai_data->dec_config,
+ &dai_data->ttp_config);
+ } else {
+ pr_debug("%s: calling AFE_PORT_START_V2 with dec format: %d\n",
+ __func__, dai_data->dec_config.format);
+ rc = afe_port_start_v2(dai->id,
+ &dai_data->port_config,
+ dai_data->rate,
+ dai_data->afe_tx_out_channels,
+ bitwidth,
+ NULL, &dai_data->dec_config);
+ }
if (rc < 0) {
pr_err("%s: fail to open AFE port 0x%x\n",
__func__, dai->id);
@@ -2795,7 +2811,6 @@
return rc;
}
-/* all ports with excursion logging requirement can use this digital_mute api */
static int msm_dai_q6_spk_digital_mute(struct snd_soc_dai *dai,
int mute)
{
@@ -3669,6 +3684,91 @@
return ret;
}
+static int msm_dai_q6_afe_enable_ttp_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
+ uinfo->count = sizeof(struct afe_ttp_gen_enable_t);
+
+ return 0;
+}
+
+static int msm_dai_q6_afe_enable_ttp_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data;
+
+ pr_debug("%s:\n", __func__);
+ if (!dai_data) {
+ pr_err("%s: Invalid dai data\n", __func__);
+ return -EINVAL;
+ }
+
+ memcpy(ucontrol->value.bytes.data,
+ &dai_data->ttp_config.ttp_gen_enable,
+ sizeof(struct afe_ttp_gen_enable_t));
+ return 0;
+}
+
+static int msm_dai_q6_afe_enable_ttp_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data;
+
+ pr_debug("%s:\n", __func__);
+ if (!dai_data) {
+ pr_err("%s: Invalid dai data\n", __func__);
+ return -EINVAL;
+ }
+
+ memcpy(&dai_data->ttp_config.ttp_gen_enable,
+ ucontrol->value.bytes.data,
+ sizeof(struct afe_ttp_gen_enable_t));
+ return 0;
+}
+
+static int msm_dai_q6_afe_ttp_cfg_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
+ uinfo->count = sizeof(struct afe_ttp_gen_cfg_t);
+
+ return 0;
+}
+
+static int msm_dai_q6_afe_ttp_cfg_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data;
+
+ pr_debug("%s:\n", __func__);
+ if (!dai_data) {
+ pr_err("%s: Invalid dai data\n", __func__);
+ return -EINVAL;
+ }
+
+ memcpy(ucontrol->value.bytes.data,
+ &dai_data->ttp_config.ttp_gen_cfg,
+ sizeof(struct afe_ttp_gen_cfg_t));
+ return 0;
+}
+
+static int msm_dai_q6_afe_ttp_cfg_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data;
+
+ pr_debug("%s: Received ttp config\n", __func__);
+ if (!dai_data) {
+ pr_err("%s: Invalid dai data\n", __func__);
+ return -EINVAL;
+ }
+
+ memcpy(&dai_data->ttp_config.ttp_gen_cfg,
+ ucontrol->value.bytes.data, sizeof(struct afe_ttp_gen_cfg_t));
+ return 0;
+}
+
static const struct snd_kcontrol_new afe_dec_config_controls[] = {
{
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
@@ -3696,6 +3796,27 @@
msm_dai_q6_afe_output_bit_format_put),
};
+static const struct snd_kcontrol_new afe_ttp_config_controls[] = {
+ {
+ .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
+ SNDRV_CTL_ELEM_ACCESS_INACTIVE),
+ .iface = SNDRV_CTL_ELEM_IFACE_PCM,
+ .name = "TTP Enable",
+ .info = msm_dai_q6_afe_enable_ttp_info,
+ .get = msm_dai_q6_afe_enable_ttp_get,
+ .put = msm_dai_q6_afe_enable_ttp_put,
+ },
+ {
+ .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
+ SNDRV_CTL_ELEM_ACCESS_INACTIVE),
+ .iface = SNDRV_CTL_ELEM_IFACE_PCM,
+ .name = "AFE TTP config",
+ .info = msm_dai_q6_afe_ttp_cfg_info,
+ .get = msm_dai_q6_afe_ttp_cfg_get,
+ .put = msm_dai_q6_afe_ttp_cfg_put,
+ },
+};
+
static int msm_dai_q6_slim_rx_drift_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo)
{
@@ -3919,6 +4040,12 @@
rc = snd_ctl_add(dai->component->card->snd_card,
snd_ctl_new1(&afe_dec_config_controls[3],
dai_data));
+ rc = snd_ctl_add(dai->component->card->snd_card,
+ snd_ctl_new1(&afe_ttp_config_controls[0],
+ dai_data));
+ rc = snd_ctl_add(dai->component->card->snd_card,
+ snd_ctl_new1(&afe_ttp_config_controls[1],
+ dai_data));
break;
case RT_PROXY_DAI_001_RX:
rc = snd_ctl_add(dai->component->card->snd_card,
@@ -12337,7 +12464,8 @@
static void msm_dai_q6_cdc_dma_shutdown(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
- struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev);
+ struct msm_dai_q6_cdc_dma_dai_data *dai_data =
+ dev_get_drvdata(dai->dev);
int rc = 0;
if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
@@ -12356,6 +12484,19 @@
clear_bit(STATUS_PORT_STARTED, dai_data->hwfree_status);
}
+static int msm_dai_q6_cdc_dma_digital_mute(struct snd_soc_dai *dai,
+ int mute)
+{
+ int port_id = dai->id;
+ struct msm_dai_q6_cdc_dma_dai_data *dai_data =
+ dev_get_drvdata(dai->dev);
+
+ if (mute && !dai_data->xt_logging_disable)
+ afe_get_sp_xt_logging_data(port_id);
+
+ return 0;
+}
+
static struct snd_soc_dai_ops msm_dai_q6_cdc_dma_ops = {
.prepare = msm_dai_q6_cdc_dma_prepare,
.hw_params = msm_dai_q6_cdc_dma_hw_params,
@@ -12368,7 +12509,7 @@
.hw_params = msm_dai_q6_cdc_dma_hw_params,
.shutdown = msm_dai_q6_cdc_dma_shutdown,
.set_channel_map = msm_dai_q6_cdc_dma_set_channel_map,
- .digital_mute = msm_dai_q6_spk_digital_mute,
+ .digital_mute = msm_dai_q6_cdc_dma_digital_mute,
};
static struct snd_soc_dai_driver msm_dai_q6_cdc_dma_dai[] = {
diff --git a/asoc/msm-lsm-client.c b/asoc/msm-lsm-client.c
index b6624f0..8a179fd 100644
--- a/asoc/msm-lsm-client.c
+++ b/asoc/msm-lsm-client.c
@@ -12,6 +12,7 @@
#include <linux/dma-mapping.h>
#include <linux/of.h>
#include <linux/freezer.h>
+#include <linux/version.h>
#include <sound/core.h>
#include <sound/soc.h>
#include <sound/soc-dapm.h>
@@ -92,7 +93,7 @@
int xrun_count;
int xrun_index;
spinlock_t xrun_lock;
- struct wakeup_source ws;
+ struct wakeup_source *ws;
};
enum { /* lsm session states */
@@ -220,7 +221,7 @@
}
rtd = substream->private_data;
- pm_wakeup_ws_event(&prtd->ws, WAKELOCK_TIMEOUT, true);
+ pm_wakeup_ws_event(prtd->ws, WAKELOCK_TIMEOUT, true);
dev_dbg(rtd->dev, "%s: opcode %x\n", __func__, opcode);
switch (opcode) {
case LSM_DATA_EVENT_READ_DONE: {
@@ -235,13 +236,13 @@
"%s: EVENT_READ_DONE invalid callback, session %d callback %d payload %pK",
__func__, prtd->lsm_client->session,
token, read_done);
- __pm_relax(&prtd->ws);
+ __pm_relax(prtd->ws);
return;
}
if (atomic_read(&prtd->read_abort)) {
dev_dbg(rtd->dev,
"%s: read abort set skip data\n", __func__);
- __pm_relax(&prtd->ws);
+ __pm_relax(prtd->ws);
return;
}
if (!lsm_lab_buffer_sanity(prtd, read_done, &buf_index)) {
@@ -254,7 +255,7 @@
"%s: Invalid index %d buf_index max cnt %d\n",
__func__, buf_index,
prtd->lsm_client->out_hw_params.period_count);
- __pm_relax(&prtd->ws);
+ __pm_relax(prtd->ws);
return;
}
spin_lock_irqsave(&prtd->xrun_lock, flags);
@@ -292,7 +293,7 @@
dev_err(rtd->dev,
"%s: client_size has invalid size[%d]\n",
__func__, client_size);
- __pm_relax(&prtd->ws);
+ __pm_relax(prtd->ws);
return;
}
status = (uint16_t)((uint8_t *)payload)[0];
@@ -308,7 +309,7 @@
dev_err(rtd->dev,
"%s: client_size has invalid size[%d]\n",
__func__, client_size);
- __pm_relax(&prtd->ws);
+ __pm_relax(prtd->ws);
return;
}
status = (uint16_t)((uint8_t *)payload)[0];
@@ -324,7 +325,7 @@
dev_err(rtd->dev,
"%s: client_size has invalid size[%d]\n",
__func__, client_size);
- __pm_relax(&prtd->ws);
+ __pm_relax(prtd->ws);
return;
}
event_ts_lsw = ((uint32_t *)payload)[0];
@@ -344,7 +345,7 @@
dev_err(rtd->dev,
"%s: client_size has invalid size[%d]\n",
__func__, client_size);
- __pm_relax(&prtd->ws);
+ __pm_relax(prtd->ws);
return;
}
@@ -364,7 +365,7 @@
"LSM_SESSION_DETECTION_ENGINE_GENERIC_EVENT",
sizeof(struct snd_lsm_event_status) +
payload_size);
- __pm_relax(&prtd->ws);
+ __pm_relax(prtd->ws);
return;
}
@@ -379,7 +380,7 @@
dev_err(rtd->dev,
"%s: Failed to copy memory with invalid size = %d\n",
__func__, payload_size);
- __pm_relax(&prtd->ws);
+ __pm_relax(prtd->ws);
return;
}
prtd->event_avail = 1;
@@ -411,7 +412,7 @@
if (!temp) {
dev_err(rtd->dev, "%s: no memory for event status\n",
__func__);
- __pm_relax(&prtd->ws);
+ __pm_relax(prtd->ws);
return;
}
/*
@@ -438,7 +439,7 @@
dev_err(rtd->dev,
"%s: Failed to copy memory with invalid size = %d\n",
__func__, payload_size);
- __pm_relax(&prtd->ws);
+ __pm_relax(prtd->ws);
return;
}
} else {
@@ -1156,7 +1157,7 @@
dev_err(rtd->dev,
"%s: lsm open failed, %d\n",
__func__, ret);
- __pm_relax(&prtd->ws);
+ __pm_relax(prtd->ws);
return ret;
}
prtd->lsm_client->opened = true;
@@ -1504,14 +1505,14 @@
if (prtd->lsm_client->num_stages > 1) {
dev_err(rtd->dev, "%s: %s: not supported for multi stage session\n",
__func__, "LSM_LAB_CONTROL");
- __pm_relax(&prtd->ws);
+ __pm_relax(prtd->ws);
return -EINVAL;
}
if (copy_from_user(&enable, arg, sizeof(enable))) {
dev_err(rtd->dev, "%s: %s: copy_frm_user failed\n",
__func__, "LSM_LAB_CONTROL");
- __pm_relax(&prtd->ws);
+ __pm_relax(prtd->ws);
return -EFAULT;
}
@@ -1566,7 +1567,7 @@
if (copy_from_user(&mode, arg, sizeof(mode))) {
dev_err(rtd->dev, "%s: %s: copy_frm_user failed\n",
__func__, "LSM_SET_FWK_MODE_CONFIG");
- __pm_relax(&prtd->ws);
+ __pm_relax(prtd->ws);
return -EFAULT;
}
@@ -1597,7 +1598,7 @@
if (copy_from_user(¶ms, arg, sizeof(params))) {
dev_err(rtd->dev, "%s: %s: copy_from_user failed\n",
__func__, "LSM_SET_INPUT_HW_PARAMS");
- __pm_relax(&prtd->ws);
+ __pm_relax(prtd->ws);
return -EFAULT;
}
@@ -1624,7 +1625,7 @@
dev_err(rtd->dev, "%s: cmd 0x%x failed %d\n",
__func__, cmd, rc);
- __pm_relax(&prtd->ws);
+ __pm_relax(prtd->ws);
return rc;
}
@@ -2528,8 +2529,11 @@
prtd->lsm_client->event_type = LSM_DET_EVENT_TYPE_LEGACY;
prtd->lsm_client->fe_id = rtd->dai_link->id;
prtd->lsm_client->unprocessed_data = 0;
-
- wakeup_source_init(&prtd->ws, "lsm-client");
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 110))
+ prtd->ws = wakeup_source_register(rtd->dev, "lsm-client");
+#else
+ prtd->ws = wakeup_source_register("lsm-client");
+#endif
return 0;
}
@@ -2774,7 +2778,7 @@
q6lsm_client_free(prtd->lsm_client);
- wakeup_source_trash(&prtd->ws);
+ wakeup_source_unregister(prtd->ws);
spin_lock_irqsave(&prtd->event_lock, flags);
kfree(prtd->event_status);
prtd->event_status = NULL;
diff --git a/asoc/msm-transcode-loopback-q6-v2.c b/asoc/msm-transcode-loopback-q6-v2.c
index e20f0df..bba4ad7 100644
--- a/asoc/msm-transcode-loopback-q6-v2.c
+++ b/asoc/msm-transcode-loopback-q6-v2.c
@@ -613,7 +613,7 @@
}
static int msm_transcode_set_render_mode(struct msm_transcode_loopback *prtd,
- uint32_t render_mode)
+ uint32_t render_mode, int dir)
{
int ret = -EINVAL;
struct audio_client *ac = prtd->audio_client;
@@ -639,7 +639,7 @@
goto exit;
}
- ret = q6asm_send_mtmx_strtr_render_mode(ac, render_mode);
+ ret = q6asm_send_mtmx_strtr_render_mode(ac, render_mode, dir);
if (ret) {
pr_err("%s: Render mode can't be set error %d\n", __func__,
ret);
@@ -705,7 +705,8 @@
}
case SNDRV_COMPRESS_RENDER_MODE:
{
- rc = msm_transcode_set_render_mode(prtd, metadata->value[0]);
+ rc = msm_transcode_set_render_mode(prtd, metadata->value[0],
+ cstream->direction);
if (rc)
pr_err("%s: error setting render mode %d\n", __func__,
rc);
diff --git a/config/litoauto.conf b/config/litoauto.conf
index d0030bb..ecf848c 100644
--- a/config/litoauto.conf
+++ b/config/litoauto.conf
@@ -38,3 +38,6 @@
CONFIG_SND_SOC_WCD937X_SLAVE=m
CONFIG_SND_SOC_LITO=m
CONFIG_SND_EVENT=m
+CONFIG_MI2S_DISABLE=m
+CONFIG_TDM_DISABLE=m
+CONFIG_AUXPCM_DISABLE=m
diff --git a/config/litoautoconf.h b/config/litoautoconf.h
index 322ac73..3c979cc 100644
--- a/config/litoautoconf.h
+++ b/config/litoautoconf.h
@@ -42,3 +42,6 @@
#define CONFIG_SND_SOC_WCD937X_SLAVE 1
#define CONFIG_SND_SOC_LITO 1
#define CONFIG_SND_EVENT 1
+#define CONFIG_MI2S_DISABLE 1
+#define CONFIG_TDM_DISABLE 1
+#define CONFIG_AUXPCM_DISABLE 1
diff --git a/dsp/codecs/audio_utils.c b/dsp/codecs/audio_utils.c
index ac93413..33495b2 100644
--- a/dsp/codecs/audio_utils.c
+++ b/dsp/codecs/audio_utils.c
@@ -936,6 +936,7 @@
int audio_in_release(struct inode *inode, struct file *file)
{
+ unsigned long flags = 0;
struct q6audio_in *audio = file->private_data;
pr_info("%s: session id %d\n", __func__, audio->ac->session);
@@ -943,11 +944,11 @@
audio_in_disable(audio);
q6asm_audio_client_free(audio->ac);
mutex_unlock(&audio->lock);
- spin_lock(&enc_dec_lock);
+ spin_lock_irqsave(&enc_dec_lock, flags);
kfree(audio->enc_cfg);
kfree(audio->codec_cfg);
kfree(audio);
file->private_data = NULL;
- spin_unlock(&enc_dec_lock);
+ spin_unlock_irqrestore(&enc_dec_lock, flags);
return 0;
}
diff --git a/dsp/codecs/audio_utils_aio.c b/dsp/codecs/audio_utils_aio.c
index 93095e3..94be57d 100644
--- a/dsp/codecs/audio_utils_aio.c
+++ b/dsp/codecs/audio_utils_aio.c
@@ -588,6 +588,7 @@
int audio_aio_release(struct inode *inode, struct file *file)
{
+ unsigned long flags = 0;
struct q6audio_aio *audio = file->private_data;
pr_debug("%s[%pK]\n", __func__, audio);
@@ -631,11 +632,11 @@
#ifdef CONFIG_DEBUG_FS
debugfs_remove(audio->dentry);
#endif
- spin_lock(&enc_dec_lock);
+ spin_lock_irqsave(&enc_dec_lock, flags);
kfree(audio->codec_cfg);
kfree(audio);
file->private_data = NULL;
- spin_unlock(&enc_dec_lock);
+ spin_unlock_irqrestore(&enc_dec_lock, flags);
mutex_unlock(&lock);
return 0;
}
diff --git a/dsp/codecs/q6audio_v2.c b/dsp/codecs/q6audio_v2.c
index 6a402f5..51ff850 100644
--- a/dsp/codecs/q6audio_v2.c
+++ b/dsp/codecs/q6audio_v2.c
@@ -20,8 +20,9 @@
{
struct q6audio_in *audio = (struct q6audio_in *)priv;
unsigned long flags;
+ unsigned long en_de_flags;
- spin_lock(&enc_dec_lock);
+ spin_lock_irqsave(&enc_dec_lock, en_de_flags);
if (audio == NULL) {
pr_err("%s: failed to get q6audio value\n", __func__);
goto error;
@@ -64,7 +65,7 @@
}
spin_unlock_irqrestore(&audio->dsp_lock, flags);
error:
- spin_unlock(&enc_dec_lock);
+ spin_unlock_irqrestore(&enc_dec_lock, en_de_flags);
}
void audio_in_get_dsp_frames(void *priv,
diff --git a/dsp/codecs/q6audio_v2_aio.c b/dsp/codecs/q6audio_v2_aio.c
index ecd14da..d9dd29b 100644
--- a/dsp/codecs/q6audio_v2_aio.c
+++ b/dsp/codecs/q6audio_v2_aio.c
@@ -42,8 +42,9 @@
{
struct q6audio_aio *audio = (struct q6audio_aio *)priv;
union msm_audio_event_payload e_payload;
+ unsigned long flags = 0;
- spin_lock(&enc_dec_lock);
+ spin_lock_irqsave(&enc_dec_lock, flags);
if (audio == NULL) {
pr_err("%s: failed to get q6audio value\n", __func__);
goto error;
@@ -113,7 +114,7 @@
break;
}
error:
- spin_unlock(&enc_dec_lock);
+ spin_unlock_irqrestore(&enc_dec_lock, flags);
}
int extract_meta_out_info(struct q6audio_aio *audio,
diff --git a/dsp/q6afe.c b/dsp/q6afe.c
index 2586bd5..9d5908d 100644
--- a/dsp/q6afe.c
+++ b/dsp/q6afe.c
@@ -10,6 +10,7 @@
#include <linux/jiffies.h>
#include <linux/sched.h>
#include <linux/delay.h>
+#include <linux/version.h>
#include <dsp/msm_audio_ion.h>
#include <dsp/apr_audio-v2.h>
#include <dsp/audio_cal_utils.h>
@@ -98,7 +99,7 @@
};
struct wlock {
- struct wakeup_source ws;
+ struct wakeup_source *ws;
};
static struct wlock wl;
@@ -3924,6 +3925,51 @@
return ret;
}
+static int q6afe_send_ttp_config(u16 port_id,
+ union afe_port_config afe_config,
+ struct afe_ttp_config *ttp_cfg)
+{
+ struct afe_ttp_gen_enable_t ttp_gen_enable;
+ struct afe_ttp_gen_cfg_t ttp_gen_cfg;
+ struct param_hdr_v3 param_hdr;
+ int ret;
+
+ memset(&ttp_gen_enable, 0, sizeof(ttp_gen_enable));
+ memset(&ttp_gen_cfg, 0, sizeof(ttp_gen_cfg));
+ memset(¶m_hdr, 0, sizeof(param_hdr));
+
+ param_hdr.module_id = AFE_MODULE_ID_DECODER;
+ param_hdr.instance_id = INSTANCE_ID_0;
+
+ pr_debug("%s: Enable TTP generator\n", __func__);
+ ttp_gen_enable = ttp_cfg->ttp_gen_enable;
+ param_hdr.param_id = AVS_DEPACKETIZER_PARAM_ID_TTP_GEN_STATE;
+ param_hdr.param_size = sizeof(struct afe_ttp_gen_enable_t);
+ ret = q6afe_pack_and_set_param_in_band(port_id,
+ q6audio_get_port_index(port_id),
+ param_hdr,
+ (u8 *) &ttp_gen_enable);
+ if (ret) {
+ pr_err("%s: AVS_DEPACKETIZER_PARAM_ID_TTP_GEN_STATE for port 0x%x failed %d\n",
+ __func__, port_id, ret);
+ goto exit;
+ }
+
+ pr_debug("%s: sending TTP generator config\n", __func__);
+ ttp_gen_cfg = ttp_cfg->ttp_gen_cfg;
+ param_hdr.param_id = AVS_DEPACKETIZER_PARAM_ID_TTP_GEN_CFG;
+ param_hdr.param_size = sizeof(struct afe_ttp_gen_cfg_t);
+ ret = q6afe_pack_and_set_param_in_band(port_id,
+ q6audio_get_port_index(port_id),
+ param_hdr,
+ (u8 *) &ttp_gen_cfg);
+ if (ret)
+ pr_err("%s: AVS_DEPACKETIZER_PARAM_ID_TTP_GEN_CFG for port 0x%x failed %d\n",
+ __func__, port_id, ret);
+exit:
+ return ret;
+}
+
static int q6afe_send_dec_config(u16 port_id,
union afe_port_config afe_config,
struct afe_dec_config *cfg,
@@ -4594,7 +4640,8 @@
u32 rate, u16 afe_in_channels, u16 afe_in_bit_width,
union afe_enc_config_data *enc_cfg,
u32 codec_format, u32 scrambler_mode, u32 mono_mode,
- struct afe_dec_config *dec_cfg)
+ struct afe_dec_config *dec_cfg,
+ struct afe_ttp_config *ttp_cfg)
{
union afe_port_config port_cfg;
struct param_hdr_v3 param_hdr;
@@ -4912,6 +4959,15 @@
goto fail_cmd;
}
}
+ if (ttp_cfg != NULL) {
+ ret = q6afe_send_ttp_config(port_id, *afe_config,
+ ttp_cfg);
+ if (ret) {
+ pr_err("%s: AFE TTP config for port 0x%x failed %d\n",
+ __func__, port_id, ret);
+ goto fail_cmd;
+ }
+ }
}
port_index = afe_get_port_index(port_id);
@@ -4958,8 +5014,8 @@
int afe_port_start(u16 port_id, union afe_port_config *afe_config,
u32 rate)
{
- return __afe_port_start(port_id, afe_config, rate,
- 0, 0, NULL, ASM_MEDIA_FMT_NONE, 0, 0, NULL);
+ return __afe_port_start(port_id, afe_config, rate, 0, 0, NULL,
+ ASM_MEDIA_FMT_NONE, 0, 0, NULL, NULL);
}
EXPORT_SYMBOL(afe_port_start);
@@ -4989,16 +5045,50 @@
afe_in_channels, afe_in_bit_width,
&enc_cfg->data, enc_cfg->format,
enc_cfg->scrambler_mode,
- enc_cfg->mono_mode, dec_cfg);
+ enc_cfg->mono_mode, dec_cfg, NULL);
else if (dec_cfg != NULL)
ret = __afe_port_start(port_id, afe_config, rate,
afe_in_channels, afe_in_bit_width,
- NULL, dec_cfg->format, 0, 0, dec_cfg);
+ NULL, dec_cfg->format, 0, 0,
+ dec_cfg, NULL);
return ret;
}
EXPORT_SYMBOL(afe_port_start_v2);
+/**
+ * afe_port_start_v3 - to configure AFE session with
+ * specified port configuration and encoder /decoder params
+ *
+ * @port_id: AFE port id number
+ * @afe_config: port configuration
+ * @rate: sampling rate of port
+ * @enc_cfg: AFE enc configuration information to setup encoder
+ * @afe_in_channels: AFE input channel configuration, this needs
+ * update only if input channel is differ from AFE output
+ * @dec_cfg: AFE dec configuration information to set up decoder
+ * @ttp_cfg: TTP generator configuration to enable TTP in AFE
+ *
+ * Returns 0 on success or error value on port start failure.
+ */
+int afe_port_start_v3(u16 port_id, union afe_port_config *afe_config,
+ u32 rate, u16 afe_in_channels, u16 afe_in_bit_width,
+ struct afe_enc_config *enc_cfg,
+ struct afe_dec_config *dec_cfg,
+ struct afe_ttp_config *ttp_cfg)
+{
+ int ret = 0;
+
+ if (dec_cfg != NULL && ttp_cfg != NULL)
+ ret = __afe_port_start(port_id, afe_config, rate,
+ afe_in_channels, afe_in_bit_width,
+ NULL, dec_cfg->format, 0, 0,
+ dec_cfg, ttp_cfg);
+
+ return ret;
+}
+EXPORT_SYMBOL(afe_port_start_v3);
+
int afe_get_port_index(u16 port_id)
{
switch (port_id) {
@@ -8960,7 +9050,7 @@
goto done;
if (cal_data->cal_info.mode == MSM_SPKR_PROT_CALIBRATION_IN_PROGRESS)
- __pm_wakeup_event(&wl.ws, jiffies_to_msecs(WAKELOCK_TIMEOUT));
+ __pm_wakeup_event(wl.ws, jiffies_to_msecs(WAKELOCK_TIMEOUT));
mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_CAL]->lock);
memcpy(&this_afe.prot_cfg, &cal_data->cal_info,
sizeof(this_afe.prot_cfg));
@@ -9166,7 +9256,7 @@
}
this_afe.initial_cal = 0;
mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_CAL]->lock);
- __pm_relax(&wl.ws);
+ __pm_relax(wl.ws);
done:
return ret;
}
@@ -9464,7 +9554,6 @@
init_waitqueue_head(&this_afe.wait_wakeup);
init_waitqueue_head(&this_afe.lpass_core_hw_wait);
init_waitqueue_head(&this_afe.clk_wait);
- wakeup_source_init(&wl.ws, "spkr-prot");
ret = afe_init_cal_data();
if (ret)
pr_err("%s: could not init cal data! %d\n", __func__, ret);
@@ -9474,8 +9563,12 @@
this_afe.uevent_data = kzalloc(sizeof(*(this_afe.uevent_data)), GFP_KERNEL);
if (!this_afe.uevent_data)
return -ENOMEM;
-
- /*
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 110))
+ wl.ws = wakeup_source_register(NULL, "spkr-prot");
+#else
+ wl.ws = wakeup_source_register("spkr-prot");
+#endif
+/*
* Set release function to cleanup memory related to kobject
* before initializing the kobject.
*/
@@ -9509,7 +9602,7 @@
mutex_destroy(&this_afe.afe_cmd_lock);
mutex_destroy(&this_afe.afe_apr_lock);
mutex_destroy(&this_afe.afe_clk_lock);
- wakeup_source_trash(&wl.ws);
+ wakeup_source_unregister(wl.ws);
}
/*
diff --git a/dsp/q6asm.c b/dsp/q6asm.c
index fef09c5..e56c7c5 100644
--- a/dsp/q6asm.c
+++ b/dsp/q6asm.c
@@ -10048,16 +10048,105 @@
EXPORT_SYMBOL(q6asm_send_mtmx_strtr_window);
/**
+ * q6asm_send_mtmx_strtr_ttp_offset -
+ * command to send matrix for ttp offset
+ *
+ * @ac: Audio client handle
+ * @ttp_offset: ttp offset params
+ * @param_id: param id for ttp offset
+ * @dir: RX or TX direction
+ *
+ * Returns 0 on success or error on failure
+ */
+int q6asm_send_mtmx_strtr_ttp_offset(struct audio_client *ac,
+ struct asm_session_mtmx_strtr_param_ttp_offset_t *ttp_offset,
+ uint32_t param_id, int dir)
+{
+ struct asm_mtmx_strtr_params matrix;
+ int sz = 0;
+ int rc = 0;
+
+ pr_debug("%s: ttp offset lsw is %d, ttp offset msw is %d\n", __func__,
+ ttp_offset->ttp_offset_lsw, ttp_offset->ttp_offset_msw);
+
+ if (!ac) {
+ pr_err("%s: audio client handle is NULL\n", __func__);
+ rc = -EINVAL;
+ goto fail_cmd;
+ }
+
+ if (ac->apr == NULL) {
+ pr_err("%s: ac->apr is NULL", __func__);
+ rc = -EINVAL;
+ goto fail_cmd;
+ }
+
+ memset(&matrix, 0, sizeof(struct asm_mtmx_strtr_params));
+ sz = sizeof(struct asm_mtmx_strtr_params);
+ q6asm_add_hdr(ac, &matrix.hdr, sz, TRUE);
+ atomic_set(&ac->cmd_state, -1);
+ matrix.hdr.opcode = ASM_SESSION_CMD_SET_MTMX_STRTR_PARAMS_V2;
+
+ matrix.param.data_payload_addr_lsw = 0;
+ matrix.param.data_payload_addr_msw = 0;
+ matrix.param.mem_map_handle = 0;
+ matrix.param.data_payload_size =
+ sizeof(struct param_hdr_v1) +
+ sizeof(struct asm_session_mtmx_strtr_param_ttp_offset_t);
+ matrix.param.direction = dir;
+ matrix.data.module_id = ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC;
+ matrix.data.param_id = param_id;
+ matrix.data.param_size =
+ sizeof(struct asm_session_mtmx_strtr_param_ttp_offset_t);
+ matrix.data.reserved = 0;
+ memcpy(&(matrix.config.ttp_offset),
+ ttp_offset,
+ sizeof(struct asm_session_mtmx_strtr_param_ttp_offset_t));
+
+ rc = apr_send_pkt(ac->apr, (uint32_t *) &matrix);
+ if (rc < 0) {
+ pr_err("%s: ttp offset send failed paramid [0x%x]\n",
+ __func__, matrix.data.param_id);
+ rc = -EINVAL;
+ goto fail_cmd;
+ }
+
+ rc = wait_event_timeout(ac->cmd_wait,
+ (atomic_read(&ac->cmd_state) >= 0),
+ msecs_to_jiffies(TIMEOUT_MS));
+ if (!rc) {
+ pr_err("%s: timeout, ttp offset paramid[0x%x]\n",
+ __func__, matrix.data.param_id);
+ rc = -ETIMEDOUT;
+ goto fail_cmd;
+ }
+
+ if (atomic_read(&ac->cmd_state) > 0) {
+ pr_err("%s: DSP returned error[%s]\n",
+ __func__, adsp_err_get_err_str(
+ atomic_read(&ac->cmd_state)));
+ rc = adsp_err_get_lnx_err_code(
+ atomic_read(&ac->cmd_state));
+ goto fail_cmd;
+ }
+ rc = 0;
+fail_cmd:
+ return rc;
+}
+EXPORT_SYMBOL(q6asm_send_mtmx_strtr_ttp_offset);
+
+/**
* q6asm_send_mtmx_strtr_render_mode -
* command to send matrix for render mode
*
* @ac: Audio client handle
* @render_mode: rendering mode
+ * @dir: RX or TX direction
*
* Returns 0 on success or error on failure
*/
int q6asm_send_mtmx_strtr_render_mode(struct audio_client *ac,
- uint32_t render_mode)
+ uint32_t render_mode, int dir)
{
struct asm_mtmx_strtr_params matrix;
struct asm_session_mtmx_strtr_param_render_mode_t render_param;
@@ -10101,7 +10190,7 @@
matrix.param.data_payload_size =
sizeof(struct param_hdr_v1) +
sizeof(struct asm_session_mtmx_strtr_param_render_mode_t);
- matrix.param.direction = 0; /* RX */
+ matrix.param.direction = dir;
matrix.data.module_id = ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC;
matrix.data.param_id = ASM_SESSION_MTMX_STRTR_PARAM_RENDER_MODE_CMD;
matrix.data.param_size =
diff --git a/dsp/usf.c b/dsp/usf.c
index e408c7d..d0f6ed3 100644
--- a/dsp/usf.c
+++ b/dsp/usf.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2017, 2020, The Linux Foundation. All rights reserved.
*/
#include <linux/compat.h>
@@ -15,6 +15,7 @@
#include <linux/time.h>
#include <linux/kmemleak.h>
#include <linux/mutex.h>
+#include <linux/version.h>
#include <dsp/apr_audio-v2.h>
#include "q6usm.h"
#include "usf.h"
@@ -173,7 +174,7 @@
/* The opened devices container */
static atomic_t s_opened_devs[MAX_DEVS_NUMBER];
-static struct wakeup_source usf_wakeup_source;
+static struct wakeup_source *usf_wakeup_source;
#define USF_NAME_PREFIX "usf_"
#define USF_NAME_PREFIX_SIZE 4
@@ -442,7 +443,7 @@
case Q6USM_EVENT_READ_DONE:
pr_debug("%s: acquiring %d msec wake lock\n", __func__,
STAY_AWAKE_AFTER_READ_MSECS);
- __pm_wakeup_event(&usf_wakeup_source,
+ __pm_wakeup_event(usf_wakeup_source,
STAY_AWAKE_AFTER_READ_MSECS);
if (token == USM_WRONG_TOKEN)
usf_xx->usf_state = USF_ERROR_STATE;
@@ -2369,8 +2370,11 @@
usf = kzalloc(sizeof(struct usf_type), GFP_KERNEL);
if (usf == NULL)
return -ENOMEM;
-
- wakeup_source_init(&usf_wakeup_source, "usf");
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 110))
+ usf_wakeup_source = wakeup_source_register(NULL, "usf");
+#else
+ usf_wakeup_source = wakeup_source_register("usf");
+#endif
file->private_data = usf;
usf->dev_ind = dev_ind;
@@ -2401,7 +2405,7 @@
atomic_set(&s_opened_devs[usf->dev_ind], 0);
- wakeup_source_trash(&usf_wakeup_source);
+ wakeup_source_unregister(usf_wakeup_source);
mutex_unlock(&usf->mutex);
mutex_destroy(&usf->mutex);
kfree(usf);
diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h
index 311c892..6814646 100644
--- a/include/dsp/apr_audio-v2.h
+++ b/include/dsp/apr_audio-v2.h
@@ -4732,6 +4732,56 @@
union afe_enc_config_data data;
};
+/*
+ * Enable TTP generator in AFE.
+ */
+#define AVS_DEPACKETIZER_PARAM_ID_TTP_GEN_STATE 0x000132EF
+/*
+ * Configure TTP generator params in AFE.
+ */
+#define AVS_DEPACKETIZER_PARAM_ID_TTP_GEN_CFG 0x000132F0
+#define MAX_TTP_OFFSET_PAIRS 4
+struct afe_ttp_gen_enable_t {
+ uint16_t enable;
+ uint16_t reserved;
+} __packed;
+
+struct afe_ttp_ssrc_offset_pair_t {
+ uint32_t ssrc;
+ uint32_t offset;
+} __packed;
+
+struct afe_ttp_gen_cfg_t {
+ uint32_t ttp_offset_default;
+ /*
+ * TTP offset uses for all other cases
+ * where no valid SSRC is received.
+ */
+ uint32_t settling_time;
+ /*
+ * If settling_mode==0x00: time in [us]
+ * after first received packet until
+ * packets are no longer dropped.
+ */
+ uint16_t settling_mode;
+ /*
+ * 0x00(Drop), 0x01(Settle)
+ */
+ uint16_t num_ssrc_offsets;
+ /*
+ * Number of SSRC/TTPOFFSET pairs to follow
+ */
+ struct afe_ttp_ssrc_offset_pair_t ssrc_ttp_offset[MAX_TTP_OFFSET_PAIRS];
+ /*
+ * Array of ssrc/offset pairs
+ */
+} __packed;
+
+struct afe_ttp_config {
+ struct afe_ttp_gen_enable_t ttp_gen_enable;
+ struct afe_ttp_gen_cfg_t ttp_gen_cfg;
+};
+
union afe_dec_config_data {
struct asm_sbc_dec_cfg_t sbc_config;
struct asm_aac_dec_cfg_v2_t aac_config;
@@ -12348,6 +12398,12 @@
*/
#define ASM_SESSION_MTMX_STRTR_PARAM_RENDER_WINDOW_END_V2 0x00010DD2
+/* Parameter used by #ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC to specify the
+ * ttp offset value. This parameter is supported only for a Set
+ * command (not a Get command) in the Tx direction
+ */
+#define ASM_SESSION_MTMX_STRTR_PARAM_TTP_OFFSET 0x00013228
+
/* Generic payload of the window parameters in the
* #ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC module.
* This payload is supported only for a Set command
@@ -12456,6 +12512,26 @@
u32 flags;
} __packed;
+struct asm_session_mtmx_strtr_param_ttp_offset_t {
+ uint32_t ttp_offset_lsw;
+ /* Lower 32 bits of the ttp_offset in microseconds. */
+
+ uint32_t ttp_offset_msw;
+ /* Upper 32 bits of the ttp_offset in microseconds.
+ *
+ * Internal default value is 0 for both values. The 64-bit number
+ * formed by ttp_offset_lsw and ttp_offset_lsw is treated as unsigned.
+ * In case of local DSP loopback when using start flag
+ * ASM_SESSION_CMD_RUN_START_TIME_RUN_WITH_TTP the max. ttp_offset
+ * value is limited by internal buffer constraints. Currently the
+ * limit is 200ms.
+
+ * This parameter can be set before or while an ASM stream is running,
+ * allowing “at-run-time” changes of the overall latency.
+ */
+
+} __packed;
+
/* Parameter used by #ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC which allows the
* audio client to specify the clock recovery mechanism that the audio DSP
* should use.
@@ -12527,6 +12603,7 @@
struct asm_session_mtmx_strtr_param_render_mode_t render_param;
struct asm_session_mtmx_strtr_param_clk_rec_t clk_rec_param;
struct asm_session_mtmx_param_adjust_session_time_ctl_t adj_time_param;
+ struct asm_session_mtmx_strtr_param_ttp_offset_t ttp_offset;
} __packed;
struct asm_mtmx_strtr_params {
diff --git a/include/dsp/q6afe-v2.h b/include/dsp/q6afe-v2.h
index 3ff3028..55ae6be 100644
--- a/include/dsp/q6afe-v2.h
+++ b/include/dsp/q6afe-v2.h
@@ -402,6 +402,11 @@
u32 rate, u16 afe_in_channels, u16 afe_in_bit_width,
struct afe_enc_config *enc_config,
struct afe_dec_config *dec_config);
+int afe_port_start_v3(u16 port_id, union afe_port_config *afe_config,
+ u32 rate, u16 afe_in_channels, u16 afe_in_bit_width,
+ struct afe_enc_config *enc_config,
+ struct afe_dec_config *dec_config,
+ struct afe_ttp_config *ttp_config);
int afe_spk_prot_feed_back_cfg(int src_port, int dst_port,
int l_ch, int r_ch, u32 enable);
int afe_spk_prot_get_calib_data(struct afe_spkr_prot_get_vi_calib *calib);
diff --git a/include/dsp/q6asm-v2.h b/include/dsp/q6asm-v2.h
index 5ad8fb0..1a34161 100644
--- a/include/dsp/q6asm-v2.h
+++ b/include/dsp/q6asm-v2.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
- * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
*/
#ifndef __Q6_ASM_V2_H__
#define __Q6_ASM_V2_H__
@@ -726,9 +726,13 @@
struct asm_session_mtmx_strtr_param_window_v2_t *window_param,
uint32_t param_id);
+int q6asm_send_mtmx_strtr_ttp_offset(struct audio_client *ac,
+ struct asm_session_mtmx_strtr_param_ttp_offset_t *ttp_offset,
+ uint32_t param_id, int dir);
+
/* Configure DSP render mode */
int q6asm_send_mtmx_strtr_render_mode(struct audio_client *ac,
- uint32_t render_mode);
+ uint32_t render_mode, int dir);
/* Configure DSP clock recovery mode */
int q6asm_send_mtmx_strtr_clk_rec_mode(struct audio_client *ac,