static void cuda_init(struct cuda_softc *sc) { volatile int i; uint8_t reg; reg = cuda_read_reg(sc, vDirB); reg |= 0x30; /* register B bits 4 and 5: outputs */ cuda_write_reg(sc, vDirB, reg); reg = cuda_read_reg(sc, vDirB); reg &= 0xf7; /* register B bit 3: input */ cuda_write_reg(sc, vDirB, reg); reg = cuda_read_reg(sc, vACR); reg &= ~vSR_OUT; /* make sure SR is set to IN */ cuda_write_reg(sc, vACR, reg); cuda_write_reg(sc, vACR, (cuda_read_reg(sc, vACR) | 0x0c) & ~0x10); sc->sc_state = CUDA_IDLE; /* used by all types of hardware */ cuda_write_reg(sc, vIER, 0x84); /* make sure VIA interrupts are on */ cuda_idle(sc); /* set ADB bus state to idle */ /* sort of a device reset */ i = cuda_read_reg(sc, vSR); /* clear interrupt */ cuda_write_reg(sc, vIER, 0x04); /* no interrupts while clearing */ cuda_idle(sc); /* reset state to idle */ delay(150); cuda_tip(sc); /* signal start of frame */ delay(150); cuda_toggle_ack(sc); delay(150); cuda_clear_tip(sc); delay(150); cuda_idle(sc); /* back to idle state */ i = cuda_read_reg(sc, vSR); /* clear interrupt */ cuda_write_reg(sc, vIER, 0x84); /* ints ok now */ }
static int cuda_attach(device_t dev) { struct cuda_softc *sc; volatile int i; uint8_t reg; phandle_t node,child; sc = device_get_softc(dev); sc->sc_dev = dev; sc->sc_memrid = 0; sc->sc_memr = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->sc_memrid, RF_ACTIVE); if (sc->sc_memr == NULL) { device_printf(dev, "Could not alloc mem resource!\n"); return (ENXIO); } sc->sc_irqrid = 0; sc->sc_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->sc_irqrid, RF_ACTIVE); if (sc->sc_irq == NULL) { device_printf(dev, "could not allocate interrupt\n"); return (ENXIO); } if (bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_MISC | INTR_MPSAFE | INTR_ENTROPY, NULL, cuda_intr, dev, &sc->sc_ih) != 0) { device_printf(dev, "could not setup interrupt\n"); bus_release_resource(dev, SYS_RES_IRQ, sc->sc_irqrid, sc->sc_irq); return (ENXIO); } mtx_init(&sc->sc_mutex,"cuda",NULL,MTX_DEF | MTX_RECURSE); sc->sc_sent = 0; sc->sc_received = 0; sc->sc_waiting = 0; sc->sc_polling = 0; sc->sc_state = CUDA_NOTREADY; sc->sc_autopoll = 0; sc->sc_rtc = -1; STAILQ_INIT(&sc->sc_inq); STAILQ_INIT(&sc->sc_outq); STAILQ_INIT(&sc->sc_freeq); for (i = 0; i < CUDA_MAXPACKETS; i++) STAILQ_INSERT_TAIL(&sc->sc_freeq, &sc->sc_pkts[i], pkt_q); /* Init CUDA */ reg = cuda_read_reg(sc, vDirB); reg |= 0x30; /* register B bits 4 and 5: outputs */ cuda_write_reg(sc, vDirB, reg); reg = cuda_read_reg(sc, vDirB); reg &= 0xf7; /* register B bit 3: input */ cuda_write_reg(sc, vDirB, reg); reg = cuda_read_reg(sc, vACR); reg &= ~vSR_OUT; /* make sure SR is set to IN */ cuda_write_reg(sc, vACR, reg); cuda_write_reg(sc, vACR, (cuda_read_reg(sc, vACR) | 0x0c) & ~0x10); sc->sc_state = CUDA_IDLE; /* used by all types of hardware */ cuda_write_reg(sc, vIER, 0x84); /* make sure VIA interrupts are on */ cuda_idle(sc); /* reset ADB */ /* Reset CUDA */ i = cuda_read_reg(sc, vSR); /* clear interrupt */ cuda_write_reg(sc, vIER, 0x04); /* no interrupts while clearing */ cuda_idle(sc); /* reset state to idle */ DELAY(150); cuda_tip(sc); /* signal start of frame */ DELAY(150); cuda_toggle_ack(sc); DELAY(150); cuda_clear_tip(sc); DELAY(150); cuda_idle(sc); /* back to idle state */ i = cuda_read_reg(sc, vSR); /* clear interrupt */ cuda_write_reg(sc, vIER, 0x84); /* ints ok now */ /* Initialize child buses (ADB) */ node = ofw_bus_get_node(dev); for (child = OF_child(node); child != 0; child = OF_peer(child)) { char name[32]; memset(name, 0, sizeof(name)); OF_getprop(child, "name", name, sizeof(name)); if (bootverbose) device_printf(dev, "CUDA child <%s>\n",name); if (strncmp(name, "adb", 4) == 0) { sc->adb_bus = device_add_child(dev,"adb",-1); } } clock_register(dev, 1000); EVENTHANDLER_REGISTER(shutdown_final, cuda_shutdown, sc, SHUTDOWN_PRI_LAST); return (bus_generic_attach(dev)); }