blob: 0dddd2f8ff359a7ae984c6a9f900bca2d3b21a54 [file] [log] [blame]
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +09001/*
2 * M66592 UDC (USB gadget)
3 *
4 * Copyright (C) 2006-2007 Renesas Solutions Corp.
5 *
6 * Author : Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com>
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 as published by
10 * the Free Software Foundation; version 2 of the License.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 *
21 */
22
23#include <linux/module.h>
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +090024#include <linux/interrupt.h>
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +090025#include <linux/delay.h>
26#include <linux/io.h>
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +090027#include <linux/platform_device.h>
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +090028
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +090029#include <linux/usb/ch9.h>
David Brownell9454a572007-10-04 18:05:17 -070030#include <linux/usb/gadget.h>
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +090031
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +090032#include "m66592-udc.h"
33
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +090034
35MODULE_DESCRIPTION("M66592 USB gadget driver");
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +090036MODULE_LICENSE("GPL");
37MODULE_AUTHOR("Yoshihiro Shimoda");
Kay Sieversf34c32f2008-04-10 21:29:21 -070038MODULE_ALIAS("platform:m66592_udc");
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +090039
Magnus Damm4048e5c2009-06-26 06:59:17 +000040#define DRIVER_VERSION "26 Jun 2009"
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +090041
42/* module parameters */
Yoshihiro Shimoda8c73aff2007-11-22 21:00:30 +090043#if defined(CONFIG_SUPERH_BUILT_IN_M66592)
44static unsigned short endian = M66592_LITTLE;
45module_param(endian, ushort, 0644);
46MODULE_PARM_DESC(endian, "data endian: big=0, little=0 (default=0)");
47#else
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +090048static unsigned short clock = M66592_XTAL24;
49module_param(clock, ushort, 0644);
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +090050MODULE_PARM_DESC(clock, "input clock: 48MHz=32768, 24MHz=16384, 12MHz=0 "
51 "(default=16384)");
52
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +090053static unsigned short vif = M66592_LDRV;
54module_param(vif, ushort, 0644);
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +090055MODULE_PARM_DESC(vif, "input VIF: 3.3V=32768, 1.5V=0 (default=32768)");
56
57static unsigned short endian;
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +090058module_param(endian, ushort, 0644);
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +090059MODULE_PARM_DESC(endian, "data endian: big=256, little=0 (default=0)");
60
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +090061static unsigned short irq_sense = M66592_INTL;
62module_param(irq_sense, ushort, 0644);
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +090063MODULE_PARM_DESC(irq_sense, "IRQ sense: low level=2, falling edge=0 "
64 "(default=2)");
Yoshihiro Shimoda8c73aff2007-11-22 21:00:30 +090065#endif
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +090066
67static const char udc_name[] = "m66592_udc";
68static const char *m66592_ep_name[] = {
69 "ep0", "ep1", "ep2", "ep3", "ep4", "ep5", "ep6", "ep7"
70};
71
72static void disable_controller(struct m66592 *m66592);
73static void irq_ep0_write(struct m66592_ep *ep, struct m66592_request *req);
74static void irq_packet_write(struct m66592_ep *ep, struct m66592_request *req);
75static int m66592_queue(struct usb_ep *_ep, struct usb_request *_req,
76 gfp_t gfp_flags);
77
78static void transfer_complete(struct m66592_ep *ep,
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +090079 struct m66592_request *req, int status);
80
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +090081/*-------------------------------------------------------------------------*/
82static inline u16 get_usb_speed(struct m66592 *m66592)
83{
84 return (m66592_read(m66592, M66592_DVSTCTR) & M66592_RHST);
85}
86
87static void enable_pipe_irq(struct m66592 *m66592, u16 pipenum,
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +090088 unsigned long reg)
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +090089{
90 u16 tmp;
91
92 tmp = m66592_read(m66592, M66592_INTENB0);
93 m66592_bclr(m66592, M66592_BEMPE | M66592_NRDYE | M66592_BRDYE,
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +090094 M66592_INTENB0);
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +090095 m66592_bset(m66592, (1 << pipenum), reg);
96 m66592_write(m66592, tmp, M66592_INTENB0);
97}
98
99static void disable_pipe_irq(struct m66592 *m66592, u16 pipenum,
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +0900100 unsigned long reg)
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +0900101{
102 u16 tmp;
103
104 tmp = m66592_read(m66592, M66592_INTENB0);
105 m66592_bclr(m66592, M66592_BEMPE | M66592_NRDYE | M66592_BRDYE,
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +0900106 M66592_INTENB0);
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +0900107 m66592_bclr(m66592, (1 << pipenum), reg);
108 m66592_write(m66592, tmp, M66592_INTENB0);
109}
110
111static void m66592_usb_connect(struct m66592 *m66592)
112{
113 m66592_bset(m66592, M66592_CTRE, M66592_INTENB0);
114 m66592_bset(m66592, M66592_WDST | M66592_RDST | M66592_CMPL,
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +0900115 M66592_INTENB0);
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +0900116 m66592_bset(m66592, M66592_BEMPE | M66592_BRDYE, M66592_INTENB0);
117
118 m66592_bset(m66592, M66592_DPRPU, M66592_SYSCFG);
119}
120
121static void m66592_usb_disconnect(struct m66592 *m66592)
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +0900122__releases(m66592->lock)
123__acquires(m66592->lock)
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +0900124{
125 m66592_bclr(m66592, M66592_CTRE, M66592_INTENB0);
126 m66592_bclr(m66592, M66592_WDST | M66592_RDST | M66592_CMPL,
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +0900127 M66592_INTENB0);
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +0900128 m66592_bclr(m66592, M66592_BEMPE | M66592_BRDYE, M66592_INTENB0);
129 m66592_bclr(m66592, M66592_DPRPU, M66592_SYSCFG);
130
131 m66592->gadget.speed = USB_SPEED_UNKNOWN;
132 spin_unlock(&m66592->lock);
133 m66592->driver->disconnect(&m66592->gadget);
134 spin_lock(&m66592->lock);
135
136 disable_controller(m66592);
137 INIT_LIST_HEAD(&m66592->ep[0].queue);
138}
139
140static inline u16 control_reg_get_pid(struct m66592 *m66592, u16 pipenum)
141{
142 u16 pid = 0;
143 unsigned long offset;
144
145 if (pipenum == 0)
146 pid = m66592_read(m66592, M66592_DCPCTR) & M66592_PID;
147 else if (pipenum < M66592_MAX_NUM_PIPE) {
148 offset = get_pipectr_addr(pipenum);
149 pid = m66592_read(m66592, offset) & M66592_PID;
150 } else
David Brownell00274922007-11-19 12:58:36 -0800151 pr_err("unexpect pipe num (%d)\n", pipenum);
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +0900152
153 return pid;
154}
155
156static inline void control_reg_set_pid(struct m66592 *m66592, u16 pipenum,
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +0900157 u16 pid)
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +0900158{
159 unsigned long offset;
160
161 if (pipenum == 0)
162 m66592_mdfy(m66592, pid, M66592_PID, M66592_DCPCTR);
163 else if (pipenum < M66592_MAX_NUM_PIPE) {
164 offset = get_pipectr_addr(pipenum);
165 m66592_mdfy(m66592, pid, M66592_PID, offset);
166 } else
David Brownell00274922007-11-19 12:58:36 -0800167 pr_err("unexpect pipe num (%d)\n", pipenum);
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +0900168}
169
170static inline void pipe_start(struct m66592 *m66592, u16 pipenum)
171{
172 control_reg_set_pid(m66592, pipenum, M66592_PID_BUF);
173}
174
175static inline void pipe_stop(struct m66592 *m66592, u16 pipenum)
176{
177 control_reg_set_pid(m66592, pipenum, M66592_PID_NAK);
178}
179
180static inline void pipe_stall(struct m66592 *m66592, u16 pipenum)
181{
182 control_reg_set_pid(m66592, pipenum, M66592_PID_STALL);
183}
184
185static inline u16 control_reg_get(struct m66592 *m66592, u16 pipenum)
186{
187 u16 ret = 0;
188 unsigned long offset;
189
190 if (pipenum == 0)
191 ret = m66592_read(m66592, M66592_DCPCTR);
192 else if (pipenum < M66592_MAX_NUM_PIPE) {
193 offset = get_pipectr_addr(pipenum);
194 ret = m66592_read(m66592, offset);
195 } else
David Brownell00274922007-11-19 12:58:36 -0800196 pr_err("unexpect pipe num (%d)\n", pipenum);
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +0900197
198 return ret;
199}
200
201static inline void control_reg_sqclr(struct m66592 *m66592, u16 pipenum)
202{
203 unsigned long offset;
204
205 pipe_stop(m66592, pipenum);
206
207 if (pipenum == 0)
208 m66592_bset(m66592, M66592_SQCLR, M66592_DCPCTR);
209 else if (pipenum < M66592_MAX_NUM_PIPE) {
210 offset = get_pipectr_addr(pipenum);
211 m66592_bset(m66592, M66592_SQCLR, offset);
212 } else
David Brownell00274922007-11-19 12:58:36 -0800213 pr_err("unexpect pipe num(%d)\n", pipenum);
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +0900214}
215
216static inline int get_buffer_size(struct m66592 *m66592, u16 pipenum)
217{
218 u16 tmp;
219 int size;
220
221 if (pipenum == 0) {
222 tmp = m66592_read(m66592, M66592_DCPCFG);
223 if ((tmp & M66592_CNTMD) != 0)
224 size = 256;
225 else {
226 tmp = m66592_read(m66592, M66592_DCPMAXP);
227 size = tmp & M66592_MAXP;
228 }
229 } else {
230 m66592_write(m66592, pipenum, M66592_PIPESEL);
231 tmp = m66592_read(m66592, M66592_PIPECFG);
232 if ((tmp & M66592_CNTMD) != 0) {
233 tmp = m66592_read(m66592, M66592_PIPEBUF);
234 size = ((tmp >> 10) + 1) * 64;
235 } else {
236 tmp = m66592_read(m66592, M66592_PIPEMAXP);
237 size = tmp & M66592_MXPS;
238 }
239 }
240
241 return size;
242}
243
244static inline void pipe_change(struct m66592 *m66592, u16 pipenum)
245{
246 struct m66592_ep *ep = m66592->pipenum2ep[pipenum];
247
248 if (ep->use_dma)
249 return;
250
251 m66592_mdfy(m66592, pipenum, M66592_CURPIPE, ep->fifosel);
252
253 ndelay(450);
254
255 m66592_bset(m66592, M66592_MBW, ep->fifosel);
256}
257
258static int pipe_buffer_setting(struct m66592 *m66592,
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +0900259 struct m66592_pipe_info *info)
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +0900260{
261 u16 bufnum = 0, buf_bsize = 0;
262 u16 pipecfg = 0;
263
264 if (info->pipe == 0)
265 return -EINVAL;
266
267 m66592_write(m66592, info->pipe, M66592_PIPESEL);
268
269 if (info->dir_in)
270 pipecfg |= M66592_DIR;
271 pipecfg |= info->type;
272 pipecfg |= info->epnum;
273 switch (info->type) {
274 case M66592_INT:
275 bufnum = 4 + (info->pipe - M66592_BASE_PIPENUM_INT);
276 buf_bsize = 0;
277 break;
278 case M66592_BULK:
Magnus Damm4048e5c2009-06-26 06:59:17 +0000279 /* isochronous pipes may be used as bulk pipes */
280 if (info->pipe > M66592_BASE_PIPENUM_BULK)
281 bufnum = info->pipe - M66592_BASE_PIPENUM_BULK;
282 else
283 bufnum = info->pipe - M66592_BASE_PIPENUM_ISOC;
284
285 bufnum = M66592_BASE_BUFNUM + (bufnum * 16);
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +0900286 buf_bsize = 7;
287 pipecfg |= M66592_DBLB;
288 if (!info->dir_in)
289 pipecfg |= M66592_SHTNAK;
290 break;
291 case M66592_ISO:
Magnus Damm4048e5c2009-06-26 06:59:17 +0000292 bufnum = M66592_BASE_BUFNUM +
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +0900293 (info->pipe - M66592_BASE_PIPENUM_ISOC) * 16;
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +0900294 buf_bsize = 7;
295 break;
296 }
Magnus Damm4048e5c2009-06-26 06:59:17 +0000297
298 if (buf_bsize && ((bufnum + 16) >= M66592_MAX_BUFNUM)) {
299 pr_err("m66592 pipe memory is insufficient\n");
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +0900300 return -ENOMEM;
301 }
302
303 m66592_write(m66592, pipecfg, M66592_PIPECFG);
304 m66592_write(m66592, (buf_bsize << 10) | (bufnum), M66592_PIPEBUF);
305 m66592_write(m66592, info->maxpacket, M66592_PIPEMAXP);
306 if (info->interval)
307 info->interval--;
308 m66592_write(m66592, info->interval, M66592_PIPEPERI);
309
310 return 0;
311}
312
313static void pipe_buffer_release(struct m66592 *m66592,
314 struct m66592_pipe_info *info)
315{
316 if (info->pipe == 0)
317 return;
318
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +0900319 if (is_bulk_pipe(info->pipe)) {
320 m66592->bulk--;
321 } else if (is_interrupt_pipe(info->pipe))
322 m66592->interrupt--;
323 else if (is_isoc_pipe(info->pipe)) {
324 m66592->isochronous--;
325 if (info->type == M66592_BULK)
326 m66592->bulk--;
327 } else
David Brownell00274922007-11-19 12:58:36 -0800328 pr_err("ep_release: unexpect pipenum (%d)\n",
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +0900329 info->pipe);
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +0900330}
331
332static void pipe_initialize(struct m66592_ep *ep)
333{
334 struct m66592 *m66592 = ep->m66592;
335
336 m66592_mdfy(m66592, 0, M66592_CURPIPE, ep->fifosel);
337
338 m66592_write(m66592, M66592_ACLRM, ep->pipectr);
339 m66592_write(m66592, 0, ep->pipectr);
340 m66592_write(m66592, M66592_SQCLR, ep->pipectr);
341 if (ep->use_dma) {
342 m66592_mdfy(m66592, ep->pipenum, M66592_CURPIPE, ep->fifosel);
343
344 ndelay(450);
345
346 m66592_bset(m66592, M66592_MBW, ep->fifosel);
347 }
348}
349
350static void m66592_ep_setting(struct m66592 *m66592, struct m66592_ep *ep,
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +0900351 const struct usb_endpoint_descriptor *desc,
352 u16 pipenum, int dma)
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +0900353{
354 if ((pipenum != 0) && dma) {
355 if (m66592->num_dma == 0) {
356 m66592->num_dma++;
357 ep->use_dma = 1;
358 ep->fifoaddr = M66592_D0FIFO;
359 ep->fifosel = M66592_D0FIFOSEL;
360 ep->fifoctr = M66592_D0FIFOCTR;
361 ep->fifotrn = M66592_D0FIFOTRN;
Yoshihiro Shimoda8c73aff2007-11-22 21:00:30 +0900362#if !defined(CONFIG_SUPERH_BUILT_IN_M66592)
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +0900363 } else if (m66592->num_dma == 1) {
364 m66592->num_dma++;
365 ep->use_dma = 1;
366 ep->fifoaddr = M66592_D1FIFO;
367 ep->fifosel = M66592_D1FIFOSEL;
368 ep->fifoctr = M66592_D1FIFOCTR;
369 ep->fifotrn = M66592_D1FIFOTRN;
Yoshihiro Shimoda8c73aff2007-11-22 21:00:30 +0900370#endif
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +0900371 } else {
372 ep->use_dma = 0;
373 ep->fifoaddr = M66592_CFIFO;
374 ep->fifosel = M66592_CFIFOSEL;
375 ep->fifoctr = M66592_CFIFOCTR;
376 ep->fifotrn = 0;
377 }
378 } else {
379 ep->use_dma = 0;
380 ep->fifoaddr = M66592_CFIFO;
381 ep->fifosel = M66592_CFIFOSEL;
382 ep->fifoctr = M66592_CFIFOCTR;
383 ep->fifotrn = 0;
384 }
385
386 ep->pipectr = get_pipectr_addr(pipenum);
387 ep->pipenum = pipenum;
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +0900388 ep->ep.maxpacket = le16_to_cpu(desc->wMaxPacketSize);
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +0900389 m66592->pipenum2ep[pipenum] = ep;
390 m66592->epaddr2ep[desc->bEndpointAddress&USB_ENDPOINT_NUMBER_MASK] = ep;
391 INIT_LIST_HEAD(&ep->queue);
392}
393
394static void m66592_ep_release(struct m66592_ep *ep)
395{
396 struct m66592 *m66592 = ep->m66592;
397 u16 pipenum = ep->pipenum;
398
399 if (pipenum == 0)
400 return;
401
402 if (ep->use_dma)
403 m66592->num_dma--;
404 ep->pipenum = 0;
405 ep->busy = 0;
406 ep->use_dma = 0;
407}
408
409static int alloc_pipe_config(struct m66592_ep *ep,
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +0900410 const struct usb_endpoint_descriptor *desc)
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +0900411{
412 struct m66592 *m66592 = ep->m66592;
413 struct m66592_pipe_info info;
414 int dma = 0;
415 int *counter;
416 int ret;
417
418 ep->desc = desc;
419
420 BUG_ON(ep->pipenum);
421
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +0900422 switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +0900423 case USB_ENDPOINT_XFER_BULK:
424 if (m66592->bulk >= M66592_MAX_NUM_BULK) {
425 if (m66592->isochronous >= M66592_MAX_NUM_ISOC) {
David Brownell00274922007-11-19 12:58:36 -0800426 pr_err("bulk pipe is insufficient\n");
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +0900427 return -ENODEV;
428 } else {
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +0900429 info.pipe = M66592_BASE_PIPENUM_ISOC
430 + m66592->isochronous;
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +0900431 counter = &m66592->isochronous;
432 }
433 } else {
434 info.pipe = M66592_BASE_PIPENUM_BULK + m66592->bulk;
435 counter = &m66592->bulk;
436 }
437 info.type = M66592_BULK;
438 dma = 1;
439 break;
440 case USB_ENDPOINT_XFER_INT:
441 if (m66592->interrupt >= M66592_MAX_NUM_INT) {
David Brownell00274922007-11-19 12:58:36 -0800442 pr_err("interrupt pipe is insufficient\n");
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +0900443 return -ENODEV;
444 }
445 info.pipe = M66592_BASE_PIPENUM_INT + m66592->interrupt;
446 info.type = M66592_INT;
447 counter = &m66592->interrupt;
448 break;
449 case USB_ENDPOINT_XFER_ISOC:
450 if (m66592->isochronous >= M66592_MAX_NUM_ISOC) {
David Brownell00274922007-11-19 12:58:36 -0800451 pr_err("isochronous pipe is insufficient\n");
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +0900452 return -ENODEV;
453 }
454 info.pipe = M66592_BASE_PIPENUM_ISOC + m66592->isochronous;
455 info.type = M66592_ISO;
456 counter = &m66592->isochronous;
457 break;
458 default:
David Brownell00274922007-11-19 12:58:36 -0800459 pr_err("unexpect xfer type\n");
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +0900460 return -EINVAL;
461 }
462 ep->type = info.type;
463
464 info.epnum = desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +0900465 info.maxpacket = le16_to_cpu(desc->wMaxPacketSize);
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +0900466 info.interval = desc->bInterval;
467 if (desc->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
468 info.dir_in = 1;
469 else
470 info.dir_in = 0;
471
472 ret = pipe_buffer_setting(m66592, &info);
473 if (ret < 0) {
David Brownell00274922007-11-19 12:58:36 -0800474 pr_err("pipe_buffer_setting fail\n");
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +0900475 return ret;
476 }
477
478 (*counter)++;
479 if ((counter == &m66592->isochronous) && info.type == M66592_BULK)
480 m66592->bulk++;
481
482 m66592_ep_setting(m66592, ep, desc, info.pipe, dma);
483 pipe_initialize(ep);
484
485 return 0;
486}
487
488static int free_pipe_config(struct m66592_ep *ep)
489{
490 struct m66592 *m66592 = ep->m66592;
491 struct m66592_pipe_info info;
492
493 info.pipe = ep->pipenum;
494 info.type = ep->type;
495 pipe_buffer_release(m66592, &info);
496 m66592_ep_release(ep);
497
498 return 0;
499}
500
501/*-------------------------------------------------------------------------*/
502static void pipe_irq_enable(struct m66592 *m66592, u16 pipenum)
503{
504 enable_irq_ready(m66592, pipenum);
505 enable_irq_nrdy(m66592, pipenum);
506}
507
508static void pipe_irq_disable(struct m66592 *m66592, u16 pipenum)
509{
510 disable_irq_ready(m66592, pipenum);
511 disable_irq_nrdy(m66592, pipenum);
512}
513
514/* if complete is true, gadget driver complete function is not call */
515static void control_end(struct m66592 *m66592, unsigned ccpl)
516{
517 m66592->ep[0].internal_ccpl = ccpl;
518 pipe_start(m66592, 0);
519 m66592_bset(m66592, M66592_CCPL, M66592_DCPCTR);
520}
521
522static void start_ep0_write(struct m66592_ep *ep, struct m66592_request *req)
523{
524 struct m66592 *m66592 = ep->m66592;
525
526 pipe_change(m66592, ep->pipenum);
527 m66592_mdfy(m66592, M66592_ISEL | M66592_PIPE0,
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +0900528 (M66592_ISEL | M66592_CURPIPE),
529 M66592_CFIFOSEL);
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +0900530 m66592_write(m66592, M66592_BCLR, ep->fifoctr);
531 if (req->req.length == 0) {
532 m66592_bset(m66592, M66592_BVAL, ep->fifoctr);
533 pipe_start(m66592, 0);
534 transfer_complete(ep, req, 0);
535 } else {
536 m66592_write(m66592, ~M66592_BEMP0, M66592_BEMPSTS);
537 irq_ep0_write(ep, req);
538 }
539}
540
541static void start_packet_write(struct m66592_ep *ep, struct m66592_request *req)
542{
543 struct m66592 *m66592 = ep->m66592;
544 u16 tmp;
545
546 pipe_change(m66592, ep->pipenum);
547 disable_irq_empty(m66592, ep->pipenum);
548 pipe_start(m66592, ep->pipenum);
549
550 tmp = m66592_read(m66592, ep->fifoctr);
551 if (unlikely((tmp & M66592_FRDY) == 0))
552 pipe_irq_enable(m66592, ep->pipenum);
553 else
554 irq_packet_write(ep, req);
555}
556
557static void start_packet_read(struct m66592_ep *ep, struct m66592_request *req)
558{
559 struct m66592 *m66592 = ep->m66592;
560 u16 pipenum = ep->pipenum;
561
562 if (ep->pipenum == 0) {
563 m66592_mdfy(m66592, M66592_PIPE0,
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +0900564 (M66592_ISEL | M66592_CURPIPE),
565 M66592_CFIFOSEL);
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +0900566 m66592_write(m66592, M66592_BCLR, ep->fifoctr);
567 pipe_start(m66592, pipenum);
568 pipe_irq_enable(m66592, pipenum);
569 } else {
570 if (ep->use_dma) {
571 m66592_bset(m66592, M66592_TRCLR, ep->fifosel);
572 pipe_change(m66592, pipenum);
573 m66592_bset(m66592, M66592_TRENB, ep->fifosel);
574 m66592_write(m66592,
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +0900575 (req->req.length + ep->ep.maxpacket - 1)
576 / ep->ep.maxpacket,
577 ep->fifotrn);
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +0900578 }
579 pipe_start(m66592, pipenum); /* trigger once */
580 pipe_irq_enable(m66592, pipenum);
581 }
582}
583
584static void start_packet(struct m66592_ep *ep, struct m66592_request *req)
585{
586 if (ep->desc->bEndpointAddress & USB_DIR_IN)
587 start_packet_write(ep, req);
588 else
589 start_packet_read(ep, req);
590}
591
592static void start_ep0(struct m66592_ep *ep, struct m66592_request *req)
593{
594 u16 ctsq;
595
596 ctsq = m66592_read(ep->m66592, M66592_INTSTS0) & M66592_CTSQ;
597
598 switch (ctsq) {
599 case M66592_CS_RDDS:
600 start_ep0_write(ep, req);
601 break;
602 case M66592_CS_WRDS:
603 start_packet_read(ep, req);
604 break;
605
606 case M66592_CS_WRND:
607 control_end(ep->m66592, 0);
608 break;
609 default:
David Brownell00274922007-11-19 12:58:36 -0800610 pr_err("start_ep0: unexpect ctsq(%x)\n", ctsq);
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +0900611 break;
612 }
613}
614
Yoshihiro Shimoda8c73aff2007-11-22 21:00:30 +0900615#if defined(CONFIG_SUPERH_BUILT_IN_M66592)
616static void init_controller(struct m66592 *m66592)
617{
Yoshihiro Shimoda8c73aff2007-11-22 21:00:30 +0900618 m66592_bset(m66592, M66592_HSE, M66592_SYSCFG); /* High spd */
619 m66592_bclr(m66592, M66592_USBE, M66592_SYSCFG);
620 m66592_bclr(m66592, M66592_DPRPU, M66592_SYSCFG);
621 m66592_bset(m66592, M66592_USBE, M66592_SYSCFG);
622
623 /* This is a workaound for SH7722 2nd cut */
624 m66592_bset(m66592, 0x8000, M66592_DVSTCTR);
625 m66592_bset(m66592, 0x1000, M66592_TESTMODE);
626 m66592_bclr(m66592, 0x8000, M66592_DVSTCTR);
627
628 m66592_bset(m66592, M66592_INTL, M66592_INTENB1);
629
630 m66592_write(m66592, 0, M66592_CFBCFG);
631 m66592_write(m66592, 0, M66592_D0FBCFG);
632 m66592_bset(m66592, endian, M66592_CFBCFG);
633 m66592_bset(m66592, endian, M66592_D0FBCFG);
634}
635#else /* #if defined(CONFIG_SUPERH_BUILT_IN_M66592) */
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +0900636static void init_controller(struct m66592 *m66592)
637{
638 m66592_bset(m66592, (vif & M66592_LDRV) | (endian & M66592_BIGEND),
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +0900639 M66592_PINCFG);
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +0900640 m66592_bset(m66592, M66592_HSE, M66592_SYSCFG); /* High spd */
641 m66592_mdfy(m66592, clock & M66592_XTAL, M66592_XTAL, M66592_SYSCFG);
642
643 m66592_bclr(m66592, M66592_USBE, M66592_SYSCFG);
644 m66592_bclr(m66592, M66592_DPRPU, M66592_SYSCFG);
645 m66592_bset(m66592, M66592_USBE, M66592_SYSCFG);
646
647 m66592_bset(m66592, M66592_XCKE, M66592_SYSCFG);
648
649 msleep(3);
650
651 m66592_bset(m66592, M66592_RCKE | M66592_PLLC, M66592_SYSCFG);
652
653 msleep(1);
654
655 m66592_bset(m66592, M66592_SCKE, M66592_SYSCFG);
656
657 m66592_bset(m66592, irq_sense & M66592_INTL, M66592_INTENB1);
658 m66592_write(m66592, M66592_BURST | M66592_CPU_ADR_RD_WR,
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +0900659 M66592_DMA0CFG);
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +0900660}
Yoshihiro Shimoda8c73aff2007-11-22 21:00:30 +0900661#endif /* #if defined(CONFIG_SUPERH_BUILT_IN_M66592) */
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +0900662
663static void disable_controller(struct m66592 *m66592)
664{
Magnus Dammaf5be792008-10-31 20:22:13 +0900665#if !defined(CONFIG_SUPERH_BUILT_IN_M66592)
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +0900666 m66592_bclr(m66592, M66592_SCKE, M66592_SYSCFG);
667 udelay(1);
668 m66592_bclr(m66592, M66592_PLLC, M66592_SYSCFG);
669 udelay(1);
670 m66592_bclr(m66592, M66592_RCKE, M66592_SYSCFG);
671 udelay(1);
672 m66592_bclr(m66592, M66592_XCKE, M66592_SYSCFG);
Yoshihiro Shimoda8c73aff2007-11-22 21:00:30 +0900673#endif
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +0900674}
675
676static void m66592_start_xclock(struct m66592 *m66592)
677{
Magnus Dammaf5be792008-10-31 20:22:13 +0900678#if !defined(CONFIG_SUPERH_BUILT_IN_M66592)
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +0900679 u16 tmp;
680
681 tmp = m66592_read(m66592, M66592_SYSCFG);
682 if (!(tmp & M66592_XCKE))
683 m66592_bset(m66592, M66592_XCKE, M66592_SYSCFG);
Yoshihiro Shimoda8c73aff2007-11-22 21:00:30 +0900684#endif
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +0900685}
686
687/*-------------------------------------------------------------------------*/
688static void transfer_complete(struct m66592_ep *ep,
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +0900689 struct m66592_request *req, int status)
690__releases(m66592->lock)
691__acquires(m66592->lock)
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +0900692{
693 int restart = 0;
694
695 if (unlikely(ep->pipenum == 0)) {
696 if (ep->internal_ccpl) {
697 ep->internal_ccpl = 0;
698 return;
699 }
700 }
701
702 list_del_init(&req->queue);
703 if (ep->m66592->gadget.speed == USB_SPEED_UNKNOWN)
704 req->req.status = -ESHUTDOWN;
705 else
706 req->req.status = status;
707
708 if (!list_empty(&ep->queue))
709 restart = 1;
710
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +0900711 spin_unlock(&ep->m66592->lock);
712 req->req.complete(&ep->ep, &req->req);
713 spin_lock(&ep->m66592->lock);
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +0900714
715 if (restart) {
716 req = list_entry(ep->queue.next, struct m66592_request, queue);
717 if (ep->desc)
718 start_packet(ep, req);
719 }
720}
721
722static void irq_ep0_write(struct m66592_ep *ep, struct m66592_request *req)
723{
724 int i;
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +0900725 u16 tmp;
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +0900726 unsigned bufsize;
727 size_t size;
728 void *buf;
729 u16 pipenum = ep->pipenum;
730 struct m66592 *m66592 = ep->m66592;
731
732 pipe_change(m66592, pipenum);
733 m66592_bset(m66592, M66592_ISEL, ep->fifosel);
734
735 i = 0;
736 do {
737 tmp = m66592_read(m66592, ep->fifoctr);
738 if (i++ > 100000) {
David Brownell00274922007-11-19 12:58:36 -0800739 pr_err("pipe0 is busy. maybe cpu i/o bus "
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +0900740 "conflict. please power off this controller.");
741 return;
742 }
743 ndelay(1);
744 } while ((tmp & M66592_FRDY) == 0);
745
746 /* prepare parameters */
747 bufsize = get_buffer_size(m66592, pipenum);
748 buf = req->req.buf + req->req.actual;
749 size = min(bufsize, req->req.length - req->req.actual);
750
751 /* write fifo */
752 if (req->req.buf) {
753 if (size > 0)
754 m66592_write_fifo(m66592, ep->fifoaddr, buf, size);
755 if ((size == 0) || ((size % ep->ep.maxpacket) != 0))
756 m66592_bset(m66592, M66592_BVAL, ep->fifoctr);
757 }
758
759 /* update parameters */
760 req->req.actual += size;
761
762 /* check transfer finish */
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +0900763 if ((!req->req.zero && (req->req.actual == req->req.length))
764 || (size % ep->ep.maxpacket)
765 || (size == 0)) {
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +0900766 disable_irq_ready(m66592, pipenum);
767 disable_irq_empty(m66592, pipenum);
768 } else {
769 disable_irq_ready(m66592, pipenum);
770 enable_irq_empty(m66592, pipenum);
771 }
772 pipe_start(m66592, pipenum);
773}
774
775static void irq_packet_write(struct m66592_ep *ep, struct m66592_request *req)
776{
777 u16 tmp;
778 unsigned bufsize;
779 size_t size;
780 void *buf;
781 u16 pipenum = ep->pipenum;
782 struct m66592 *m66592 = ep->m66592;
783
784 pipe_change(m66592, pipenum);
785 tmp = m66592_read(m66592, ep->fifoctr);
786 if (unlikely((tmp & M66592_FRDY) == 0)) {
787 pipe_stop(m66592, pipenum);
788 pipe_irq_disable(m66592, pipenum);
David Brownell00274922007-11-19 12:58:36 -0800789 pr_err("write fifo not ready. pipnum=%d\n", pipenum);
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +0900790 return;
791 }
792
793 /* prepare parameters */
794 bufsize = get_buffer_size(m66592, pipenum);
795 buf = req->req.buf + req->req.actual;
796 size = min(bufsize, req->req.length - req->req.actual);
797
798 /* write fifo */
799 if (req->req.buf) {
800 m66592_write_fifo(m66592, ep->fifoaddr, buf, size);
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +0900801 if ((size == 0)
802 || ((size % ep->ep.maxpacket) != 0)
803 || ((bufsize != ep->ep.maxpacket)
804 && (bufsize > size)))
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +0900805 m66592_bset(m66592, M66592_BVAL, ep->fifoctr);
806 }
807
808 /* update parameters */
809 req->req.actual += size;
810 /* check transfer finish */
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +0900811 if ((!req->req.zero && (req->req.actual == req->req.length))
812 || (size % ep->ep.maxpacket)
813 || (size == 0)) {
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +0900814 disable_irq_ready(m66592, pipenum);
815 enable_irq_empty(m66592, pipenum);
816 } else {
817 disable_irq_empty(m66592, pipenum);
818 pipe_irq_enable(m66592, pipenum);
819 }
820}
821
822static void irq_packet_read(struct m66592_ep *ep, struct m66592_request *req)
823{
824 u16 tmp;
825 int rcv_len, bufsize, req_len;
826 int size;
827 void *buf;
828 u16 pipenum = ep->pipenum;
829 struct m66592 *m66592 = ep->m66592;
830 int finish = 0;
831
832 pipe_change(m66592, pipenum);
833 tmp = m66592_read(m66592, ep->fifoctr);
834 if (unlikely((tmp & M66592_FRDY) == 0)) {
835 req->req.status = -EPIPE;
836 pipe_stop(m66592, pipenum);
837 pipe_irq_disable(m66592, pipenum);
David Brownell00274922007-11-19 12:58:36 -0800838 pr_err("read fifo not ready");
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +0900839 return;
840 }
841
842 /* prepare parameters */
843 rcv_len = tmp & M66592_DTLN;
844 bufsize = get_buffer_size(m66592, pipenum);
845
846 buf = req->req.buf + req->req.actual;
847 req_len = req->req.length - req->req.actual;
848 if (rcv_len < bufsize)
849 size = min(rcv_len, req_len);
850 else
851 size = min(bufsize, req_len);
852
853 /* update parameters */
854 req->req.actual += size;
855
856 /* check transfer finish */
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +0900857 if ((!req->req.zero && (req->req.actual == req->req.length))
858 || (size % ep->ep.maxpacket)
859 || (size == 0)) {
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +0900860 pipe_stop(m66592, pipenum);
861 pipe_irq_disable(m66592, pipenum);
862 finish = 1;
863 }
864
865 /* read fifo */
866 if (req->req.buf) {
867 if (size == 0)
868 m66592_write(m66592, M66592_BCLR, ep->fifoctr);
869 else
870 m66592_read_fifo(m66592, ep->fifoaddr, buf, size);
871 }
872
873 if ((ep->pipenum != 0) && finish)
874 transfer_complete(ep, req, 0);
875}
876
877static void irq_pipe_ready(struct m66592 *m66592, u16 status, u16 enb)
878{
879 u16 check;
880 u16 pipenum;
881 struct m66592_ep *ep;
882 struct m66592_request *req;
883
884 if ((status & M66592_BRDY0) && (enb & M66592_BRDY0)) {
885 m66592_write(m66592, ~M66592_BRDY0, M66592_BRDYSTS);
886 m66592_mdfy(m66592, M66592_PIPE0, M66592_CURPIPE,
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +0900887 M66592_CFIFOSEL);
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +0900888
889 ep = &m66592->ep[0];
890 req = list_entry(ep->queue.next, struct m66592_request, queue);
891 irq_packet_read(ep, req);
892 } else {
893 for (pipenum = 1; pipenum < M66592_MAX_NUM_PIPE; pipenum++) {
894 check = 1 << pipenum;
895 if ((status & check) && (enb & check)) {
896 m66592_write(m66592, ~check, M66592_BRDYSTS);
897 ep = m66592->pipenum2ep[pipenum];
898 req = list_entry(ep->queue.next,
899 struct m66592_request, queue);
900 if (ep->desc->bEndpointAddress & USB_DIR_IN)
901 irq_packet_write(ep, req);
902 else
903 irq_packet_read(ep, req);
904 }
905 }
906 }
907}
908
909static void irq_pipe_empty(struct m66592 *m66592, u16 status, u16 enb)
910{
911 u16 tmp;
912 u16 check;
913 u16 pipenum;
914 struct m66592_ep *ep;
915 struct m66592_request *req;
916
917 if ((status & M66592_BEMP0) && (enb & M66592_BEMP0)) {
918 m66592_write(m66592, ~M66592_BEMP0, M66592_BEMPSTS);
919
920 ep = &m66592->ep[0];
921 req = list_entry(ep->queue.next, struct m66592_request, queue);
922 irq_ep0_write(ep, req);
923 } else {
924 for (pipenum = 1; pipenum < M66592_MAX_NUM_PIPE; pipenum++) {
925 check = 1 << pipenum;
926 if ((status & check) && (enb & check)) {
927 m66592_write(m66592, ~check, M66592_BEMPSTS);
928 tmp = control_reg_get(m66592, pipenum);
929 if ((tmp & M66592_INBUFM) == 0) {
930 disable_irq_empty(m66592, pipenum);
931 pipe_irq_disable(m66592, pipenum);
932 pipe_stop(m66592, pipenum);
933 ep = m66592->pipenum2ep[pipenum];
934 req = list_entry(ep->queue.next,
935 struct m66592_request,
936 queue);
937 if (!list_empty(&ep->queue))
938 transfer_complete(ep, req, 0);
939 }
940 }
941 }
942 }
943}
944
945static void get_status(struct m66592 *m66592, struct usb_ctrlrequest *ctrl)
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +0900946__releases(m66592->lock)
947__acquires(m66592->lock)
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +0900948{
949 struct m66592_ep *ep;
950 u16 pid;
951 u16 status = 0;
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +0900952 u16 w_index = le16_to_cpu(ctrl->wIndex);
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +0900953
954 switch (ctrl->bRequestType & USB_RECIP_MASK) {
955 case USB_RECIP_DEVICE:
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +0900956 status = 1 << USB_DEVICE_SELF_POWERED;
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +0900957 break;
958 case USB_RECIP_INTERFACE:
959 status = 0;
960 break;
961 case USB_RECIP_ENDPOINT:
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +0900962 ep = m66592->epaddr2ep[w_index & USB_ENDPOINT_NUMBER_MASK];
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +0900963 pid = control_reg_get_pid(m66592, ep->pipenum);
964 if (pid == M66592_PID_STALL)
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +0900965 status = 1 << USB_ENDPOINT_HALT;
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +0900966 else
967 status = 0;
968 break;
969 default:
970 pipe_stall(m66592, 0);
971 return; /* exit */
972 }
973
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +0900974 m66592->ep0_data = cpu_to_le16(status);
975 m66592->ep0_req->buf = &m66592->ep0_data;
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +0900976 m66592->ep0_req->length = 2;
Al Viro53b67952007-07-15 20:59:22 +0100977 /* AV: what happens if we get called again before that gets through? */
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +0900978 spin_unlock(&m66592->lock);
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +0900979 m66592_queue(m66592->gadget.ep0, m66592->ep0_req, GFP_KERNEL);
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +0900980 spin_lock(&m66592->lock);
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +0900981}
982
983static void clear_feature(struct m66592 *m66592, struct usb_ctrlrequest *ctrl)
984{
985 switch (ctrl->bRequestType & USB_RECIP_MASK) {
986 case USB_RECIP_DEVICE:
987 control_end(m66592, 1);
988 break;
989 case USB_RECIP_INTERFACE:
990 control_end(m66592, 1);
991 break;
992 case USB_RECIP_ENDPOINT: {
993 struct m66592_ep *ep;
994 struct m66592_request *req;
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +0900995 u16 w_index = le16_to_cpu(ctrl->wIndex);
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +0900996
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +0900997 ep = m66592->epaddr2ep[w_index & USB_ENDPOINT_NUMBER_MASK];
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +0900998 pipe_stop(m66592, ep->pipenum);
999 control_reg_sqclr(m66592, ep->pipenum);
1000
1001 control_end(m66592, 1);
1002
1003 req = list_entry(ep->queue.next,
1004 struct m66592_request, queue);
1005 if (ep->busy) {
1006 ep->busy = 0;
1007 if (list_empty(&ep->queue))
1008 break;
1009 start_packet(ep, req);
1010 } else if (!list_empty(&ep->queue))
1011 pipe_start(m66592, ep->pipenum);
1012 }
1013 break;
1014 default:
1015 pipe_stall(m66592, 0);
1016 break;
1017 }
1018}
1019
1020static void set_feature(struct m66592 *m66592, struct usb_ctrlrequest *ctrl)
1021{
1022
1023 switch (ctrl->bRequestType & USB_RECIP_MASK) {
1024 case USB_RECIP_DEVICE:
1025 control_end(m66592, 1);
1026 break;
1027 case USB_RECIP_INTERFACE:
1028 control_end(m66592, 1);
1029 break;
1030 case USB_RECIP_ENDPOINT: {
1031 struct m66592_ep *ep;
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +09001032 u16 w_index = le16_to_cpu(ctrl->wIndex);
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +09001033
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +09001034 ep = m66592->epaddr2ep[w_index & USB_ENDPOINT_NUMBER_MASK];
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +09001035 pipe_stall(m66592, ep->pipenum);
1036
1037 control_end(m66592, 1);
1038 }
1039 break;
1040 default:
1041 pipe_stall(m66592, 0);
1042 break;
1043 }
1044}
1045
1046/* if return value is true, call class driver's setup() */
1047static int setup_packet(struct m66592 *m66592, struct usb_ctrlrequest *ctrl)
1048{
1049 u16 *p = (u16 *)ctrl;
1050 unsigned long offset = M66592_USBREQ;
1051 int i, ret = 0;
1052
1053 /* read fifo */
1054 m66592_write(m66592, ~M66592_VALID, M66592_INTSTS0);
1055
1056 for (i = 0; i < 4; i++)
1057 p[i] = m66592_read(m66592, offset + i*2);
1058
1059 /* check request */
1060 if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) {
1061 switch (ctrl->bRequest) {
1062 case USB_REQ_GET_STATUS:
1063 get_status(m66592, ctrl);
1064 break;
1065 case USB_REQ_CLEAR_FEATURE:
1066 clear_feature(m66592, ctrl);
1067 break;
1068 case USB_REQ_SET_FEATURE:
1069 set_feature(m66592, ctrl);
1070 break;
1071 default:
1072 ret = 1;
1073 break;
1074 }
1075 } else
1076 ret = 1;
1077 return ret;
1078}
1079
1080static void m66592_update_usb_speed(struct m66592 *m66592)
1081{
1082 u16 speed = get_usb_speed(m66592);
1083
1084 switch (speed) {
1085 case M66592_HSMODE:
1086 m66592->gadget.speed = USB_SPEED_HIGH;
1087 break;
1088 case M66592_FSMODE:
1089 m66592->gadget.speed = USB_SPEED_FULL;
1090 break;
1091 default:
1092 m66592->gadget.speed = USB_SPEED_UNKNOWN;
David Brownell00274922007-11-19 12:58:36 -08001093 pr_err("USB speed unknown\n");
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +09001094 }
1095}
1096
1097static void irq_device_state(struct m66592 *m66592)
1098{
1099 u16 dvsq;
1100
1101 dvsq = m66592_read(m66592, M66592_INTSTS0) & M66592_DVSQ;
1102 m66592_write(m66592, ~M66592_DVST, M66592_INTSTS0);
1103
1104 if (dvsq == M66592_DS_DFLT) { /* bus reset */
1105 m66592->driver->disconnect(&m66592->gadget);
1106 m66592_update_usb_speed(m66592);
1107 }
1108 if (m66592->old_dvsq == M66592_DS_CNFG && dvsq != M66592_DS_CNFG)
1109 m66592_update_usb_speed(m66592);
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +09001110 if ((dvsq == M66592_DS_CNFG || dvsq == M66592_DS_ADDS)
1111 && m66592->gadget.speed == USB_SPEED_UNKNOWN)
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +09001112 m66592_update_usb_speed(m66592);
1113
1114 m66592->old_dvsq = dvsq;
1115}
1116
1117static void irq_control_stage(struct m66592 *m66592)
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +09001118__releases(m66592->lock)
1119__acquires(m66592->lock)
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +09001120{
1121 struct usb_ctrlrequest ctrl;
1122 u16 ctsq;
1123
1124 ctsq = m66592_read(m66592, M66592_INTSTS0) & M66592_CTSQ;
1125 m66592_write(m66592, ~M66592_CTRT, M66592_INTSTS0);
1126
1127 switch (ctsq) {
1128 case M66592_CS_IDST: {
1129 struct m66592_ep *ep;
1130 struct m66592_request *req;
1131 ep = &m66592->ep[0];
1132 req = list_entry(ep->queue.next, struct m66592_request, queue);
1133 transfer_complete(ep, req, 0);
1134 }
1135 break;
1136
1137 case M66592_CS_RDDS:
1138 case M66592_CS_WRDS:
1139 case M66592_CS_WRND:
1140 if (setup_packet(m66592, &ctrl)) {
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +09001141 spin_unlock(&m66592->lock);
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +09001142 if (m66592->driver->setup(&m66592->gadget, &ctrl) < 0)
1143 pipe_stall(m66592, 0);
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +09001144 spin_lock(&m66592->lock);
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +09001145 }
1146 break;
1147 case M66592_CS_RDSS:
1148 case M66592_CS_WRSS:
1149 control_end(m66592, 0);
1150 break;
1151 default:
David Brownell00274922007-11-19 12:58:36 -08001152 pr_err("ctrl_stage: unexpect ctsq(%x)\n", ctsq);
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +09001153 break;
1154 }
1155}
1156
1157static irqreturn_t m66592_irq(int irq, void *_m66592)
1158{
1159 struct m66592 *m66592 = _m66592;
1160 u16 intsts0;
1161 u16 intenb0;
1162 u16 brdysts, nrdysts, bempsts;
1163 u16 brdyenb, nrdyenb, bempenb;
1164 u16 savepipe;
1165 u16 mask0;
1166
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +09001167 spin_lock(&m66592->lock);
1168
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +09001169 intsts0 = m66592_read(m66592, M66592_INTSTS0);
1170 intenb0 = m66592_read(m66592, M66592_INTENB0);
1171
Yoshihiro Shimoda8c73aff2007-11-22 21:00:30 +09001172#if defined(CONFIG_SUPERH_BUILT_IN_M66592)
1173 if (!intsts0 && !intenb0) {
1174 /*
1175 * When USB clock stops, it cannot read register. Even if a
1176 * clock stops, the interrupt occurs. So this driver turn on
1177 * a clock by this timing and do re-reading of register.
1178 */
1179 m66592_start_xclock(m66592);
1180 intsts0 = m66592_read(m66592, M66592_INTSTS0);
1181 intenb0 = m66592_read(m66592, M66592_INTENB0);
1182 }
1183#endif
1184
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +09001185 savepipe = m66592_read(m66592, M66592_CFIFOSEL);
1186
1187 mask0 = intsts0 & intenb0;
1188 if (mask0) {
1189 brdysts = m66592_read(m66592, M66592_BRDYSTS);
1190 nrdysts = m66592_read(m66592, M66592_NRDYSTS);
1191 bempsts = m66592_read(m66592, M66592_BEMPSTS);
1192 brdyenb = m66592_read(m66592, M66592_BRDYENB);
1193 nrdyenb = m66592_read(m66592, M66592_NRDYENB);
1194 bempenb = m66592_read(m66592, M66592_BEMPENB);
1195
1196 if (mask0 & M66592_VBINT) {
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +09001197 m66592_write(m66592, 0xffff & ~M66592_VBINT,
1198 M66592_INTSTS0);
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +09001199 m66592_start_xclock(m66592);
1200
1201 /* start vbus sampling */
1202 m66592->old_vbus = m66592_read(m66592, M66592_INTSTS0)
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +09001203 & M66592_VBSTS;
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +09001204 m66592->scount = M66592_MAX_SAMPLING;
1205
1206 mod_timer(&m66592->timer,
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +09001207 jiffies + msecs_to_jiffies(50));
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +09001208 }
1209 if (intsts0 & M66592_DVSQ)
1210 irq_device_state(m66592);
1211
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +09001212 if ((intsts0 & M66592_BRDY) && (intenb0 & M66592_BRDYE)
1213 && (brdysts & brdyenb)) {
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +09001214 irq_pipe_ready(m66592, brdysts, brdyenb);
1215 }
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +09001216 if ((intsts0 & M66592_BEMP) && (intenb0 & M66592_BEMPE)
1217 && (bempsts & bempenb)) {
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +09001218 irq_pipe_empty(m66592, bempsts, bempenb);
1219 }
1220
1221 if (intsts0 & M66592_CTRT)
1222 irq_control_stage(m66592);
1223 }
1224
1225 m66592_write(m66592, savepipe, M66592_CFIFOSEL);
1226
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +09001227 spin_unlock(&m66592->lock);
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +09001228 return IRQ_HANDLED;
1229}
1230
1231static void m66592_timer(unsigned long _m66592)
1232{
1233 struct m66592 *m66592 = (struct m66592 *)_m66592;
1234 unsigned long flags;
1235 u16 tmp;
1236
1237 spin_lock_irqsave(&m66592->lock, flags);
1238 tmp = m66592_read(m66592, M66592_SYSCFG);
1239 if (!(tmp & M66592_RCKE)) {
1240 m66592_bset(m66592, M66592_RCKE | M66592_PLLC, M66592_SYSCFG);
1241 udelay(10);
1242 m66592_bset(m66592, M66592_SCKE, M66592_SYSCFG);
1243 }
1244 if (m66592->scount > 0) {
1245 tmp = m66592_read(m66592, M66592_INTSTS0) & M66592_VBSTS;
1246 if (tmp == m66592->old_vbus) {
1247 m66592->scount--;
1248 if (m66592->scount == 0) {
1249 if (tmp == M66592_VBSTS)
1250 m66592_usb_connect(m66592);
1251 else
1252 m66592_usb_disconnect(m66592);
1253 } else {
1254 mod_timer(&m66592->timer,
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +09001255 jiffies + msecs_to_jiffies(50));
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +09001256 }
1257 } else {
1258 m66592->scount = M66592_MAX_SAMPLING;
1259 m66592->old_vbus = tmp;
1260 mod_timer(&m66592->timer,
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +09001261 jiffies + msecs_to_jiffies(50));
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +09001262 }
1263 }
1264 spin_unlock_irqrestore(&m66592->lock, flags);
1265}
1266
1267/*-------------------------------------------------------------------------*/
1268static int m66592_enable(struct usb_ep *_ep,
1269 const struct usb_endpoint_descriptor *desc)
1270{
1271 struct m66592_ep *ep;
1272
1273 ep = container_of(_ep, struct m66592_ep, ep);
1274 return alloc_pipe_config(ep, desc);
1275}
1276
1277static int m66592_disable(struct usb_ep *_ep)
1278{
1279 struct m66592_ep *ep;
1280 struct m66592_request *req;
1281 unsigned long flags;
1282
1283 ep = container_of(_ep, struct m66592_ep, ep);
1284 BUG_ON(!ep);
1285
1286 while (!list_empty(&ep->queue)) {
1287 req = list_entry(ep->queue.next, struct m66592_request, queue);
1288 spin_lock_irqsave(&ep->m66592->lock, flags);
1289 transfer_complete(ep, req, -ECONNRESET);
1290 spin_unlock_irqrestore(&ep->m66592->lock, flags);
1291 }
1292
1293 pipe_irq_disable(ep->m66592, ep->pipenum);
1294 return free_pipe_config(ep);
1295}
1296
1297static struct usb_request *m66592_alloc_request(struct usb_ep *_ep,
1298 gfp_t gfp_flags)
1299{
1300 struct m66592_request *req;
1301
1302 req = kzalloc(sizeof(struct m66592_request), gfp_flags);
1303 if (!req)
1304 return NULL;
1305
1306 INIT_LIST_HEAD(&req->queue);
1307
1308 return &req->req;
1309}
1310
1311static void m66592_free_request(struct usb_ep *_ep, struct usb_request *_req)
1312{
1313 struct m66592_request *req;
1314
1315 req = container_of(_req, struct m66592_request, req);
1316 kfree(req);
1317}
1318
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +09001319static int m66592_queue(struct usb_ep *_ep, struct usb_request *_req,
1320 gfp_t gfp_flags)
1321{
1322 struct m66592_ep *ep;
1323 struct m66592_request *req;
1324 unsigned long flags;
1325 int request = 0;
1326
1327 ep = container_of(_ep, struct m66592_ep, ep);
1328 req = container_of(_req, struct m66592_request, req);
1329
1330 if (ep->m66592->gadget.speed == USB_SPEED_UNKNOWN)
1331 return -ESHUTDOWN;
1332
1333 spin_lock_irqsave(&ep->m66592->lock, flags);
1334
1335 if (list_empty(&ep->queue))
1336 request = 1;
1337
1338 list_add_tail(&req->queue, &ep->queue);
1339 req->req.actual = 0;
1340 req->req.status = -EINPROGRESS;
1341
David Brownella9475222007-07-30 12:31:07 -07001342 if (ep->desc == NULL) /* control */
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +09001343 start_ep0(ep, req);
1344 else {
1345 if (request && !ep->busy)
1346 start_packet(ep, req);
1347 }
1348
1349 spin_unlock_irqrestore(&ep->m66592->lock, flags);
1350
1351 return 0;
1352}
1353
1354static int m66592_dequeue(struct usb_ep *_ep, struct usb_request *_req)
1355{
1356 struct m66592_ep *ep;
1357 struct m66592_request *req;
1358 unsigned long flags;
1359
1360 ep = container_of(_ep, struct m66592_ep, ep);
1361 req = container_of(_req, struct m66592_request, req);
1362
1363 spin_lock_irqsave(&ep->m66592->lock, flags);
1364 if (!list_empty(&ep->queue))
1365 transfer_complete(ep, req, -ECONNRESET);
1366 spin_unlock_irqrestore(&ep->m66592->lock, flags);
1367
1368 return 0;
1369}
1370
1371static int m66592_set_halt(struct usb_ep *_ep, int value)
1372{
1373 struct m66592_ep *ep;
1374 struct m66592_request *req;
1375 unsigned long flags;
1376 int ret = 0;
1377
1378 ep = container_of(_ep, struct m66592_ep, ep);
1379 req = list_entry(ep->queue.next, struct m66592_request, queue);
1380
1381 spin_lock_irqsave(&ep->m66592->lock, flags);
1382 if (!list_empty(&ep->queue)) {
1383 ret = -EAGAIN;
1384 goto out;
1385 }
1386 if (value) {
1387 ep->busy = 1;
1388 pipe_stall(ep->m66592, ep->pipenum);
1389 } else {
1390 ep->busy = 0;
1391 pipe_stop(ep->m66592, ep->pipenum);
1392 }
1393
1394out:
1395 spin_unlock_irqrestore(&ep->m66592->lock, flags);
1396 return ret;
1397}
1398
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +09001399static void m66592_fifo_flush(struct usb_ep *_ep)
1400{
1401 struct m66592_ep *ep;
1402 unsigned long flags;
1403
1404 ep = container_of(_ep, struct m66592_ep, ep);
1405 spin_lock_irqsave(&ep->m66592->lock, flags);
1406 if (list_empty(&ep->queue) && !ep->busy) {
1407 pipe_stop(ep->m66592, ep->pipenum);
1408 m66592_bclr(ep->m66592, M66592_BCLR, ep->fifoctr);
1409 }
1410 spin_unlock_irqrestore(&ep->m66592->lock, flags);
1411}
1412
1413static struct usb_ep_ops m66592_ep_ops = {
1414 .enable = m66592_enable,
1415 .disable = m66592_disable,
1416
1417 .alloc_request = m66592_alloc_request,
1418 .free_request = m66592_free_request,
1419
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +09001420 .queue = m66592_queue,
1421 .dequeue = m66592_dequeue,
1422
1423 .set_halt = m66592_set_halt,
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +09001424 .fifo_flush = m66592_fifo_flush,
1425};
1426
1427/*-------------------------------------------------------------------------*/
1428static struct m66592 *the_controller;
1429
1430int usb_gadget_register_driver(struct usb_gadget_driver *driver)
1431{
1432 struct m66592 *m66592 = the_controller;
1433 int retval;
1434
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +09001435 if (!driver
1436 || driver->speed != USB_SPEED_HIGH
1437 || !driver->bind
1438 || !driver->setup)
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +09001439 return -EINVAL;
1440 if (!m66592)
1441 return -ENODEV;
1442 if (m66592->driver)
1443 return -EBUSY;
1444
1445 /* hook up the driver */
1446 driver->driver.bus = NULL;
1447 m66592->driver = driver;
1448 m66592->gadget.dev.driver = &driver->driver;
1449
1450 retval = device_add(&m66592->gadget.dev);
1451 if (retval) {
David Brownell00274922007-11-19 12:58:36 -08001452 pr_err("device_add error (%d)\n", retval);
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +09001453 goto error;
1454 }
1455
1456 retval = driver->bind (&m66592->gadget);
1457 if (retval) {
David Brownell00274922007-11-19 12:58:36 -08001458 pr_err("bind to driver error (%d)\n", retval);
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +09001459 device_del(&m66592->gadget.dev);
1460 goto error;
1461 }
1462
1463 m66592_bset(m66592, M66592_VBSE | M66592_URST, M66592_INTENB0);
1464 if (m66592_read(m66592, M66592_INTSTS0) & M66592_VBSTS) {
1465 m66592_start_xclock(m66592);
1466 /* start vbus sampling */
1467 m66592->old_vbus = m66592_read(m66592,
1468 M66592_INTSTS0) & M66592_VBSTS;
1469 m66592->scount = M66592_MAX_SAMPLING;
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +09001470 mod_timer(&m66592->timer, jiffies + msecs_to_jiffies(50));
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +09001471 }
1472
1473 return 0;
1474
1475error:
1476 m66592->driver = NULL;
1477 m66592->gadget.dev.driver = NULL;
1478
1479 return retval;
1480}
1481EXPORT_SYMBOL(usb_gadget_register_driver);
1482
1483int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
1484{
1485 struct m66592 *m66592 = the_controller;
1486 unsigned long flags;
1487
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +09001488 if (driver != m66592->driver || !driver->unbind)
1489 return -EINVAL;
1490
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +09001491 spin_lock_irqsave(&m66592->lock, flags);
1492 if (m66592->gadget.speed != USB_SPEED_UNKNOWN)
1493 m66592_usb_disconnect(m66592);
1494 spin_unlock_irqrestore(&m66592->lock, flags);
1495
1496 m66592_bclr(m66592, M66592_VBSE | M66592_URST, M66592_INTENB0);
1497
1498 driver->unbind(&m66592->gadget);
Patrik Sevalliuseb0be472007-11-20 09:32:00 -08001499 m66592->gadget.dev.driver = NULL;
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +09001500
1501 init_controller(m66592);
1502 disable_controller(m66592);
1503
1504 device_del(&m66592->gadget.dev);
1505 m66592->driver = NULL;
1506 return 0;
1507}
1508EXPORT_SYMBOL(usb_gadget_unregister_driver);
1509
1510/*-------------------------------------------------------------------------*/
1511static int m66592_get_frame(struct usb_gadget *_gadget)
1512{
1513 struct m66592 *m66592 = gadget_to_m66592(_gadget);
1514 return m66592_read(m66592, M66592_FRMNUM) & 0x03FF;
1515}
1516
1517static struct usb_gadget_ops m66592_gadget_ops = {
1518 .get_frame = m66592_get_frame,
1519};
1520
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +09001521static int __exit m66592_remove(struct platform_device *pdev)
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +09001522{
1523 struct m66592 *m66592 = dev_get_drvdata(&pdev->dev);
1524
1525 del_timer_sync(&m66592->timer);
1526 iounmap(m66592->reg);
1527 free_irq(platform_get_irq(pdev, 0), m66592);
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +09001528 m66592_free_request(&m66592->ep[0].ep, m66592->ep0_req);
Magnus Dammaf5be792008-10-31 20:22:13 +09001529#if defined(CONFIG_SUPERH_BUILT_IN_M66592) && defined(CONFIG_HAVE_CLK)
1530 clk_disable(m66592->clk);
1531 clk_put(m66592->clk);
1532#endif
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +09001533 kfree(m66592);
1534 return 0;
1535}
1536
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +09001537static void nop_completion(struct usb_ep *ep, struct usb_request *r)
1538{
1539}
1540
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +09001541static int __init m66592_probe(struct platform_device *pdev)
1542{
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +09001543 struct resource *res;
1544 int irq;
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +09001545 void __iomem *reg = NULL;
1546 struct m66592 *m66592 = NULL;
Magnus Dammaf5be792008-10-31 20:22:13 +09001547#if defined(CONFIG_SUPERH_BUILT_IN_M66592) && defined(CONFIG_HAVE_CLK)
1548 char clk_name[8];
1549#endif
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +09001550 int ret = 0;
1551 int i;
1552
Magnus Damm0a2e5b92008-11-13 15:46:37 +09001553 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +09001554 if (!res) {
1555 ret = -ENODEV;
Magnus Damm0a2e5b92008-11-13 15:46:37 +09001556 pr_err("platform_get_resource error.\n");
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +09001557 goto clean_up;
1558 }
1559
1560 irq = platform_get_irq(pdev, 0);
1561 if (irq < 0) {
1562 ret = -ENODEV;
David Brownell00274922007-11-19 12:58:36 -08001563 pr_err("platform_get_irq error.\n");
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +09001564 goto clean_up;
1565 }
1566
Magnus Damm0a2e5b92008-11-13 15:46:37 +09001567 reg = ioremap(res->start, resource_size(res));
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +09001568 if (reg == NULL) {
1569 ret = -ENOMEM;
David Brownell00274922007-11-19 12:58:36 -08001570 pr_err("ioremap error.\n");
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +09001571 goto clean_up;
1572 }
1573
1574 /* initialize ucd */
1575 m66592 = kzalloc(sizeof(struct m66592), GFP_KERNEL);
1576 if (m66592 == NULL) {
David Brownell00274922007-11-19 12:58:36 -08001577 pr_err("kzalloc error\n");
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +09001578 goto clean_up;
1579 }
1580
1581 spin_lock_init(&m66592->lock);
1582 dev_set_drvdata(&pdev->dev, m66592);
1583
1584 m66592->gadget.ops = &m66592_gadget_ops;
1585 device_initialize(&m66592->gadget.dev);
Paul Mundt836e4b12008-07-29 22:33:43 -07001586 dev_set_name(&m66592->gadget.dev, "gadget");
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +09001587 m66592->gadget.is_dualspeed = 1;
1588 m66592->gadget.dev.parent = &pdev->dev;
1589 m66592->gadget.dev.dma_mask = pdev->dev.dma_mask;
1590 m66592->gadget.dev.release = pdev->dev.release;
1591 m66592->gadget.name = udc_name;
1592
1593 init_timer(&m66592->timer);
1594 m66592->timer.function = m66592_timer;
1595 m66592->timer.data = (unsigned long)m66592;
1596 m66592->reg = reg;
1597
Yoshihiro Shimoda15a1d5c2007-05-30 22:06:00 +09001598 ret = request_irq(irq, m66592_irq, IRQF_DISABLED | IRQF_SHARED,
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +09001599 udc_name, m66592);
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +09001600 if (ret < 0) {
David Brownell00274922007-11-19 12:58:36 -08001601 pr_err("request_irq error (%d)\n", ret);
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +09001602 goto clean_up;
1603 }
1604
Magnus Dammaf5be792008-10-31 20:22:13 +09001605#if defined(CONFIG_SUPERH_BUILT_IN_M66592) && defined(CONFIG_HAVE_CLK)
1606 snprintf(clk_name, sizeof(clk_name), "usbf%d", pdev->id);
1607 m66592->clk = clk_get(&pdev->dev, clk_name);
1608 if (IS_ERR(m66592->clk)) {
1609 dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name);
1610 ret = PTR_ERR(m66592->clk);
1611 goto clean_up2;
1612 }
1613 clk_enable(m66592->clk);
1614#endif
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +09001615 INIT_LIST_HEAD(&m66592->gadget.ep_list);
1616 m66592->gadget.ep0 = &m66592->ep[0].ep;
1617 INIT_LIST_HEAD(&m66592->gadget.ep0->ep_list);
1618 for (i = 0; i < M66592_MAX_NUM_PIPE; i++) {
1619 struct m66592_ep *ep = &m66592->ep[i];
1620
1621 if (i != 0) {
1622 INIT_LIST_HEAD(&m66592->ep[i].ep.ep_list);
1623 list_add_tail(&m66592->ep[i].ep.ep_list,
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +09001624 &m66592->gadget.ep_list);
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +09001625 }
1626 ep->m66592 = m66592;
1627 INIT_LIST_HEAD(&ep->queue);
1628 ep->ep.name = m66592_ep_name[i];
1629 ep->ep.ops = &m66592_ep_ops;
1630 ep->ep.maxpacket = 512;
1631 }
1632 m66592->ep[0].ep.maxpacket = 64;
1633 m66592->ep[0].pipenum = 0;
1634 m66592->ep[0].fifoaddr = M66592_CFIFO;
1635 m66592->ep[0].fifosel = M66592_CFIFOSEL;
1636 m66592->ep[0].fifoctr = M66592_CFIFOCTR;
1637 m66592->ep[0].fifotrn = 0;
1638 m66592->ep[0].pipectr = get_pipectr_addr(0);
1639 m66592->pipenum2ep[0] = &m66592->ep[0];
1640 m66592->epaddr2ep[0] = &m66592->ep[0];
1641
1642 the_controller = m66592;
1643
1644 m66592->ep0_req = m66592_alloc_request(&m66592->ep[0].ep, GFP_KERNEL);
1645 if (m66592->ep0_req == NULL)
Magnus Dammaf5be792008-10-31 20:22:13 +09001646 goto clean_up3;
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +09001647 m66592->ep0_req->complete = nop_completion;
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +09001648
1649 init_controller(m66592);
1650
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +09001651 dev_info(&pdev->dev, "version %s\n", DRIVER_VERSION);
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +09001652 return 0;
1653
Magnus Dammaf5be792008-10-31 20:22:13 +09001654clean_up3:
1655#if defined(CONFIG_SUPERH_BUILT_IN_M66592) && defined(CONFIG_HAVE_CLK)
1656 clk_disable(m66592->clk);
1657 clk_put(m66592->clk);
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +09001658clean_up2:
Paul Mundtd6435102008-11-18 12:40:39 +09001659#endif
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +09001660 free_irq(irq, m66592);
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +09001661clean_up:
1662 if (m66592) {
1663 if (m66592->ep0_req)
1664 m66592_free_request(&m66592->ep[0].ep, m66592->ep0_req);
1665 kfree(m66592);
1666 }
1667 if (reg)
1668 iounmap(reg);
1669
1670 return ret;
1671}
1672
1673/*-------------------------------------------------------------------------*/
1674static struct platform_driver m66592_driver = {
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +09001675 .remove = __exit_p(m66592_remove),
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +09001676 .driver = {
1677 .name = (char *) udc_name,
Kay Sieversf34c32f2008-04-10 21:29:21 -07001678 .owner = THIS_MODULE,
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +09001679 },
1680};
1681
1682static int __init m66592_udc_init(void)
1683{
Yoshihiro Shimoda598f22e2007-07-17 21:01:17 +09001684 return platform_driver_probe(&m66592_driver, m66592_probe);
Yoshihiro Shimoda4cf25032007-05-10 13:18:23 +09001685}
1686module_init(m66592_udc_init);
1687
1688static void __exit m66592_udc_cleanup(void)
1689{
1690 platform_driver_unregister(&m66592_driver);
1691}
1692module_exit(m66592_udc_cleanup);