static void mv_twsi_cal_baud_rate(const uint32_t target, struct mv_twsi_baud_rate *rate) { uint32_t clk, cur, diff, diff0; int m, n, m0, n0; /* Calculate baud rate. */ m0 = n0 = 4; /* Default values on reset */ diff0 = 0xffffffff; clk = get_tclk(); for (n = 0; n < 8; n++) { for (m = 0; m < 16; m++) { cur = TWSI_BAUD_RATE_RAW(clk,m,n); diff = ABSSUB(target, cur); if (diff < diff0) { m0 = m; n0 = n; diff0 = diff; } } } rate->raw = TWSI_BAUD_RATE_RAW(clk, m0, n0); rate->param = TWSI_BAUD_RATE_PARAM(m0, n0); rate->m = m0; rate->n = n0; }
static int a10_twsi_attach(device_t dev) { struct twsi_softc *sc; clk_t clk; hwreset_t rst; int error; sc = device_get_softc(dev); /* De-assert reset */ if (hwreset_get_by_ofw_idx(dev, 0, &rst) == 0) { error = hwreset_deassert(rst); if (error != 0) { device_printf(dev, "could not de-assert reset\n"); return (error); } } /* Activate clock */ error = clk_get_by_ofw_index(dev, 0, &clk); if (error != 0) { device_printf(dev, "could not find clock\n"); return (error); } error = clk_enable(clk); if (error != 0) { device_printf(dev, "could not enable clock\n"); return (error); } sc->reg_data = TWI_DATA; sc->reg_slave_addr = TWI_ADDR; sc->reg_slave_ext_addr = TWI_XADDR; sc->reg_control = TWI_CNTR; sc->reg_status = TWI_STAT; sc->reg_baud_rate = TWI_CCR; sc->reg_soft_reset = TWI_SRST; /* Setup baud rate params */ sc->baud_rate[IIC_SLOW].param = TWSI_BAUD_RATE_PARAM(11, 2); sc->baud_rate[IIC_FAST].param = TWSI_BAUD_RATE_PARAM(11, 2); sc->baud_rate[IIC_FASTEST].param = TWSI_BAUD_RATE_PARAM(2, 2); return (twsi_attach(dev)); }
static int a10_twsi_attach(device_t dev) { struct twsi_softc *sc; int clk; sc = device_get_softc(dev); /* Activate clock */ switch (ofw_bus_search_compatible(dev, compat_data)->ocd_data) { #if defined(SOC_ALLWINNER_A10) || defined(SOC_ALLWINNER_A20) case A10_I2C: clk = a10_clk_i2c_activate(device_get_unit(dev)); break; #endif #if defined(SOC_ALLWINNER_A31) || defined(SOC_ALLWINNER_A31S) case A31_I2C: clk = a31_clk_i2c_activate(device_get_unit(dev)); break; #endif default: clk = -1; } if (clk != 0) { device_printf(dev, "could not activate i2c clock\n"); return (ENXIO); } sc->reg_data = TWI_DATA; sc->reg_slave_addr = TWI_ADDR; sc->reg_slave_ext_addr = TWI_XADDR; sc->reg_control = TWI_CNTR; sc->reg_status = TWI_STAT; sc->reg_baud_rate = TWI_CCR; sc->reg_soft_reset = TWI_SRST; /* Setup baud rate params */ sc->baud_rate[IIC_SLOW].param = TWSI_BAUD_RATE_PARAM(11, 2); sc->baud_rate[IIC_FAST].param = TWSI_BAUD_RATE_PARAM(11, 2); sc->baud_rate[IIC_FASTEST].param = TWSI_BAUD_RATE_PARAM(2, 2); return (twsi_attach(dev)); }