static int at91_twi_attach(device_t dev) { struct at91_twi_softc *sc = device_get_softc(dev); int err; sc->dev = dev; err = at91_twi_activate(dev); if (err) goto out; AT91_TWI_LOCK_INIT(sc); #ifdef FDT /* * Disable devices need to hold their resources, so return now and not attach * the iicbus, setup interrupt handlers, etc. */ if (!ofw_bus_status_okay(dev)) return 0; #endif /* * Activate the interrupt */ err = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC | INTR_MPSAFE, NULL, at91_twi_intr, sc, &sc->intrhand); if (err) { AT91_TWI_LOCK_DESTROY(sc); goto out; } sc->cwgr = TWI_CWGR_CKDIV(8 * at91_master_clock / TWI_FASTEST_CLOCK) | TWI_CWGR_CHDIV(TWI_CWGR_DIV(TWI_DEF_CLK)) | TWI_CWGR_CLDIV(TWI_CWGR_DIV(TWI_DEF_CLK)); WR4(sc, TWI_CR, TWI_CR_SWRST); WR4(sc, TWI_CR, TWI_CR_MSEN | TWI_CR_SVDIS); WR4(sc, TWI_CWGR, sc->cwgr); if ((sc->iicbus = device_add_child(dev, "iicbus", -1)) == NULL) device_printf(dev, "could not allocate iicbus instance\n"); /* probe and attach the iicbus */ bus_generic_attach(dev); out: if (err) at91_twi_deactivate(dev); return (err); }
static int at91_twi_rst_card(device_t dev, u_char speed, u_char addr, u_char *oldaddr) { struct at91_twi_softc *sc; int clk; sc = device_get_softc(dev); AT91_TWI_LOCK(sc); if (oldaddr) *oldaddr = sc->twi_addr; sc->twi_addr = addr; /* * speeds are for 1.5kb/s, 45kb/s and 90kb/s. */ switch (speed) { case IIC_SLOW: clk = TWI_SLOW_CLOCK; break; case IIC_FAST: clk = TWI_FAST_CLOCK; break; case IIC_UNKNOWN: case IIC_FASTEST: default: clk = TWI_FASTEST_CLOCK; break; } sc->cwgr = TWI_CWGR_CKDIV(1) | TWI_CWGR_CHDIV(TWI_CWGR_DIV(clk)) | TWI_CWGR_CLDIV(TWI_CWGR_DIV(clk)); WR4(sc, TWI_CR, TWI_CR_SWRST); WR4(sc, TWI_CR, TWI_CR_MSEN | TWI_CR_SVDIS); WR4(sc, TWI_CWGR, sc->cwgr); printf("setting cwgr to %#x\n", sc->cwgr); AT91_TWI_UNLOCK(sc); return 0; }