aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/renesas_usbhs/pipe.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/renesas_usbhs/pipe.c')
-rw-r--r--drivers/usb/renesas_usbhs/pipe.c200
1 files changed, 91 insertions, 109 deletions
diff --git a/drivers/usb/renesas_usbhs/pipe.c b/drivers/usb/renesas_usbhs/pipe.c
index 1b14cae45704..c74389ce2177 100644
--- a/drivers/usb/renesas_usbhs/pipe.c
+++ b/drivers/usb/renesas_usbhs/pipe.c
@@ -29,9 +29,6 @@
29#define usbhsp_flags_has(p, f) ((p)->flags & USBHS_PIPE_FLAGS_##f) 29#define usbhsp_flags_has(p, f) ((p)->flags & USBHS_PIPE_FLAGS_##f)
30#define usbhsp_flags_init(p) do {(p)->flags = 0; } while (0) 30#define usbhsp_flags_init(p) do {(p)->flags = 0; } while (0)
31 31
32#define usbhsp_type(p) ((p)->pipe_type)
33#define usbhsp_type_is(p, t) ((p)->pipe_type == t)
34
35/* 32/*
36 * for debug 33 * for debug
37 */ 34 */
@@ -42,28 +39,9 @@ static char *usbhsp_pipe_name[] = {
42 [USB_ENDPOINT_XFER_ISOC] = "ISO", 39 [USB_ENDPOINT_XFER_ISOC] = "ISO",
43}; 40};
44 41
45/* 42char *usbhs_pipe_name(struct usbhs_pipe *pipe)
46 * usb request functions
47 */
48void usbhs_usbreq_get_val(struct usbhs_priv *priv, struct usb_ctrlrequest *req)
49{ 43{
50 u16 val; 44 return usbhsp_pipe_name[usbhs_pipe_type(pipe)];
51
52 val = usbhs_read(priv, USBREQ);
53 req->bRequest = (val >> 8) & 0xFF;
54 req->bRequestType = (val >> 0) & 0xFF;
55
56 req->wValue = usbhs_read(priv, USBVAL);
57 req->wIndex = usbhs_read(priv, USBINDX);
58 req->wLength = usbhs_read(priv, USBLENG);
59}
60
61void usbhs_usbreq_set_val(struct usbhs_priv *priv, struct usb_ctrlrequest *req)
62{
63 usbhs_write(priv, USBREQ, (req->bRequest << 8) | req->bRequestType);
64 usbhs_write(priv, USBVAL, req->wValue);
65 usbhs_write(priv, USBINDX, req->wIndex);
66 usbhs_write(priv, USBLENG, req->wLength);
67} 45}
68 46
69/* 47/*
@@ -106,17 +84,6 @@ static void __usbhsp_pipe_xxx_set(struct usbhs_pipe *pipe,
106 usbhs_bset(priv, pipe_reg, mask, val); 84 usbhs_bset(priv, pipe_reg, mask, val);
107} 85}
108 86
109static u16 __usbhsp_pipe_xxx_get(struct usbhs_pipe *pipe,
110 u16 dcp_reg, u16 pipe_reg)
111{
112 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
113
114 if (usbhs_pipe_is_dcp(pipe))
115 return usbhs_read(priv, dcp_reg);
116 else
117 return usbhs_read(priv, pipe_reg);
118}
119
120/* 87/*
121 * DCPCFG/PIPECFG functions 88 * DCPCFG/PIPECFG functions
122 */ 89 */
@@ -144,11 +111,6 @@ static void usbhsp_pipe_maxp_set(struct usbhs_pipe *pipe, u16 mask, u16 val)
144 __usbhsp_pipe_xxx_set(pipe, DCPMAXP, PIPEMAXP, mask, val); 111 __usbhsp_pipe_xxx_set(pipe, DCPMAXP, PIPEMAXP, mask, val);
145} 112}
146 113
147static u16 usbhsp_pipe_maxp_get(struct usbhs_pipe *pipe)
148{
149 return __usbhsp_pipe_xxx_get(pipe, DCPMAXP, PIPEMAXP);
150}
151
152/* 114/*
153 * pipe control functions 115 * pipe control functions
154 */ 116 */
@@ -303,16 +265,16 @@ static int usbhsp_possible_double_buffer(struct usbhs_pipe *pipe)
303 /* 265 /*
304 * only ISO / BULK pipe can use double buffer 266 * only ISO / BULK pipe can use double buffer
305 */ 267 */
306 if (usbhsp_type_is(pipe, USB_ENDPOINT_XFER_BULK) || 268 if (usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_BULK) ||
307 usbhsp_type_is(pipe, USB_ENDPOINT_XFER_ISOC)) 269 usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_ISOC))
308 return 1; 270 return 1;
309 271
310 return 0; 272 return 0;
311} 273}
312 274
313static u16 usbhsp_setup_pipecfg(struct usbhs_pipe *pipe, 275static u16 usbhsp_setup_pipecfg(struct usbhs_pipe *pipe,
314 const struct usb_endpoint_descriptor *desc, 276 int is_host,
315 int is_host) 277 int dir_in)
316{ 278{
317 u16 type = 0; 279 u16 type = 0;
318 u16 bfre = 0; 280 u16 bfre = 0;
@@ -341,40 +303,40 @@ static u16 usbhsp_setup_pipecfg(struct usbhs_pipe *pipe,
341 */ 303 */
342 304
343 /* TYPE */ 305 /* TYPE */
344 type = type_array[usbhsp_type(pipe)]; 306 type = type_array[usbhs_pipe_type(pipe)];
345 307
346 /* BFRE */ 308 /* BFRE */
347 if (usbhsp_type_is(pipe, USB_ENDPOINT_XFER_ISOC) || 309 if (usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_ISOC) ||
348 usbhsp_type_is(pipe, USB_ENDPOINT_XFER_BULK)) 310 usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_BULK))
349 bfre = 0; /* FIXME */ 311 bfre = 0; /* FIXME */
350 312
351 /* DBLB */ 313 /* DBLB */
352 if (usbhsp_type_is(pipe, USB_ENDPOINT_XFER_ISOC) || 314 if (usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_ISOC) ||
353 usbhsp_type_is(pipe, USB_ENDPOINT_XFER_BULK)) 315 usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_BULK))
354 dblb = (is_double) ? DBLB : 0; 316 dblb = (is_double) ? DBLB : 0;
355 317
356 /* CNTMD */ 318 /* CNTMD */
357 if (usbhsp_type_is(pipe, USB_ENDPOINT_XFER_BULK)) 319 if (usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_BULK))
358 cntmd = 0; /* FIXME */ 320 cntmd = 0; /* FIXME */
359 321
360 /* DIR */ 322 /* DIR */
361 if (usb_endpoint_dir_in(desc)) 323 if (dir_in)
362 usbhsp_flags_set(pipe, IS_DIR_HOST); 324 usbhsp_flags_set(pipe, IS_DIR_HOST);
363 325
364 if ((is_host && usb_endpoint_dir_out(desc)) || 326 if ((is_host && !dir_in) ||
365 (!is_host && usb_endpoint_dir_in(desc))) 327 (!is_host && dir_in))
366 dir |= DIR_OUT; 328 dir |= DIR_OUT;
367 329
368 if (!dir) 330 if (!dir)
369 usbhsp_flags_set(pipe, IS_DIR_IN); 331 usbhsp_flags_set(pipe, IS_DIR_IN);
370 332
371 /* SHTNAK */ 333 /* SHTNAK */
372 if (usbhsp_type_is(pipe, USB_ENDPOINT_XFER_BULK) && 334 if (usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_BULK) &&
373 !dir) 335 !dir)
374 shtnak = SHTNAK; 336 shtnak = SHTNAK;
375 337
376 /* EPNUM */ 338 /* EPNUM */
377 epnum = 0xF & usb_endpoint_num(desc); 339 epnum = 0; /* see usbhs_pipe_config_update() */
378 340
379 return type | 341 return type |
380 bfre | 342 bfre |
@@ -385,19 +347,7 @@ static u16 usbhsp_setup_pipecfg(struct usbhs_pipe *pipe,
385 epnum; 347 epnum;
386} 348}
387 349
388static u16 usbhsp_setup_pipemaxp(struct usbhs_pipe *pipe, 350static u16 usbhsp_setup_pipebuff(struct usbhs_pipe *pipe)
389 const struct usb_endpoint_descriptor *desc,
390 int is_host)
391{
392 /* host should set DEVSEL */
393
394 /* reutn MXPS */
395 return PIPE_MAXP_MASK & le16_to_cpu(desc->wMaxPacketSize);
396}
397
398static u16 usbhsp_setup_pipebuff(struct usbhs_pipe *pipe,
399 const struct usb_endpoint_descriptor *desc,
400 int is_host)
401{ 351{
402 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); 352 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
403 struct usbhs_pipe_info *info = usbhs_priv_to_pipeinfo(priv); 353 struct usbhs_pipe_info *info = usbhs_priv_to_pipeinfo(priv);
@@ -441,9 +391,9 @@ static u16 usbhsp_setup_pipebuff(struct usbhs_pipe *pipe,
441 * INT : 64 byte 391 * INT : 64 byte
442 * ISOC: 512 byte 392 * ISOC: 512 byte
443 */ 393 */
444 if (usbhsp_type_is(pipe, USB_ENDPOINT_XFER_CONTROL)) 394 if (usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_CONTROL))
445 buff_size = 256; 395 buff_size = 256;
446 else if (usbhsp_type_is(pipe, USB_ENDPOINT_XFER_INT)) 396 else if (usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_INT))
447 buff_size = 64; 397 buff_size = 64;
448 else 398 else
449 buff_size = 512; 399 buff_size = 512;
@@ -453,7 +403,7 @@ static u16 usbhsp_setup_pipebuff(struct usbhs_pipe *pipe,
453 403
454 /* BUFNMB has been reserved for INT pipe 404 /* BUFNMB has been reserved for INT pipe
455 * see above */ 405 * see above */
456 if (usbhsp_type_is(pipe, USB_ENDPOINT_XFER_INT)) { 406 if (usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_INT)) {
457 bufnmb = pipe_num - 2; 407 bufnmb = pipe_num - 2;
458 } else { 408 } else {
459 bufnmb = info->bufnmb_last; 409 bufnmb = info->bufnmb_last;
@@ -473,16 +423,42 @@ static u16 usbhsp_setup_pipebuff(struct usbhs_pipe *pipe,
473 (0xff & bufnmb) << 0; 423 (0xff & bufnmb) << 0;
474} 424}
475 425
426void usbhs_pipe_config_update(struct usbhs_pipe *pipe, u16 devsel,
427 u16 epnum, u16 maxp)
428{
429 if (devsel > 0xA) {
430 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
431 struct device *dev = usbhs_priv_to_dev(priv);
432
433 dev_err(dev, "devsel error %d\n", devsel);
434
435 devsel = 0;
436 }
437
438 usbhsp_pipe_barrier(pipe);
439
440 pipe->maxp = maxp;
441
442 usbhsp_pipe_select(pipe);
443 usbhsp_pipe_maxp_set(pipe, 0xFFFF,
444 (devsel << 12) |
445 maxp);
446
447 if (!usbhs_pipe_is_dcp(pipe))
448 usbhsp_pipe_cfg_set(pipe, 0x000F, epnum);
449}
450
476/* 451/*
477 * pipe control 452 * pipe control
478 */ 453 */
479int usbhs_pipe_get_maxpacket(struct usbhs_pipe *pipe) 454int usbhs_pipe_get_maxpacket(struct usbhs_pipe *pipe)
480{ 455{
481 u16 mask = usbhs_pipe_is_dcp(pipe) ? DCP_MAXP_MASK : PIPE_MAXP_MASK; 456 /*
482 457 * see
483 usbhsp_pipe_select(pipe); 458 * usbhs_pipe_config_update()
484 459 * usbhs_dcp_malloc()
485 return (int)(usbhsp_pipe_maxp_get(pipe) & mask); 460 */
461 return pipe->maxp;
486} 462}
487 463
488int usbhs_pipe_is_dir_in(struct usbhs_pipe *pipe) 464int usbhs_pipe_is_dir_in(struct usbhs_pipe *pipe)
@@ -495,9 +471,12 @@ int usbhs_pipe_is_dir_host(struct usbhs_pipe *pipe)
495 return usbhsp_flags_has(pipe, IS_DIR_HOST); 471 return usbhsp_flags_has(pipe, IS_DIR_HOST);
496} 472}
497 473
498void usbhs_pipe_clear_sequence(struct usbhs_pipe *pipe) 474void usbhs_pipe_data_sequence(struct usbhs_pipe *pipe, int data)
499{ 475{
500 usbhsp_pipectrl_set(pipe, SQCLR, SQCLR); 476 u16 mask = (SQCLR | SQSET);
477 u16 val = (data) ? SQSET : SQCLR;
478
479 usbhsp_pipectrl_set(pipe, mask, val);
501} 480}
502 481
503void usbhs_pipe_clear(struct usbhs_pipe *pipe) 482void usbhs_pipe_clear(struct usbhs_pipe *pipe)
@@ -516,7 +495,7 @@ static struct usbhs_pipe *usbhsp_get_pipe(struct usbhs_priv *priv, u32 type)
516 */ 495 */
517 pipe = NULL; 496 pipe = NULL;
518 usbhs_for_each_pipe_with_dcp(pos, priv, i) { 497 usbhs_for_each_pipe_with_dcp(pos, priv, i) {
519 if (!usbhsp_type_is(pos, type)) 498 if (!usbhs_pipe_type_is(pos, type))
520 continue; 499 continue;
521 if (usbhsp_flags_has(pos, IS_USED)) 500 if (usbhsp_flags_has(pos, IS_USED))
522 continue; 501 continue;
@@ -538,19 +517,12 @@ static struct usbhs_pipe *usbhsp_get_pipe(struct usbhs_priv *priv, u32 type)
538} 517}
539 518
540void usbhs_pipe_init(struct usbhs_priv *priv, 519void usbhs_pipe_init(struct usbhs_priv *priv,
541 void (*done)(struct usbhs_pkt *pkt),
542 int (*dma_map_ctrl)(struct usbhs_pkt *pkt, int map)) 520 int (*dma_map_ctrl)(struct usbhs_pkt *pkt, int map))
543{ 521{
544 struct usbhs_pipe_info *info = usbhs_priv_to_pipeinfo(priv); 522 struct usbhs_pipe_info *info = usbhs_priv_to_pipeinfo(priv);
545 struct device *dev = usbhs_priv_to_dev(priv);
546 struct usbhs_pipe *pipe; 523 struct usbhs_pipe *pipe;
547 int i; 524 int i;
548 525
549 if (!done) {
550 dev_err(dev, "no done function\n");
551 return;
552 }
553
554 /* 526 /*
555 * FIXME 527 * FIXME
556 * 528 *
@@ -565,7 +537,7 @@ void usbhs_pipe_init(struct usbhs_priv *priv,
565 */ 537 */
566 info->bufnmb_last = 4; 538 info->bufnmb_last = 4;
567 usbhs_for_each_pipe_with_dcp(pipe, priv, i) { 539 usbhs_for_each_pipe_with_dcp(pipe, priv, i) {
568 if (usbhsp_type_is(pipe, USB_ENDPOINT_XFER_INT)) 540 if (usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_INT))
569 info->bufnmb_last++; 541 info->bufnmb_last++;
570 542
571 usbhsp_flags_init(pipe); 543 usbhsp_flags_init(pipe);
@@ -577,24 +549,23 @@ void usbhs_pipe_init(struct usbhs_priv *priv,
577 usbhs_pipe_clear(pipe); 549 usbhs_pipe_clear(pipe);
578 } 550 }
579 551
580 info->done = done;
581 info->dma_map_ctrl = dma_map_ctrl; 552 info->dma_map_ctrl = dma_map_ctrl;
582} 553}
583 554
584struct usbhs_pipe *usbhs_pipe_malloc(struct usbhs_priv *priv, 555struct usbhs_pipe *usbhs_pipe_malloc(struct usbhs_priv *priv,
585 const struct usb_endpoint_descriptor *desc) 556 int endpoint_type,
557 int dir_in)
586{ 558{
587 struct device *dev = usbhs_priv_to_dev(priv); 559 struct device *dev = usbhs_priv_to_dev(priv);
588 struct usbhs_mod *mod = usbhs_mod_get_current(priv);
589 struct usbhs_pipe *pipe; 560 struct usbhs_pipe *pipe;
590 int is_host = usbhs_mod_is_host(priv, mod); 561 int is_host = usbhs_mod_is_host(priv);
591 int ret; 562 int ret;
592 u16 pipecfg, pipebuf, pipemaxp; 563 u16 pipecfg, pipebuf;
593 564
594 pipe = usbhsp_get_pipe(priv, usb_endpoint_type(desc)); 565 pipe = usbhsp_get_pipe(priv, endpoint_type);
595 if (!pipe) { 566 if (!pipe) {
596 dev_err(dev, "can't get pipe (%s)\n", 567 dev_err(dev, "can't get pipe (%s)\n",
597 usbhsp_pipe_name[usb_endpoint_type(desc)]); 568 usbhsp_pipe_name[endpoint_type]);
598 return NULL; 569 return NULL;
599 } 570 }
600 571
@@ -609,22 +580,25 @@ struct usbhs_pipe *usbhs_pipe_malloc(struct usbhs_priv *priv,
609 return NULL; 580 return NULL;
610 } 581 }
611 582
612 pipecfg = usbhsp_setup_pipecfg(pipe, desc, is_host); 583 pipecfg = usbhsp_setup_pipecfg(pipe, is_host, dir_in);
613 pipebuf = usbhsp_setup_pipebuff(pipe, desc, is_host); 584 pipebuf = usbhsp_setup_pipebuff(pipe);
614 pipemaxp = usbhsp_setup_pipemaxp(pipe, desc, is_host);
615 585
616 usbhsp_pipe_select(pipe); 586 usbhsp_pipe_select(pipe);
617 usbhsp_pipe_cfg_set(pipe, 0xFFFF, pipecfg); 587 usbhsp_pipe_cfg_set(pipe, 0xFFFF, pipecfg);
618 usbhsp_pipe_buf_set(pipe, 0xFFFF, pipebuf); 588 usbhsp_pipe_buf_set(pipe, 0xFFFF, pipebuf);
619 usbhsp_pipe_maxp_set(pipe, 0xFFFF, pipemaxp);
620 589
621 usbhs_pipe_clear_sequence(pipe); 590 usbhs_pipe_sequence_data0(pipe);
622 591
623 dev_dbg(dev, "enable pipe %d : %s (%s)\n", 592 dev_dbg(dev, "enable pipe %d : %s (%s)\n",
624 usbhs_pipe_number(pipe), 593 usbhs_pipe_number(pipe),
625 usbhsp_pipe_name[usb_endpoint_type(desc)], 594 usbhs_pipe_name(pipe),
626 usbhs_pipe_is_dir_in(pipe) ? "in" : "out"); 595 usbhs_pipe_is_dir_in(pipe) ? "in" : "out");
627 596
597 /*
598 * epnum / maxp are still not set to this pipe.
599 * call usbhs_pipe_config_update() after this function !!
600 */
601
628 return pipe; 602 return pipe;
629} 603}
630 604
@@ -651,25 +625,31 @@ struct usbhs_pipe *usbhs_dcp_malloc(struct usbhs_priv *priv)
651 if (!pipe) 625 if (!pipe)
652 return NULL; 626 return NULL;
653 627
628 INIT_LIST_HEAD(&pipe->list);
629
654 /* 630 /*
655 * dcpcfg : default 631 * call usbhs_pipe_config_update() after this function !!
656 * dcpmaxp : default
657 * pipebuf : nothing to do
658 */ 632 */
659 633
660 usbhsp_pipe_select(pipe);
661 usbhs_pipe_clear_sequence(pipe);
662 INIT_LIST_HEAD(&pipe->list);
663
664 return pipe; 634 return pipe;
665} 635}
666 636
667void usbhs_dcp_control_transfer_done(struct usbhs_pipe *pipe) 637void usbhs_dcp_control_transfer_done(struct usbhs_pipe *pipe)
668{ 638{
639 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
640
669 WARN_ON(!usbhs_pipe_is_dcp(pipe)); 641 WARN_ON(!usbhs_pipe_is_dcp(pipe));
670 642
671 usbhs_pipe_enable(pipe); 643 usbhs_pipe_enable(pipe);
672 usbhsp_pipectrl_set(pipe, CCPL, CCPL); 644
645 if (!usbhs_mod_is_host(priv)) /* funconly */
646 usbhsp_pipectrl_set(pipe, CCPL, CCPL);
647}
648
649void usbhs_dcp_dir_for_host(struct usbhs_pipe *pipe, int dir_out)
650{
651 usbhsp_pipe_cfg_set(pipe, DIR_OUT,
652 dir_out ? DIR_OUT : 0);
673} 653}
674 654
675/* 655/*
@@ -703,7 +683,9 @@ int usbhs_pipe_probe(struct usbhs_priv *priv)
703 */ 683 */
704 usbhs_for_each_pipe_with_dcp(pipe, priv, i) { 684 usbhs_for_each_pipe_with_dcp(pipe, priv, i) {
705 pipe->priv = priv; 685 pipe->priv = priv;
706 usbhsp_type(pipe) = pipe_type[i] & USB_ENDPOINT_XFERTYPE_MASK; 686
687 usbhs_pipe_type(pipe) =
688 pipe_type[i] & USB_ENDPOINT_XFERTYPE_MASK;
707 689
708 dev_dbg(dev, "pipe %x\t: %s\n", 690 dev_dbg(dev, "pipe %x\t: %s\n",
709 i, usbhsp_pipe_name[pipe_type[i]]); 691 i, usbhsp_pipe_name[pipe_type[i]]);