diff options
author | Loic Poulain <loic.poulain@linaro.org> | 2018-09-04 17:18:55 +0200 |
---|---|---|
committer | Peter Chen <peter.chen@nxp.com> | 2018-09-20 11:04:21 +0200 |
commit | 16caf1fa37db4722d8d8c7bc26177279949d75a6 (patch) | |
tree | a787b234e6b11249bd2ca209cf3a5391cf6f72f9 /drivers/usb | |
parent | usb: chipidea: imx: make MODULE_LICENCE and SPDX-identifier match (diff) | |
download | linux-16caf1fa37db4722d8d8c7bc26177279949d75a6.tar.xz linux-16caf1fa37db4722d8d8c7bc26177279949d75a6.zip |
usb: chipidea: Add dynamic pinctrl selection
Some hardware implementations require to configure pins differently
according to the USB role (host/device), this can be an update of the
pins routing or a simple GPIO value change.
This patch introduces new optional "host" and "device" pinctrls.
If these pinctrls are defined by the device, they are respectively
selected on host/device role start.
If a default pinctrl exist, it is restored on host/device role stop.
Signed-off-by: Loic Poulain <loic.poulain@linaro.org>
Signed-off-by: Peter Chen <peter.chen@nxp.com>
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/chipidea/core.c | 19 | ||||
-rw-r--r-- | drivers/usb/chipidea/host.c | 9 | ||||
-rw-r--r-- | drivers/usb/chipidea/udc.c | 9 |
3 files changed, 37 insertions, 0 deletions
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 85fc6db48e44..7bfcbb23c2a4 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -53,6 +53,7 @@ #include <linux/kernel.h> #include <linux/slab.h> #include <linux/pm_runtime.h> +#include <linux/pinctrl/consumer.h> #include <linux/usb/ch9.h> #include <linux/usb/gadget.h> #include <linux/usb/otg.h> @@ -723,6 +724,24 @@ static int ci_get_platdata(struct device *dev, else cable->connected = false; } + + platdata->pctl = devm_pinctrl_get(dev); + if (!IS_ERR(platdata->pctl)) { + struct pinctrl_state *p; + + p = pinctrl_lookup_state(platdata->pctl, "default"); + if (!IS_ERR(p)) + platdata->pins_default = p; + + p = pinctrl_lookup_state(platdata->pctl, "host"); + if (!IS_ERR(p)) + platdata->pins_host = p; + + p = pinctrl_lookup_state(platdata->pctl, "device"); + if (!IS_ERR(p)) + platdata->pins_device = p; + } + return 0; } diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c index 4638d9b066be..d858a82c4f44 100644 --- a/drivers/usb/chipidea/host.c +++ b/drivers/usb/chipidea/host.c @@ -13,6 +13,7 @@ #include <linux/usb/hcd.h> #include <linux/usb/chipidea.h> #include <linux/regulator/consumer.h> +#include <linux/pinctrl/consumer.h> #include "../host/ehci.h" @@ -153,6 +154,10 @@ static int host_start(struct ci_hdrc *ci) } } + if (ci->platdata->pins_host) + pinctrl_select_state(ci->platdata->pctl, + ci->platdata->pins_host); + ret = usb_add_hcd(hcd, 0, 0); if (ret) { goto disable_reg; @@ -197,6 +202,10 @@ static void host_stop(struct ci_hdrc *ci) } ci->hcd = NULL; ci->otg.host = NULL; + + if (ci->platdata->pins_host && ci->platdata->pins_default) + pinctrl_select_state(ci->platdata->pctl, + ci->platdata->pins_default); } diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index 9852ec5e6e01..829e947cabf5 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -15,6 +15,7 @@ #include <linux/kernel.h> #include <linux/slab.h> #include <linux/pm_runtime.h> +#include <linux/pinctrl/consumer.h> #include <linux/usb/ch9.h> #include <linux/usb/gadget.h> #include <linux/usb/otg-fsm.h> @@ -1965,6 +1966,10 @@ void ci_hdrc_gadget_destroy(struct ci_hdrc *ci) static int udc_id_switch_for_device(struct ci_hdrc *ci) { + if (ci->platdata->pins_device) + pinctrl_select_state(ci->platdata->pctl, + ci->platdata->pins_device); + if (ci->is_otg) /* Clear and enable BSV irq */ hw_write_otgsc(ci, OTGSC_BSVIS | OTGSC_BSVIE, @@ -1983,6 +1988,10 @@ static void udc_id_switch_for_host(struct ci_hdrc *ci) hw_write_otgsc(ci, OTGSC_BSVIE | OTGSC_BSVIS, OTGSC_BSVIS); ci->vbus_active = 0; + + if (ci->platdata->pins_device && ci->platdata->pins_default) + pinctrl_select_state(ci->platdata->pctl, + ci->platdata->pins_default); } /** |