From 48029da3fe77f9fff666ffe322f0cd5384db7b16 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Fri, 17 Jul 2020 19:13:19 +0530 Subject: [PATCH 1/2] ASoC: rouleur: Change hph and ear gain according to soc capacity Register to power supply framework to get soc capacity. Reduce ear and hph gain for reduced voltage to optimize power consumption. Also set LD22 voltage to lower value for low SoC. Change-Id: I94de9341b8c7307128d3cd41c7398c31d57fa685 Signed-off-by: Vatsal Bucha --- asoc/codecs/bolero/bolero-cdc.c | 9 +++ asoc/codecs/bolero/bolero-cdc.h | 1 + asoc/codecs/bolero/internal.h | 1 + asoc/codecs/bolero/rx-macro.c | 49 ++++++++++++++ asoc/codecs/msm-cdc-supply.c | 46 +++++++++++++ asoc/codecs/rouleur/internal.h | 4 ++ asoc/codecs/rouleur/rouleur.c | 113 ++++++++++++++++++++++++++++++++ include/asoc/msm-cdc-supply.h | 5 ++ 8 files changed, 228 insertions(+) diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index e7fd7a287e46..e14ea9466ef3 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -232,6 +232,15 @@ 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: + /* Update PA Gain only for bolero version 2.1 */ + if (priv->version == BOLERO_VERSION_2_1) + 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 eee4c0c2a7e9..fbfdebcf56d6 100644 --- a/asoc/codecs/bolero/bolero-cdc.h +++ b/asoc/codecs/bolero/bolero-cdc.h @@ -50,6 +50,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 503443158c4a..2bdcb248978f 100644 --- a/asoc/codecs/bolero/internal.h +++ b/asoc/codecs/bolero/internal.h @@ -32,6 +32,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 3271c0cc9029..b28c3e727916 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 { @@ -454,6 +459,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[]; @@ -1460,6 +1467,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; @@ -3882,6 +3929,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 1618b83a5516..e7d868038701 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 cc1500be70d6..b1d21faafb20 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 8ce51a3b159c..9066bd8e60d8 100644 --- a/asoc/codecs/rouleur/rouleur.c +++ b/asoc/codecs/rouleur/rouleur.c @@ -26,6 +26,7 @@ #include #include #include +#include #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; } diff --git a/include/asoc/msm-cdc-supply.h b/include/asoc/msm-cdc-supply.h index c7404007544c..3b19387d4711 100644 --- a/include/asoc/msm-cdc-supply.h +++ b/include/asoc/msm-cdc-supply.h @@ -69,5 +69,10 @@ extern int msm_cdc_init_supplies_v2(struct device *dev, int msm_cdc_init_wcd_supply(struct device_node *np, const char *name, struct cdc_wcd_supply *cdc_supply); int msm_cdc_enable_wcd_supply(struct cdc_wcd_supply *cdc_supply, bool enable); +extern 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); #endif From ef642d3e2aed14dc805cb3afef10a9c6736a9656 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Tue, 14 Jul 2020 05:33:06 +0530 Subject: [PATCH 2/2] ASoC: rouleur: Update hph registers based on foundry id Rouleur has different hph settings for different foundry id. Read foundry id and update hph settings so as to provide same settings to end user. Change-Id: I114047226462ab95e0c93271c3d6099f15af2343 Signed-off-by: Vatsal Bucha --- asoc/codecs/bolero/bolero-cdc.c | 12 +++++++ asoc/codecs/bolero/bolero-cdc.h | 2 ++ asoc/codecs/bolero/internal.h | 2 ++ asoc/codecs/bolero/rx-macro.c | 10 ++++++ asoc/codecs/rouleur/internal.h | 5 +++ asoc/codecs/rouleur/pm2250-spmi.h | 5 +++ asoc/codecs/rouleur/pm2250_spmi.c | 34 +++++++++++++++++++ asoc/codecs/rouleur/rouleur.c | 55 +++++++++++++++++++++++++++++++ 8 files changed, 125 insertions(+) diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index e14ea9466ef3..0ee578cfaab8 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -241,6 +241,18 @@ static int bolero_cdc_update_wcd_event(void *handle, u16 event, u32 data) BOLERO_MACRO_EVT_RX_PA_GAIN_UPDATE, data); break; + case WCD_BOLERO_EVT_HPHL_HD2_ENABLE: + if (priv->macro_params[RX_MACRO].event_handler) + priv->macro_params[RX_MACRO].event_handler( + priv->component, + BOLERO_MACRO_EVT_HPHL_HD2_ENABLE, data); + break; + case WCD_BOLERO_EVT_HPHR_HD2_ENABLE: + if (priv->macro_params[RX_MACRO].event_handler) + priv->macro_params[RX_MACRO].event_handler( + priv->component, + BOLERO_MACRO_EVT_HPHR_HD2_ENABLE, 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 fbfdebcf56d6..85784265b8f9 100644 --- a/asoc/codecs/bolero/bolero-cdc.h +++ b/asoc/codecs/bolero/bolero-cdc.h @@ -51,6 +51,8 @@ enum { BOLERO_MACRO_EVT_SSR_GFMUX_UP, BOLERO_MACRO_EVT_PRE_SSR_UP, BOLERO_MACRO_EVT_RX_PA_GAIN_UPDATE, + BOLERO_MACRO_EVT_HPHL_HD2_ENABLE, /* Enable HD2 cfg for HPHL */ + BOLERO_MACRO_EVT_HPHR_HD2_ENABLE, /* Enable HD2 cfg for HPHR */ }; enum { diff --git a/asoc/codecs/bolero/internal.h b/asoc/codecs/bolero/internal.h index 2bdcb248978f..cd2cdcbfc40d 100644 --- a/asoc/codecs/bolero/internal.h +++ b/asoc/codecs/bolero/internal.h @@ -33,6 +33,8 @@ enum { WCD_BOLERO_EVT_RX_COMPANDER_SOFT_RST, WCD_BOLERO_EVT_BCS_CLK_OFF, WCD_BOLERO_EVT_RX_PA_GAIN_UPDATE, + WCD_BOLERO_EVT_HPHL_HD2_ENABLE, /* to enable hd2 config for hphl */ + WCD_BOLERO_EVT_HPHR_HD2_ENABLE, /* to enable hd2 config for hphr */ }; struct wcd_ctrl_platform_data { diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index b28c3e727916..7d54d4281a14 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -1507,6 +1507,16 @@ static int rx_macro_event_handler(struct snd_soc_component *component, RX_MACRO_MOD_GAIN)); } break; + case BOLERO_MACRO_EVT_HPHL_HD2_ENABLE: + /* Enable hd2 config for hphl*/ + snd_soc_component_update_bits(component, + BOLERO_CDC_RX_RX0_RX_PATH_CFG0, 0x04, data); + break; + case BOLERO_MACRO_EVT_HPHR_HD2_ENABLE: + /* Enable hd2 config for hphr*/ + snd_soc_component_update_bits(component, + BOLERO_CDC_RX_RX1_RX_PATH_CFG0, 0x04, data); + break; } done: return ret; diff --git a/asoc/codecs/rouleur/internal.h b/asoc/codecs/rouleur/internal.h index b1d21faafb20..a8fc83325c33 100644 --- a/asoc/codecs/rouleur/internal.h +++ b/asoc/codecs/rouleur/internal.h @@ -88,6 +88,8 @@ struct rouleur_priv { struct notifier_block psy_nb; struct work_struct soc_eval_work; bool low_soc; + int foundry_id_reg; + int foundry_id; }; struct rouleur_micbias_setting { @@ -105,6 +107,7 @@ struct rouleur_pdata { struct cdc_regulator *regulator; int num_supplies; int reset_reg; + int foundry_id_reg; }; struct wcd_ctrl_platform_data { @@ -135,6 +138,8 @@ enum { 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 */ + WCD_BOLERO_EVT_HPHL_HD2_ENABLE, /* to enable hd2 config for hphl */ + WCD_BOLERO_EVT_HPHR_HD2_ENABLE, /* to enable hd2 config for hphr */ }; enum { diff --git a/asoc/codecs/rouleur/pm2250-spmi.h b/asoc/codecs/rouleur/pm2250-spmi.h index 87c913d43d0f..2eaf28f02cc6 100644 --- a/asoc/codecs/rouleur/pm2250-spmi.h +++ b/asoc/codecs/rouleur/pm2250-spmi.h @@ -7,11 +7,16 @@ #ifdef CONFIG_PM2250_SPMI int pm2250_spmi_write(struct device *dev, int reg, int value); +int pm2250_spmi_read(struct device *dev, int reg, int *value); #else int pm2250_spmi_write(struct device *dev, int reg, int value) { return 0; } +int pm2250_spmi_read(struct device *dev, int reg, int *value); +{ + return 0; +} #endif /* CONFIG_PM2250_SPMI */ #endif diff --git a/asoc/codecs/rouleur/pm2250_spmi.c b/asoc/codecs/rouleur/pm2250_spmi.c index 1e5f70d177e8..10a7d109bbbe 100644 --- a/asoc/codecs/rouleur/pm2250_spmi.c +++ b/asoc/codecs/rouleur/pm2250_spmi.c @@ -25,6 +25,12 @@ static const struct of_device_id pm2250_id_table[] = { }; MODULE_DEVICE_TABLE(of, pm2250_id_table); +/** + * pm2250_spmi_write: Function to write to PMIC register + * @device: node for rouleur device + * @reg: PMIC register to write value + * @value: Value to be written to PMIC register + */ int pm2250_spmi_write(struct device *dev, int reg, int value) { int rc; @@ -47,6 +53,34 @@ int pm2250_spmi_write(struct device *dev, int reg, int value) } EXPORT_SYMBOL(pm2250_spmi_write); +/** + * pm2250_spmi_read: Function to read PMIC register + * @device: node for rouleur device + * @reg: PMIC register to read value + * @value: Pointer to value of reg to be read + */ +int pm2250_spmi_read(struct device *dev, int reg, int *value) +{ + int rc; + struct pm2250_spmi *spmi_dd; + + if (!of_device_is_compatible(dev->of_node, "qcom,pm2250-spmi")) { + pr_err("%s: Device node is invalid\n", __func__); + return -EINVAL; + } + + spmi_dd = dev_get_drvdata(dev); + if (!spmi_dd) + return -EINVAL; + + rc = regmap_read(spmi_dd->regmap, reg, value); + if (rc) + dev_err(dev, "%s: Read from PMIC register failed\n", __func__); + + return rc; +} +EXPORT_SYMBOL(pm2250_spmi_read); + static int pm2250_spmi_probe(struct platform_device *pdev) { struct pm2250_spmi *spmi_dd; diff --git a/asoc/codecs/rouleur/rouleur.c b/asoc/codecs/rouleur/rouleur.c index 9066bd8e60d8..44ec2476a8e0 100644 --- a/asoc/codecs/rouleur/rouleur.c +++ b/asoc/codecs/rouleur/rouleur.c @@ -39,6 +39,8 @@ #define SOC_THRESHOLD_LEVEL 25 #define LOW_SOC_MBIAS_REG_MIN_VOLTAGE 2850000 +#define FOUNDRY_ID_SEC 0x5 + enum { CODEC_TX = 0, CODEC_RX, @@ -641,6 +643,11 @@ static int rouleur_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, set_bit(HPH_PA_DELAY, &rouleur->status_mask); usleep_range(200, 210); + /* Enable HD2 Config for HPHR if foundry id is SEC */ + if (rouleur->foundry_id == FOUNDRY_ID_SEC) + rouleur->update_wcd_event(rouleur->handle, + WCD_BOLERO_EVT_HPHR_HD2_ENABLE, + 0x04); snd_soc_component_update_bits(component, ROULEUR_DIG_SWR_PDM_WD_CTL1, 0x03, 0x03); @@ -685,6 +692,10 @@ static int rouleur_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, clear_bit(HPH_PA_DELAY, &rouleur->status_mask); } + if (rouleur->foundry_id == FOUNDRY_ID_SEC) + rouleur->update_wcd_event(rouleur->handle, + WCD_BOLERO_EVT_HPHR_HD2_ENABLE, + 0x00); blocking_notifier_call_chain(&rouleur->mbhc->notifier, WCD_EVENT_POST_HPHR_PA_OFF, &rouleur->mbhc->wcd_mbhc); @@ -715,6 +726,10 @@ static int rouleur_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, true); set_bit(HPH_PA_DELAY, &rouleur->status_mask); usleep_range(200, 210); + if (rouleur->foundry_id == FOUNDRY_ID_SEC) + rouleur->update_wcd_event(rouleur->handle, + WCD_BOLERO_EVT_HPHL_HD2_ENABLE, + 0x04); snd_soc_component_update_bits(component, ROULEUR_DIG_SWR_PDM_WD_CTL0, 0x03, 0x03); @@ -758,6 +773,10 @@ static int rouleur_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, clear_bit(HPH_PA_DELAY, &rouleur->status_mask); } + if (rouleur->foundry_id == FOUNDRY_ID_SEC) + rouleur->update_wcd_event(rouleur->handle, + WCD_BOLERO_EVT_HPHL_HD2_ENABLE, + 0x00); blocking_notifier_call_chain(&rouleur->mbhc->notifier, WCD_EVENT_POST_HPHL_PA_OFF, &rouleur->mbhc->wcd_mbhc); @@ -798,6 +817,10 @@ static int rouleur_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, snd_soc_component_update_bits(component, ROULEUR_ANA_COMBOPA_CTL, 0x40, 0x00); + if (rouleur->foundry_id == FOUNDRY_ID_SEC) + rouleur->update_wcd_event(rouleur->handle, + WCD_BOLERO_EVT_HPHL_HD2_ENABLE, + 0x04); snd_soc_component_update_bits(component, ROULEUR_DIG_SWR_PDM_WD_CTL0, 0x03, 0x03); @@ -824,6 +847,10 @@ static int rouleur_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, break; case SND_SOC_DAPM_POST_PMD: usleep_range(5000, 5100); + if (rouleur->foundry_id == FOUNDRY_ID_SEC) + rouleur->update_wcd_event(rouleur->handle, + WCD_BOLERO_EVT_HPHL_HD2_ENABLE, + 0x00); snd_soc_component_update_bits(component, ROULEUR_DIG_SWR_PDM_WD_CTL0, 0x03, 0x00); @@ -2104,6 +2131,25 @@ static void rouleur_evaluate_soc(struct work_struct *work) } } +static void rouleur_get_foundry_id(struct rouleur_priv *rouleur) +{ + int ret; + + if (rouleur->foundry_id_reg == 0) { + pr_debug("%s: foundry id not defined\n", __func__); + return; + } + + ret = pm2250_spmi_read(rouleur->spmi_dev, + rouleur->foundry_id_reg, &rouleur->foundry_id); + if (ret == 0) + pr_debug("%s: rouleur foundry id = %x\n", rouleur->foundry_id, + __func__); + else + pr_debug("%s: rouleur error in spmi read ret = %d\n", + __func__, ret); +} + static int rouleur_soc_codec_probe(struct snd_soc_component *component) { struct rouleur_priv *rouleur = snd_soc_component_get_drvdata(component); @@ -2159,6 +2205,8 @@ static int rouleur_soc_codec_probe(struct snd_soc_component *component) snd_soc_dapm_sync(dapm); rouleur_init_reg(component); + /* Get rouleur foundry id */ + rouleur_get_foundry_id(rouleur); rouleur->version = ROULEUR_VERSION_1_0; /* Register event notifier */ @@ -2417,6 +2465,12 @@ struct rouleur_pdata *rouleur_populate_dt_data(struct device *dev) } pdata->reset_reg = reg; + if (of_property_read_u32(dev->of_node, "qcom,foundry-id-reg", ®)) + dev_dbg(dev, "%s: Failed to obtain foundry id\n", + __func__); + else + pdata->foundry_id_reg = reg; + /* Parse power supplies */ msm_cdc_get_power_supplies(dev, &pdata->regulator, &pdata->num_supplies); @@ -2492,6 +2546,7 @@ static int rouleur_bind(struct device *dev) rouleur->spmi_dev = &pdev->dev; rouleur->reset_reg = pdata->reset_reg; + rouleur->foundry_id_reg = pdata->foundry_id_reg; ret = msm_cdc_init_supplies(dev, &rouleur->supplies, pdata->regulator, pdata->num_supplies); if (!rouleur->supplies) {