diff options
author | hselasky <hselasky@FreeBSD.org> | 2013-10-24 07:38:32 +0000 |
---|---|---|
committer | hselasky <hselasky@FreeBSD.org> | 2013-10-24 07:38:32 +0000 |
commit | 110ec3f7e38eb87529f8a17b5e5a207378bce219 (patch) | |
tree | dde87ec7a20808212dcf43014af42946a6963e7e /sys/dev/usb/controller/musb_otg.c | |
parent | be939ca962d3012cea3d32385af7527e0ce5c525 (diff) | |
download | FreeBSD-src-110ec3f7e38eb87529f8a17b5e5a207378bce219.zip FreeBSD-src-110ec3f7e38eb87529f8a17b5e5a207378bce219.tar.gz |
MFC r256548:
Correct programming of XXX_MAXP register. This register is 16-bit wide
and not 8-bit. Fix support for isochronous transfers in USB host mode.
Fix a whitespace while at it.
PR: usb/181987
Approved by: re (Xin Li)
Diffstat (limited to 'sys/dev/usb/controller/musb_otg.c')
-rw-r--r-- | sys/dev/usb/controller/musb_otg.c | 53 |
1 files changed, 37 insertions, 16 deletions
diff --git a/sys/dev/usb/controller/musb_otg.c b/sys/dev/usb/controller/musb_otg.c index 9b2974f..6944a59 100644 --- a/sys/dev/usb/controller/musb_otg.c +++ b/sys/dev/usb/controller/musb_otg.c @@ -1661,7 +1661,7 @@ repeat: } /* Max packet size */ - MUSB2_WRITE_1(sc, MUSB2_REG_TXMAXP, td->max_packet); + MUSB2_WRITE_2(sc, MUSB2_REG_TXMAXP, td->reg_max_packet); /* write command */ MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL, @@ -1726,13 +1726,16 @@ repeat: td->hport); /* RX NAK timeout */ - MUSB2_WRITE_1(sc, MUSB2_REG_RXNAKLIMIT, MAX_NAK_TO); + if (td->transfer_type & MUSB2_MASK_TI_PROTO_ISOC) + MUSB2_WRITE_1(sc, MUSB2_REG_RXNAKLIMIT, 0); + else + MUSB2_WRITE_1(sc, MUSB2_REG_RXNAKLIMIT, MAX_NAK_TO); /* Protocol, speed, device endpoint */ MUSB2_WRITE_1(sc, MUSB2_REG_RXTI, td->transfer_type); /* Max packet size */ - MUSB2_WRITE_1(sc, MUSB2_REG_RXMAXP, td->max_packet); + MUSB2_WRITE_2(sc, MUSB2_REG_RXMAXP, td->reg_max_packet); /* Data Toggle */ csrh = MUSB2_READ_1(sc, MUSB2_REG_RXCSRH); @@ -1938,7 +1941,7 @@ musbotg_host_data_tx(struct musbotg_td *td) return (0); /* complete */ } - if (csr & MUSB2_MASK_CSRL_TXNAKTO ) { + if (csr & MUSB2_MASK_CSRL_TXNAKTO) { /* * Flush TX FIFO before clearing NAK TO */ @@ -2069,13 +2072,16 @@ musbotg_host_data_tx(struct musbotg_td *td) td->hport); /* TX NAK timeout */ - MUSB2_WRITE_1(sc, MUSB2_REG_TXNAKLIMIT, MAX_NAK_TO); + if (td->transfer_type & MUSB2_MASK_TI_PROTO_ISOC) + MUSB2_WRITE_1(sc, MUSB2_REG_TXNAKLIMIT, 0); + else + MUSB2_WRITE_1(sc, MUSB2_REG_TXNAKLIMIT, MAX_NAK_TO); /* Protocol, speed, device endpoint */ MUSB2_WRITE_1(sc, MUSB2_REG_TXTI, td->transfer_type); /* Max packet size */ - MUSB2_WRITE_1(sc, MUSB2_REG_TXMAXP, td->max_packet); + MUSB2_WRITE_2(sc, MUSB2_REG_TXMAXP, td->reg_max_packet); if (!td->transaction_started) { csrh = MUSB2_READ_1(sc, MUSB2_REG_TXCSRH); @@ -2406,7 +2412,6 @@ musbotg_setup_standard_chain(struct usb_xfer *xfer) if (xfer->flags_int.usb_mode == USB_MODE_HOST) { speed = usbd_get_speed(xfer->xroot->udev); - xfer_type = xfer->endpoint->edesc->bmAttributes & UE_XFERTYPE; switch (speed) { case USB_SPEED_LOW: @@ -2444,7 +2449,6 @@ musbotg_setup_standard_chain(struct usb_xfer *xfer) } temp.transfer_type |= ep_no; - td->max_packet = xfer->max_packet_size; td->toggle = xfer->endpoint->toggle_next; } @@ -2469,9 +2473,9 @@ musbotg_setup_standard_chain(struct usb_xfer *xfer) x = 0; } - if (x != xfer->nframes) { - tx = 0; + tx = 0; + if (x != xfer->nframes) { if (xfer->endpointno & UE_DIR_IN) tx = 1; @@ -2532,9 +2536,14 @@ musbotg_setup_standard_chain(struct usb_xfer *xfer) } else { - /* regular data transfer */ - - temp.short_pkt = (xfer->flags.force_short_xfer) ? 0 : 1; + if (xfer->flags_int.isochronous_xfr) { + /* isochronous data transfer */ + /* don't force short */ + temp.short_pkt = 1; + } else { + /* regular data transfer */ + temp.short_pkt = (xfer->flags.force_short_xfer ? 0 : 1); + } } musbotg_setup_standard_chain_sub(&temp); @@ -3158,7 +3167,12 @@ musbotg_init(struct musbotg_softc *sc) if (dynfifo) { if (frx && (temp <= nrx)) { - if (temp < 8) { + if (temp == 1) { + frx = 12; /* 4K */ + MUSB2_WRITE_1(sc, MUSB2_REG_RXFIFOSZ, + MUSB2_VAL_FIFOSZ_4096 | + MUSB2_MASK_FIFODB); + } else if (temp < 8) { frx = 10; /* 1K */ MUSB2_WRITE_1(sc, MUSB2_REG_RXFIFOSZ, MUSB2_VAL_FIFOSZ_512 | @@ -3175,7 +3189,12 @@ musbotg_init(struct musbotg_softc *sc) offset += (1 << frx); } if (ftx && (temp <= ntx)) { - if (temp < 8) { + if (temp == 1) { + ftx = 12; /* 4K */ + MUSB2_WRITE_1(sc, MUSB2_REG_TXFIFOSZ, + MUSB2_VAL_FIFOSZ_4096 | + MUSB2_MASK_FIFODB); + } else if (temp < 8) { ftx = 10; /* 1K */ MUSB2_WRITE_1(sc, MUSB2_REG_TXFIFOSZ, MUSB2_VAL_FIFOSZ_512 | @@ -4042,7 +4061,7 @@ musbotg_xfer_setup(struct usb_setup_params *parm) * reasonable dummies: */ parm->hc_max_packet_size = 0x400; - parm->hc_max_frame_size = 0x400; + parm->hc_max_frame_size = 0xc00; if ((parm->methods == &musbotg_device_isoc_methods) || (parm->methods == &musbotg_device_intr_methods)) @@ -4117,6 +4136,8 @@ musbotg_xfer_setup(struct usb_setup_params *parm) /* init TD */ td->max_frame_size = xfer->max_frame_size; + td->reg_max_packet = xfer->max_packet_size | + ((xfer->max_packet_count - 1) << 11); td->ep_no = ep_no; td->obj_next = last_obj; |