/*
 * Transmit a single data word to one of the ICs, keep the chip selected
 * afterwards, and don't wait for data to be returned in SSDR.  Interrupts
 * must be held off until wzero3ssp_ic_stop() gets called.
 */
void
wzero3ssp_ic_start(int ic, uint32_t cmd)
{
	struct wzero3ssp_softc *sc;

	KASSERT(wzero3ssp_sc != NULL);
	sc = wzero3ssp_sc;

	mutex_enter(&sc->sc_mtx);

	/* disable other ICs */
	bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR0, 0);
	if (platid_match(&platid, &platid_mask_MACH_SHARP_WZERO3_WS007SH)) {
		if (ic != WZERO3_SSP_IC_ADS7846)
			pxa2x0_gpio_set_bit(GPIO_WS007SH_ADS7846_CS);
	}
	if (platid_match(&platid, &platid_mask_MACH_SHARP_WZERO3_WS011SH)) {
		if (ic != WZERO3_SSP_IC_AK4184_TP
		 && ic != WZERO3_SSP_IC_AK4184_KEYPAD)
			pxa2x0_gpio_set_bit(GPIO_WS011SH_AK4184_CS);
	}

	/* activate the chosen one */
	switch (ic) {
	case WZERO3_SSP_IC_ADS7846:
		bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR0, 0);
		bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR0,
		    WS007SH_SSCR0_ADS7846);
		pxa2x0_gpio_clear_bit(GPIO_WS007SH_ADS7846_CS);
		bus_space_write_1(sc->sc_iot, sc->sc_ioh, SSP_SSDR, cmd);
		while ((bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR)
		    & SSSR_TNF) != SSSR_TNF)
			continue;	/* poll */
		break;
	case WZERO3_SSP_IC_AK4184_TP:
		bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR0, 0);
		bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR0,
		    WS011SH_SSCR0_AK4184_TP);
		pxa2x0_gpio_clear_bit(GPIO_WS011SH_AK4184_CS);
		(void) bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR);
		while (!(bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR)
		    & SSSR_TNF))
			continue;	/* poll */
		bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR, cmd << 16);
		while (bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR)
		    & SSSR_BUSY)
			continue;	/* poll */
		break;
	case WZERO3_SSP_IC_MAX1233:
	case WZERO3_SSP_IC_AK4184_KEYPAD:
	case WZERO3_SSP_IC_NUM:
	default:
		break;
	}
}
static uint32_t
wzero3ssp_read_ak4184_tp(struct wzero3ssp_softc *sc, uint32_t cmd)
{
	uint32_t rv;

	mutex_enter(&sc->sc_mtx);

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

	pxa2x0_gpio_clear_bit(GPIO_WS011SH_AK4184_CS);

	/* clear rx fifo */
	(void) bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR);

	/* send cmd */
	while (!(bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR) & SSSR_TNF))
		continue;	/* poll */
	bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR, cmd << 16);
	while (bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR) & SSSR_BUSY)
		continue;	/* poll */

	while (!(bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR) & SSSR_RNE))
		continue;	/* poll */
	rv = bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR);

	pxa2x0_gpio_set_bit(GPIO_WS011SH_AK4184_CS);

	mutex_exit(&sc->sc_mtx);

	return rv;
}
static uint32_t
wzero3ssp_read_ads7846(struct wzero3ssp_softc *sc, uint32_t cmd)
{
	uint32_t rv;

	mutex_enter(&sc->sc_mtx);

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

	pxa2x0_gpio_clear_bit(GPIO_WS007SH_ADS7846_CS);

	/* send cmd */
	while (!(bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR) & SSSR_TNF))
		continue;	/* poll */
	bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR, cmd);
	while (bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR) & SSSR_BUSY)
		continue;	/* poll */

	while (!(bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR) & SSSR_RNE))
		continue;	/* poll */
	rv = bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR);

	pxa2x0_gpio_set_bit(GPIO_WS007SH_ADS7846_CS);

	mutex_exit(&sc->sc_mtx);

	return rv;
}
Esempio n. 4
0
int
palm_mmc_set_power(void *cookie, u_int32_t ocr)
{
	if (ISSET(ocr, MMC_OCR_3_2V_3_3V | MMC_OCR_3_3V_3_4V)) {
		if (mach_is_palmz72)
			pxa2x0_gpio_clear_bit(GPIO98_PALMZ72_MMC_POWER);
		else if (mach_is_palmtc)
			pxa2x0_gpio_set_bit(GPIO32_PALMTC_MMC_POWER);
		else
			pxa2x0_gpio_set_bit(GPIO114_MMC_POWER);
		return 0;
	} else if (ocr != 0) {
		printf("palm_mmc_set_power: unsupported OCR (%#x)\n", ocr);
		return EINVAL;
	} else {
		if (mach_is_palmz72)
			pxa2x0_gpio_set_bit(GPIO98_PALMZ72_MMC_POWER);
		else if (mach_is_palmtc)
			pxa2x0_gpio_clear_bit(GPIO32_PALMTC_MMC_POWER);
		else
			pxa2x0_gpio_clear_bit(GPIO114_MMC_POWER);
		return 0;
	}
}
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
wzero3mci_set_power(void *arg, uint32_t ocr)
{
	struct wzero3mci_softc *sc = (struct wzero3mci_softc *)arg;
	int error = 0;

	if (sc->sc_power_pin >= 0) {
		if (ISSET(ocr, MMC_OCR_3_2V_3_3V|MMC_OCR_3_3V_3_4V)) {
			/* power on */
			pxa2x0_gpio_set_bit(sc->sc_power_pin);
		} else if (ocr == 0) {
			/* power off */
			pxa2x0_gpio_clear_bit(sc->sc_power_pin);
		} else {
			aprint_error_dev(sc->sc.sc_dev,
			    "unsupported OCR (%#x)\n", ocr);
			error = EINVAL;
		}
	}
	return error;
}
static uint32_t
wzero3ssp_read_max1233(struct wzero3ssp_softc *sc, uint32_t cmd, uint32_t data)
{
	uint32_t rv;

	mutex_enter(&sc->sc_mtx);

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

	pxa2x0_gpio_set_bit(39/*GPIO_WS003SH_XXX*/);
	pxa2x0_gpio_clear_bit(GPIO_WS003SH_MAX1233_CS);

	/* send cmd */
	while (!(bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR) & SSSR_TNF))
		continue;	/* poll */
	bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR, cmd);
	while (bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR) & SSSR_BUSY)
		continue;	/* poll */
	while (!(bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR) & SSSR_RNE))
		continue;	/* poll */
	(void)bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR);

	while (!(bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR) & SSSR_TNF))
		continue;	/* poll */
	bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR, data);
	while (bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR) & SSSR_BUSY)
		continue;	/* poll */
	while (!(bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR) & SSSR_RNE))
		continue;	/* poll */
	rv = bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR);

	pxa2x0_gpio_set_bit(GPIO_WS003SH_MAX1233_CS);

	mutex_exit(&sc->sc_mtx);

	return rv;
}
Esempio n. 8
0
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);
}