input: fingerprint: fpc_tee: Make vreg control mode runtime configurable

Idea from Mi 11 Lite 5G MIUI V12.5.6.0.RKIMIXM

Change-Id: I4ae9c002b8d58357621523822e457f299cfc0d69
This commit is contained in:
Arian 2022-01-09 23:58:52 +01:00 committed by Giovanni Ricca
parent 4f894e2f18
commit 0443dfad88
No known key found for this signature in database

View File

@ -27,7 +27,6 @@
#define FPC_DRM_INTERFACE_WA
#define CONFIG_FINGERPRINT_FP_VREG_CONTROL
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/atomic.h>
@ -84,9 +83,7 @@ struct vreg_config {
int gpio;
};
#ifdef CONFIG_FINGERPRINT_FP_VREG_CONTROL
struct regulator *vreg;
#endif
static struct vreg_config vreg_conf[] = {
{"vdd_ana", 1800000UL, 1800000UL, 6000, FPC_GPIO_NO_DEFAULT},
@ -94,6 +91,8 @@ static struct vreg_config vreg_conf[] = {
/*{ "vdd_io", 1800000UL, 1800000UL, 6000, }, */
};
static int power_cfg = 0;
struct fpc1020_data {
struct device *dev;
@ -573,35 +572,36 @@ static int device_prepare(struct fpc1020_data *fpc1020, bool enable)
select_pin_ctl(fpc1020, "fpc1020_reset_reset");
#ifdef CONFIG_FINGERPRINT_FP_VREG_CONTROL
pr_info("Try to enable fp_vdd_vreg\n");
vreg = regulator_get(dev, "fp_vdd_vreg");
if (power_cfg == 1) {
pr_info("Try to enable fp_vdd_vreg\n");
vreg = regulator_get(dev, "fp_vdd_vreg");
if (vreg == NULL) {
dev_err(dev, "fp_vdd_vreg regulator get failed!\n");
goto exit;
}
if (vreg == NULL) {
dev_err(dev, "fp_vdd_vreg regulator get failed!\n");
goto exit;
}
if (regulator_is_enabled(vreg)) {
pr_info("fp_vdd_vreg is already enabled!\n");
if (regulator_is_enabled(vreg)) {
pr_info("fp_vdd_vreg is already enabled!\n");
} else {
rc = regulator_enable(vreg);
if (rc) {
dev_err(dev, "error enabling fp_vdd_vreg!\n");
regulator_put(vreg);
vreg = NULL;
goto exit;
}
}
pr_info("fp_vdd_vreg is enabled!\n");
} else {
rc = regulator_enable(vreg);
rc = vreg_setup(fpc1020, "vdd_ana", true);
if (rc) {
dev_err(dev, "error enabling fp_vdd_vreg!\n");
regulator_put(vreg);
vreg = NULL;
goto exit;
dev_dbg(dev, "fpc power on failed。 \n");
goto exit;
}
}
pr_info("fp_vdd_vreg is enabled!\n");
#else
rc = vreg_setup(fpc1020, "vdd_ana", true);
if (rc) {
dev_dbg(dev, "fpc power on failed。 \n");
goto exit;
}
#endif
usleep_range(PWR_ON_SLEEP_MIN_US, PWR_ON_SLEEP_MAX_US);
/* As we can't control chip select here the other part of the
@ -625,19 +625,20 @@ static int device_prepare(struct fpc1020_data *fpc1020, bool enable)
(void)select_pin_ctl(fpc1020, "fpc1020_reset_reset");
usleep_range(PWR_ON_SLEEP_MIN_US, PWR_ON_SLEEP_MAX_US);
#ifdef CONFIG_FINGERPRINT_FP_VREG_CONTROL
rc = regulator_disable(vreg);
if (rc) {
dev_dbg(dev, "error disabling fp_vdd_vreg!\n");
goto exit;
if (power_cfg == 1) {
rc = regulator_disable(vreg);
if (rc) {
dev_dbg(dev, "error disabling fp_vdd_vreg!\n");
goto exit;
}
} else {
rc = vreg_setup(fpc1020, "vdd_ana", false);
if (rc) {
dev_dbg(dev, "fpc vreg power off failed. \n");
goto exit;
}
}
#else
rc = vreg_setup(fpc1020, "vdd_ana", false);
if (rc) {
dev_dbg(dev, "fpc vreg power off failed. \n");
goto exit;
}
#endif
exit:
fpc1020->prepared = false;
} else {
@ -823,6 +824,31 @@ static ssize_t irq_enable_set(struct device *dev,
static DEVICE_ATTR(irq_enable, S_IWUSR | S_IRUSR | S_IRGRP | S_IWGRP, NULL,
irq_enable_set);
static ssize_t power_cfg_set(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
int rc = 0;
struct fpc1020_data *fpc1020 = dev_get_drvdata(dev);
mutex_lock(&fpc1020->lock);
if (!strncmp(buf, "1V8", strlen("1V8")))
power_cfg = 0;
else if (!strncmp(buf, "3V3", strlen("3V3")))
power_cfg = 1;
else
rc = -EINVAL;
mutex_unlock(&fpc1020->lock);
dev_info(fpc1020->dev, "fpc set power_cfg: %d, rc: %d\n", power_cfg, rc);
return rc ? rc : count;
}
static DEVICE_ATTR(power_cfg, S_IWUSR, NULL, power_cfg_set);
static struct attribute *attributes[] = {
&dev_attr_request_vreg.attr,
&dev_attr_pinctl_set.attr,
@ -836,6 +862,7 @@ static struct attribute *attributes[] = {
&dev_attr_irq.attr,
&dev_attr_vendor.attr,
&dev_attr_fingerdown_wait.attr,
&dev_attr_power_cfg.attr,
NULL
};