1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31#include <common.h>
32#include <exports.h>
33#include <usb/ulpi.h>
34
35#define ULPI_ID_REGS_COUNT 4
36#define ULPI_TEST_VALUE 0x55
37
38static struct ulpi_regs *ulpi = (struct ulpi_regs *)0;
39
40static int ulpi_integrity_check(struct ulpi_viewport *ulpi_vp)
41{
42 u32 val, tval = ULPI_TEST_VALUE;
43 int err, i;
44
45
46 for (i = 0; i < 2; i++, tval <<= 1) {
47 err = ulpi_write(ulpi_vp, &ulpi->scratch, tval);
48 if (err)
49 return err;
50
51 val = ulpi_read(ulpi_vp, &ulpi->scratch);
52 if (val != tval) {
53 printf("ULPI integrity check failed\n");
54 return val;
55 }
56 }
57
58 return 0;
59}
60
61int ulpi_init(struct ulpi_viewport *ulpi_vp)
62{
63 u32 val, id = 0;
64 u8 *reg = &ulpi->product_id_high;
65 int i;
66
67
68 for (i = 0; i < ULPI_ID_REGS_COUNT; i++) {
69 val = ulpi_read(ulpi_vp, reg - i);
70 if (val == ULPI_ERROR)
71 return val;
72
73 id = (id << 8) | val;
74 }
75
76
77 debug("ULPI transceiver ID 0x%04x:0x%04x\n", id >> 16, id & 0xffff);
78
79 return ulpi_integrity_check(ulpi_vp);
80}
81
82int ulpi_select_transceiver(struct ulpi_viewport *ulpi_vp, unsigned speed)
83{
84 u32 tspeed = ULPI_FC_FULL_SPEED;
85 u32 val;
86
87 switch (speed) {
88 case ULPI_FC_HIGH_SPEED:
89 case ULPI_FC_FULL_SPEED:
90 case ULPI_FC_LOW_SPEED:
91 case ULPI_FC_FS4LS:
92 tspeed = speed;
93 break;
94 default:
95 printf("ULPI: %s: wrong transceiver speed specified: %u, "
96 "falling back to full speed\n", __func__, speed);
97 }
98
99 val = ulpi_read(ulpi_vp, &ulpi->function_ctrl);
100 if (val == ULPI_ERROR)
101 return val;
102
103
104 val = (val & ~ULPI_FC_XCVRSEL_MASK) | tspeed;
105
106 return ulpi_write(ulpi_vp, &ulpi->function_ctrl, val);
107}
108
109int ulpi_set_vbus(struct ulpi_viewport *ulpi_vp, int on, int ext_power,
110 int ext_ind)
111{
112 u32 flags = ULPI_OTG_DRVVBUS;
113 u8 *reg = on ? &ulpi->otg_ctrl_set : &ulpi->otg_ctrl_clear;
114
115 if (ext_power)
116 flags |= ULPI_OTG_DRVVBUS_EXT;
117 if (ext_ind)
118 flags |= ULPI_OTG_EXTVBUSIND;
119
120 return ulpi_write(ulpi_vp, reg, flags);
121}
122
123int ulpi_set_pd(struct ulpi_viewport *ulpi_vp, int enable)
124{
125 u32 val = ULPI_OTG_DP_PULLDOWN | ULPI_OTG_DM_PULLDOWN;
126 u8 *reg = enable ? &ulpi->otg_ctrl_set : &ulpi->otg_ctrl_clear;
127
128 return ulpi_write(ulpi_vp, reg, val);
129}
130
131int ulpi_opmode_sel(struct ulpi_viewport *ulpi_vp, unsigned opmode)
132{
133 u32 topmode = ULPI_FC_OPMODE_NORMAL;
134 u32 val;
135
136 switch (opmode) {
137 case ULPI_FC_OPMODE_NORMAL:
138 case ULPI_FC_OPMODE_NONDRIVING:
139 case ULPI_FC_OPMODE_DISABLE_NRZI:
140 case ULPI_FC_OPMODE_NOSYNC_NOEOP:
141 topmode = opmode;
142 break;
143 default:
144 printf("ULPI: %s: wrong OpMode specified: %u, "
145 "falling back to OpMode Normal\n", __func__, opmode);
146 }
147
148 val = ulpi_read(ulpi_vp, &ulpi->function_ctrl);
149 if (val == ULPI_ERROR)
150 return val;
151
152
153 val = (val & ~ULPI_FC_OPMODE_MASK) | topmode;
154
155 return ulpi_write(ulpi_vp, &ulpi->function_ctrl, val);
156}
157
158int ulpi_serial_mode_enable(struct ulpi_viewport *ulpi_vp, unsigned smode)
159{
160 switch (smode) {
161 case ULPI_IFACE_6_PIN_SERIAL_MODE:
162 case ULPI_IFACE_3_PIN_SERIAL_MODE:
163 break;
164 default:
165 printf("ULPI: %s: unrecognized Serial Mode specified: %u\n",
166 __func__, smode);
167 return ULPI_ERROR;
168 }
169
170 return ulpi_write(ulpi_vp, &ulpi->iface_ctrl_set, smode);
171}
172
173int ulpi_suspend(struct ulpi_viewport *ulpi_vp)
174{
175 int err;
176
177 err = ulpi_write(ulpi_vp, &ulpi->function_ctrl_clear,
178 ULPI_FC_SUSPENDM);
179 if (err)
180 printf("ULPI: %s: failed writing the suspend bit\n", __func__);
181
182 return err;
183}
184
185
186
187
188
189
190static int __ulpi_reset_wait(struct ulpi_viewport *ulpi_vp)
191{
192 u32 val;
193 int timeout = CONFIG_USB_ULPI_TIMEOUT;
194
195
196 while (--timeout) {
197
198
199
200
201
202
203 val = ulpi_read(ulpi_vp, &ulpi->function_ctrl);
204 if (!(val & ULPI_FC_RESET))
205 return 0;
206
207 udelay(1);
208 }
209
210 printf("ULPI: %s: reset timed out\n", __func__);
211
212 return ULPI_ERROR;
213}
214int ulpi_reset_wait(struct ulpi_viewport *ulpi_vp)
215 __attribute__((weak, alias("__ulpi_reset_wait")));
216
217int ulpi_reset(struct ulpi_viewport *ulpi_vp)
218{
219 int err;
220
221 err = ulpi_write(ulpi_vp,
222 &ulpi->function_ctrl_set, ULPI_FC_RESET);
223 if (err) {
224 printf("ULPI: %s: failed writing reset bit\n", __func__);
225 return err;
226 }
227
228 return ulpi_reset_wait(ulpi_vp);
229}
230