Skip to content

Instantly share code, notes, and snippets.

@17twenty
Created May 22, 2012 14:25
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 17twenty/2769392 to your computer and use it in GitHub Desktop.
Save 17twenty/2769392 to your computer and use it in GitHub Desktop.
GPIO1_7 interrupt driven
#include <linux/module.h> /* Needed by all modules */
#include <linux/kernel.h> /* Needed for KERN_INFO */
#include <linux/init.h> /* Needed for the macros */
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <plat/gpio.h>
#include <asm/gpio.h>
#include <plat/am33xx.h>
#include <asm/io.h>
#define DEVICE_NAME "led_drv"
#define GPIO1_7 39 /* (chip_num * 32) + pin */
#define PIN_POS 7
#define AM33XX_CONTROL_PADCONF_MUX_PBASE 0x44E10000LU
static __iomem unsigned char *gpio1_start;
static __iomem unsigned char *control_module_start;
static irqreturn_t hello_irq_handler (int irq, void *dev_id)
{
printk (KERN_INFO "INTERRUPT!\n");
return IRQ_HANDLED;
}
static int __init hello_start(void)
{
int ret;
unsigned int value;
unsigned long flags = 0;
printk(KERN_INFO "Hello world\n");
/* Get access to the GPIO */
request_mem_region (AM33XX_GPIO1_BASE, 0x1000, DEVICE_NAME);
/* Map io memory */
gpio1_start = ioremap(AM33XX_GPIO1_BASE, 0x1000);
if (gpio1_start == NULL)
{
printk (KERN_INFO "Cannot map GPIO memory\n");
return -EIO;
}
/* Get access to the Control Module */
request_mem_region (AM33XX_CONTROL_PADCONF_MUX_PBASE, 0x1000, DEVICE_NAME);
/* Map io memory */
control_module_start = ioremap(AM33XX_CONTROL_PADCONF_MUX_PBASE, 0x1000);
if (control_module_start == NULL)
{
printk (KERN_INFO "Cannot map control module memory\n");
return -EIO;
}
{
/* Configure the GPIO to be an input */
local_irq_save(flags);
value = __raw_readl(gpio1_start + OMAP4_GPIO_OE);
value |= 1 << PIN_POS;
__raw_writel(value, gpio1_start + OMAP4_GPIO_OE);
value = __raw_readl(gpio1_start + OMAP4_GPIO_SETDATAOUT);
value |= 1 << PIN_POS;
__raw_writel(value, gpio1_start + OMAP4_GPIO_SETDATAOUT);
local_irq_restore(flags);
}
{
/* Set the control module pad stuff - gpmc_ad7 is at OFFSET 0x81c */
/*
Bit Field Type Reset Description
31-20 Reserved R 0x0
19-7 Reserved R 0x0
6 conf_sle R/W 0x0 Select between faster or slower slew rate
0: Fast
1: Slow
Reset value is pad-dependent.
5 conf_rx R/W 0x1 Input Enable value for pad
0: rx disabled
1: rx enabled
4 conf_putypesel R/W 0x0 Pad pullup/pulldown type selection
0: Pulldown
1: Pullup
Reset value is pad-dependent.
3 conf_puden R/W 0x0 Pad pullup/pulldown enable
0: Pullup/Pulldown enabled
1: Pullup/Pulldown disabled
Reset value is pad-dependent.
2-0 conf_m_mode R/W 0x0 Pad functional signal mux select
Reset value is pad-dependent.
*/
/* If we were being a good citizen, we'd restore this =) */
local_irq_save(flags);
__raw_writel(0x27, control_module_start + 0x81c);
value = __raw_readl(control_module_start + 0x81c);
local_irq_restore(flags);
}
if (0x27 != value)
{
printk (KERN_INFO "Couldn't set value, expected 0x27 but got 0x%x - " \
"Exiting\n", value);
iounmap(gpio1_start);
release_mem_region(AM33XX_GPIO1_BASE, 0x1000);
iounmap(control_module_start);
release_mem_region(AM33XX_CONTROL_PADCONF_MUX_PBASE, 0x1000);
return -EIO;
}
/* Get the IRQ value */
ret = gpio_to_irq(GPIO1_7);
/* Install interrupt handler */
ret = request_irq(ret, hello_irq_handler, IRQF_TRIGGER_RISING,
"hello-int", NULL);
if (ret != 0 )
{
printk (KERN_INFO "Error: request_irq returned %d\n", ret);
return -EIO;
}
return 0;
}
static void __exit hello_end(void)
{
free_irq (gpio_to_irq(GPIO1_7), NULL);
iounmap (gpio1_start);
release_mem_region (AM33XX_GPIO1_BASE, 0x1000);
iounmap (control_module_start);
release_mem_region (AM33XX_CONTROL_PADCONF_MUX_PBASE, 0x1000);
printk(KERN_INFO "Goodbye World\n");
}
module_init(hello_start);
module_exit(hello_end);
MODULE_AUTHOR("Nick Glynn <nick.glynn@feabhas.com>");
MODULE_LICENSE("GPL");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment