1 /******************************************************************
2 * Copyright 2005 Mentor Graphics Corporation
3 * Copyright (C) 2005-2006 by Texas Instruments
5 * This file is part of the Inventra Controller Driver for Linux.
7 * The Inventra Controller Driver for Linux is free software; you
8 * can redistribute it and/or modify it under the terms of the GNU
9 * General Public License version 2 as published by the Free Software
12 * The Inventra Controller Driver for Linux is distributed in
13 * the hope that it will be useful, but WITHOUT ANY WARRANTY;
14 * without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
16 * License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with The Inventra Controller Driver for Linux ; if not,
20 * write to the Free Software Foundation, Inc., 59 Temple Place,
21 * Suite 330, Boston, MA 02111-1307 USA
23 * ANY DOWNLOAD, USE, REPRODUCTION, MODIFICATION OR DISTRIBUTION
24 * OF THIS DRIVER INDICATES YOUR COMPLETE AND UNCONDITIONAL ACCEPTANCE
25 * OF THOSE TERMS.THIS DRIVER IS PROVIDED "AS IS" AND MENTOR GRAPHICS
26 * MAKES NO WARRANTIES, EXPRESS OR IMPLIED, RELATED TO THIS DRIVER.
27 * MENTOR GRAPHICS SPECIFICALLY DISCLAIMS ALL IMPLIED WARRANTIES
28 * OF MERCHANTABILITY; FITNESS FOR A PARTICULAR PURPOSE AND
29 * NON-INFRINGEMENT. MENTOR GRAPHICS DOES NOT PROVIDE SUPPORT
30 * SERVICES OR UPDATES FOR THIS DRIVER, EVEN IF YOU ARE A MENTOR
31 * GRAPHICS SUPPORT CUSTOMER.
32 ******************************************************************/
34 #ifndef __MUSB_MUSBDEFS_H__
35 #define __MUSB_MUSBDEFS_H__
37 #include <linux/slab.h>
38 #include <linux/list.h>
39 #include <linux/interrupt.h>
40 #include <linux/smp_lock.h>
41 #include <linux/errno.h>
42 #include <linux/device.h>
43 #include <linux/usb_ch9.h>
44 #include <linux/usb_otg.h>
45 #include <linux/usb/musb.h>
55 #ifdef CONFIG_USB_MUSB_SOC
57 * Get core configuration from a header converted (by cfg_conv)
58 * from the Verilog config file generated by the core config utility
60 * For now we assume that header is provided along with other
61 * arch-specific files. Discrete chips will need a build tweak.
62 * So will using AHB IDs from silicon that provides them.
64 #include <asm/arch/hdrc_cnf.h>
71 /* REVISIT tune this */
72 #define MIN_DMA_REQUEST 1 /* use PIO below this xfer size */
75 #ifdef CONFIG_USB_MUSB_OTG
78 #define is_peripheral_enabled(musb) ((musb)->board_mode != MUSB_HOST)
79 #define is_host_enabled(musb) ((musb)->board_mode != MUSB_PERIPHERAL)
80 #define is_otg_enabled(musb) ((musb)->board_mode == MUSB_OTG)
82 /* NOTE: otg and peripheral-only state machines start at B_IDLE.
83 * OTG or host-only go to A_IDLE when ID is sensed.
85 #define is_peripheral_active(m) (is_peripheral_capable() && !(m)->bIsHost)
86 #define is_host_active(m) (is_host_capable() && (m)->bIsHost)
88 /* for some reason, the "select USB_GADGET_MUSB_HDRC" doesn't really
89 * override that choice selection (often USB_GADGET_DUMMY_HCD).
91 #ifndef CONFIG_USB_GADGET_MUSB_HDRC
92 #error bogus Kconfig output ... select CONFIG_USB_GADGET_MUSB_HDRC
96 #define is_peripheral_enabled(musb) is_peripheral_capable()
97 #define is_host_enabled(musb) is_host_capable()
98 #define is_otg_enabled(musb) 0
100 #define is_peripheral_active(musb) is_peripheral_capable()
101 #define is_host_active(musb) is_host_capable()
104 #ifdef CONFIG_PROC_FS
105 #include <linux/fs.h>
106 #define MUSB_CONFIG_PROC_FS
109 /****************************** PERIPHERAL ROLE *****************************/
111 #ifdef CONFIG_USB_GADGET_MUSB_HDRC
113 #include <linux/usb_gadget.h>
114 #include "musb_gadget.h"
116 #define is_peripheral_capable() (1)
118 extern irqreturn_t musb_g_ep0_irq(struct musb *);
119 extern void musb_g_tx(struct musb *, u8);
120 extern void musb_g_rx(struct musb *, u8);
121 extern void musb_g_reset(struct musb *);
122 extern void musb_g_suspend(struct musb *);
123 extern void musb_g_resume(struct musb *);
124 extern void musb_g_disconnect(struct musb *);
128 #define is_peripheral_capable() (0)
130 static inline irqreturn_t musb_g_ep0_irq(struct musb *m) { return IRQ_NONE; }
131 static inline void musb_g_tx(struct musb *m, u8 e) {}
132 static inline void musb_g_rx(struct musb *m, u8 e) {}
133 static inline void musb_g_reset(struct musb *m) {}
134 static inline void musb_g_suspend(struct musb *m) {}
135 static inline void musb_g_resume(struct musb *m) {}
136 static inline void musb_g_disconnect(struct musb *m) {}
140 /****************************** HOST ROLE ***********************************/
142 #ifdef CONFIG_USB_MUSB_HDRC_HCD
144 #include <linux/usb.h>
145 #include "../core/hcd.h"
146 #include "musb_host.h"
148 #define is_host_capable() (1)
150 extern irqreturn_t musb_h_ep0_irq(struct musb *);
151 extern void musb_host_tx(struct musb *, u8);
152 extern void musb_host_rx(struct musb *, u8);
156 #define is_host_capable() (0)
158 static inline irqreturn_t musb_h_ep0_irq(struct musb *m) { return IRQ_NONE; }
159 static inline void musb_host_tx(struct musb *m, u8 e) {}
160 static inline void musb_host_rx(struct musb *m, u8 e) {}
162 static inline void musb_root_disconnect(struct musb *musb) { BUG(); }
167 /****************************** CONSTANTS ********************************/
176 #ifndef MUSB_C_NUM_EPS
177 #define MUSB_C_NUM_EPS ((u8)16)
180 #ifndef MUSB_MAX_END0_PACKET
181 #define MUSB_MAX_END0_PACKET ((u16)MGC_END0_FIFOSIZE)
184 /* host side ep0 states */
185 #define MGC_END0_START 0x0
186 #define MGC_END0_OUT 0x2
187 #define MGC_END0_IN 0x4
188 #define MGC_END0_STATUS 0x8
190 /* peripheral side ep0 states */
191 enum musb_g_ep0_state {
192 MGC_END0_STAGE_SETUP, /* idle, waiting for setup */
193 MGC_END0_STAGE_TX, /* IN data */
194 MGC_END0_STAGE_RX, /* OUT data */
195 MGC_END0_STAGE_STATUSIN, /* (after OUT data) */
196 MGC_END0_STAGE_STATUSOUT, /* (after IN data) */
197 MGC_END0_STAGE_ACKWAIT, /* after zlp, before statusin */
198 } __attribute__ ((packed));
200 /* driver and cable VBUS status states for musb_irq_work */
201 #define MUSB_VBUS_STATUS_CHG (1 << 0)
204 #define MUSB_ERR_WAITING 1
205 #define MUSB_ERR_VBUS -1
206 #define MUSB_ERR_BABBLE -2
207 #define MUSB_ERR_CORRUPTED -3
208 #define MUSB_ERR_IRQ -4
209 #define MUSB_ERR_SHUTDOWN -5
210 #define MUSB_ERR_RESTART -6
213 /*************************** REGISTER ACCESS ********************************/
215 /* Endpoint registers (other than dynfifo setup) can be accessed either
216 * directly with the "flat" model, or after setting up an index register.
219 #if defined(CONFIG_ARCH_DAVINCI) || defined(CONFIG_ARCH_OMAP243X)
220 /* REVISIT "flat" takes about 1% more object code space and can't be very
221 * noticeable for speed differences. But for now indexed access seems to
222 * misbehave (on DaVinci) for at least peripheral IN ...
224 #define MUSB_FLAT_REG
227 /* TUSB mapping: "flat" plus ep0 special cases */
228 #if defined(CONFIG_USB_TUSB6010)
229 #define MGC_SelectEnd(_pBase, _bEnd) \
230 musb_writeb((_pBase), MGC_O_HDRC_INDEX, (_bEnd))
231 #define MGC_END_OFFSET MGC_TUSB_OFFSET
233 /* "flat" mapping: each endpoint has its own i/o address */
234 #elif defined(MUSB_FLAT_REG)
235 #define MGC_SelectEnd(_pBase, _bEnd) (((void)(_pBase)),((void)(_bEnd)))
236 #define MGC_END_OFFSET MGC_FLAT_OFFSET
238 /* "indexed" mapping: INDEX register controls register bank select */
240 #define MGC_SelectEnd(_pBase, _bEnd) \
241 musb_writeb((_pBase), MGC_O_HDRC_INDEX, (_bEnd))
242 #define MGC_END_OFFSET MGC_INDEXED_OFFSET
245 /* FIXME: replace with musb_readcsr(hw_ep *, REGNAME), etc
246 * using hw_ep->regs, for all access except writing INDEX
249 #define MGC_ReadCsr8(_pBase, _bOffset, _bEnd) \
250 musb_readb((_pBase), MGC_END_OFFSET((_bEnd), (_bOffset)))
251 #define MGC_ReadCsr16(_pBase, _bOffset, _bEnd) \
252 musb_readw((_pBase), MGC_END_OFFSET((_bEnd), (_bOffset)))
253 #define MGC_WriteCsr8(_pBase, _bOffset, _bEnd, _bData) \
254 musb_writeb((_pBase), MGC_END_OFFSET((_bEnd), (_bOffset)), (_bData))
255 #define MGC_WriteCsr16(_pBase, _bOffset, _bEnd, _bData) \
256 musb_writew((_pBase), MGC_END_OFFSET((_bEnd), (_bOffset)), (_bData))
258 #define MGC_ReadCsr8(_pBase, _bOffset, _bEnd) \
259 musb_readb(_pBase, (_bOffset + 0x10))
260 #define MGC_ReadCsr16(_pBase, _bOffset, _bEnd) \
261 musb_readw(_pBase, (_bOffset + 0x10))
262 #define MGC_WriteCsr8(_pBase, _bOffset, _bEnd, _bData) \
263 musb_writeb(_pBase, (_bOffset + 0x10), _bData)
264 #define MGC_WriteCsr16(_pBase, _bOffset, _bEnd, _bData) \
265 musb_writew(_pBase, (_bOffset + 0x10), _bData)
268 /****************************** FUNCTIONS ********************************/
270 #define MUSB_HST_MODE(_pthis)\
271 { (_pthis)->bIsHost=TRUE; (_pthis)->bIsDevice=FALSE; \
272 (_pthis)->bFailCode=0; }
273 #define MUSB_DEV_MODE(_pthis) \
274 { (_pthis)->bIsHost=FALSE; (_pthis)->bIsDevice=TRUE; \
275 (_pthis)->bFailCode=0; }
276 #define MUSB_OTG_MODE(_pthis) \
277 { (_pthis)->bIsHost=FALSE; (_pthis)->bIsDevice=FALSE; \
278 (_pthis)->bFailCode=MUSB_ERR_WAITING; }
279 #define MUSB_ERR_MODE(_pthis, _cause) \
280 { (_pthis)->bIsHost=FALSE; (_pthis)->bIsDevice=FALSE; \
281 (_pthis)->bFailCode=_cause; }
283 #define MUSB_IS_ERR(_x) ( (_x)->bFailCode<0 )
284 #define MUSB_IS_HST(_x) (!MUSB_IS_ERR(_x) \
285 && (_x)->bIsHost && !(_x)->bIsDevice )
286 #define MUSB_IS_DEV(_x) (!MUSB_IS_ERR(_x) \
287 && !(_x)->bIsHost && (_x)->bIsDevice )
288 #define MUSB_IS_OTG(_x) (!MUSB_IS_ERR(_x) \
289 && !(_x)->bIsHost && !(_x)->bIsDevice )
291 #define test_devctl_hst_mode(_x) \
292 (musb_readb((_x)->pRegs, MGC_O_HDRC_DEVCTL)&MGC_M_DEVCTL_HM)
294 /* REVISIT OTG isn't a third non-error mode... */
295 #define MUSB_MODE(_x) ( MUSB_IS_HST(_x)?"HOST" \
296 :(MUSB_IS_DEV(_x)?"PERIPHERAL" \
297 :(MUSB_IS_OTG(_x)?"UNCONNECTED" \
300 /************************** Ep Configuration ********************************/
302 /** The End point descriptor */
303 struct MUSB_EpFifoDescriptor {
304 u8 bType; /* 0 for autoconfig, CNTR, ISOC, BULK, INTR */
305 u8 bDir; /* 0 for autoconfig, INOUT, IN, OUT */
306 int wSize; /* 0 for autoconfig, or the size */
309 #define MUSB_EPD_AUTOCONFIG 0
311 #define MUSB_EPD_T_CNTRL 1
312 #define MUSB_EPD_T_ISOC 2
313 #define MUSB_EPD_T_BULK 3
314 #define MUSB_EPD_T_INTR 4
316 #define MUSB_EPD_D_INOUT 0
317 #define MUSB_EPD_D_TX 1
318 #define MUSB_EPD_D_RX 2
320 /******************************** TYPES *************************************/
323 * struct musb_hw_ep - endpoint hardware (bidirectional)
325 * Ordered slightly for better cacheline locality.
332 #ifdef CONFIG_USB_TUSB6010
336 /* index in musb->aLocalEnd[] */
339 /* hardware configuration, possibly dynamic */
341 u8 tx_double_buffered;
342 u8 rx_double_buffered;
343 u16 wMaxPacketSizeTx;
344 u16 wMaxPacketSizeRx;
346 struct dma_channel *tx_channel;
347 struct dma_channel *rx_channel;
349 #ifdef CONFIG_USB_TUSB6010
350 /* TUSB has "asynchronous" and "synchronous" dma modes */
351 dma_addr_t fifo_async;
352 dma_addr_t fifo_sync;
355 #ifdef CONFIG_USB_MUSB_HDRC_HCD
356 void __iomem *target_regs;
358 /* currently scheduled peripheral endpoint */
359 struct musb_qh *in_qh;
360 struct musb_qh *out_qh;
366 #ifdef CONFIG_USB_GADGET_MUSB_HDRC
367 /* peripheral side */
368 struct musb_ep ep_in; /* TX */
369 struct musb_ep ep_out; /* RX */
373 static inline struct usb_request *next_in_request(struct musb_hw_ep *hw_ep)
375 #ifdef CONFIG_USB_GADGET_MUSB_HDRC
376 return next_request(&hw_ep->ep_in);
382 static inline struct usb_request *next_out_request(struct musb_hw_ep *hw_ep)
384 #ifdef CONFIG_USB_GADGET_MUSB_HDRC
385 return next_request(&hw_ep->ep_out);
392 * struct musb - Driver instance data.
397 irqreturn_t (*isr)(int, void *, struct pt_regs *);
398 struct work_struct irq_work;
400 #ifdef CONFIG_USB_MUSB_HDRC_HCD
403 unsigned long rh_timer;
405 u8 bEnd0Stage; /* end0 stage while in host */
407 /* bulk traffic normally dedicates endpoint hardware, and each
408 * direction has its own ring of host side endpoints.
409 * we try to progress the transfer at the head of each endpoint's
410 * queue until it completes or NAKs too much; then we try the next
413 struct musb_hw_ep *bulk_ep;
415 struct list_head control; /* of musb_qh */
416 struct list_head in_bulk; /* of musb_qh */
417 struct list_head out_bulk; /* of musb_qh */
418 struct musb_qh *periodic[32]; /* tree of interrupt+iso */
422 struct dma_controller *pDmaController;
424 struct device *controller;
425 void __iomem *ctrl_base;
428 #ifdef CONFIG_USB_TUSB6010
433 /* passed down from chip/board specific irq handlers */
437 struct pt_regs *int_regs;
439 struct otg_transceiver xceiv;
443 struct musb_hw_ep aLocalEnd[MUSB_C_NUM_EPS];
444 #define control_ep aLocalEnd
450 u8 board_mode; /* enum musb_mode */
451 int (*board_set_power)(int state);
453 u8 status; /* status change flags for musb_irq_work */
455 s8 bFailCode; /* one of MUSB_ERR_* failure code */
457 /* active means connected and not suspended */
458 unsigned is_active:1;
460 unsigned bIsMultipoint:1;
461 unsigned bIsDevice:1;
463 unsigned bIgnoreDisconnect:1; /* during bus resets */
466 unsigned bBulkSplit:1;
467 #define can_bulk_split(musb,type) \
468 (((type) == USB_ENDPOINT_XFER_BULK) && (musb)->bBulkSplit)
470 #define can_bulk_split(musb,type) 0
474 unsigned bBulkCombine:1;
475 /* REVISIT allegedly doesn't work reliably */
477 #define can_bulk_combine(musb,type) \
478 (((type) == USB_ENDPOINT_XFER_BULK) && (musb)->bBulkCombine)
480 #define can_bulk_combine(musb,type) 0
483 #define can_bulk_combine(musb,type) 0
486 #ifdef CONFIG_USB_GADGET_MUSB_HDRC
487 unsigned bIsSelfPowered:1;
488 unsigned bMayWakeup:1;
489 unsigned bSetAddress:1;
490 unsigned bTestMode:1;
491 unsigned softconnect:1;
493 enum musb_g_ep0_state ep0_state;
496 u16 ackpend; /* ep0 */
497 struct usb_gadget g; /* the gadget */
498 struct usb_gadget_driver *pGadgetDriver; /* its driver */
501 #ifdef CONFIG_USB_MUSB_OTG
502 struct otg_machine OtgMachine;
503 u8 bDelayPortPowerOff;
506 #ifdef MUSB_CONFIG_PROC_FS
507 struct proc_dir_entry *pProcEntry;
511 #ifdef CONFIG_USB_GADGET_MUSB_HDRC
512 static inline struct musb *gadget_to_musb(struct usb_gadget *g)
514 return container_of(g, struct musb, g);
519 /***************************** Glue it together *****************************/
521 extern const char musb_driver_name[];
523 extern void musb_start(struct musb *pThis);
524 extern void musb_stop(struct musb *pThis);
526 extern void musb_write_fifo(struct musb_hw_ep *ep,
527 u16 wCount, const u8 * pSource);
528 extern void musb_read_fifo(struct musb_hw_ep *ep,
529 u16 wCount, u8 * pDest);
531 extern void musb_load_testpacket(struct musb *);
533 extern irqreturn_t musb_interrupt(struct musb *);
535 extern void musb_platform_enable(struct musb *musb);
536 extern void musb_platform_disable(struct musb *musb);
538 #ifdef CONFIG_USB_TUSB6010
539 extern void musb_platform_try_idle(struct musb *musb);
540 extern int musb_platform_get_vbus_status(struct musb *musb);
542 #define musb_platform_try_idle(x) do {} while (0)
543 #define musb_platform_get_vbus_status(x) 0
546 extern int __devinit musb_platform_init(struct musb *musb);
547 extern int musb_platform_exit(struct musb *musb);
549 /*-------------------------- ProcFS definitions ---------------------*/
551 struct proc_dir_entry;
553 #if (MUSB_DEBUG > 0) && defined(MUSB_CONFIG_PROC_FS)
554 extern struct proc_dir_entry *musb_debug_create(char *name,
556 extern void musb_debug_delete(char *name, struct musb *data);
559 static inline struct proc_dir_entry *musb_debug_create(char *name,
564 static inline void musb_debug_delete(char *name, struct musb *data)
569 #endif /* __MUSB_MUSBDEFS_H__ */