summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLoic Poulain <loic.poulain@linaro.org>2018-09-04 11:18:55 -0400
committerPeter Chen <peter.chen@nxp.com>2018-09-20 05:04:21 -0400
commit16caf1fa37db4722d8d8c7bc26177279949d75a6 (patch)
treea787b234e6b11249bd2ca209cf3a5391cf6f72f9
parent1f06072cd22fbbd2e961b49c8e4fa9f7a0c120d6 (diff)
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>
-rw-r--r--drivers/usb/chipidea/core.c19
-rw-r--r--drivers/usb/chipidea/host.c9
-rw-r--r--drivers/usb/chipidea/udc.c9
-rw-r--r--include/linux/usb/chipidea.h6
4 files changed, 43 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 @@
53#include <linux/kernel.h> 53#include <linux/kernel.h>
54#include <linux/slab.h> 54#include <linux/slab.h>
55#include <linux/pm_runtime.h> 55#include <linux/pm_runtime.h>
56#include <linux/pinctrl/consumer.h>
56#include <linux/usb/ch9.h> 57#include <linux/usb/ch9.h>
57#include <linux/usb/gadget.h> 58#include <linux/usb/gadget.h>
58#include <linux/usb/otg.h> 59#include <linux/usb/otg.h>
@@ -723,6 +724,24 @@ static int ci_get_platdata(struct device *dev,
723 else 724 else
724 cable->connected = false; 725 cable->connected = false;
725 } 726 }
727
728 platdata->pctl = devm_pinctrl_get(dev);
729 if (!IS_ERR(platdata->pctl)) {
730 struct pinctrl_state *p;
731
732 p = pinctrl_lookup_state(platdata->pctl, "default");
733 if (!IS_ERR(p))
734 platdata->pins_default = p;
735
736 p = pinctrl_lookup_state(platdata->pctl, "host");
737 if (!IS_ERR(p))
738 platdata->pins_host = p;
739
740 p = pinctrl_lookup_state(platdata->pctl, "device");
741 if (!IS_ERR(p))
742 platdata->pins_device = p;
743 }
744
726 return 0; 745 return 0;
727} 746}
728 747
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 @@
13#include <linux/usb/hcd.h> 13#include <linux/usb/hcd.h>
14#include <linux/usb/chipidea.h> 14#include <linux/usb/chipidea.h>
15#include <linux/regulator/consumer.h> 15#include <linux/regulator/consumer.h>
16#include <linux/pinctrl/consumer.h>
16 17
17#include "../host/ehci.h" 18#include "../host/ehci.h"
18 19
@@ -153,6 +154,10 @@ static int host_start(struct ci_hdrc *ci)
153 } 154 }
154 } 155 }
155 156
157 if (ci->platdata->pins_host)
158 pinctrl_select_state(ci->platdata->pctl,
159 ci->platdata->pins_host);
160
156 ret = usb_add_hcd(hcd, 0, 0); 161 ret = usb_add_hcd(hcd, 0, 0);
157 if (ret) { 162 if (ret) {
158 goto disable_reg; 163 goto disable_reg;
@@ -197,6 +202,10 @@ static void host_stop(struct ci_hdrc *ci)
197 } 202 }
198 ci->hcd = NULL; 203 ci->hcd = NULL;
199 ci->otg.host = NULL; 204 ci->otg.host = NULL;
205
206 if (ci->platdata->pins_host && ci->platdata->pins_default)
207 pinctrl_select_state(ci->platdata->pctl,
208 ci->platdata->pins_default);
200} 209}
201 210
202 211
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 @@
15#include <linux/kernel.h> 15#include <linux/kernel.h>
16#include <linux/slab.h> 16#include <linux/slab.h>
17#include <linux/pm_runtime.h> 17#include <linux/pm_runtime.h>
18#include <linux/pinctrl/consumer.h>
18#include <linux/usb/ch9.h> 19#include <linux/usb/ch9.h>
19#include <linux/usb/gadget.h> 20#include <linux/usb/gadget.h>
20#include <linux/usb/otg-fsm.h> 21#include <linux/usb/otg-fsm.h>
@@ -1965,6 +1966,10 @@ void ci_hdrc_gadget_destroy(struct ci_hdrc *ci)
1965 1966
1966static int udc_id_switch_for_device(struct ci_hdrc *ci) 1967static int udc_id_switch_for_device(struct ci_hdrc *ci)
1967{ 1968{
1969 if (ci->platdata->pins_device)
1970 pinctrl_select_state(ci->platdata->pctl,
1971 ci->platdata->pins_device);
1972
1968 if (ci->is_otg) 1973 if (ci->is_otg)
1969 /* Clear and enable BSV irq */ 1974 /* Clear and enable BSV irq */
1970 hw_write_otgsc(ci, OTGSC_BSVIS | OTGSC_BSVIE, 1975 hw_write_otgsc(ci, OTGSC_BSVIS | OTGSC_BSVIE,
@@ -1983,6 +1988,10 @@ static void udc_id_switch_for_host(struct ci_hdrc *ci)
1983 hw_write_otgsc(ci, OTGSC_BSVIE | OTGSC_BSVIS, OTGSC_BSVIS); 1988 hw_write_otgsc(ci, OTGSC_BSVIE | OTGSC_BSVIS, OTGSC_BSVIS);
1984 1989
1985 ci->vbus_active = 0; 1990 ci->vbus_active = 0;
1991
1992 if (ci->platdata->pins_device && ci->platdata->pins_default)
1993 pinctrl_select_state(ci->platdata->pctl,
1994 ci->platdata->pins_default);
1986} 1995}
1987 1996
1988/** 1997/**
diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h
index 07f99362bc90..63758c399e4e 100644
--- a/include/linux/usb/chipidea.h
+++ b/include/linux/usb/chipidea.h
@@ -77,6 +77,12 @@ struct ci_hdrc_platform_data {
77 struct ci_hdrc_cable vbus_extcon; 77 struct ci_hdrc_cable vbus_extcon;
78 struct ci_hdrc_cable id_extcon; 78 struct ci_hdrc_cable id_extcon;
79 u32 phy_clkgate_delay_us; 79 u32 phy_clkgate_delay_us;
80
81 /* pins */
82 struct pinctrl *pctl;
83 struct pinctrl_state *pins_default;
84 struct pinctrl_state *pins_host;
85 struct pinctrl_state *pins_device;
80}; 86};
81 87
82/* Default offset of capability registers */ 88/* Default offset of capability registers */