// SPDX-License-Identifier: GPL-2.0+ /* * at91_udc -- driver for at91-series USB peripheral controller * * Copyright (C) 2004 by Thomas Rathbone * Copyright (C) 2005 by HP Labs * Copyright (C) 2005 by David Brownell
*/
/* * This controller is simple and PIO-only. It's used in many AT91-series * full speed USB controllers, including the at91rm9200 (arm920T, with MMU), * at91sam926x (arm926ejs, with MMU), and several no-mmu versions. * * This driver expects the board has been wired with two GPIOs supporting * a VBUS sensing IRQ, and a D+ pullup. (They may be omitted, but the * testing hasn't covered such cases.) * * The pullup is most important (so it's integrated on sam926x parts). It * provides software control over whether the host enumerates the device. * * The VBUS sensing helps during enumeration, and allows both USB clocks * (and the transceiver) to stay gated off until they're necessary, saving * power. During USB suspend, the 48 MHz clock is gated off in hardware; * it may also be gated off by software during some Linux sleep states.
*/
/* ep0 is always ready; other endpoints need a non-empty queue */ if (list_empty(&ep->queue) && ep->int_mask != (1 << 0))
at91_udp_write(udc, AT91_UDP_IDR, ep->int_mask);
}
/* bits indicating OUT fifo has data ready */ #define RX_DATA_READY (AT91_UDP_RX_DATA_BK0 | AT91_UDP_RX_DATA_BK1)
/* * Endpoint FIFO CSR bits have a mix of bits, making it unsafe to just write * back most of the value you just read (because of side effects, including * bits that may change after reading and before writing). * * Except when changing a specific bit, always write values which: * - clear SET_FX bits (setting them could change something) * - set CLR_FX bits (clearing them could change something) * * There are also state bits like FORCESTALL, EPEDS, DIR, and EPTYPE * that shouldn't normally be changed. * * NOTE at91sam9260 docs mention synch between UDPCK and MCK clock domains, * implying a need to wait for one write to complete (test relevant bits) * before starting the next write. This shouldn't be an issue given how * infrequently we write, except maybe for write-then-read idioms.
*/ #define SET_FX (AT91_UDP_TXPKTRDY) #define CLR_FX (RX_DATA_READY | AT91_UDP_RXSETUP \
| AT91_UDP_STALLSENT | AT91_UDP_TXCOMP)
/* * there might be nothing to read if ep_queue() calls us, * or if we already emptied both pingpong buffers
*/
rescan:
csr = __raw_readl(creg); if ((csr & RX_DATA_READY) == 0) return 0;
/* * avoid extra trips through IRQ logic for packets already in * the fifo ... maybe preventing an extra (expensive) OUT-NAK
*/ if (is_done)
done(ep, req, 0); elseif (ep->is_pingpong) { /* * One dummy read to delay the code because of a HW glitch: * CSR returns bad RXCOUNT when read too soon after updating * RX_DATA_BK flags.
*/
csr = __raw_readl(creg);
/* * TODO: allow for writing two packets to the fifo ... that'll * reduce the amount of IN-NAKing, but probably won't affect * throughput much. (Unlike preventing OUT-NAKing!)
*/
/* * If ep_queue() calls us, the queue is empty and possibly in * odd states like TXCOMP not yet cleared (we do it, saving at * least one IRQ) or the fifo not yet being free. Those aren't * issues normally (IRQ handler fast path).
*/ if (unlikely(csr & (AT91_UDP_TXCOMP | AT91_UDP_TXPKTRDY))) { if (csr & AT91_UDP_TXCOMP) {
csr |= CLR_FX;
csr &= ~(SET_FX | AT91_UDP_TXCOMP);
__raw_writel(csr, creg);
csr = __raw_readl(creg);
} if (csr & AT91_UDP_TXPKTRDY) return 0;
}
/* * Write the packet, maybe it's a ZLP. * * NOTE: incrementing req->actual before we receive the ACK means * gadget driver IN bytecounts can be wrong in fault cases. That's * fixable with PIO drivers like this one (save "count" here, and * do the increment later on TX irq), but not for most DMA hardware. * * So all gadget drivers must accept that potential error. Some * hardware supports precise fifo status reporting, letting them * recover when the actual bytecount matters (e.g. for USB Test * and Measurement Class devices).
*/
__raw_writesb(dreg, buf, count);
csr &= ~SET_FX;
csr |= CLR_FX | AT91_UDP_TXPKTRDY;
__raw_writel(csr, creg);
req->req.actual += count;
tmp = usb_endpoint_type(desc); switch (tmp) { case USB_ENDPOINT_XFER_CONTROL:
DBG("only one control endpoint\n"); return -EINVAL; case USB_ENDPOINT_XFER_INT: if (maxpacket > 64) goto bogus_max; break; case USB_ENDPOINT_XFER_BULK: switch (maxpacket) { case 8: case 16: case 32: case 64: goto ok;
}
bogus_max:
DBG("bogus maxpacket %d\n", maxpacket); return -EINVAL; case USB_ENDPOINT_XFER_ISOC: if (!ep->is_pingpong) {
DBG("iso requires double buffering\n"); return -EINVAL;
} break;
}
ok:
spin_lock_irqsave(&udc->lock, flags);
/* initialize endpoint to match this descriptor */
ep->is_in = usb_endpoint_dir_in(desc);
ep->is_iso = (tmp == USB_ENDPOINT_XFER_ISOC);
ep->stopped = 0; if (ep->is_in)
tmp |= 0x04;
tmp <<= 8;
tmp |= AT91_UDP_EPEDS;
__raw_writel(tmp, ep->creg);
/* try to kickstart any empty and idle queue */ if (list_empty(&ep->queue) && !ep->stopped) { int is_ep0;
/* * If this control request has a non-empty DATA stage, this * will start that stage. It works just like a non-control * request (until the status stage starts, maybe early). * * If the data stage is empty, then this starts a successful * IN/STATUS stage. (Unsuccessful ones use set_halt.)
*/
is_ep0 = (ep->ep.name == ep0name); if (is_ep0) {
u32 tmp;
if (!udc->req_pending) {
status = -EINVAL; goto done;
}
/* * defer changing CONFG until after the gadget driver * reconfigures the endpoints.
*/ if (udc->wait_for_config_ack) {
tmp = at91_udp_read(udc, AT91_UDP_GLB_STAT);
tmp ^= AT91_UDP_CONFG;
VDBG("toggle config\n");
at91_udp_write(udc, AT91_UDP_GLB_STAT, tmp);
} if (req->req.length == 0) {
ep0_in_status:
PACKET("ep0 in/status\n");
status = 0;
tmp = __raw_readl(ep->creg);
tmp &= ~SET_FX;
tmp |= CLR_FX | AT91_UDP_TXPKTRDY;
__raw_writel(tmp, ep->creg);
udc->req_pending = 0; goto done;
}
}
if (ep->is_in)
status = write_fifo(ep, req); else {
status = read_fifo(ep, req);
/* IN/STATUS stage is otherwise triggered by irq */ if (status && is_ep0) goto ep0_in_status;
}
} else
status = 0;
/* * activate/deactivate link with host; minimize power usage for * inactive links by cutting clocks and transceiver power.
*/ staticvoid pullup(struct at91_udc *udc, int is_on)
{ if (!udc->enabled || !udc->vbus)
is_on = 0;
DBG("%sactive\n", is_on ? "" : "in");
/* * VBUS-powered devices may also want to support bigger * power budgets after an appropriate SET_CONFIGURATION.
*/ /* .vbus_power = at91_vbus_power, */
};
/* * A few standard requests get handled here, ones that touch * hardware ... notably for device and endpoint features.
*/
udc->req_pending = 1;
csr = __raw_readl(creg);
csr |= CLR_FX;
csr &= ~SET_FX; switch ((pkt.r.bRequestType << 8) | pkt.r.bRequest) {
case ((USB_TYPE_STANDARD|USB_RECIP_DEVICE) << 8)
| USB_REQ_SET_ADDRESS:
__raw_writel(csr | AT91_UDP_TXPKTRDY, creg);
udc->addr = w_value;
udc->wait_for_addr_ack = 1;
udc->req_pending = 0; /* FADDR is set later, when we ack host STATUS */ return;
case ((USB_TYPE_STANDARD|USB_RECIP_DEVICE) << 8)
| USB_REQ_SET_CONFIGURATION:
tmp = at91_udp_read(udc, AT91_UDP_GLB_STAT) & AT91_UDP_CONFG; if (pkt.r.wValue)
udc->wait_for_config_ack = (tmp == 0); else
udc->wait_for_config_ack = (tmp != 0); if (udc->wait_for_config_ack)
VDBG("wait for config\n"); /* CONFG is toggled later, if gadget driver succeeds */ break;
/* * Hosts may set or clear remote wakeup status, and * devices may report they're VBUS powered.
*/ case ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_DEVICE) << 8)
| USB_REQ_GET_STATUS:
tmp = (udc->gadget.is_selfpowered << USB_DEVICE_SELF_POWERED); if (at91_udp_read(udc, AT91_UDP_GLB_STAT) & AT91_UDP_ESR)
tmp |= (1 << USB_DEVICE_REMOTE_WAKEUP);
PACKET("get device status\n");
__raw_writeb(tmp, dreg);
__raw_writeb(0, dreg); goto write_in; /* then STATUS starts later, automatically */ case ((USB_TYPE_STANDARD|USB_RECIP_DEVICE) << 8)
| USB_REQ_SET_FEATURE: if (w_value != USB_DEVICE_REMOTE_WAKEUP) goto stall;
tmp = at91_udp_read(udc, AT91_UDP_GLB_STAT);
tmp |= AT91_UDP_ESR;
at91_udp_write(udc, AT91_UDP_GLB_STAT, tmp); goto succeed; case ((USB_TYPE_STANDARD|USB_RECIP_DEVICE) << 8)
| USB_REQ_CLEAR_FEATURE: if (w_value != USB_DEVICE_REMOTE_WAKEUP) goto stall;
tmp = at91_udp_read(udc, AT91_UDP_GLB_STAT);
tmp &= ~AT91_UDP_ESR;
at91_udp_write(udc, AT91_UDP_GLB_STAT, tmp); goto succeed;
/* * Interfaces have no feature settings; this is pretty useless. * we won't even insist the interface exists...
*/ case ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_INTERFACE) << 8)
| USB_REQ_GET_STATUS:
PACKET("get interface status\n");
__raw_writeb(0, dreg);
__raw_writeb(0, dreg); goto write_in; /* then STATUS starts later, automatically */ case ((USB_TYPE_STANDARD|USB_RECIP_INTERFACE) << 8)
| USB_REQ_SET_FEATURE: case ((USB_TYPE_STANDARD|USB_RECIP_INTERFACE) << 8)
| USB_REQ_CLEAR_FEATURE: goto stall;
/* * Hosts may clear bulk/intr endpoint halt after the gadget * driver sets it (not widely used); or set it (for testing)
*/ case ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_ENDPOINT) << 8)
| USB_REQ_GET_STATUS:
tmp = w_index & USB_ENDPOINT_NUMBER_MASK;
ep = &udc->ep[tmp]; if (tmp >= NUM_ENDPOINTS || (tmp && !ep->ep.desc)) goto stall;
if (tmp) { if ((w_index & USB_DIR_IN)) { if (!ep->is_in) goto stall;
} elseif (ep->is_in) goto stall;
}
PACKET("get %s status\n", ep->ep.name); if (__raw_readl(ep->creg) & AT91_UDP_FORCESTALL)
tmp = (1 << USB_ENDPOINT_HALT); else
tmp = 0;
__raw_writeb(tmp, dreg);
__raw_writeb(0, dreg); goto write_in; /* then STATUS starts later, automatically */ case ((USB_TYPE_STANDARD|USB_RECIP_ENDPOINT) << 8)
| USB_REQ_SET_FEATURE:
tmp = w_index & USB_ENDPOINT_NUMBER_MASK;
ep = &udc->ep[tmp]; if (w_value != USB_ENDPOINT_HALT || tmp >= NUM_ENDPOINTS) goto stall; if (!ep->ep.desc || ep->is_iso) goto stall; if ((w_index & USB_DIR_IN)) { if (!ep->is_in) goto stall;
} elseif (ep->is_in) goto stall;
tmp = __raw_readl(ep->creg);
tmp &= ~SET_FX;
tmp |= CLR_FX | AT91_UDP_FORCESTALL;
__raw_writel(tmp, ep->creg); goto succeed; case ((USB_TYPE_STANDARD|USB_RECIP_ENDPOINT) << 8)
| USB_REQ_CLEAR_FEATURE:
tmp = w_index & USB_ENDPOINT_NUMBER_MASK;
ep = &udc->ep[tmp]; if (w_value != USB_ENDPOINT_HALT || tmp >= NUM_ENDPOINTS) goto stall; if (tmp == 0) goto succeed; if (!ep->ep.desc || ep->is_iso) goto stall; if ((w_index & USB_DIR_IN)) { if (!ep->is_in) goto stall;
} elseif (ep->is_in) goto stall;
/* host ACKed an IN packet that we sent */ if (csr & AT91_UDP_TXCOMP) {
csr |= CLR_FX;
csr &= ~(SET_FX | AT91_UDP_TXCOMP);
/* write more IN DATA? */ if (req && ep0->is_in) { if (handle_ep(ep0))
udc->req_pending = 0;
/* * Ack after: * - last IN DATA packet (including GET_STATUS) * - IN/STATUS for OUT DATA * - IN/STATUS for any zero-length DATA stage * except for the IN DATA case, the host should send * an OUT status later, which we'll ack.
*/
} else {
udc->req_pending = 0;
__raw_writel(csr, creg);
/* * SET_ADDRESS takes effect only after the STATUS * (to the original address) gets acked.
*/ if (udc->wait_for_addr_ack) {
u32 tmp;
/* OUT DATA stage */ if (!ep0->is_in) { if (req) { if (handle_ep(ep0)) { /* send IN/STATUS */
PACKET("ep0 in/status\n");
csr = __raw_readl(creg);
csr &= ~SET_FX;
csr |= CLR_FX | AT91_UDP_TXPKTRDY;
__raw_writel(csr, creg);
udc->req_pending = 0;
}
} elseif (udc->req_pending) { /* * AT91 hardware has a hard time with this * "deferred response" mode for control-OUT * transfers. (For control-IN it's fine.) * * The normal solution leaves OUT data in the * fifo until the gadget driver is ready. * We couldn't do that here without disabling * the IRQ that tells about SETUP packets, * e.g. when the host gets impatient... * * Working around it by copying into a buffer * would almost be a non-deferred response, * except that it wouldn't permit reliable * stalling of the request. Instead, demand * that gadget drivers not use this mode.
*/
DBG("no control-OUT deferred responses!\n");
__raw_writel(csr | AT91_UDP_FORCESTALL, creg);
udc->req_pending = 0;
}
/* STATUS stage for control-IN; ack. */
} else {
PACKET("ep0 out/status ACK\n");
__raw_writel(csr, creg);
/* "early" status stage */ if (req)
done(ep0, req, 0);
}
}
}
/* * NOTE: this driver keeps clocks off unless the * USB host is present. That saves power, but for * boards that don't support VBUS detection, both * clocks need to be active most of the time.
*/
/* * NOTE: when suspending a VBUS-powered device, the * gadget driver should switch into slow clock mode * and then into standby to avoid drawing more than * 500uA power (2500uA for some high-power configs).
*/ if (udc->driver && udc->driver->suspend) {
spin_unlock(&udc->lock);
udc->driver->suspend(&udc->gadget);
spin_lock(&udc->lock);
}
/* * NOTE: for a VBUS-powered device, the gadget driver * would normally want to switch out of slow clock * mode into normal mode.
*/ if (udc->driver && udc->driver->resume) {
spin_unlock(&udc->lock);
udc->driver->resume(&udc->gadget);
spin_lock(&udc->lock);
}
/* endpoint IRQs are cleared by handling them */
} else { int i; unsigned mask = 1; struct at91_ep *ep = &udc->ep[1];
if (status & mask)
handle_ep0(udc); for (i = 1; i < NUM_ENDPOINTS; i++) {
mask <<= 1; if (status & mask)
handle_ep(ep);
ep++;
}
}
}
/* * If we are polling vbus it is likely that the gpio is on an * bus such as i2c or spi which may sleep, so schedule some work * to read the vbus gpio
*/
schedule_work(&udc->vbus_timer_work);
}
for (i = 0; i < NUM_ENDPOINTS; i++) {
ep = &udc->ep[i];
ep->ep.name = ep_info[i].name;
ep->ep.caps = ep_info[i].caps;
ep->ep.ops = &at91_ep_ops;
ep->udc = udc;
ep->int_mask = BIT(i); if (i != 0 && i != 3)
ep->is_pingpong = 1;
}
udc->udp_baseaddr = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(udc->udp_baseaddr)) return PTR_ERR(udc->udp_baseaddr);
if (udc->caps && udc->caps->init) {
retval = udc->caps->init(udc); if (retval) return retval;
}
udc_reinit(udc);
/* get interface and function clocks */
udc->iclk = devm_clk_get(dev, "pclk"); if (IS_ERR(udc->iclk)) return PTR_ERR(udc->iclk);
udc->fclk = devm_clk_get(dev, "hclk"); if (IS_ERR(udc->fclk)) return PTR_ERR(udc->fclk);
/* don't do anything until we have both gadget driver and VBUS */
clk_set_rate(udc->fclk, 48000000);
retval = clk_prepare(udc->fclk); if (retval) return retval;
retval = clk_prepare_enable(udc->iclk); if (retval) goto err_unprepare_fclk;
at91_udp_write(udc, AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS);
at91_udp_write(udc, AT91_UDP_IDR, 0xffffffff); /* Clear all pending interrupts - UDP may be used by bootloader. */
at91_udp_write(udc, AT91_UDP_ICR, 0xffffffff);
clk_disable(udc->iclk);
/* Unless we can act normally to the host (letting it wake us up * whenever it has work for us) force disconnect. Wakeup requires * PLLB for USB events (signaling for reset, wakeup, or incoming * tokens) and VBUS irqs (on systems which support them).
*/ if ((!udc->suspended && udc->addr)
|| !wake
|| at91_suspend_entering_slow_clock()) {
spin_lock_irqsave(&udc->lock, flags);
pullup(udc, 0);
wake = 0;
spin_unlock_irqrestore(&udc->lock, flags);
} else
enable_irq_wake(udc->udp_irq);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.