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 spakkkk
parent 89e9ace199
commit ad96973589
2 changed files with 57 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

@ -360,6 +360,7 @@ struct dwc3_msm {
u64 dummy_gsi_db;
dma_addr_t dummy_gsi_db_dma;
int orientation_override;
bool usb_data_enabled;
};
#define USB_HSPHY_3P3_VOL_MIN 3050000 /* uV */
@ -3294,6 +3295,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);
@ -3355,6 +3359,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);
@ -3686,6 +3693,35 @@ static int dwc_dpdm_cb(struct notifier_block *nb, unsigned long evt, void *p)
return NOTIFY_OK;
}
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;
@ -4058,11 +4094,14 @@ 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_usb_compliance_mode);
device_create_file(&pdev->dev, &dev_attr_bus_vote);
device_create_file(&pdev->dev, &dev_attr_usb_data_enabled);
return 0;
@ -4091,6 +4130,8 @@ static int dwc3_msm_remove(struct platform_device *pdev)
mdwc->dpdm_nb.notifier_call = NULL;
}
device_remove_file(&pdev->dev, &dev_attr_usb_data_enabled);
if (mdwc->usb_psy)
power_supply_put(mdwc->usb_psy);