コード例 #1
0
/*
 * Initialize the dedicated SSP unit and disable all chip selects.
 * This function is called with interrupts disabled.
 */
static void
wzero3ssp_init(struct wzero3ssp_softc *sc)
{

	if (sc->sc_model->sspaddr == PXA2X0_SSP1_BASE)
		pxa2x0_clkman_config(CKEN_SSP2, 1);
	else if (sc->sc_model->sspaddr == PXA2X0_SSP2_BASE)
		pxa2x0_clkman_config(CKEN_SSP3, 1);

	bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR0, 0);
	bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR1, 0);

	/* XXX */
	if (platid_match(&platid, &platid_mask_MACH_SHARP_WZERO3_WS003SH)
	 || platid_match(&platid, &platid_mask_MACH_SHARP_WZERO3_WS004SH)) {
		pxa2x0_gpio_set_function(39/*GPIO_WS003SH_XXX*/,
		    GPIO_OUT|GPIO_SET);
		pxa2x0_gpio_set_function(GPIO_WS003SH_MAX1233_CS,
		    GPIO_OUT|GPIO_SET);
	}
	if (platid_match(&platid, &platid_mask_MACH_SHARP_WZERO3_WS007SH)) {
		pxa2x0_gpio_set_function(GPIO_WS007SH_ADS7846_CS,
		    GPIO_OUT|GPIO_SET);
	}
	if (platid_match(&platid, &platid_mask_MACH_SHARP_WZERO3_WS011SH)) {
		pxa2x0_gpio_set_function(GPIO_WS011SH_AK4184_CS,
		    GPIO_OUT|GPIO_SET);
	}
}
コード例 #2
0
/*
 * XXXXX: slot count functions from Linux
 */
