Created
May 22, 2012 14:25
-
-
Save 17twenty/2769392 to your computer and use it in GitHub Desktop.
GPIO1_7 interrupt driven
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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