static u8 spic_read(u8 fn) { u8 v1, v2; int n = 100; while (n--) { v1 = spic_call2(0x8f, fn); v2 = spic_call2(0x8f, fn); if (v1 == v2 && v1 != 0xff) { return v1; } } return 0xff; }
void spic_shutdown(int power_off) { spic_call2(0x81, 0); /* make sure we don't get any more events */ if (power_off) { spic_camera_off(); printf("camera off\n"); } spic_dis();
int spic_jogger_turned(void) { u8 v1, v2; v1 = inb(SPIC_PORT1); v2 = inb(SPIC_PORT2); if ((v2 & 0x10) == 0) return 0; spic_call2(0x81, 0xff); return (signed char)v1; }
bool spic_resume(device_t dev, const pmf_qual_t *qual) { struct spic_softc *sc = device_private(dev); spic_call1(sc, 0x82); spic_call2(sc, 0x81, 0xff); spic_call1(sc, 0x92); /* or 0x82 */ callout_reset(&sc->sc_poll, POLLRATE, spictimeout, sc); return true; }
void spic_init(void) { iopl(3); spic_fd = pci_find_device(SPIC_PCI_VENDOR, SPIC_PCI_DEVICE); if (spic_fd == -1) { printf("can't find spic PCI device\n"); exit(1); } spic_srs(spic_fd, SPIC_PORT1, SPIC_PORT2, 0x3); spic_call1(0x82); spic_call2(0x81, 0xff); spic_call1(0x92); printf("spic enabled\n");
/* turn the camera on */ void spic_camera_on(void) { int i; while (spic_call2(0x91, 0x1) != 0) usleep(1); spic_call1(0x93); if (!spic_camera_ready()) { printf("waiting for camera ready\n"); for (i=400;i>0;i--) { if (spic_camera_ready()) break; usleep(100); } if (i == 0) { printf("failed to power on camera\n"); return; } } spic_set(0x10, 0x5a); }
void spic_attach(struct spic_softc *sc) { struct wsmousedev_attach_args a; int i, rv; #ifdef SPIC_DEBUG if (spicdebug) printf("spic_attach %x\n", (uint)sc->sc_ioh); #endif callout_init(&sc->sc_poll, 0); spic_call1(sc, 0x82); spic_call2(sc, 0x81, 0xff); spic_call1(sc, 0x92); /* or 0x82 */ a.accessops = &spic_accessops; a.accesscookie = sc; sc->sc_wsmousedev = config_found(sc->sc_dev, &a, wsmousedevprint); sc->sc_smpsw[SPIC_PSWITCH_LID].smpsw_name = "spiclid0"; sc->sc_smpsw[SPIC_PSWITCH_LID].smpsw_type = PSWITCH_TYPE_LID; sc->sc_smpsw[SPIC_PSWITCH_SUSPEND].smpsw_name = "spicsuspend0"; sc->sc_smpsw[SPIC_PSWITCH_SUSPEND].smpsw_type = PSWITCH_TYPE_SLEEP; sc->sc_smpsw[SPIC_PSWITCH_HIBERNATE].smpsw_name = "spichibernate0"; sc->sc_smpsw[SPIC_PSWITCH_HIBERNATE].smpsw_type = PSWITCH_TYPE_SLEEP; for (i = 0; i < SPIC_NPSWITCH; i++) { rv = sysmon_pswitch_register(&sc->sc_smpsw[i]); if (rv != 0) aprint_error_dev(sc->sc_dev, "unable to register %s with sysmon\n", sc->sc_smpsw[i].smpsw_name); } callout_reset(&sc->sc_poll, POLLRATE, spictimeout, sc); return; }
/* Interrupt handler: some event is available */ int spic_intr(void *v) { struct spic_softc *sc = v; u_int8_t v1, v2; int dz, buttons; v1 = INB(sc, SPIC_PORT1); v2 = INB(sc, SPIC_PORT2); /* Handle lid switch */ if (v2 == 0x30) { switch (v1) { case 0x50: /* opened */ sysmon_pswitch_event(&sc->sc_smpsw[SPIC_PSWITCH_LID], PSWITCH_EVENT_RELEASED); goto skip; break; case 0x51: /* closed */ sysmon_pswitch_event(&sc->sc_smpsw[SPIC_PSWITCH_LID], PSWITCH_EVENT_PRESSED); goto skip; break; default: aprint_debug_dev(sc->sc_dev, "unknown lid event 0x%02x\n", v1); goto skip; break; } } /* Handle suspend/hibernate buttons */ if (v2 == 0x20) { switch (v1) { case 0x10: /* suspend */ sysmon_pswitch_event( &sc->sc_smpsw[SPIC_PSWITCH_SUSPEND], PSWITCH_EVENT_PRESSED); goto skip; break; case 0x1c: /* hibernate */ sysmon_pswitch_event( &sc->sc_smpsw[SPIC_PSWITCH_HIBERNATE], PSWITCH_EVENT_PRESSED); goto skip; break; } } buttons = 0; if (v1 & 0x40) buttons |= 1 << 1; if (v1 & 0x20) buttons |= 1 << 5; dz = v1 & 0x1f; switch (dz) { case 0: case 1: case 2: case 3: break; case 0x1f: case 0x1e: case 0x1d: dz -= 0x20; break; case SPIC_EVENT_BRIGHTNESS_UP: pmf_event_inject(sc->sc_dev, PMFE_DISPLAY_BRIGHTNESS_UP); break; case SPIC_EVENT_BRIGHTNESS_DOWN: pmf_event_inject(sc->sc_dev, PMFE_DISPLAY_BRIGHTNESS_DOWN); break; default: printf("spic0: v1=0x%02x v2=0x%02x\n", v1, v2); goto skip; } if (!sc->sc_enabled) { /*printf("spic: not enabled\n");*/ goto skip; } if (dz != 0 || buttons != sc->sc_buttons) { #ifdef SPIC_DEBUG if (spicdebug) printf("spic: but=0x%x dz=%d v1=0x%02x v2=0x%02x\n", buttons, dz, v1, v2); #endif sc->sc_buttons = buttons; if (sc->sc_wsmousedev != NULL) { wsmouse_input(sc->sc_wsmousedev, buttons, 0, 0, dz, 0, WSMOUSE_INPUT_DELTA); } } skip: spic_call2(sc, 0x81, 0xff); /* Clear event */ return (1); }
/* turn the camera off */ void spic_camera_off(void) { spic_call2(0x91, 0); }
static int spic_camera_ready(void) { u8 v = spic_call2(0x8f, SPIC_CAMERA_STATUS); return (v != 0xff && (v & SPIC_CAMERA_STATUS_READY)); }