blob: 0f226b0d476170597c15a8b97efe8a1accd6070f [file] [log] [blame]
Alexander Shishkine443b332012-05-11 17:25:46 +03001/*
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>
Alexander Shishkin5f36e232012-05-11 17:25:47 +030017#include <linux/irqreturn.h>
Alexander Shishkine443b332012-05-11 17:25:46 +030018#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 */
31struct 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
Alexander Shishkin5f36e232012-05-11 17:25:47 +030051enum 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 */
64struct 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
Alexander Shishkine443b332012-05-11 17:25:46 +030071struct 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 */
81struct ci13xxx {
82 spinlock_t lock; /* ctrl register bank access */
Alexander Shishkine443b332012-05-11 17:25:46 +030083
84 struct dma_pool *qh_pool; /* DMA pool for queue heads */
85 struct dma_pool *td_pool; /* DMA pool for transfer descs */
86 struct usb_request *status; /* ep0 status request */
87
88 struct device *dev;
89 struct usb_gadget gadget; /* USB slave device */
90 struct ci13xxx_ep ci13xxx_ep[ENDPT_MAX]; /* extended endpts */
91 u32 ep0_dir; /* ep0 direction */
92 struct ci13xxx_ep *ep0out, *ep0in;
93 unsigned hw_ep_max; /* number of hw endpoints */
94
95 bool setaddr;
96 u8 address;
97 u8 remote_wakeup; /* Is remote wakeup feature
98 enabled by the host? */
99 u8 suspended; /* suspended by the host */
100 u8 test_mode; /* the selected test mode */
101
102 struct hw_bank hw_bank;
103 int irq;
104 struct usb_gadget_driver *driver; /* 3rd party gadget driver */
105 struct ci13xxx_udc_driver *udc_driver; /* device controller driver */
106 int vbus_active; /* is VBUS active */
107 struct usb_phy *transceiver; /* Transceiver struct */
Alexander Shishkin5f36e232012-05-11 17:25:47 +0300108 struct ci_role_driver *roles[CI_ROLE_END];
109 enum ci_role role;
110 bool is_otg;
111 struct work_struct work;
112 struct workqueue_struct *wq;
Alexander Shishkine443b332012-05-11 17:25:46 +0300113};
114
Alexander Shishkin5f36e232012-05-11 17:25:47 +0300115static inline struct ci_role_driver *ci_role(struct ci13xxx *ci)
116{
117 BUG_ON(ci->role >= CI_ROLE_END || !ci->roles[ci->role]);
118 return ci->roles[ci->role];
119}
120
121static inline int ci_role_start(struct ci13xxx *ci, enum ci_role role)
122{
123 int ret;
124
125 if (role >= CI_ROLE_END)
126 return -EINVAL;
127
128 if (!ci->roles[role])
129 return -ENXIO;
130
131 ret = ci->roles[role]->start(ci);
132 if (!ret)
133 ci->role = role;
134 return ret;
135}
136
137static inline void ci_role_stop(struct ci13xxx *ci)
138{
139 enum ci_role role = ci->role;
140
141 if (role == CI_ROLE_END)
142 return;
143
144 ci->role = CI_ROLE_END;
145
146 ci->roles[role]->stop(ci);
147}
148
Alexander Shishkine443b332012-05-11 17:25:46 +0300149/******************************************************************************
150 * REGISTERS
151 *****************************************************************************/
152/* register size */
153#define REG_BITS (32)
154
155/* register indices */
156enum ci13xxx_regs {
157 CAP_CAPLENGTH,
158 CAP_HCCPARAMS,
159 CAP_DCCPARAMS,
160 CAP_TESTMODE,
161 CAP_LAST = CAP_TESTMODE,
162 OP_USBCMD,
163 OP_USBSTS,
164 OP_USBINTR,
165 OP_DEVICEADDR,
166 OP_ENDPTLISTADDR,
167 OP_PORTSC,
168 OP_DEVLC,
Alexander Shishkin5f36e232012-05-11 17:25:47 +0300169 OP_OTGSC,
Alexander Shishkine443b332012-05-11 17:25:46 +0300170 OP_USBMODE,
171 OP_ENDPTSETUPSTAT,
172 OP_ENDPTPRIME,
173 OP_ENDPTFLUSH,
174 OP_ENDPTSTAT,
175 OP_ENDPTCOMPLETE,
176 OP_ENDPTCTRL,
177 /* endptctrl1..15 follow */
178 OP_LAST = OP_ENDPTCTRL + ENDPT_MAX / 2,
179};
180
Alexander Shishkine443b332012-05-11 17:25:46 +0300181/**
182 * ffs_nr: find first (least significant) bit set
183 * @x: the word to search
184 *
185 * This function returns bit number (instead of position)
186 */
187static inline int ffs_nr(u32 x)
188{
189 int n = ffs(x);
190
191 return n ? n-1 : 32;
192}
193
194/**
195 * hw_read: reads from a hw register
196 * @reg: register index
197 * @mask: bitfield mask
198 *
199 * This function returns register contents
200 */
201static inline u32 hw_read(struct ci13xxx *udc, enum ci13xxx_regs reg, u32 mask)
202{
203 return ioread32(udc->hw_bank.regmap[reg]) & mask;
204}
205
206/**
207 * hw_write: writes to a hw register
208 * @reg: register index
209 * @mask: bitfield mask
210 * @data: new value
211 */
212static inline void hw_write(struct ci13xxx *udc, enum ci13xxx_regs reg,
213 u32 mask, u32 data)
214{
215 if (~mask)
216 data = (ioread32(udc->hw_bank.regmap[reg]) & ~mask)
217 | (data & mask);
218
219 iowrite32(data, udc->hw_bank.regmap[reg]);
220}
221
222/**
223 * hw_test_and_clear: tests & clears a hw register
224 * @reg: register index
225 * @mask: bitfield mask
226 *
227 * This function returns register contents
228 */
229static inline u32 hw_test_and_clear(struct ci13xxx *udc, enum ci13xxx_regs reg,
230 u32 mask)
231{
232 u32 val = ioread32(udc->hw_bank.regmap[reg]) & mask;
233
234 iowrite32(val, udc->hw_bank.regmap[reg]);
235 return val;
236}
237
238/**
239 * hw_test_and_write: tests & writes a hw register
240 * @reg: register index
241 * @mask: bitfield mask
242 * @data: new value
243 *
244 * This function returns register contents
245 */
246static inline u32 hw_test_and_write(struct ci13xxx *udc, enum ci13xxx_regs reg,
247 u32 mask, u32 data)
248{
249 u32 val = hw_read(udc, reg, ~0);
250
251 hw_write(udc, reg, mask, data);
252 return (val & mask) >> ffs_nr(mask);
253}
254
Alexander Shishkine443b332012-05-11 17:25:46 +0300255int hw_device_reset(struct ci13xxx *ci);
256
257int hw_port_test_set(struct ci13xxx *ci, u8 mode);
258
259u8 hw_port_test_get(struct ci13xxx *ci);
260
261#endif /* __DRIVERS_USB_CHIPIDEA_CI_H */