aboutsummaryrefslogtreecommitdiff
path: root/include/linux/musb
diff options
context:
space:
mode:
authorMeizu OpenSource <patchwork@meizu.com>2016-08-15 10:19:42 +0800
committerMeizu OpenSource <patchwork@meizu.com>2016-08-15 10:19:42 +0800
commitd2e1446d81725c351dc73a03b397ce043fb18452 (patch)
tree4dbc616b7f92aea39cd697a9084205ddb805e344 /include/linux/musb
first commit
Diffstat (limited to 'include/linux/musb')
-rw-r--r--include/linux/musb/mtk_musb.h88
-rw-r--r--include/linux/musb/mtk_qmu.h324
-rw-r--r--include/linux/musb/musb.h132
-rw-r--r--include/linux/musb/musb_core.h601
-rw-r--r--include/linux/musb/musb_debug.h100
-rw-r--r--include/linux/musb/musb_dma.h171
-rw-r--r--include/linux/musb/musb_gadget.h125
-rw-r--r--include/linux/musb/musb_host.h111
-rw-r--r--include/linux/musb/musb_io.h231
-rw-r--r--include/linux/musb/musb_qmu.h21
-rw-r--r--include/linux/musb/musbhsdma.h97
11 files changed, 2001 insertions, 0 deletions
diff --git a/include/linux/musb/mtk_musb.h b/include/linux/musb/mtk_musb.h
new file mode 100644
index 000000000..2473d1130
--- /dev/null
+++ b/include/linux/musb/mtk_musb.h
@@ -0,0 +1,88 @@
+#ifndef __MUSB_MTK_MUSB_H__
+#define __MUSB_MTK_MUSB_H__
+
+#ifdef CONFIG_OF
+extern struct musb *mtk_musb;
+#define USBPHY_READ8(offset) readb((void __iomem *)(((unsigned long)mtk_musb->xceiv->io_priv)+0x800+offset))
+#define USBPHY_WRITE8(offset, value) writeb(value, (void __iomem *)(((unsigned long)mtk_musb->xceiv->io_priv)+0x800+offset))
+#define USBPHY_SET8(offset, mask) USBPHY_WRITE8(offset, (USBPHY_READ8(offset)) | (mask))
+#define USBPHY_CLR8(offset, mask) USBPHY_WRITE8(offset, (USBPHY_READ8(offset)) & (~mask))
+
+#define USBPHY_READ16(offset) readw((void __iomem *)(((unsigned long)mtk_musb->xceiv->io_priv)+0x800+offset))
+#define USBPHY_WRITE16(offset, value) writew(value, (void __iomem *)(((unsigned long)mtk_musb->xceiv->io_priv)+0x800+offset))
+#define USBPHY_SET16(offset, mask) USBPHY_WRITE16(offset, (USBPHY_READ16(offset)) | (mask))
+#define USBPHY_CLR16(offset, mask) USBPHY_WRITE16(offset, (USBPHY_READ16(offset)) & (~mask))
+
+#define USBPHY_READ32(offset) readl((void __iomem *)(((unsigned long)mtk_musb->xceiv->io_priv)+0x800+offset))
+#define USBPHY_WRITE32(offset, value) writel(value, (void __iomem *)(((unsigned long)mtk_musb->xceiv->io_priv)+0x800+offset))
+#define USBPHY_SET32(offset, mask) USBPHY_WRITE32(offset, (USBPHY_READ32(offset)) | (mask))
+#define USBPHY_CLR32(offset, mask) USBPHY_WRITE32(offset, (USBPHY_READ32(offset)) & (~mask))
+
+#ifdef MTK_UART_USB_SWITCH
+#define UART2_BASE 0x11003000
+#endif
+
+#else
+
+#include <mach/mt_reg_base.h>
+
+#define USBPHY_READ8(offset) readb((void __iomem *)(USB_SIF_BASE+0x800+offset))
+#define USBPHY_WRITE8(offset, value) writeb(value, (void __iomem *)(USB_SIF_BASE+0x800+offset))
+#define USBPHY_SET8(offset, mask) USBPHY_WRITE8(offset, (USBPHY_READ8(offset)) | (mask))
+#define USBPHY_CLR8(offset, mask) USBPHY_WRITE8(offset, (USBPHY_READ8(offset)) & (~mask))
+
+#define USBPHY_READ16(offset) readw((void __iomem *)(USB_SIF_BASE+0x800+offset))
+#define USBPHY_WRITE16(offset, value) writew(value, (void __iomem *)(USB_SIF_BASE+0x800+offset))
+#define USBPHY_SET16(offset, mask) USBPHY_WRITE16(offset, (USBPHY_READ16(offset)) | (mask))
+#define USBPHY_CLR16(offset, mask) USBPHY_WRITE16(offset, (USBPHY_READ16(offset)) & (~mask))
+
+#define USBPHY_READ32(offset) readl((void __iomem *)(USB_SIF_BASE+0x800+offset))
+#define USBPHY_WRITE32(offset, value) writel(value, (void __iomem *)(USB_SIF_BASE+0x800+offset))
+#define USBPHY_SET32(offset, mask) USBPHY_WRITE32(offset, (USBPHY_READ32(offset)) | (mask))
+#define USBPHY_CLR32(offset, mask) USBPHY_WRITE32(offset, (USBPHY_READ32(offset)) & (~mask))
+
+#endif
+struct musb;
+
+typedef enum {
+ USB_SUSPEND = 0,
+ USB_UNCONFIGURED,
+ USB_CONFIGURED
+} usb_state_enum;
+
+/* USB phy and clock */
+extern void usb_phy_poweron(void);
+extern void usb_phy_recover(void);
+extern void usb_phy_savecurrent(void);
+extern void usb_phy_context_restore(void);
+extern void usb_phy_context_save(void);
+extern bool usb_enable_clock(bool enable);
+
+/* general USB */
+extern bool mt_usb_is_device(void);
+extern void mt_usb_connect(void);
+extern void mt_usb_disconnect(void);
+/* ALPS00775710 */
+/* extern bool usb_iddig_state(void); */
+/* ALPS00775710 */
+extern bool usb_cable_connected(void);
+extern void pmic_chrdet_int_en(int is_on);
+extern void musb_platform_reset(struct musb *musb);
+extern void musb_sync_with_bat(struct musb *musb, int usb_state);
+
+extern bool is_saving_mode(void);
+
+/* USB switch charger */
+extern bool is_switch_charger(void);
+
+/* host and otg */
+extern void mt_usb_otg_init(struct musb *musb);
+extern void mt_usb_init_drvvbus(void);
+extern void mt_usb_set_vbus(struct musb *musb, int is_on);
+extern int mt_usb_get_vbus_status(struct musb *musb);
+extern void mt_usb_iddig_int(struct musb *musb);
+extern void switch_int_to_device(struct musb *musb);
+extern void switch_int_to_host(struct musb *musb);
+extern void switch_int_to_host_and_mask(struct musb *musb);
+extern void musb_session_restart(struct musb *musb);
+#endif
diff --git a/include/linux/musb/mtk_qmu.h b/include/linux/musb/mtk_qmu.h
new file mode 100644
index 000000000..4eea9cdfe
--- /dev/null
+++ b/include/linux/musb/mtk_qmu.h
@@ -0,0 +1,324 @@
+#ifndef _MTK_QMU_H_
+#define _MTK_QMU_H_
+
+#ifdef MUSB_QMU_SUPPORT
+
+/* for musb_read/write api */
+#include "mtk_musb.h"
+#include "musb_debug.h"
+#include "musb_io.h"
+
+#include <linux/dmapool.h>
+
+/* CUSTOM SETTING */
+#define GPD_LEN_ALIGNED (64) /* > gpd len (16) and cache line size aligned */
+#define GPD_EXT_LEN (48) /* GPD_LEN_ALIGNED - 16(should be sizeof(TGPD) */
+#define GPD_SZ (16)
+#define MAX_GPD_NUM 36
+#define RXQ_NUM 8
+#define TXQ_NUM 8
+#define MAX_QMU_EP RXQ_NUM
+#define TXQ 0
+#define RXQ 1
+
+/* QMU SETTING */
+#define NO_ZLP 0
+#define HW_MODE 1
+#define GPD_MODE 2
+//#define TXZLP GPD_MODE
+//#define TXZLP HW_MODE
+#define TXZLP NO_ZLP
+
+//#define CFG_RX_ZLP_EN
+//#define CFG_RX_COZ_EN
+
+#define CFG_CS_CHECK
+//#define CFG_EMPTY_CHECK
+
+/* TGPD */
+typedef struct _TGPD
+{
+ u8 flag;
+ u8 chksum;
+ u16 DataBufferLen; /*Rx Allow Length*/
+
+ /* address field, 32-bit long */
+ u32 pNext;
+ u32 pBuf;
+
+ u16 bufLen;
+ u8 ExtLength;
+ u8 ZTepFlag;
+}TGPD, *PGPD;
+
+typedef struct _GPD_RANGE {
+ PGPD pNext;
+ PGPD pStart;
+ PGPD pEnd;
+}GPD_R, *RGPD;
+
+extern int mtk_qmu_dbg_level; /* refer to musb_core.c */
+static inline int mtk_dbg_level(unsigned level)
+{
+ return mtk_qmu_dbg_level >= level;
+}
+
+#define LOG_EMERG 0
+#define LOG_ALERT 1
+#define LOG_CRIT 2
+#define LOG_ERR 3
+#define LOG_WARN 4
+#define LOG_NOTICE 5
+#define LOG_INFO 6
+#define LOG_DBG 7
+
+#define QMU_DBG_ON
+
+#ifdef QMU_DBG_ON
+#define QMU_ERR(format, args...) do {if(mtk_dbg_level(LOG_ERR)){printk(KERN_WARNING "QMU_ERR,<%s %d>, " format , __func__, __LINE__ , ## args);}}while(0)
+#define QMU_WARN(format, args...) do {if(mtk_dbg_level(LOG_WARN)){printk(KERN_WARNING "QMU_WARN,<%s %d>, " format , __func__, __LINE__ , ## args);}}while(0)
+#define QMU_INFO(format, args...) do {if(mtk_dbg_level(LOG_INFO)){printk(KERN_WARNING "QMU_INFO,<%s %d>, " format , __func__, __LINE__ , ## args);}}while(0)
+#define QMU_DBG(format, args...) do {if(mtk_dbg_level(LOG_DBG)){printk(KERN_WARNING "QMU_DBG,<%s %d>, " format , __func__, __LINE__ , ## args);}}while(0)
+#else
+#define QMU_ERR(format, args...) do {}while(0)
+#define QMU_WARN(format, args...) do {}while(0)
+#define QMU_INFO(format, args...) do {}while(0)
+#define QMU_DBG(format, args...) do {}while(0)
+#endif
+
+
+
+/* QMU macros */
+#define USB_HW_QMU_OFF 0x0000
+#define USB_HW_QUCS_OFF 0x0300
+#define USB_HW_QIRQ_OFF 0x0400
+#define USB_HW_QDBG_OFF 0x04F0
+
+#define MGC_O_QMU_QCR0 0x0000
+#define MGC_O_QMU_QCR2 0x0008
+#define MGC_O_QMU_QCR3 0x000C
+
+#define MGC_O_QMU_RQCSR0 0x0010
+#define MGC_O_QMU_RQSAR0 0x0014
+#define MGC_O_QMU_RQCPR0 0x0018
+#define MGC_O_QMU_RQCSR(n) (MGC_O_QMU_RQCSR0+0x0010*((n)-1))
+#define MGC_O_QMU_RQSAR(n) (MGC_O_QMU_RQSAR0+0x0010*((n)-1))
+#define MGC_O_QMU_RQCPR(n) (MGC_O_QMU_RQCPR0+0x0010*((n)-1))
+
+#define MGC_O_QMU_RQTR_BASE 0x0090
+#define MGC_O_QMU_RQTR(n) (MGC_O_QMU_RQTR_BASE+0x4*((n)-1))
+#define MGC_O_QMU_RQLDPR0 0x0100
+#define MGC_O_QMU_RQLDPR(n) (MGC_O_QMU_RQLDPR0+0x4*((n)-1))
+
+#define MGC_O_QMU_TQCSR0 0x0200
+#define MGC_O_QMU_TQSAR0 0x0204
+#define MGC_O_QMU_TQCPR0 0x0208
+#define MGC_O_QMU_TQCSR(n) (MGC_O_QMU_TQCSR0+0x0010*((n)-1))
+#define MGC_O_QMU_TQSAR(n) (MGC_O_QMU_TQSAR0+0x0010*((n)-1))
+#define MGC_O_QMU_TQCPR(n) (MGC_O_QMU_TQCPR0+0x0010*((n)-1))
+
+#define MGC_O_QMU_QAR 0x0300
+#define MGC_O_QUCS_USBGCSR 0x0000
+#define MGC_O_QIRQ_QISAR 0x0000
+#define MGC_O_QIRQ_QIMR 0x0004
+#define MGC_O_QIRQ_QIMCR 0x0008
+#define MGC_O_QIRQ_QIMSR 0x000C
+#define MGC_O_QIRQ_IOCDISR 0x0030
+#define MGC_O_QIRQ_TEPEMPR 0x0060
+#define MGC_O_QIRQ_TEPEMPMR 0x0064
+#define MGC_O_QIRQ_TEPEMPMCR 0x0068
+#define MGC_O_QIRQ_TEPEMPMSR 0x006C
+#define MGC_O_QIRQ_REPEMPR 0x0070
+#define MGC_O_QIRQ_REPEMPMR 0x0074
+#define MGC_O_QIRQ_REPEMPMCR 0x0078
+#define MGC_O_QIRQ_REPEMPMSR 0x007C
+
+#define MGC_O_QIRQ_RQEIR 0x0090
+#define MGC_O_QIRQ_RQEIMR 0x0094
+#define MGC_O_QIRQ_RQEIMCR 0x0098
+#define MGC_O_QIRQ_RQEIMSR 0x009C
+#define MGC_O_QIRQ_REPEIR 0x00A0
+#define MGC_O_QIRQ_REPEIMR 0x00A4
+#define MGC_O_QIRQ_REPEIMCR 0x00A8
+#define MGC_O_QIRQ_REPEIMSR 0x00AC
+#define MGC_O_QIRQ_TQEIR 0x00B0
+#define MGC_O_QIRQ_TQEIMR 0x00B4
+#define MGC_O_QIRQ_TQEIMCR 0x00B8
+#define MGC_O_QIRQ_TQEIMSR 0x00BC
+#define MGC_O_QIRQ_TEPEIR 0x00C0
+#define MGC_O_QIRQ_TEPEIMR 0x00C4
+#define MGC_O_QIRQ_TEPEIMCR 0x00C8
+#define MGC_O_QIRQ_TEPEIMSR 0x00CC
+
+#define MGC_O_QDBG_DFCR 0x0000
+#define MGC_O_QDBG_DFMR 0x0004
+
+/* brief Queue Control value Definition */
+#define DQMU_QUE_START 0x00000001
+#define DQMU_QUE_RESUME 0x00000002
+#define DQMU_QUE_STOP 0x00000004
+#define DQMU_QUE_ACTIVE 0x00008000
+
+/*brief USB QMU Special Control USBGCSR value Definition*/
+#define USB_QMU_Tx0_EN 0x00000001
+#define USB_QMU_Tx_EN(n) (USB_QMU_Tx0_EN<<((n)-1))
+#define USB_QMU_Rx0_EN 0x00010000
+#define USB_QMU_Rx_EN(n) (USB_QMU_Rx0_EN<<((n)-1))
+#define USB_QMU_HIFEVT_EN 0x00000100
+#define USB_QMU_HIFCMD_EN 0x01000000
+#define DQMU_SW_RESET 0x00010000
+#define DQMU_CS16B_EN 0x80000000
+#define DQMU_TQ0CS_EN 0x00010000
+#define DQMU_TQCS_EN(n) (DQMU_TQ0CS_EN<<((n)-1))
+#define DQMU_RQ0CS_EN 0x00000001
+#define DQMU_RQCS_EN(n) (DQMU_RQ0CS_EN<<((n)-1))
+#define DQMU_TX0_ZLP 0x01000000
+#define DQMU_TX_ZLP(n) (DQMU_TX0_ZLP<<((n)-1))
+#define DQMU_TX0_MULTIPLE 0x00010000
+#define DQMU_TX_MULTIPLE(n) (DQMU_TX0_MULTIPLE<<((n)-1))
+#define DQMU_RX0_MULTIPLE 0x00010000
+#define DQMU_RX_MULTIPLE(n) (DQMU_RX0_MULTIPLE<<((n)-1))
+#define DQMU_RX0_ZLP 0x01000000
+#define DQMU_RX_ZLP(n) (DQMU_RX0_ZLP<<((n)-1))
+#define DQMU_RX0_COZ 0x00000100
+#define DQMU_RX_COZ(n) (DQMU_RX0_COZ<<((n)-1))
+
+#define DQMU_M_TXEP_ERR 0x10000000
+#define DQMU_M_TXQ_ERR 0x08000000
+#define DQMU_M_RXEP_ERR 0x04000000
+#define DQMU_M_RXQ_ERR 0x02000000
+#define DQMU_M_RQ_EMPTY 0x00020000
+#define DQMU_M_TQ_EMPTY 0x00010000
+#define DQMU_M_RX0_EMPTY 0x00000001
+#define DQMU_M_RX_EMPTY(n) (DQMU_M_RX0_EMPTY<<((n)-1))
+#define DQMU_M_TX0_EMPTY 0x00000001
+#define DQMU_M_TX_EMPTY(n) (DQMU_M_TX0_EMPTY<<((n)-1))
+#define DQMU_M_RX0_DONE 0x00000100
+#define DQMU_M_RX_DONE(n) (DQMU_M_RX0_DONE<<((n)-1))
+#define DQMU_M_TX0_DONE 0x00000001
+#define DQMU_M_TX_DONE(n) (DQMU_M_TX0_DONE<<((n)-1))
+
+#define DQMU_M_RX0_ZLP_ERR 0x01000000
+#define DQMU_M_RX_ZLP_ERR(n) (DQMU_M_RX0_ZLP_ERR<<((n)-1))
+#define DQMU_M_RX0_LEN_ERR 0x00000100
+#define DQMU_M_RX_LEN_ERR(n) (DQMU_M_RX0_LEN_ERR<<((n)-1))
+#define DQMU_M_RX0_GPDCS_ERR 0x00000001
+#define DQMU_M_RX_GPDCS_ERR(n) (DQMU_M_RX0_GPDCS_ERR<<((n)-1))
+
+#define DQMU_M_TX0_LEN_ERR 0x00010000
+#define DQMU_M_TX_LEN_ERR(n) (DQMU_M_TX0_LEN_ERR<<((n)-1))
+#define DQMU_M_TX0_GPDCS_ERR 0x00000100
+#define DQMU_M_TX_GPDCS_ERR(n) (DQMU_M_TX0_GPDCS_ERR<<((n)-1))
+#define DQMU_M_TX0_BDCS_ERR 0x00000001
+#define DQMU_M_TX_BDCS_ERR(n) (DQMU_M_TX0_BDCS_ERR<<((n)-1))
+
+#define DQMU_M_TX0_EP_ERR 0x00000001
+#define DQMU_M_TX_EP_ERR(n) (DQMU_M_TX0_EP_ERR<<((n)-1))
+
+#define DQMU_M_RX0_EP_ERR 0x00000001
+#define DQMU_M_RX_EP_ERR(n) (DQMU_M_RX0_EP_ERR<<((n)-1))
+#define DQMU_M_RQ_DIS_IOC(n) (0x100<<((n)-1))
+
+#define MGC_ReadQMU8(base,_offset) \
+ musb_readb(base, (USB_HW_QMU_OFF + _offset))
+
+#define MGC_ReadQUCS8(base,_offset) \
+ musb_readb(base, (USB_HW_QUCS_OFF + _offset))
+
+#define MGC_ReadQIRQ8(base,_offset) \
+ musb_readb(base, (USB_HW_QIRQ_OFF + _offset))
+
+#define MGC_ReadQMU16(base,_offset) \
+ musb_readw(base, (USB_HW_QMU_OFF + _offset))
+
+#define MGC_ReadQUCS16(base,_offset) \
+ musb_readw(base,(USB_HW_QUCS_OFF + _offset))
+
+#define MGC_ReadQIRQ16(base,_offset) \
+ musb_readw(base, (USB_HW_QIRQ_OFF + _offset))
+#define MGC_ReadQMU32(base,_offset) \
+ musb_readl(base, (USB_HW_QMU_OFF + _offset))
+
+#define MGC_ReadQUCS32(base,_offset) \
+ musb_readl(base, (USB_HW_QUCS_OFF + _offset))
+
+#define MGC_ReadQIRQ32(base,_offset) \
+ musb_readl(base, (USB_HW_QIRQ_OFF + _offset))
+
+#define MGC_WriteQMU32(base,_offset, _data) \
+ musb_writel(base, (USB_HW_QMU_OFF + _offset), _data)
+
+#define MGC_WriteQUCS32(base,_offset, _data) \
+ musb_writel(base, (USB_HW_QUCS_OFF + _offset), _data)
+
+#define MGC_WriteQIRQ32(base,_offset, _data) \
+ musb_writel(base,(USB_HW_QIRQ_OFF + _offset), _data)
+
+u8 PDU_calcCksum(u8 *data, int len);
+
+/* brief Define DMAQ GPD format */
+#define TGPD_FLAGS_HWO 0x01
+#define TGPD_IS_FLAGS_HWO(_pd) (((TGPD *)_pd)->flag & TGPD_FLAGS_HWO)
+#define TGPD_SET_FLAGS_HWO(_pd) (((TGPD *)_pd)->flag |= TGPD_FLAGS_HWO)
+#define TGPD_CLR_FLAGS_HWO(_pd) (((TGPD *)_pd)->flag &= (~TGPD_FLAGS_HWO))
+#define TGPD_FORMAT_BDP 0x02
+#define TGPD_IS_FORMAT_BDP(_pd) (((TGPD *)_pd)->flag & TGPD_FORMAT_BDP)
+#define TGPD_SET_FORMAT_BDP(_pd) (((TGPD *)_pd)->flag |= TGPD_FORMAT_BDP)
+#define TGPD_CLR_FORMAT_BDP(_pd) (((TGPD *)_pd)->flag &= (~TGPD_FORMAT_BDP))
+
+#define TGPD_SET_FLAG(_pd, _flag) ((TGPD *)_pd)->flag = (((TGPD *)_pd)->flag&(~TGPD_FLAGS_HWO))|(_flag)
+#define TGPD_GET_FLAG(_pd) (((TGPD *)_pd)->flag & TGPD_FLAGS_HWO)
+#define TGPD_SET_CHKSUM(_pd, _n) ((TGPD *)_pd)->chksum = PDU_calcCksum((u8 *)_pd, _n)
+#define TGPD_SET_CHKSUM_HWO(_pd, _n) ((TGPD *)_pd)->chksum = PDU_calcCksum((u8 *)_pd, _n)-1
+#define TGPD_GET_CHKSUM(_pd) ((TGPD *)_pd)->chksum
+#define TGPD_SET_FORMAT(_pd, _fmt) ((TGPD *)_pd)->flag = (((TGPD *)_pd)->flag&(~TGPD_FORMAT_BDP))|(_fmt)
+#define TGPD_GET_FORMAT(_pd) ((((TGPD *)_pd)->flag & TGPD_FORMAT_BDP)>>1)
+#define TGPD_SET_DataBUF_LEN(_pd, _len) ((TGPD *)_pd)->DataBufferLen = _len
+#define TGPD_ADD_DataBUF_LEN(_pd, _len) ((TGPD *)_pd)->DataBufferLen += _len
+#define TGPD_GET_DataBUF_LEN(_pd) ((TGPD *)_pd)->DataBufferLen
+#define TGPD_SET_NEXT(_pd, _next) ((TGPD *)_pd)->pNext = (u32)(unsigned long)((TGPD *)_next)
+#define TGPD_GET_NEXT(_pd) (TGPD *)(unsigned long)((TGPD *)_pd)->pNext
+
+#define TGPD_SET_DATA(_pd, _data) ((TGPD *)_pd)->pBuf = (u32)(unsigned long)_data
+#define TGPD_GET_DATA(_pd) (u8 *)(unsigned long)((TGPD *)_pd)->pBuf
+#define TGPD_SET_BUF_LEN(_pd, _len) ((TGPD *)_pd)->bufLen = _len
+#define TGPD_ADD_BUF_LEN(_pd, _len) ((TGPD *)_pd)->bufLen += _len
+#define TGPD_GET_BUF_LEN(_pd) ((TGPD *)_pd)->bufLen
+#define TGPD_SET_EXT_LEN(_pd, _len) ((TGPD *)_pd)->ExtLength = _len
+#define TGPD_GET_EXT_LEN(_pd) ((TGPD *)_pd)->ExtLength
+#define TGPD_SET_EPaddr(_pd, _EP) ((TGPD *)_pd)->ZTepFlag =(((TGPD *)_pd)->ZTepFlag&0xF0)|(_EP)
+#define TGPD_GET_EPaddr(_pd) ((TGPD *)_pd)->ZTepFlag & 0x0F
+
+#define TGPD_FORMAT_TGL 0x10
+#define TGPD_IS_FORMAT_TGL(_pd) (((TGPD *)_pd)->ZTepFlag & TGPD_FORMAT_TGL)
+#define TGPD_SET_FORMAT_TGL(_pd) (((TGPD *)_pd)->ZTepFlag |=TGPD_FORMAT_TGL)
+#define TGPD_CLR_FORMAT_TGL(_pd) (((TGPD *)_pd)->ZTepFlag &= (~TGPD_FORMAT_TGL))
+#define TGPD_FORMAT_ZLP 0x20
+#define TGPD_IS_FORMAT_ZLP(_pd) (((TGPD *)_pd)->ZTepFlag & TGPD_FORMAT_ZLP)
+#define TGPD_SET_FORMAT_ZLP(_pd) (((TGPD *)_pd)->ZTepFlag |=TGPD_FORMAT_ZLP)
+#define TGPD_CLR_FORMAT_ZLP(_pd) (((TGPD *)_pd)->ZTepFlag &= (~TGPD_FORMAT_ZLP))
+
+#define TGPD_SET_TGL(_pd, _TGL) ((TGPD *)_pd)->ZTepFlag |=(( _TGL) ? 0x10: 0x00)
+#define TGPD_GET_TGL(_pd) ((TGPD *)_pd)->ZTepFlag & 0x10 ? 1:0
+#define TGPD_SET_ZLP(_pd, _ZLP) ((TGPD *)_pd)->ZTepFlag |= ((_ZLP) ? 0x20: 0x00)
+#define TGPD_GET_ZLP(_pd) ((TGPD *)_pd)->ZTepFlag & 0x20 ? 1:0
+
+#define TGPD_FLAG_IOC 0x80
+#define TGPD_SET_IOC(_pd) (((TGPD *)_pd)->flag |= TGPD_FLAG_IOC)
+
+extern void qmu_destroy_gpd_pool(struct device *dev);
+extern int qmu_init_gpd_pool(struct device *dev);
+extern void qmu_reset_gpd_pool(u32 ep_num, u8 isRx);
+extern bool mtk_is_qmu_enabled(u8 EP_Num, u8 isRx);
+extern void mtk_qmu_enable(struct musb *musb, u8 EP_Num, u8 isRx);
+extern void mtk_qmu_insert_task(u8 EP_Num, u8 isRx, u8* buf, u32 length, u8 zlp);
+extern void mtk_qmu_resume(u8 EP_Num, u8 isRx);
+extern void qmu_done_rx(struct musb *musb, u8 ep_num);
+extern void qmu_done_tx(struct musb *musb, u8 ep_num);
+extern void mtk_disable_q(struct musb *musb, u8 ep_num, u8 isRx);
+extern void mtk_qmu_irq_err(struct musb *musb, u32 qisar);
+extern void flush_ep_csr(struct musb *musb, u8 ep_num, u8 isRx);
+extern void mtk_qmu_stop(u8 ep_num, u8 isRx);
+
+#endif
+#endif
diff --git a/include/linux/musb/musb.h b/include/linux/musb/musb.h
new file mode 100644
index 000000000..e9234567b
--- /dev/null
+++ b/include/linux/musb/musb.h
@@ -0,0 +1,132 @@
+/*
+ * This is used to for host and peripheral modes of the driver for
+ * Inventra (Multidrop) Highspeed Dual-Role Controllers: (M)HDRC.
+ *
+ * Board initialization should put one of these into dev->platform_data,
+ * probably on some platform_device named "musb-hdrc". It encapsulates
+ * key configuration differences between boards.
+ */
+
+#ifndef __LINUX_USB_MUSB_H
+#define __LINUX_USB_MUSB_H
+
+/* The USB role is defined by the connector used on the board, so long as
+ * standards are being followed. (Developer boards sometimes won't.)
+ */
+enum musb_mode {
+ MUSB_UNDEFINED = 0,
+ MUSB_HOST, /* A or Mini-A connector */
+ MUSB_PERIPHERAL, /* B or Mini-B connector */
+ MUSB_OTG /* Mini-AB connector */
+};
+
+struct clk;
+
+enum musb_fifo_style {
+ MUSB_FIFO_RXTX, /* add MUSB_ prefix to avoid confilicts with musbfsh.h, gang */
+ MUSB_FIFO_TX,
+ MUSB_FIFO_RX
+} __attribute__ ((packed));
+
+enum musb_buf_mode {
+ MUSB_BUF_SINGLE, /* add MUSB_ prefix to avoid confilicts with musbfsh.h, gang */
+ MUSB_BUF_DOUBLE
+} __attribute__ ((packed));
+
+enum musb_ep_mode {
+ EP_CONT,
+ EP_INT,
+ EP_BULK,
+ EP_ISO
+} __attribute__ ((packed));
+
+struct musb_fifo_cfg {
+ u8 hw_ep_num;
+ enum musb_fifo_style style;
+ enum musb_buf_mode mode;
+ u16 maxpacket;
+ enum musb_ep_mode ep_mode;
+};
+
+#define MUSB_EP_FIFO(ep, st, m, pkt) \
+{ \
+ .hw_ep_num = ep, \
+ .style = st, \
+ .mode = m, \
+ .maxpacket = pkt, \
+}
+
+#define MUSB_EP_FIFO_SINGLE(ep, st, pkt) \
+ MUSB_EP_FIFO(ep, st, BUF_SINGLE, pkt)
+
+#define MUSB_EP_FIFO_DOUBLE(ep, st, pkt) \
+ MUSB_EP_FIFO(ep, st, BUF_DOUBLE, pkt)
+
+struct musb_hdrc_eps_bits {
+ const char name[16];
+ u8 bits;
+};
+
+struct musb_hdrc_config {
+ struct musb_fifo_cfg *fifo_cfg; /* board fifo configuration */
+ unsigned fifo_cfg_size; /* size of the fifo configuration */
+
+ /* MUSB configuration-specific details */
+ unsigned multipoint:1; /* multipoint device */
+ unsigned dyn_fifo:1 __deprecated; /* supports dynamic fifo sizing */
+ unsigned soft_con:1 __deprecated; /* soft connect required */
+ unsigned utm_16:1 __deprecated; /* utm data witdh is 16 bits */
+ unsigned big_endian:1; /* true if CPU uses big-endian */
+ unsigned mult_bulk_tx:1; /* Tx ep required for multbulk pkts */
+ unsigned mult_bulk_rx:1; /* Rx ep required for multbulk pkts */
+ unsigned high_iso_tx:1; /* Tx ep required for HB iso */
+ unsigned high_iso_rx:1; /* Rx ep required for HD iso */
+ unsigned dma:1 __deprecated; /* supports DMA */
+ unsigned vendor_req:1 __deprecated; /* vendor registers required */
+
+ u8 num_eps; /* number of endpoints _with_ ep0 */
+ u8 dma_channels __deprecated; /* number of dma channels */
+ u8 dyn_fifo_size; /* dynamic size in bytes */
+ u8 vendor_ctrl __deprecated; /* vendor control reg width */
+ u8 vendor_stat __deprecated; /* vendor status reg witdh */
+ u8 dma_req_chan __deprecated; /* bitmask for required dma channels */
+ u8 ram_bits; /* ram address size */
+
+ struct musb_hdrc_eps_bits *eps_bits __deprecated;
+};
+
+struct musb_hdrc_platform_data {
+ /* MUSB_HOST, MUSB_PERIPHERAL, or MUSB_OTG */
+ u8 mode;
+
+ /* for clk_get() */
+ const char *clock;
+
+ /* (HOST or OTG) switch VBUS on/off */
+ int (*set_vbus) (struct device *dev, int is_on);
+
+ /* (HOST or OTG) mA/2 power supplied on (default = 8mA) */
+ u8 power;
+
+ /* (PERIPHERAL) mA/2 max power consumed (default = 100mA) */
+ u8 min_power;
+
+ /* (HOST or OTG) msec/2 after VBUS on till power good */
+ u8 potpgt;
+
+ /* (HOST or OTG) program PHY for external Vbus */
+ unsigned extvbus:1;
+
+ /* Power the device on or off */
+ int (*set_power) (int state);
+
+ /* MUSB configuration-specific details */
+ struct musb_hdrc_config *config;
+
+ /* Architecture specific board data */
+ void *board_data;
+
+ /* Platform specific struct musb_ops pointer */
+ const void *platform_ops;
+};
+#endif /* __LINUX_USB_MUSB_H */
diff --git a/include/linux/musb/musb_core.h b/include/linux/musb/musb_core.h
new file mode 100644
index 000000000..88d719f63
--- /dev/null
+++ b/include/linux/musb/musb_core.h
@@ -0,0 +1,601 @@
+/*
+ * MUSB OTG driver defines
+ *
+ * Copyright 2005 Mentor Graphics Corporation
+ * Copyright (C) 2005-2006 by Texas Instruments
+ * Copyright (C) 2006-2007 Nokia Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __MUSB_CORE_H__
+#define __MUSB_CORE_H__
+
+#include <linux/slab.h>
+#include <linux/list.h>
+#include <linux/interrupt.h>
+#include <linux/errno.h>
+#include <linux/timer.h>
+#include <linux/device.h>
+#include <linux/usb/ch9.h>
+#include <linux/usb/gadget.h>
+#include <linux/usb.h>
+#include <linux/usb/otg.h>
+#include <linux/musb/musb.h>
+#include <linux/wakelock.h>
+#include <linux/version.h>
+#include <mach/mt_typedefs.h>
+
+#ifdef MUSB_QMU_SUPPORT
+#include "mtk_qmu.h"
+#endif
+
+#define SHARE_IRQ -1
+
+struct musb;
+struct musb_hw_ep;
+struct musb_ep;
+extern volatile bool usb_is_host;
+
+/* Helper defines for struct musb->hwvers */
+#define MUSB_HWVERS_MAJOR(x) ((x >> 10) & 0x1f)
+#define MUSB_HWVERS_MINOR(x) (x & 0x3ff)
+#define MUSB_HWVERS_RC 0x8000
+#define MUSB_HWVERS_1300 0x52C
+#define MUSB_HWVERS_1400 0x590
+#define MUSB_HWVERS_1800 0x720
+#define MUSB_HWVERS_1900 0x784
+#define MUSB_HWVERS_2000 0x800
+#define MUSB_HUB_SUPPORT 0x4000
+#include "mtk_musb.h"
+
+#include "musb_debug.h"
+#include "musb_dma.h"
+
+#include "musb_io.h"
+#include <mach/mt_musb_reg.h>
+
+#include "musb_gadget.h"
+#include <linux/usb/hcd.h>
+#include "musb_host.h"
+#ifdef CONFIG_OF
+
+enum {
+ usb0 = 0,
+ usb_sif,
+ usb_acm_temp_device,
+};
+#endif
+
+
+#ifdef ENABLE_STORAGE_LOGGER
+#define USB_LOGGER(msg_id, func_name, ...) \
+ do { \
+ if (unlikely(is_dump_musb())) { \
+ ADD_USB_TRACE(msg_id, func_name, __VA_ARGS__); \
+ } \
+ } while (0)
+#else
+#define USB_LOGGER(msg_id, func_name, args...) do {} while (0)
+#endif
+
+/* NOTE: otg and peripheral-only state machines start at B_IDLE.
+ * OTG or host-only go to A_IDLE when ID is sensed.
+ */
+#define is_peripheral_active(m) (!(m)->is_host)
+#define is_host_active(m) ((m)->is_host)
+
+#ifdef CONFIG_PROC_FS
+#include <linux/fs.h>
+#define MUSB_CONFIG_PROC_FS
+#endif
+
+/****************************** PERIPHERAL ROLE *****************************/
+
+extern irqreturn_t musb_g_ep0_irq(struct musb *);
+extern void musb_g_tx(struct musb *, u8);
+extern void musb_g_rx(struct musb *, u8);
+extern void musb_g_reset(struct musb *);
+extern void musb_g_suspend(struct musb *);
+extern void musb_g_resume(struct musb *);
+extern void musb_g_wakeup(struct musb *);
+extern void musb_g_disconnect(struct musb *);
+
+/****************************** HOST ROLE ***********************************/
+extern irqreturn_t musb_h_ep0_irq(struct musb *);
+extern void musb_host_tx(struct musb *, u8);
+extern void musb_host_rx(struct musb *, u8);
+
+/****************************** CONSTANTS ********************************/
+
+#ifndef MUSB_C_NUM_EPS
+#define MUSB_C_NUM_EPS ((u8)16)
+#endif
+
+#ifndef MUSB_MAX_END0_PACKET
+#define MUSB_MAX_END0_PACKET ((u16)MUSB_EP0_FIFOSIZE)
+#endif
+
+/* host side ep0 states */
+enum musb_h_ep0_state {
+ MUSB_EP0_IDLE,
+ MUSB_EP0_START, /* expect ack of setup */
+ MUSB_EP0_IN, /* expect IN DATA */
+ MUSB_EP0_OUT, /* expect ack of OUT DATA */
+ MUSB_EP0_STATUS, /* expect ack of STATUS */
+} __attribute__ ((packed));
+
+/* peripheral side ep0 states */
+enum musb_g_ep0_state {
+ MUSB_EP0_STAGE_IDLE, /* idle, waiting for SETUP */
+ MUSB_EP0_STAGE_SETUP, /* received SETUP */
+ MUSB_EP0_STAGE_TX, /* IN data */
+ MUSB_EP0_STAGE_RX, /* OUT data */
+ MUSB_EP0_STAGE_STATUSIN, /* (after OUT data) */
+ MUSB_EP0_STAGE_STATUSOUT, /* (after IN data) */
+ MUSB_EP0_STAGE_ACKWAIT, /* after zlp, before statusin */
+} __attribute__ ((packed));
+
+/*
+ * OTG protocol constants. See USB OTG 1.3 spec,
+ * sections 5.5 "Device Timings" and 6.6.5 "Timers".
+ */
+#define OTG_TIME_A_WAIT_VRISE 100 /* msec (max) */
+#define OTG_TIME_A_WAIT_BCON 1100 /* min 1 second */
+#define OTG_TIME_A_AIDL_BDIS 200 /* min 200 msec */
+#if defined(CONFIG_USBIF_COMPLIANCE)
+#define OTG_TIME_B_ASE0_BRST 155 /* min 3.125 ms */
+#else
+#define OTG_TIME_B_ASE0_BRST 100 /* min 3.125 ms */
+#endif
+
+
+
+/*************************** REGISTER ACCESS ********************************/
+
+#define musb_ep_select(_mbase, _epnum) \
+ musb_writeb((_mbase), MUSB_INDEX, (_epnum))
+#define MUSB_EP_OFFSET MUSB_INDEXED_OFFSET
+
+/****************************** FUNCTIONS ********************************/
+
+#define MUSB_HST_MODE(_musb)\
+ { (_musb)->is_host = true; }
+#define MUSB_DEV_MODE(_musb) \
+ { (_musb)->is_host = false; }
+
+#define test_devctl_hst_mode(_x) \
+ (musb_readb((_x)->mregs, MUSB_DEVCTL)&MUSB_DEVCTL_HM)
+
+#define MUSB_MODE(musb) ((musb)->is_host ? "Host" : "Peripheral")
+
+typedef enum {
+ funcWriteb = 0,
+ funcWritew,
+ funcWritel,
+ funcInterrupt
+} writeFunc_enum;
+
+void dumpTime(writeFunc_enum func, int epnum);
+
+/******************************** TYPES *************************************/
+
+/**
+ * struct musb_platform_ops - Operations passed to musb_core by HW glue layer
+ * @init: turns on clocks, sets up platform-specific registers, etc
+ * @exit: undoes @init
+ * @set_mode: forcefully changes operating mode
+ * @try_ilde: tries to idle the IP
+ * @vbus_status: returns vbus status if possible
+ * @set_vbus: forces vbus status
+ * @adjust_channel_params: pre check for standard dma channel_program func
+ */
+struct musb_platform_ops {
+ int (*init) (struct musb *musb);
+ int (*exit) (struct musb *musb);
+
+ void (*enable) (struct musb *musb);
+ void (*disable) (struct musb *musb);
+
+ int (*set_mode) (struct musb *musb, u8 mode);
+ void (*try_idle) (struct musb *musb, unsigned long timeout);
+
+ int (*vbus_status) (struct musb *musb);
+ void (*set_vbus) (struct musb *musb, int on);
+
+ int (*adjust_channel_params) (struct dma_channel *channel,
+ u16 packet_sz, u8 *mode, dma_addr_t *dma_addr, u32 *len);
+};
+
+/*
+ * struct musb_hw_ep - endpoint hardware (bidirectional)
+ *
+ * Ordered slightly for better cacheline locality.
+ */
+struct musb_hw_ep {
+ struct musb *musb;
+ void __iomem *fifo;
+ void __iomem *regs;
+
+ /* index in musb->endpoints[] */
+ u8 epnum;
+ enum musb_ep_mode ep_mode;
+
+ /* hardware configuration, possibly dynamic */
+ bool is_shared_fifo;
+ bool tx_double_buffered;
+ bool rx_double_buffered;
+ u16 max_packet_sz_tx;
+ u16 max_packet_sz_rx;
+
+ struct dma_channel *tx_channel;
+ struct dma_channel *rx_channel;
+
+ void __iomem *target_regs;
+
+ /* currently scheduled peripheral endpoint */
+ struct musb_qh *in_qh;
+ struct musb_qh *out_qh;
+
+ u8 rx_reinit;
+ u8 tx_reinit;
+
+ /* peripheral side */
+ struct musb_ep ep_in; /* TX */
+ struct musb_ep ep_out; /* RX */
+};
+
+static inline struct musb_request *next_in_request(struct musb_hw_ep *hw_ep)
+{
+ return next_request(&hw_ep->ep_in);
+}
+
+static inline struct musb_request *next_out_request(struct musb_hw_ep *hw_ep)
+{
+ return next_request(&hw_ep->ep_out);
+}
+
+struct musb_csr_regs {
+ /* FIFO registers */
+ u16 txmaxp, txcsr, rxmaxp, rxcsr;
+ u16 rxfifoadd, txfifoadd;
+ u8 txtype, txinterval, rxtype, rxinterval;
+ u8 rxfifosz, txfifosz;
+ u8 txfunaddr, txhubaddr, txhubport;
+ u8 rxfunaddr, rxhubaddr, rxhubport;
+};
+
+struct musb_context_registers {
+
+ u8 power;
+ u8 intrusbe;
+ u16 frame;
+ u8 index, testmode;
+
+ u8 devctl, busctl, misc;
+ u32 otg_interfsel;
+ u32 l1_int;
+
+ struct musb_csr_regs index_regs[MUSB_C_NUM_EPS];
+};
+
+/*
+ * struct musb - Driver instance data.
+ */
+struct musb {
+ struct semaphore musb_lock;
+ /* device lock */
+ spinlock_t lock;
+
+ const struct musb_platform_ops *ops;
+ struct musb_context_registers context;
+
+ irqreturn_t(*isr) (int, void *);
+ struct work_struct irq_work;
+ struct work_struct otg_notifier_work;
+ u16 hwvers;
+ struct delayed_work id_pin_work;
+
+ struct musb_fifo_cfg *fifo_cfg;
+ unsigned fifo_cfg_size;
+ struct musb_fifo_cfg *fifo_cfg_host;
+ unsigned fifo_cfg_host_size;
+ u32 fifo_size;
+
+ u16 intrrxe;
+ u16 intrtxe;
+/* this hub status bit is reserved by USB 2.0 and not seen by usbcore */
+#define MUSB_PORT_STAT_RESUME (1 << 31)
+
+ u32 port1_status;
+
+ unsigned long rh_timer;
+
+ enum musb_h_ep0_state ep0_stage;
+
+ /* bulk traffic normally dedicates endpoint hardware, and each
+ * direction has its own ring of host side endpoints.
+ * we try to progress the transfer at the head of each endpoint's
+ * queue until it completes or NAKs too much; then we try the next
+ * endpoint.
+ */
+ struct musb_hw_ep *bulk_ep;
+
+ struct list_head control; /* of musb_qh */
+ struct list_head in_bulk; /* of musb_qh */
+ struct list_head out_bulk; /* of musb_qh */
+
+ struct timer_list otg_timer;
+#if defined(CONFIG_USBIF_COMPLIANCE)
+ struct timer_list otg_vbus_polling_timer;
+#endif
+ struct notifier_block nb;
+
+ struct dma_controller *dma_controller;
+
+ struct device *controller;
+ void __iomem *ctrl_base;
+ void __iomem *mregs;
+
+ /* passed down from chip/board specific irq handlers */
+ u8 int_usb;
+ u16 int_rx;
+ u16 int_tx;
+
+#ifdef MUSB_QMU_SUPPORT
+ u32 int_queue;
+#ifdef QMU_TASKLET
+ u32 qmu_done_intr;
+ struct tasklet_struct qmu_done;
+#endif
+#endif
+
+ struct usb_phy *xceiv;
+ u8 xceiv_event;
+
+ int nIrq;
+ int dma_irq;
+ unsigned irq_wake:1;
+
+ struct musb_hw_ep endpoints[MUSB_C_NUM_EPS];
+#define control_ep endpoints
+
+#define VBUSERR_RETRY_COUNT 3
+ u16 vbuserr_retry;
+ u16 epmask;
+ u8 nr_endpoints;
+
+ int (*board_set_power) (int state);
+
+ u8 min_power; /* vbus for periph, in mA/2 */
+
+ bool is_host;
+ bool in_ipo_off;
+
+ int a_wait_bcon; /* VBUS timeout in msecs */
+ unsigned long idle_timeout; /* Next timeout in jiffies */
+
+ /* active means connected and not suspended */
+ unsigned is_active:1;
+
+ unsigned is_multipoint:1;
+ unsigned ignore_disconnect:1; /* during bus resets */
+
+ unsigned hb_iso_rx:1; /* high bandwidth iso rx? */
+ unsigned hb_iso_tx:1; /* high bandwidth iso tx? */
+ unsigned dyn_fifo:1; /* dynamic FIFO supported? */
+
+ unsigned bulk_split:1;
+#define can_bulk_split(musb, type) \
+ (((type) == USB_ENDPOINT_XFER_BULK) && (musb)->bulk_split)
+
+ unsigned bulk_combine:1;
+#define can_bulk_combine(musb, type) \
+ (((type) == USB_ENDPOINT_XFER_BULK) && (musb)->bulk_combine)
+
+ /* is_suspended means USB B_PERIPHERAL suspend */
+ unsigned is_suspended:1;
+
+ /* may_wakeup means remote wakeup is enabled */
+ unsigned may_wakeup:1;
+
+ /* is_self_powered is reported in device status and the
+ * config descriptor. is_bus_powered means B_PERIPHERAL
+ * draws some VBUS current; both can be true.
+ */
+ unsigned is_self_powered:1;
+ unsigned is_bus_powered:1;
+
+ unsigned set_address:1;
+ unsigned test_mode:1;
+ unsigned softconnect:1;
+
+ u8 address;
+ u8 test_mode_nr;
+ u16 ackpend; /* ep0 */
+ enum musb_g_ep0_state ep0_state;
+ struct usb_gadget g; /* the gadget */
+ struct usb_gadget_driver *gadget_driver; /* its driver */
+ struct wake_lock usb_lock;
+
+ /*
+ * FIXME: Remove this flag.
+ *
+ * This is only added to allow Blackfin to work
+ * with current driver. For some unknown reason
+ * Blackfin doesn't work with double buffering
+ * and that's enabled by default.
+ *
+ * We added this flag to forcefully disable double
+ * buffering until we get it working.
+ */
+ unsigned double_buffer_not_ok:1;
+
+ struct musb_hdrc_config *config;
+
+#ifdef MUSB_CONFIG_PROC_FS
+ struct proc_dir_entry *proc_entry;
+#endif
+ int xceiv_old_state;
+#ifdef CONFIG_DEBUG_FS
+ struct dentry *debugfs_root;
+#endif
+ bool power;
+ bool is_ready:1;
+ bool usb_if;
+ u16 fifo_addr;
+#if defined(CONFIG_USBIF_COMPLIANCE)
+ bool srp_drvvbus;
+ enum usb_otg_event otg_event;
+#endif
+};
+
+static inline struct musb *gadget_to_musb(struct usb_gadget *g)
+{
+ return container_of(g, struct musb, g);
+}
+
+static inline int musb_read_fifosize(struct musb *musb, struct musb_hw_ep *hw_ep, u8 epnum)
+{
+ void __iomem *mbase = musb->mregs;
+ u8 reg = 0;
+
+ /* read from core using indexed model */
+ reg = musb_readb(mbase, MUSB_EP_OFFSET(epnum, MUSB_FIFOSIZE));
+ /* 0's returned when no more endpoints */
+ if (!reg)
+ return -ENODEV;
+
+ musb->nr_endpoints++;
+ musb->epmask |= (1 << epnum);
+
+ hw_ep->max_packet_sz_tx = 1 << (reg & 0x0f);
+
+ /* shared TX/RX FIFO? */
+ if ((reg & 0xf0) == 0xf0) {
+ hw_ep->max_packet_sz_rx = hw_ep->max_packet_sz_tx;
+ hw_ep->is_shared_fifo = true;
+ return 0;
+ } else {
+ hw_ep->max_packet_sz_rx = 1 << ((reg & 0xf0) >> 4);
+ hw_ep->is_shared_fifo = false;
+ }
+
+ return 0;
+}
+
+static inline void musb_configure_ep0(struct musb *musb)
+{
+ musb->endpoints[0].max_packet_sz_tx = MUSB_EP0_FIFOSIZE;
+ musb->endpoints[0].max_packet_sz_rx = MUSB_EP0_FIFOSIZE;
+ musb->endpoints[0].is_shared_fifo = true;
+}
+
+
+/***************************** Glue it together *****************************/
+
+extern const char musb_driver_name[];
+
+extern void musb_start(struct musb *musb);
+extern void musb_stop(struct musb *musb);
+extern int musb_get_id(struct device *dev, gfp_t gfp_mask);
+extern void musb_put_id(struct device *dev, int id);
+
+extern void musb_write_fifo(struct musb_hw_ep *ep, u16 len, const u8 *src);
+extern void musb_read_fifo(struct musb_hw_ep *ep, u16 len, u8 *dst);
+
+extern void musb_load_testpacket(struct musb *);
+extern void musb_generic_disable(struct musb *);
+extern irqreturn_t musb_interrupt(struct musb *);
+extern irqreturn_t dma_controller_irq(int irq, void *private_data);
+
+extern void musb_hnp_stop(struct musb *musb);
+
+static inline void musb_platform_set_vbus(struct musb *musb, int is_on)
+{
+ if (musb->ops->set_vbus)
+ musb->ops->set_vbus(musb, is_on);
+}
+
+static inline void musb_platform_enable(struct musb *musb)
+{
+ if (musb->ops->enable)
+ musb->ops->enable(musb);
+}
+
+static inline void musb_platform_disable(struct musb *musb)
+{
+ if (musb->ops->disable)
+ musb->ops->disable(musb);
+}
+
+static inline int musb_platform_set_mode(struct musb *musb, u8 mode)
+{
+ if (!musb->ops->set_mode)
+ return 0;
+
+ return musb->ops->set_mode(musb, mode);
+}
+
+static inline void musb_platform_try_idle(struct musb *musb, unsigned long timeout)
+{
+ if (musb->ops->try_idle)
+ musb->ops->try_idle(musb, timeout);
+}
+
+static inline int musb_platform_get_vbus_status(struct musb *musb)
+{
+ if (!musb->ops->vbus_status)
+ return 0;
+
+ return musb->ops->vbus_status(musb);
+}
+
+static inline int musb_platform_init(struct musb *musb)
+{
+ if (!musb->ops->init)
+ return -EINVAL;
+
+ return musb->ops->init(musb);
+}
+
+static inline int musb_platform_exit(struct musb *musb)
+{
+ if (!musb->ops->exit)
+ return -EINVAL;
+
+ return musb->ops->exit(musb);
+}
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
+static inline const char *otg_state_string(enum usb_otg_state state)
+{
+ return usb_otg_state_string(state);
+}
+#endif
+
+#endif /* __MUSB_CORE_H__ */
diff --git a/include/linux/musb/musb_debug.h b/include/linux/musb/musb_debug.h
new file mode 100644
index 000000000..24c380603
--- /dev/null
+++ b/include/linux/musb/musb_debug.h
@@ -0,0 +1,100 @@
+/*
+ * MUSB OTG driver debug defines
+ *
+ * Copyright 2005 Mentor Graphics Corporation
+ * Copyright (C) 2005-2006 by Texas Instruments
+ * Copyright (C) 2006-2007 Nokia Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __MUSB_LINUX_DEBUG_H__
+#define __MUSB_LINUX_DEBUG_H__
+
+#define yprintk(facility, format, args...) \
+ do { printk(facility "%s %d: " format , \
+ __func__, __LINE__ , ## args); } while (0)
+
+/* workaroud for redefine warning in usb_dump.c */
+#ifdef WARNING
+#undef WARNING
+#endif
+
+#ifdef INFO
+#undef INFO
+#endif
+
+#ifdef ERR
+#undef ERR
+#endif
+
+#define WARNING(fmt, args...) yprintk(KERN_WARNING, fmt, ## args)
+#define INFO(fmt, args...) yprintk(KERN_INFO, fmt, ## args)
+#define ERR(fmt, args...) yprintk(KERN_ERR, fmt, ## args)
+
+#define xprintk(level, format, args...) do { \
+ if (_dbg_level(level)) { \
+ if (musb_uart_debug) {\
+ printk(KERN_EMERG "[MUSB]%s %d: " format , \
+ __func__, __LINE__ , ## args); \
+ } \
+ else{\
+ printk(KERN_DEBUG "[MUSB]%s %d: " format , \
+ __func__, __LINE__ , ## args); \
+ } \
+ } } while (0)
+
+extern unsigned musb_debug;
+extern unsigned musb_uart_debug;
+
+static inline int _dbg_level(unsigned level)
+{
+ return level <= musb_debug;
+}
+
+#ifdef DBG
+#undef DBG
+#endif
+#define DBG(level, fmt, args...) xprintk(level, fmt, ## args)
+
+/* extern const char *otg_state_string(struct musb *); */
+
+#ifdef CONFIG_USB_MTK_DEBUG_FS
+extern int musb_init_debugfs(struct musb *musb);
+extern void musb_exit_debugfs(struct musb *musb);
+#else
+static inline int musb_init_debugfs(struct musb *musb)
+{
+ return 0;
+}
+
+static inline void musb_exit_debugfs(struct musb *musb)
+{
+}
+#endif
+
+#endif /* __MUSB_LINUX_DEBUG_H__ */
diff --git a/include/linux/musb/musb_dma.h b/include/linux/musb/musb_dma.h
new file mode 100644
index 000000000..720341148
--- /dev/null
+++ b/include/linux/musb/musb_dma.h
@@ -0,0 +1,171 @@
+/*
+ * MUSB OTG driver DMA controller abstraction
+ *
+ * Copyright 2005 Mentor Graphics Corporation
+ * Copyright (C) 2005-2006 by Texas Instruments
+ * Copyright (C) 2006-2007 Nokia Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __MUSB_DMA_H__
+#define __MUSB_DMA_H__
+
+struct musb_hw_ep;
+
+/*
+ * DMA Controller Abstraction
+ *
+ * DMA Controllers are abstracted to allow use of a variety of different
+ * implementations of DMA, as allowed by the Inventra USB cores. On the
+ * host side, usbcore sets up the DMA mappings and flushes caches; on the
+ * peripheral side, the gadget controller driver does. Responsibilities
+ * of a DMA controller driver include:
+ *
+ * - Handling the details of moving multiple USB packets
+ * in cooperation with the Inventra USB core, including especially
+ * the correct RX side treatment of short packets and buffer-full
+ * states (both of which terminate transfers).
+ *
+ * - Knowing the correlation between dma channels and the
+ * Inventra core's local endpoint resources and data direction.
+ *
+ * - Maintaining a list of allocated/available channels.
+ *
+ * - Updating channel status on interrupts,
+ * whether shared with the Inventra core or separate.
+ */
+
+#define DMA_ADDR_INVALID (~(dma_addr_t)0)
+
+#ifndef CONFIG_MUSB_PIO_ONLY
+#define is_dma_capable() (1)
+#else
+#define is_dma_capable() (0)
+#endif
+
+/* Anomaly 05000456 - USB Receive Interrupt Is Not Generated in DMA Mode 1
+ * Only allow DMA mode 1 to be used when the USB will actually generate the
+ * interrupts we expect.
+ */
+/*
+ * DMA channel status ... updated by the dma controller driver whenever that
+ * status changes, and protected by the overall controller spinlock.
+ */
+enum dma_channel_status {
+ /* unallocated */
+ MUSB_DMA_STATUS_UNKNOWN,
+ /* allocated ... but not busy, no errors */
+ MUSB_DMA_STATUS_FREE,
+ /* busy ... transactions are active */
+ MUSB_DMA_STATUS_BUSY,
+ /* transaction(s) aborted due to ... dma or memory bus error */
+ MUSB_DMA_STATUS_BUS_ABORT,
+ /* transaction(s) aborted due to ... core error or USB fault */
+ MUSB_DMA_STATUS_CORE_ABORT
+};
+
+struct dma_controller;
+
+/**
+ * struct dma_channel - A DMA channel.
+ * @private_data: channel-private data
+ * @max_len: the maximum number of bytes the channel can move in one
+ * transaction (typically representing many USB maximum-sized packets)
+ * @actual_len: how many bytes have been transferred
+ * @prog_len: how many bytes have been programmed for transfer
+ * @status: current channel status (updated e.g. on interrupt)
+ * @desired_mode: true if mode 1 is desired; false if mode 0 is desired
+ *
+ * channels are associated with an endpoint for the duration of at least
+ * one usb transfer.
+ */
+struct dma_channel {
+ void *private_data;
+ /* FIXME not void* private_data, but a dma_controller * */
+ size_t max_len;
+ size_t actual_len;
+ size_t prog_len;
+ enum dma_channel_status status;
+ bool desired_mode;
+};
+
+/*
+ * dma_channel_status - return status of dma channel
+ * @c: the channel
+ *
+ * Returns the software's view of the channel status. If that status is BUSY
+ * then it's possible that the hardware has completed (or aborted) a transfer,
+ * so the driver needs to update that status.
+ */
+static inline enum dma_channel_status dma_channel_status(struct dma_channel *c)
+{
+ return (is_dma_capable() && c) ? c->status : MUSB_DMA_STATUS_UNKNOWN;
+}
+
+/**
+ * struct dma_controller - A DMA Controller.
+ * @start: call this to start a DMA controller;
+ * return 0 on success, else negative errno
+ * @stop: call this to stop a DMA controller
+ * return 0 on success, else negative errno
+ * @channel_alloc: call this to allocate a DMA channel
+ * @channel_release: call this to release a DMA channel
+ * @channel_abort: call this to abort a pending DMA transaction,
+ * returning it to FREE (but allocated) state
+ * @channel_pause: This function pauses the ongoing DMA transfer
+ * @channel_resume: This function resumes the ongoing DMA transfer
+ * @tx_status: Gets the residue of an ongoing DMA transfer
+ * @check_resiudue: checks if the residue of an ongoing DMA
+ * transfer is valid
+ * Controllers manage dma channels.
+ */
+struct dma_controller {
+ int (*start) (struct dma_controller *);
+ int (*stop) (struct dma_controller *);
+ struct dma_channel *(*channel_alloc) (struct dma_controller *,
+ struct musb_hw_ep *, u8 is_tx);
+ void (*channel_release) (struct dma_channel *);
+ int (*channel_program) (struct dma_channel *channel,
+ u16 maxpacket, u8 mode, dma_addr_t dma_addr, u32 length);
+ int (*channel_abort) (struct dma_channel *);
+ int (*channel_pause) (struct dma_channel *);
+ int (*channel_resume) (struct dma_channel *);
+ int (*tx_status) (struct dma_channel *);
+ int (*check_residue) (struct dma_channel *, u32 residue);
+ int (*is_compatible) (struct dma_channel *channel, u16 maxpacket, void *buf, u32 length);
+};
+
+/* called after channel_program(), may indicate a fault */
+extern void musb_dma_completion(struct musb *musb, u8 epnum, u8 transmit);
+
+
+extern struct dma_controller *dma_controller_create(struct musb *, void __iomem *);
+
+extern void dma_controller_destroy(struct dma_controller *);
+
+#endif /* __MUSB_DMA_H__ */
diff --git a/include/linux/musb/musb_gadget.h b/include/linux/musb/musb_gadget.h
new file mode 100644
index 000000000..b90bc6a5c
--- /dev/null
+++ b/include/linux/musb/musb_gadget.h
@@ -0,0 +1,125 @@
+/*
+ * MUSB OTG driver peripheral defines
+ *
+ * Copyright 2005 Mentor Graphics Corporation
+ * Copyright (C) 2005-2006 by Texas Instruments
+ * Copyright (C) 2006-2007 Nokia Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __MUSB_GADGET_H
+#define __MUSB_GADGET_H
+
+#include <linux/list.h>
+
+enum buffer_map_state {
+ UN_MAPPED = 0,
+ PRE_MAPPED,
+ MUSB_MAPPED
+};
+
+struct musb_request {
+ struct usb_request request;
+ struct list_head list;
+ struct musb_ep *ep;
+ struct musb *musb;
+ u8 tx; /* endpoint direction */
+ u8 epnum;
+ enum buffer_map_state map_state;
+};
+
+static inline struct musb_request *to_musb_request(struct usb_request *req)
+{
+ return req ? container_of(req, struct musb_request, request) : NULL;
+}
+
+extern struct usb_request *musb_alloc_request(struct usb_ep *ep, gfp_t gfp_flags);
+extern void musb_free_request(struct usb_ep *ep, struct usb_request *req);
+
+
+/*
+ * struct musb_ep - peripheral side view of endpoint rx or tx side
+ */
+struct musb_ep {
+ /* stuff towards the head is basically write-once. */
+ struct usb_ep end_point;
+ char name[12];
+ struct musb_hw_ep *hw_ep;
+ struct musb *musb;
+ u16 fifo_size;
+ enum musb_buf_mode fifo_mode;
+ u8 current_epnum;
+
+ /* ... when enabled/disabled ... */
+ u8 type;
+ u8 is_in;
+ u16 packet_sz;
+ const struct usb_endpoint_descriptor *desc;
+ struct dma_channel *dma;
+
+ /* later things are modified based on usage */
+ struct list_head req_list;
+
+ u8 wedged;
+
+ /* true if lock must be dropped but req_list may not be advanced */
+ u8 busy;
+
+ u8 hb_mult;
+
+ /* true if packet is received in fifo and req_list is empty */
+ u8 rx_pending;
+};
+
+static inline struct musb_ep *to_musb_ep(struct usb_ep *ep)
+{
+ return ep ? container_of(ep, struct musb_ep, end_point) : NULL;
+}
+
+static inline struct musb_request *next_request(struct musb_ep *ep)
+{
+ struct list_head *queue = &ep->req_list;
+
+ if (list_empty(queue))
+ return NULL;
+ return container_of(queue->next, struct musb_request, list);
+}
+
+extern void musb_g_tx(struct musb *musb, u8 epnum);
+extern void musb_g_rx(struct musb *musb, u8 epnum);
+
+extern const struct usb_ep_ops musb_g_ep0_ops;
+
+extern int musb_gadget_setup(struct musb *);
+extern void musb_gadget_cleanup(struct musb *);
+
+extern void musb_g_giveback(struct musb_ep *, struct usb_request *, int);
+
+extern void musb_ep_restart(struct musb *, struct musb_request *);
+
+#endif /* __MUSB_GADGET_H */
diff --git a/include/linux/musb/musb_host.h b/include/linux/musb/musb_host.h
new file mode 100644
index 000000000..7c8270ddd
--- /dev/null
+++ b/include/linux/musb/musb_host.h
@@ -0,0 +1,111 @@
+/*
+ * MUSB OTG driver host defines
+ *
+ * Copyright 2005 Mentor Graphics Corporation
+ * Copyright (C) 2005-2006 by Texas Instruments
+ * Copyright (C) 2006-2007 Nokia Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef _MUSB_HOST_H
+#define _MUSB_HOST_H
+
+#include <linux/scatterlist.h>
+
+static inline struct usb_hcd *musb_to_hcd(struct musb *musb)
+{
+ return container_of((void *)musb, struct usb_hcd, hcd_priv);
+}
+
+static inline struct musb *hcd_to_musb(struct usb_hcd *hcd)
+{
+ return (struct musb *)(hcd->hcd_priv);
+}
+
+/* stored in "usb_host_endpoint.hcpriv" for scheduled endpoints */
+struct musb_qh {
+ struct usb_host_endpoint *hep; /* usbcore info */
+ struct usb_device *dev;
+ struct musb_hw_ep *hw_ep; /* current binding */
+
+ struct list_head ring; /* of musb_qh */
+ /* struct musb_qh *next; *//* for periodic tree */
+ u8 mux; /* qh multiplexed to hw_ep */
+
+ unsigned offset; /* in urb->transfer_buffer */
+ unsigned segsize; /* current xfer fragment */
+
+ u8 type_reg; /* {rx,tx} type register */
+ u8 intv_reg; /* {rx,tx} interval register */
+ u8 addr_reg; /* device address register */
+ u8 h_addr_reg; /* hub address register */
+ u8 h_port_reg; /* hub port register */
+
+ u8 is_ready; /* safe to modify hw_ep */
+ u8 type; /* XFERTYPE_* */
+ u8 epnum;
+ u8 hb_mult; /* high bandwidth pkts per uf */
+ u16 maxpacket;
+ u16 frame; /* for periodic schedule */
+ unsigned iso_idx; /* in urb->iso_frame_desc[] */
+ struct sg_mapping_iter sg_miter; /* for highmem in PIO mode */
+};
+
+/* map from control or bulk queue head to the first qh on that ring */
+static inline struct musb_qh *first_qh(struct list_head *q)
+{
+ if (list_empty(q))
+ return NULL;
+ return list_entry(q->next, struct musb_qh, ring);
+}
+
+void musb_h_pre_disable(struct musb *musb);
+
+extern void musb_root_disconnect(struct musb *musb);
+
+struct usb_hcd;
+
+extern int musb_hub_status_data(struct usb_hcd *hcd, char *buf);
+extern int musb_hub_control(struct usb_hcd *hcd,
+ u16 typeReq, u16 wValue, u16 wIndex, char *buf, u16 wLength);
+
+extern const struct hc_driver musb_hc_driver;
+
+static inline struct urb *next_urb(struct musb_qh *qh)
+{
+ struct list_head *queue;
+
+ if (!qh)
+ return NULL;
+ queue = &qh->hep->urb_list;
+ if (list_empty(queue))
+ return NULL;
+ return list_entry(queue->next, struct urb, urb_list);
+}
+
+#endif /* _MUSB_HOST_H */
diff --git a/include/linux/musb/musb_io.h b/include/linux/musb/musb_io.h
new file mode 100644
index 000000000..38da79b43
--- /dev/null
+++ b/include/linux/musb/musb_io.h
@@ -0,0 +1,231 @@
+/*
+ * MUSB OTG driver register I/O
+ *
+ * Copyright 2005 Mentor Graphics Corporation
+ * Copyright (C) 2005-2006 by Texas Instruments
+ * Copyright (C) 2006-2007 Nokia Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __MUSB_LINUX_PLATFORM_ARCH_H__
+#define __MUSB_LINUX_PLATFORM_ARCH_H__
+
+#include <linux/io.h>
+#include <linux/spinlock.h>
+
+extern bool mtk_usb_power;
+extern bool usb_enable_clock(bool enable);
+extern spinlock_t usb_io_lock;
+
+static inline u16 musb_readw(const void __iomem *addr, unsigned offset)
+{
+ u16 rc = 0;
+
+ if (mtk_usb_power) {
+ rc = readw(addr + offset);
+ } else {
+ unsigned long flags = 0;
+ spin_lock_irqsave(&usb_io_lock, flags);
+ usb_enable_clock(true);
+ DBG(0, "[MUSB]:access %s function when usb clock is off 0x%X\n", __func__, offset);
+ rc = readw(addr + offset);
+ usb_enable_clock(false);
+ spin_unlock_irqrestore(&usb_io_lock, flags);
+ }
+ return rc;
+}
+
+static inline u32 musb_readl(const void __iomem *addr, unsigned offset)
+{
+ u32 rc = 0;
+
+ if (mtk_usb_power) {
+ rc = readl(addr + offset);
+ } else {
+ unsigned long flags = 0;
+ spin_lock_irqsave(&usb_io_lock, flags);
+ usb_enable_clock(true);
+ DBG(0, "[MUSB]:access %s function when usb clock is off 0x%X\n", __func__, offset);
+ rc = readl(addr + offset);
+ usb_enable_clock(false);
+ spin_unlock_irqrestore(&usb_io_lock, flags);
+ }
+ return rc;
+}
+
+
+static inline void musb_writew(void __iomem *addr, unsigned offset, u16 data)
+{
+ if (mtk_usb_power) {
+ writew(data, addr + offset);
+ } else {
+ unsigned long flags = 0;
+ spin_lock_irqsave(&usb_io_lock, flags);
+ usb_enable_clock(true);
+ DBG(0, "[MUSB]:access %s function when usb clock is off 0x%X\n", __func__, offset);
+ writew(data, addr + offset);
+ usb_enable_clock(false);
+ spin_unlock_irqrestore(&usb_io_lock, flags);
+ }
+}
+
+static inline void musb_writel(void __iomem *addr, unsigned offset, u32 data)
+{
+ if (mtk_usb_power) {
+ writel(data, addr + offset);
+ } else {
+ unsigned long flags = 0;
+ spin_lock_irqsave(&usb_io_lock, flags);
+ usb_enable_clock(true);
+ DBG(0, "[MUSB]:access %s function when usb clock is off 0x%X\n", __func__, offset);
+ writel(data, addr + offset);
+ usb_enable_clock(false);
+ spin_unlock_irqrestore(&usb_io_lock, flags);
+ }
+}
+
+static inline u8 musb_readb(const void __iomem *addr, unsigned offset)
+{
+ u8 rc = 0;
+
+ if (mtk_usb_power) {
+ rc = readb(addr + offset);
+ } else {
+ unsigned long flags = 0;
+ spin_lock_irqsave(&usb_io_lock, flags);
+ usb_enable_clock(true);
+ DBG(0, "[MUSB]:access %s function when usb clock is off 0x%X\n", __func__, offset);
+ rc = readb(addr + offset);
+ usb_enable_clock(false);
+ spin_unlock_irqrestore(&usb_io_lock, flags);
+ }
+ return rc;
+}
+
+static inline void musb_writeb(void __iomem *addr, unsigned offset, u8 data)
+{
+ if (mtk_usb_power) {
+ writeb(data, addr + offset);
+ } else {
+ unsigned long flags = 0;
+ spin_lock_irqsave(&usb_io_lock, flags);
+ usb_enable_clock(true);
+ DBG(0, "[MUSB]:access %s function when usb clock is off 0x%X\n", __func__, offset);
+ writeb(data, addr + offset);
+ usb_enable_clock(false);
+ spin_unlock_irqrestore(&usb_io_lock, flags);
+ }
+}
+
+#if 0
+struct musb_reg {
+ u8(*_readb) (u32 addr, u32 offset);
+ u16(*_readw) (u32 addr, u32 offset);
+ u32(*_readl) (u32 addr, u32 offset);
+ void (*_writeb) (u32 addr, u32 offset, u8 data);
+ void (*_writew) (u32 addr, u32 offset, u16 data);
+ void (*_writel) (u32 addr, u32 offset, u32 data);
+};
+/* NOTE: these offsets are all in bytes */
+
+static inline u16 power_on_readw(const void __iomem *addr, unsigned offset)
+{
+ return __raw_readw(addr + offset);
+}
+
+static inline u32 power_on_readl(const void __iomem *addr, unsigned offset)
+{
+ return __raw_readl(addr + offset);
+}
+
+
+static inline void power_on_writew(void __iomem *addr, unsigned offset, u16 data)
+{
+ __raw_writew(data, addr + offset);
+}
+
+static inline void power_on_writel(void __iomem *addr, unsigned offset, u32 data)
+{
+ __raw_writel(data, addr + offset);
+}
+
+static inline u8 power_on_readb(const void __iomem *addr, unsigned offset)
+{
+ return __raw_readb(addr + offset);
+}
+
+static inline void power_on_writeb(void __iomem *addr, unsigned offset, u8 data)
+{
+ __raw_writeb(data, addr + offset);
+}
+
+
+static inline u16 power_off_readw(const void __iomem *addr, unsigned offset)
+{
+ printk("MUSB:access %s function when usb clock is off\n", __func__);
+ return 0;
+}
+
+static inline u32 power_off_readl(const void __iomem *addr, unsigned offset)
+{
+ printk("MUSB:access %s function when usb clock is off\n", __func__);
+ return 0;
+}
+
+
+static inline void power_off_writew(void __iomem *addr, unsigned offset, u16 data)
+{
+ printk("MUSB:access %s function when usb clock is off\n", __func__);
+}
+
+static inline void power_off_writel(void __iomem *addr, unsigned offset, u32 data)
+{
+ printk("MUSB:access %s function when usb clock is off\n", __func__);
+}
+
+static inline u8 power_off_readb(const void __iomem *addr, unsigned offset)
+{
+ printk("MUSB:access %s function when usb clock is off\n", __func__);
+ return 0;
+}
+
+static inline void power_off_writeb(void __iomem *addr, unsigned offset, u8 data)
+{
+ printk("MUSB:access %s function when usb clock is off\n", __func__);
+}
+
+extern struct musb_reg musb_reg;
+#define musb_readb musb_reg._readb
+#define musb_readw musb_reg._readl
+#define musb_readl musb_reg._readw
+#define musb_writeb musb_reg._writeb
+#define musb_writew musb_reg._writew
+#define musb_writel musb_reg._writel
+#endif
+
+#endif
diff --git a/include/linux/musb/musb_qmu.h b/include/linux/musb/musb_qmu.h
new file mode 100644
index 000000000..3364244fa
--- /dev/null
+++ b/include/linux/musb/musb_qmu.h
@@ -0,0 +1,21 @@
+#ifndef _MUSB_QMU_H_
+#define _MUSB_QMU_H_
+
+#ifdef MUSB_QMU_SUPPORT
+#include "musb_core.h" /* for struct musb */
+
+extern int musb_qmu_init(struct musb *musb);
+extern void musb_qmu_exit(struct musb *musb);
+extern void musb_kick_D_CmdQ(struct musb *musb, struct musb_request *request);
+extern void musb_disable_q_all(struct musb *musb);
+extern irqreturn_t musb_q_irq(struct musb *musb);
+extern void musb_flush_qmu(u32 ep_num, u8 isRx);
+extern void musb_restart_qmu(struct musb *musb, u32 ep_num, u8 isRx);
+extern bool musb_is_qmu_stop(u32 ep_num, u8 isRx);
+extern void musb_tx_zlp_qmu(struct musb *musb, u32 ep_num);
+
+/*FIXME, not good layer present */
+extern void mtk_qmu_enable(struct musb *musb, u8 EP_Num, u8 isRx);
+
+#endif
+#endif
diff --git a/include/linux/musb/musbhsdma.h b/include/linux/musb/musbhsdma.h
new file mode 100644
index 000000000..200deb70f
--- /dev/null
+++ b/include/linux/musb/musbhsdma.h
@@ -0,0 +1,97 @@
+/*
+ * MUSB OTG driver - support for Mentor's DMA controller
+ *
+ * Copyright 2005 Mentor Graphics Corporation
+ * Copyright (C) 2005-2007 by Texas Instruments
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#define MUSB_HSDMA_BASE 0x200
+#define MUSB_HSDMA_INTR (MUSB_HSDMA_BASE + 0)
+#define MUSB_HSDMA_CONTROL 0x4
+#define MUSB_HSDMA_ADDRESS 0x8
+#define MUSB_HSDMA_COUNT 0xc
+
+#define MUSB_HSDMA_CHANNEL_OFFSET(_bchannel, _offset) \
+ (MUSB_HSDMA_BASE + (_bchannel << 4) + _offset)
+
+#define musb_read_hsdma_addr(mbase, bchannel) \
+ musb_readl(mbase, \
+ MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_ADDRESS))
+
+#define musb_write_hsdma_addr(mbase, bchannel, addr) \
+ musb_writel(mbase, \
+ MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_ADDRESS), \
+ addr)
+
+#define musb_read_hsdma_count(mbase, bchannel) \
+ musb_readl(mbase, \
+ MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT))
+
+#define musb_write_hsdma_count(mbase, bchannel, len) \
+ musb_writel(mbase, \
+ MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT), \
+ len)
+/* control register (16-bit): */
+#define MUSB_HSDMA_ENABLE_SHIFT 0
+#define MUSB_HSDMA_TRANSMIT_SHIFT 1
+#define MUSB_HSDMA_MODE1_SHIFT 2
+#define MUSB_HSDMA_IRQENABLE_SHIFT 3
+#define MUSB_HSDMA_ENDPOINT_SHIFT 4
+#define MUSB_HSDMA_BUSERROR_SHIFT 8
+#define MUSB_HSDMA_BURSTMODE_SHIFT 9
+#define MUSB_HSDMA_BURSTMODE (3 << MUSB_HSDMA_BURSTMODE_SHIFT)
+#define MUSB_HSDMA_BURSTMODE_UNSPEC 0
+#define MUSB_HSDMA_BURSTMODE_INCR4 1
+#define MUSB_HSDMA_BURSTMODE_INCR8 2
+#define MUSB_HSDMA_BURSTMODE_INCR16 3
+
+#define MUSB_HSDMA_CHANNELS 8
+
+struct musb_dma_controller;
+
+struct musb_dma_channel {
+ struct dma_channel channel;
+ struct musb_dma_controller *controller;
+ u32 start_addr;
+ u32 len;
+ u16 max_packet_sz;
+ u8 idx;
+ u8 epnum;
+ u8 transmit;
+};
+
+struct musb_dma_controller {
+ struct dma_controller controller;
+ struct musb_dma_channel channel[MUSB_HSDMA_CHANNELS];
+ void *private_data;
+ void __iomem *base;
+ u8 channel_count;
+ u8 used_channels;
+ u8 irq;
+};