Пример #1
0
int pnx_gpio_read_pin(int gpio)
{
	struct gpio_bank *bank;
	void __iomem *reg;
	u32 l = 0;
	int irq, index;

	if (!check_gpio(gpio))
		return -EINVAL;

	bank = get_gpio_bank(gpio);
	index = get_gpio_index(gpio);
	if (!check_gpio_requested(bank, index))
		return -EINVAL;

	/* check if the GPIO is used as extint */
	irq = pnx_gpio_to_extint(gpio);
	if (irq >= 0) {
		/* and if it's an alternate internal signal */
		/* (cf PNX67xx datasheet table 444)*/
		reg = (void __iomem*) EXTINT_CFGx(irq);
		l = __raw_readl(reg);
		if (l & EXTINT_SEL_ALTERNATE) {
			reg = (void __iomem*) EXTINT_SIGNAL_REG;
			return (__raw_readl(reg) & (1 << irq)) !=0;
		}
	}

	reg = bank->gpio_base;
	reg += PNX_GPIO_PINS_OFFSET;
	return (__raw_readl(reg) & (1 << index)) != 0;
}
Пример #2
0
int pnx_gpio_set_irq_selection(int irq, int selection)
{
	int gpio, index;
	struct gpio_bank *bank;
	u32 l = 0;
	void __iomem *reg;

	gpio = EXTINT_TO_GPIO(irq);
	irq -= IRQ_COUNT;
	if (!check_gpio_irq(irq))
		return -EINVAL;

	bank = get_gpio_bank(gpio);
	index = get_gpio_index(gpio);
	if (!check_gpio_requested(bank, index))
		return -EINVAL;

	reg = (void __iomem*) EXTINT_CFGx(irq);
	l = __raw_readl(reg);

	if (selection == EXTINT_SEL_ALTERNATE)
		l |= EXTINT_SEL_ALTERNATE;
	else
		l &= ~EXTINT_SEL_ALTERNATE;
	__raw_writel(l,reg);

	return  0;
}
Пример #3
0
/**
 * Get value of the specified gpio
 */
int gpio_get_value(unsigned gpio)
{
	const struct gpio_bank *bank;
	void *reg;
	int input;

	if (check_gpio(gpio) < 0)
		return -1;
	bank = get_gpio_bank(gpio);
	reg = bank->base;
	switch (bank->method) {
	case METHOD_GPIO_24XX:
		input = _get_gpio_direction(bank, get_gpio_index(gpio));
		switch (input) {
		case OMAP_GPIO_DIR_IN:
			reg += OMAP_GPIO_DATAIN;
			break;
		case OMAP_GPIO_DIR_OUT:
			reg += OMAP_GPIO_DATAOUT;
			break;
		default:
			return -1;
		}
		break;
	default:
		return -1;
	}
	return (__raw_readl(reg)
			& (1 << get_gpio_index(gpio))) != 0;
}
Пример #4
0
void omap_set_gpio_direction(int gpio, int is_input)
{
	struct gpio_bank *bank;

	if (check_gpio(gpio) < 0)
		return;
	bank = get_gpio_bank(gpio);
	_set_gpio_direction(bank, get_gpio_index(gpio), is_input);
}
Пример #5
0
void omap_set_gpio_dataout(int gpio, int enable)
{
	struct gpio_bank *bank;

	if (check_gpio(gpio) < 0)
		return;
	bank = get_gpio_bank(gpio);
	_set_gpio_dataout(bank, get_gpio_index(gpio), enable);
}
Пример #6
0
void omap_free_gpio(int gpio)
{
	struct gpio_bank *bank;

	if (check_gpio(gpio) < 0)
		return;
	bank = get_gpio_bank(gpio);

	_reset_gpio(bank, gpio);
}
Пример #7
0
static int check_gpio_unrequested(struct gpio_bank *bank, int index)
{
	int retval = !gpio_is_requested(bank, 1 << index);
	if (unlikely(!retval)) {
		char c = 'A' + (bank - get_gpio_bank(0));
		printk(KERN_ERR "pnx-gpio: GPIO %c%d is already requested\n",
		       c, index);
		dump_stack();
	}
	return retval;
}
Пример #8
0
/**
 * Set value of the specified gpio
 */
int gpio_set_value(unsigned gpio, int value)
{
	const struct gpio_bank *bank;

	if (check_gpio(gpio) < 0)
		return -1;
	bank = get_gpio_bank(gpio);
	_set_gpio_dataout(bank, get_gpio_index(gpio), value);

	return 0;
}
Пример #9
0
/**
 * Set gpio direction as input
 */
