Ejemplo n.º 1
0
int gpio_set_wake(unsigned int gpio, unsigned int on)
{
	struct gpio_desc *d;
	unsigned long c, mux_taken;

	if (gpio > mfp_to_gpio(MFP_PIN_GPIO127))
		return -EINVAL;

	d = &gpio_desc[gpio];
	c = d->config;

	if (!d->valid)
		return -EINVAL;

	/* Allow keypad GPIOs to wakeup system when
	 * configured as generic GPIOs.
	 */
	if (d->keypad_gpio && (MFP_AF(d->config) == 0) &&
	    (d->config & MFP_LPM_CAN_WAKEUP)) {
		if (on)
			PKWR |= d->mask;
		else
			PKWR &= ~d->mask;
		return 0;
	}

	mux_taken = (PWER & d->mux_mask) & (~d->mask);
	if (on && mux_taken)
		return -EBUSY;

	if (d->can_wakeup && (c & MFP_LPM_CAN_WAKEUP)) {
		if (on) {
			PWER = (PWER & ~d->mux_mask) | d->mask;

			if (c & MFP_LPM_EDGE_RISE)
				PRER |= d->mask;
			else
				PRER &= ~d->mask;

			if (c & MFP_LPM_EDGE_FALL)
				PFER |= d->mask;
			else
				PFER &= ~d->mask;
		} else {
			PWER &= ~d->mask;
			PRER &= ~d->mask;
			PFER &= ~d->mask;
		}
	}
	return 0;
}
Ejemplo n.º 2
0
void mfp_config(unsigned long *mfp_cfgs, int num)
{
	unsigned long flags;
	int i, drv_b11 = 0, no_lpm = 0;

#ifdef CONFIG_ARCH_MMP
	if (cpu_is_pxa910() || cpu_is_pxa988() || cpu_is_pxa986() ||
		cpu_is_mmp2() || cpu_is_mmp3() || cpu_is_pxa1088())
		drv_b11 = 1;
	if (cpu_is_pxa168() || cpu_is_pxa910())
		no_lpm = 1;
#elif defined(CONFIG_ARCH_PXA)
	if (cpu_is_pxa95x())
		drv_b11 = 1;
#endif
	spin_lock_irqsave(&mfp_spin_lock, flags);

	for (i = 0; i < num; i++, mfp_cfgs++) {
		unsigned long tmp, c = *mfp_cfgs;
		struct mfp_pin *p;
		int pin, af, drv, lpm, edge, pull;

		pin = MFP_PIN(c);
		BUG_ON(pin >= MFP_PIN_MAX);
		p = &mfp_table[pin];

		af  = MFP_AF(c);
		drv = MFP_DS(c);
		lpm = MFP_LPM_STATE(c);
		edge = MFP_LPM_EDGE(c);
		pull = MFP_PULL(c);
		if (drv_b11)
			drv = drv << 1;
		if (no_lpm)
			lpm = 0;

		tmp = MFPR_AF_SEL(af) | MFPR_DRIVE(drv);
		tmp |= mfpr_pull[pull] | mfpr_lpm[lpm] | mfpr_edge[edge];
		p->mfpr_run = tmp;
		p->mfpr_lpm = p->mfpr_run;

		p->config = c; __mfp_config_run(p);
	}

	mfpr_sync();
	spin_unlock_irqrestore(&mfp_spin_lock, flags);
}
Ejemplo n.º 3
0
void pxa3xx_mfp_config(unsigned long *mfp_cfgs, int num)
{
    unsigned long flags;
    int i;

    spin_lock_irqsave(&mfp_spin_lock, flags);

    for (i = 0; i < num; i++, mfp_cfgs++) {
        unsigned long tmp, c = *mfp_cfgs;
        struct pxa3xx_mfp_pin *p;
        int pin, af, drv, lpm, edge, pull;

        pin = MFP_PIN(c);
        BUG_ON(pin >= MFP_PIN_MAX);
        p = &mfp_table[pin];

        af  = MFP_AF(c);
        drv = MFP_DS(c);
        lpm = MFP_LPM_STATE(c);
        edge = MFP_LPM_EDGE(c);
        pull = MFP_PULL(c);

        /* run-mode pull settings will conflict with MFPR bits of
         * low power mode state,  calculate mfpr_run and mfpr_lpm
         * individually if pull != MFP_PULL_NONE
         */
        tmp = MFPR_AF_SEL(af) | MFPR_DRIVE(drv);

        if (likely(pull == MFP_PULL_NONE)) {
            p->mfpr_run = tmp | mfpr_lpm[lpm] | mfpr_edge[edge];
            p->mfpr_lpm = p->mfpr_run;
        } else {
            p->mfpr_lpm = tmp | mfpr_lpm[lpm] | mfpr_edge[edge];
            p->mfpr_run = tmp | mfpr_pull[pull];
        }

        p->config = c;
        __mfp_config_run(p);
    }

    mfpr_sync();
    spin_unlock_irqrestore(&mfp_spin_lock, flags);
}
Ejemplo n.º 4
0
static int __mfp_config_gpio(unsigned gpio, unsigned long c)
{
	unsigned long gafr, mask = GPIO_bit(gpio);
	int fn;

	fn = MFP_AF(c);
	if (fn > 3)
		return -EINVAL;

	/* alternate function and direction */
	gafr = GAFR(gpio) & ~(0x3 << ((gpio & 0xf) * 2));
	GAFR(gpio) = gafr |  (fn  << ((gpio & 0xf) * 2));

	if (c & MFP_DIR_OUT)
		GPDR(gpio) |= mask;
	else
		GPDR(gpio) &= ~mask;

	if (__mfp_config_lpm(gpio, c & MFP_LPM_STATE_MASK))
		return -EINVAL;

	/* give early warning if MFP_LPM_CAN_WAKEUP is set on the
	 * configurations of those pins not able to wakeup
	 */
	if ((c & MFP_LPM_CAN_WAKEUP) && !gpio_desc[gpio].can_wakeup) {
		pr_warning("%s: GPIO%d unable to wakeup\n",
				__func__, gpio);
		return -EINVAL;
	}

	if ((c & MFP_LPM_CAN_WAKEUP) && (c & MFP_DIR_OUT)) {
		pr_warning("%s: output GPIO%d unable to wakeup\n",
				__func__, gpio);
		return -EINVAL;
	}

	return 0;
}
Ejemplo n.º 5
0
int keypad_set_wake(unsigned int on)
{
	unsigned int i, gpio, mask = 0;
	struct gpio_desc *d;

	for (i = 0; i < ARRAY_SIZE(pxa27x_pkwr_gpio); i++) {

		gpio = pxa27x_pkwr_gpio[i];
		d = &gpio_desc[gpio];

		/* skip if configured as generic GPIO */
		if (MFP_AF(d->config) == 0)
			continue;

		if (d->config & MFP_LPM_CAN_WAKEUP)
			mask |= gpio_desc[gpio].mask;
	}

	if (on)
		PKWR |= mask;
	else
		PKWR &= ~mask;
	return 0;
}
Ejemplo n.º 6
0
static int __mfp_config_gpio(unsigned gpio, unsigned long c)
{
	unsigned long gafr, mask = GPIO_bit(gpio);
	int bank = gpio_to_bank(gpio);
	int uorl = !!(gpio & 0x10); /* GAFRx_U or GAFRx_L ? */
	int shft = (gpio & 0xf) << 1;
	int fn = MFP_AF(c);
	int is_out = (c & MFP_DIR_OUT) ? 1 : 0;

	if (fn > 3)
		return -EINVAL;

	/* alternate function and direction at run-time */
	gafr = (uorl == 0) ? GAFR_L(bank) : GAFR_U(bank);
	gafr = (gafr & ~(0x3 << shft)) | (fn << shft);

	if (uorl == 0)
		GAFR_L(bank) = gafr;
	else
		GAFR_U(bank) = gafr;

	if (is_out ^ gpio_desc[gpio].dir_inverted)
		GPDR(gpio) |= mask;
	else
		GPDR(gpio) &= ~mask;

	/* alternate function and direction at low power mode */
	switch (c & MFP_LPM_STATE_MASK) {
	case MFP_LPM_DRIVE_HIGH:
		PGSR(bank) |= mask;
		is_out = 1;
		break;
	case MFP_LPM_DRIVE_LOW:
		PGSR(bank) &= ~mask;
		is_out = 1;
		break;
	case MFP_LPM_INPUT:
	case MFP_LPM_DEFAULT:
		break;
	default:
		/* warning and fall through, treat as MFP_LPM_DEFAULT */
		pr_warning("%s: GPIO%d: unsupported low power mode\n",
				__func__, gpio);
		break;
	}

	if (is_out ^ gpio_desc[gpio].dir_inverted)
		gpdr_lpm[bank] |= mask;
	else
		gpdr_lpm[bank] &= ~mask;

	/* give early warning if MFP_LPM_CAN_WAKEUP is set on the
	 * configurations of those pins not able to wakeup
	 */
	if ((c & MFP_LPM_CAN_WAKEUP) && !gpio_desc[gpio].can_wakeup) {
		pr_warning("%s: GPIO%d unable to wakeup\n",
				__func__, gpio);
		return -EINVAL;
	}

	if ((c & MFP_LPM_CAN_WAKEUP) && is_out) {
		pr_warning("%s: output GPIO%d unable to wakeup\n",
				__func__, gpio);
		return -EINVAL;
	}

	return 0;
}
Ejemplo n.º 7
0
static int __mfp_config_gpio(unsigned gpio, unsigned long c)
{
	unsigned long gafr, mask = GPIO_bit(gpio);
	int bank = gpio_to_bank(gpio);
	int uorl = !!(gpio & 0x10); 
	int shft = (gpio & 0xf) << 1;
	int fn = MFP_AF(c);
	int is_out = (c & MFP_DIR_OUT) ? 1 : 0;

	if (fn > 3)
		return -EINVAL;

	
	gafr = (uorl == 0) ? GAFR_L(bank) : GAFR_U(bank);
	gafr = (gafr & ~(0x3 << shft)) | (fn << shft);

	if (uorl == 0)
		GAFR_L(bank) = gafr;
	else
		GAFR_U(bank) = gafr;

	if (is_out ^ gpio_desc[gpio].dir_inverted)
		GPDR(gpio) |= mask;
	else
		GPDR(gpio) &= ~mask;

	
	switch (c & MFP_LPM_STATE_MASK) {
	case MFP_LPM_DRIVE_HIGH:
		PGSR(bank) |= mask;
		is_out = 1;
		break;
	case MFP_LPM_DRIVE_LOW:
		PGSR(bank) &= ~mask;
		is_out = 1;
		break;
	case MFP_LPM_INPUT:
	case MFP_LPM_DEFAULT:
		break;
	default:
		
		pr_warning("%s: GPIO%d: unsupported low power mode\n",
				__func__, gpio);
		break;
	}

	if (is_out ^ gpio_desc[gpio].dir_inverted)
		gpdr_lpm[bank] |= mask;
	else
		gpdr_lpm[bank] &= ~mask;

	if ((c & MFP_LPM_CAN_WAKEUP) && !gpio_desc[gpio].can_wakeup) {
		pr_warning("%s: GPIO%d unable to wakeup\n",
				__func__, gpio);
		return -EINVAL;
	}

	if ((c & MFP_LPM_CAN_WAKEUP) && is_out) {
		pr_warning("%s: output GPIO%d unable to wakeup\n",
				__func__, gpio);
		return -EINVAL;
	}

	return 0;
}