Beispiel #1
0
static void
iicbus_probe_nomatch(device_t bus, device_t child)
{
	struct iicbus_ivar *devi = IICBUS_IVAR(child);

	device_printf(bus, "<unknown card> at addr %#x\n", devi->addr);
}
Beispiel #2
0
static struct resource_list *
iicbus_get_resource_list(device_t bus __unused, device_t child)
{
	struct iicbus_ivar *devi;

	devi = IICBUS_IVAR(child);
	return (&devi->rl);
}
Beispiel #3
0
static int
iicbus_child_location_str(device_t bus, device_t child, char *buf,
    size_t buflen)
{
	struct iicbus_ivar *devi = IICBUS_IVAR(child);

	snprintf(buf, buflen, "addr=%#x", devi->addr);
	return (0);
}
Beispiel #4
0
static void
iicbus_hinted_child(device_t bus, const char *dname, int dunit)
{
	device_t child;
	struct iicbus_ivar *devi;

	child = BUS_ADD_CHILD(bus, 0, dname, dunit);
	devi = IICBUS_IVAR(child);
	resource_int_value(dname, dunit, "addr", &devi->addr);
}
Beispiel #5
0
static int
iicbus_print_child(device_t dev, device_t child)
{
	struct iicbus_ivar *devi = IICBUS_IVAR(child);
	int retval = 0;

	retval += bus_print_child_header(dev, child);
	if (devi->addr != 0)
		retval += printf(" at addr %#x", devi->addr);
	retval += bus_print_child_footer(dev, child);

	return (retval);
}
Beispiel #6
0
static int
iicbus_print_child(device_t dev, device_t child)
{
	struct iicbus_ivar *devi = IICBUS_IVAR(child);
	int retval = 0;

	retval += bus_print_child_header(dev, child);
	if (devi->addr != 0)
		retval += printf(" at addr %#x", devi->addr);
	resource_list_print_type(&devi->rl, "irq", SYS_RES_IRQ, "%jd");
	retval += bus_print_child_footer(dev, child);

	return (retval);
}
Beispiel #7
0
static int
iicbus_read_ivar(device_t bus, device_t child, int which, uintptr_t *result)
{
	struct iicbus_ivar *devi = IICBUS_IVAR(child);

	switch (which) {
	default:
		return (EINVAL);
	case IICBUS_IVAR_ADDR:
		*result = devi->addr;
		break;
	}
	return (0);
}
Beispiel #8
0
static void
iicbus_hinted_child(device_t bus, const char *dname, int dunit)
{
	device_t child;
	int irq;
	struct iicbus_ivar *devi;

	child = BUS_ADD_CHILD(bus, 0, dname, dunit);
	devi = IICBUS_IVAR(child);
	resource_int_value(dname, dunit, "addr", &devi->addr);
	if (resource_int_value(dname, dunit, "irq", &irq) == 0) {
		if (bus_set_resource(child, SYS_RES_IRQ, 0, irq, 1) != 0)
			device_printf(bus,
			    "warning: bus_set_resource() failed\n");
	}
}
Beispiel #9
0
static int
iicbus_write_ivar(device_t bus, device_t child, int which, uintptr_t value)
{
	struct iicbus_ivar *devi = IICBUS_IVAR(child);

	switch (which) {
	default:
		return (EINVAL);
	case IICBUS_IVAR_ADDR:
		if (devi->addr != 0)
			return (EINVAL);
		devi->addr = value;
	case IICBUS_IVAR_NOSTOP:
		devi->nostop = value;
		break;
	}
	return (0);
}
Beispiel #10
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);
}
Beispiel #11
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);
}