int gpio_direction_input(unsigned gpio)
{
	const struct gpio_bank *bank;

	if (check_gpio(gpio) < 0)
		return -1;

	bank = get_gpio_bank(gpio);
	_set_gpio_direction(bank, get_gpio_index(gpio), 1);

	return 0;
}
Пример #10
0
void omap_free_gpio(int gpio)
{
#if !defined (CONFIG_OMAP3_CE30X) && !defined (CONFIG_OMAP3_A317)
	struct gpio_bank *bank;

	if (check_gpio(gpio) < 0)
		return;
	bank = get_gpio_bank(gpio);

	_reset_gpio(bank, gpio);
#endif
}
Пример #11
0
void pnx_gpio_free(int gpio)
{
	int index;
	struct gpio_bank *bank;

	if (!check_gpio(gpio))
		return;

	index = get_gpio_index(gpio);
	bank = get_gpio_bank(gpio);
	_pnx_gpio_free(bank, index);
}
Пример #12
0
int pnx_gpio_request(int gpio)
{
	int index;
	struct gpio_bank *bank;

	if (!check_gpio(gpio))
		return -EINVAL;

	index = get_gpio_index(gpio);
	bank = get_gpio_bank(gpio);

	return _pnx_gpio_request(bank, index);
}
Пример #13
0
int omap_get_gpio_datain(int gpio)
{
	struct gpio_bank *bank;
	void *reg;

	if (check_gpio(gpio) < 0)
		return -EINVAL;
	bank = get_gpio_bank(gpio);
	reg = bank->base;
	switch (bank->method) {
	case METHOD_GPIO_24XX:
		reg += OMAP24XX_GPIO_DATAIN;
		break;
	default:
		return -EINVAL;
	}
	return (__raw_readl(reg)
			& (1 << get_gpio_index(gpio))) != 0;
}
Пример #14
0
int pnx_gpio_set_direction(int gpio, int is_input)
{
	unsigned long flags, index;
	struct gpio_bank *bank;

	if (!check_gpio(gpio))
		return -EINVAL;

	bank = get_gpio_bank(gpio);
	index = get_gpio_index(gpio);
	if (!check_gpio_requested(bank, index))
		return -EINVAL;

	spin_lock_irqsave(&bank->lock, flags);
	_set_gpio_direction(bank, index, is_input);
	spin_unlock_irqrestore(&bank->lock, flags);

	return 0;
}
Пример #15
0
int pnx_gpio_set_mode(int gpio, int mode)
{
	struct gpio_bank *bank;
	int index;

	if (!check_gpio(gpio))
		return -EINVAL;

	bank = get_gpio_bank(gpio);
	index = get_gpio_index(gpio);
	if (!check_gpio_requested(bank, index))
		return -EINVAL;

	spin_lock(&bank->lock);
	_set_gpio_mode(bank, get_gpio_index(gpio), mode);
	spin_unlock(&bank->lock);

	return 0;
}
Пример #16
0
int pnx_gpio_write_pin(int gpio, int gpio_value)
{
	struct gpio_bank *bank;
	unsigned long index;

	if (!check_gpio(gpio))
		return -EINVAL;

	bank = get_gpio_bank(gpio);
	index = get_gpio_index(gpio);
	if (!check_gpio_requested(bank, index))
		return -EINVAL;

	spin_lock(&bank->lock);
	_write_gpio_pin(bank, index, gpio_value);
	spin_unlock(&bank->lock);

	return 0;
}
Пример #17
0
int pnx_gpio_set_irq_debounce(int irq, int cycles)
{
	int gpio;
	struct gpio_bank *bank;
	void __iomem *reg;
	int mode;
	u32 l = 0;

	gpio = EXTINT_TO_GPIO(irq);
	irq -= IRQ_COUNT;
	if (!check_gpio_irq(irq))
		goto err;

	bank = get_gpio_bank(gpio);
	if (!check_gpio_requested(bank, get_gpio_index(gpio)))
		return -EINVAL;

	reg = (void __iomem*) EXTINT_CFGx(irq);
	l = __raw_readl(reg);

	mode=l&(3<<EXTINT_MODE_SHIFT);
	if ( mode==EXTINT_MODE_BYPASS )
		goto err;

	/* clear mode and set streching to debounce */
	if ( mode==EXTINT_MODE_STRETCHING ){
		l &= ~(3 << EXTINT_MODE_SHIFT);
		l |= EXTINT_MODE_DEBOUNCE;
	}
	/* clear and set the debounce field */
	l &= ~(7<<EXTINT_DEBOUNCE_SHIFT);
	l |= ((cycles & 0x7) << EXTINT_DEBOUNCE_SHIFT);
	__raw_writel(l,reg);

	return 0;
err:
	return -EINVAL;
}
Пример #18
0
static int __init pnx_gpio_probe(struct platform_device *pdev)
{
	int i,j;
	int gpio = 0;
	struct gpio_bank *bank;
	struct gpio_data *data = pdev->dev.platform_data;
	unsigned long flags;

	initialized = 1;

	printk(KERN_INFO "PNX GPIO\n");
	gpio_bank_desc = data->gpio_bank_desc;
	gpio_bank_count = data->nb_banks;

	for (i = 0; i < gpio_bank_count; i++) {
		int gpio_count = 32; /* 32 GPIO per bank */
		bank = &gpio_bank_desc[i];
		bank->reserved_map = 0; /* must always be initialized */
		spin_lock_init(&bank->lock);

		/* check if bank is managed by PNX GPIO driver */
		if ((bank->gpio_base != 0) && (bank->mux_base != 0)) {
		bank->chip.request = pnx_gpio_acquire;
		bank->chip.free = pnx_gpio_release;
		bank->chip.direction_input = gpio_input;
		bank->chip.get = gpio_get;
		bank->chip.direction_output = gpio_output;
		bank->chip.set = gpio_set;
		bank->chip.to_irq = gpio_2irq;
		bank->chip.label = "gpio";
		bank->chip.base = gpio;

		bank->chip.ngpio = gpio_count;

		gpiochip_add(&bank->chip);
		}
		gpio += gpio_count;
	}

#ifdef CONFIG_MODEM_BLACK_BOX
	/* set init value */
	printk(KERN_INFO "PNX GPIO initialize SCON\n");

	/* configure MUX and PAD settings */
	for (i = 0; i< SCON_REGISTER_NB; i++)
		__raw_writel(pnx_scon_init_config[i].scon_reg_value,
			     pnx_scon_init_config[i].scon_reg_addr);

	/* configure GPIO direction and value */
	for (i=0; i < gpio_to_configure; i++) {
		int index;

		bank = get_gpio_bank(pnx_gpio_init_config[i].gpio);
		index = get_gpio_index(pnx_gpio_init_config[i].gpio);
		_set_gpio_direction(bank, index, pnx_gpio_init_config[i].dir);
		_write_gpio_pin(bank, index, pnx_gpio_init_config[i].value);
	}

	/* reserve GPIO used by Modem */
	for (i = 0; i < pnx_modem_gpio_reserved_nb; i++) {
		int index;

		bank = get_gpio_bank(pnx_modem_gpio_reserved[i]);
		index = get_gpio_index(pnx_modem_gpio_reserved[i]);
		bank->reserved_map |= (1 << index);
	}

	/* configure EXTINT used by modem */
	for (i = 0; i< pnx_modem_extint_nb; i++)
		__raw_writel(pnx_extint_init_config[i].reg_value,
			     pnx_extint_init_config[i].reg_addr);

	printk(KERN_INFO "PNX GPIO Driver\n");
#endif

	/* for extint */
	for (j = IRQ_COUNT; j < IRQ_COUNT + NR_EXTINT; j++) {
		set_irq_chip(j, &gpio_irq_chip);
		set_irq_handler(j, handle_simple_irq);
		set_irq_flags(j, IRQF_VALID);
	}

	hw_raw_local_irq_save ( flags );
	/* mask all EXT IRQ sources before registring handler */
	/* read status */
	j = __raw_readl(EXTINT_STATUS_REG) & __raw_readl(EXTINT_ENABLE3_REG);
	/* clear IRQ source(s)*/
	__raw_writel(j, EXTINT_STATUS_REG);

	__raw_writel(0, EXTINT_ENABLE3_REG);

	/* set irq in low level */
	set_irq_type(IRQ_EXTINT3, IRQF_TRIGGER_LOW);

	/* chained GPIO-IRQ on EXTINT3 */
	set_irq_chained_handler(IRQ_EXTINT3, gpio_irq_handler);
	hw_raw_local_irq_restore ( flags );

	return 0;
}