static int zkbd_hinge(void *v) { struct zkbd_softc *sc = (struct zkbd_softc *)v; int a, b; if (sc->sc_swa_pin < 0 || sc->sc_swb_pin < 0) return 1; a = pxa2x0_gpio_get_bit(sc->sc_swa_pin) ? 1 : 0; b = pxa2x0_gpio_get_bit(sc->sc_swb_pin) ? 2 : 0; sc->sc_hinge = a | b; if (sc->sc_hinge == 3) { #if NAPM > 0 if (lid_suspend) apm_suspends++; #endif #if NLCDCTL > 0 lcdctl_blank(true); #endif } else { #if NLCDCTL > 0 lcdctl_blank(false); #endif } return 1; }
/* * Called after wake-up from suspend with interrupts still disabled, * before any powerhooks are done. */ int zapm_resume(struct pxa2x0_apm_softc *pxa_sc) { struct zapm_softc *sc = (struct zapm_softc *)pxa_sc; int a, b; u_int wsrc; int wakeup = 0; /* C3000 */ a = pxa2x0_gpio_get_bit(97) ? 1 : 0; b = pxa2x0_gpio_get_bit(96) ? 2 : 0; wsrc = pxa2x0_wakeup_status(); /* Resume only if the lid is not closed. */ if ((a | b) != 3 && (wsrc & PXA2X0_WAKEUP_POWERON) != 0) { int timeout = 100; /* 10 ms */ /* C3000 */ while (timeout-- > 0 && pxa2x0_gpio_get_bit(95) != 0) { if (timeout == 0) { wakeup = 1; break; } delay(100); } } /* Initialize the SSP unit before using the MAX1111 again. */ zssp_init(); zapm_poll(sc); if (wakeup) { /* Resume normal polling. */ sc->sc_suspended = 0; pxa2x0_rtc_setalarm(0); } else { #if 0 DPRINTF(("zapm_resume: suspended %lu %lu\n", sc->sc_lastbattchk.tv_sec, pxa2x0_rtc_getsecs())); pxa2x0_rtc_setalarm(pxa2x0_rtc_getsecs() + 5); #endif } return (wakeup); }
static int zapm_get_ac_state(struct zapm_softc *sc) { if (!pxa2x0_gpio_get_bit(sc->sc_ac_detect_pin)) return APM_AC_ON; return APM_AC_OFF; }
static int wzero3kbd_intr3(void *arg) { int pin = (int)arg; printf("wzero3kbd_intr3: GPIO pin #%d = %s\n", pin, pxa2x0_gpio_get_bit(pin) ? "on" : "off"); return 1; }
static int wzero3kbd_intr2(void *arg) { struct wzero3kbd_softc *sc = (struct wzero3kbd_softc *)arg; printf("wzero3kbd_intr2: GPIO_IN: GPIO pin #%d = %s\n", sc->sc_test_pin, pxa2x0_gpio_get_bit(sc->sc_test_pin) ? "on" : "off"); return 1; }
/* * Return non-zero if the card is currently inserted. */ static int wzero3mci_card_detect(void *arg) { struct wzero3mci_softc *sc = (struct wzero3mci_softc *)arg; if (sc->sc_detect_pin >= 0) { if (pxa2x0_gpio_get_bit(sc->sc_detect_pin)) return 0; } return 1; }
static int wzero3kbd_intr(void *arg) { struct wzero3kbd_softc *sc = (struct wzero3kbd_softc *)arg; #if defined(KEYTEST) || defined(KEYTEST2) || defined(KEYTEST3) || defined(KEYTEST4) || defined(KEYTEST5) printf("wzero3kbd_intr: GPIO pin #%d = %s\n", sc->sc_key_pin, pxa2x0_gpio_get_bit(sc->sc_key_pin) ? "on" : "off"); #endif #if defined(KEYTEST4) if (sc->sc_test_pin >= 0) { if (pxa2x0_gpio_get_bit(sc->sc_test_pin)) { printf("GPIO_OUT: GPIO pin #%d: L\n",sc->sc_test_pin); pxa2x0_gpio_clear_bit(sc->sc_test_pin); } else { printf("GPIO_OUT: GPIO pin #%d: H\n", sc->sc_test_pin); pxa2x0_gpio_set_bit(sc->sc_test_pin); } } #endif #if defined(KEYTEST5) printf("CPLD(%#x): value=%#x, mask=%#x\n", sc->sc_test_pin, CSR_READ4(sc->sc_test_pin), sc->sc_bit); if (CSR_READ4(sc->sc_test_pin) & sc->sc_bit) { printf("CPLD_OUT: CPLD: L\n"); CSR_WRITE4(sc->sc_test_pin, CSR_READ4(sc->sc_test_pin) & ~sc->sc_bit); } else { printf("CPLD_OUT: CPLD: H\n"); CSR_WRITE4(sc->sc_test_pin, CSR_READ4(sc->sc_test_pin) | sc->sc_bit); } #endif (void) wzero3kbd_poll1(sc); pxa2x0_gpio_clear_intr(sc->sc_key_pin); return 1; }
static int zkbd_on(void *v) { #if NAPM > 0 struct zkbd_softc *sc = (struct zkbd_softc *)v; int down; if (sc->sc_onkey_pin < 0) return 1; down = pxa2x0_gpio_get_bit(sc->sc_onkey_pin) ? 1 : 0; /* * Change run mode depending on how long the key is held down. * Ignore the key if it gets pressed while the lid is closed. * * Keys can bounce and we have to work around missed interrupts. * Only the second edge is detected upon exit from sleep mode. */ if (down) { if (sc->sc_hinge == 3) { zkbdondown = 0; } else { microuptime(&zkbdontv); zkbdondown = 1; } } else if (zkbdondown) { if (ratecheck(&zkbdontv, &zkbdhalttv)) { if (kbd_reset == 1) { kbd_reset = 0; psignal(initproc, SIGUSR1); } } else if (ratecheck(&zkbdontv, &zkbdsleeptv)) { apm_suspends++; } zkbdondown = 0; } #endif return 1; }
/* * Return non-zero if the charge complete signal indicates that the * battery is fully charged. Restart charging to clear this signal. */ int zapm_charge_complete(struct zapm_softc *sc) { if (sc->sc_charging && sc->sc_batt_full < MIN_BATT_FULL) { if (pxa2x0_gpio_get_bit(GPIO_CHRG_CO_C3000) != 0) { if (++sc->sc_batt_full < MIN_BATT_FULL) { DPRINTF(("battery almost full\n")); zapm_enable_charging(sc, 0); delay(15000); zapm_enable_charging(sc, 1); } } else if (sc->sc_batt_full > 0) { /* false alarm */ sc->sc_batt_full = 0; zapm_enable_charging(sc, 0); delay(15000); zapm_enable_charging(sc, 1); } } return (sc->sc_batt_full >= MIN_BATT_FULL); }
/* * Poll power-management related GPIO inputs, update battery life * in softc, and/or control battery charging. */ void zapm_poll(void *v) { struct zapm_softc *sc = v; int ac_on; int bc_lock; int charging; int volt; int s; s = splhigh(); /* Check positition of battery compartment lock switch. */ bc_lock = pxa2x0_gpio_get_bit(GPIO_BATT_COVER_C3000) ? 1 : 0; /* Stop discharging. */ if (sc->sc_discharging) { sc->sc_discharging = 0; volt = zapm_batt_volt(); ac_on = zapm_ac_on(); charging = 0; DPRINTF(("zapm_poll: discharge off volt %d\n", volt)); } else { ac_on = zapm_ac_on(); charging = sc->sc_charging; volt = sc->sc_batt_volt; } /* Start or stop charging as necessary. */ if (ac_on && bc_lock) { if (charging) { if (zapm_charge_complete(sc)) { DPRINTF(("zapm_poll: batt full\n")); charging = 0; zapm_enable_charging(sc, 0); } } else if (!zapm_charge_complete(sc)) { charging = 1; volt = zapm_batt_volt(); zapm_enable_charging(sc, 1); DPRINTF(("zapm_poll: start charging volt %d\n", volt)); } } else { if (charging) { charging = 0; zapm_enable_charging(sc, 0); timerclear(&sc->sc_lastbattchk); DPRINTF(("zapm_poll: stop charging\n")); } sc->sc_batt_full = 0; } /* * Restart charging once in a while. Discharge a few milliseconds * before updating the voltage in our softc if A/C is connected. */ if (bc_lock && ratecheck(&sc->sc_lastbattchk, &zapm_battchkrate)) { if (sc->sc_suspended) { DPRINTF(("zapm_poll: suspended %lu %lu\n", sc->sc_lastbattchk.tv_sec, pxa2x0_rtc_getsecs())); if (charging) { zapm_enable_charging(sc, 0); delay(15000); zapm_enable_charging(sc, 1); pxa2x0_rtc_setalarm(pxa2x0_rtc_getsecs() + zapm_battchkrate.tv_sec + 1); } } else if (ac_on && sc->sc_batt_full == 0) { DPRINTF(("zapm_poll: discharge on\n")); if (charging) zapm_enable_charging(sc, 0); sc->sc_discharging = 1; scoop_discharge_battery(1); timeout_add(&sc->sc_poll, DISCHARGE_TIMEOUT); } else if (!ac_on) { volt = zapm_batt_volt(); DPRINTF(("zapm_poll: volt %d\n", volt)); } } /* Update the cached power state in our softc. */ if (ac_on != sc->sc_ac_on || charging != sc->sc_charging || volt != sc->sc_batt_volt) { sc->sc_ac_on = ac_on; sc->sc_charging = charging; sc->sc_batt_volt = volt; if (sc->sc_event == APM_NOEVENT) sc->sc_event = APM_POWER_CHANGE; } /* Detect battery low conditions. */ if (!ac_on) { if (zapm_batt_life(volt) < 5) sc->sc_event = APM_BATTERY_LOW; if (zapm_batt_state(volt) == APM_BATT_CRITICAL) sc->sc_event = APM_CRIT_SUSPEND_REQ; } #ifdef APMDEBUG if (sc->sc_event != APM_NOEVENT) DPRINTF(("zapm_poll: power event %d\n", sc->sc_event)); #endif splx(s); }
int zapm_ac_on(void) { return (!pxa2x0_gpio_get_bit(GPIO_AC_IN_C3000)); }
static int wzero3kbd_power_intr(void *arg) { struct wzero3kbd_softc *sc = (struct wzero3kbd_softc *)arg; #if defined(KEYTEST) || defined(KEYTEST2) || defined(KEYTEST3) || defined(KEYTEST4) printf("wzero3kbd_power_intr: status = %s\n", pxa2x0_gpio_get_bit(sc->sc_power_pin) ? "on" : "off"); #endif #if defined(KEYTEST) if (pxa2x0_gpio_get_bit(sc->sc_power_pin)) { if (sc->sc_test_pin >= 0) { int orig_pin = sc->sc_test_pin; pxa2x0_gpio_intr_disestablish(sc->sc_test_ih); sc->sc_test_ih = NULL; for (;;) { if (++sc->sc_test_pin >= PXA270_GPIO_NPINS) sc->sc_test_pin = 2; if (sc->sc_test_pin == orig_pin) break; if (sc->sc_test_pin != sc->sc_nouse_pin && sc->sc_test_pin != sc->sc_nouse_pin2 && sc->sc_test_pin != sc->sc_nouse_pin3 && sc->sc_test_pin != sc->sc_key_pin && sc->sc_test_pin != sc->sc_power_pin && sc->sc_test_pin != sc->sc_reset_pin && GPIO_IS_GPIO_IN(pxa2x0_gpio_get_function(sc->sc_test_pin))) break; } if (sc->sc_test_pin != orig_pin) { printf("GPIO_IN: GPIO pin #%d\n", sc->sc_test_pin); sc->sc_test_ih = pxa2x0_gpio_intr_establish(sc->sc_test_pin, IST_EDGE_BOTH, IPL_TTY, wzero3kbd_intr2,sc); } else { sc->sc_test_pin = -1; } } } #endif #if defined(KEYTEST2) if (pxa2x0_gpio_get_bit(sc->sc_power_pin)) { sc->sc_enabled ^= 2; if (sc->sc_enabled & 2) { printf("print col/row\n"); } else { printf("keyscan\n"); } } #endif #if defined(KEYTEST4) if (pxa2x0_gpio_get_bit(sc->sc_power_pin)) { if (sc->sc_test_pin >= 0) { int orig_pin = sc->sc_test_pin; for (;;) { if (++sc->sc_test_pin >= PXA270_GPIO_NPINS) sc->sc_test_pin = 2; if (sc->sc_test_pin == orig_pin) break; if (sc->sc_test_pin != sc->sc_nouse_pin && sc->sc_test_pin != sc->sc_nouse_pin2 && sc->sc_test_pin != sc->sc_nouse_pin3 && sc->sc_test_pin != sc->sc_key_pin && sc->sc_test_pin != sc->sc_power_pin && sc->sc_test_pin != sc->sc_reset_pin && GPIO_IS_GPIO_OUT(pxa2x0_gpio_get_function(sc->sc_test_pin))) break; } if (sc->sc_test_pin != orig_pin) { printf("GPIO_OUT: GPIO pin #%d\n", sc->sc_test_pin); } else { sc->sc_test_pin = -1; } } } #endif #if defined(KEYTEST5) if (pxa2x0_gpio_get_bit(sc->sc_power_pin)) { sc->sc_bit <<= 1; if (sc->sc_bit & ~0xff) { sc->sc_bit = 0x01; sc->sc_test_pin += 0x4; if (sc->sc_test_pin >= 0x20) { sc->sc_test_pin = 0x00; } } printf("CPLD(%#x), mask=%#x\n", sc->sc_test_pin, sc->sc_bit); } #endif pxa2x0_gpio_clear_intr(sc->sc_power_pin); return 1; }
static void zkbd_poll(void *v) { struct zkbd_softc *sc = (struct zkbd_softc *)v; int i, j, col, pin, type, keysdown = 0; int stuck; int keystate; int s; #ifdef WSDISPLAY_COMPAT_RAWKBD int npress = 0, ncbuf = 0, c; char cbuf[MAXKEYS * 2]; #endif s = spltty(); /* discharge all */ for (i = 0; i < sc->sc_nstrobe; i++) { pin = sc->sc_strobe_array[i]; if (pin == -1) continue; pxa2x0_gpio_clear_bit(pin); pxa2x0_gpio_set_dir(pin, GPIO_IN); } delay(10); for (col = 0; col < sc->sc_nstrobe; col++) { pin = sc->sc_strobe_array[col]; if (pin == -1) continue; /* activate_col */ pxa2x0_gpio_set_bit(pin); pxa2x0_gpio_set_dir(pin, GPIO_OUT); /* wait activate delay */ delay(10); /* read row */ for (i = 0; i < sc->sc_nsense; i++) { int bit; if (sc->sc_sense_array[i] == -1) continue; bit = pxa2x0_gpio_get_bit(sc->sc_sense_array[i]); if (bit && sc->sc_hinge && col < sc->sc_maxkbdcol) continue; sc->sc_keystate[i + (col * sc->sc_nsense)] = bit; } /* reset_col */ pxa2x0_gpio_set_dir(pin, GPIO_IN); /* wait discharge delay */ delay(10); } /* charge all */ for (i = 0; i < sc->sc_nstrobe; i++) { pin = sc->sc_strobe_array[i]; if (pin == -1) continue; pxa2x0_gpio_set_bit(pin); pxa2x0_gpio_set_dir(pin, GPIO_OUT); } /* force the irqs to clear as we have just played with them. */ for (i = 0; i < sc->sc_nsense; i++) { pin = sc->sc_sense_array[i]; if (pin == -1) continue; pxa2x0_gpio_clear_intr(pin); } /* process after resetting interrupt */ zkbd_modstate = ( (sc->sc_keystate[84] ? (1 << 0) : 0) | /* shift */ (sc->sc_keystate[93] ? (1 << 1) : 0) | /* Fn */ (sc->sc_keystate[14] ? (1 << 2) : 0)); /* 'alt' */ for (i = 0; i < sc->sc_nsense * sc->sc_nstrobe; i++) { stuck = 0; /* extend xt_keymap to do this faster. */ /* ignore 'stuck' keys' */ for (j = 0; j < sc->sc_nstuck; j++) { if (sc->sc_stuck_keys[j] == i) { stuck = 1; break; } } if (stuck) continue; keystate = sc->sc_keystate[i]; keysdown |= keystate; /* if any keys held */ #ifdef WSDISPLAY_COMPAT_RAWKBD if (sc->sc_polling == 0 && sc->sc_rawkbd) { if ((keystate) || (sc->sc_okeystate[i] != keystate)) { c = sc->sc_xt_keymap[i]; if (c & 0x80) { cbuf[ncbuf++] = 0xe0; } cbuf[ncbuf] = c & 0x7f; if (keystate) { if (c & 0x80) { sc->sc_rep[npress++] = 0xe0; } sc->sc_rep[npress++] = c & 0x7f; } else { cbuf[ncbuf] |= 0x80; } ncbuf++; sc->sc_okeystate[i] = keystate; } } #endif if ((!sc->sc_rawkbd) && (sc->sc_okeystate[i] != keystate)) { type = keystate ? WSCONS_EVENT_KEY_DOWN : WSCONS_EVENT_KEY_UP; if (sc->sc_polling) { sc->sc_pollkey = i; sc->sc_pollUD = type; } else { wskbd_input(sc->sc_wskbddev, type, i); } sc->sc_okeystate[i] = keystate; } } #ifdef WSDISPLAY_COMPAT_RAWKBD if (sc->sc_polling == 0 && sc->sc_rawkbd) { wskbd_rawinput(sc->sc_wskbddev, cbuf, ncbuf); sc->sc_nrep = npress; if (npress != 0) callout_schedule(&sc->sc_rawrepeat_ch, hz * REP_DELAY1 / 1000); else callout_stop(&sc->sc_rawrepeat_ch); } #endif if (keysdown) callout_schedule(&sc->sc_roll_to, hz * REP_DELAYN / 1000 / 2); else callout_stop(&sc->sc_roll_to); /* always cancel? */ splx(s); }
int zaurus_udc_is_host(void) { return !(pxa2x0_gpio_get_bit(GPIO_USB_DETECT) || pxa2x0_gpio_get_bit(GPIO_USB_DEVICE)); }
static int zapm_get_charge_complete_state(struct zapm_softc *sc) { return pxa2x0_gpio_get_bit(sc->sc_charge_comp_pin); }
static int zapm_get_battery_compartment_state(struct zapm_softc *sc) { return pxa2x0_gpio_get_bit(sc->sc_batt_cover_pin); }