summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrei Ciubotariu <aciubotariu@google.com>2024-01-05 17:40:05 -0800
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2024-01-12 08:30:08 +0000
commit9b607e693df841b8deeb6492ec048e6e6241c9d0 (patch)
tree82236e9868e7582c4642f89e62324b56335c2f95
parentb6f5cc52e952f408f98abbc967bb3b234288b01f (diff)
downloadmsm-9b607e693df841b8deeb6492ec048e6e6241c9d0.tar.gz
google-smblite-hvdcp: Runtime-enable HVDCP (QC3.0) negotiation
- Add 'enabled' sysfs node to gate HVDCP negotiation at runtime. Default is 0 (disabled). Write 1 to the node to enable. - For an HVDCP request, the state machine will now first transition to a READY state. When in READY, the state machine will start negotiation only if enabled is set. Bug: 319005242 Signed-off-by: Andrei Ciubotariu <aciubotariu@google.com> (cherry picked from https://partner-android-review.googlesource.com/q/commit:7d418969964edbc0ca6aceaf133b6c21b577c36c) (cherry picked from https://partner-android-review.googlesource.com/q/commit:62f5509d09c84eafcc101dac64596a332fbcfaeb) Merged-In: I89933873cc50a3b1fe2617ff96a05ba78df6fed6 Change-Id: I89933873cc50a3b1fe2617ff96a05ba78df6fed6
-rw-r--r--drivers/power/supply/google/google-smblite-hvdcp.c64
1 files changed, 63 insertions, 1 deletions
diff --git a/drivers/power/supply/google/google-smblite-hvdcp.c b/drivers/power/supply/google/google-smblite-hvdcp.c
index 558d5c8..4a3fabf 100644
--- a/drivers/power/supply/google/google-smblite-hvdcp.c
+++ b/drivers/power/supply/google/google-smblite-hvdcp.c
@@ -5,7 +5,9 @@
Controller state transitions illustrated below in graphviz format:
digraph {
- OFF -> USBIN_SUSPEND_WAIT [label="HVDCP request"]
+ OFF -> READY [label="HVDCP request received"]
+ READY -> USBIN_SUSPEND_WAIT [label="HVDCP functionality enabled"]
+ READY -> OFF [label="unplug"]
USBIN_SUSPEND_WAIT -> ENTER_IDLE_WAIT [label="usbin suspended"]
@@ -67,6 +69,7 @@ Controller state transitions illustrated below in graphviz format:
#define STATES \
X(OFF) \
+ X(READY) \
X(PAUSE) \
X(USBIN_SUSPEND_WAIT) \
X(ENTER_IDLE_WAIT) \
@@ -157,6 +160,7 @@ struct hvdcp {
u16 settle_monitor_ms;
u32 voltage_ceiling;
u32 abandon_timeout_ms;
+ bool enabled;
struct device *dev;
struct power_supply *shim_psy;
struct smblite_shim *smblite_shim;
@@ -479,6 +483,18 @@ rerun_controller:
switch (hvdcp->state) {
case HVDCP_OFF:
+ new_state = HVDCP_READY;
+ wait_ms = 0;
+ break;
+ case HVDCP_READY:
+ if (!hvdcp->enabled) {
+ /*
+ * Nothing to do if functionality is disabled, park
+ * here in case functionality gets enabled.
+ */
+ wait_ms = WAIT_DISABLED;
+ break;
+ }
/*
* Suspend the charging path so that:
* - We can read an accurate charger voltage without drops due
@@ -726,11 +742,57 @@ static ssize_t state_show(struct device *dev, struct device_attribute *attr,
}
static const DEVICE_ATTR_RO(state);
+static ssize_t enabled_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ bool enabled;
+ struct platform_device *pdev =
+ container_of(dev, struct platform_device, dev);
+ struct hvdcp *hvdcp = platform_get_drvdata(pdev);
+
+ mutex_lock(&hvdcp->lock);
+ enabled = hvdcp->enabled;
+ mutex_unlock(&hvdcp->lock);
+
+ return scnprintf(buf, PAGE_SIZE, "%u\n", (int)enabled);
+}
+
+static ssize_t enabled_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ bool enable;
+ int ret;
+ struct platform_device *pdev =
+ container_of(dev, struct platform_device, dev);
+ struct hvdcp *hvdcp = platform_get_drvdata(pdev);
+
+ ret = kstrtobool(buf, &enable);
+ if (ret != 0)
+ return ret;
+
+ mutex_lock(&hvdcp->lock);
+ hvdcp->enabled = enable;
+ if (hvdcp->state == HVDCP_READY)
+ queue_work(hvdcp->controller_q, &hvdcp->controller_work);
+ mutex_unlock(&hvdcp->lock);
+
+ return count;
+}
+static const DEVICE_ATTR_RW(enabled);
+
static int setup_sysfs(struct hvdcp *hvdcp)
{
struct device *dev = hvdcp->dev;
int ret;
+ ret = device_create_file(hvdcp->dev, &dev_attr_enabled);
+ if (ret < 0) {
+ dev_err(dev, "Failed to create %s: %d\n",
+ dev_attr_enabled.attr.name, ret);
+ return ret;
+ }
+
ret = device_create_file(hvdcp->dev, &dev_attr_state);
if (ret < 0) {
dev_err(dev, "Failed to create %s: %d\n",