static __inline void
gxpcic_cpld_clk(void)
{

	pxa2x0_gpio_set_function(48, GPIO_OUT | GPIO_CLR);
	pxa2x0_gpio_set_function(48, GPIO_OUT | GPIO_SET);
}
コード例 #3
0
void
pxapcic_attach(struct pxapcic_softc *sc,
    void (*socket_setup_hook)(struct pxapcic_socket *))
{
	struct pcmciabus_attach_args paa;
	struct pxapcic_socket *so;
	int i;

	printf(": %d slot%s\n", sc->sc_nslots, sc->sc_nslots==1 ? "" : "s");

	if (bus_space_map(sc->sc_iot, PXA2X0_MEMCTL_BASE, PXA2X0_MEMCTL_SIZE,
	    0, &sc->sc_memctl_ioh)) {
		printf("%s: failed to map MEMCTL\n", sc->sc_dev.dv_xname);
		return;
	}

	/* Clear CIT (card present) and set NOS correctly. */
	bus_space_write_4(sc->sc_iot, sc->sc_memctl_ioh, MEMCTL_MECR,
	    sc->sc_nslots == 2 ? MECR_NOS : 0);

	/* zaurus: configure slot 1 first to make internal drive be wd0. */
	for (i = sc->sc_nslots-1; i >= 0; i--) {
		so = &sc->sc_socket[i];
		so->sc = sc;
		so->socket = i;
		so->flags = 0;

		socket_setup_hook(so);

		paa.paa_busname = "pcmcia";
		paa.pct = (pcmcia_chipset_tag_t)&pxapcic_pcmcia_functions;
		paa.pch = (pcmcia_chipset_handle_t)so;
		paa.iobase = 0;
		paa.iosize = 0x4000000;
	
		so->pcmcia = config_found_sm(&sc->sc_dev, &paa,
		    pxapcic_print, pxapcic_submatch);

		pxa2x0_gpio_set_function(sc->sc_irqpin[i], GPIO_IN);
		pxa2x0_gpio_set_function(sc->sc_irqcfpin[i], GPIO_IN);
	
		/* Card slot interrupt */
		so->irq = pxa2x0_gpio_intr_establish(sc->sc_irqcfpin[i],
		    IST_EDGE_BOTH, IPL_BIO /* XXX */, pxapcic_intr, so,
		    sc->sc_dev.dv_xname);
	
		/* GPIO pin for interrupt */
		so->irqpin = sc->sc_irqpin[i];

#ifdef DO_CONFIG_PENDING
		config_pending_incr();
#endif
		kthread_create_deferred(pxapcic_create_event_thread, so);
	}
}
コード例 #4
0
ファイル: palm_mmc.c プロジェクト: alenichev/openbsd-kernel
void
palm_mmc_attach(struct device *parent, struct device *self, void *aux)
{
	struct pxammc_softc *sc = (struct pxammc_softc *)self;

	sc->tag.cookie = (void *)sc;
	sc->tag.get_ocr = palm_mmc_get_ocr;
	sc->tag.set_power = palm_mmc_set_power;

	/*
	 * Configure the GPIO pins.  In SD/MMC mode, all pins except
	 * MMCLK are bidirectional and the direction is controlled in
	 * hardware without our assistence.
	 */
	if (mach_is_palmtc) {
		pxa2x0_gpio_set_function(6, GPIO_ALT_FN_1_OUT);
		pxa2x0_gpio_set_function(8, GPIO_ALT_FN_1_OUT);
		sc->sc_gpio_detect = GPIO12_TC_MMC_DETECT;
	} else {
		pxa2x0_gpio_set_function(32, GPIO_ALT_FN_2_OUT);
		pxa2x0_gpio_set_function(112, GPIO_ALT_FN_1_IN);
		pxa2x0_gpio_set_function(92, GPIO_ALT_FN_1_IN);
		pxa2x0_gpio_set_function(109, GPIO_ALT_FN_1_IN);
		pxa2x0_gpio_set_function(110, GPIO_ALT_FN_1_IN);
		pxa2x0_gpio_set_function(111, GPIO_ALT_FN_1_IN);
		sc->sc_gpio_detect = GPIO14_MMC_DETECT;
	}

	pxammc_attach(sc, aux);
}
コード例 #5
0
ファイル: zts.c プロジェクト: alenichev/openbsd-kernel
int
zts_enable(void *v)
{
	struct zts_softc *sc = v;

	if (sc->sc_enabled)
		return EBUSY;

	timeout_del(&sc->sc_ts_poll);

	pxa2x0_gpio_set_function(GPIO_TP_INT_C3K, GPIO_IN);

	/* XXX */
	if (sc->sc_gh == NULL)
		sc->sc_gh = pxa2x0_gpio_intr_establish(GPIO_TP_INT_C3K,
		    IST_EDGE_FALLING, IPL_TTY, zts_irq, sc,
		    sc->sc_dev.dv_xname);
	else
		pxa2x0_gpio_intr_unmask(sc->sc_gh);

	/* enable interrupts */
	sc->sc_enabled = 1;
	sc->sc_running = 1;
	sc->sc_buttons = 0;

	return 0;
}
コード例 #6
0
ファイル: zts.c プロジェクト: alenichev/openbsd-kernel
int
zts_activate(struct device *self, int act)
{
	struct zts_softc *sc = (struct zts_softc *)self;

	switch (act) {
	case DVACT_SUSPEND:
		if (sc->sc_enabled == 0)
			break;
		sc->sc_running = 0;
#if 0
		pxa2x0_gpio_intr_disestablish(sc->sc_gh);
#endif
		timeout_del(&sc->sc_ts_poll);

		pxa2x0_gpio_intr_mask(sc->sc_gh);

		/* Turn off reference voltage but leave ADC on. */
		(void)zssp_ic_send(ZSSP_IC_ADS7846, (1 << ADSCTRL_PD1_SH) |
		    (1 << ADSCTRL_ADR_SH) | (1 << ADSCTRL_STS_SH));

		pxa2x0_gpio_set_function(GPIO_TP_INT_C3K,
		    GPIO_OUT | GPIO_SET);
		break;

	case DVACT_RESUME:
		if (sc->sc_enabled == 0)
			break;
		pxa2x0_gpio_set_function(GPIO_TP_INT_C3K, GPIO_IN);
		pxa2x0_gpio_intr_mask(sc->sc_gh);

		/* Enable automatic low power mode. */
		(void)zssp_ic_send(ZSSP_IC_ADS7846,
		    (4 << ADSCTRL_ADR_SH) | (1 << ADSCTRL_STS_SH));

#if 0
		sc->sc_gh = pxa2x0_gpio_intr_establish(GPIO_TP_INT_C3K,
		    IST_EDGE_FALLING, IPL_TTY, zts_irq, sc,
		    sc->sc_dev.dv_xname);
#else
		pxa2x0_gpio_intr_unmask(sc->sc_gh);
#endif
		sc->sc_running = 1;
		break;
	}
	return 0;
}
コード例 #7
0
ファイル: palm_kpc.c プロジェクト: alenichev/openbsd-kernel
void
palm_kpc_attach(struct device *parent, struct device *self, void *aux)
{
	struct pxa27x_kpc_softc *sc = (struct pxa27x_kpc_softc *)self;

	pxa2x0_gpio_set_function(100, GPIO_ALT_FN_1_IN);
	pxa2x0_gpio_set_function(101, GPIO_ALT_FN_1_IN);
	pxa2x0_gpio_set_function(102, GPIO_ALT_FN_1_IN);
	pxa2x0_gpio_set_function(97, GPIO_ALT_FN_3_IN);

	pxa2x0_gpio_set_function(103, GPIO_ALT_FN_2_OUT);
	pxa2x0_gpio_set_function(104, GPIO_ALT_FN_2_OUT);
	pxa2x0_gpio_set_function(105, GPIO_ALT_FN_2_OUT);

	sc->sc_rows	= 4;
	sc->sc_cols	= 3;
	sc->sc_kmap	= palmkpc_keymap;
	sc->sc_kcodes	= palmkpc_keycodes;
#ifdef WSDISPLAY_COMPAT_RAWKBD
	sc->sc_xt_kcodes	= palmkpc_xt_keycodes;
#endif
	sc->sc_ksize	= sizeof(palmkpc_keycodes)/sizeof(keysym_t);

	pxa27x_kpc_attach(sc, aux);
}
コード例 #8
0
void
apm_attach(struct device *parent, struct device *self, void *aux)
{
	struct zapm_softc *sc = (struct zapm_softc *)self;

	pxa2x0_gpio_set_function(GPIO_AC_IN_C3000, GPIO_IN);
	pxa2x0_gpio_set_function(GPIO_CHRG_CO_C3000, GPIO_IN);
	pxa2x0_gpio_set_function(GPIO_BATT_COVER_C3000, GPIO_IN);

	(void)pxa2x0_gpio_intr_establish(GPIO_AC_IN_C3000,
	    IST_EDGE_BOTH, IPL_BIO, zapm_acintr, sc, "apm_ac");
	(void)pxa2x0_gpio_intr_establish(GPIO_BATT_COVER_C3000,
	    IST_EDGE_BOTH, IPL_BIO, zapm_bcintr, sc, "apm_bc");

	sc->sc_event = APM_NOEVENT;
	sc->sc.sc_get_event = zapm_get_event;
	sc->sc.sc_power_info = zapm_power_info;
	sc->sc.sc_suspend = zapm_suspend;
	sc->sc.sc_resume = zapm_resume;

	timeout_set(&sc->sc_poll, &zapm_poll, sc);

	/* Get initial battery voltage. */
	zapm_enable_charging(sc, 0);
	if (zapm_ac_on()) {
		/* C3000: discharge 100 ms when AC is on. */
		scoop_discharge_battery(1);
		delay(100000);
	}
	sc->sc_batt_volt = zapm_batt_volt();
	scoop_discharge_battery(0);

	pxa2x0_apm_attach_sub(&sc->sc);

#if 0
	(void)shutdownhook_establish(zapm_shutdown, NULL);
#endif

	cpu_setperf = pxa2x0_setperf;
	cpu_cpuspeed = pxa2x0_cpuspeed;
}
コード例 #9
0
static void
pxamci_attach(device_t parent, device_t self, void *aux)
{
	struct wzero3mci_softc *sc = device_private(self);
	struct pxaip_attach_args *pxa = aux;
	const struct wzero3mci_model *model;

	sc->sc.sc_dev = self;

	model = wzero3mci_lookup();
	if (model == NULL) {
		aprint_error(": Unknown model.");
		return;
	}

	sc->sc_detect_pin = model->detect_pin;
	sc->sc_power_pin = model->power_pin;

	/* Establish SD detect interrupt */
	if (sc->sc_detect_pin >= 0) {
		pxa2x0_gpio_set_function(sc->sc_detect_pin, GPIO_IN);
		sc->sc_detect_ih = pxa2x0_gpio_intr_establish(sc->sc_detect_pin,
		    IST_EDGE_BOTH, IPL_BIO, wzero3mci_intr, sc);
		if (sc->sc_detect_ih == NULL) {
			aprint_error_dev(self,
			    "unable to establish card detect interrupt\n");
			return;
		}
	}

	sc->sc.sc_tag.cookie = sc;
	sc->sc.sc_tag.get_ocr = wzero3mci_get_ocr;
	sc->sc.sc_tag.set_power = wzero3mci_set_power;
	sc->sc.sc_tag.card_detect = wzero3mci_card_detect;
	sc->sc.sc_tag.write_protect = wzero3mci_write_protect;
	sc->sc.sc_caps = PMC_CAPS_4BIT;

	if (pxamci_attach_sub(self, pxa)) {
		aprint_error_dev(self, "unable to attach MMC controller\n");
		goto free_intr;
	}

	if (!pmf_device_register(self, NULL, NULL)) {
		aprint_error_dev(self, "couldn't establish power handler\n");
	}

	return;

free_intr:
	pxa2x0_gpio_intr_disestablish(sc->sc_detect_ih);
	sc->sc_detect_ih = NULL;
}
コード例 #10
0
ファイル: pxa2x0_i2c.c プロジェクト: avsm/openbsd-xen-sys
int
pxa2x0_i2c_attach_sub(struct pxa2x0_i2c_softc *sc)
{
	if (bus_space_map(sc->sc_iot, PXA2X0_I2C_BASE,
	    PXA2X0_I2C_SIZE, 0, &sc->sc_ioh)) {
		sc->sc_size = 0;
		return EIO;
	}
	bus_space_barrier(sc->sc_iot, sc->sc_ioh, 0, sc->sc_size,
	    BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE);

	/*
	 * Configure the alternate functions.  The _IN is arbitrary, as the
	 * direction is managed by the I2C unit when comms are in progress.
	 */
	pxa2x0_gpio_set_function(117, GPIO_ALT_FN_1_IN);	/* SCL */
	pxa2x0_gpio_set_function(118, GPIO_ALT_FN_1_IN);	/* SDA */

	pxa2x0_i2c_init(sc);

	return 0;
}
コード例 #11
0
int
pxa2x0_i2s_attach_sub(struct pxa2x0_i2s_softc *sc)
{
	if (bus_space_map(sc->sc_iot, PXA2X0_I2S_BASE, PXA2X0_I2S_SIZE, 0,
	    &sc->sc_ioh)) {
		sc->sc_size = 0;
		return 1;
	}
	sc->sc_sadiv = SADIV_3_058MHz;

	bus_space_barrier(sc->sc_iot, sc->sc_ioh, 0, sc->sc_size,
	    BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE);

	pxa2x0_gpio_set_function(28, GPIO_ALT_FN_1_OUT);  /* I2S_BITCLK */
	pxa2x0_gpio_set_function(113, GPIO_ALT_FN_1_OUT); /* I2S_SYSCLK */
	pxa2x0_gpio_set_function(31, GPIO_ALT_FN_1_OUT);  /* I2S_SYNC */
	pxa2x0_gpio_set_function(30, GPIO_ALT_FN_1_OUT);  /* I2S_SDATA_OUT */
	pxa2x0_gpio_set_function(29, GPIO_ALT_FN_2_IN);   /* I2S_SDATA_IN */

	pxa2x0_i2s_init(sc);

	return 0;
}
コード例 #12
0
/*
 * We use the CPLD on the CF-CF card to read a value from a shift register.
 * If we can read that magic sequence, then we have 2 CF cards; otherwise
 * we assume just one.  The CPLD will send the value of the shift register
 * on GPIO11 (the CD line for slot 0) when RESET is held in reset.  We use
 * GPIO48 (nPWE) as a clock signal, GPIO52/53 (card enable for both cards)
 * to control read/write to the shift register.
 */
