Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bb70b615 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "drivers/extcon: Trigger gpio when device switch to usb host mode"

parents cf763442 3905e7ec
Loading
Loading
Loading
Loading
+33 −0
Original line number Original line Diff line number Diff line
@@ -27,6 +27,7 @@
#include <linux/slab.h>
#include <linux/slab.h>
#include <linux/workqueue.h>
#include <linux/workqueue.h>
#include <linux/acpi.h>
#include <linux/acpi.h>
#include <linux/delay.h>


#define USB_GPIO_DEBOUNCE_MS	20	/* ms */
#define USB_GPIO_DEBOUNCE_MS	20	/* ms */


@@ -36,6 +37,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 *trig_gpiod;
	int id_irq;
	int id_irq;
	int vbus_irq;
	int vbus_irq;


@@ -87,6 +89,12 @@ static void usb_extcon_detect_cable(struct work_struct *work)


	if (!id) {
	if (!id) {
		extcon_set_state_sync(info->edev, EXTCON_USB_HOST, true);
		extcon_set_state_sync(info->edev, EXTCON_USB_HOST, true);
		if (info->trig_gpiod) {
			gpiod_set_value(info->trig_gpiod, 1);
			msleep(20);
			gpiod_set_value(info->trig_gpiod, 0);
			msleep(20);
		}
	} else {
	} else {
		if (vbus)
		if (vbus)
			extcon_set_state_sync(info->edev, EXTCON_USB, true);
			extcon_set_state_sync(info->edev, EXTCON_USB, true);
@@ -109,6 +117,7 @@ static int usb_extcon_probe(struct platform_device *pdev)
	struct device_node *np = dev->of_node;
	struct device_node *np = dev->of_node;
	struct usb_extcon_info *info;
	struct usb_extcon_info *info;
	int ret;
	int ret;
	const char *name = NULL;


	if (!np && !ACPI_HANDLE(dev))
	if (!np && !ACPI_HANDLE(dev))
		return -EINVAL;
		return -EINVAL;
@@ -121,6 +130,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->trig_gpiod = devm_gpiod_get_optional(&pdev->dev, "trig",
						   GPIOD_OUT_LOW);


	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 +144,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->trig_gpiod))
		return PTR_ERR(info->trig_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");
@@ -145,6 +159,25 @@ static int usb_extcon_probe(struct platform_device *pdev)
		return ret;
		return ret;
	}
	}


	if (info->trig_gpiod) {
		ret = of_property_read_string_index(np, "gpio-names", 0, &name);
		if (ret) {
			dev_err(dev, "Could not get gpio name\n");
			return ret;
		}

		ret = gpiod_export(info->trig_gpiod, 0);
		if (ret) {
			dev_err(dev, "failed to export gpio\n");
			return ret;
		}

		ret = gpiod_export_link(dev, name, info->trig_gpiod);
		if (ret) {
		dev_err(dev, "failed to export gpio link\n");
		return ret;
		}
	}
	if (info->id_gpiod)
	if (info->id_gpiod)
		ret = gpiod_set_debounce(info->id_gpiod,
		ret = gpiod_set_debounce(info->id_gpiod,
					 USB_GPIO_DEBOUNCE_MS * 1000);
					 USB_GPIO_DEBOUNCE_MS * 1000);