VOID CyapaBootWorkItem( IN WDFWORKITEM WorkItem ) { WDFDEVICE Device = (WDFDEVICE)WdfWorkItemGetParentObject(WorkItem); PDEVICE_CONTEXT pDevice = GetDeviceContext(Device); cyapa_boot_regs boot; csgesture_softc *sc = &pDevice->sc; if (!sc->infoSetup) { struct cyapa_cap cap; SpbReadDataSynchronously(&pDevice->I2CContext, CMD_QUERY_CAPABILITIES, &cap, sizeof(cap)); if (strncmp((const char *)cap.prod_ida, "CYTRA", 5) != 0) { CyapaPrint(DEBUG_LEVEL_ERROR, DBG_PNP, "[cyapainit] Product ID \"%5.5s\" mismatch\n", cap.prod_ida); SpbReadDataSynchronously(&pDevice->I2CContext, CMD_QUERY_CAPABILITIES, &cap, sizeof(cap)); } sc->resx = ((cap.max_abs_xy_high << 4) & 0x0F00) | cap.max_abs_x_low; sc->resy = ((cap.max_abs_xy_high << 8) & 0x0F00) | cap.max_abs_y_low; sc->phyx = ((cap.phy_siz_xy_high << 4) & 0x0F00) | cap.phy_siz_x_low; sc->phyy = ((cap.phy_siz_xy_high << 8) & 0x0F00) | cap.phy_siz_y_low; CyapaPrint(DEBUG_LEVEL_INFO, DBG_PNP, "[cyapainit] %5.5s-%6.6s-%2.2s buttons=%c%c%c res=%dx%d\n", cap.prod_ida, cap.prod_idb, cap.prod_idc, ((cap.buttons & CYAPA_FNGR_LEFT) ? 'L' : '-'), ((cap.buttons & CYAPA_FNGR_MIDDLE) ? 'M' : '-'), ((cap.buttons & CYAPA_FNGR_RIGHT) ? 'R' : '-'), sc->resx, sc->resy); for (int i = 0; i < 5; i++) { sc->product_id[i] = cap.prod_ida[i]; } sc->product_id[5] = '-'; for (int i = 0; i < 6; i++) { sc->product_id[i + 6] = cap.prod_idb[i]; } sc->product_id[12] = '-'; for (int i = 0; i < 2; i++) { sc->product_id[i + 13] = cap.prod_idc[i]; } sc->product_id[15] = '\0'; sprintf(sc->firmware_version, "%d.%d", cap.fw_maj_ver, cap.fw_min_ver); sc->infoSetup = true; } cyapa_set_power_mode(pDevice, CMD_POWER_MODE_FULL); SpbReadDataSynchronously(&pDevice->I2CContext, CMD_BOOT_STATUS, &boot, sizeof(boot)); WdfObjectDelete(WorkItem); }
static int cyapa_attach(device_t dev) { struct cyapa_softc *sc; struct cyapa_cap cap; int unit; int addr; sc = device_get_softc(dev); sc->reporting_mode = 1; unit = device_get_unit(dev); addr = smbus_get_addr(dev); if (init_device(dev, &cap, addr, 0)) return (ENXIO); mtx_init(&sc->mutex, "cyapa", NULL, MTX_DEF); sc->dev = dev; sc->addr = addr; knlist_init_mtx(&sc->selinfo.si_note, &sc->mutex); sc->cap_resx = ((cap.max_abs_xy_high << 4) & 0x0F00) | cap.max_abs_x_low; sc->cap_resy = ((cap.max_abs_xy_high << 8) & 0x0F00) | cap.max_abs_y_low; sc->cap_phyx = ((cap.phy_siz_xy_high << 4) & 0x0F00) | cap.phy_siz_x_low; sc->cap_phyy = ((cap.phy_siz_xy_high << 8) & 0x0F00) | cap.phy_siz_y_low; sc->cap_buttons = cap.buttons; device_printf(dev, "%5.5s-%6.6s-%2.2s buttons=%c%c%c res=%dx%d\n", cap.prod_ida, cap.prod_idb, cap.prod_idc, ((cap.buttons & CYAPA_FNGR_LEFT) ? 'L' : '-'), ((cap.buttons & CYAPA_FNGR_MIDDLE) ? 'M' : '-'), ((cap.buttons & CYAPA_FNGR_RIGHT) ? 'R' : '-'), sc->cap_resx, sc->cap_resy); sc->hw.buttons = 5; sc->hw.iftype = MOUSE_IF_PS2; sc->hw.type = MOUSE_MOUSE; sc->hw.model = MOUSE_MODEL_INTELLI; sc->hw.hwid = addr; sc->mode.protocol = MOUSE_PROTO_PS2; sc->mode.rate = 100; sc->mode.resolution = 4; sc->mode.accelfactor = 1; sc->mode.level = 0; sc->mode.packetsize = MOUSE_PS2_PACKETSIZE; sc->drag_state = D_IDLE; sc->draglock_ticks = -1; sc->dragwait_ticks = -1; sc->tft_state = T_IDLE; sc->tft_ticks = -1; sc->send_but = 0; /* Setup input event tracking */ cyapa_set_power_mode(sc, CMD_POWER_MODE_IDLE); /* Start the polling thread */ kthread_add(cyapa_poll_thread, sc, NULL, NULL, 0, 0, "cyapa-poll"); sc->devnode = make_dev(&cyapa_cdevsw, unit, UID_ROOT, GID_WHEEL, 0600, "cyapa%d", unit); sc->devnode->si_drv1 = sc; return (0); }