/*
* PB18_IRQTest.c
* This is a test program for sam9260, using PB19(J5_18 pin) input a signal to PB18(J5_16 pin),
* PB18 receive this signal as IRQ and make the LED linking on PB17((J5_14 pin)) turn on or turn off
*
* @Author: Cun Tian Rui
* @Date :March.18.2011
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
void led_on()
{
at91_set_gpio_output(AT91_PIN_PB17,1);
}
void led_off()
{
at91_set_gpio_output(AT91_PIN_PB17 ,0);
}
struct light_dev *light_devp;
int light_major = 200;
struct light_dev
{
struct cdev cdev;
unsigned char value;
};
MODULE_AUTHOR("Cun Tian Rui");
MODULE_LICENSE("Dual BSD/GPL");
static void io_init(void)
{
at91_set_gpio_input(AT91_PIN_PB18, 1);
at91_set_deglitch(AT91_PIN_PB18, 1);
at91_sys_write(1 + PIO_IDR, 1<<18);
at91_sys_write(1 + PIO_IER, (~(1<<18)));
at91_sys_write(AT91_PMC_PCER, 1 <
}
struct gpio_irq_desc
{
int irq;
unsigned long flags;
char *name;
};
static struct gpio_irq_desc PB18_IRQ={AT91_PIN_PB18,AT91_AIC_SRCTYPE_LOW,"PB18"};
static irqreturn_t PB18_intHandle(int irq, void *dev_id)
{
led_on();
return IRQ_RETVAL(IRQ_HANDLED);
}
int light_open(struct inode *inode,struct file *filp)
{
int err;
struct light_dev *dev;
dev = container_of(inode->i_cdev,struct light_dev,cdev);
filp->private_data = dev;
io_init();
err = request_irq(PB18_IRQ.irq,PB18_intHandle,PB18_IRQ.flags,PB18_IRQ.name,(void*)0);
if(err)
{
free_irq(PB18_IRQ.irq,(void*)0);
return -EBUSY;
}
return 0;
}
int light_release(struct inode *inode,struct file *filp)
{
free_irq(PB18_IRQ.irq,(void*)0);
return 0;
}
// ioctl
int light_ioctl(struct inode *inode,struct file *filp,unsigned int cmd,
unsigned long arg)
{
struct light_dev *dev = filp->private_data;
switch(cmd)
{
case 0:
at91_set_gpio_output(AT91_PIN_PB19,0);
break;
case 1:
at91_set_gpio_output(AT91_PIN_PB19,1);
led_off();
break;
default:
return -ENOTTY;
// break;
}
return 0;
}
struct file_operations light_fops =
{
.owner = THIS_MODULE,
.ioctl = light_ioctl,
.open = light_open,
.release = light_release,
};
static void light_setup_cdev(struct light_dev *dev,int index)
{
int err,devno = MKDEV(light_major,index);
cdev_init(&dev->cdev,&light_fops);
dev->cdev.owner = THIS_MODULE;
dev->cdev.ops = &light_fops;
err = cdev_add(&dev->cdev,devno,1);
if(err)
{
printk(KERN_NOTICE "Error %d adding LED%d",err,index);
}
}
int light_init(void)
{
int result;
dev_t dev = MKDEV(light_major,0);
if(light_major)
{
result = register_chrdev_region(dev,1,"PB18_IRQTest");
}
if(result
{
return result;
}
light_devp = kmalloc(sizeof(struct light_dev),GFP_KERNEL);
if(!light_devp)
{
result = - ENOMEM;
goto fail_malloc;
}
memset(light_devp,0,sizeof(struct light_dev));
light_setup_cdev(light_devp,0);
return 0;
fail_malloc:unregister_chrdev_region(dev,light_devp);
return result;
}
void light_cleanup(void)
{
cdev_del(&light_devp->cdev);
kfree(light_devp);
unregister_chrdev_region(MKDEV(light_major,0),1);
}
module_init(light_init);
module_exit(light_cleanup);