Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1411747 > unrolled thread
| Started by | Lu Baolu <baolu.lu@linux.intel.com> |
|---|---|
| First post | 2016-06-02 03:40 +0200 |
| Last post | 2016-06-02 03:40 +0200 |
| Articles | 8 — 3 participants |
Back to article view | Back to linux.kernel
[PATCH v10 0/7] usb: add support for Intel dual role port mux Lu Baolu <baolu.lu@linux.intel.com> - 2016-06-02 03:40 +0200
[PATCH v10 1/7] regulator: fixed: add support for ACPI interface Lu Baolu <baolu.lu@linux.intel.com> - 2016-06-02 03:40 +0200
Re: [PATCH v10 1/7] regulator: fixed: add support for ACPI interface Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-06-08 06:50 +0200
Re: [PATCH v10 1/7] regulator: fixed: add support for ACPI interface Mark Brown <broonie@kernel.org> - 2016-06-08 15:50 +0200
Re: [PATCH v10 1/7] regulator: fixed: add support for ACPI interface Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-06-08 17:50 +0200
Re: [PATCH v10 1/7] regulator: fixed: add support for ACPI interface Lu Baolu <baolu.lu@linux.intel.com> - 2016-06-09 04:50 +0200
[PATCH v10 5/7] mfd: intel_vuport: Add Intel virtual USB port MFD Driver Lu Baolu <baolu.lu@linux.intel.com> - 2016-06-02 03:40 +0200
[PATCH v10 3/7] usb: mux: add driver for Intel gpio controlled port mux Lu Baolu <baolu.lu@linux.intel.com> - 2016-06-02 03:40 +0200
| From | Lu Baolu <baolu.lu@linux.intel.com> |
|---|---|
| Date | 2016-06-02 03:40 +0200 |
| Subject | [PATCH v10 0/7] usb: add support for Intel dual role port mux |
| Message-ID | <rFpM5-7QO-3@gated-at.bofh.it> |
Intel SOC chips are featured with USB dual role. The host role
is provided by Intel xHCI IP, and the gadget role is provided
by IP from designware. Tablet platform designs always share a
single port for both host and gadget controllers. There is a
mux to switch the port to the right controller according to the
cable type. OS needs to provide the callback to control the mux
when a plug-in event raises. The method to control the mux is
platform dependent. At least three types of implementation can
be found across current devices. 1) GPIO pins; 2) a unit which
can be controlled by memory mapped registers; 3) ACPI ASL code.
This patch series adds supports for Intel dual role port mux.
It includes:
(1) A generic framework for port mux devices. It exports interfaces
to register and unregister a port mux device. It also exports
an interface for the port mux consumers (e.x. PHY and charger
drivers) to switch the port role according to the events they
have detected.
(2) Drivers for GPIO controlled port mux which could be found
on Baytrail devices. A mfd driver is used to split the GPIOs
into a USB gpio extcon device, a fixed regulator for gpio
controlled USB VCC, and a USB mux device. Driver for USB
gpio extcon device is already in upstream Linux. This patch
series includes a driver for GPIO USB mux.
(3) Drivers for USB port mux controlled through memory mapped
registers and the logic to create the mux device. This type
of dual role port mux could be found in Cherry Trail and
Broxton devices.
All patches have been verified on Intel's BayTrail, CherryTrail,
and Broxton P platforms.
Lu Baolu (7):
regulator: fixed: add support for ACPI interface
usb: mux: add generic code for dual role port mux
usb: mux: add driver for Intel gpio controlled port mux
usb: mux: add driver for Intel drcfg controlled port mux
mfd: intel_vuport: Add Intel virtual USB port MFD Driver
usb: pci-quirks: add Intel USB drcfg mux device
MAINTAINERS: add maintainer entry for Intel USB dual role mux drivers
Change log:
v9->v10:
- rebase the patch series on top of 4.7-rc1.
v8->v9:
- Patch "mfd: intel_vuport: Add Intel virtual USB port MFD Driver"
has been ACK-ed by "Lee Jones <lee.jones@linaro.org>".
- remove extcon dependency out of the generic mux code to support
systems which have multiple port muxes.
- Add dev.release for mux device, otherwise, the mux driver module
couldn't be removed.
- Use the refreshed device property interface updated in Commit (f4d0526
device property: don't bother the drivers with struct property_set)
v7->v8:
- In patch "regulator: fixed: add support for ACPI interface", the
fixed regulator gpio name has been changed to "gpio".
- In patch "MAINTAINERS: add maintainer entry for Intel USB dual role
mux drivers", filenames have been updated.
v6->v7:
- Two patches have been picked up by extcon maintainer. Hence,
remove them since this version.
- extcon: usb-gpio: add device binding for platform device
- extcon: usb-gpio: add support for ACPI gpio interface
- Below patch has been removed from this series because it's unnecessary.
- regulator: fixed: add device binding for platform device
- In patch "regulator: fixed: add support for ACPI interface",
a static gpio name is used to get the regulator gpio.
- In patch "mfd: intel_vuport: Add Intel virtual USB port MFD Driver",
unnecessary "gpio-name" string property has been removed.
v5->v6:
Work internally with Felipe to improve the whole patch series.
Below changes have been made since last version.
- rework the common code to make it a generic interface for mux devices;
- split the vbus gpio handling to a fixed regulator device;
- removed unnecessary filtering for state change;
- removed unnecessary WARN statement;
- removed globals in mux drivers;
- removed unnecessary register polling and waiting in drcfg driver;
v4->v5:
- Change the extcon interfaces with the new ones suggested by
2a9de9c0f08d6 (extcon: Use the unique id for external connector
instead of string)
- remove patch "usb: pci-quirks: add Intel USB drcfg mux device"
from this serial due to that it's not driver staff. Will be
submitted seperately.
v3->v4:
- Check all patches with "checkpatch.pl --strict", and fix all
CHECKs;
- Change sysfs node from "intel_mux" to "port_mux";
- Refines below confusing functions:
intel_usb_mux_register() -> intel_usb_mux_bind_cable()
intel_usb_mux_unregister() -> intel_usb_mux_unbind_cable();
- Remove unnecessary struct intel_mux_dev.
v2->v3:
- uvport mfd driver got reviewed by Lee Jones, the following
changes were made accordingly.
- seperate uvport driver from the mux drivers in MAINTAINERS file
- refine the description in Kconfig
- refine the mfd_cell structure data
v1->v2:
- move mux driver from drivers/usb/misc to drivers/usb/mux;
- replace debugfs with sysfs for user level mux control;
- remove unnecessary register restore if mux registeration failed;
- Add "Acked-by: Chanwoo Choi <cw00.choi@samsung.com>" to extcon changes;
- Make the file names and exported function names more specific;
- Remove the usb_mux_get_dev() interface;
- Move "struct intel_usb_mux" from .h to .c file;
- Fix various kbuild robot warnings.
Documentation/ABI/testing/sysfs-bus-platform | 18 +++
MAINTAINERS | 10 ++
drivers/mfd/Kconfig | 8 ++
drivers/mfd/Makefile | 1 +
drivers/mfd/intel-vuport.c | 86 ++++++++++++
drivers/regulator/fixed.c | 46 ++++++
drivers/usb/Kconfig | 2 +
drivers/usb/Makefile | 1 +
drivers/usb/host/pci-quirks.c | 42 +++++-
drivers/usb/host/xhci-ext-caps.h | 2 +
drivers/usb/mux/Kconfig | 28 ++++
drivers/usb/mux/Makefile | 6 +
drivers/usb/mux/portmux-core.c | 202 +++++++++++++++++++++++++++
drivers/usb/mux/portmux-intel-drcfg.c | 162 +++++++++++++++++++++
drivers/usb/mux/portmux-intel-gpio.c | 183 ++++++++++++++++++++++++
include/linux/usb/portmux.h | 90 ++++++++++++
16 files changed, 886 insertions(+), 1 deletion(-)
create mode 100644 drivers/mfd/intel-vuport.c
create mode 100644 drivers/usb/mux/Kconfig
create mode 100644 drivers/usb/mux/Makefile
create mode 100644 drivers/usb/mux/portmux-core.c
create mode 100644 drivers/usb/mux/portmux-intel-drcfg.c
create mode 100644 drivers/usb/mux/portmux-intel-gpio.c
create mode 100644 include/linux/usb/portmux.h
--
2.1.4
[toc] | [next] | [standalone]
| From | Lu Baolu <baolu.lu@linux.intel.com> |
|---|---|
| Date | 2016-06-02 03:40 +0200 |
| Subject | [PATCH v10 1/7] regulator: fixed: add support for ACPI interface |
| Message-ID | <rFpM5-7QO-21@gated-at.bofh.it> |
| In reply to | #1411747 |
Add support to retrieve fixed voltage configure information through
ACPI interface. This is needed for Intel Bay Trail devices, where a
GPIO is used to control the USB vbus.
Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
---
drivers/regulator/fixed.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 46 insertions(+)
diff --git a/drivers/regulator/fixed.c b/drivers/regulator/fixed.c
index ff62d69..207ab40 100644
--- a/drivers/regulator/fixed.c
+++ b/drivers/regulator/fixed.c
@@ -30,6 +30,9 @@
#include <linux/of_gpio.h>
#include <linux/regulator/of_regulator.h>
#include <linux/regulator/machine.h>
+#include <linux/acpi.h>
+#include <linux/property.h>
+#include <linux/gpio/consumer.h>
struct fixed_voltage_data {
struct regulator_desc desc;
@@ -104,6 +107,44 @@ of_get_fixed_voltage_config(struct device *dev,
return config;
}
+/**
+ * acpi_get_fixed_voltage_config - extract fixed_voltage_config structure info
+ * @dev: device requesting for fixed_voltage_config
+ * @desc: regulator description
+ *
+ * Populates fixed_voltage_config structure by extracting data through ACPI
+ * interface, returns a pointer to the populated structure of NULL if memory
+ * alloc fails.
+ */
+static struct fixed_voltage_config *
+acpi_get_fixed_voltage_config(struct device *dev,
+ const struct regulator_desc *desc)
+{
+ struct fixed_voltage_config *config;
+ const char *supply_name;
+ struct gpio_desc *gpiod;
+ int ret;
+
+ config = devm_kzalloc(dev, sizeof(*config), GFP_KERNEL);
+ if (!config)
+ return ERR_PTR(-ENOMEM);
+
+ ret = device_property_read_string(dev, "supply-name", &supply_name);
+ if (!ret)
+ config->supply_name = supply_name;
+
+ gpiod = gpiod_get(dev, "gpio", GPIOD_ASIS);
+ if (IS_ERR(gpiod))
+ return ERR_PTR(-ENODEV);
+
+ config->gpio = desc_to_gpio(gpiod);
+ config->enable_high = device_property_read_bool(dev,
+ "enable-active-high");
+ gpiod_put(gpiod);
+
+ return config;
+}
+
static struct regulator_ops fixed_voltage_ops = {
};
@@ -124,6 +165,11 @@ static int reg_fixed_voltage_probe(struct platform_device *pdev)
&drvdata->desc);
if (IS_ERR(config))
return PTR_ERR(config);
+ } else if (ACPI_HANDLE(&pdev->dev)) {
+ config = acpi_get_fixed_voltage_config(&pdev->dev,
+ &drvdata->desc);
+ if (IS_ERR(config))
+ return PTR_ERR(config);
} else {
config = dev_get_platdata(&pdev->dev);
}
--
2.1.4
[toc] | [prev] | [next] | [standalone]
| From | Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
|---|---|
| Date | 2016-06-08 06:50 +0200 |
| Subject | Re: [PATCH v10 1/7] regulator: fixed: add support for ACPI interface |
| Message-ID | <rHDBg-3MJ-3@gated-at.bofh.it> |
| In reply to | #1411748 |
On Thu, Jun 02, 2016 at 09:37:23AM +0800, Lu Baolu wrote: > Add support to retrieve fixed voltage configure information through > ACPI interface. This is needed for Intel Bay Trail devices, where a > GPIO is used to control the USB vbus. > > Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com> > --- > drivers/regulator/fixed.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 46 insertions(+) Can't do anything with this until I get an ack from the "owners" of this file. And what happened to the acks from other Intel developers for this whole patch series, I don't see that here :( greg k-h
[toc] | [prev] | [next] | [standalone]
| From | Mark Brown <broonie@kernel.org> |
|---|---|
| Date | 2016-06-08 15:50 +0200 |
| Subject | Re: [PATCH v10 1/7] regulator: fixed: add support for ACPI interface |
| Message-ID | <rHM1Q-Pq-25@gated-at.bofh.it> |
| In reply to | #1416863 |
[Multipart message — attachments visible in raw view] — view raw
On Tue, Jun 07, 2016 at 09:42:48PM -0700, Greg Kroah-Hartman wrote: > On Thu, Jun 02, 2016 at 09:37:23AM +0800, Lu Baolu wrote: > > Add support to retrieve fixed voltage configure information through > > ACPI interface. This is needed for Intel Bay Trail devices, where a > > GPIO is used to control the USB vbus. > Can't do anything with this until I get an ack from the "owners" of this > file. Please allow a reasonable time for review, it's been under a week since this was posted. I would *not* expect this to be applied to another tree, please don't do that.
[toc] | [prev] | [next] | [standalone]
| From | Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
|---|---|
| Date | 2016-06-08 17:50 +0200 |
| Subject | Re: [PATCH v10 1/7] regulator: fixed: add support for ACPI interface |
| Message-ID | <rHNTY-21z-9@gated-at.bofh.it> |
| In reply to | #1417443 |
On Wed, Jun 08, 2016 at 02:43:27PM +0100, Mark Brown wrote: > On Tue, Jun 07, 2016 at 09:42:48PM -0700, Greg Kroah-Hartman wrote: > > On Thu, Jun 02, 2016 at 09:37:23AM +0800, Lu Baolu wrote: > > > > Add support to retrieve fixed voltage configure information through > > > ACPI interface. This is needed for Intel Bay Trail devices, where a > > > GPIO is used to control the USB vbus. > > > Can't do anything with this until I get an ack from the "owners" of this > > file. > > Please allow a reasonable time for review, it's been under a week since > this was posted. I would *not* expect this to be applied to another > tree, please don't do that. I wouldn't consider it, my response was to the developer of the patch, sorry for the confusion, greg k-h
[toc] | [prev] | [next] | [standalone]
| From | Lu Baolu <baolu.lu@linux.intel.com> |
|---|---|
| Date | 2016-06-09 04:50 +0200 |
| Subject | Re: [PATCH v10 1/7] regulator: fixed: add support for ACPI interface |
| Message-ID | <rHYcF-bc-1@gated-at.bofh.it> |
| In reply to | #1416863 |
Hi Felipe and Heikki, On 06/08/2016 12:42 PM, Greg Kroah-Hartman wrote: > On Thu, Jun 02, 2016 at 09:37:23AM +0800, Lu Baolu wrote: >> Add support to retrieve fixed voltage configure information through >> ACPI interface. This is needed for Intel Bay Trail devices, where a >> GPIO is used to control the USB vbus. >> >> Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com> >> --- >> drivers/regulator/fixed.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ >> 1 file changed, 46 insertions(+) > Can't do anything with this until I get an ack from the "owners" of this > file. > > And what happened to the acks from other Intel developers for this whole > patch series, I don't see that here :( > You have reviewed the whole patches in this series. Are you willing to ack them? Best regards, Lu Baolu
[toc] | [prev] | [next] | [standalone]
| From | Lu Baolu <baolu.lu@linux.intel.com> |
|---|---|
| Date | 2016-06-02 03:40 +0200 |
| Subject | [PATCH v10 5/7] mfd: intel_vuport: Add Intel virtual USB port MFD Driver |
| Message-ID | <rFpM5-7QO-19@gated-at.bofh.it> |
| In reply to | #1411747 |
Some Intel platforms have an USB port mux controlled by GPIOs.
There's a single ACPI platform device that provides 1) USB ID
extcon device; 2) USB vbus regulator device; and 3) USB port
switch device. This MFD driver will split these 3 devices for
their respective drivers.
[baolu: removed .owner per platform_no_drv_owner.cocci]
Suggested-by: David Cohen <david.a.cohen@linux.intel.com>
Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
Reviewed-by: Felipe Balbi <balbi@kernel.org>
Acked-by: Lee Jones <lee.jones@linaro.org>
---
drivers/mfd/Kconfig | 8 +++++
drivers/mfd/Makefile | 1 +
drivers/mfd/intel-vuport.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 95 insertions(+)
create mode 100644 drivers/mfd/intel-vuport.c
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 1bcf601..94affb3 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -1603,5 +1603,13 @@ config MFD_VEXPRESS_SYSREG
System Registers are the platform configuration block
on the ARM Ltd. Versatile Express board.
+config MFD_INTEL_VUPORT
+ tristate "Intel virtual USB port controller"
+ select MFD_CORE
+ depends on X86 && ACPI
+ help
+ Say Y here to enable support for Intel's dual role port mux
+ controlled by GPIOs.
+
endmenu
endif
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 42a66e1..b86d4f9 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -205,3 +205,4 @@ intel-soc-pmic-objs := intel_soc_pmic_core.o intel_soc_pmic_crc.o
intel-soc-pmic-$(CONFIG_INTEL_PMC_IPC) += intel_soc_pmic_bxtwc.o
obj-$(CONFIG_INTEL_SOC_PMIC) += intel-soc-pmic.o
obj-$(CONFIG_MFD_MT6397) += mt6397-core.o
+obj-$(CONFIG_MFD_INTEL_VUPORT) += intel-vuport.o
diff --git a/drivers/mfd/intel-vuport.c b/drivers/mfd/intel-vuport.c
new file mode 100644
index 0000000..eb27a8f
--- /dev/null
+++ b/drivers/mfd/intel-vuport.c
@@ -0,0 +1,86 @@
+/*
+ * MFD driver for Intel virtual USB port
+ *
+ * Copyright(c) 2016 Intel Corporation.
+ * Author: Lu Baolu <baolu.lu@linux.intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/acpi.h>
+#include <linux/module.h>
+#include <linux/gpio.h>
+#include <linux/mfd/core.h>
+#include <linux/property.h>
+#include <linux/platform_device.h>
+
+/* ACPI GPIO Mappings */
+static const struct acpi_gpio_params id_gpio = { 0, 0, false };
+static const struct acpi_gpio_params vbus_gpio = { 1, 0, false };
+static const struct acpi_gpio_params mux_gpio = { 2, 0, false };
+static const struct acpi_gpio_mapping acpi_usb_gpios[] = {
+ { "id-gpios", &id_gpio, 1 },
+ { "gpio-gpios", &vbus_gpio, 1 },
+ { "usb_mux-gpios", &mux_gpio, 1 },
+ { },
+};
+
+static struct property_entry reg_properties[] = {
+ PROPERTY_ENTRY_STRING("supply-name", "regulator-usb-gpio"),
+ { },
+};
+
+static const struct mfd_cell intel_vuport_mfd_cells[] = {
+ { .name = "extcon-usb-gpio", },
+ {
+ .name = "reg-fixed-voltage",
+ .properties = reg_properties,
+ },
+ { .name = "intel-mux-gpio", },
+};
+
+static int vuport_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ int ret;
+
+ ret = acpi_dev_add_driver_gpios(ACPI_COMPANION(dev), acpi_usb_gpios);
+ if (ret)
+ return ret;
+
+ return mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE,
+ intel_vuport_mfd_cells,
+ ARRAY_SIZE(intel_vuport_mfd_cells), NULL, 0,
+ NULL);
+}
+
+static int vuport_remove(struct platform_device *pdev)
+{
+ mfd_remove_devices(&pdev->dev);
+ acpi_dev_remove_driver_gpios(ACPI_COMPANION(&pdev->dev));
+
+ return 0;
+}
+
+static struct acpi_device_id vuport_acpi_match[] = {
+ { "INT3496" },
+ { }
+};
+MODULE_DEVICE_TABLE(acpi, vuport_acpi_match);
+
+static struct platform_driver vuport_driver = {
+ .driver = {
+ .name = "intel-vuport",
+ .acpi_match_table = ACPI_PTR(vuport_acpi_match),
+ },
+ .probe = vuport_probe,
+ .remove = vuport_remove,
+};
+
+module_platform_driver(vuport_driver);
+
+MODULE_AUTHOR("Lu Baolu <baolu.lu@linux.intel.com>");
+MODULE_DESCRIPTION("Intel virtual USB port");
+MODULE_LICENSE("GPL v2");
--
2.1.4
[toc] | [prev] | [next] | [standalone]
| From | Lu Baolu <baolu.lu@linux.intel.com> |
|---|---|
| Date | 2016-06-02 03:40 +0200 |
| Subject | [PATCH v10 3/7] usb: mux: add driver for Intel gpio controlled port mux |
| Message-ID | <rFpM5-7QO-17@gated-at.bofh.it> |
| In reply to | #1411747 |
In some Intel platforms, a single usb port is shared between USB host
and device controller. The shared port is under control of GPIO pins.
This patch adds the support for USB GPIO controlled port mux.
[baolu: removed .owner per platform_no_drv_owner.cocci]
[baolu: extcon usage reviewed by Chanwoo Choi]
Signed-off-by: David Cohen <david.a.cohen@linux.intel.com>
Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Reviewed-by: Felipe Balbi <balbi@kernel.org>
Reviewed-by: Chanwoo Choi <cw00.choi@samsung.com>
---
drivers/usb/mux/Kconfig | 13 +++
drivers/usb/mux/Makefile | 1 +
drivers/usb/mux/portmux-intel-gpio.c | 183 +++++++++++++++++++++++++++++++++++
3 files changed, 197 insertions(+)
create mode 100644 drivers/usb/mux/portmux-intel-gpio.c
diff --git a/drivers/usb/mux/Kconfig b/drivers/usb/mux/Kconfig
index ba778f2..41b0f72 100644
--- a/drivers/usb/mux/Kconfig
+++ b/drivers/usb/mux/Kconfig
@@ -6,3 +6,16 @@ menuconfig USB_PORTMUX
bool "USB dual role port MUX support"
help
Generic USB dual role port mux support.
+
+if USB_PORTMUX
+
+config INTEL_MUX_GPIO
+tristate "Intel dual role port mux controlled by GPIOs"
+ depends on GPIOLIB
+ depends on REGULATOR
+ depends on X86 && ACPI
+ help
+ Say Y here to enable support for Intel dual role port mux
+ controlled by GPIOs.
+
+endif
diff --git a/drivers/usb/mux/Makefile b/drivers/usb/mux/Makefile
index f85df92..4eb5582 100644
--- a/drivers/usb/mux/Makefile
+++ b/drivers/usb/mux/Makefile
@@ -2,3 +2,4 @@
# Makefile for USB port mux drivers
#
obj-$(CONFIG_USB_PORTMUX) += portmux-core.o
+obj-$(CONFIG_INTEL_MUX_GPIO) += portmux-intel-gpio.o
diff --git a/drivers/usb/mux/portmux-intel-gpio.c b/drivers/usb/mux/portmux-intel-gpio.c
new file mode 100644
index 0000000..cada490
--- /dev/null
+++ b/drivers/usb/mux/portmux-intel-gpio.c
@@ -0,0 +1,183 @@
+/*
+ * USB Dual Role Port Mux driver controlled by gpios
+ *
+ * Copyright (c) 2016, Intel Corporation.
+ * Author: David Cohen <david.a.cohen@linux.intel.com>
+ * Author: Lu Baolu <baolu.lu@linux.intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/acpi.h>
+#include <linux/module.h>
+#include <linux/extcon.h>
+#include <linux/gpio/consumer.h>
+#include <linux/platform_device.h>
+#include <linux/usb/portmux.h>
+#include <linux/regulator/consumer.h>
+
+struct vuport {
+ struct extcon_dev *edev;
+ struct notifier_block nb;
+ struct portmux_desc desc;
+ struct portmux_dev *pdev;
+ struct regulator *regulator;
+ struct gpio_desc *gpio_usb_mux;
+};
+
+/*
+ * id == 0, HOST connected, USB port should be set to peripheral
+ * id == 1, HOST disconnected, USB port should be set to host
+ *
+ * Peripheral: set USB mux to peripheral and disable VBUS
+ * Host: set USB mux to host and enable VBUS
+ */
+static inline int vuport_set_port(struct device *dev, int id)
+{
+ struct vuport *vup;
+
+ dev_dbg(dev, "USB PORT ID: %s\n", id ? "HOST" : "PERIPHERAL");
+
+ vup = dev_get_drvdata(dev);
+
+ gpiod_set_value_cansleep(vup->gpio_usb_mux, !id);
+
+ if (!id ^ regulator_is_enabled(vup->regulator))
+ return id ? regulator_disable(vup->regulator) :
+ regulator_enable(vup->regulator);
+
+ return 0;
+}
+
+static int vuport_cable_set(struct device *dev)
+{
+ return vuport_set_port(dev, 1);
+}
+
+static int vuport_cable_unset(struct device *dev)
+{
+ return vuport_set_port(dev, 0);
+}
+
+static const struct portmux_ops vuport_ops = {
+ .set_host_cb = vuport_cable_set,
+ .set_device_cb = vuport_cable_unset,
+};
+
+static int vuport_notifier(struct notifier_block *nb,
+ unsigned long event, void *ptr)
+{
+ struct vuport *vup;
+ int state;
+
+ vup = container_of(nb, struct vuport, nb);
+ state = extcon_get_cable_state_(vup->edev, EXTCON_USB_HOST);
+ if (state < 0)
+ return state;
+
+ return portmux_switch(vup->pdev, state ? PORTMUX_HOST : PORTMUX_DEVICE);
+}
+
+static int vuport_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct vuport *vup;
+ int ret;
+
+ vup = devm_kzalloc(dev, sizeof(*vup), GFP_KERNEL);
+ if (!vup)
+ return -ENOMEM;
+
+ vup->regulator = devm_regulator_get_exclusive(dev,
+ "regulator-usb-gpio");
+ if (IS_ERR_OR_NULL(vup->regulator))
+ return -EPROBE_DEFER;
+
+ vup->edev = extcon_get_extcon_dev("extcon-usb-gpio");
+ if (IS_ERR_OR_NULL(vup->edev))
+ return -EPROBE_DEFER;
+
+ vup->gpio_usb_mux = devm_gpiod_get_optional(dev,
+ "usb_mux", GPIOD_ASIS);
+ if (IS_ERR(vup->gpio_usb_mux))
+ return PTR_ERR(vup->gpio_usb_mux);
+
+ vup->desc.dev = dev;
+ vup->desc.name = "intel-mux-gpio";
+ vup->desc.ops = &vuport_ops;
+ dev_set_drvdata(dev, vup);
+ vup->pdev = portmux_register(&vup->desc);
+ if (IS_ERR(vup->pdev))
+ return PTR_ERR(vup->pdev);
+
+ vup->nb.notifier_call = vuport_notifier;
+ ret = extcon_register_notifier(vup->edev, EXTCON_USB_HOST,
+ &vup->nb);
+ if (ret < 0) {
+ portmux_unregister(vup->pdev);
+ return ret;
+ }
+
+ vuport_notifier(&vup->nb, 0, NULL);
+
+ return 0;
+}
+
+static int vuport_remove(struct platform_device *pdev)
+{
+ struct vuport *vup;
+
+ vup = platform_get_drvdata(pdev);
+ extcon_unregister_notifier(vup->edev, EXTCON_USB_HOST, &vup->nb);
+ portmux_unregister(vup->pdev);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+/*
+ * In case a micro A cable was plugged in while device was sleeping,
+ * we missed the interrupt. We need to poll usb id gpio when waking the
+ * driver to detect the missed event.
+ * We use 'complete' callback to give time to all extcon listeners to
+ * resume before we send new events.
+ */
+static void vuport_complete(struct device *dev)
+{
+ struct vuport *vup;
+
+ vup = dev_get_drvdata(dev);
+ vuport_notifier(&vup->nb, 0, NULL);
+}
+
+static const struct dev_pm_ops vuport_pm_ops = {
+ .complete = vuport_complete,
+};
+#endif
+
+static const struct platform_device_id vuport_platform_ids[] = {
+ { .name = "intel-mux-gpio", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(platform, vuport_platform_ids);
+
+static struct platform_driver vuport_driver = {
+ .driver = {
+ .name = "intel-mux-gpio",
+#ifdef CONFIG_PM_SLEEP
+ .pm = &vuport_pm_ops,
+#endif
+ },
+ .probe = vuport_probe,
+ .remove = vuport_remove,
+ .id_table = vuport_platform_ids,
+};
+
+module_platform_driver(vuport_driver);
+
+MODULE_AUTHOR("David Cohen <david.a.cohen@linux.intel.com>");
+MODULE_AUTHOR("Lu Baolu <baolu.lu@linux.intel.com>");
+MODULE_DESCRIPTION("Intel USB gpio mux driver");
+MODULE_LICENSE("GPL v2");
--
2.1.4
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web