Example #1
0
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;
}
Example #2
0
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));
}
Example #3
0
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));
}