static int
gxpcic_count_slot(struct pxapcic_softc *sc)
{
	u_int poe, pce1, pce2;
	int nslot;

	poe = pxa2x0_gpio_get_function(48);
	pce1 = pxa2x0_gpio_get_function(52);
	pce2 = pxa2x0_gpio_get_function(53);

	/* RESET */
	pxa2x0_gpio_set_function(gxpcic_gpio_reset, GPIO_OUT | GPIO_CLR);

	/* Setup the shift register */
	pxa2x0_gpio_set_function(52, GPIO_OUT | GPIO_SET);
	pxa2x0_gpio_set_function(53, GPIO_OUT | GPIO_CLR);

	/* Tick the clock to program the shift register */
	gxpcic_cpld_clk();

	/* Now set shift register into read mode */
	pxa2x0_gpio_set_function(52, GPIO_OUT | GPIO_CLR);
	pxa2x0_gpio_set_function(53, GPIO_OUT | GPIO_SET);

	/* We can read the bits now -- 0xc2 means "Dual compact flash" */
	if (gxpcic_cpld_read_bits(8) != 0xc2)
		/* We do not have 2 CF slots */
		nslot = 1;
	else
		/* We have 2 CF slots */
		nslot = 2;

	delay(50);
	/* clear RESET */
	pxa2x0_gpio_set_function(gxpcic_gpio_reset, GPIO_OUT | GPIO_CLR);

	pxa2x0_gpio_set_function(48, poe);
	pxa2x0_gpio_set_function(52, pce1);
	pxa2x0_gpio_set_function(53, pce2);

	return nslot;
}
コード例 #13
0
/*
 * Do a GPIO reset, immediately causing the processor to begin the normal
 * boot sequence.  See 2.7 Reset in the PXA27x Developer's Manual for the
 * summary of effects of this kind of reset.
 */
