diff options
author | Davide Garberi <dade.garberi@gmail.com> | 2019-08-21 03:23:03 +0200 |
---|---|---|
committer | Michael Bestas <mkbestas@lineageos.org> | 2020-05-01 17:02:33 +0300 |
commit | 6abc14f74a4e924d00b2919e7dd3cf2921a3c8bd (patch) | |
tree | b78f3ed1a830626a343accb4888cb8f2ceb1ca7d /drivers | |
parent | 1727d33f3c9f948ef8f3b9b5034e46ef0a11e123 (diff) |
iio: qcom-rradc: Import xiaomi tulip changes
* Modified ifdef style and config name to MACH_XIAOMI_TULIP
Change-Id: I6d270520ffd7b52d36d7657d1c53b6fb5a48cefb
Signed-off-by: Isaac Chen <tingyi364@gmail.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/iio/adc/qcom-rradc.c | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/drivers/iio/adc/qcom-rradc.c b/drivers/iio/adc/qcom-rradc.c index b3aa73f1a5a1..62153b8a8594 100644 --- a/drivers/iio/adc/qcom-rradc.c +++ b/drivers/iio/adc/qcom-rradc.c @@ -199,6 +199,10 @@ #define FG_RR_TP_REV_VERSION2 29 #define FG_RR_TP_REV_VERSION3 32 +#ifdef CONFIG_MACH_XIAOMI_TULIP +int rradc_die = 0; +#endif + /* * The channel number is not a physical index in hardware, * rather it's a list of supported channels and an index to @@ -236,6 +240,13 @@ struct rradc_chip { struct pmic_revid_data *pmic_fab_id; int volt; struct power_supply *usb_trig; +#ifdef CONFIG_MACH_XIAOMI_TULIP + struct power_supply *batt_psy; + struct power_supply *bms_psy; + struct notifier_block nb; + bool conv_cbk; + struct work_struct psy_notify_work; +#endif }; struct rradc_channels { @@ -680,6 +691,30 @@ static const struct rradc_channels rradc_chans[] = { FG_ADC_RR_AUX_THERM_STS) }; +#ifdef CONFIG_MACH_XIAOMI_TULIP +static bool rradc_is_batt_psy_available(struct rradc_chip *chip) +{ + if (!chip->batt_psy) + chip->batt_psy = power_supply_get_by_name("battery"); + + if (!chip->batt_psy) + return false; + + return true; +} + +static bool rradc_is_bms_psy_available(struct rradc_chip *chip) +{ + if (!chip->bms_psy) + chip->bms_psy = power_supply_get_by_name("bms"); + + if (!chip->bms_psy) + return false; + + return true; +} +#endif + static int rradc_enable_continuous_mode(struct rradc_chip *chip) { int rc = 0; @@ -749,6 +784,9 @@ static int rradc_check_status_ready_with_retry(struct rradc_chip *chip, struct rradc_chan_prop *prop, u8 *buf, u16 status) { int rc = 0, retry_cnt = 0, mask = 0; +#ifdef CONFIG_MACH_XIAOMI_TULIP + union power_supply_propval pval = {0, }; +#endif switch (prop->channel) { case RR_ADC_BATT_ID: @@ -784,8 +822,31 @@ static int rradc_check_status_ready_with_retry(struct rradc_chip *chip, } } +#ifdef CONFIG_MACH_XIAOMI_TULIP + if ((retry_cnt >= FG_RR_CONV_MAX_RETRY_CNT) && + ((prop->channel != RR_ADC_DCIN_V) || + (prop->channel != RR_ADC_DCIN_I))) { + pr_err("rradc is hung, Proceed to recovery\n"); + if (rradc_is_bms_psy_available(chip)) { + rc = power_supply_set_property(chip->bms_psy, + POWER_SUPPLY_PROP_FG_RESET_CLOCK, + &pval); + if (rc < 0) { + pr_err("Couldn't reset FG clock rc=%d\n", rc); + return rc; + } + } else { + pr_err("Error obtaining bms power supply\n"); + rc = -EINVAL; + } + } else { + if (retry_cnt >= FG_RR_CONV_MAX_RETRY_CNT) + rc = -ENODATA; + } +#else if (retry_cnt >= FG_RR_CONV_MAX_RETRY_CNT) rc = -ENODATA; +#endif return rc; } @@ -1073,6 +1134,66 @@ static int rradc_read_raw(struct iio_dev *indio_dev, return rc; } +#ifdef CONFIG_MACH_XIAOMI_TULIP +static void psy_notify_work(struct work_struct *work) +{ + struct rradc_chip *chip = container_of(work, + struct rradc_chip, psy_notify_work); + + struct rradc_chan_prop *prop; + union power_supply_propval pval = {0, }; + u16 adc_code; + int rc = 0; + + if (rradc_is_batt_psy_available(chip)) { + rc = power_supply_get_property(chip->batt_psy, + POWER_SUPPLY_PROP_STATUS, &pval); + if (rc < 0) { + pr_err("Error obtaining battery status, rc=%d\n", rc); + } + + if (pval.intval == POWER_SUPPLY_STATUS_CHARGING) { + chip->conv_cbk = true; + prop = &chip->chan_props[RR_ADC_USBIN_V]; + rc = rradc_do_conversion(chip, prop, &adc_code); + if (rc == -ENODATA) { + pr_err("rradc is hung, Proceed to recovery\n"); + rradc_die = 1; + if (rradc_is_bms_psy_available(chip)) { + rc = power_supply_set_property + (chip->bms_psy, + POWER_SUPPLY_PROP_FG_RESET_CLOCK, + &pval); + if (rc < 0) { + pr_err("Couldn't reset FG clock rc=%d\n", rc); + } + } else { + pr_err("Error obtaining bms power supply"); + } + } + } + } else { + pr_err("Error obtaining battery power supply"); + } + chip->conv_cbk = false; + pm_relax(chip->dev); +} + +static int rradc_psy_notifier_cb(struct notifier_block *nb, + unsigned long event, void *data) +{ + struct power_supply *psy = data; + struct rradc_chip *chip = container_of(nb, struct rradc_chip, nb); + + if (strcmp(psy->desc->name, "battery") == 0) { + pm_stay_awake(chip->dev); + schedule_work(&chip->psy_notify_work); + } + + return NOTIFY_OK; +} +#endif + static const struct iio_info rradc_info = { .read_raw = &rradc_read_raw, .driver_module = THIS_MODULE, @@ -1180,6 +1301,21 @@ static int rradc_probe(struct platform_device *pdev) indio_dev->channels = chip->iio_chans; indio_dev->num_channels = chip->nchannels; +#ifdef CONFIG_MACH_XIAOMI_TULIP + chip->batt_psy = power_supply_get_by_name("battery"); + if (!chip->batt_psy) + pr_debug("Error obtaining battery power supply\n"); + + chip->bms_psy = power_supply_get_by_name("bms"); + if (!chip->bms_psy) + pr_debug("Error obtaining bms power supply\n"); + + chip->nb.notifier_call = rradc_psy_notifier_cb; + rc = power_supply_reg_notifier(&chip->nb); + if (rc < 0) + pr_err("Error registering psy notifier rc = %d\n", rc); + INIT_WORK(&chip->psy_notify_work, psy_notify_work); +#endif chip->usb_trig = power_supply_get_by_name("usb"); if (!chip->usb_trig) pr_debug("Error obtaining usb power supply\n"); |