summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/gadget/r8a66597-udc.c364
-rw-r--r--drivers/usb/gadget/r8a66597-udc.h26
-rw-r--r--include/linux/usb/r8a66597.h60
3 files changed, 430 insertions, 20 deletions
diff --git a/drivers/usb/gadget/r8a66597-udc.c b/drivers/usb/gadget/r8a66597-udc.c
index 34abb12a88e8..035879b98dd9 100644
--- a/drivers/usb/gadget/r8a66597-udc.c
+++ b/drivers/usb/gadget/r8a66597-udc.c
@@ -18,13 +18,14 @@
18#include <linux/clk.h> 18#include <linux/clk.h>
19#include <linux/err.h> 19#include <linux/err.h>
20#include <linux/slab.h> 20#include <linux/slab.h>
21#include <linux/dma-mapping.h>
21 22
22#include <linux/usb/ch9.h> 23#include <linux/usb/ch9.h>
23#include <linux/usb/gadget.h> 24#include <linux/usb/gadget.h>
24 25
25#include "r8a66597-udc.h" 26#include "r8a66597-udc.h"
26 27
27#define DRIVER_VERSION "2009-08-18" 28#define DRIVER_VERSION "2011-09-26"
28 29
29static const char udc_name[] = "r8a66597_udc"; 30static const char udc_name[] = "r8a66597_udc";
30static const char *r8a66597_ep_name[] = { 31static const char *r8a66597_ep_name[] = {
@@ -184,6 +185,54 @@ static inline void control_reg_sqclr(struct r8a66597 *r8a66597, u16 pipenum)
184 } 185 }
185} 186}
186 187
188static void control_reg_sqset(struct r8a66597 *r8a66597, u16 pipenum)
189{
190 unsigned long offset;
191
192 pipe_stop(r8a66597, pipenum);
193
194 if (pipenum == 0) {
195 r8a66597_bset(r8a66597, SQSET, DCPCTR);
196 } else if (pipenum < R8A66597_MAX_NUM_PIPE) {
197 offset = get_pipectr_addr(pipenum);
198 r8a66597_bset(r8a66597, SQSET, offset);
199 } else {
200 dev_err(r8a66597_to_dev(r8a66597),
201 "unexpect pipe num(%d)\n", pipenum);
202 }
203}
204
205static u16 control_reg_sqmon(struct r8a66597 *r8a66597, u16 pipenum)
206{
207 unsigned long offset;
208
209 if (pipenum == 0) {
210 return r8a66597_read(r8a66597, DCPCTR) & SQMON;
211 } else if (pipenum < R8A66597_MAX_NUM_PIPE) {
212 offset = get_pipectr_addr(pipenum);
213 return r8a66597_read(r8a66597, offset) & SQMON;
214 } else {
215 dev_err(r8a66597_to_dev(r8a66597),
216 "unexpect pipe num(%d)\n", pipenum);
217 }
218
219 return 0;
220}
221
222static u16 save_usb_toggle(struct r8a66597 *r8a66597, u16 pipenum)
223{
224 return control_reg_sqmon(r8a66597, pipenum);
225}
226
227static void restore_usb_toggle(struct r8a66597 *r8a66597, u16 pipenum,
228 u16 toggle)
229{
230 if (toggle)
231 control_reg_sqset(r8a66597, pipenum);
232 else
233 control_reg_sqclr(r8a66597, pipenum);
234}
235
187static inline int get_buffer_size(struct r8a66597 *r8a66597, u16 pipenum) 236static inline int get_buffer_size(struct r8a66597 *r8a66597, u16 pipenum)
188{ 237{
189 u16 tmp; 238 u16 tmp;
@@ -220,18 +269,51 @@ static inline unsigned short mbw_value(struct r8a66597 *r8a66597)
220 return MBW_16; 269 return MBW_16;
221} 270}
222 271
272static void r8a66597_change_curpipe(struct r8a66597 *r8a66597, u16 pipenum,
273 u16 isel, u16 fifosel)
274{
275 u16 tmp, mask, loop;
276 int i = 0;
277
278 if (!pipenum) {
279 mask = ISEL | CURPIPE;
280 loop = isel;
281 } else {
282 mask = CURPIPE;
283 loop = pipenum;
284 }
285 r8a66597_mdfy(r8a66597, loop, mask, fifosel);
286
287 do {
288 tmp = r8a66597_read(r8a66597, fifosel);
289 if (i++ > 1000000) {
290 dev_err(r8a66597_to_dev(r8a66597),
291 "r8a66597: register%x, loop %x "
292 "is timeout\n", fifosel, loop);
293 break;
294 }
295 ndelay(1);
296 } while ((tmp & mask) != loop);
297}
298
223static inline void pipe_change(struct r8a66597 *r8a66597, u16 pipenum) 299static inline void pipe_change(struct r8a66597 *r8a66597, u16 pipenum)
224{ 300{
225 struct r8a66597_ep *ep = r8a66597->pipenum2ep[pipenum]; 301 struct r8a66597_ep *ep = r8a66597->pipenum2ep[pipenum];
226 302
227 if (ep->use_dma) 303 if (ep->use_dma)
228 return; 304 r8a66597_bclr(r8a66597, DREQE, ep->fifosel);
229 305
230 r8a66597_mdfy(r8a66597, pipenum, CURPIPE, ep->fifosel); 306 r8a66597_mdfy(r8a66597, pipenum, CURPIPE, ep->fifosel);
231 307
232 ndelay(450); 308 ndelay(450);
233 309
234 r8a66597_bset(r8a66597, mbw_value(r8a66597), ep->fifosel); 310 if (r8a66597_is_sudmac(r8a66597) && ep->use_dma)
311 r8a66597_bclr(r8a66597, mbw_value(r8a66597), ep->fifosel);
312 else
313 r8a66597_bset(r8a66597, mbw_value(r8a66597), ep->fifosel);
314
315 if (ep->use_dma)
316 r8a66597_bset(r8a66597, DREQE, ep->fifosel);
235} 317}
236 318
237static int pipe_buffer_setting(struct r8a66597 *r8a66597, 319static int pipe_buffer_setting(struct r8a66597 *r8a66597,
@@ -336,9 +418,15 @@ static void r8a66597_ep_setting(struct r8a66597 *r8a66597,
336 ep->fifoaddr = CFIFO; 418 ep->fifoaddr = CFIFO;
337 ep->fifosel = CFIFOSEL; 419 ep->fifosel = CFIFOSEL;
338 ep->fifoctr = CFIFOCTR; 420 ep->fifoctr = CFIFOCTR;
339 ep->fifotrn = 0;
340 421
341 ep->pipectr = get_pipectr_addr(pipenum); 422 ep->pipectr = get_pipectr_addr(pipenum);
423 if (is_bulk_pipe(pipenum) || is_isoc_pipe(pipenum)) {
424 ep->pipetre = get_pipetre_addr(pipenum);
425 ep->pipetrn = get_pipetrn_addr(pipenum);
426 } else {
427 ep->pipetre = 0;
428 ep->pipetrn = 0;
429 }
342 ep->pipenum = pipenum; 430 ep->pipenum = pipenum;
343 ep->ep.maxpacket = usb_endpoint_maxp(desc); 431 ep->ep.maxpacket = usb_endpoint_maxp(desc);
344 r8a66597->pipenum2ep[pipenum] = ep; 432 r8a66597->pipenum2ep[pipenum] = ep;
@@ -498,6 +586,124 @@ static void start_ep0_write(struct r8a66597_ep *ep,
498 } 586 }
499} 587}
500 588
589static void disable_fifosel(struct r8a66597 *r8a66597, u16 pipenum,
590 u16 fifosel)
591{
592 u16 tmp;
593
594 tmp = r8a66597_read(r8a66597, fifosel) & CURPIPE;
595 if (tmp == pipenum)
596 r8a66597_change_curpipe(r8a66597, 0, 0, fifosel);
597}
598
599static void change_bfre_mode(struct r8a66597 *r8a66597, u16 pipenum,
600 int enable)
601{
602 struct r8a66597_ep *ep = r8a66597->pipenum2ep[pipenum];
603 u16 tmp, toggle;
604
605 /* check current BFRE bit */
606 r8a66597_write(r8a66597, pipenum, PIPESEL);
607 tmp = r8a66597_read(r8a66597, PIPECFG) & R8A66597_BFRE;
608 if ((enable && tmp) || (!enable && !tmp))
609 return;
610
611 /* change BFRE bit */
612 pipe_stop(r8a66597, pipenum);
613 disable_fifosel(r8a66597, pipenum, CFIFOSEL);
614 disable_fifosel(r8a66597, pipenum, D0FIFOSEL);
615 disable_fifosel(r8a66597, pipenum, D1FIFOSEL);
616
617 toggle = save_usb_toggle(r8a66597, pipenum);
618
619 r8a66597_write(r8a66597, pipenum, PIPESEL);
620 if (enable)
621 r8a66597_bset(r8a66597, R8A66597_BFRE, PIPECFG);
622 else
623 r8a66597_bclr(r8a66597, R8A66597_BFRE, PIPECFG);
624
625 /* initialize for internal BFRE flag */
626 r8a66597_bset(r8a66597, ACLRM, ep->pipectr);
627 r8a66597_bclr(r8a66597, ACLRM, ep->pipectr);
628
629 restore_usb_toggle(r8a66597, pipenum, toggle);
630}
631
632static int sudmac_alloc_channel(struct r8a66597 *r8a66597,
633 struct r8a66597_ep *ep,
634 struct r8a66597_request *req)
635{
636 struct r8a66597_dma *dma;
637
638 if (!r8a66597_is_sudmac(r8a66597))
639 return -ENODEV;
640
641 /* Check transfer type */
642 if (!is_bulk_pipe(ep->pipenum))
643 return -EIO;
644
645 if (r8a66597->dma.used)
646 return -EBUSY;
647
648 /* set SUDMAC parameters */
649 dma = &r8a66597->dma;
650 dma->used = 1;
651 if (ep->desc->bEndpointAddress & USB_DIR_IN) {
652 dma->dir = 1;
653 } else {
654 dma->dir = 0;
655 change_bfre_mode(r8a66597, ep->pipenum, 1);
656 }
657
658 /* set r8a66597_ep paramters */
659 ep->use_dma = 1;
660 ep->dma = dma;
661 ep->fifoaddr = D0FIFO;
662 ep->fifosel = D0FIFOSEL;
663 ep->fifoctr = D0FIFOCTR;
664
665 /* dma mapping */
666 req->req.dma = dma_map_single(r8a66597_to_dev(ep->r8a66597),
667 req->req.buf, req->req.length,
668 dma->dir ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
669
670 return 0;
671}
672
673static void sudmac_free_channel(struct r8a66597 *r8a66597,
674 struct r8a66597_ep *ep,
675 struct r8a66597_request *req)
676{
677 if (!r8a66597_is_sudmac(r8a66597))
678 return;
679
680 dma_unmap_single(r8a66597_to_dev(ep->r8a66597),
681 req->req.dma, req->req.length,
682 ep->dma->dir ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
683
684 r8a66597_bclr(r8a66597, DREQE, ep->fifosel);
685 r8a66597_change_curpipe(r8a66597, 0, 0, ep->fifosel);
686
687 ep->dma->used = 0;
688 ep->use_dma = 0;
689 ep->fifoaddr = CFIFO;
690 ep->fifosel = CFIFOSEL;
691 ep->fifoctr = CFIFOCTR;
692}
693
694static void sudmac_start(struct r8a66597 *r8a66597, struct r8a66597_ep *ep,
695 struct r8a66597_request *req)
696{
697 BUG_ON(req->req.length == 0);
698
699 r8a66597_sudmac_write(r8a66597, LBA_WAIT, CH0CFG);
700 r8a66597_sudmac_write(r8a66597, req->req.dma, CH0BA);
701 r8a66597_sudmac_write(r8a66597, req->req.length, CH0BBC);
702 r8a66597_sudmac_write(r8a66597, CH0ENDE, DINTCTRL);
703
704 r8a66597_sudmac_write(r8a66597, DEN, CH0DEN);
705}
706
501static void start_packet_write(struct r8a66597_ep *ep, 707static void start_packet_write(struct r8a66597_ep *ep,
502 struct r8a66597_request *req) 708 struct r8a66597_request *req)
503{ 709{
@@ -508,11 +714,29 @@ static void start_packet_write(struct r8a66597_ep *ep,
508 disable_irq_empty(r8a66597, ep->pipenum); 714 disable_irq_empty(r8a66597, ep->pipenum);
509 pipe_start(r8a66597, ep->pipenum); 715 pipe_start(r8a66597, ep->pipenum);
510 716
511 tmp = r8a66597_read(r8a66597, ep->fifoctr); 717 if (req->req.length == 0) {
512 if (unlikely((tmp & FRDY) == 0)) 718 transfer_complete(ep, req, 0);
513 pipe_irq_enable(r8a66597, ep->pipenum); 719 } else {
514 else 720 r8a66597_write(r8a66597, ~(1 << ep->pipenum), BRDYSTS);
515 irq_packet_write(ep, req); 721 if (sudmac_alloc_channel(r8a66597, ep, req) < 0) {
722 /* PIO mode */
723 pipe_change(r8a66597, ep->pipenum);
724 disable_irq_empty(r8a66597, ep->pipenum);
725 pipe_start(r8a66597, ep->pipenum);
726 tmp = r8a66597_read(r8a66597, ep->fifoctr);
727 if (unlikely((tmp & FRDY) == 0))
728 pipe_irq_enable(r8a66597, ep->pipenum);
729 else
730 irq_packet_write(ep, req);
731 } else {
732 /* DMA mode */
733 pipe_change(r8a66597, ep->pipenum);
734 disable_irq_nrdy(r8a66597, ep->pipenum);
735 pipe_start(r8a66597, ep->pipenum);
736 enable_irq_nrdy(r8a66597, ep->pipenum);
737 sudmac_start(r8a66597, ep, req);
738 }
739 }
516} 740}
517 741
518static void start_packet_read(struct r8a66597_ep *ep, 742static void start_packet_read(struct r8a66597_ep *ep,
@@ -527,17 +751,26 @@ static void start_packet_read(struct r8a66597_ep *ep,
527 pipe_start(r8a66597, pipenum); 751 pipe_start(r8a66597, pipenum);
528 pipe_irq_enable(r8a66597, pipenum); 752 pipe_irq_enable(r8a66597, pipenum);
529 } else { 753 } else {
530 if (ep->use_dma) { 754 pipe_stop(r8a66597, pipenum);
531 r8a66597_bset(r8a66597, TRCLR, ep->fifosel); 755 if (ep->pipetre) {
532 pipe_change(r8a66597, pipenum); 756 enable_irq_nrdy(r8a66597, pipenum);
533 r8a66597_bset(r8a66597, TRENB, ep->fifosel); 757 r8a66597_write(r8a66597, TRCLR, ep->pipetre);
534 r8a66597_write(r8a66597, 758 r8a66597_write(r8a66597,
535 (req->req.length + ep->ep.maxpacket - 1) 759 DIV_ROUND_UP(req->req.length, ep->ep.maxpacket),
536 / ep->ep.maxpacket, 760 ep->pipetrn);
537 ep->fifotrn); 761 r8a66597_bset(r8a66597, TRENB, ep->pipetre);
762 }
763
764 if (sudmac_alloc_channel(r8a66597, ep, req) < 0) {
765 /* PIO mode */
766 change_bfre_mode(r8a66597, ep->pipenum, 0);
767 pipe_start(r8a66597, pipenum); /* trigger once */
768 pipe_irq_enable(r8a66597, pipenum);
769 } else {
770 pipe_change(r8a66597, pipenum);
771 sudmac_start(r8a66597, ep, req);
772 pipe_start(r8a66597, pipenum); /* trigger once */
538 } 773 }
539 pipe_start(r8a66597, pipenum); /* trigger once */
540 pipe_irq_enable(r8a66597, pipenum);
541 } 774 }
542} 775}
543 776
@@ -694,6 +927,9 @@ __acquires(r8a66597->lock)
694 if (!list_empty(&ep->queue)) 927 if (!list_empty(&ep->queue))
695 restart = 1; 928 restart = 1;
696 929
930 if (ep->use_dma)
931 sudmac_free_channel(ep->r8a66597, ep, req);
932
697 spin_unlock(&ep->r8a66597->lock); 933 spin_unlock(&ep->r8a66597->lock);
698 req->req.complete(&ep->ep, &req->req); 934 req->req.complete(&ep->ep, &req->req);
699 spin_lock(&ep->r8a66597->lock); 935 spin_lock(&ep->r8a66597->lock);
@@ -1170,6 +1406,65 @@ __acquires(r8a66597->lock)
1170 } 1406 }
1171} 1407}
1172 1408
1409static void sudmac_finish(struct r8a66597 *r8a66597, struct r8a66597_ep *ep)
1410{
1411 u16 pipenum;
1412 struct r8a66597_request *req;
1413 u32 len;
1414 int i = 0;
1415
1416 pipenum = ep->pipenum;
1417 pipe_change(r8a66597, pipenum);
1418
1419 while (!(r8a66597_read(r8a66597, ep->fifoctr) & FRDY)) {
1420 udelay(1);
1421 if (unlikely(i++ >= 10000)) { /* timeout = 10 msec */
1422 dev_err(r8a66597_to_dev(r8a66597),
1423 "%s: FRDY was not set (%d)\n",
1424 __func__, pipenum);
1425 return;
1426 }
1427 }
1428
1429 r8a66597_bset(r8a66597, BCLR, ep->fifoctr);
1430 req = get_request_from_ep(ep);
1431
1432 /* prepare parameters */
1433 len = r8a66597_sudmac_read(r8a66597, CH0CBC);
1434 req->req.actual += len;
1435
1436 /* clear */
1437 r8a66597_sudmac_write(r8a66597, CH0STCLR, DSTSCLR);
1438
1439 /* check transfer finish */
1440 if ((!req->req.zero && (req->req.actual == req->req.length))
1441 || (len % ep->ep.maxpacket)) {
1442 if (ep->dma->dir) {
1443 disable_irq_ready(r8a66597, pipenum);
1444 enable_irq_empty(r8a66597, pipenum);
1445 } else {
1446 /* Clear the interrupt flag for next transfer */
1447 r8a66597_write(r8a66597, ~(1 << pipenum), BRDYSTS);
1448 transfer_complete(ep, req, 0);
1449 }
1450 }
1451}
1452
1453static void r8a66597_sudmac_irq(struct r8a66597 *r8a66597)
1454{
1455 u32 irqsts;
1456 struct r8a66597_ep *ep;
1457 u16 pipenum;
1458
1459 irqsts = r8a66597_sudmac_read(r8a66597, DINTSTS);
1460 if (irqsts & CH0ENDS) {
1461 r8a66597_sudmac_write(r8a66597, CH0ENDC, DINTSTSCLR);
1462 pipenum = (r8a66597_read(r8a66597, D0FIFOSEL) & CURPIPE);
1463 ep = r8a66597->pipenum2ep[pipenum];
1464 sudmac_finish(r8a66597, ep);
1465 }
1466}
1467
1173static irqreturn_t r8a66597_irq(int irq, void *_r8a66597) 1468static irqreturn_t r8a66597_irq(int irq, void *_r8a66597)
1174{ 1469{
1175 struct r8a66597 *r8a66597 = _r8a66597; 1470 struct r8a66597 *r8a66597 = _r8a66597;
@@ -1180,6 +1475,9 @@ static irqreturn_t r8a66597_irq(int irq, void *_r8a66597)
1180 u16 savepipe; 1475 u16 savepipe;
1181 u16 mask0; 1476 u16 mask0;
1182 1477
1478 if (r8a66597_is_sudmac(r8a66597))
1479 r8a66597_sudmac_irq(r8a66597);
1480
1183 spin_lock(&r8a66597->lock); 1481 spin_lock(&r8a66597->lock);
1184 1482
1185 intsts0 = r8a66597_read(r8a66597, INTSTS0); 1483 intsts0 = r8a66597_read(r8a66597, INTSTS0);
@@ -1556,6 +1854,8 @@ static int __exit r8a66597_remove(struct platform_device *pdev)
1556 usb_del_gadget_udc(&r8a66597->gadget); 1854 usb_del_gadget_udc(&r8a66597->gadget);
1557 del_timer_sync(&r8a66597->timer); 1855 del_timer_sync(&r8a66597->timer);
1558 iounmap(r8a66597->reg); 1856 iounmap(r8a66597->reg);
1857 if (r8a66597->pdata->sudmac)
1858 iounmap(r8a66597->sudmac_reg);
1559 free_irq(platform_get_irq(pdev, 0), r8a66597); 1859 free_irq(platform_get_irq(pdev, 0), r8a66597);
1560 r8a66597_free_request(&r8a66597->ep[0].ep, r8a66597->ep0_req); 1860 r8a66597_free_request(&r8a66597->ep[0].ep, r8a66597->ep0_req);
1561#ifdef CONFIG_HAVE_CLK 1861#ifdef CONFIG_HAVE_CLK
@@ -1572,6 +1872,26 @@ static void nop_completion(struct usb_ep *ep, struct usb_request *r)
1572{ 1872{
1573} 1873}
1574 1874
1875static int __init r8a66597_sudmac_ioremap(struct r8a66597 *r8a66597,
1876 struct platform_device *pdev)
1877{
1878 struct resource *res;
1879
1880 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sudmac");
1881 if (!res) {
1882 dev_err(&pdev->dev, "platform_get_resource error(sudmac).\n");
1883 return -ENODEV;
1884 }
1885
1886 r8a66597->sudmac_reg = ioremap(res->start, resource_size(res));
1887 if (r8a66597->sudmac_reg == NULL) {
1888 dev_err(&pdev->dev, "ioremap error(sudmac).\n");
1889 return -ENOMEM;
1890 }
1891
1892 return 0;
1893}
1894
1575static int __init r8a66597_probe(struct platform_device *pdev) 1895static int __init r8a66597_probe(struct platform_device *pdev)
1576{ 1896{
1577#ifdef CONFIG_HAVE_CLK 1897#ifdef CONFIG_HAVE_CLK
@@ -1649,6 +1969,11 @@ static int __init r8a66597_probe(struct platform_device *pdev)
1649 clk_enable(r8a66597->clk); 1969 clk_enable(r8a66597->clk);
1650 } 1970 }
1651#endif 1971#endif
1972 if (r8a66597->pdata->sudmac) {
1973 ret = r8a66597_sudmac_ioremap(r8a66597, pdev);
1974 if (ret < 0)
1975 goto clean_up2;
1976 }
1652 1977
1653 disable_controller(r8a66597); /* make sure controller is disabled */ 1978 disable_controller(r8a66597); /* make sure controller is disabled */
1654 1979
@@ -1681,7 +2006,6 @@ static int __init r8a66597_probe(struct platform_device *pdev)
1681 r8a66597->ep[0].fifoaddr = CFIFO; 2006 r8a66597->ep[0].fifoaddr = CFIFO;
1682 r8a66597->ep[0].fifosel = CFIFOSEL; 2007 r8a66597->ep[0].fifosel = CFIFOSEL;
1683 r8a66597->ep[0].fifoctr = CFIFOCTR; 2008 r8a66597->ep[0].fifoctr = CFIFOCTR;
1684 r8a66597->ep[0].fifotrn = 0;
1685 r8a66597->ep[0].pipectr = get_pipectr_addr(0); 2009 r8a66597->ep[0].pipectr = get_pipectr_addr(0);
1686 r8a66597->pipenum2ep[0] = &r8a66597->ep[0]; 2010 r8a66597->pipenum2ep[0] = &r8a66597->ep[0];
1687 r8a66597->epaddr2ep[0] = &r8a66597->ep[0]; 2011 r8a66597->epaddr2ep[0] = &r8a66597->ep[0];
@@ -1714,6 +2038,8 @@ clean_up2:
1714#endif 2038#endif
1715clean_up: 2039clean_up:
1716 if (r8a66597) { 2040 if (r8a66597) {
2041 if (r8a66597->sudmac_reg)
2042 iounmap(r8a66597->sudmac_reg);
1717 if (r8a66597->ep0_req) 2043 if (r8a66597->ep0_req)
1718 r8a66597_free_request(&r8a66597->ep[0].ep, 2044 r8a66597_free_request(&r8a66597->ep[0].ep,
1719 r8a66597->ep0_req); 2045 r8a66597->ep0_req);
diff --git a/drivers/usb/gadget/r8a66597-udc.h b/drivers/usb/gadget/r8a66597-udc.h
index 832ee59c8e45..8e3de61cd4b8 100644
--- a/drivers/usb/gadget/r8a66597-udc.h
+++ b/drivers/usb/gadget/r8a66597-udc.h
@@ -43,6 +43,7 @@
43 ((pipenum >= R8A66597_BASE_PIPENUM_ISOC) && \ 43 ((pipenum >= R8A66597_BASE_PIPENUM_ISOC) && \
44 (pipenum < (R8A66597_BASE_PIPENUM_ISOC + R8A66597_MAX_NUM_ISOC))) 44 (pipenum < (R8A66597_BASE_PIPENUM_ISOC + R8A66597_MAX_NUM_ISOC)))
45 45
46#define r8a66597_is_sudmac(r8a66597) (r8a66597->pdata->sudmac)
46struct r8a66597_pipe_info { 47struct r8a66597_pipe_info {
47 u16 pipe; 48 u16 pipe;
48 u16 epnum; 49 u16 epnum;
@@ -60,6 +61,7 @@ struct r8a66597_request {
60struct r8a66597_ep { 61struct r8a66597_ep {
61 struct usb_ep ep; 62 struct usb_ep ep;
62 struct r8a66597 *r8a66597; 63 struct r8a66597 *r8a66597;
64 struct r8a66597_dma *dma;
63 65
64 struct list_head queue; 66 struct list_head queue;
65 unsigned busy:1; 67 unsigned busy:1;
@@ -75,13 +77,20 @@ struct r8a66597_ep {
75 unsigned char fifoaddr; 77 unsigned char fifoaddr;
76 unsigned char fifosel; 78 unsigned char fifosel;
77 unsigned char fifoctr; 79 unsigned char fifoctr;
78 unsigned char fifotrn;
79 unsigned char pipectr; 80 unsigned char pipectr;
81 unsigned char pipetre;
82 unsigned char pipetrn;
83};
84
85struct r8a66597_dma {
86 unsigned used:1;
87 unsigned dir:1; /* 1 = IN(write), 0 = OUT(read) */
80}; 88};
81 89
82struct r8a66597 { 90struct r8a66597 {
83 spinlock_t lock; 91 spinlock_t lock;
84 void __iomem *reg; 92 void __iomem *reg;
93 void __iomem *sudmac_reg;
85 94
86#ifdef CONFIG_HAVE_CLK 95#ifdef CONFIG_HAVE_CLK
87 struct clk *clk; 96 struct clk *clk;
@@ -94,6 +103,7 @@ struct r8a66597 {
94 struct r8a66597_ep ep[R8A66597_MAX_NUM_PIPE]; 103 struct r8a66597_ep ep[R8A66597_MAX_NUM_PIPE];
95 struct r8a66597_ep *pipenum2ep[R8A66597_MAX_NUM_PIPE]; 104 struct r8a66597_ep *pipenum2ep[R8A66597_MAX_NUM_PIPE];
96 struct r8a66597_ep *epaddr2ep[16]; 105 struct r8a66597_ep *epaddr2ep[16];
106 struct r8a66597_dma dma;
97 107
98 struct timer_list timer; 108 struct timer_list timer;
99 struct usb_request *ep0_req; /* for internal request */ 109 struct usb_request *ep0_req; /* for internal request */
@@ -251,7 +261,21 @@ static inline u16 get_xtal_from_pdata(struct r8a66597_platdata *pdata)
251 return clock; 261 return clock;
252} 262}
253 263
264static inline u32 r8a66597_sudmac_read(struct r8a66597 *r8a66597,
265 unsigned long offset)
266{
267 return ioread32(r8a66597->sudmac_reg + offset);
268}
269
270static inline void r8a66597_sudmac_write(struct r8a66597 *r8a66597, u32 val,
271 unsigned long offset)
272{
273 iowrite32(val, r8a66597->sudmac_reg + offset);
274}
275
254#define get_pipectr_addr(pipenum) (PIPE1CTR + (pipenum - 1) * 2) 276#define get_pipectr_addr(pipenum) (PIPE1CTR + (pipenum - 1) * 2)
277#define get_pipetre_addr(pipenum) (PIPE1TRE + (pipenum - 1) * 4)
278#define get_pipetrn_addr(pipenum) (PIPE1TRN + (pipenum - 1) * 4)
255 279
256#define enable_irq_ready(r8a66597, pipenum) \ 280#define enable_irq_ready(r8a66597, pipenum) \
257 enable_pipe_irq(r8a66597, pipenum, BRDYENB) 281 enable_pipe_irq(r8a66597, pipenum, BRDYENB)
diff --git a/include/linux/usb/r8a66597.h b/include/linux/usb/r8a66597.h
index b6b8660d0c68..55805f9dcf21 100644
--- a/include/linux/usb/r8a66597.h
+++ b/include/linux/usb/r8a66597.h
@@ -48,6 +48,9 @@ struct r8a66597_platdata {
48 48
49 /* (external controller only) set one = WR0_N shorted to WR1_N */ 49 /* (external controller only) set one = WR0_N shorted to WR1_N */
50 unsigned wr0_shorted_to_wr1:1; 50 unsigned wr0_shorted_to_wr1:1;
51
52 /* set one = using SUDMAC */
53 unsigned sudmac:1;
51}; 54};
52 55
53/* Register definitions */ 56/* Register definitions */
@@ -417,5 +420,62 @@ struct r8a66597_platdata {
417#define USBSPD 0x00C0 420#define USBSPD 0x00C0
418#define RTPORT 0x0001 421#define RTPORT 0x0001
419 422
423/* SUDMAC registers */
424#define CH0CFG 0x00
425#define CH1CFG 0x04
426#define CH0BA 0x10
427#define CH1BA 0x14
428#define CH0BBC 0x18
429#define CH1BBC 0x1C
430#define CH0CA 0x20
431#define CH1CA 0x24
432#define CH0CBC 0x28
433#define CH1CBC 0x2C
434#define CH0DEN 0x30
435#define CH1DEN 0x34
436#define DSTSCLR 0x38
437#define DBUFCTRL 0x3C
438#define DINTCTRL 0x40
439#define DINTSTS 0x44
440#define DINTSTSCLR 0x48
441#define CH0SHCTRL 0x50
442#define CH1SHCTRL 0x54
443
444/* SUDMAC Configuration Registers */
445#define SENDBUFM 0x1000 /* b12: Transmit Buffer Mode */
446#define RCVENDM 0x0100 /* b8: Receive Data Transfer End Mode */
447#define LBA_WAIT 0x0030 /* b5-4: Local Bus Access Wait */
448
449/* DMA Enable Registers */
450#define DEN 0x0001 /* b1: DMA Transfer Enable */
451
452/* DMA Status Clear Register */
453#define CH1STCLR 0x0002 /* b2: Ch1 DMA Status Clear */
454#define CH0STCLR 0x0001 /* b1: Ch0 DMA Status Clear */
455
456/* DMA Buffer Control Register */
457#define CH1BUFW 0x0200 /* b9: Ch1 DMA Buffer Data Transfer Enable */
458#define CH0BUFW 0x0100 /* b8: Ch0 DMA Buffer Data Transfer Enable */
459#define CH1BUFS 0x0002 /* b2: Ch1 DMA Buffer Data Status */
460#define CH0BUFS 0x0001 /* b1: Ch0 DMA Buffer Data Status */
461
462/* DMA Interrupt Control Register */
463#define CH1ERRE 0x0200 /* b9: Ch1 SHwy Res Err Detect Int Enable */
464#define CH0ERRE 0x0100 /* b8: Ch0 SHwy Res Err Detect Int Enable */
465#define CH1ENDE 0x0002 /* b2: Ch1 DMA Transfer End Int Enable */
466#define CH0ENDE 0x0001 /* b1: Ch0 DMA Transfer End Int Enable */
467
468/* DMA Interrupt Status Register */
469#define CH1ERRS 0x0200 /* b9: Ch1 SHwy Res Err Detect Int Status */
470#define CH0ERRS 0x0100 /* b8: Ch0 SHwy Res Err Detect Int Status */
471#define CH1ENDS 0x0002 /* b2: Ch1 DMA Transfer End Int Status */
472#define CH0ENDS 0x0001 /* b1: Ch0 DMA Transfer End Int Status */
473
474/* DMA Interrupt Status Clear Register */
475#define CH1ERRC 0x0200 /* b9: Ch1 SHwy Res Err Detect Int Stat Clear */
476#define CH0ERRC 0x0100 /* b8: Ch0 SHwy Res Err Detect Int Stat Clear */
477#define CH1ENDC 0x0002 /* b2: Ch1 DMA Transfer End Int Stat Clear */
478#define CH0ENDC 0x0001 /* b1: Ch0 DMA Transfer End Int Stat Clear */
479
420#endif /* __LINUX_USB_R8A66597_H */ 480#endif /* __LINUX_USB_R8A66597_H */
421 481