void
zapm_restart(void)
{
	if (apm_cd.cd_ndevs > 0 && apm_cd.cd_devs[0] != NULL) {
		struct pxa2x0_apm_softc *sc = apm_cd.cd_devs[0];
		int rv;

		/*
		 * Reduce the ROM Delay Next Access and ROM Delay First
		 * Access times for synchronous flash connected to nCS1.
		 */
		rv = bus_space_read_4(sc->sc_iot, sc->sc_memctl_ioh,
		    MEMCTL_MSC0);
		if ((rv & 0xffff0000) == 0x7ff00000)
			bus_space_write_4(sc->sc_iot, sc->sc_memctl_ioh,
			    MEMCTL_MSC0, (rv & 0xffff) | 0x7ee00000);
	}

	/* External reset circuit presumably asserts nRESET_GPIO. */
	pxa2x0_gpio_set_function(89, GPIO_OUT | GPIO_SET);
	delay(1000000);
}
コード例 #14
0
ファイル: zaurus_udc.c プロジェクト: ajinkya93/OpenBSD
void
zaurus_udc_attach(struct device *parent, struct device *self, void *aux)
{
	struct pxaudc_softc *sc = (struct pxaudc_softc *)self;


	sc->sc_gpio_detect	= GPIO_USB_DETECT;
	sc->sc_gpio_pullup	= GPIO_USB_PULLUP;
	sc->sc_gpio_pullup_inv	= 0;
	sc->sc_is_host		= zaurus_udc_is_host;

	/* Platform specific GPIO configuration */
	pxa2x0_gpio_set_function(GPIO_USB_DETECT, GPIO_IN);
	pxa2x0_gpio_set_function(GPIO_USB_DEVICE, GPIO_IN);
	pxa2x0_gpio_set_function(GPIO_USB_PULLUP, GPIO_OUT);

	pxa2x0_gpio_set_function(45, GPIO_OUT);
	pxa2x0_gpio_set_function(40, GPIO_OUT);
	pxa2x0_gpio_set_function(39, GPIO_IN);
	pxa2x0_gpio_set_function(38, GPIO_IN);
	pxa2x0_gpio_set_function(37, GPIO_OUT);
	pxa2x0_gpio_set_function(36, GPIO_IN);
	pxa2x0_gpio_set_function(34, GPIO_IN);
	pxa2x0_gpio_set_function(89, GPIO_OUT);
	pxa2x0_gpio_set_function(120, GPIO_OUT);

	pxaudc_attach(sc, aux);
}
コード例 #15
0
ファイル: zapm.c プロジェクト: ryo/netbsd-src
static void
zapm_attach(device_t parent, device_t self, void *aux)
{
	struct zapm_softc *sc = device_private(self);
	struct apmdev_attach_args aaa;

	sc->sc_dev = self;

	aprint_normal(": pseudo power management module\n");
	aprint_naive("\n");

	/* machine-depent part */
	callout_init(&sc->sc_cyclic_poll, 0);
	callout_setfunc(&sc->sc_cyclic_poll, zapm_cyclic, sc);
	callout_init(&sc->sc_discharge_poll, 0);
	callout_setfunc(&sc->sc_discharge_poll, zapm_poll, sc);
	mutex_init(&sc->sc_mtx, MUTEX_DEFAULT, IPL_NONE);

	if (ZAURUS_ISC1000 || ZAURUS_ISC3000) {
		sc->sc_ac_detect_pin = GPIO_AC_IN_C3000;
		sc->sc_batt_cover_pin = GPIO_BATT_COVER_C3000;
		sc->sc_charge_comp_pin = GPIO_CHRG_CO_C3000;
	} else {
		/* XXX */
		return;
	}

	pxa2x0_gpio_set_function(sc->sc_ac_detect_pin, GPIO_IN);
	pxa2x0_gpio_set_function(sc->sc_charge_comp_pin, GPIO_IN);
	pxa2x0_gpio_set_function(sc->sc_batt_cover_pin, GPIO_IN);

	(void)pxa2x0_gpio_intr_establish(sc->sc_ac_detect_pin,
	    IST_EDGE_BOTH, IPL_BIO, zapm_acintr, sc);
	(void)pxa2x0_gpio_intr_establish(sc->sc_charge_comp_pin,
	    IST_EDGE_BOTH, IPL_BIO, zapm_bcintr, sc);

	/* machine-independent part */
	sc->events = 0;
	sc->power_state = APM_SYS_READY;
	sc->battery_state = APM_BATT_FLAG_UNKNOWN;
	sc->ac_state = APM_AC_UNKNOWN;
	sc->battery_life = APM_BATT_LIFE_UNKNOWN;
	sc->minutes_left = 0;
	sc->sc_standby_hook = config_hook(CONFIG_HOOK_PMEVENT,
					  CONFIG_HOOK_PMEVENT_STANDBYREQ,
					  CONFIG_HOOK_EXCLUSIVE,
					  zapm_hook, sc);
	sc->sc_suspend_hook = config_hook(CONFIG_HOOK_PMEVENT,
					  CONFIG_HOOK_PMEVENT_SUSPENDREQ,
					  CONFIG_HOOK_EXCLUSIVE,
					  zapm_hook, sc);

	sc->sc_battery_hook = config_hook(CONFIG_HOOK_PMEVENT,
					  CONFIG_HOOK_PMEVENT_BATTERY,
					  CONFIG_HOOK_SHARE,
					  zapm_hook, sc);

	sc->sc_ac_hook = config_hook(CONFIG_HOOK_PMEVENT,
				     CONFIG_HOOK_PMEVENT_AC,
				     CONFIG_HOOK_SHARE,
				     zapm_hook, sc);

	aaa.accessops = &zapm_accessops;
	aaa.accesscookie = sc;
	aaa.apm_detail = 0x0102;

	sc->sc_apmdev = config_found_ia(self, "apmdevif", &aaa, apmprint);
	if (sc->sc_apmdev != NULL) {
		zapm_poll1(sc, 0);
		callout_schedule(&sc->sc_cyclic_poll, CYCLIC_TIME);
	}
}
コード例 #16
0
static void
wzero3kbd_attach(device_t parent, device_t self, void *aux)
{
	struct wzero3kbd_softc *sc = device_private(self);
	struct pxaip_attach_args *pxa = (struct pxaip_attach_args *)aux;
	struct hpckbd_attach_args haa;
	const struct wzero3kbd_model *model;

	sc->sc_dev = self;

	model = wzero3kbd_lookup();
	if (model == NULL) {
		aprint_error(": unknown model\n");
		return;
	}

	aprint_normal(": keyboard\n");
	aprint_naive("\n");

	sc->sc_key_pin = model->key_pin;
	sc->sc_power_pin = model->power_pin;
	sc->sc_reset_pin = model->reset_pin;
	sc->sc_ncolumn = model->ncolumn;
	sc->sc_nrow = model->nrow;

	sc->sc_iot = pxa->pxa_iot;
	if (bus_space_map(sc->sc_iot, PXA2X0_CS2_START, REGMAPSIZE, 0,
	    &sc->sc_ioh)) {
		aprint_error_dev(self, "couldn't map registers.\n");
		return;
	}

	sc->sc_okeystat = malloc(sc->sc_nrow * sc->sc_ncolumn, M_DEVBUF,
	    M_NOWAIT | M_ZERO);
	sc->sc_keystat = malloc(sc->sc_nrow * sc->sc_ncolumn, M_DEVBUF,
	    M_NOWAIT | M_ZERO);
	if (sc->sc_okeystat == NULL || sc->sc_keystat == NULL) {
		aprint_error_dev(self, "couldn't alloc memory.\n");
		if (sc->sc_okeystat)
			free(sc->sc_okeystat, M_DEVBUF);
		if (sc->sc_keystat)
			free(sc->sc_keystat, M_DEVBUF);
		return;
	}

	sc->sc_if.hii_ctx = sc;
	sc->sc_if.hii_establish = wzero3kbd_input_establish;
	sc->sc_if.hii_poll = wzero3kbd_poll;

	/* Attach console if not using serial. */
	if (!(bootinfo->bi_cnuse & BI_CNUSE_SERIAL))
		hpckbd_cnattach(&sc->sc_if);

	/* Install interrupt handler. */
	if (sc->sc_key_pin >= 0) {
		pxa2x0_gpio_set_function(sc->sc_key_pin, GPIO_IN);
		sc->sc_key_ih = pxa2x0_gpio_intr_establish(sc->sc_key_pin,
		    IST_EDGE_BOTH, IPL_TTY, wzero3kbd_intr, sc);
		if (sc->sc_key_ih == NULL) {
			aprint_error_dev(sc->sc_dev,
			    "couldn't establish key interrupt\n");
		}
	} else {
		sc->sc_interval = KEY_INTERVAL / (1000 / hz);
		if (sc->sc_interval < 1)
			sc->sc_interval = 1;
		callout_init(&sc->sc_keyscan_ch, 0);
		callout_reset(&sc->sc_keyscan_ch, sc->sc_interval,
		    wzero3kbd_tick, sc);
	}

	/* power key */
	if (sc->sc_power_pin >= 0) {
		pxa2x0_gpio_set_function(sc->sc_power_pin, GPIO_IN);
		sc->sc_power_ih = pxa2x0_gpio_intr_establish(
		    sc->sc_power_pin, IST_EDGE_BOTH, IPL_TTY,
		    wzero3kbd_power_intr, sc);
		if (sc->sc_power_ih == NULL) {
			aprint_error_dev(sc->sc_dev,
			    "couldn't establish power key interrupt\n");
		}
	}

	/* reset button */
	if (sc->sc_reset_pin >= 0) {
		pxa2x0_gpio_set_function(sc->sc_reset_pin, GPIO_IN);
		sc->sc_reset_ih = pxa2x0_gpio_intr_establish(
		    sc->sc_reset_pin, IST_EDGE_BOTH, IPL_TTY,
		    wzero3kbd_reset_intr, sc);
		if (sc->sc_reset_ih == NULL) {
			aprint_error_dev(sc->sc_dev,
			    "couldn't establish reset key interrupt\n");
		}

		sc->sc_smpsw.smpsw_name = device_xname(self);
		sc->sc_smpsw.smpsw_type = PSWITCH_TYPE_RESET;
		if (sysmon_pswitch_register(&sc->sc_smpsw) != 0) {
			aprint_error_dev(sc->sc_dev,
			    "unable to register reset event handler\n");
		}
	}

	/* Attach hpckbd. */
	haa.haa_ic = &sc->sc_if;
	config_found(self, &haa, hpckbd_print);

#if defined(KEYTEST) || defined(KEYTEST2) || defined(KEYTEST3) || defined(KEYTEST4) || defined(KEYTEST5)
	sc->sc_test_ih = NULL;
	sc->sc_test_pin = -1;
	sc->sc_nouse_pin = -1;
	sc->sc_nouse_pin2 = -1;
	sc->sc_nouse_pin3 = -1;
	sc->sc_bit = 0x01;
	if (platid_match(&platid, &platid_mask_MACH_SHARP_WZERO3_WS003SH)
	 || platid_match(&platid, &platid_mask_MACH_SHARP_WZERO3_WS004SH)) {
		sc->sc_nouse_pin = GPIO_WS003SH_SD_DETECT;  /* SD_DETECT */
		sc->sc_nouse_pin2 = 86;  /* Vsync? */
		sc->sc_nouse_pin3 = 89;  /* RESET? */
	}
	if (platid_match(&platid, &platid_mask_MACH_SHARP_WZERO3_WS007SH)) {
		sc->sc_nouse_pin = GPIO_WS007SH_SD_DETECT;  /* SD_DETECT */
		sc->sc_nouse_pin2 = 77;  /* Vsync? */
	}
	if (platid_match(&platid, &platid_mask_MACH_SHARP_WZERO3_WS011SH)) {
		sc->sc_nouse_pin = GPIO_WS011SH_SD_DETECT;  /* SD_DETECT */
		sc->sc_nouse_pin2 = 77;  /* Vsync? */
	}
	if (platid_match(&platid, &platid_mask_MACH_SHARP_WZERO3_WS020SH)) {
		sc->sc_nouse_pin = GPIO_WS020SH_SD_DETECT;  /* SD_DETECT */
		sc->sc_nouse_pin2 = 77;  /* Vsync? */
	}

#ifdef KEYTEST
	for (sc->sc_test_pin = 2; sc->sc_test_pin < PXA270_GPIO_NPINS; sc->sc_test_pin++) {
		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 < PXA270_GPIO_NPINS) {
		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

#ifdef KEYTEST3
	{
		int i;
		printf("pin: ");
		for (i = 0; i < PXA270_GPIO_NPINS; i++) {
			if (i == sc->sc_nouse_pin
			 || i == sc->sc_nouse_pin2
			 || i == sc->sc_nouse_pin3
			 || i == sc->sc_key_pin
			 || i == sc->sc_power_pin
			 || i == sc->sc_reset_pin)
				continue;

			printf("%d, ", i);
			if (GPIO_IS_GPIO_IN(pxa2x0_gpio_get_function(i))) {
				pxa2x0_gpio_intr_establish(i, IST_EDGE_BOTH,
				    IPL_TTY, wzero3kbd_intr3, (void *)(long)i);
			}
		}
	}
#endif

#ifdef KEYTEST4
	for (sc->sc_test_pin = 2; sc->sc_test_pin < PXA270_GPIO_NPINS; sc->sc_test_pin++) {
		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 < PXA270_GPIO_NPINS) {
		printf("GPIO_OUT: GPIO pin #%d\n", sc->sc_test_pin);
	} else {
		sc->sc_test_pin = -1;
	}
#endif
#ifdef KEYTEST5
	sc->sc_test_pin = 0x00;
	sc->sc_bit = 0x01;
#endif
#endif
}
コード例 #17
0
ファイル: zkbd.c プロジェクト: ryo/netbsd-src
static void
zkbd_attach(device_t parent, device_t self, void *aux)
{
	struct zkbd_softc *sc = device_private(self);
	struct wskbddev_attach_args a;
	int pin, i;

	sc->sc_dev = self;
	zkbd_sc = sc;

	aprint_normal("\n");
	aprint_naive("\n");

	sc->sc_polling = 0;
#ifdef WSDISPLAY_COMPAT_RAWKBD
	sc->sc_rawkbd = 0;
#endif

	callout_init(&sc->sc_roll_to, 0);
	callout_setfunc(&sc->sc_roll_to, zkbd_poll, sc);
#ifdef WSDISPLAY_COMPAT_RAWKBD
	callout_init(&sc->sc_rawrepeat_ch, 0);
	callout_setfunc(&sc->sc_rawrepeat_ch, zkbd_rawrepeat, sc);
#endif

	if (ZAURUS_ISC1000 || ZAURUS_ISC3000) {
		sc->sc_sense_array = gpio_sense_pins_c3000;
		sc->sc_strobe_array = gpio_strobe_pins_c3000;
		sc->sc_nsense = __arraycount(gpio_sense_pins_c3000);
		sc->sc_nstrobe = __arraycount(gpio_strobe_pins_c3000);
		sc->sc_stuck_keys = stuck_keys_c3000;
		sc->sc_nstuck = __arraycount(stuck_keys_c3000);
		sc->sc_maxkbdcol = 10;
		sc->sc_onkey_pin = 95;
		sc->sc_sync_pin = 16;
		sc->sc_swa_pin = 97;
		sc->sc_swb_pin = 96;
		sc->sc_keymapdata = &zkbd_keymapdata;
#ifdef WSDISPLAY_COMPAT_RAWKBD
		sc->sc_xt_keymap = xt_keymap;
#endif
	} else if (ZAURUS_ISC860) {
		sc->sc_sense_array = gpio_sense_pins_c860;
		sc->sc_strobe_array = gpio_strobe_pins_c860;
		sc->sc_nsense = __arraycount(gpio_sense_pins_c860);
		sc->sc_nstrobe = __arraycount(gpio_strobe_pins_c860);
		sc->sc_stuck_keys = stuck_keys_c860;
		sc->sc_nstuck = __arraycount(stuck_keys_c860);
		sc->sc_maxkbdcol = 0;
		sc->sc_onkey_pin = -1;
		sc->sc_sync_pin = -1;
		sc->sc_swa_pin = -1;
		sc->sc_swb_pin = -1;
		sc->sc_keymapdata = &zkbd_keymapdata_c860;
#ifdef WSDISPLAY_COMPAT_RAWKBD
		sc->sc_xt_keymap = xt_keymap_c860;
#endif
	} else {
		/* XXX */
		return;
	}

	if (!pmf_device_register(sc->sc_dev, NULL, zkbd_resume))
		aprint_error_dev(sc->sc_dev,
		    "couldn't establish power handler\n");

	sc->sc_okeystate = malloc(sc->sc_nsense * sc->sc_nstrobe,
	    M_DEVBUF, M_NOWAIT);
	memset(sc->sc_okeystate, 0, sc->sc_nsense * sc->sc_nstrobe);

	sc->sc_keystate = malloc(sc->sc_nsense * sc->sc_nstrobe,
	    M_DEVBUF, M_NOWAIT);
	memset(sc->sc_keystate, 0, sc->sc_nsense * sc->sc_nstrobe);

	/* set all the strobe bits */
	for (i = 0; i < sc->sc_nstrobe; i++) {
		pin = sc->sc_strobe_array[i];
		if (pin == -1)
			continue;
		pxa2x0_gpio_set_function(pin, GPIO_SET|GPIO_OUT);
	}

	/* set all the sense bits */
	for (i = 0; i < sc->sc_nsense; i++) {
		pin = sc->sc_sense_array[i];
		if (pin == -1)
			continue;
		pxa2x0_gpio_set_function(pin, GPIO_IN);
		if (ZAURUS_ISC1000 || ZAURUS_ISC3000) {
			pxa2x0_gpio_intr_establish(pin, IST_EDGE_BOTH,
			    IPL_TTY, zkbd_irq_c3000, sc);
		} else if (ZAURUS_ISC860) {
			pxa2x0_gpio_intr_establish(pin, IST_EDGE_RISING,
			    IPL_TTY, zkbd_irq_c860, sc);
		}
	}

	if (sc->sc_onkey_pin >= 0)
		pxa2x0_gpio_intr_establish(sc->sc_onkey_pin, IST_EDGE_BOTH,
		    IPL_TTY, zkbd_on, sc);
	if (sc->sc_sync_pin >= 0)
		pxa2x0_gpio_intr_establish(sc->sc_sync_pin, IST_EDGE_RISING,
		    IPL_TTY, zkbd_sync, sc);
	if (sc->sc_swa_pin >= 0)
		pxa2x0_gpio_intr_establish(sc->sc_swa_pin, IST_EDGE_BOTH,
		    IPL_TTY, zkbd_hinge, sc);
	if (sc->sc_swb_pin >= 0)
		pxa2x0_gpio_intr_establish(sc->sc_swb_pin, IST_EDGE_BOTH,
		    IPL_TTY, zkbd_hinge, sc);

	if (glass_console) {
		wskbd_cnattach(&zkbd_consops, sc, sc->sc_keymapdata);
		a.console = 1;
	} else {
		a.console = 0;
	}
	a.keymap = sc->sc_keymapdata;
	a.accessops = &zkbd_accessops;
	a.accesscookie = sc;

	zkbd_hinge(sc);		/* to initialize sc_hinge */

	sc->sc_wskbddev = config_found(self, &a, wskbddevprint);
}
コード例 #18
0
ファイル: pxa2x0_apm.c プロジェクト: alenichev/openbsd-kernel
void
pxa2x0_apm_sleep(struct pxa2x0_apm_softc *sc)
{
	struct pxa2x0_sleep_data sd;
	bus_space_handle_t ost_ioh;
	int save;
	u_int32_t rv;

	ost_ioh = (bus_space_handle_t)0;
	if (bus_space_map(sc->sc_iot, PXA2X0_OST_BASE, PXA2X0_OST_SIZE, 0,
	    &ost_ioh)) {
		printf("pxa2x0_apm_sleep: can't map OST\n");
		goto out;
	}

	save = disable_interrupts(I32_bit|F32_bit);

	sd.sd_oscr0 = bus_space_read_4(sc->sc_iot, ost_ioh, OST_OSCR0);
	sd.sd_oscr4 = bus_space_read_4(sc->sc_iot, ost_ioh, OST_OSCR4);
	sd.sd_omcr4 = bus_space_read_4(sc->sc_iot, ost_ioh, OST_OMCR4);
	sd.sd_omcr5 = bus_space_read_4(sc->sc_iot, ost_ioh, OST_OMCR5);
	sd.sd_osmr0 = bus_space_read_4(sc->sc_iot, ost_ioh, OST_OSMR0);
	sd.sd_osmr1 = bus_space_read_4(sc->sc_iot, ost_ioh, OST_OSMR1);
	sd.sd_osmr2 = bus_space_read_4(sc->sc_iot, ost_ioh, OST_OSMR2);
	sd.sd_osmr3 = bus_space_read_4(sc->sc_iot, ost_ioh, OST_OSMR3);
	sd.sd_osmr4 = bus_space_read_4(sc->sc_iot, ost_ioh, OST_OSMR4);
	sd.sd_osmr5 = bus_space_read_4(sc->sc_iot, ost_ioh, OST_OSMR5);
	sd.sd_oier = bus_space_read_4(sc->sc_iot, ost_ioh, OST_OIER);

	/* Bring the PXA27x into 416MHz turbo mode. */
        if ((cputype & ~CPU_ID_XSCALE_COREREV_MASK) == CPU_ID_PXA27X &&
	    bus_space_read_4(sc->sc_iot, pxa2x0_clkman_ioh, CLKMAN_CCCR) !=
	    (CCCR_A | CCCR_TURBO_X2 | CCCR_RUN_X16)) {
#if 0
		pxa27x_cpu_speed_high();
#else
#define CLKCFG_T		(1<<0)	/* turbo */
#define CLKCFG_F		(1<<1)	/* frequency change */
#define CLKCFG_B		(1<<3)	/* fast-bus */
		pxa27x_frequency_change(CCCR_A | CCCR_TURBO_X2 |
		    CCCR_RUN_X16, CLKCFG_B | CLKCFG_F | CLKCFG_T,
		    &pxa2x0_memcfg);
#endif
		delay(500000); /* XXX */
	}

suspend_again:
	/* Clear wake-up status. */
	bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PEDR,
	    0xffffffff);
	bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PKSR,
	    0xffffffff);

	/* XXX control battery charging in sleep mode. */

	/* XXX schedule RTC alarm to check the battery, or schedule
	   XXX wake-up shortly before an already programmed alarm? */

	pxa27x_run_mode();
