]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/usb/chipidea/ci.h
usb: chipidea: add support for roles
[karo-tx-linux.git] / drivers / usb / chipidea / ci.h
1 /*
2  * ci.h - common structures, functions, and macros of the ChipIdea driver
3  *
4  * Copyright (C) 2008 Chipidea - MIPS Technologies, Inc. All rights reserved.
5  *
6  * Author: David Lopo
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 as
10  * published by the Free Software Foundation.
11  */
12
13 #ifndef __DRIVERS_USB_CHIPIDEA_CI_H
14 #define __DRIVERS_USB_CHIPIDEA_CI_H
15
16 #include <linux/list.h>
17 #include <linux/irqreturn.h>
18 #include <linux/usb/gadget.h>
19
20 /******************************************************************************
21  * DEFINE
22  *****************************************************************************/
23 #define DMA_ADDR_INVALID        (~(dma_addr_t)0)
24 #define CI13XXX_PAGE_SIZE  4096ul /* page size for TD's */
25 #define ENDPT_MAX          32
26
27 /******************************************************************************
28  * STRUCTURES
29  *****************************************************************************/
30 /* Extension of usb_ep */
31 struct ci13xxx_ep {
32         struct usb_ep                          ep;
33         u8                                     dir;
34         u8                                     num;
35         u8                                     type;
36         char                                   name[16];
37         struct {
38                 struct list_head   queue;
39                 struct ci13xxx_qh *ptr;
40                 dma_addr_t         dma;
41         }                                      qh;
42         int                                    wedge;
43
44         /* global resources */
45         struct ci13xxx                        *udc;
46         spinlock_t                            *lock;
47         struct device                         *device;
48         struct dma_pool                       *td_pool;
49 };
50
51 enum ci_role {
52         CI_ROLE_HOST = 0,
53         CI_ROLE_GADGET,
54         CI_ROLE_END,
55 };
56
57 /**
58  * struct ci_role_driver - host/gadget role driver
59  * start: start this role
60  * stop: stop this role
61  * irq: irq handler for this role
62  * name: role name string (host/gadget)
63  */
64 struct ci_role_driver {
65         int             (*start)(struct ci13xxx *);
66         void            (*stop)(struct ci13xxx *);
67         irqreturn_t     (*irq)(struct ci13xxx *);
68         const char      *name;
69 };
70
71 struct hw_bank {
72         unsigned      lpm;    /* is LPM? */
73         void __iomem *abs;    /* bus map offset */
74         void __iomem *cap;    /* bus map offset + CAP offset */
75         void __iomem *op;     /* bus map offset + OP offset */
76         size_t        size;   /* bank size */
77         void __iomem **regmap;
78 };
79
80 /* CI13XXX UDC descriptor & global resources */
81 struct ci13xxx {
82         spinlock_t                 lock;      /* ctrl register bank access */
83         void __iomem              *regs;      /* registers address space */
84
85         struct dma_pool           *qh_pool;   /* DMA pool for queue heads */
86         struct dma_pool           *td_pool;   /* DMA pool for transfer descs */
87         struct usb_request        *status;    /* ep0 status request */
88
89         struct device             *dev;
90         struct usb_gadget          gadget;     /* USB slave device */
91         struct ci13xxx_ep          ci13xxx_ep[ENDPT_MAX]; /* extended endpts */
92         u32                        ep0_dir;    /* ep0 direction */
93         struct ci13xxx_ep          *ep0out, *ep0in;
94         unsigned                   hw_ep_max;  /* number of hw endpoints */
95
96         bool                       setaddr;
97         u8                         address;
98         u8                         remote_wakeup; /* Is remote wakeup feature
99                                                         enabled by the host? */
100         u8                         suspended;  /* suspended by the host */
101         u8                         test_mode;  /* the selected test mode */
102
103         struct hw_bank             hw_bank;
104         int                        irq;
105         struct usb_gadget_driver  *driver;     /* 3rd party gadget driver */
106         struct ci13xxx_udc_driver *udc_driver; /* device controller driver */
107         int                        vbus_active; /* is VBUS active */
108         struct usb_phy            *transceiver; /* Transceiver struct */
109         struct ci_role_driver     *roles[CI_ROLE_END];
110         enum ci_role               role;
111         bool                       is_otg;
112         struct work_struct         work;
113         struct workqueue_struct   *wq;
114 };
115
116 static inline struct ci_role_driver *ci_role(struct ci13xxx *ci)
117 {
118         BUG_ON(ci->role >= CI_ROLE_END || !ci->roles[ci->role]);
119         return ci->roles[ci->role];
120 }
121
122 static inline int ci_role_start(struct ci13xxx *ci, enum ci_role role)
123 {
124         int ret;
125
126         if (role >= CI_ROLE_END)
127                 return -EINVAL;
128
129         if (!ci->roles[role])
130                 return -ENXIO;
131
132         ret = ci->roles[role]->start(ci);
133         if (!ret)
134                 ci->role = role;
135         return ret;
136 }
137
138 static inline void ci_role_stop(struct ci13xxx *ci)
139 {
140         enum ci_role role = ci->role;
141
142         if (role == CI_ROLE_END)
143                 return;
144
145         ci->role = CI_ROLE_END;
146
147         ci->roles[role]->stop(ci);
148 }
149
150 /******************************************************************************
151  * REGISTERS
152  *****************************************************************************/
153 /* register size */
154 #define REG_BITS   (32)
155
156 /* register indices */
157 enum ci13xxx_regs {
158         CAP_CAPLENGTH,
159         CAP_HCCPARAMS,
160         CAP_DCCPARAMS,
161         CAP_TESTMODE,
162         CAP_LAST = CAP_TESTMODE,
163         OP_USBCMD,
164         OP_USBSTS,
165         OP_USBINTR,
166         OP_DEVICEADDR,
167         OP_ENDPTLISTADDR,
168         OP_PORTSC,
169         OP_DEVLC,
170         OP_OTGSC,
171         OP_USBMODE,
172         OP_ENDPTSETUPSTAT,
173         OP_ENDPTPRIME,
174         OP_ENDPTFLUSH,
175         OP_ENDPTSTAT,
176         OP_ENDPTCOMPLETE,
177         OP_ENDPTCTRL,
178         /* endptctrl1..15 follow */
179         OP_LAST = OP_ENDPTCTRL + ENDPT_MAX / 2,
180 };
181
182 /**
183  * ffs_nr: find first (least significant) bit set
184  * @x: the word to search
185  *
186  * This function returns bit number (instead of position)
187  */
188 static inline int ffs_nr(u32 x)
189 {
190         int n = ffs(x);
191
192         return n ? n-1 : 32;
193 }
194
195 /**
196  * hw_read: reads from a hw register
197  * @reg:  register index
198  * @mask: bitfield mask
199  *
200  * This function returns register contents
201  */
202 static inline u32 hw_read(struct ci13xxx *udc, enum ci13xxx_regs reg, u32 mask)
203 {
204         return ioread32(udc->hw_bank.regmap[reg]) & mask;
205 }
206
207 /**
208  * hw_write: writes to a hw register
209  * @reg:  register index
210  * @mask: bitfield mask
211  * @data: new value
212  */
213 static inline void hw_write(struct ci13xxx *udc, enum ci13xxx_regs reg,
214                             u32 mask, u32 data)
215 {
216         if (~mask)
217                 data = (ioread32(udc->hw_bank.regmap[reg]) & ~mask)
218                         | (data & mask);
219
220         iowrite32(data, udc->hw_bank.regmap[reg]);
221 }
222
223 /**
224  * hw_test_and_clear: tests & clears a hw register
225  * @reg:  register index
226  * @mask: bitfield mask
227  *
228  * This function returns register contents
229  */
230 static inline u32 hw_test_and_clear(struct ci13xxx *udc, enum ci13xxx_regs reg,
231                                     u32 mask)
232 {
233         u32 val = ioread32(udc->hw_bank.regmap[reg]) & mask;
234
235         iowrite32(val, udc->hw_bank.regmap[reg]);
236         return val;
237 }
238
239 /**
240  * hw_test_and_write: tests & writes a hw register
241  * @reg:  register index
242  * @mask: bitfield mask
243  * @data: new value
244  *
245  * This function returns register contents
246  */
247 static inline u32 hw_test_and_write(struct ci13xxx *udc, enum ci13xxx_regs reg,
248                                     u32 mask, u32 data)
249 {
250         u32 val = hw_read(udc, reg, ~0);
251
252         hw_write(udc, reg, mask, data);
253         return (val & mask) >> ffs_nr(mask);
254 }
255
256 int hw_device_reset(struct ci13xxx *ci);
257
258 int hw_port_test_set(struct ci13xxx *ci, u8 mode);
259
260 u8 hw_port_test_get(struct ci13xxx *ci);
261
262 #endif  /* __DRIVERS_USB_CHIPIDEA_CI_H */