summaryrefslogtreecommitdiff
path: root/asoc
diff options
context:
space:
mode:
authorqctecmdr <qctecmdr@localhost>2020-07-30 01:44:59 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2020-07-30 01:44:59 -0700
commitdde137e930beb3a2e6a5664f98698f997dd5db41 (patch)
tree5f8f2a2209c7ffef76520554dc3dd76af75eadc8 /asoc
parent280fd01fc83b8afe7bfda5e537018dbc5d0054f7 (diff)
parent8203a06e6197a322b426971de2bfb94d5c29616a (diff)
downloadmsm-extra-dde137e930beb3a2e6a5664f98698f997dd5db41.tar.gz
Merge "ASoC: rouleur: Change hph and ear gain according to soc capacity"
Diffstat (limited to 'asoc')
-rw-r--r--asoc/codecs/bolero/bolero-cdc.c6
-rw-r--r--asoc/codecs/bolero/bolero-cdc.h1
-rw-r--r--asoc/codecs/bolero/internal.h1
-rw-r--r--asoc/codecs/bolero/rx-macro.c49
-rw-r--r--asoc/codecs/msm-cdc-supply.c46
-rw-r--r--asoc/codecs/rouleur/internal.h4
-rw-r--r--asoc/codecs/rouleur/rouleur.c113
7 files changed, 220 insertions, 0 deletions
diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c
index 233a0b4b..173343ca 100644
--- a/asoc/codecs/bolero/bolero-cdc.c
+++ b/asoc/codecs/bolero/bolero-cdc.c
@@ -232,6 +232,12 @@ static int bolero_cdc_update_wcd_event(void *handle, u16 event, u32 data)
priv->component,
BOLERO_MACRO_EVT_BCS_CLK_OFF, data);
break;
+ case WCD_BOLERO_EVT_RX_PA_GAIN_UPDATE:
+ if (priv->macro_params[RX_MACRO].event_handler)
+ priv->macro_params[RX_MACRO].event_handler(
+ priv->component,
+ BOLERO_MACRO_EVT_RX_PA_GAIN_UPDATE, data);
+ break;
default:
dev_err(priv->dev, "%s: Invalid event %d trigger from wcd\n",
__func__, event);
diff --git a/asoc/codecs/bolero/bolero-cdc.h b/asoc/codecs/bolero/bolero-cdc.h
index 7e3468a8..bcd4a255 100644
--- a/asoc/codecs/bolero/bolero-cdc.h
+++ b/asoc/codecs/bolero/bolero-cdc.h
@@ -55,6 +55,7 @@ enum {
BOLERO_MACRO_EVT_BCS_CLK_OFF,
BOLERO_MACRO_EVT_SSR_GFMUX_UP,
BOLERO_MACRO_EVT_PRE_SSR_UP,
+ BOLERO_MACRO_EVT_RX_PA_GAIN_UPDATE,
};
enum {
diff --git a/asoc/codecs/bolero/internal.h b/asoc/codecs/bolero/internal.h
index d3a072c9..4d098da3 100644
--- a/asoc/codecs/bolero/internal.h
+++ b/asoc/codecs/bolero/internal.h
@@ -33,6 +33,7 @@ enum {
WCD_BOLERO_EVT_IMPED_FALSE, /* for imped false */
WCD_BOLERO_EVT_RX_COMPANDER_SOFT_RST,
WCD_BOLERO_EVT_BCS_CLK_OFF,
+ WCD_BOLERO_EVT_RX_PA_GAIN_UPDATE,
};
struct wcd_ctrl_platform_data {
diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c
index c858d2c6..f79e984e 100644
--- a/asoc/codecs/bolero/rx-macro.c
+++ b/asoc/codecs/bolero/rx-macro.c
@@ -77,6 +77,11 @@ static const struct snd_kcontrol_new name##_mux = \
#define RX_MACRO_EC_MIX_TX1_MASK 0x0f
#define RX_MACRO_EC_MIX_TX2_MASK 0x0f
+#define RX_MACRO_GAIN_MAX_VAL 0x28
+#define RX_MACRO_GAIN_VAL_UNITY 0x0
+/* Define macros to increase PA Gain by half */
+#define RX_MACRO_MOD_GAIN (RX_MACRO_GAIN_VAL_UNITY + 6)
+
#define COMP_MAX_COEFF 25
struct wcd_imped_val {
@@ -452,6 +457,8 @@ struct rx_macro_priv {
struct rx_macro_bcl_pmic_params bcl_pmic_params;
u16 clk_id;
u16 default_clk_id;
+ int8_t rx0_gain_val;
+ int8_t rx1_gain_val;
};
static struct snd_soc_dai_driver rx_macro_dai[];
@@ -1416,6 +1423,46 @@ static int rx_macro_event_handler(struct snd_soc_component *component,
case BOLERO_MACRO_EVT_CLK_RESET:
bolero_rsc_clk_reset(rx_dev, RX_CORE_CLK);
break;
+ case BOLERO_MACRO_EVT_RX_PA_GAIN_UPDATE:
+ rx_priv->rx0_gain_val = snd_soc_component_read32(component,
+ BOLERO_CDC_RX_RX0_RX_VOL_CTL);
+ rx_priv->rx1_gain_val = snd_soc_component_read32(component,
+ BOLERO_CDC_RX_RX1_RX_VOL_CTL);
+ if (data) {
+ /* Reduce gain by half only if its greater than -6DB */
+ if ((rx_priv->rx0_gain_val >= RX_MACRO_GAIN_VAL_UNITY)
+ && (rx_priv->rx0_gain_val <= RX_MACRO_GAIN_MAX_VAL))
+ snd_soc_component_update_bits(component,
+ BOLERO_CDC_RX_RX0_RX_VOL_CTL, 0xFF,
+ (rx_priv->rx0_gain_val -
+ RX_MACRO_MOD_GAIN));
+ if ((rx_priv->rx1_gain_val >= RX_MACRO_GAIN_VAL_UNITY)
+ && (rx_priv->rx1_gain_val <= RX_MACRO_GAIN_MAX_VAL))
+ snd_soc_component_update_bits(component,
+ BOLERO_CDC_RX_RX1_RX_VOL_CTL, 0xFF,
+ (rx_priv->rx1_gain_val -
+ RX_MACRO_MOD_GAIN));
+ }
+ else {
+ /* Reset gain value to default */
+ if ((rx_priv->rx0_gain_val >=
+ (RX_MACRO_GAIN_VAL_UNITY - RX_MACRO_MOD_GAIN)) &&
+ (rx_priv->rx0_gain_val <= (RX_MACRO_GAIN_MAX_VAL -
+ RX_MACRO_MOD_GAIN)))
+ snd_soc_component_update_bits(component,
+ BOLERO_CDC_RX_RX0_RX_VOL_CTL, 0xFF,
+ (rx_priv->rx0_gain_val +
+ RX_MACRO_MOD_GAIN));
+ if ((rx_priv->rx1_gain_val >=
+ (RX_MACRO_GAIN_VAL_UNITY - RX_MACRO_MOD_GAIN)) &&
+ (rx_priv->rx1_gain_val <= (RX_MACRO_GAIN_MAX_VAL -
+ RX_MACRO_MOD_GAIN)))
+ snd_soc_component_update_bits(component,
+ BOLERO_CDC_RX_RX1_RX_VOL_CTL, 0xFF,
+ (rx_priv->rx1_gain_val +
+ RX_MACRO_MOD_GAIN));
+ }
+ break;
}
done:
return ret;
@@ -3825,6 +3872,8 @@ static int rx_macro_init(struct snd_soc_component *component)
return ret;
}
rx_priv->dev_up = true;
+ rx_priv->rx0_gain_val = 0;
+ rx_priv->rx1_gain_val = 0;
snd_soc_dapm_ignore_suspend(dapm, "RX_MACRO_AIF1 Playback");
snd_soc_dapm_ignore_suspend(dapm, "RX_MACRO_AIF2 Playback");
snd_soc_dapm_ignore_suspend(dapm, "RX_MACRO_AIF3 Playback");
diff --git a/asoc/codecs/msm-cdc-supply.c b/asoc/codecs/msm-cdc-supply.c
index 0d49c28f..98639f3c 100644
--- a/asoc/codecs/msm-cdc-supply.c
+++ b/asoc/codecs/msm-cdc-supply.c
@@ -173,6 +173,52 @@ bool msm_cdc_is_ondemand_supply(struct device *dev,
EXPORT_SYMBOL(msm_cdc_is_ondemand_supply);
/*
+ * msm_cdc_set_supply_min_voltage:
+ * Set min supply voltage for particular supply
+ *
+ * @dev: pointer to codec device
+ * @supplies: pointer to regulator bulk data
+ * @cdc_vreg: pointer to platform regulator data
+ * @num_supplies: number of supplies
+ * @supply_name: Supply name to change voltage for
+ * @vval_min: Min voltage to be set in uV
+ * @override_min_vol: True if override min voltage from default
+ * Return error code if unable to set voltage
+ */
+int msm_cdc_set_supply_min_voltage(struct device *dev,
+ struct regulator_bulk_data *supplies,
+ struct cdc_regulator *cdc_vreg,
+ int num_supplies, char *supply_name,
+ int vval_min, bool override_min_vol)
+{
+ int rc = 0, i;
+
+ if ((!supply_name) || (!supplies)) {
+ pr_err("%s: either dev or supplies or cdc_vreg is NULL\n",
+ __func__);
+ return -EINVAL;
+ }
+ /* input parameter validation */
+ rc = msm_cdc_check_supply_param(dev, cdc_vreg, num_supplies);
+ if (rc)
+ return rc;
+ for (i = 0; i < num_supplies; i++) {
+ if (!strcmp(cdc_vreg[i].name, supply_name)) {
+ if (override_min_vol)
+ regulator_set_voltage(supplies[i].consumer,
+ vval_min, cdc_vreg[i].max_uV);
+ else
+ regulator_set_voltage(supplies[i].consumer,
+ cdc_vreg[i].min_uV, cdc_vreg[i].max_uV);
+ break;
+ }
+ }
+
+ return rc;
+}
+EXPORT_SYMBOL(msm_cdc_set_supply_min_voltage);
+
+/*
* msm_cdc_disable_ondemand_supply:
* Disable codec ondemand supply
*
diff --git a/asoc/codecs/rouleur/internal.h b/asoc/codecs/rouleur/internal.h
index cc1500be..b1d21faa 100644
--- a/asoc/codecs/rouleur/internal.h
+++ b/asoc/codecs/rouleur/internal.h
@@ -85,6 +85,9 @@ struct rouleur_priv {
struct mutex main_bias_lock;
bool dev_up;
bool usbc_hs_status;
+ struct notifier_block psy_nb;
+ struct work_struct soc_eval_work;
+ bool low_soc;
};
struct rouleur_micbias_setting {
@@ -131,6 +134,7 @@ enum {
WCD_BOLERO_EVT_IMPED_FALSE, /* for imped false */
WCD_BOLERO_EVT_RX_COMPANDER_SOFT_RST,
WCD_BOLERO_EVT_BCS_CLK_OFF,
+ WCD_BOLERO_EVT_RX_PA_GAIN_UPDATE, /* To reduce PA gain for low SoC */
};
enum {
diff --git a/asoc/codecs/rouleur/rouleur.c b/asoc/codecs/rouleur/rouleur.c
index 8ce51a3b..9066bd8e 100644
--- a/asoc/codecs/rouleur/rouleur.c
+++ b/asoc/codecs/rouleur/rouleur.c
@@ -26,6 +26,7 @@
#include <asoc/msm-cdc-pinctrl.h>
#include <dt-bindings/sound/audio-codec-port-types.h>
#include <asoc/msm-cdc-supply.h>
+#include <linux/power_supply.h>
#define DRV_NAME "rouleur_codec"
@@ -35,6 +36,8 @@
#define ROULEUR_VERSION_ENTRY_SIZE 32
#define NUM_ATTEMPTS 5
+#define SOC_THRESHOLD_LEVEL 25
+#define LOW_SOC_MBIAS_REG_MIN_VOLTAGE 2850000
enum {
CODEC_TX = 0,
@@ -2000,6 +2003,107 @@ done:
return rc;
}
+static int rouleur_battery_supply_cb(struct notifier_block *nb,
+ unsigned long event, void *data)
+{
+ struct power_supply *psy = data;
+ struct rouleur_priv *rouleur =
+ container_of(nb, struct rouleur_priv, psy_nb);
+
+ if (strcmp(psy->desc->name, "battery"))
+ return NOTIFY_OK;
+ queue_work(system_freezable_wq, &rouleur->soc_eval_work);
+
+ return NOTIFY_OK;
+}
+
+static int rouleur_read_battery_soc(struct rouleur_priv *rouleur, int *soc_val)
+{
+ static struct power_supply *batt_psy;
+ union power_supply_propval ret = {0,};
+ int err = 0;
+
+ *soc_val = 100;
+ if (!batt_psy)
+ batt_psy = power_supply_get_by_name("battery");
+ if (batt_psy) {
+ err = power_supply_get_property(batt_psy,
+ POWER_SUPPLY_PROP_CAPACITY, &ret);
+ if (err) {
+ pr_err("%s: battery SoC read error:%d\n",
+ __func__, err);
+ return err;
+ }
+ *soc_val = ret.intval;
+ }
+ pr_debug("%s: soc:%d\n", __func__, *soc_val);
+
+ return err;
+}
+
+static void rouleur_evaluate_soc(struct work_struct *work)
+{
+ struct rouleur_priv *rouleur =
+ container_of(work, struct rouleur_priv, soc_eval_work);
+ int soc_val = 0, ret = 0;
+ struct rouleur_pdata *pdata = NULL;
+
+ pdata = dev_get_platdata(rouleur->dev);
+ if (!pdata) {
+ dev_err(rouleur->dev, "%s: pdata is NULL\n", __func__);
+ return;
+ }
+
+ if (rouleur_read_battery_soc(rouleur, &soc_val) < 0) {
+ dev_err(rouleur->dev, "%s unable to read battery SoC\n",
+ __func__);
+ return;
+ }
+
+ if (soc_val < SOC_THRESHOLD_LEVEL) {
+ dev_dbg(rouleur->dev,
+ "%s battery SoC less than threshold soc_val = %d\n",
+ __func__, soc_val);
+ /* Reduce PA Gain by 6DB for low SoC */
+ if (rouleur->update_wcd_event)
+ rouleur->update_wcd_event(rouleur->handle,
+ WCD_BOLERO_EVT_RX_PA_GAIN_UPDATE,
+ true);
+ rouleur->low_soc = true;
+ ret = msm_cdc_set_supply_min_voltage(rouleur->dev,
+ rouleur->supplies,
+ pdata->regulator,
+ pdata->num_supplies,
+ "cdc-vdd-mic-bias",
+ LOW_SOC_MBIAS_REG_MIN_VOLTAGE,
+ true);
+ if (ret < 0)
+ dev_err(rouleur->dev,
+ "%s unable to set mbias min voltage\n",
+ __func__);
+ } else {
+ if (rouleur->low_soc == true) {
+ /* Reset PA Gain to default for normal SoC */
+ if (rouleur->update_wcd_event)
+ rouleur->update_wcd_event(rouleur->handle,
+ WCD_BOLERO_EVT_RX_PA_GAIN_UPDATE,
+ false);
+ ret = msm_cdc_set_supply_min_voltage(rouleur->dev,
+ rouleur->supplies,
+ pdata->regulator,
+ pdata->num_supplies,
+ "cdc-vdd-mic-bias",
+ LOW_SOC_MBIAS_REG_MIN_VOLTAGE,
+ false);
+ if (ret < 0)
+ dev_err(rouleur->dev,
+ "%s unable to set mbias min voltage\n",
+ __func__);
+ rouleur->low_soc = false;
+ }
+ }
+}
+
static int rouleur_soc_codec_probe(struct snd_soc_component *component)
{
struct rouleur_priv *rouleur = snd_soc_component_get_drvdata(component);
@@ -2070,7 +2174,16 @@ static int rouleur_soc_codec_probe(struct snd_soc_component *component)
return ret;
}
}
+ rouleur->low_soc = false;
rouleur->dev_up = true;
+ /* Register notifier to change gain based on state of charge */
+ INIT_WORK(&rouleur->soc_eval_work, rouleur_evaluate_soc);
+ rouleur->psy_nb.notifier_call = rouleur_battery_supply_cb;
+ if (power_supply_reg_notifier(&rouleur->psy_nb) < 0)
+ dev_dbg(rouleur->dev,
+ "%s: could not register pwr supply notifier\n",
+ __func__);
+ queue_work(system_freezable_wq, &rouleur->soc_eval_work);
done:
return ret;
}