#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define LED_MAJOR 244/*预设LED的主设备号*/
#define rGPECON (*(volatile unsigned long*)(vaddr+0x40))
#define rGPEDAT (*(volatile unsigned short *)(vaddr+0x44))
char* vaddr=NULL;
struct cdev* led_cdev=NULL;
#define SET1(X, Y) (X)|=(1<
#define SET0(X, Y) (X)&=~(1<
void gpecon_init(void)
{
/*GPE13------>LED1*/
SET1(rGPECON, 13*2);
SET0(rGPECON, 13*2+1);
/*GPE12------>LED2*/
SET1(rGPECON, 12*2);
SET0(rGPECON, 12*2+1);
/*GPE11------>LED3*/
SET1(rGPECON, 11*2);
SET0(rGPECON, 11*2+1);
/*GPE0------>LED4*/
SET1(rGPECON, 0);
SET0(rGPECON, 1);
/*GPE4------>LED5*/
SET1(rGPECON, 4*2);
SET0(rGPECON, 4*2+1);
/*GPE3------>LED6*/
SET1(rGPECON, 3*2);
SET0(rGPECON, 3*2+1);
/*GPE1------>LED7*/
SET1(rGPECON, 1*2);;
SET0(rGPECON, 1*2+1);
/*GPE2------>LED8*/
SET1(rGPECON, 2*2);
SET0(rGPECON, 2*2+1);
}
void gpedata_init(void)
{
/*LED1*/
SET1(rGPEDAT, 13);
/*LED2*/
SET1(rGPEDAT, 12);
/*LED3*/
SET1(rGPEDAT, 11);
/*LED4*/
SET1(rGPEDAT, 0);
/*LED5*/
SET1(rGPEDAT, 4);
/*LED6*/
SET1(rGPEDAT, 3);
/*LED7*/
SET1(rGPEDAT, 1);
/*LED8*/
SET1(rGPEDAT, 2);
}
void led_on(int num)
{
switch(num){
case 1:
SET0(rGPEDAT, 13);
break;
case 2:
SET0(rGPEDAT, 12);
break;
case 3:
SET0(rGPEDAT, 11);
break;
case 4:
SET0(rGPEDAT, 0);
break;
case 5:
SET0(rGPEDAT, 4);
break;
case 6:
SET0(rGPEDAT, 3);
break;
case 7:
SET0(rGPEDAT, 1);
break;
case 8:
SET0(rGPEDAT, 2);
break;
default:
printk("argumets error!/n");
break;
}
}
void led_off(int num)
{
switch(num){
case 1:
SET1(rGPEDAT, 13);
break;
case 2:
SET1(rGPEDAT, 12);
break;
case 3:
SET1(rGPEDAT, 11);
break;
case 4:
SET1(rGPEDAT, 0);
break;
case 5:
SET1(rGPEDAT, 4);
break;
case 6:
SET1(rGPEDAT, 3);
break;
case 7:
SET1(rGPEDAT, 1);
break;
case 8:
SET1(rGPEDAT, 2);
break;
default:
printk("argumets error!/n");
break;
}
}
int led_open(struct inode* inode, struct file* filp)
{
printk("open led device.../n");
return 0;
}
static int led_ioctl(struct inode* inode, struct file* filp,
unsigned int cmd, unsigned long arg)
{
if( 0==cmd )
{
led_on(arg);
}
else if( 1==cmd )
{
led_off(arg);
}
return 0;
}
static int led_release(struct inode *inode,struct file *file)
{
gpedata_init();
printk("device close!!!/n");
return 0;
}
struct file_operations led_fops={
owner:THIS_MODULE,
release:led_release,
open:led_open,
ioctl:led_ioctl
};
static int __init led_init(void)
{
int result;
dev_t devno=MKDEV(LED_MAJOR, 0);
result=register_chrdev_region(devno, 1, "led");
if( result<0 )
{
printk("init error!/n");
return result;
}
vaddr=ioremap(0x56000000, 0x100);
gpecon_init();
gpedata_init();
led_cdev=cdev_alloc();
cdev_init(led_cdev, &led_fops);
led_cdev->owner=THIS_MODULE;
led_cdev->ops=&led_fops;
result=cdev_add(led_cdev, devno, 1);
if( result<0 )
{
printk("cdev_add Error/n");
}
printk("init success!/n");
return 0;
}
static void __exit led_exit(void)
{
iounmap(vaddr);
cdev_del(led_cdev);
unregister_chrdev_region(MKDEV(LED_MAJOR, 0), 1);
printk("exit/n");
}
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Peng Li");
module_init(led_init);
module_exit(led_exit);