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