diff options
author | Andrei Ciubotariu <aciubotariu@google.com> | 2024-01-05 17:40:05 -0800 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2024-01-12 08:30:08 +0000 |
commit | 9b607e693df841b8deeb6492ec048e6e6241c9d0 (patch) | |
tree | 82236e9868e7582c4642f89e62324b56335c2f95 | |
parent | b6f5cc52e952f408f98abbc967bb3b234288b01f (diff) | |
download | msm-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.c | 64 |
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", |