Exemplo n.º 1
0
static int
mv_twsi_attach(device_t dev)
{
	struct mv_twsi_softc *sc;
	phandle_t child, iicbusnode;
	device_t childdev;
	struct iicbus_ivar *devi;
	char dname[32];	/* 32 is taken from struct u_device */
	uint32_t paddr;
	int len, error;

	sc = device_get_softc(dev);
	sc->dev = dev;
	bzero(baud_rate, sizeof(baud_rate));

	mtx_init(&sc->mutex, device_get_nameunit(dev), MV_TWSI_NAME, MTX_DEF);

	/* Allocate IO resources */
	if (bus_alloc_resources(dev, res_spec, sc->res)) {
		device_printf(dev, "could not allocate resources\n");
		mv_twsi_detach(dev);
		return (ENXIO);
	}

	mv_twsi_cal_baud_rate(TWSI_BAUD_RATE_SLOW, &baud_rate[IIC_SLOW]);
	mv_twsi_cal_baud_rate(TWSI_BAUD_RATE_FAST, &baud_rate[IIC_FAST]);
	if (bootverbose)
		device_printf(dev, "calculated baud rates are:\n"
		    " %" PRIu32 " kHz (M=%d, N=%d) for slow,\n"
		    " %" PRIu32 " kHz (M=%d, N=%d) for fast.\n",
		    baud_rate[IIC_SLOW].raw / 1000,
		    baud_rate[IIC_SLOW].m,
		    baud_rate[IIC_SLOW].n,
		    baud_rate[IIC_FAST].raw / 1000,
		    baud_rate[IIC_FAST].m,
		    baud_rate[IIC_FAST].n);

	sc->iicbus = device_add_child(dev, IICBUS_DEVNAME, -1);
	if (sc->iicbus == NULL) {
		device_printf(dev, "could not add iicbus child\n");
		mv_twsi_detach(dev);
		return (ENXIO);
	}
	/* Attach iicbus. */
	bus_generic_attach(dev);

	iicbusnode = 0;
	/* Find iicbus as the child devices in the device tree. */
	for (child = OF_child(ofw_bus_get_node(dev)); child != 0;
	    child = OF_peer(child)) {
		len = OF_getproplen(child, "model");
		if (len <= 0 || len > sizeof(dname) - 1)
			continue;
		error = OF_getprop(child, "model", &dname, len);
		dname[len + 1] = '\0';
		if (error == -1)
			continue;
		len = strlen(dname);
		if (len == strlen(IICBUS_DEVNAME) &&
		    strncasecmp(dname, IICBUS_DEVNAME, len) == 0) {
			iicbusnode = child;
			break; 
		}
	}
	if (iicbusnode == 0)
		goto attach_end;

	/* Attach child devices onto iicbus. */
	for (child = OF_child(iicbusnode); child != 0; child = OF_peer(child)) {
		/* Get slave address. */
		error = OF_getprop(child, "i2c-address", &paddr, sizeof(paddr));
		if (error == -1)
			error = OF_getprop(child, "reg", &paddr, sizeof(paddr));
		if (error == -1)
			continue;

		/* Get device driver name. */
		len = OF_getproplen(child, "model");
		if (len <= 0 || len > sizeof(dname) - 1)
			continue;
		OF_getprop(child, "model", &dname, len);
		dname[len + 1] = '\0';

		if (bootverbose)
			device_printf(dev, "adding a device %s at %d.\n",
			    dname, fdt32_to_cpu(paddr));
		childdev = BUS_ADD_CHILD(sc->iicbus, 0, dname, -1);
		devi = IICBUS_IVAR(childdev);
		devi->addr = fdt32_to_cpu(paddr);
	}

attach_end:
	bus_generic_attach(sc->iicbus);

	return (0);
}
Exemplo n.º 2
0
static int
mv_twsi_attach(device_t dev)
{
	struct twsi_softc *sc;
	phandle_t child, iicbusnode;
	device_t childdev;
	struct iicbus_ivar *devi;
	char dname[32];	/* 32 is taken from struct u_device */
	uint32_t paddr;
	int len, error, ret;

	sc = device_get_softc(dev);

	mv_twsi_cal_baud_rate(TWSI_BAUD_RATE_SLOW, &sc->baud_rate[IIC_SLOW]);
	mv_twsi_cal_baud_rate(TWSI_BAUD_RATE_FAST, &sc->baud_rate[IIC_FAST]);
	if (bootverbose)
		device_printf(dev, "calculated baud rates are:\n"
		    " %" PRIu32 " kHz (M=%d, N=%d) for slow,\n"
		    " %" PRIu32 " kHz (M=%d, N=%d) for fast.\n",
		    sc->baud_rate[IIC_SLOW].raw / 1000,
		    sc->baud_rate[IIC_SLOW].m,
		    sc->baud_rate[IIC_SLOW].n,
		    sc->baud_rate[IIC_FAST].raw / 1000,
		    sc->baud_rate[IIC_FAST].m,
		    sc->baud_rate[IIC_FAST].n);


	ret = twsi_attach(dev);
	if (ret != 0)
		return (ret);

	iicbusnode = 0;
	/* Find iicbus as the child devices in the device tree. */
	for (child = OF_child(ofw_bus_get_node(dev)); child != 0;
	    child = OF_peer(child)) {
		len = OF_getproplen(child, "model");
		if (len <= 0 || len > sizeof(dname))
			continue;
		error = OF_getprop(child, "model", &dname, len);
		if (error == -1)
			continue;
		len = strlen(dname);
		if (len == strlen(IICBUS_DEVNAME) &&
		    strncasecmp(dname, IICBUS_DEVNAME, len) == 0) {
			iicbusnode = child;
			break; 
		}
	}
	if (iicbusnode == 0)
		goto attach_end;

	/* Attach child devices onto iicbus. */
	for (child = OF_child(iicbusnode); child != 0; child = OF_peer(child)) {
		/* Get slave address. */
		error = OF_getencprop(child, "i2c-address", &paddr, sizeof(paddr));
		if (error == -1)
			error = OF_getencprop(child, "reg", &paddr, sizeof(paddr));
		if (error == -1)
			continue;

		/* Get device driver name. */
		len = OF_getproplen(child, "model");
		if (len <= 0 || len > sizeof(dname))
			continue;
		OF_getprop(child, "model", &dname, len);

		if (bootverbose)
			device_printf(dev, "adding a device %s at %d.\n",
			    dname, paddr);
		childdev = BUS_ADD_CHILD(sc->iicbus, 0, dname, -1);
		devi = IICBUS_IVAR(childdev);
		devi->addr = paddr;
	}

attach_end:
	bus_generic_attach(sc->iicbus);

	return (0);
}