aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIgor Grinberg <grinberg@compulab.co.il>2010-07-15 09:00:16 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-08-10 17:35:40 -0400
commit13dd0c9767349b280cf131c34461f85e5effc42a (patch)
treefd4571015c4ed0097fb60e9d22132ab0aac6240f
parent51a91a5424cb94f40eb0c9d0b71d8df4e423742a (diff)
USB: otg/ulpi: extend the generic ulpi driver.
1) Introduce ulpi specific flags for control of the ulpi phy 2) Extend the generic ulpi driver with support for Function and Interface control of upli phy 3) Update the platforms using the generic ulpi driver with new ulpi flags 4) Remove the otg control flags not in use Signed-off-by: Igor Grinberg <grinberg@compulab.co.il> Signed-off-by: Mike Rapoport <mike@compulab.co.il> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--arch/arm/mach-mx3/mach-armadillo5x0.c4
-rw-r--r--arch/arm/mach-mx3/mach-mx31lilly.c4
-rw-r--r--arch/arm/mach-mx3/mach-mx31lite.c2
-rw-r--r--arch/arm/mach-mx3/mach-mx31moboard.c2
-rw-r--r--arch/arm/mach-mx3/mach-pcm037.c4
-rw-r--r--arch/arm/mach-mx3/mach-pcm043.c2
-rw-r--r--arch/arm/mach-mx3/mx31moboard-smartbot.c2
-rw-r--r--drivers/usb/otg/ulpi.c127
-rw-r--r--include/linux/usb/otg.h7
-rw-r--r--include/linux/usb/ulpi.h39
10 files changed, 166 insertions, 27 deletions
diff --git a/arch/arm/mach-mx3/mach-armadillo5x0.c b/arch/arm/mach-mx3/mach-armadillo5x0.c
index 96aadcadb4ff..68879c996a55 100644
--- a/arch/arm/mach-mx3/mach-armadillo5x0.c
+++ b/arch/arm/mach-mx3/mach-armadillo5x0.c
@@ -551,9 +551,9 @@ static void __init armadillo5x0_init(void)
551 /* USB */ 551 /* USB */
552#if defined(CONFIG_USB_ULPI) 552#if defined(CONFIG_USB_ULPI)
553 usbotg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, 553 usbotg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
554 USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT); 554 ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
555 usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, 555 usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
556 USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT); 556 ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
557 557
558 mxc_register_device(&mxc_otg_host, &usbotg_pdata); 558 mxc_register_device(&mxc_otg_host, &usbotg_pdata);
559 mxc_register_device(&mxc_usbh2, &usbh2_pdata); 559 mxc_register_device(&mxc_usbh2, &usbh2_pdata);
diff --git a/arch/arm/mach-mx3/mach-mx31lilly.c b/arch/arm/mach-mx3/mach-mx31lilly.c
index 8f66f65e80e2..7c37daabb757 100644
--- a/arch/arm/mach-mx3/mach-mx31lilly.c
+++ b/arch/arm/mach-mx3/mach-mx31lilly.c
@@ -245,9 +245,9 @@ static struct mxc_usbh_platform_data usbh2_pdata = {
245static void lilly1131_usb_init(void) 245static void lilly1131_usb_init(void)
246{ 246{
247 usbotg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, 247 usbotg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
248 USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT); 248 ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
249 usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, 249 usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
250 USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT); 250 ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
251 251
252 mxc_register_device(&mxc_usbh1, &usbh1_pdata); 252 mxc_register_device(&mxc_usbh1, &usbh1_pdata);
253 mxc_register_device(&mxc_usbh2, &usbh2_pdata); 253 mxc_register_device(&mxc_usbh2, &usbh2_pdata);
diff --git a/arch/arm/mach-mx3/mach-mx31lite.c b/arch/arm/mach-mx3/mach-mx31lite.c
index da236c497d2a..f66a9576d8c2 100644
--- a/arch/arm/mach-mx3/mach-mx31lite.c
+++ b/arch/arm/mach-mx3/mach-mx31lite.c
@@ -256,7 +256,7 @@ static void __init mxc_board_init(void)
256#if defined(CONFIG_USB_ULPI) 256#if defined(CONFIG_USB_ULPI)
257 /* USB */ 257 /* USB */
258 usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, 258 usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
259 USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT); 259 ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
260 260
261 mxc_register_device(&mxc_usbh2, &usbh2_pdata); 261 mxc_register_device(&mxc_usbh2, &usbh2_pdata);
262#endif 262#endif
diff --git a/arch/arm/mach-mx3/mach-mx31moboard.c b/arch/arm/mach-mx3/mach-mx31moboard.c
index 67776bc61c33..7a075e8bf2d4 100644
--- a/arch/arm/mach-mx3/mach-mx31moboard.c
+++ b/arch/arm/mach-mx3/mach-mx31moboard.c
@@ -412,7 +412,7 @@ static struct mxc_usbh_platform_data usbh2_pdata = {
412static int __init moboard_usbh2_init(void) 412static int __init moboard_usbh2_init(void)
413{ 413{
414 usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, 414 usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
415 USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT); 415 ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
416 416
417 return mxc_register_device(&mxc_usbh2, &usbh2_pdata); 417 return mxc_register_device(&mxc_usbh2, &usbh2_pdata);
418} 418}
diff --git a/arch/arm/mach-mx3/mach-pcm037.c b/arch/arm/mach-mx3/mach-pcm037.c
index 8a292dd1a714..214de11b20b9 100644
--- a/arch/arm/mach-mx3/mach-pcm037.c
+++ b/arch/arm/mach-mx3/mach-pcm037.c
@@ -654,13 +654,13 @@ static void __init mxc_board_init(void)
654#if defined(CONFIG_USB_ULPI) 654#if defined(CONFIG_USB_ULPI)
655 if (otg_mode_host) { 655 if (otg_mode_host) {
656 otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, 656 otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
657 USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT); 657 ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
658 658
659 mxc_register_device(&mxc_otg_host, &otg_pdata); 659 mxc_register_device(&mxc_otg_host, &otg_pdata);
660 } 660 }
661 661
662 usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, 662 usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
663 USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT); 663 ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
664 664
665 mxc_register_device(&mxc_usbh2, &usbh2_pdata); 665 mxc_register_device(&mxc_usbh2, &usbh2_pdata);
666#endif 666#endif
diff --git a/arch/arm/mach-mx3/mach-pcm043.c b/arch/arm/mach-mx3/mach-pcm043.c
index 47f5311b301a..28886f0e62f9 100644
--- a/arch/arm/mach-mx3/mach-pcm043.c
+++ b/arch/arm/mach-mx3/mach-pcm043.c
@@ -378,7 +378,7 @@ static void __init mxc_board_init(void)
378#if defined(CONFIG_USB_ULPI) 378#if defined(CONFIG_USB_ULPI)
379 if (otg_mode_host) { 379 if (otg_mode_host) {
380 otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, 380 otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
381 USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT); 381 ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
382 382
383 mxc_register_device(&mxc_otg_host, &otg_pdata); 383 mxc_register_device(&mxc_otg_host, &otg_pdata);
384 } 384 }
diff --git a/arch/arm/mach-mx3/mx31moboard-smartbot.c b/arch/arm/mach-mx3/mx31moboard-smartbot.c
index 40c3e7564cb6..417757e78c65 100644
--- a/arch/arm/mach-mx3/mx31moboard-smartbot.c
+++ b/arch/arm/mach-mx3/mx31moboard-smartbot.c
@@ -134,7 +134,7 @@ static struct mxc_usbh_platform_data otg_host_pdata = {
134static int __init smartbot_otg_host_init(void) 134static int __init smartbot_otg_host_init(void)
135{ 135{
136 otg_host_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, 136 otg_host_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
137 USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT); 137 ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
138 138
139 return mxc_register_device(&mxc_otg_host, &otg_host_pdata); 139 return mxc_register_device(&mxc_otg_host, &otg_host_pdata);
140} 140}
diff --git a/drivers/usb/otg/ulpi.c b/drivers/usb/otg/ulpi.c
index ef7dbe40f111..ccc81950822b 100644
--- a/drivers/usb/otg/ulpi.c
+++ b/drivers/usb/otg/ulpi.c
@@ -37,25 +37,106 @@ static unsigned int ulpi_ids[] = {
37 ULPI_ID(0x0424, 0x0006), /* SMSC USB3319 */ 37 ULPI_ID(0x0424, 0x0006), /* SMSC USB3319 */
38}; 38};
39 39
40static int ulpi_set_flags(struct otg_transceiver *otg) 40static int ulpi_set_otg_flags(struct otg_transceiver *otg)
41{ 41{
42 unsigned int flags = 0; 42 unsigned int flags = ULPI_OTG_CTRL_DP_PULLDOWN |
43 ULPI_OTG_CTRL_DM_PULLDOWN;
43 44
44 if (otg->flags & USB_OTG_PULLUP_ID) 45 if (otg->flags & ULPI_OTG_ID_PULLUP)
45 flags |= ULPI_OTG_CTRL_ID_PULLUP; 46 flags |= ULPI_OTG_CTRL_ID_PULLUP;
46 47
47 if (otg->flags & USB_OTG_PULLDOWN_DM) 48 /*
48 flags |= ULPI_OTG_CTRL_DM_PULLDOWN; 49 * ULPI Specification rev.1.1 default
50 * for Dp/DmPulldown is enabled.
51 */
52 if (otg->flags & ULPI_OTG_DP_PULLDOWN_DIS)
53 flags &= ~ULPI_OTG_CTRL_DP_PULLDOWN;
49 54
50 if (otg->flags & USB_OTG_PULLDOWN_DP) 55 if (otg->flags & ULPI_OTG_DM_PULLDOWN_DIS)
51 flags |= ULPI_OTG_CTRL_DP_PULLDOWN; 56 flags &= ~ULPI_OTG_CTRL_DM_PULLDOWN;
52 57
53 if (otg->flags & USB_OTG_EXT_VBUS_INDICATOR) 58 if (otg->flags & ULPI_OTG_EXTVBUSIND)
54 flags |= ULPI_OTG_CTRL_EXTVBUSIND; 59 flags |= ULPI_OTG_CTRL_EXTVBUSIND;
55 60
56 return otg_io_write(otg, flags, ULPI_OTG_CTRL); 61 return otg_io_write(otg, flags, ULPI_OTG_CTRL);
57} 62}
58 63
64static int ulpi_set_fc_flags(struct otg_transceiver *otg)
65{
66 unsigned int flags = 0;
67
68 /*
69 * ULPI Specification rev.1.1 default
70 * for XcvrSelect is Full Speed.
71 */
72 if (otg->flags & ULPI_FC_HS)
73 flags |= ULPI_FUNC_CTRL_HIGH_SPEED;
74 else if (otg->flags & ULPI_FC_LS)
75 flags |= ULPI_FUNC_CTRL_LOW_SPEED;
76 else if (otg->flags & ULPI_FC_FS4LS)
77 flags |= ULPI_FUNC_CTRL_FS4LS;
78 else
79 flags |= ULPI_FUNC_CTRL_FULL_SPEED;
80
81 if (otg->flags & ULPI_FC_TERMSEL)
82 flags |= ULPI_FUNC_CTRL_TERMSELECT;
83
84 /*
85 * ULPI Specification rev.1.1 default
86 * for OpMode is Normal Operation.
87 */
88 if (otg->flags & ULPI_FC_OP_NODRV)
89 flags |= ULPI_FUNC_CTRL_OPMODE_NONDRIVING;
90 else if (otg->flags & ULPI_FC_OP_DIS_NRZI)
91 flags |= ULPI_FUNC_CTRL_OPMODE_DISABLE_NRZI;
92 else if (otg->flags & ULPI_FC_OP_NSYNC_NEOP)
93 flags |= ULPI_FUNC_CTRL_OPMODE_NOSYNC_NOEOP;
94 else
95 flags |= ULPI_FUNC_CTRL_OPMODE_NORMAL;
96
97 /*
98 * ULPI Specification rev.1.1 default
99 * for SuspendM is Powered.
100 */
101 flags |= ULPI_FUNC_CTRL_SUSPENDM;
102
103 return otg_io_write(otg, flags, ULPI_FUNC_CTRL);
104}
105
106static int ulpi_set_ic_flags(struct otg_transceiver *otg)
107{
108 unsigned int flags = 0;
109
110 if (otg->flags & ULPI_IC_AUTORESUME)
111 flags |= ULPI_IFC_CTRL_AUTORESUME;
112
113 if (otg->flags & ULPI_IC_EXTVBUS_INDINV)
114 flags |= ULPI_IFC_CTRL_EXTERNAL_VBUS;
115
116 if (otg->flags & ULPI_IC_IND_PASSTHRU)
117 flags |= ULPI_IFC_CTRL_PASSTHRU;
118
119 if (otg->flags & ULPI_IC_PROTECT_DIS)
120 flags |= ULPI_IFC_CTRL_PROTECT_IFC_DISABLE;
121
122 return otg_io_write(otg, flags, ULPI_IFC_CTRL);
123}
124
125static int ulpi_set_flags(struct otg_transceiver *otg)
126{
127 int ret;
128
129 ret = ulpi_set_otg_flags(otg);
130 if (ret)
131 return ret;
132
133 ret = ulpi_set_ic_flags(otg);
134 if (ret)
135 return ret;
136
137 return ulpi_set_fc_flags(otg);
138}
139
59static int ulpi_init(struct otg_transceiver *otg) 140static int ulpi_init(struct otg_transceiver *otg)
60{ 141{
61 int i, vid, pid, ret; 142 int i, vid, pid, ret;
@@ -80,6 +161,31 @@ static int ulpi_init(struct otg_transceiver *otg)
80 return -ENODEV; 161 return -ENODEV;
81} 162}
82 163
164static int ulpi_set_host(struct otg_transceiver *otg, struct usb_bus *host)
165{
166 unsigned int flags = otg_io_read(otg, ULPI_IFC_CTRL);
167
168 if (!host) {
169 otg->host = NULL;
170 return 0;
171 }
172
173 otg->host = host;
174
175 flags &= ~(ULPI_IFC_CTRL_6_PIN_SERIAL_MODE |
176 ULPI_IFC_CTRL_3_PIN_SERIAL_MODE |
177 ULPI_IFC_CTRL_CARKITMODE);
178
179 if (otg->flags & ULPI_IC_6PIN_SERIAL)
180 flags |= ULPI_IFC_CTRL_6_PIN_SERIAL_MODE;
181 else if (otg->flags & ULPI_IC_3PIN_SERIAL)
182 flags |= ULPI_IFC_CTRL_3_PIN_SERIAL_MODE;
183 else if (otg->flags & ULPI_IC_CARKIT)
184 flags |= ULPI_IFC_CTRL_CARKITMODE;
185
186 return otg_io_write(otg, flags, ULPI_IFC_CTRL);
187}
188
83static int ulpi_set_vbus(struct otg_transceiver *otg, bool on) 189static int ulpi_set_vbus(struct otg_transceiver *otg, bool on)
84{ 190{
85 unsigned int flags = otg_io_read(otg, ULPI_OTG_CTRL); 191 unsigned int flags = otg_io_read(otg, ULPI_OTG_CTRL);
@@ -87,10 +193,10 @@ static int ulpi_set_vbus(struct otg_transceiver *otg, bool on)
87 flags &= ~(ULPI_OTG_CTRL_DRVVBUS | ULPI_OTG_CTRL_DRVVBUS_EXT); 193 flags &= ~(ULPI_OTG_CTRL_DRVVBUS | ULPI_OTG_CTRL_DRVVBUS_EXT);
88 194
89 if (on) { 195 if (on) {
90 if (otg->flags & USB_OTG_DRV_VBUS) 196 if (otg->flags & ULPI_OTG_DRVVBUS)
91 flags |= ULPI_OTG_CTRL_DRVVBUS; 197 flags |= ULPI_OTG_CTRL_DRVVBUS;
92 198
93 if (otg->flags & USB_OTG_DRV_VBUS_EXT) 199 if (otg->flags & ULPI_OTG_DRVVBUS_EXT)
94 flags |= ULPI_OTG_CTRL_DRVVBUS_EXT; 200 flags |= ULPI_OTG_CTRL_DRVVBUS_EXT;
95 } 201 }
96 202
@@ -111,6 +217,7 @@ otg_ulpi_create(struct otg_io_access_ops *ops,
111 otg->flags = flags; 217 otg->flags = flags;
112 otg->io_ops = ops; 218 otg->io_ops = ops;
113 otg->init = ulpi_init; 219 otg->init = ulpi_init;
220 otg->set_host = ulpi_set_host;
114 otg->set_vbus = ulpi_set_vbus; 221 otg->set_vbus = ulpi_set_vbus;
115 222
116 return otg; 223 return otg;
diff --git a/include/linux/usb/otg.h b/include/linux/usb/otg.h
index 54b2c5e48b9d..545cba73ccaf 100644
--- a/include/linux/usb/otg.h
+++ b/include/linux/usb/otg.h
@@ -43,13 +43,6 @@ enum usb_xceiv_events {
43 USB_EVENT_ENUMERATED, /* gadget driver enumerated */ 43 USB_EVENT_ENUMERATED, /* gadget driver enumerated */
44}; 44};
45 45
46#define USB_OTG_PULLUP_ID (1 << 0)
47#define USB_OTG_PULLDOWN_DP (1 << 1)
48#define USB_OTG_PULLDOWN_DM (1 << 2)
49#define USB_OTG_EXT_VBUS_INDICATOR (1 << 3)
50#define USB_OTG_DRV_VBUS (1 << 4)
51#define USB_OTG_DRV_VBUS_EXT (1 << 5)
52
53struct otg_transceiver; 46struct otg_transceiver;
54 47
55/* for transceivers connected thru an ULPI interface, the user must 48/* for transceivers connected thru an ULPI interface, the user must
diff --git a/include/linux/usb/ulpi.h b/include/linux/usb/ulpi.h
index 900d97b7096a..82b1507f4735 100644
--- a/include/linux/usb/ulpi.h
+++ b/include/linux/usb/ulpi.h
@@ -15,6 +15,41 @@
15/*-------------------------------------------------------------------------*/ 15/*-------------------------------------------------------------------------*/
16 16
17/* 17/*
18 * ULPI Flags
19 */
20#define ULPI_OTG_ID_PULLUP (1 << 0)
21#define ULPI_OTG_DP_PULLDOWN_DIS (1 << 1)
22#define ULPI_OTG_DM_PULLDOWN_DIS (1 << 2)
23#define ULPI_OTG_DISCHRGVBUS (1 << 3)
24#define ULPI_OTG_CHRGVBUS (1 << 4)
25#define ULPI_OTG_DRVVBUS (1 << 5)
26#define ULPI_OTG_DRVVBUS_EXT (1 << 6)
27#define ULPI_OTG_EXTVBUSIND (1 << 7)
28
29#define ULPI_IC_6PIN_SERIAL (1 << 8)
30#define ULPI_IC_3PIN_SERIAL (1 << 9)
31#define ULPI_IC_CARKIT (1 << 10)
32#define ULPI_IC_CLKSUSPM (1 << 11)
33#define ULPI_IC_AUTORESUME (1 << 12)
34#define ULPI_IC_EXTVBUS_INDINV (1 << 13)
35#define ULPI_IC_IND_PASSTHRU (1 << 14)
36#define ULPI_IC_PROTECT_DIS (1 << 15)
37
38#define ULPI_FC_HS (1 << 16)
39#define ULPI_FC_FS (1 << 17)
40#define ULPI_FC_LS (1 << 18)
41#define ULPI_FC_FS4LS (1 << 19)
42#define ULPI_FC_TERMSEL (1 << 20)
43#define ULPI_FC_OP_NORM (1 << 21)
44#define ULPI_FC_OP_NODRV (1 << 22)
45#define ULPI_FC_OP_DIS_NRZI (1 << 23)
46#define ULPI_FC_OP_NSYNC_NEOP (1 << 24)
47#define ULPI_FC_RST (1 << 25)
48#define ULPI_FC_SUSPM (1 << 26)
49
50/*-------------------------------------------------------------------------*/
51
52/*
18 * Macros for Set and Clear 53 * Macros for Set and Clear
19 * See ULPI 1.1 specification to find the registers with Set and Clear offsets 54 * See ULPI 1.1 specification to find the registers with Set and Clear offsets
20 */ 55 */
@@ -59,6 +94,10 @@
59 94
60/*-------------------------------------------------------------------------*/ 95/*-------------------------------------------------------------------------*/
61 96
97/*
98 * Register Bits
99 */
100
62/* Function Control */ 101/* Function Control */
63#define ULPI_FUNC_CTRL_XCVRSEL (1 << 0) 102#define ULPI_FUNC_CTRL_XCVRSEL (1 << 0)
64#define ULPI_FUNC_CTRL_XCVRSEL_MASK (3 << 0) 103#define ULPI_FUNC_CTRL_XCVRSEL_MASK (3 << 0)