static int adb_tapping_sysctl(SYSCTL_HANDLER_ARGS) { struct adb_mouse_softc *sc = arg1; device_t dev; int error; u_char r2[8]; u_int tapping; dev = sc->sc_dev; tapping = sc->sc_tapping; error = sysctl_handle_int(oidp, &tapping, 0, req); if (error || !req->newptr) return (error); if (tapping == 1) { adb_read_register(dev, 2, r2); r2[0] = 0x99; /* enable tapping. */ adb_write_register(dev, 2, 8, r2); sc->sc_tapping = 1; } else if (tapping == 0) { adb_read_register(dev, 2, r2); r2[0] = 0x19; /* disable tapping. */ adb_write_register(dev, 2, 8, r2); sc->sc_tapping = 0; } else return (EINVAL); return (0); }
static int adb_fn_keys(SYSCTL_HANDLER_ARGS) { struct adb_kbd_softc *sc = arg1; int error; uint16_t is_fn_enabled; unsigned int is_fn_enabled_sysctl; adb_read_register(sc->sc_dev, 1, &is_fn_enabled); is_fn_enabled &= 1; is_fn_enabled_sysctl = is_fn_enabled; error = sysctl_handle_int(oidp, &is_fn_enabled_sysctl, 0, req); if (error || !req->newptr) return (error); is_fn_enabled = is_fn_enabled_sysctl; if (is_fn_enabled != 1 && is_fn_enabled != 0) return (EINVAL); adb_write_register(sc->sc_dev, 1, 2, &is_fn_enabled); return (0); }
static void adb_init_trackpad(device_t dev) { struct adb_mouse_softc *sc; struct sysctl_ctx_list *ctx; struct sysctl_oid *tree; size_t r1_len; u_char r1[8]; u_char r2[8]; sc = device_get_softc(dev); r1_len = adb_read_register(dev, 1, r1); /* An Extended Mouse register1 must return 8 bytes. */ if (r1_len != 8) return; if((r1[6] != 0x0d)) { r1[6] = 0x0d; adb_write_register(dev, 1, 8, r1); r1_len = adb_read_register(dev, 1, r1); if (r1[6] != 0x0d) { device_printf(dev, "ADB Mouse = 0x%x " "(non-Extended Mode)\n", r1[6]); return; } else { device_printf(dev, "ADB Mouse = 0x%x " "(Extended Mode)\n", r1[6]); /* Set ADB Extended Features to default values, enabled. */ r2[0] = 0x19; /* Clicking: 0x19 disabled 0x99 enabled */ r2[1] = 0x94; /* Dragging: 0x14 disabled 0x94 enabled */ r2[2] = 0x19; r2[3] = 0xff; /* DragLock: 0xff disabled 0xb2 enabled */ r2[4] = 0xb2; r2[5] = 0x8a; r2[6] = 0x1b; r2[7] = 0x57; /* 0x57 bits 3:0 for W mode */ adb_write_register(dev, 2, 8, r2); } } /* * Set up sysctl */ ctx = device_get_sysctl_ctx(dev); tree = device_get_sysctl_tree(dev); SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "tapping", CTLTYPE_INT | CTLFLAG_RW, sc, 0, adb_tapping_sysctl, "I", "Tapping the pad causes button events"); return; }
static int adb_mouse_attach(device_t dev) { struct adb_mouse_softc *sc; char *description = "Unknown Pointing Device"; size_t r1_len; u_char r1[8]; sc = device_get_softc(dev); sc->sc_dev = dev; mtx_init(&sc->sc_mtx, "ams", NULL, MTX_DEF); cv_init(&sc->sc_cv,"ams"); sc->flags = 0; sc->hw.buttons = 2; sc->hw.iftype = MOUSE_IF_UNKNOWN; sc->hw.type = MOUSE_UNKNOWN; sc->hw.model = sc->hw.hwid = 0; sc->mode.protocol = MOUSE_PROTO_SYSMOUSE; sc->mode.rate = -1; sc->mode.resolution = 100; sc->mode.accelfactor = 0; sc->mode.level = 0; sc->mode.packetsize = 5; sc->buttons = 0; sc->sc_tapping = 0; sc->button_buf = 0; sc->last_buttons = 0; sc->packet_read_len = 0; /* Try to switch to extended protocol */ adb_set_device_handler(dev,4); switch(adb_get_device_handler(dev)) { case 1: sc->mode.resolution = 100; break; case 2: sc->mode.resolution = 200; break; case 4: r1_len = adb_read_register(dev,1,r1); if (r1_len < 8) break; sc->flags |= AMS_EXTENDED; memcpy(&sc->hw.hwid,r1,4); sc->mode.resolution = (r1[4] << 8) | r1[5]; switch (r1[6]) { case 0: sc->hw.type = MOUSE_PAD; description = "Tablet"; break; case 1: sc->hw.type = MOUSE_MOUSE; description = "Mouse"; break; case 2: sc->hw.type = MOUSE_TRACKBALL; description = "Trackball"; break; case 3: sc->flags |= AMS_TOUCHPAD; sc->hw.type = MOUSE_PAD; adb_init_trackpad(dev); description = "Touchpad"; break; } sc->hw.buttons = r1[7]; device_printf(dev,"%d-button %d-dpi %s\n", sc->hw.buttons, sc->mode.resolution,description); /* * Check for one of MacAlly's non-compliant 2-button mice. * These claim to speak the extended mouse protocol, but * instead speak the standard protocol and only when their * handler is set to 0x42. */ if (sc->hw.hwid == 0x4b4f4954) { adb_set_device_handler(dev,0x42); if (adb_get_device_handler(dev) == 0x42) { device_printf(dev, "MacAlly 2-Button Mouse\n"); sc->flags &= ~AMS_EXTENDED; } } break; } sc->cdev = make_dev(&ams_cdevsw, device_get_unit(dev), UID_ROOT, GID_OPERATOR, 0644, "ams%d", device_get_unit(dev)); sc->cdev->si_drv1 = sc; adb_set_autopoll(dev,1); return (0); }
static int adb_kbd_attach(device_t dev) { struct adb_kbd_softc *sc; keyboard_switch_t *sw; uint32_t fkeys; phandle_t handle; sw = kbd_get_switch(KBD_DRIVER_NAME); if (sw == NULL) { return ENXIO; } sc = device_get_softc(dev); sc->sc_dev = dev; sc->sc_mode = K_RAW; sc->sc_state = 0; sc->have_led_control = 0; sc->buffers = 0; /* Try stepping forward to the extended keyboard protocol */ adb_set_device_handler(dev,3); mtx_init(&sc->sc_mutex, KBD_DRIVER_NAME, NULL, MTX_DEF); cv_init(&sc->sc_cv,KBD_DRIVER_NAME); callout_init(&sc->sc_repeater, 0); #ifdef AKBD_EMULATE_ATKBD kbd_init_struct(&sc->sc_kbd, KBD_DRIVER_NAME, KB_101, 0, 0, 0, 0); kbd_set_maps(&sc->sc_kbd, &key_map, &accent_map, fkey_tab, sizeof(fkey_tab) / sizeof(fkey_tab[0])); #else #error ADB raw mode not implemented #endif KBD_FOUND_DEVICE(&sc->sc_kbd); KBD_PROBE_DONE(&sc->sc_kbd); KBD_INIT_DONE(&sc->sc_kbd); KBD_CONFIG_DONE(&sc->sc_kbd); (*sw->enable)(&sc->sc_kbd); kbd_register(&sc->sc_kbd); #ifdef KBD_INSTALL_CDEV if (kbd_attach(&sc->sc_kbd)) { adb_kbd_detach(dev); return ENXIO; } #endif /* Check if we can read out the LED state from this keyboard by reading the key state register */ if (adb_read_register(dev, 2, NULL) == 2) sc->have_led_control = 1; adb_set_autopoll(dev,1); handle = OF_finddevice("mac-io/via-pmu/adb/keyboard"); if (handle != -1 && OF_getprop(handle, "AAPL,has-embedded-fn-keys", &fkeys, sizeof(fkeys)) != -1) { static const char *key_names[] = {"F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12"}; struct sysctl_ctx_list *ctx; struct sysctl_oid *tree; int i; if (bootverbose) device_printf(dev, "Keyboard has embedded Fn keys\n"); for (i = 0; i < 12; i++) { uint32_t keyval; char buf[3]; if (OF_getprop(handle, key_names[i], &keyval, sizeof(keyval)) < 0) continue; buf[0] = 1; buf[1] = i+1; buf[2] = keyval; adb_write_register(dev, 0, 3, buf); } adb_write_register(dev, 1, 2, &(uint16_t){0}); ctx = device_get_sysctl_ctx(dev); tree = device_get_sysctl_tree(dev); SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "fn_keys_function_as_primary", CTLTYPE_INT | CTLFLAG_RW, sc, 0, adb_fn_keys, "I", "Set the Fn keys to be their F-key type as default"); } return (0); }