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); }
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); }
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); }
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); }
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); }
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); }
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); }
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"); } }
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); }
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); }
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); }