usb: new attributes implementation to enable/disable usb data

Bug: 188760285
Test: driver probe and attributes access normally
Signed-off-by: Albert Wang <albertccwang@google.com>
Change-Id: I0aec98eebff9454cdec065bb09825f6442ac013b
This commit is contained in:
Albert Wang 2021-07-02 21:06:34 +08:00 • committed by Michael Bestas
commit 082f70a89c
No known key found for this signature in database
GPG key ID: CC95044519BE6669
2 changed files with 55 additions and 0 deletions

View file

@ -0,0 +1,16 @@
What: /sys/class/udc/<udc name>/device/usb_data_enabled
Date: December 2020
Contact: "Ray Chi" <raychi@google.com>
Description:
The attribute can allow user space can check and modify
the value to enable or disable usb functionality. Therefore,
if the attritube is set to 0, USB host and USB peripheral
modes wouldn't be working.
Example:
Enable USB data functionality
# echo 1 > /sys/class/udc/.../device/usb_data_enabled
Disable USB data functionality
# echo 0 > /sys/class/udc/.../device/usb_data_enabled

View file

@ -533,6 +533,7 @@ struct dwc3_msm {
bool dual_port;
bool perf_mode;
bool usb_data_enabled;
};
#define USB_HSPHY_3P3_VOL_MIN 3050000 /* uV */
@ -4023,6 +4024,9 @@ static int dwc3_msm_id_notifier(struct notifier_block *nb,
if (!edev || !mdwc)
return NOTIFY_DONE;
if (!mdwc->usb_data_enabled)
return NOTIFY_DONE;
dwc = platform_get_drvdata(mdwc->dwc3);
dbg_event(0xFF, "extcon idx", enb->idx);
@ -4077,6 +4081,9 @@ static int dwc3_msm_vbus_notifier(struct notifier_block *nb,
if (!edev || !mdwc)
return NOTIFY_DONE;
if (!mdwc->usb_data_enabled)
return NOTIFY_DONE;
dwc = platform_get_drvdata(mdwc->dwc3);
dbg_event(0xFF, "extcon idx", enb->idx);
@ -4660,6 +4667,34 @@ int dwc3_msm_release_ss_lane(struct device *dev, bool usb_dp_concurrent_mode)
}
EXPORT_SYMBOL(dwc3_msm_release_ss_lane);
static ssize_t usb_data_enabled_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct dwc3_msm *mdwc = dev_get_drvdata(dev);
return sysfs_emit(buf, "%s\n",
mdwc->usb_data_enabled ? "enabled" : "disabled");
}
static ssize_t usb_data_enabled_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct dwc3_msm *mdwc = dev_get_drvdata(dev);
if (kstrtobool(buf, &mdwc->usb_data_enabled))
return -EINVAL;
if (!mdwc->usb_data_enabled) {
mdwc->vbus_active = false;
mdwc->id_state = DWC3_ID_FLOAT;
dwc3_ext_event_notify(mdwc);
}
return count;
}
static DEVICE_ATTR_RW(usb_data_enabled);
static int dwc3_msm_probe(struct platform_device *pdev)
{
struct device_node *node = pdev->dev.of_node, *dwc3_node;
@ -5077,10 +5112,13 @@ static int dwc3_msm_probe(struct platform_device *pdev)
dwc3_ext_event_notify(mdwc);
}
/* set the initial value */
mdwc->usb_data_enabled = true;
device_create_file(&pdev->dev, &dev_attr_orientation);
device_create_file(&pdev->dev, &dev_attr_mode);
device_create_file(&pdev->dev, &dev_attr_speed);
device_create_file(&pdev->dev, &dev_attr_bus_vote);
device_create_file(&pdev->dev, &dev_attr_usb_data_enabled);
return 0;
@ -5109,6 +5147,7 @@ static int dwc3_msm_remove(struct platform_device *pdev)
device_remove_file(&pdev->dev, &dev_attr_mode);
device_remove_file(&pdev->dev, &dev_attr_speed);
device_remove_file(&pdev->dev, &dev_attr_bus_vote);
device_remove_file(&pdev->dev, &dev_attr_usb_data_enabled);
if (mdwc->dpdm_nb.notifier_call) {
regulator_unregister_notifier(mdwc->dpdm_reg, &mdwc->dpdm_nb);