How to use mpc8xxx_gpio.c device driver
Ravi Gupta
dceravigupta at gmail.com
Wed Aug 18 22:45:02 EST 2010
Hi,
Thanks for all your replies. Now I want to enable interrupts on some GPIO
pins(GPIO pins number 224, 225, 226, 227, 228 and 229 i.e gpiochip224's pins
0 to 5). I configured these pins as input(GPIOF_IN) during gpio request. I
am able to request gpio pins successfully.
#define GPIO_CHIP0_BASE 192
#define GPIO_CHIP0_COUNT 32
#define GPIO_CHIP1_BASE 224
#define GPIO_CHIP1_COUNT 32
#define GPIO(chip, pin) (GPIO_CHIP##chip##_BASE + (pin))
/* Initial GPIO pins setting. */
static struct gpio gpio_pins[] = {
{ GPIO(1, 0), GPIOF_IN, "Chip 1, Pin 0" },
{ GPIO(1, 1), GPIOF_IN, "Chip 1, Pin 1" },
{ GPIO(1, 2), GPIOF_IN, "Chip 1, Pin 2" },
{ GPIO(1, 3), GPIOF_IN, "Chip 1, Pin 3" },
{ GPIO(1, 4), GPIOF_IN, "Chip 1, Pin 4" },
{ GPIO(1, 5), GPIOF_IN, "Chip 1, Pin 5" },
};
static __init int gpio_module_init(void)
{
int err;
dev_t devno = 0;
printk(KERN_INFO "GPIO Driver Version 0.1\n");
/* resuest the gpio pin */
err = gpio_request_array(gpio_pins, ARRAY_SIZE(gpio_pins));
if (err) {
printk(KERN_WARNING "gpio: unable to request gpio pins\n");
return -EBUSY;
}
/* register interrupts handlers */
err = gpio_request_irq_array(gpio_irq_pins, ARRAY_SIZE(gpio_irq_pins));
if (err) {
printk(KERN_WARNING "gpio: unable to register interrupt handler.\n");
goto interrupt_fail;
}
.
.
.
}
Now in order to enable interrupts I have to set the bits corresponding to
these pins in gpiochp Interrupt Mask Register.
My first question is that is there any gpio API call available for doing
this? OR I have to manually memory map the gpio IMR register and set bit
manually? For the time being I have manually set the IMR bit(using memory
map).
Second, in order to register an interrupt handler on a gpio pin, I need a
IRQ number, so how am I going to get that number? From the
Documentation/gpio.txt, it looks to me that gpio_to_irq() function should
give me the irq number, but when I tried to use it, it gives me an error.
#define GPIO_CHIP0_BASE 192
#define GPIO_CHIP0_COUNT 32
#define GPIO_CHIP1_BASE 224
#define GPIO_CHIP1_COUNT 32
#define GPIO(chip, pin) (GPIO_CHIP##chip##_BASE + (pin))
static struct gpio_irq gpio_irq_pins[] = {
{ GPIO(1, 0), IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW },
{ GPIO(1, 1), IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW },
{ GPIO(1, 2), IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW },
{ GPIO(1, 3), IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW },
{ GPIO(1, 4), IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW },
{ GPIO(1, 5), IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW },
};
int gpio_request_irq_array(struct gpio_irq *array, size_t num)
{
int i, err, irq;
for (i = 0; i < num; i++, array++) {
/* get the irq number corresponding to the gpio pin */
irq = gpio_to_irq(array->gpio);
if (irq < 0) {
printk(KERN_ERR "gpio: Trying to get irq number for GPIO%d\n",
array->gpio);
err = -EINVAL;
goto err_free;
}
printd("gpio: irq number for GPIO%d = %d(i=%d)\n", array->gpio, irq, i);
/* set the irq type for the gpio pin */
err = set_irq_type(irq, array->type);
if (err)
goto err_free;
/* register irq handler */
err = request_irq(irq, gpio_irq_handler, IRQF_SHARED, "GPIO Driver",
NULL);
if (err) {
printk(KERN_ERR "gpio: can't get assigned irq for GPIO%d\n",
array->gpio);
goto err_free;
}
}
return 0;
err_free:
while (i--)
free_irq(gpio_to_irq((--array)->gpio), NULL);
return err;
}
Given above is my driver code, I have implemented a function named
"gpio_request_irq_array" which works in same manner as that of
"gpio_request_array". I am calling in the init function, see the init code
given initially. Now when I load it on my MPC837xERDB board, it gives the
following errors.
[ 1812.776420] GPIO Driver Version 0.1
[ 1812.779985] gpio: Trying to get irq number for GPIO224
[ 1812.785126] gpio: unable to register interrupt handler.
insmod: error inserting './gpio.ko': -1 Invalid parameters
Thanks in advance
Ravi Gupta
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.ozlabs.org/pipermail/linuxppc-dev/attachments/20100818/e473b34e/attachment.html>
More information about the Linuxppc-dev
mailing list