diff options
author | qctecmdr <qctecmdr@localhost> | 2020-07-30 01:44:59 -0700 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2020-07-30 01:44:59 -0700 |
commit | dde137e930beb3a2e6a5664f98698f997dd5db41 (patch) | |
tree | 5f8f2a2209c7ffef76520554dc3dd76af75eadc8 /asoc | |
parent | 280fd01fc83b8afe7bfda5e537018dbc5d0054f7 (diff) | |
parent | 8203a06e6197a322b426971de2bfb94d5c29616a (diff) | |
download | msm-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.c | 6 | ||||
-rw-r--r-- | asoc/codecs/bolero/bolero-cdc.h | 1 | ||||
-rw-r--r-- | asoc/codecs/bolero/internal.h | 1 | ||||
-rw-r--r-- | asoc/codecs/bolero/rx-macro.c | 49 | ||||
-rw-r--r-- | asoc/codecs/msm-cdc-supply.c | 46 | ||||
-rw-r--r-- | asoc/codecs/rouleur/internal.h | 4 | ||||
-rw-r--r-- | asoc/codecs/rouleur/rouleur.c | 113 |
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; } |