#define MDREFR_LOW		(MDREFR_C3000 | 0x00b)
	pxa27x_fastbus_run_mode(0, MDREFR_LOW);
	delay(1);
#if 1
	pxa27x_cpu_speed_91();
#else
	pxa27x_frequency_change(CCCR_TURBO_X1 | CCCR_RUN_X7, CLKCFG_F,
	    &pxa2x0_memcfg);
#endif
	pxa2x0_pi2c_setvoltage(sc->sc_iot, sc->sc_pm_ioh, PI2C_VOLTAGE_LOW);

	sd.sd_gpdr0 = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPDR0);
	sd.sd_gpdr1 = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPDR1);
	sd.sd_gpdr2 = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPDR2);
	sd.sd_gpdr3 = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPDR3);

	sd.sd_grer0 = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GRER0);
	sd.sd_grer1 = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GRER1);
	sd.sd_grer2 = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GRER2);
	sd.sd_grer3 = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GRER3);

	sd.sd_gfer0 = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GFER0);
	sd.sd_gfer1 = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GFER1);
	sd.sd_gfer2 = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GFER2);
	sd.sd_gfer3 = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GFER3);

	sd.sd_gafr0_l = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GAFR0_L);
	sd.sd_gafr1_l = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GAFR1_L);
	sd.sd_gafr2_l = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GAFR2_L);
	sd.sd_gafr3_l = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GAFR3_L);

	sd.sd_gafr0_u = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GAFR0_U);
	sd.sd_gafr1_u = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GAFR1_U);
	sd.sd_gafr2_u = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GAFR2_U);
	sd.sd_gafr3_u = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GAFR3_U);

	sd.sd_gplr0 = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPLR0);
	sd.sd_gplr1 = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPLR1);
	sd.sd_gplr2 = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPLR2);
	sd.sd_gplr3 = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPLR3);

	sd.sd_iclr = read_icu(INTCTL_ICLR);
	sd.sd_icmr = read_icu(INTCTL_ICMR);
	sd.sd_iccr = read_icu(INTCTL_ICCR);
	write_icu(INTCTL_ICMR, 0);

	sd.sd_mecr = bus_space_read_4(sc->sc_iot, pxa2x0_memctl_ioh,
	    MEMCTL_MECR);
	sd.sd_mcmem0 = bus_space_read_4(sc->sc_iot, pxa2x0_memctl_ioh,
	    MEMCTL_MCMEM(0));
	sd.sd_mcmem1 = bus_space_read_4(sc->sc_iot, pxa2x0_memctl_ioh,
	    MEMCTL_MCMEM(1));
	sd.sd_mcatt0 = bus_space_read_4(sc->sc_iot, pxa2x0_memctl_ioh,
	    MEMCTL_MCATT(0));
	sd.sd_mcatt1 = bus_space_read_4(sc->sc_iot, pxa2x0_memctl_ioh,
	    MEMCTL_MCATT(1));
	sd.sd_mcio0 = bus_space_read_4(sc->sc_iot, pxa2x0_memctl_ioh,
	    MEMCTL_MCIO(0));
	sd.sd_mcio1 = bus_space_read_4(sc->sc_iot, pxa2x0_memctl_ioh,
	    MEMCTL_MCIO(1));

	sd.sd_cken = bus_space_read_4(sc->sc_iot, pxa2x0_clkman_ioh,
	    CLKMAN_CKEN);

	/*
	 * Stop clocks to all units except to the memory controller, and
	 * to the keypad controller if it is enabled as a wake-up source.
	 */
	rv = CKEN_MEM;
	if ((sc->sc_wakeon & PXA2X0_WAKEUP_KEYNS_ALL) != 0)
		rv |= CKEN_KEY;
	bus_space_write_4(sc->sc_iot, pxa2x0_clkman_ioh, CLKMAN_CKEN, rv);

	/* Disable nRESET_OUT. */
	rv = bus_space_read_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PSLR);
