aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHeikki Krogerus <ext-heikki.krogerus@nokia.com>2010-03-25 07:25:28 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-05-20 16:21:36 -0400
commitffb865b1e4608cf76867f132b9e8df359fdffc91 (patch)
tree6d130ab2b0a733d153ed2b6541610232640d4ef3
parent58815fa3bffdee8dbac5af6931eea991d7a71a19 (diff)
usb: musb: add ulpi access operations
This adds helper functions for ULPI access, and implements otg_io_access_ops for musb. Signed-off-by: Heikki Krogerus <ext-heikki.krogerus@nokia.com> Signed-off-by: Felipe Balbi <felipe.balbi@nokia.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/usb/musb/musb_core.c86
-rw-r--r--drivers/usb/musb/musb_regs.h10
2 files changed, 96 insertions, 0 deletions
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index 27aaaa023a1..fad70bc8355 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -149,6 +149,87 @@ static inline struct musb *dev_to_musb(struct device *dev)
149 149
150/*-------------------------------------------------------------------------*/ 150/*-------------------------------------------------------------------------*/
151 151
152#ifndef CONFIG_BLACKFIN
153static int musb_ulpi_read(struct otg_transceiver *otg, u32 offset)
154{
155 void __iomem *addr = otg->io_priv;
156 int i = 0;
157 u8 r;
158 u8 power;
159
160 /* Make sure the transceiver is not in low power mode */
161 power = musb_readb(addr, MUSB_POWER);
162 power &= ~MUSB_POWER_SUSPENDM;
163 musb_writeb(addr, MUSB_POWER, power);
164
165 /* REVISIT: musbhdrc_ulpi_an.pdf recommends setting the
166 * ULPICarKitControlDisableUTMI after clearing POWER_SUSPENDM.
167 */
168
169 musb_writeb(addr, MUSB_ULPI_REG_ADDR, (u8)offset);
170 musb_writeb(addr, MUSB_ULPI_REG_CONTROL,
171 MUSB_ULPI_REG_REQ | MUSB_ULPI_RDN_WR);
172
173 while (!(musb_readb(addr, MUSB_ULPI_REG_CONTROL)
174 & MUSB_ULPI_REG_CMPLT)) {
175 i++;
176 if (i == 10000) {
177 DBG(3, "ULPI read timed out\n");
178 return -ETIMEDOUT;
179 }
180
181 }
182 r = musb_readb(addr, MUSB_ULPI_REG_CONTROL);
183 r &= ~MUSB_ULPI_REG_CMPLT;
184 musb_writeb(addr, MUSB_ULPI_REG_CONTROL, r);
185
186 return musb_readb(addr, MUSB_ULPI_REG_DATA);
187}
188
189static int musb_ulpi_write(struct otg_transceiver *otg,
190 u32 offset, u32 data)
191{
192 void __iomem *addr = otg->io_priv;
193 int i = 0;
194 u8 r = 0;
195 u8 power;
196
197 /* Make sure the transceiver is not in low power mode */
198 power = musb_readb(addr, MUSB_POWER);
199 power &= ~MUSB_POWER_SUSPENDM;
200 musb_writeb(addr, MUSB_POWER, power);
201
202 musb_writeb(addr, MUSB_ULPI_REG_ADDR, (u8)offset);
203 musb_writeb(addr, MUSB_ULPI_REG_DATA, (u8)data);
204 musb_writeb(addr, MUSB_ULPI_REG_CONTROL, MUSB_ULPI_REG_REQ);
205
206 while (!(musb_readb(addr, MUSB_ULPI_REG_CONTROL)
207 & MUSB_ULPI_REG_CMPLT)) {
208 i++;
209 if (i == 10000) {
210 DBG(3, "ULPI write timed out\n");
211 return -ETIMEDOUT;
212 }
213 }
214
215 r = musb_readb(addr, MUSB_ULPI_REG_CONTROL);
216 r &= ~MUSB_ULPI_REG_CMPLT;
217 musb_writeb(addr, MUSB_ULPI_REG_CONTROL, r);
218
219 return 0;
220}
221#else
222#define musb_ulpi_read(a, b) NULL
223#define musb_ulpi_write(a, b, c) NULL
224#endif
225
226static struct otg_io_access_ops musb_ulpi_access = {
227 .read = musb_ulpi_read,
228 .write = musb_ulpi_write,
229};
230
231/*-------------------------------------------------------------------------*/
232
152#if !defined(CONFIG_USB_TUSB6010) && !defined(CONFIG_BLACKFIN) 233#if !defined(CONFIG_USB_TUSB6010) && !defined(CONFIG_BLACKFIN)
153 234
154/* 235/*
@@ -1954,6 +2035,11 @@ bad_config:
1954 goto fail3; 2035 goto fail3;
1955 } 2036 }
1956 2037
2038 if (!musb->xceiv->io_ops) {
2039 musb->xceiv->io_priv = musb->mregs;
2040 musb->xceiv->io_ops = &musb_ulpi_access;
2041 }
2042
1957#ifndef CONFIG_MUSB_PIO_ONLY 2043#ifndef CONFIG_MUSB_PIO_ONLY
1958 if (use_dma && dev->dma_mask) { 2044 if (use_dma && dev->dma_mask) {
1959 struct dma_controller *c; 2045 struct dma_controller *c;
diff --git a/drivers/usb/musb/musb_regs.h b/drivers/usb/musb/musb_regs.h
index fa55aacc385..244267527a6 100644
--- a/drivers/usb/musb/musb_regs.h
+++ b/drivers/usb/musb/musb_regs.h
@@ -75,6 +75,10 @@
75/* MUSB ULPI VBUSCONTROL */ 75/* MUSB ULPI VBUSCONTROL */
76#define MUSB_ULPI_USE_EXTVBUS 0x01 76#define MUSB_ULPI_USE_EXTVBUS 0x01
77#define MUSB_ULPI_USE_EXTVBUSIND 0x02 77#define MUSB_ULPI_USE_EXTVBUSIND 0x02
78/* ULPI_REG_CONTROL */
79#define MUSB_ULPI_REG_REQ (1 << 0)
80#define MUSB_ULPI_REG_CMPLT (1 << 1)
81#define MUSB_ULPI_RDN_WR (1 << 2)
78 82
79/* TESTMODE */ 83/* TESTMODE */
80#define MUSB_TEST_FORCE_HOST 0x80 84#define MUSB_TEST_FORCE_HOST 0x80
@@ -251,6 +255,12 @@
251/* REVISIT: vctrl/vstatus: optional vendor utmi+phy register at 0x68 */ 255/* REVISIT: vctrl/vstatus: optional vendor utmi+phy register at 0x68 */
252#define MUSB_HWVERS 0x6C /* 8 bit */ 256#define MUSB_HWVERS 0x6C /* 8 bit */
253#define MUSB_ULPI_BUSCONTROL 0x70 /* 8 bit */ 257#define MUSB_ULPI_BUSCONTROL 0x70 /* 8 bit */
258#define MUSB_ULPI_INT_MASK 0x72 /* 8 bit */
259#define MUSB_ULPI_INT_SRC 0x73 /* 8 bit */
260#define MUSB_ULPI_REG_DATA 0x74 /* 8 bit */
261#define MUSB_ULPI_REG_ADDR 0x75 /* 8 bit */
262#define MUSB_ULPI_REG_CONTROL 0x76 /* 8 bit */
263#define MUSB_ULPI_RAW_DATA 0x77 /* 8 bit */
254 264
255#define MUSB_EPINFO 0x78 /* 8 bit */ 265#define MUSB_EPINFO 0x78 /* 8 bit */
256#define MUSB_RAMINFO 0x79 /* 8 bit */ 266#define MUSB_RAMINFO 0x79 /* 8 bit */