Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /*
0003  * SL811HS register declarations and HCD data structures
0004  *
0005  * Copyright (C) 2004 Psion Teklogix
0006  * Copyright (C) 2004 David Brownell
0007  * Copyright (C) 2001 Cypress Semiconductor Inc. 
0008  */
0009 
0010 /*
0011  * SL811HS has transfer registers, and control registers.  In host/master
0012  * mode one set of registers is used; in peripheral/slave mode, another.
0013  *  - SL11H only has some "A" transfer registers from 0x00-0x04
0014  *  - SL811HS also has "B" registers from 0x08-0x0c
0015  *  - SL811S (or HS in slave mode) has four A+B sets, at 00, 10, 20, 30
0016  */
0017 
0018 #define SL811_EP_A(base)    ((base) + 0)
0019 #define SL811_EP_B(base)    ((base) + 8)
0020 
0021 #define SL811_HOST_BUF      0x00
0022 #define SL811_PERIPH_EP0    0x00
0023 #define SL811_PERIPH_EP1    0x10
0024 #define SL811_PERIPH_EP2    0x20
0025 #define SL811_PERIPH_EP3    0x30
0026 
0027 
0028 /* TRANSFER REGISTERS:  host and peripheral sides are similar
0029  * except for the control models (master vs slave).
0030  */
0031 #define SL11H_HOSTCTLREG    0
0032 #   define SL11H_HCTLMASK_ARM   0x01
0033 #   define SL11H_HCTLMASK_ENABLE    0x02
0034 #   define SL11H_HCTLMASK_IN    0x00
0035 #   define SL11H_HCTLMASK_OUT   0x04
0036 #   define SL11H_HCTLMASK_ISOCH 0x10
0037 #   define SL11H_HCTLMASK_AFTERSOF  0x20
0038 #   define SL11H_HCTLMASK_TOGGLE    0x40
0039 #   define SL11H_HCTLMASK_PREAMBLE  0x80
0040 #define SL11H_BUFADDRREG    1
0041 #define SL11H_BUFLNTHREG    2
0042 #define SL11H_PKTSTATREG    3   /* read */
0043 #   define SL11H_STATMASK_ACK   0x01
0044 #   define SL11H_STATMASK_ERROR 0x02
0045 #   define SL11H_STATMASK_TMOUT 0x04
0046 #   define SL11H_STATMASK_SEQ   0x08
0047 #   define SL11H_STATMASK_SETUP 0x10
0048 #   define SL11H_STATMASK_OVF   0x20
0049 #   define SL11H_STATMASK_NAK   0x40
0050 #   define SL11H_STATMASK_STALL 0x80
0051 #define SL11H_PIDEPREG      3   /* write */
0052 #   define  SL_SETUP    0xd0
0053 #   define  SL_IN       0x90
0054 #   define  SL_OUT      0x10
0055 #   define  SL_SOF      0x50
0056 #   define  SL_PREAMBLE 0xc0
0057 #   define  SL_NAK      0xa0
0058 #   define  SL_STALL    0xe0
0059 #   define  SL_DATA0    0x30
0060 #   define  SL_DATA1    0xb0
0061 #define SL11H_XFERCNTREG    4   /* read */
0062 #define SL11H_DEVADDRREG    4   /* write */
0063 
0064 
0065 /* CONTROL REGISTERS:  host and peripheral are very different.
0066  */
0067 #define SL11H_CTLREG1       5
0068 #   define SL11H_CTL1MASK_SOF_ENA   0x01
0069 #   define SL11H_CTL1MASK_FORCE 0x18
0070 #       define SL11H_CTL1MASK_NORMAL    0x00
0071 #       define SL11H_CTL1MASK_SE0   0x08    /* reset */
0072 #       define SL11H_CTL1MASK_J     0x10
0073 #       define SL11H_CTL1MASK_K     0x18    /* resume */
0074 #   define SL11H_CTL1MASK_LSPD  0x20
0075 #   define SL11H_CTL1MASK_SUSPEND   0x40
0076 #define SL11H_IRQ_ENABLE    6
0077 #   define SL11H_INTMASK_DONE_A 0x01
0078 #   define SL11H_INTMASK_DONE_B 0x02
0079 #   define SL11H_INTMASK_SOFINTR    0x10
0080 #   define SL11H_INTMASK_INSRMV 0x20    /* to/from SE0 */
0081 #   define SL11H_INTMASK_RD     0x40
0082 #   define SL11H_INTMASK_DP     0x80    /* only in INTSTATREG */
0083 #define SL11S_ADDRESS       7
0084 
0085 /* 0x08-0x0c are for the B buffer (not in SL11) */
0086 
0087 #define SL11H_IRQ_STATUS    0x0D    /* write to ack */
0088 #define SL11H_HWREVREG      0x0E    /* read */
0089 #   define SL11H_HWRMASK_HWREV  0xF0
0090 #define SL11H_SOFLOWREG     0x0E    /* write */
0091 #define SL11H_SOFTMRREG     0x0F    /* read */
0092 
0093 /* a write to this register enables SL811HS features.
0094  * HOST flag presumably overrides the chip input signal?
0095  */
0096 #define SL811HS_CTLREG2     0x0F
0097 #   define SL811HS_CTL2MASK_SOF_MASK    0x3F
0098 #   define SL811HS_CTL2MASK_DSWAP       0x40
0099 #   define SL811HS_CTL2MASK_HOST        0x80
0100 
0101 #define SL811HS_CTL2_INIT   (SL811HS_CTL2MASK_HOST | 0x2e)
0102 
0103 
0104 /* DATA BUFFERS: registers from 0x10..0xff are for data buffers;
0105  * that's 240 bytes, which we'll split evenly between A and B sides.
0106  * Only ISO can use more than 64 bytes per packet.
0107  * (The SL11S has 0x40..0xff for buffers.)
0108  */
0109 #define H_MAXPACKET 120     /* bytes in A or B fifos */
0110 
0111 #define SL11H_DATA_START    0x10
0112 #define SL811HS_PACKET_BUF(is_a)    ((is_a) \
0113         ? SL11H_DATA_START \
0114         : (SL11H_DATA_START + H_MAXPACKET))
0115 
0116 /*-------------------------------------------------------------------------*/
0117 
0118 #define LOG2_PERIODIC_SIZE  5   /* arbitrary; this matches OHCI */
0119 #define PERIODIC_SIZE       (1 << LOG2_PERIODIC_SIZE)
0120 
0121 struct sl811 {
0122     spinlock_t      lock;
0123     void __iomem        *addr_reg;
0124     void __iomem        *data_reg;
0125     struct sl811_platform_data  *board;
0126 
0127     unsigned long       stat_insrmv;
0128     unsigned long       stat_wake;
0129     unsigned long       stat_sof;
0130     unsigned long       stat_a;
0131     unsigned long       stat_b;
0132     unsigned long       stat_lost;
0133     unsigned long       stat_overrun;
0134 
0135     /* sw model */
0136     struct timer_list   timer;
0137     struct sl811h_ep    *next_periodic;
0138     struct sl811h_ep    *next_async;
0139 
0140     struct sl811h_ep    *active_a;
0141     unsigned long       jiffies_a;
0142     struct sl811h_ep    *active_b;
0143     unsigned long       jiffies_b;
0144 
0145     u32         port1;
0146     u8          ctrl1, ctrl2, irq_enable;
0147     u16         frame;
0148 
0149     /* async schedule: control, bulk */
0150     struct list_head    async;
0151 
0152     /* periodic schedule: interrupt, iso */
0153     u16         load[PERIODIC_SIZE];
0154     struct sl811h_ep    *periodic[PERIODIC_SIZE];
0155     unsigned        periodic_count;
0156 };
0157 
0158 static inline struct sl811 *hcd_to_sl811(struct usb_hcd *hcd)
0159 {
0160     return (struct sl811 *) (hcd->hcd_priv);
0161 }
0162 
0163 static inline struct usb_hcd *sl811_to_hcd(struct sl811 *sl811)
0164 {
0165     return container_of((void *) sl811, struct usb_hcd, hcd_priv);
0166 }
0167 
0168 struct sl811h_ep {
0169     struct usb_host_endpoint *hep;
0170     struct usb_device   *udev;
0171 
0172     u8          defctrl;
0173     u8          maxpacket;
0174     u8          epnum;
0175     u8          nextpid;
0176 
0177     u16         error_count;
0178     u16         nak_count;
0179     u16         length;     /* of current packet */
0180 
0181     /* periodic schedule */
0182     u16         period;
0183     u16         branch;
0184     u16         load;
0185     struct sl811h_ep    *next;
0186 
0187     /* async schedule */
0188     struct list_head    schedule;
0189 };
0190 
0191 /*-------------------------------------------------------------------------*/
0192 
0193 /* These register utilities should work for the SL811S register API too
0194  * NOTE:  caller must hold sl811->lock.
0195  */
0196 
0197 static inline u8 sl811_read(struct sl811 *sl811, int reg)
0198 {
0199     writeb(reg, sl811->addr_reg);
0200     return readb(sl811->data_reg);
0201 }
0202 
0203 static inline void sl811_write(struct sl811 *sl811, int reg, u8 val)
0204 {
0205     writeb(reg, sl811->addr_reg);
0206     writeb(val, sl811->data_reg);
0207 }
0208 
0209 static inline void
0210 sl811_write_buf(struct sl811 *sl811, int addr, const void *buf, size_t count)
0211 {
0212     const u8    *data;
0213     void __iomem    *data_reg;
0214 
0215     if (!count)
0216         return;
0217     writeb(addr, sl811->addr_reg);
0218 
0219     data = buf;
0220     data_reg = sl811->data_reg;
0221     do {
0222         writeb(*data++, data_reg);
0223     } while (--count);
0224 }
0225 
0226 static inline void
0227 sl811_read_buf(struct sl811 *sl811, int addr, void *buf, size_t count)
0228 {
0229     u8      *data;
0230     void __iomem    *data_reg;
0231 
0232     if (!count)
0233         return;
0234     writeb(addr, sl811->addr_reg);
0235 
0236     data = buf;
0237     data_reg = sl811->data_reg;
0238     do {
0239         *data++ = readb(data_reg);
0240     } while (--count);
0241 }
0242 
0243 /*-------------------------------------------------------------------------*/
0244 
0245 #ifdef PACKET_TRACE
0246 #    define PACKET      pr_debug("sl811: "stuff)
0247 #else
0248 #    define PACKET(stuff...)    do{}while(0)
0249 #endif