#define  PSLR_SL_ROD	(1<<20)
	bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PSLR,
	    rv | PSLR_SL_ROD);

	/* Clear all reset status flags. */
	bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_RCSR,
	    RCSR_GPR | RCSR_SMR | RCSR_WDR | RCSR_HWR);

	/* Stop 3/13MHz oscillator; do not float PCMCIA and chip-selects. */
	rv = PCFR_OPDE;
        if ((cputype & ~CPU_ID_XSCALE_COREREV_MASK) == CPU_ID_PXA27X)
		/* Enable nRESET_GPIO as a GPIO reset input. */
		rv |= PCFR_GPR_EN;
	bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PCFR, rv);

	/* XXX C3000 */
#define	GPIO_G0_STROBE_BIT		0x0f800000
#define	GPIO_G1_STROBE_BIT		0x00100000
#define	GPIO_G2_STROBE_BIT		0x01000000
#define	GPIO_G3_STROBE_BIT		0x00041880
#define	GPIO_KEY_STROBE0		88
	bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PGSR0,
	    0x00144018);
	bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PGSR1,
	    0x00ef0000);
	bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PGSR2,
	    0x0121c000);
	bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PGSR3,
	    0x00600000);
	bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PGSR0,
	    0x00144018 & ~GPIO_G0_STROBE_BIT);
	bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PGSR1,
	    0x00ef0000 & ~GPIO_G1_STROBE_BIT);
	bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PGSR2,
	    0x0121c000 & ~GPIO_G2_STROBE_BIT);
	bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PGSR3,
	    0x00600000 & ~GPIO_G3_STROBE_BIT);
	bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PGSR2,
	    (0x0121c000 & ~GPIO_G2_STROBE_BIT) |
	    GPIO_BIT(GPIO_KEY_STROBE0));

	/* C3000 */
