Merge 2.6.38-rc5 into staging-next
[deliverable/linux.git] / drivers / usb / musb / blackfin.c
CommitLineData
0c6a8818
BW
1/*
2 * MUSB OTG controller driver for Blackfin Processors
3 *
4 * Copyright 2006-2008 Analog Devices Inc.
5 *
6 * Enter bugs at http://blackfin.uclinux.org/
7 *
8 * Licensed under the GPL-2 or later.
9 */
10
11#include <linux/module.h>
12#include <linux/kernel.h>
13#include <linux/sched.h>
0c6a8818
BW
14#include <linux/init.h>
15#include <linux/list.h>
0c6a8818
BW
16#include <linux/gpio.h>
17#include <linux/io.h>
9cb0308e
FB
18#include <linux/platform_device.h>
19#include <linux/dma-mapping.h>
0c6a8818
BW
20
21#include <asm/cacheflush.h>
22
23#include "musb_core.h"
24#include "blackfin.h"
25
a023c631
FB
26struct bfin_glue {
27 struct device *dev;
28 struct platform_device *musb;
29};
fcd22e3b 30#define glue_to_musb(g) platform_get_drvdata(g->musb)
a023c631 31
0c6a8818
BW
32/*
33 * Load an endpoint's FIFO
34 */
35void musb_write_fifo(struct musb_hw_ep *hw_ep, u16 len, const u8 *src)
36{
37 void __iomem *fifo = hw_ep->fifo;
38 void __iomem *epio = hw_ep->regs;
1c4bdc01 39 u8 epnum = hw_ep->epnum;
0c6a8818
BW
40
41 prefetch((u8 *)src);
42
43 musb_writew(epio, MUSB_TXCOUNT, len);
44
45 DBG(4, "TX ep%d fifo %p count %d buf %p, epio %p\n",
46 hw_ep->epnum, fifo, len, src, epio);
47
48 dump_fifo_data(src, len);
49
1c4bdc01 50 if (!ANOMALY_05000380 && epnum != 0) {
1ca9e9ca
BW
51 u16 dma_reg;
52
53 flush_dcache_range((unsigned long)src,
54 (unsigned long)(src + len));
1c4bdc01
BW
55
56 /* Setup DMA address register */
1ca9e9ca 57 dma_reg = (u32)src;
1c4bdc01
BW
58 bfin_write16(USB_DMA_REG(epnum, USB_DMAx_ADDR_LOW), dma_reg);
59 SSYNC();
60
1ca9e9ca 61 dma_reg = (u32)src >> 16;
1c4bdc01
BW
62 bfin_write16(USB_DMA_REG(epnum, USB_DMAx_ADDR_HIGH), dma_reg);
63 SSYNC();
64
65 /* Setup DMA count register */
66 bfin_write16(USB_DMA_REG(epnum, USB_DMAx_COUNT_LOW), len);
67 bfin_write16(USB_DMA_REG(epnum, USB_DMAx_COUNT_HIGH), 0);
68 SSYNC();
69
70 /* Enable the DMA */
71 dma_reg = (epnum << 4) | DMA_ENA | INT_ENA | DIRECTION;
72 bfin_write16(USB_DMA_REG(epnum, USB_DMAx_CTRL), dma_reg);
73 SSYNC();
74
75 /* Wait for compelete */
76 while (!(bfin_read_USB_DMA_INTERRUPT() & (1 << epnum)))
77 cpu_relax();
78
79 /* acknowledge dma interrupt */
80 bfin_write_USB_DMA_INTERRUPT(1 << epnum);
81 SSYNC();
82
83 /* Reset DMA */
84 bfin_write16(USB_DMA_REG(epnum, USB_DMAx_CTRL), 0);
85 SSYNC();
86 } else {
87 SSYNC();
88
89 if (unlikely((unsigned long)src & 0x01))
1ca9e9ca 90 outsw_8((unsigned long)fifo, src, (len + 1) >> 1);
1c4bdc01 91 else
1ca9e9ca 92 outsw((unsigned long)fifo, src, (len + 1) >> 1);
1c4bdc01 93 }
0c6a8818 94}
0c6a8818
BW
95/*
96 * Unload an endpoint's FIFO
97 */
98void musb_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *dst)
99{
100 void __iomem *fifo = hw_ep->fifo;
101 u8 epnum = hw_ep->epnum;
0c6a8818 102
1c4bdc01 103 if (ANOMALY_05000467 && epnum != 0) {
1ca9e9ca 104 u16 dma_reg;
1c4bdc01 105
1ca9e9ca
BW
106 invalidate_dcache_range((unsigned long)dst,
107 (unsigned long)(dst + len));
1c4bdc01
BW
108
109 /* Setup DMA address register */
1ca9e9ca 110 dma_reg = (u32)dst;
1c4bdc01
BW
111 bfin_write16(USB_DMA_REG(epnum, USB_DMAx_ADDR_LOW), dma_reg);
112 SSYNC();
113
1ca9e9ca 114 dma_reg = (u32)dst >> 16;
1c4bdc01
BW
115 bfin_write16(USB_DMA_REG(epnum, USB_DMAx_ADDR_HIGH), dma_reg);
116 SSYNC();
117
118 /* Setup DMA count register */
119 bfin_write16(USB_DMA_REG(epnum, USB_DMAx_COUNT_LOW), len);
120 bfin_write16(USB_DMA_REG(epnum, USB_DMAx_COUNT_HIGH), 0);
121 SSYNC();
122
123 /* Enable the DMA */
124 dma_reg = (epnum << 4) | DMA_ENA | INT_ENA;
125 bfin_write16(USB_DMA_REG(epnum, USB_DMAx_CTRL), dma_reg);
126 SSYNC();
127
128 /* Wait for compelete */
129 while (!(bfin_read_USB_DMA_INTERRUPT() & (1 << epnum)))
130 cpu_relax();
131
132 /* acknowledge dma interrupt */
133 bfin_write_USB_DMA_INTERRUPT(1 << epnum);
134 SSYNC();
135
136 /* Reset DMA */
137 bfin_write16(USB_DMA_REG(epnum, USB_DMAx_CTRL), 0);
138 SSYNC();
139 } else {
140 SSYNC();
141 /* Read the last byte of packet with odd size from address fifo + 4
142 * to trigger 1 byte access to EP0 FIFO.
143 */
144 if (len == 1)
145 *dst = (u8)inw((unsigned long)fifo + 4);
146 else {
147 if (unlikely((unsigned long)dst & 0x01))
148 insw_8((unsigned long)fifo, dst, len >> 1);
149 else
150 insw((unsigned long)fifo, dst, len >> 1);
151
152 if (len & 0x01)
153 *(dst + len - 1) = (u8)inw((unsigned long)fifo + 4);
154 }
155 }
04f4086f
MF
156 DBG(4, "%cX ep%d fifo %p count %d buf %p\n",
157 'R', hw_ep->epnum, fifo, len, dst);
158
0c6a8818
BW
159 dump_fifo_data(dst, len);
160}
161
162static irqreturn_t blackfin_interrupt(int irq, void *__hci)
163{
164 unsigned long flags;
165 irqreturn_t retval = IRQ_NONE;
166 struct musb *musb = __hci;
167
168 spin_lock_irqsave(&musb->lock, flags);
169
170 musb->int_usb = musb_readb(musb->mregs, MUSB_INTRUSB);
171 musb->int_tx = musb_readw(musb->mregs, MUSB_INTRTX);
172 musb->int_rx = musb_readw(musb->mregs, MUSB_INTRRX);
173
174 if (musb->int_usb || musb->int_tx || musb->int_rx) {
175 musb_writeb(musb->mregs, MUSB_INTRUSB, musb->int_usb);
176 musb_writew(musb->mregs, MUSB_INTRTX, musb->int_tx);
177 musb_writew(musb->mregs, MUSB_INTRRX, musb->int_rx);
178 retval = musb_interrupt(musb);
179 }
180
ff927add 181 /* Start sampling ID pin, when plug is removed from MUSB */
68f64714
BL
182 if ((is_otg_enabled(musb) && (musb->xceiv->state == OTG_STATE_B_IDLE
183 || musb->xceiv->state == OTG_STATE_A_WAIT_BCON)) ||
184 (musb->int_usb & MUSB_INTR_DISCONNECT && is_host_active(musb))) {
ff927add
CC
185 mod_timer(&musb_conn_timer, jiffies + TIMER_DELAY);
186 musb->a_wait_bcon = TIMER_DELAY;
187 }
188
0c6a8818
BW
189 spin_unlock_irqrestore(&musb->lock, flags);
190
2f831751 191 return retval;
0c6a8818
BW
192}
193
194static void musb_conn_timer_handler(unsigned long _musb)
195{
196 struct musb *musb = (void *)_musb;
197 unsigned long flags;
198 u16 val;
ff927add 199 static u8 toggle;
0c6a8818
BW
200
201 spin_lock_irqsave(&musb->lock, flags);
84e250ff 202 switch (musb->xceiv->state) {
0c6a8818
BW
203 case OTG_STATE_A_IDLE:
204 case OTG_STATE_A_WAIT_BCON:
205 /* Start a new session */
206 val = musb_readw(musb->mregs, MUSB_DEVCTL);
ff927add
CC
207 val &= ~MUSB_DEVCTL_SESSION;
208 musb_writew(musb->mregs, MUSB_DEVCTL, val);
0c6a8818
BW
209 val |= MUSB_DEVCTL_SESSION;
210 musb_writew(musb->mregs, MUSB_DEVCTL, val);
ff927add
CC
211 /* Check if musb is host or peripheral. */
212 val = musb_readw(musb->mregs, MUSB_DEVCTL);
213
214 if (!(val & MUSB_DEVCTL_BDEVICE)) {
215 gpio_set_value(musb->config->gpio_vrsel, 1);
216 musb->xceiv->state = OTG_STATE_A_WAIT_BCON;
217 } else {
218 gpio_set_value(musb->config->gpio_vrsel, 0);
219 /* Ignore VBUSERROR and SUSPEND IRQ */
220 val = musb_readb(musb->mregs, MUSB_INTRUSBE);
221 val &= ~MUSB_INTR_VBUSERROR;
222 musb_writeb(musb->mregs, MUSB_INTRUSBE, val);
223
224 val = MUSB_INTR_SUSPEND | MUSB_INTR_VBUSERROR;
225 musb_writeb(musb->mregs, MUSB_INTRUSB, val);
226 if (is_otg_enabled(musb))
227 musb->xceiv->state = OTG_STATE_B_IDLE;
228 else
229 musb_writeb(musb->mregs, MUSB_POWER, MUSB_POWER_HSENAB);
230 }
231 mod_timer(&musb_conn_timer, jiffies + TIMER_DELAY);
232 break;
233 case OTG_STATE_B_IDLE:
0c6a8818 234
ff927add
CC
235 if (!is_peripheral_enabled(musb))
236 break;
237 /* Start a new session. It seems that MUSB needs taking
238 * some time to recognize the type of the plug inserted?
239 */
240 val = musb_readw(musb->mregs, MUSB_DEVCTL);
241 val |= MUSB_DEVCTL_SESSION;
242 musb_writew(musb->mregs, MUSB_DEVCTL, val);
0c6a8818 243 val = musb_readw(musb->mregs, MUSB_DEVCTL);
ff927add 244
0c6a8818
BW
245 if (!(val & MUSB_DEVCTL_BDEVICE)) {
246 gpio_set_value(musb->config->gpio_vrsel, 1);
84e250ff 247 musb->xceiv->state = OTG_STATE_A_WAIT_BCON;
0c6a8818
BW
248 } else {
249 gpio_set_value(musb->config->gpio_vrsel, 0);
250
251 /* Ignore VBUSERROR and SUSPEND IRQ */
252 val = musb_readb(musb->mregs, MUSB_INTRUSBE);
253 val &= ~MUSB_INTR_VBUSERROR;
254 musb_writeb(musb->mregs, MUSB_INTRUSBE, val);
255
256 val = MUSB_INTR_SUSPEND | MUSB_INTR_VBUSERROR;
257 musb_writeb(musb->mregs, MUSB_INTRUSB, val);
258
ff927add
CC
259 /* Toggle the Soft Conn bit, so that we can response to
260 * the inserting of either A-plug or B-plug.
261 */
262 if (toggle) {
263 val = musb_readb(musb->mregs, MUSB_POWER);
264 val &= ~MUSB_POWER_SOFTCONN;
265 musb_writeb(musb->mregs, MUSB_POWER, val);
266 toggle = 0;
267 } else {
268 val = musb_readb(musb->mregs, MUSB_POWER);
269 val |= MUSB_POWER_SOFTCONN;
270 musb_writeb(musb->mregs, MUSB_POWER, val);
271 toggle = 1;
272 }
273 /* The delay time is set to 1/4 second by default,
274 * shortening it, if accelerating A-plug detection
275 * is needed in OTG mode.
276 */
277 mod_timer(&musb_conn_timer, jiffies + TIMER_DELAY / 4);
0c6a8818 278 }
0c6a8818 279 break;
0c6a8818
BW
280 default:
281 DBG(1, "%s state not handled\n", otg_state_string(musb));
282 break;
283 }
284 spin_unlock_irqrestore(&musb->lock, flags);
285
286 DBG(4, "state is %s\n", otg_state_string(musb));
287}
288
743411b3 289static void bfin_musb_enable(struct musb *musb)
0c6a8818 290{
ff927add 291 if (!is_otg_enabled(musb) && is_host_enabled(musb)) {
0c6a8818
BW
292 mod_timer(&musb_conn_timer, jiffies + TIMER_DELAY);
293 musb->a_wait_bcon = TIMER_DELAY;
294 }
295}
296
743411b3 297static void bfin_musb_disable(struct musb *musb)
0c6a8818
BW
298{
299}
300
743411b3 301static void bfin_musb_set_vbus(struct musb *musb, int is_on)
0c6a8818 302{
6ddc6dae
CC
303 int value = musb->config->gpio_vrsel_active;
304 if (!is_on)
305 value = !value;
306 gpio_set_value(musb->config->gpio_vrsel, value);
0c6a8818
BW
307
308 DBG(1, "VBUS %s, devctl %02x "
309 /* otg %3x conf %08x prcm %08x */ "\n",
310 otg_state_string(musb),
311 musb_readb(musb->mregs, MUSB_DEVCTL));
312}
313
743411b3 314static int bfin_musb_set_power(struct otg_transceiver *x, unsigned mA)
0c6a8818
BW
315{
316 return 0;
317}
318
743411b3 319static void bfin_musb_try_idle(struct musb *musb, unsigned long timeout)
0c6a8818 320{
ff927add 321 if (!is_otg_enabled(musb) && is_host_enabled(musb))
0c6a8818
BW
322 mod_timer(&musb_conn_timer, jiffies + TIMER_DELAY);
323}
324
743411b3 325static int bfin_musb_get_vbus_status(struct musb *musb)
0c6a8818
BW
326{
327 return 0;
328}
329
743411b3 330static int bfin_musb_set_mode(struct musb *musb, u8 musb_mode)
0c6a8818 331{
2002e768 332 return -EIO;
0c6a8818
BW
333}
334
743411b3 335static void bfin_musb_reg_init(struct musb *musb)
0c6a8818 336{
d426e60d
RG
337 if (ANOMALY_05000346) {
338 bfin_write_USB_APHY_CALIB(ANOMALY_05000346_value);
339 SSYNC();
340 }
0c6a8818 341
d426e60d
RG
342 if (ANOMALY_05000347) {
343 bfin_write_USB_APHY_CNTRL(0x0);
344 SSYNC();
345 }
0c6a8818 346
0c6a8818 347 /* Configure PLL oscillator register */
9c756462
BL
348 bfin_write_USB_PLLOSC_CTRL(0x3080 |
349 ((480/musb->config->clkin) << 1));
0c6a8818
BW
350 SSYNC();
351
352 bfin_write_USB_SRP_CLKDIV((get_sclk()/1000) / 32 - 1);
353 SSYNC();
354
355 bfin_write_USB_EP_NI0_RXMAXP(64);
356 SSYNC();
357
358 bfin_write_USB_EP_NI0_TXMAXP(64);
359 SSYNC();
360
361 /* Route INTRUSB/INTR_RX/INTR_TX to USB_INT0*/
362 bfin_write_USB_GLOBINTR(0x7);
363 SSYNC();
364
365 bfin_write_USB_GLOBAL_CTL(GLOBAL_ENA | EP1_TX_ENA | EP2_TX_ENA |
366 EP3_TX_ENA | EP4_TX_ENA | EP5_TX_ENA |
367 EP6_TX_ENA | EP7_TX_ENA | EP1_RX_ENA |
368 EP2_RX_ENA | EP3_RX_ENA | EP4_RX_ENA |
369 EP5_RX_ENA | EP6_RX_ENA | EP7_RX_ENA);
370 SSYNC();
743411b3
FB
371}
372
373static int bfin_musb_init(struct musb *musb)
374{
375
376 /*
377 * Rev 1.0 BF549 EZ-KITs require PE7 to be high for both DEVICE
378 * and OTG HOST modes, while rev 1.1 and greater require PE7 to
379 * be low for DEVICE mode and high for HOST mode. We set it high
380 * here because we are in host mode
381 */
382
383 if (gpio_request(musb->config->gpio_vrsel, "USB_VRSEL")) {
384 printk(KERN_ERR "Failed ro request USB_VRSEL GPIO_%d\n",
385 musb->config->gpio_vrsel);
386 return -ENODEV;
387 }
388 gpio_direction_output(musb->config->gpio_vrsel, 0);
389
390 usb_nop_xceiv_register();
391 musb->xceiv = otg_get_transceiver();
392 if (!musb->xceiv) {
393 gpio_free(musb->config->gpio_vrsel);
394 return -ENODEV;
395 }
396
397 bfin_musb_reg_init(musb);
0c6a8818
BW
398
399 if (is_host_enabled(musb)) {
0c6a8818
BW
400 setup_timer(&musb_conn_timer,
401 musb_conn_timer_handler, (unsigned long) musb);
402 }
403 if (is_peripheral_enabled(musb))
743411b3 404 musb->xceiv->set_power = bfin_musb_set_power;
0c6a8818
BW
405
406 musb->isr = blackfin_interrupt;
06624818 407 musb->double_buffer_not_ok = true;
0c6a8818
BW
408
409 return 0;
410}
411
743411b3 412static int bfin_musb_exit(struct musb *musb)
0c6a8818 413{
0c6a8818 414 gpio_free(musb->config->gpio_vrsel);
0c6a8818 415
f4053874 416 otg_put_transceiver(musb->xceiv);
3daad24d 417 usb_nop_xceiv_unregister();
0c6a8818
BW
418 return 0;
419}
743411b3 420
f7ec9437 421static const struct musb_platform_ops bfin_ops = {
743411b3
FB
422 .init = bfin_musb_init,
423 .exit = bfin_musb_exit,
424
425 .enable = bfin_musb_enable,
426 .disable = bfin_musb_disable,
427
428 .set_mode = bfin_musb_set_mode,
429 .try_idle = bfin_musb_try_idle,
430
431 .vbus_status = bfin_musb_vbus_status,
432 .set_vbus = bfin_musb_set_vbus,
433};
9cb0308e
FB
434
435static u64 bfin_dmamask = DMA_BIT_MASK(32);
436
437static int __init bfin_probe(struct platform_device *pdev)
438{
439 struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data;
440 struct platform_device *musb;
a023c631 441 struct bfin_glue *glue;
9cb0308e
FB
442
443 int ret = -ENOMEM;
444
a023c631
FB
445 glue = kzalloc(sizeof(*glue), GFP_KERNEL);
446 if (!glue) {
447 dev_err(&pdev->dev, "failed to allocate glue context\n");
448 goto err0;
449 }
450
9cb0308e
FB
451 musb = platform_device_alloc("musb-hdrc", -1);
452 if (!musb) {
453 dev_err(&pdev->dev, "failed to allocate musb device\n");
a023c631 454 goto err1;
9cb0308e
FB
455 }
456
457 musb->dev.parent = &pdev->dev;
458 musb->dev.dma_mask = &bfin_dmamask;
459 musb->dev.coherent_dma_mask = bfin_dmamask;
460
a023c631
FB
461 glue->dev = &pdev->dev;
462 glue->musb = musb;
463
f7ec9437
FB
464 pdata->platform_ops = &bfin_ops;
465
a023c631 466 platform_set_drvdata(pdev, glue);
9cb0308e
FB
467
468 ret = platform_device_add_resources(musb, pdev->resource,
469 pdev->num_resources);
470 if (ret) {
471 dev_err(&pdev->dev, "failed to add resources\n");
a023c631 472 goto err2;
9cb0308e
FB
473 }
474
475 ret = platform_device_add_data(musb, pdata, sizeof(*pdata));
476 if (ret) {
477 dev_err(&pdev->dev, "failed to add platform_data\n");
a023c631 478 goto err2;
9cb0308e
FB
479 }
480
481 ret = platform_device_add(musb);
482 if (ret) {
483 dev_err(&pdev->dev, "failed to register musb device\n");
a023c631 484 goto err2;
9cb0308e
FB
485 }
486
487 return 0;
488
a023c631 489err2:
9cb0308e
FB
490 platform_device_put(musb);
491
a023c631
FB
492err1:
493 kfree(glue);
494
9cb0308e
FB
495err0:
496 return ret;
497}
498
499static int __exit bfin_remove(struct platform_device *pdev)
500{
a023c631 501 struct bfin_glue *glue = platform_get_drvdata(pdev);
9cb0308e 502
a023c631
FB
503 platform_device_del(glue->musb);
504 platform_device_put(glue->musb);
505 kfree(glue);
9cb0308e
FB
506
507 return 0;
508}
509
fcd22e3b
FB
510#ifdef CONFIG_PM
511static int bfin_suspend(struct device *dev)
512{
513 struct bfin_glue *glue = dev_get_drvdata(dev);
514 struct musb *musb = glue_to_musb(glue);
515
516 if (is_host_active(musb))
517 /*
518 * During hibernate gpio_vrsel will change from high to low
519 * low which will generate wakeup event resume the system
520 * immediately. Set it to 0 before hibernate to avoid this
521 * wakeup event.
522 */
523 gpio_set_value(musb->config->gpio_vrsel, 0);
524
525 return 0;
526}
527
528static int bfin_resume(struct device *dev)
529{
530 struct bfin_glue *glue = dev_get_drvdata(dev);
531 struct musb *musb = glue_to_musb(glue);
532
533 bfin_musb_reg_init(musb);
534
535 return 0;
536}
537
538static struct dev_pm_ops bfin_pm_ops = {
539 .suspend = bfin_suspend,
540 .resume = bfin_resume,
541};
542
543#define DEV_PM_OPS &bfin_pm_op,
544#else
545#define DEV_PM_OPS NULL
546#endif
547
9cb0308e
FB
548static struct platform_driver bfin_driver = {
549 .remove = __exit_p(bfin_remove),
550 .driver = {
551 .name = "musb-bfin",
fcd22e3b 552 .pm = DEV_PM_OPS,
9cb0308e
FB
553 },
554};
555
556MODULE_DESCRIPTION("Blackfin MUSB Glue Layer");
557MODULE_AUTHOR("Bryan Wy <cooloney@kernel.org>");
558MODULE_LICENSE("GPL v2");
559
560static int __init bfin_init(void)
561{
562 return platform_driver_probe(&bfin_driver, bfin_probe);
563}
564subsys_initcall(bfin_init);
565
566static void __exit bfin_exit(void)
567{
568 platform_driver_unregister(&bfin_driver);
569}
570module_exit(bfin_exit);
This page took 0.222411 seconds and 5 git commands to generate.