• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6.36/drivers/usb/musb/
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>
14#include <linux/init.h>
15#include <linux/list.h>
16#include <linux/gpio.h>
17#include <linux/io.h>
18
19#include <asm/cacheflush.h>
20
21#include "musb_core.h"
22#include "blackfin.h"
23
24/*
25 * Load an endpoint's FIFO
26 */
27void musb_write_fifo(struct musb_hw_ep *hw_ep, u16 len, const u8 *src)
28{
29	void __iomem *fifo = hw_ep->fifo;
30	void __iomem *epio = hw_ep->regs;
31	u8 epnum = hw_ep->epnum;
32
33	prefetch((u8 *)src);
34
35	musb_writew(epio, MUSB_TXCOUNT, len);
36
37	DBG(4, "TX ep%d fifo %p count %d buf %p, epio %p\n",
38			hw_ep->epnum, fifo, len, src, epio);
39
40	dump_fifo_data(src, len);
41
42	if (!ANOMALY_05000380 && epnum != 0) {
43		u16 dma_reg;
44
45		flush_dcache_range((unsigned long)src,
46			(unsigned long)(src + len));
47
48		/* Setup DMA address register */
49		dma_reg = (u32)src;
50		bfin_write16(USB_DMA_REG(epnum, USB_DMAx_ADDR_LOW), dma_reg);
51		SSYNC();
52
53		dma_reg = (u32)src >> 16;
54		bfin_write16(USB_DMA_REG(epnum, USB_DMAx_ADDR_HIGH), dma_reg);
55		SSYNC();
56
57		/* Setup DMA count register */
58		bfin_write16(USB_DMA_REG(epnum, USB_DMAx_COUNT_LOW), len);
59		bfin_write16(USB_DMA_REG(epnum, USB_DMAx_COUNT_HIGH), 0);
60		SSYNC();
61
62		/* Enable the DMA */
63		dma_reg = (epnum << 4) | DMA_ENA | INT_ENA | DIRECTION;
64		bfin_write16(USB_DMA_REG(epnum, USB_DMAx_CTRL), dma_reg);
65		SSYNC();
66
67		/* Wait for compelete */
68		while (!(bfin_read_USB_DMA_INTERRUPT() & (1 << epnum)))
69			cpu_relax();
70
71		/* acknowledge dma interrupt */
72		bfin_write_USB_DMA_INTERRUPT(1 << epnum);
73		SSYNC();
74
75		/* Reset DMA */
76		bfin_write16(USB_DMA_REG(epnum, USB_DMAx_CTRL), 0);
77		SSYNC();
78	} else {
79		SSYNC();
80
81		if (unlikely((unsigned long)src & 0x01))
82			outsw_8((unsigned long)fifo, src, (len + 1) >> 1);
83		else
84			outsw((unsigned long)fifo, src, (len + 1) >> 1);
85	}
86}
87/*
88 * Unload an endpoint's FIFO
89 */
90void musb_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *dst)
91{
92	void __iomem *fifo = hw_ep->fifo;
93	u8 epnum = hw_ep->epnum;
94
95	if (ANOMALY_05000467 && epnum != 0) {
96		u16 dma_reg;
97
98		invalidate_dcache_range((unsigned long)dst,
99			(unsigned long)(dst + len));
100
101		/* Setup DMA address register */
102		dma_reg = (u32)dst;
103		bfin_write16(USB_DMA_REG(epnum, USB_DMAx_ADDR_LOW), dma_reg);
104		SSYNC();
105
106		dma_reg = (u32)dst >> 16;
107		bfin_write16(USB_DMA_REG(epnum, USB_DMAx_ADDR_HIGH), dma_reg);
108		SSYNC();
109
110		/* Setup DMA count register */
111		bfin_write16(USB_DMA_REG(epnum, USB_DMAx_COUNT_LOW), len);
112		bfin_write16(USB_DMA_REG(epnum, USB_DMAx_COUNT_HIGH), 0);
113		SSYNC();
114
115		/* Enable the DMA */
116		dma_reg = (epnum << 4) | DMA_ENA | INT_ENA;
117		bfin_write16(USB_DMA_REG(epnum, USB_DMAx_CTRL), dma_reg);
118		SSYNC();
119
120		/* Wait for compelete */
121		while (!(bfin_read_USB_DMA_INTERRUPT() & (1 << epnum)))
122			cpu_relax();
123
124		/* acknowledge dma interrupt */
125		bfin_write_USB_DMA_INTERRUPT(1 << epnum);
126		SSYNC();
127
128		/* Reset DMA */
129		bfin_write16(USB_DMA_REG(epnum, USB_DMAx_CTRL), 0);
130		SSYNC();
131	} else {
132		SSYNC();
133		/* Read the last byte of packet with odd size from address fifo + 4
134		 * to trigger 1 byte access to EP0 FIFO.
135		 */
136		if (len == 1)
137			*dst = (u8)inw((unsigned long)fifo + 4);
138		else {
139			if (unlikely((unsigned long)dst & 0x01))
140				insw_8((unsigned long)fifo, dst, len >> 1);
141			else
142				insw((unsigned long)fifo, dst, len >> 1);
143
144			if (len & 0x01)
145				*(dst + len - 1) = (u8)inw((unsigned long)fifo + 4);
146		}
147	}
148	DBG(4, "%cX ep%d fifo %p count %d buf %p\n",
149			'R', hw_ep->epnum, fifo, len, dst);
150
151	dump_fifo_data(dst, len);
152}
153
154static irqreturn_t blackfin_interrupt(int irq, void *__hci)
155{
156	unsigned long	flags;
157	irqreturn_t	retval = IRQ_NONE;
158	struct musb	*musb = __hci;
159
160	spin_lock_irqsave(&musb->lock, flags);
161
162	musb->int_usb = musb_readb(musb->mregs, MUSB_INTRUSB);
163	musb->int_tx = musb_readw(musb->mregs, MUSB_INTRTX);
164	musb->int_rx = musb_readw(musb->mregs, MUSB_INTRRX);
165
166	if (musb->int_usb || musb->int_tx || musb->int_rx) {
167		musb_writeb(musb->mregs, MUSB_INTRUSB, musb->int_usb);
168		musb_writew(musb->mregs, MUSB_INTRTX, musb->int_tx);
169		musb_writew(musb->mregs, MUSB_INTRRX, musb->int_rx);
170		retval = musb_interrupt(musb);
171	}
172
173	/* Start sampling ID pin, when plug is removed from MUSB */
174	if (is_otg_enabled(musb) && (musb->xceiv->state == OTG_STATE_B_IDLE
175		|| musb->xceiv->state == OTG_STATE_A_WAIT_BCON)) {
176		mod_timer(&musb_conn_timer, jiffies + TIMER_DELAY);
177		musb->a_wait_bcon = TIMER_DELAY;
178	}
179
180	spin_unlock_irqrestore(&musb->lock, flags);
181
182	return retval;
183}
184
185static void musb_conn_timer_handler(unsigned long _musb)
186{
187	struct musb *musb = (void *)_musb;
188	unsigned long flags;
189	u16 val;
190	static u8 toggle;
191
192	spin_lock_irqsave(&musb->lock, flags);
193	switch (musb->xceiv->state) {
194	case OTG_STATE_A_IDLE:
195	case OTG_STATE_A_WAIT_BCON:
196		/* Start a new session */
197		val = musb_readw(musb->mregs, MUSB_DEVCTL);
198		val &= ~MUSB_DEVCTL_SESSION;
199		musb_writew(musb->mregs, MUSB_DEVCTL, val);
200		val |= MUSB_DEVCTL_SESSION;
201		musb_writew(musb->mregs, MUSB_DEVCTL, val);
202		/* Check if musb is host or peripheral. */
203		val = musb_readw(musb->mregs, MUSB_DEVCTL);
204
205		if (!(val & MUSB_DEVCTL_BDEVICE)) {
206			gpio_set_value(musb->config->gpio_vrsel, 1);
207			musb->xceiv->state = OTG_STATE_A_WAIT_BCON;
208		} else {
209			gpio_set_value(musb->config->gpio_vrsel, 0);
210			/* Ignore VBUSERROR and SUSPEND IRQ */
211			val = musb_readb(musb->mregs, MUSB_INTRUSBE);
212			val &= ~MUSB_INTR_VBUSERROR;
213			musb_writeb(musb->mregs, MUSB_INTRUSBE, val);
214
215			val = MUSB_INTR_SUSPEND | MUSB_INTR_VBUSERROR;
216			musb_writeb(musb->mregs, MUSB_INTRUSB, val);
217			if (is_otg_enabled(musb))
218				musb->xceiv->state = OTG_STATE_B_IDLE;
219			else
220				musb_writeb(musb->mregs, MUSB_POWER, MUSB_POWER_HSENAB);
221		}
222		mod_timer(&musb_conn_timer, jiffies + TIMER_DELAY);
223		break;
224	case OTG_STATE_B_IDLE:
225
226		if (!is_peripheral_enabled(musb))
227			break;
228		/* Start a new session.  It seems that MUSB needs taking
229		 * some time to recognize the type of the plug inserted?
230		 */
231		val = musb_readw(musb->mregs, MUSB_DEVCTL);
232		val |= MUSB_DEVCTL_SESSION;
233		musb_writew(musb->mregs, MUSB_DEVCTL, val);
234		val = musb_readw(musb->mregs, MUSB_DEVCTL);
235
236		if (!(val & MUSB_DEVCTL_BDEVICE)) {
237			gpio_set_value(musb->config->gpio_vrsel, 1);
238			musb->xceiv->state = OTG_STATE_A_WAIT_BCON;
239		} else {
240			gpio_set_value(musb->config->gpio_vrsel, 0);
241
242			/* Ignore VBUSERROR and SUSPEND IRQ */
243			val = musb_readb(musb->mregs, MUSB_INTRUSBE);
244			val &= ~MUSB_INTR_VBUSERROR;
245			musb_writeb(musb->mregs, MUSB_INTRUSBE, val);
246
247			val = MUSB_INTR_SUSPEND | MUSB_INTR_VBUSERROR;
248			musb_writeb(musb->mregs, MUSB_INTRUSB, val);
249
250			/* Toggle the Soft Conn bit, so that we can response to
251			 * the inserting of either A-plug or B-plug.
252			 */
253			if (toggle) {
254				val = musb_readb(musb->mregs, MUSB_POWER);
255				val &= ~MUSB_POWER_SOFTCONN;
256				musb_writeb(musb->mregs, MUSB_POWER, val);
257				toggle = 0;
258			} else {
259				val = musb_readb(musb->mregs, MUSB_POWER);
260				val |= MUSB_POWER_SOFTCONN;
261				musb_writeb(musb->mregs, MUSB_POWER, val);
262				toggle = 1;
263			}
264			/* The delay time is set to 1/4 second by default,
265			 * shortening it, if accelerating A-plug detection
266			 * is needed in OTG mode.
267			 */
268			mod_timer(&musb_conn_timer, jiffies + TIMER_DELAY / 4);
269		}
270		break;
271	default:
272		DBG(1, "%s state not handled\n", otg_state_string(musb));
273		break;
274	}
275	spin_unlock_irqrestore(&musb->lock, flags);
276
277	DBG(4, "state is %s\n", otg_state_string(musb));
278}
279
280void musb_platform_enable(struct musb *musb)
281{
282	if (!is_otg_enabled(musb) && is_host_enabled(musb)) {
283		mod_timer(&musb_conn_timer, jiffies + TIMER_DELAY);
284		musb->a_wait_bcon = TIMER_DELAY;
285	}
286}
287
288void musb_platform_disable(struct musb *musb)
289{
290}
291
292static void bfin_set_vbus(struct musb *musb, int is_on)
293{
294	int value = musb->config->gpio_vrsel_active;
295	if (!is_on)
296		value = !value;
297	gpio_set_value(musb->config->gpio_vrsel, value);
298
299	DBG(1, "VBUS %s, devctl %02x "
300		/* otg %3x conf %08x prcm %08x */ "\n",
301		otg_state_string(musb),
302		musb_readb(musb->mregs, MUSB_DEVCTL));
303}
304
305static int bfin_set_power(struct otg_transceiver *x, unsigned mA)
306{
307	return 0;
308}
309
310void musb_platform_try_idle(struct musb *musb, unsigned long timeout)
311{
312	if (!is_otg_enabled(musb) && is_host_enabled(musb))
313		mod_timer(&musb_conn_timer, jiffies + TIMER_DELAY);
314}
315
316int musb_platform_get_vbus_status(struct musb *musb)
317{
318	return 0;
319}
320
321int musb_platform_set_mode(struct musb *musb, u8 musb_mode)
322{
323	return -EIO;
324}
325
326int __init musb_platform_init(struct musb *musb, void *board_data)
327{
328
329	/*
330	 * Rev 1.0 BF549 EZ-KITs require PE7 to be high for both DEVICE
331	 * and OTG HOST modes, while rev 1.1 and greater require PE7 to
332	 * be low for DEVICE mode and high for HOST mode. We set it high
333	 * here because we are in host mode
334	 */
335
336	if (gpio_request(musb->config->gpio_vrsel, "USB_VRSEL")) {
337		printk(KERN_ERR "Failed ro request USB_VRSEL GPIO_%d \n",
338			musb->config->gpio_vrsel);
339		return -ENODEV;
340	}
341	gpio_direction_output(musb->config->gpio_vrsel, 0);
342
343	usb_nop_xceiv_register();
344	musb->xceiv = otg_get_transceiver();
345	if (!musb->xceiv) {
346		gpio_free(musb->config->gpio_vrsel);
347		return -ENODEV;
348	}
349
350	if (ANOMALY_05000346) {
351		bfin_write_USB_APHY_CALIB(ANOMALY_05000346_value);
352		SSYNC();
353	}
354
355	if (ANOMALY_05000347) {
356		bfin_write_USB_APHY_CNTRL(0x0);
357		SSYNC();
358	}
359
360	/* Configure PLL oscillator register */
361	bfin_write_USB_PLLOSC_CTRL(0x30a8);
362	SSYNC();
363
364	bfin_write_USB_SRP_CLKDIV((get_sclk()/1000) / 32 - 1);
365	SSYNC();
366
367	bfin_write_USB_EP_NI0_RXMAXP(64);
368	SSYNC();
369
370	bfin_write_USB_EP_NI0_TXMAXP(64);
371	SSYNC();
372
373	/* Route INTRUSB/INTR_RX/INTR_TX to USB_INT0*/
374	bfin_write_USB_GLOBINTR(0x7);
375	SSYNC();
376
377	bfin_write_USB_GLOBAL_CTL(GLOBAL_ENA | EP1_TX_ENA | EP2_TX_ENA |
378				EP3_TX_ENA | EP4_TX_ENA | EP5_TX_ENA |
379				EP6_TX_ENA | EP7_TX_ENA | EP1_RX_ENA |
380				EP2_RX_ENA | EP3_RX_ENA | EP4_RX_ENA |
381				EP5_RX_ENA | EP6_RX_ENA | EP7_RX_ENA);
382	SSYNC();
383
384	if (is_host_enabled(musb)) {
385		musb->board_set_vbus = bfin_set_vbus;
386		setup_timer(&musb_conn_timer,
387			musb_conn_timer_handler, (unsigned long) musb);
388	}
389	if (is_peripheral_enabled(musb))
390		musb->xceiv->set_power = bfin_set_power;
391
392	musb->isr = blackfin_interrupt;
393
394	return 0;
395}
396
397int musb_platform_exit(struct musb *musb)
398{
399	gpio_free(musb->config->gpio_vrsel);
400
401	otg_put_transceiver(musb->xceiv);
402	usb_nop_xceiv_unregister();
403	return 0;
404}
405