#define GPIO_EXT_BUS_READY	18
	pxa2x0_gpio_set_function(GPIO_EXT_BUS_READY, GPIO_SET | GPIO_OUT);
	bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPDR0, 0xd01c4418);
	bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPDR1, 0xfcefbd21);
	bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPDR2, 0x13a5ffff);
	bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPDR3, 0x01e3e10c);

	bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PSPR,
	    (u_int32_t)&pxa2x0_cpu_resume - 0xc0200000 + 0xa0200000);

	pxa2x0_cpu_suspend();

	bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PSPR, 0);

	pxa2x0_clkman_config(CKEN_SSP|CKEN_PWM0|CKEN_PWM1, 1);
	pxa2x0_clkman_config(CKEN_KEY, 0);

#if 1
	/* Clear all GPIO interrupt sources. */
	bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GEDR0, 0xffffffff);
	bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GEDR1, 0xffffffff);
	bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GEDR2, 0xffffffff);
#endif

	bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPDR0, sd.sd_gpdr0);
	bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPDR1, sd.sd_gpdr1);
	bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPDR2, sd.sd_gpdr2);
	bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GRER0, sd.sd_grer0);
	bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GRER1, sd.sd_grer1);
	bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GRER2, sd.sd_grer2);
	bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GFER0, sd.sd_gfer0);
	bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GFER1, sd.sd_gfer1);
	bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GFER2, sd.sd_gfer2);
	bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GAFR0_L, sd.sd_gafr0_l);
	bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GAFR1_L, sd.sd_gafr1_l);
	bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GAFR2_L, sd.sd_gafr2_l);
	bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GAFR0_U, sd.sd_gafr0_u);
	bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GAFR1_U, sd.sd_gafr1_u);
	bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GAFR2_U, sd.sd_gafr2_u);
	bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPSR0, sd.sd_gplr0 &
	    sd.sd_gpdr0);
	bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPSR1, sd.sd_gplr1 &
	    sd.sd_gpdr1);
	bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPSR2, sd.sd_gplr2 &
	    sd.sd_gpdr2);
	bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPCR0, ~sd.sd_gplr0 &
	    sd.sd_gpdr0);
	bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPCR1, ~sd.sd_gplr1 &
	    sd.sd_gpdr1);
	bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPCR2, ~sd.sd_gplr2 &
	    sd.sd_gpdr2);

	/* PXA27x */
