void at91ohci_callback(device_t self) { struct at91ohci_softc *sc = device_private(self); usbd_status r; /* Disable interrupts, so we don't get any spurious ones. */ bus_space_write_4(sc->sc.iot, sc->sc.ioh, OHCI_INTERRUPT_DISABLE, OHCI_ALL_INTRS); strlcpy(sc->sc.sc_vendor, "Atmel", sizeof sc->sc.sc_vendor); sc->sc_ih = at91_intr_establish(sc->sc_pid, IPL_USB, INTR_HIGH_LEVEL, ohci_intr, sc); r = ohci_init(&sc->sc); if (r != USBD_NORMAL_COMPLETION) { printf("%s: init failed, error=%d\n", device_xname(self), r); at91_intr_disestablish(sc->sc_ih); return; } /* Attach usb device. */ sc->sc.sc_child = config_found(self, &sc->sc.sc_bus, usbctlprint); }
static void emac_attach(device_t parent, device_t self, void *aux) { struct emac_softc *sc = device_private(self); struct at91bus_attach_args *sa = aux; prop_data_t enaddr; uint32_t u; printf("\n"); sc->sc_dev = self; sc->sc_iot = sa->sa_iot; sc->sc_pid = sa->sa_pid; sc->sc_dmat = sa->sa_dmat; if (bus_space_map(sa->sa_iot, sa->sa_addr, sa->sa_size, 0, &sc->sc_ioh)) panic("%s: Cannot map registers", device_xname(self)); /* enable peripheral clock */ at91_peripheral_clock(sc->sc_pid, 1); /* configure emac: */ EMAC_WRITE(ETH_CTL, 0); // disable everything EMAC_WRITE(ETH_IDR, -1); // disable interrupts EMAC_WRITE(ETH_RBQP, 0); // clear receive EMAC_WRITE(ETH_CFG, ETH_CFG_CLK_32 | ETH_CFG_SPD | ETH_CFG_FD | ETH_CFG_BIG); EMAC_WRITE(ETH_TCR, 0); // send nothing //(void)EMAC_READ(ETH_ISR); u = EMAC_READ(ETH_TSR); EMAC_WRITE(ETH_TSR, (u & (ETH_TSR_UND | ETH_TSR_COMP | ETH_TSR_BNQ | ETH_TSR_IDLE | ETH_TSR_RLE | ETH_TSR_COL|ETH_TSR_OVR))); u = EMAC_READ(ETH_RSR); EMAC_WRITE(ETH_RSR, (u & (ETH_RSR_OVR|ETH_RSR_REC|ETH_RSR_BNA))); /* Fetch the Ethernet address from property if set. */ enaddr = prop_dictionary_get(device_properties(self), "mac-addr"); if (enaddr != NULL) { KASSERT(prop_object_type(enaddr) == PROP_TYPE_DATA); KASSERT(prop_data_size(enaddr) == ETHER_ADDR_LEN); memcpy(sc->sc_enaddr, prop_data_data_nocopy(enaddr), ETHER_ADDR_LEN); } else { static const uint8_t hardcoded[ETHER_ADDR_LEN] = { 0x00, 0x0d, 0x10, 0x81, 0x0c, 0x94 }; memcpy(sc->sc_enaddr, hardcoded, ETHER_ADDR_LEN); } at91_intr_establish(sc->sc_pid, IPL_NET, INTR_HIGH_LEVEL, emac_intr, sc); emac_init(sc); }
void cpu_initclocks(void) { struct at91st_softc *sc = at91st_sc; if (!sc || !sc->sc_initialized) panic("%s: driver has not been initialized! (sc=%p)", __FUNCTION__, sc); stathz = profhz = 0; /* set up and enable interval timer 1 as kernel timer, */ /* using 32kHz clock source */ WRITE_ST(ST_PIMR, AT91ST_DIVIDER); /* register interrupt handler */ at91_intr_establish(sc->sc_pid, IPL_CLOCK, INTR_HIGH_LEVEL, at91st_intr, NULL); /* enable interrupts from timer */ WRITE_ST(ST_IER, ST_SR_PITS); }
void cpu_initclocks(void) { struct at91tctmr_softc *sc = at91tctmr_sc; if (!sc || !sc->sc_initialized) panic("%s: driver has not been initialized! (sc=%p)", __FUNCTION__, sc); hz = sc->sc_timerclock / sc->sc_divider; stathz = profhz = 0; /* set up and enable interval timer 1 as kernel timer, */ /* using 32kHz clock source */ /* register interrupt handler */ at91_intr_establish(sc->sc_pid, IPL_CLOCK, INTR_HIGH_LEVEL, at91tctmr_intr, sc); /* enable interrupts from timer */ WRITE_TC(sc, TC_IER, TC_SR_CPCS); }
void at91usart_attach_subr(struct at91usart_softc *sc, struct at91bus_attach_args *sa) { struct tty *tp; int err; printf("\n"); if (bus_space_map(sa->sa_iot, sa->sa_addr, sa->sa_size, 0, &sc->sc_ioh)) panic("%s: Cannot map registers", device_xname(sc->sc_dev)); sc->sc_iot = sa->sa_iot; sc->sc_hwbase = sa->sa_addr; sc->sc_dmat = sa->sa_dmat; sc->sc_pid = sa->sa_pid; /* allocate fifos */ err = at91pdc_alloc_fifo(sc->sc_dmat, &sc->sc_rx_fifo, AT91USART_RING_SIZE, BUS_DMA_READ | BUS_DMA_STREAMING); if (err) panic("%s: cannot allocate rx fifo", device_xname(sc->sc_dev)); err = at91pdc_alloc_fifo(sc->sc_dmat, &sc->sc_tx_fifo, AT91USART_RING_SIZE, BUS_DMA_WRITE | BUS_DMA_STREAMING); if (err) panic("%s: cannot allocate tx fifo", device_xname(sc->sc_dev)); /* initialize uart */ at91_peripheral_clock(sc->sc_pid, 1); at91usart_writereg(sc, US_IDR, -1); at91usart_writereg(sc, US_RTOR, 12); // 12-bit timeout at91usart_writereg(sc, US_PDC + PDC_PTCR, PDC_PTCR_TXTDIS | PDC_PTCR_RXTDIS); at91_intr_establish(sa->sa_pid, IPL_TTY, INTR_HIGH_LEVEL, at91usart_intr, sc); USART_INIT(sc, 115200U); #ifdef NOTYET if (sc->sc_iot == usart_cn_sc.sc_iot && sc->sc_hwbase == usart_cn_sc.sc_hwbase) { usart_cn_sc.sc_attached = 1; /* Make sure the console is always "hardwired". */ delay(10000); /* wait for output to finish */ SET(sc->sc_hwflags, COM_HW_CONSOLE); SET(sc->sc_swflags, TIOCFLAG_SOFTCAR); SET(sc->sc_ier, USART_INT_RXRDY); USARTREG(USART_IER) = USART_INT_RXRDY; // @@@@@ } #endif // NOTYET tp = tty_alloc(); tp->t_oproc = at91usart_start; tp->t_param = at91usart_param; tp->t_hwiflow = at91usart_hwiflow; sc->sc_tty = tp; tty_attach(tp); #if NOTYET if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) { int maj; /* locate the major number */ maj = cdevsw_lookup_major(&at91usart_cdevsw); cn_tab->cn_dev = makedev(maj, device_unit(sc->sc_dev)); aprint_normal("%s: console (maj %u min %u cn_dev %u)\n", device_xname(sc->sc_dev), maj, device_unit(sc->sc_dev), cn_tab->cn_dev); } #endif /* NOTYET */ sc->sc_si = softint_establish(SOFTINT_SERIAL, at91usart_soft, sc); #ifdef RND_COM rnd_attach_source(&sc->rnd_source, device_xname(sc->sc_dev), RND_TYPE_TTY, RND_FLAG_DEFAULT); #endif /* if there are no enable/disable functions, assume the device is always enabled */ if (!sc->enable) sc->enabled = 1; /* XXX configure register */ /* xxx_config(sc) */ SET(sc->sc_hwflags, COM_HW_DEV_OK); }
static void at91dbgu_attach(device_t parent, device_t self, void *aux) { struct at91dbgu_softc *sc = device_private(self); struct at91bus_attach_args *sa = aux; struct tty *tp; printf("\n"); sc->sc_dev = self; bus_space_map(sa->sa_iot, sa->sa_addr, sa->sa_size, 0, &sc->sc_ioh); sc->sc_iot = sa->sa_iot; sc->sc_hwbase = sa->sa_addr; DBGUREG(DBGU_IDR) = -1; at91_intr_establish(sa->sa_pid, IPL_SERIAL, INTR_HIGH_LEVEL, dbgu_intr, sc); DBGU_INIT(AT91_MSTCLK, 115200U); if (sc->sc_iot == dbgu_cn_sc.sc_iot && sc->sc_hwbase == dbgu_cn_sc.sc_hwbase) { dbgu_cn_sc.sc_attached = 1; /* Make sure the console is always "hardwired". */ delay(10000); /* wait for output to finish */ SET(sc->sc_hwflags, COM_HW_CONSOLE); SET(sc->sc_swflags, TIOCFLAG_SOFTCAR); SET(sc->sc_ier, DBGU_INT_RXRDY); DBGUREG(DBGU_IER) = DBGU_INT_RXRDY; // @@@@@ } tp = tty_alloc(); tp->t_oproc = at91dbgu_start; tp->t_param = at91dbgu_param; tp->t_hwiflow = at91dbgu_hwiflow; sc->sc_tty = tp; sc->sc_rbuf = malloc(AT91DBGU_RING_SIZE << 1, M_DEVBUF, M_NOWAIT); sc->sc_rbput = sc->sc_rbget = sc->sc_rbuf; sc->sc_rbavail = AT91DBGU_RING_SIZE; if (sc->sc_rbuf == NULL) { printf("%s: unable to allocate ring buffer\n", device_xname(sc->sc_dev)); return; } sc->sc_ebuf = sc->sc_rbuf + (AT91DBGU_RING_SIZE << 1); sc->sc_tbc = 0; tty_attach(tp); if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) { int maj; /* locate the major number */ maj = cdevsw_lookup_major(&at91dbgu_cdevsw); cn_tab->cn_dev = makedev(maj, device_unit(sc->sc_dev)); aprint_normal("%s: console (maj %u min %u cn_dev %#"PRIx64")\n", device_xname(sc->sc_dev), maj, device_unit(sc->sc_dev), cn_tab->cn_dev); } sc->sc_si = softint_establish(SOFTINT_SERIAL, at91dbgu_soft, sc); #ifdef RND_COM rnd_attach_source(&sc->rnd_source, device_xname(sc->sc_dev), RND_TYPE_TTY, 0); #endif /* if there are no enable/disable functions, assume the device is always enabled */ if (!sc->enable) sc->enabled = 1; /* XXX configure register */ /* xxx_config(sc) */ SET(sc->sc_hwflags, COM_HW_DEV_OK); }
void at91spi_attach_common(device_t parent, device_t self, void *aux, at91spi_machdep_tag_t md) { struct at91spi_softc *sc = device_private(self); struct at91bus_attach_args *sa = aux; struct spibus_attach_args sba; bus_dma_segment_t segs; int rsegs, err; aprint_normal(": AT91 SPI Controller\n"); sc->sc_dev = self; sc->sc_iot = sa->sa_iot; sc->sc_pid = sa->sa_pid; sc->sc_dmat = sa->sa_dmat; sc->sc_md = md; if (bus_space_map(sa->sa_iot, sa->sa_addr, sa->sa_size, 0, &sc->sc_ioh)) panic("%s: Cannot map registers", device_xname(self)); /* we want to use dma, so allocate dma memory: */ err = bus_dmamem_alloc(sc->sc_dmat, PAGE_SIZE, 0, PAGE_SIZE, &segs, 1, &rsegs, BUS_DMA_WAITOK); if (err == 0) { err = bus_dmamem_map(sc->sc_dmat, &segs, 1, PAGE_SIZE, &sc->sc_dmapage, BUS_DMA_WAITOK); } if (err == 0) { err = bus_dmamap_create(sc->sc_dmat, PAGE_SIZE, 1, PAGE_SIZE, 0, BUS_DMA_WAITOK, &sc->sc_dmamap); } if (err == 0) { err = bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap, sc->sc_dmapage, PAGE_SIZE, NULL, BUS_DMA_WAITOK); } if (err != 0) { panic("%s: Cannot get DMA memory", device_xname(sc->sc_dev)); } sc->sc_dmaaddr = sc->sc_dmamap->dm_segs[0].ds_addr; /* * Initialize SPI controller */ sc->sc_spi.sct_cookie = sc; sc->sc_spi.sct_configure = at91spi_configure; sc->sc_spi.sct_transfer = at91spi_transfer; //sc->sc_spi.sct_nslaves must have been initialized by machdep code if (!sc->sc_spi.sct_nslaves) { aprint_error("%s: no slaves!\n", device_xname(sc->sc_dev)); } sba.sba_controller = &sc->sc_spi; /* initialize the queue */ SIMPLEQ_INIT(&sc->sc_q); /* reset the SPI */ at91_peripheral_clock(sc->sc_pid, 1); PUTREG(sc, SPI_CR, SPI_CR_SWRST); delay(100); /* be paranoid and make sure the PDC is dead */ PUTREG(sc, SPI_PDC_BASE + PDC_PTCR, PDC_PTCR_TXTDIS | PDC_PTCR_RXTDIS); PUTREG(sc, SPI_PDC_BASE + PDC_RNCR, 0); PUTREG(sc, SPI_PDC_BASE + PDC_RCR, 0); PUTREG(sc, SPI_PDC_BASE + PDC_TNCR, 0); PUTREG(sc, SPI_PDC_BASE + PDC_TCR, 0); // configure SPI: PUTREG(sc, SPI_IDR, -1); PUTREG(sc, SPI_CSR(0), SPI_CSR_SCBR | SPI_CSR_BITS_8); PUTREG(sc, SPI_CSR(1), SPI_CSR_SCBR | SPI_CSR_BITS_8); PUTREG(sc, SPI_CSR(2), SPI_CSR_SCBR | SPI_CSR_BITS_8); PUTREG(sc, SPI_CSR(3), SPI_CSR_SCBR | SPI_CSR_BITS_8); PUTREG(sc, SPI_MR, SPI_MR_MODFDIS/* <- machdep? */ | SPI_MR_MSTR); /* enable device interrupts */ sc->sc_ih = at91_intr_establish(sc->sc_pid, IPL_BIO, INTR_HIGH_LEVEL, at91spi_intr, sc); /* enable SPI */ PUTREG(sc, SPI_CR, SPI_CR_SPIEN); if (GETREG(sc, SPI_SR) & SPI_SR_RDRF) (void)GETREG(sc, SPI_RDR); PUTREG(sc, SPI_PDC_BASE + PDC_PTCR, PDC_PTCR_TXTEN | PDC_PTCR_RXTEN); /* attach slave devices */ (void) config_found_ia(sc->sc_dev, "spibus", &sba, spibus_print); }