Merge "extcon: usb-gpio: Add support for optional VBUS output enable GPIO"

This commit is contained in:
qctecmdr Service
2019-01-30 17:08:54 -08:00
committed by Gerrit - the friendly Code Review server
2 changed files with 15 additions and 1 deletions

View File

@@ -10,6 +10,9 @@ Either one of id-gpio or vbus-gpio must be present. Both can be present as well.
- id-gpio: gpio for USB ID pin. See gpio binding. - id-gpio: gpio for USB ID pin. See gpio binding.
- vbus-gpio: gpio for USB VBUS pin. - vbus-gpio: gpio for USB VBUS pin.
Optional properties:
- vbus-out-gpio: gpio for enabling VBUS output (e.g. when entering host mode)
Example: Examples of extcon-usb-gpio node in dra7-evm.dts as listed below: Example: Examples of extcon-usb-gpio node in dra7-evm.dts as listed below:
extcon_usb1 { extcon_usb1 {
compatible = "linux,extcon-usb-gpio"; compatible = "linux,extcon-usb-gpio";

View File

@@ -36,6 +36,7 @@ struct usb_extcon_info {
struct gpio_desc *id_gpiod; struct gpio_desc *id_gpiod;
struct gpio_desc *vbus_gpiod; struct gpio_desc *vbus_gpiod;
struct gpio_desc *vbus_out_gpiod;
int id_irq; int id_irq;
int vbus_irq; int vbus_irq;
@@ -80,12 +81,17 @@ static void usb_extcon_detect_cable(struct work_struct *work)
gpiod_get_value_cansleep(info->vbus_gpiod) : id; gpiod_get_value_cansleep(info->vbus_gpiod) : id;
/* at first we clean states which are no longer active */ /* at first we clean states which are no longer active */
if (id) if (id) {
if (info->vbus_out_gpiod)
gpiod_set_value_cansleep(info->vbus_out_gpiod, 0);
extcon_set_state_sync(info->edev, EXTCON_USB_HOST, false); extcon_set_state_sync(info->edev, EXTCON_USB_HOST, false);
}
if (!vbus) if (!vbus)
extcon_set_state_sync(info->edev, EXTCON_USB, false); extcon_set_state_sync(info->edev, EXTCON_USB, false);
if (!id) { if (!id) {
if (info->vbus_out_gpiod)
gpiod_set_value_cansleep(info->vbus_out_gpiod, 1);
extcon_set_state_sync(info->edev, EXTCON_USB_HOST, true); extcon_set_state_sync(info->edev, EXTCON_USB_HOST, true);
} else { } else {
if (vbus) if (vbus)
@@ -121,6 +127,8 @@ static int usb_extcon_probe(struct platform_device *pdev)
info->id_gpiod = devm_gpiod_get_optional(&pdev->dev, "id", GPIOD_IN); info->id_gpiod = devm_gpiod_get_optional(&pdev->dev, "id", GPIOD_IN);
info->vbus_gpiod = devm_gpiod_get_optional(&pdev->dev, "vbus", info->vbus_gpiod = devm_gpiod_get_optional(&pdev->dev, "vbus",
GPIOD_IN); GPIOD_IN);
info->vbus_out_gpiod = devm_gpiod_get_optional(&pdev->dev, "vbus-out",
GPIOD_OUT_HIGH);
if (!info->id_gpiod && !info->vbus_gpiod) { if (!info->id_gpiod && !info->vbus_gpiod) {
dev_err(dev, "failed to get gpios\n"); dev_err(dev, "failed to get gpios\n");
@@ -133,6 +141,9 @@ static int usb_extcon_probe(struct platform_device *pdev)
if (IS_ERR(info->vbus_gpiod)) if (IS_ERR(info->vbus_gpiod))
return PTR_ERR(info->vbus_gpiod); return PTR_ERR(info->vbus_gpiod);
if (IS_ERR(info->vbus_out_gpiod))
return PTR_ERR(info->vbus_out_gpiod);
info->edev = devm_extcon_dev_allocate(dev, usb_extcon_cable); info->edev = devm_extcon_dev_allocate(dev, usb_extcon_cable);
if (IS_ERR(info->edev)) { if (IS_ERR(info->edev)) {
dev_err(dev, "failed to allocate extcon device\n"); dev_err(dev, "failed to allocate extcon device\n");