#if 0
	bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GEDR3, 0xffffffff);
#endif
	bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPDR3, sd.sd_gpdr3);
	bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GRER3, sd.sd_grer3);
	bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GFER3, sd.sd_gfer3);
	bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GAFR3_L, sd.sd_gafr3_l);
	bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GAFR3_U, sd.sd_gafr3_u);
	bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPSR3, sd.sd_gplr3 &
	    sd.sd_gpdr3);
	bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPCR3, ~sd.sd_gplr3 &
	    sd.sd_gpdr3);

	bus_space_write_4(sc->sc_iot, pxa2x0_memctl_ioh, MEMCTL_MECR,
	    sd.sd_mecr);
	bus_space_write_4(sc->sc_iot, pxa2x0_memctl_ioh, MEMCTL_MCMEM(0),
	    sd.sd_mcmem0);
	bus_space_write_4(sc->sc_iot, pxa2x0_memctl_ioh, MEMCTL_MCMEM(1),
	    sd.sd_mcmem1);
	bus_space_write_4(sc->sc_iot, pxa2x0_memctl_ioh, MEMCTL_MCATT(0),
	    sd.sd_mcatt0);
	bus_space_write_4(sc->sc_iot, pxa2x0_memctl_ioh, MEMCTL_MCATT(1),
	    sd.sd_mcatt1);
	bus_space_write_4(sc->sc_iot, pxa2x0_memctl_ioh, MEMCTL_MCIO(0),
	    sd.sd_mcio0);
	bus_space_write_4(sc->sc_iot, pxa2x0_memctl_ioh, MEMCTL_MCIO(1),
	    sd.sd_mcio1);

	bus_space_write_4(sc->sc_iot, pxa2x0_clkman_ioh, CLKMAN_CKEN,
	    sd.sd_cken);

	write_icu(INTCTL_ICLR, sd.sd_iclr);
	write_icu(INTCTL_ICCR, sd.sd_iccr);
	write_icu(INTCTL_ICMR, sd.sd_icmr);

	if ((read_icu(INTCTL_ICIP) & 0x1) != 0)
		bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PEDR, 0x1);

	bus_space_write_4(sc->sc_iot, ost_ioh, OST_OSMR0, sd.sd_osmr0);
	bus_space_write_4(sc->sc_iot, ost_ioh, OST_OSMR1, sd.sd_osmr1);
	bus_space_write_4(sc->sc_iot, ost_ioh, OST_OSMR2, sd.sd_osmr2);
	bus_space_write_4(sc->sc_iot, ost_ioh, OST_OSMR3, sd.sd_osmr3);
	bus_space_write_4(sc->sc_iot, ost_ioh, OST_OSMR4, sd.sd_osmr4);
	bus_space_write_4(sc->sc_iot, ost_ioh, OST_OSMR5, sd.sd_osmr5);
	bus_space_write_4(sc->sc_iot, ost_ioh, OST_OMCR4, sd.sd_omcr4);
	bus_space_write_4(sc->sc_iot, ost_ioh, OST_OMCR5, sd.sd_omcr5);
	bus_space_write_4(sc->sc_iot, ost_ioh, OST_OSCR0, sd.sd_oscr0);
	bus_space_write_4(sc->sc_iot, ost_ioh, OST_OSCR4, sd.sd_oscr4);
	bus_space_write_4(sc->sc_iot, ost_ioh, OST_OIER, sd.sd_oier);

	pxa2x0_pi2c_setvoltage(sc->sc_iot, sc->sc_pm_ioh, PI2C_VOLTAGE_HIGH);

	/* Change to 208MHz run mode with fast-bus still disabled. */
	pxa27x_frequency_change(CCCR_A | CCCR_TURBO_X2 | CCCR_RUN_X16,
	    CLKCFG_F, &pxa2x0_memcfg);
	delay(1); /* XXX is the delay long enough, and necessary at all? */
	pxa27x_fastbus_run_mode(1, pxa2x0_memcfg.mdrefr_high);

	/* Change to 416MHz turbo mode with fast-bus enabled. */
	pxa27x_frequency_change(CCCR_A | CCCR_TURBO_X2 | CCCR_RUN_X16,
	    CLKCFG_B | CLKCFG_F | CLKCFG_T, &pxa2x0_memcfg);

	if (sc->sc_resume != NULL) {
		if (!sc->sc_resume(sc))
			goto suspend_again;
	}

	/*
	 * Allow immediate entry into deep-sleep mode if power fails.
	 * Resume from immediate deep-sleep is not implemented yet.
	 */
	bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PMCR, 0);


	restore_interrupts(save);

	pxa2x0_setperf(perflevel);

 out:
	if (ost_ioh != (bus_space_handle_t)0)
		bus_space_unmap(sc->sc_iot, ost_ioh, PXA2X0_OST_SIZE);
}