Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/usb/controller/musb_otg.c
Show First 20 Lines • Show All 143 Lines • ▼ Show 20 Lines | static const struct usb_hw_ep_profile musbotg_ep_profile[1] = { | ||||
[0] = { | [0] = { | ||||
.max_in_frame_size = 64,/* fixed */ | .max_in_frame_size = 64,/* fixed */ | ||||
.max_out_frame_size = 64, /* fixed */ | .max_out_frame_size = 64, /* fixed */ | ||||
.is_simplex = 1, | .is_simplex = 1, | ||||
.support_control = 1, | .support_control = 1, | ||||
} | } | ||||
}; | }; | ||||
static const struct musb_otg_ep_cfg musbotg_ep_default[] = { | |||||
{ | |||||
.ep_end = 1, | |||||
.ep_fifosz_shift = 12, | |||||
.ep_fifosz_reg = MUSB2_VAL_FIFOSZ_4096 | MUSB2_MASK_FIFODB, | |||||
}, | |||||
{ | |||||
.ep_end = 7, | |||||
.ep_fifosz_shift = 9, | |||||
.ep_fifosz_reg = MUSB2_VAL_FIFOSZ_512 | MUSB2_MASK_FIFODB, | |||||
}, | |||||
{ | |||||
.ep_end = 15, | |||||
.ep_fifosz_shift = 7, | |||||
.ep_fifosz_reg = MUSB2_VAL_FIFOSZ_128, | |||||
}, | |||||
{ | |||||
.ep_end = -1, | |||||
}, | |||||
}; | |||||
static int | static int | ||||
musbotg_channel_alloc(struct musbotg_softc *sc, struct musbotg_td *td, uint8_t is_tx) | musbotg_channel_alloc(struct musbotg_softc *sc, struct musbotg_td *td, uint8_t is_tx) | ||||
{ | { | ||||
int ch; | int ch; | ||||
int ep; | int ep; | ||||
ep = td->ep_no; | ep = td->ep_no; | ||||
▲ Show 20 Lines • Show All 233 Lines • ▼ Show 20 Lines | musbotg_dev_ctrl_setup_rx(struct musbotg_td *td) | ||||
/* EP0 is busy, wait */ | /* EP0 is busy, wait */ | ||||
if (td->channel == -1) | if (td->channel == -1) | ||||
return (1); | return (1); | ||||
DPRINTFN(1, "ep_no=%d\n", td->channel); | DPRINTFN(1, "ep_no=%d\n", td->channel); | ||||
/* select endpoint 0 */ | /* select endpoint 0 */ | ||||
MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, 0); | MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, td->channel); | ||||
/* read out FIFO status */ | /* read out FIFO status */ | ||||
csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL); | csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL); | ||||
DPRINTFN(4, "csr=0x%02x\n", csr); | DPRINTFN(4, "csr=0x%02x\n", csr); | ||||
/* | /* | ||||
* NOTE: If DATAEND is set we should not call the | * NOTE: If DATAEND is set we should not call the | ||||
▲ Show 20 Lines • Show All 109 Lines • ▼ Show 20 Lines | musbotg_host_ctrl_setup_tx(struct musbotg_td *td) | ||||
/* EP0 is busy, wait */ | /* EP0 is busy, wait */ | ||||
if (td->channel == -1) | if (td->channel == -1) | ||||
return (1); | return (1); | ||||
DPRINTFN(1, "ep_no=%d\n", td->channel); | DPRINTFN(1, "ep_no=%d\n", td->channel); | ||||
/* select endpoint 0 */ | /* select endpoint 0 */ | ||||
MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, 0); | MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, td->channel); | ||||
/* read out FIFO status */ | /* read out FIFO status */ | ||||
csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL); | csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL); | ||||
DPRINTFN(4, "csr=0x%02x\n", csr); | DPRINTFN(4, "csr=0x%02x\n", csr); | ||||
/* Not ready yet yet */ | /* Not ready yet yet */ | ||||
if (csr & MUSB2_MASK_CSR0L_TXPKTRDY) | if (csr & MUSB2_MASK_CSR0L_TXPKTRDY) | ||||
return (1); | return (1); | ||||
▲ Show 20 Lines • Show All 355 Lines • ▼ Show 20 Lines | musbotg_host_ctrl_data_rx(struct musbotg_td *td) | ||||
/* EP0 is busy, wait */ | /* EP0 is busy, wait */ | ||||
if (td->channel == -1) | if (td->channel == -1) | ||||
return (1); | return (1); | ||||
DPRINTFN(1, "ep_no=%d\n", td->channel); | DPRINTFN(1, "ep_no=%d\n", td->channel); | ||||
/* select endpoint 0 */ | /* select endpoint 0 */ | ||||
MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, 0); | MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, td->channel); | ||||
/* read out FIFO status */ | /* read out FIFO status */ | ||||
csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL); | csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL); | ||||
DPRINTFN(4, "csr=0x%02x\n", csr); | DPRINTFN(4, "csr=0x%02x\n", csr); | ||||
got_short = 0; | got_short = 0; | ||||
if (!td->transaction_started) { | if (!td->transaction_started) { | ||||
▲ Show 20 Lines • Show All 162 Lines • ▼ Show 20 Lines | musbotg_host_ctrl_data_tx(struct musbotg_td *td) | ||||
/* No free EPs */ | /* No free EPs */ | ||||
if (td->channel == -1) | if (td->channel == -1) | ||||
return (1); | return (1); | ||||
DPRINTFN(1, "ep_no=%d\n", td->channel); | DPRINTFN(1, "ep_no=%d\n", td->channel); | ||||
/* select endpoint */ | /* select endpoint */ | ||||
MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, 0); | MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, td->channel); | ||||
/* read out FIFO status */ | /* read out FIFO status */ | ||||
csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL); | csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL); | ||||
DPRINTFN(4, "csr=0x%02x\n", csr); | DPRINTFN(4, "csr=0x%02x\n", csr); | ||||
if (csr & (MUSB2_MASK_CSR0L_RXSTALL | | if (csr & (MUSB2_MASK_CSR0L_RXSTALL | | ||||
MUSB2_MASK_CSR0L_ERROR)) { | MUSB2_MASK_CSR0L_ERROR)) { | ||||
/* clear status bits */ | /* clear status bits */ | ||||
▲ Show 20 Lines • Show All 193 Lines • ▼ Show 20 Lines | musbotg_host_ctrl_status_rx(struct musbotg_td *td) | ||||
/* EP0 is busy, wait */ | /* EP0 is busy, wait */ | ||||
if (td->channel == -1) | if (td->channel == -1) | ||||
return (1); | return (1); | ||||
DPRINTFN(1, "ep_no=%d\n", td->channel); | DPRINTFN(1, "ep_no=%d\n", td->channel); | ||||
/* select endpoint 0 */ | /* select endpoint 0 */ | ||||
MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, 0); | MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, td->channel); | ||||
if (!td->transaction_started) { | if (!td->transaction_started) { | ||||
MUSB2_WRITE_1(sc, MUSB2_REG_RXFADDR(0), | MUSB2_WRITE_1(sc, MUSB2_REG_RXFADDR(0), | ||||
td->dev_addr); | td->dev_addr); | ||||
MUSB2_WRITE_1(sc, MUSB2_REG_RXHADDR(0), td->haddr); | MUSB2_WRITE_1(sc, MUSB2_REG_RXHADDR(0), td->haddr); | ||||
MUSB2_WRITE_1(sc, MUSB2_REG_RXHUBPORT(0), td->hport); | MUSB2_WRITE_1(sc, MUSB2_REG_RXHUBPORT(0), td->hport); | ||||
MUSB2_WRITE_1(sc, MUSB2_REG_RXTI, td->transfer_type); | MUSB2_WRITE_1(sc, MUSB2_REG_RXTI, td->transfer_type); | ||||
▲ Show 20 Lines • Show All 1,757 Lines • ▼ Show 20 Lines | musbotg_clear_stall_sub(sc, | ||||
(ed->bEndpointAddress & UE_ADDR), | (ed->bEndpointAddress & UE_ADDR), | ||||
(ed->bmAttributes & UE_XFERTYPE), | (ed->bmAttributes & UE_XFERTYPE), | ||||
(ed->bEndpointAddress & (UE_DIR_IN | UE_DIR_OUT))); | (ed->bEndpointAddress & (UE_DIR_IN | UE_DIR_OUT))); | ||||
} | } | ||||
usb_error_t | usb_error_t | ||||
musbotg_init(struct musbotg_softc *sc) | musbotg_init(struct musbotg_softc *sc) | ||||
{ | { | ||||
const struct musb_otg_ep_cfg *cfg; | |||||
struct usb_hw_ep_profile *pf; | struct usb_hw_ep_profile *pf; | ||||
int i; | |||||
uint16_t offset; | uint16_t offset; | ||||
uint8_t nrx; | uint8_t nrx; | ||||
uint8_t ntx; | uint8_t ntx; | ||||
uint8_t temp; | uint8_t temp; | ||||
uint8_t fsize; | uint8_t fsize; | ||||
uint8_t frx; | uint8_t frx; | ||||
uint8_t ftx; | uint8_t ftx; | ||||
uint8_t dynfifo; | uint8_t dynfifo; | ||||
DPRINTFN(1, "start\n"); | DPRINTFN(1, "start\n"); | ||||
/* set up the bus structure */ | /* set up the bus structure */ | ||||
sc->sc_bus.usbrev = USB_REV_2_0; | sc->sc_bus.usbrev = USB_REV_2_0; | ||||
sc->sc_bus.methods = &musbotg_bus_methods; | sc->sc_bus.methods = &musbotg_bus_methods; | ||||
/* Set a default endpoint configuration */ | |||||
if (sc->sc_eb_cfg == NULL) | |||||
sc->sc_eb_cfg = musbotg_ep_default; | |||||
USB_BUS_LOCK(&sc->sc_bus); | USB_BUS_LOCK(&sc->sc_bus); | ||||
/* turn on clocks */ | /* turn on clocks */ | ||||
if (sc->sc_clocks_on) { | if (sc->sc_clocks_on) { | ||||
(sc->sc_clocks_on) (sc->sc_clocks_arg); | (sc->sc_clocks_on) (sc->sc_clocks_arg); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 50 Lines • ▼ Show 20 Lines | musbotg_init(struct musbotg_softc *sc) | ||||
/* set default value */ | /* set default value */ | ||||
MUSB2_WRITE_1(sc, MUSB2_REG_MISC, 0); | MUSB2_WRITE_1(sc, MUSB2_REG_MISC, 0); | ||||
/* select endpoint index 0 */ | /* select endpoint index 0 */ | ||||
MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, 0); | MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, 0); | ||||
if (sc->sc_ep_max == 0) { | |||||
/* read out number of endpoints */ | /* read out number of endpoints */ | ||||
nrx = | nrx = | ||||
(MUSB2_READ_1(sc, MUSB2_REG_EPINFO) / 16); | (MUSB2_READ_1(sc, MUSB2_REG_EPINFO) / 16); | ||||
andrew: (Why the extra parentheses?) | |||||
Not Done Inline ActionsOld code was like this, I only changed the indentation. jmcneill: Old code was like this, I only changed the indentation. | |||||
ntx = | ntx = | ||||
(MUSB2_READ_1(sc, MUSB2_REG_EPINFO) % 16); | (MUSB2_READ_1(sc, MUSB2_REG_EPINFO) % 16); | ||||
sc->sc_ep_max = (nrx > ntx) ? nrx : ntx; | |||||
} else { | |||||
nrx = ntx = sc->sc_ep_max; | |||||
} | |||||
/* these numbers exclude the control endpoint */ | /* these numbers exclude the control endpoint */ | ||||
DPRINTFN(2, "RX/TX endpoints: %u/%u\n", nrx, ntx); | DPRINTFN(2, "RX/TX endpoints: %u/%u\n", nrx, ntx); | ||||
sc->sc_ep_max = (nrx > ntx) ? nrx : ntx; | |||||
if (sc->sc_ep_max == 0) { | if (sc->sc_ep_max == 0) { | ||||
DPRINTFN(2, "ERROR: Looks like the clocks are off!\n"); | DPRINTFN(2, "ERROR: Looks like the clocks are off!\n"); | ||||
} | } | ||||
/* read out configuration data */ | /* read out configuration data */ | ||||
sc->sc_conf_data = MUSB2_READ_1(sc, MUSB2_REG_CONFDATA); | sc->sc_conf_data = MUSB2_READ_1(sc, MUSB2_REG_CONFDATA); | ||||
DPRINTFN(2, "Config Data: 0x%02x\n", | DPRINTFN(2, "Config Data: 0x%02x\n", | ||||
Show All 23 Lines | for (temp = 1; temp <= sc->sc_ep_max; temp++) { | ||||
frx = (fsize & MUSB2_MASK_RX_FSIZE) / 16; | frx = (fsize & MUSB2_MASK_RX_FSIZE) / 16; | ||||
ftx = (fsize & MUSB2_MASK_TX_FSIZE); | ftx = (fsize & MUSB2_MASK_TX_FSIZE); | ||||
DPRINTF("Endpoint %u FIFO size: IN=%u, OUT=%u, DYN=%d\n", | DPRINTF("Endpoint %u FIFO size: IN=%u, OUT=%u, DYN=%d\n", | ||||
temp, ftx, frx, dynfifo); | temp, ftx, frx, dynfifo); | ||||
if (dynfifo) { | if (dynfifo) { | ||||
if (frx && (temp <= nrx)) { | if (frx && (temp <= nrx)) { | ||||
if (temp == 1) { | for (i = 0; sc->sc_eb_cfg[i].ep_end >= 0; i++) { | ||||
frx = 12; /* 4K */ | cfg = &sc->sc_eb_cfg[i]; | ||||
MUSB2_WRITE_1(sc, MUSB2_REG_RXFIFOSZ, | if (temp <= cfg->ep_end) { | ||||
MUSB2_VAL_FIFOSZ_4096 | | frx = cfg->ep_fifosz_shift; | ||||
MUSB2_MASK_FIFODB); | MUSB2_WRITE_1(sc, | ||||
} else if (temp < 8) { | MUSB2_REG_RXFIFOSZ, | ||||
frx = 10; /* 1K */ | cfg->ep_fifosz_reg); | ||||
MUSB2_WRITE_1(sc, MUSB2_REG_RXFIFOSZ, | break; | ||||
MUSB2_VAL_FIFOSZ_512 | | |||||
MUSB2_MASK_FIFODB); | |||||
} else { | |||||
frx = 7; /* 128 bytes */ | |||||
MUSB2_WRITE_1(sc, MUSB2_REG_RXFIFOSZ, | |||||
MUSB2_VAL_FIFOSZ_128); | |||||
} | } | ||||
} | |||||
MUSB2_WRITE_2(sc, MUSB2_REG_RXFIFOADD, | MUSB2_WRITE_2(sc, MUSB2_REG_RXFIFOADD, | ||||
offset >> 3); | offset >> 3); | ||||
offset += (1 << frx); | offset += (1 << frx); | ||||
} | } | ||||
if (ftx && (temp <= ntx)) { | if (ftx && (temp <= ntx)) { | ||||
if (temp == 1) { | for (i = 0; sc->sc_eb_cfg[i].ep_end >= 0; i++) { | ||||
ftx = 12; /* 4K */ | cfg = &sc->sc_eb_cfg[i]; | ||||
MUSB2_WRITE_1(sc, MUSB2_REG_TXFIFOSZ, | if (temp <= cfg->ep_end) { | ||||
MUSB2_VAL_FIFOSZ_4096 | | ftx = cfg->ep_fifosz_shift; | ||||
MUSB2_MASK_FIFODB); | MUSB2_WRITE_1(sc, | ||||
} else if (temp < 8) { | MUSB2_REG_TXFIFOSZ, | ||||
ftx = 10; /* 1K */ | cfg->ep_fifosz_reg); | ||||
MUSB2_WRITE_1(sc, MUSB2_REG_TXFIFOSZ, | break; | ||||
MUSB2_VAL_FIFOSZ_512 | | } | ||||
MUSB2_MASK_FIFODB); | |||||
} else { | |||||
ftx = 7; /* 128 bytes */ | |||||
MUSB2_WRITE_1(sc, MUSB2_REG_TXFIFOSZ, | |||||
MUSB2_VAL_FIFOSZ_128); | |||||
} | } | ||||
MUSB2_WRITE_2(sc, MUSB2_REG_TXFIFOADD, | MUSB2_WRITE_2(sc, MUSB2_REG_TXFIFOADD, | ||||
offset >> 3); | offset >> 3); | ||||
offset += (1 << ftx); | offset += (1 << ftx); | ||||
} | } | ||||
} | } | ||||
▲ Show 20 Lines • Show All 1,018 Lines • Show Last 20 Lines |
(Why the extra parentheses?)