#include<linux/init.h>
#include<linux/module.h>
#include<linux/fs.h>
#include <linux/cdev.h>
#include <asm/uaccess.h>
#include <linux/errno.h>
#include <linux/fcntl.h>
#include <linux/delay.h>
#include <linux/proc_fs.h>
#include <linux/workqueue.h>
#include <linux/device.h>
#include <linux/miscdevice.h>
#include <linux/vmalloc.h>
#include <linux/io.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/cache.h>
#include "led.h"
#define DEVICE_NAME "ledmsic"
void __iomem* reg_gpio_base_va = 0;
#define SUDA_ERR(x,arg...) \
do { \
printk(KERN_ALERT "%s->%d: ", __FUNCTION__, __LINE__); \
printk(KERN_ALERT x,##arg); \
printk(KERN_ALERT "\n"); \
} while (0)
#define HI_IO_GPIO_ADDRESS(x) (reg_gpio_base_va + ((x)-(GPIO_ADRESS_BASE)))
#define GPIO_ADRESS_BASE 0x12140000
#define GPIO_CTRL_ADRESS_BASE 0x12040000
/*
R: GPIO1_0
G: GPIO1_1
B: GPIO5_7
*/
#define GPIO1_REG0 HI_IO_GPIO_ADDRESS(GPIO_ADRESS_BASE+(1<<12)+0x004) //红
#define GPIO1_REG1 HI_IO_GPIO_ADDRESS(GPIO_ADRESS_BASE+(1<<12)+0x008)//绿
#define GPIO5_REG7 HI_IO_GPIO_ADDRESS(GPIO_ADRESS_BASE+(0x5000)+0x200)//蓝
#define GPIO1_CTRL_REG0 HI_IO_GPIO_ADDRESS(GPIO_CTRL_ADRESS_BASE)
#define GPIO1_CTRL_REG1 HI_IO_GPIO_ADDRESS(GPIO_CTRL_ADRESS_BASE+0x0004)
#define GPIO5_CTRL_REG7 HI_IO_GPIO_ADDRESS(GPIO_CTRL_ADRESS_BASE+0x00A4)
#define GPIO1_DIR0 HI_IO_GPIO_ADDRESS(GPIO_ADRESS_BASE+(1<<12)+0x400)
#define GPIO1_DIR1 HI_IO_GPIO_ADDRESS(GPIO_ADRESS_BASE+(1<<12)+0x400)
#define GPIO5_DIR7 HI_IO_GPIO_ADDRESS(GPIO_ADRESS_BASE+(0x5000)+0x400)
#define GPIO_SET(g,r) ((*(volatile unsigned int *)g) |= (1<<(r)))
#define GPIO_RST(g,r) ((*(volatile unsigned int *)g) &= ~(1<<(r)))
#define GPIO_WRITE_REG(Addr, Value) ((*(volatile unsigned int *)(Addr))=(Value))
#define GPIO_READ_REG(Addr) (*(volatile unsigned int *)(Addr))
void flicker(void)
{
int i;
for(i=0;i<10;i++)
{
printk("start flicker");
GPIO_SET(GPIO1_REG0,0);
msleep(1000);
GPIO_RST(GPIO1_REG0,0);
GPIO_SET(GPIO1_REG1,1);
msleep(1000);
GPIO_RST(GPIO1_REG1,1);
GPIO_SET(GPIO5_REG7,7);
msleep(1000);
GPIO_RST(GPIO5_REG7,7);
GPIO_SET(GPIO1_REG0,0);
GPIO_SET(GPIO1_REG1,1);
msleep(1000);
GPIO_RST(GPIO1_REG0,0);
GPIO_RST(GPIO1_REG1,1);
GPIO_SET(GPIO1_REG0,0);
GPIO_SET(GPIO5_REG7,7);
msleep(1000);
GPIO_RST(GPIO1_REG0,0);
GPIO_RST(GPIO5_REG7,7);
GPIO_SET(GPIO5_REG7,7);
GPIO_SET(GPIO1_REG1,1);
msleep(1000);
GPIO_RST(GPIO5_REG7,7);
GPIO_RST(GPIO1_REG1,1);
GPIO_SET(GPIO5_REG7,7);
GPIO_SET(GPIO1_REG1,1);
GPIO_SET(GPIO1_REG0,0);
msleep(1000);
GPIO_RST(GPIO1_REG0,0);
GPIO_RST(GPIO1_REG1,1);
GPIO_RST(GPIO5_REG7,7);
}
}
int cdd_open(struct inode*inode,struct file *filp)
{
printk("enter cdd_open!\n");
return 0;
}
long cdd_ioctl(struct file* file, unsigned int cmd, unsigned long arg)
{
printk("cmd=0x%08x\n",cmd);
printk("arg=%lu\n",arg);
GPIO_RST(GPIO1_REG0,0);
GPIO_RST(GPIO1_REG1,1);
GPIO_RST(GPIO5_REG7,7);
switch (cmd)
{
case RGBLED_SET_ON:
{
printk("RGBLED_SET_ON\n");
if(arg==0)
/*设置输出值*/
GPIO_SET(GPIO1_REG0,0);
if(arg==1)
GPIO_SET(GPIO1_REG1,1);
if(arg==2)
GPIO_SET(GPIO5_REG7,7);
if(arg==3)
{
GPIO_SET(GPIO1_REG0,0);
GPIO_SET(GPIO1_REG1,1);
}
if(arg==4)
{
GPIO_SET(GPIO1_REG0,0);
GPIO_SET(GPIO5_REG7,7);
}
if(arg==5)
{
GPIO_SET(GPIO1_REG1,1);
GPIO_SET(GPIO5_REG7,7);
}
if(arg==6)
{
GPIO_SET(GPIO1_REG0,0);
GPIO_SET(GPIO1_REG1,1);
GPIO_SET(GPIO5_REG7,7);
}
if(arg==7)//交替闪烁
{
flicker();
}
break;
}
case RGBLED_SET_OFF:
{
printk("RGBLED_SET_OFF\n");
GPIO_RST(GPIO1_REG0,0);
GPIO_RST(GPIO1_REG1,1);
GPIO_RST(GPIO5_REG7,7);
break;
}
}
return 0;
}
static struct file_operations cdd_fops =
{
.owner= THIS_MODULE,
.open=cdd_open,
.unlocked_ioctl= cdd_ioctl,
};
static struct miscdevice cdd_dev =
{
.minor=MISC_DYNAMIC_MINOR,
.name=DEVICE_NAME,
.fops=&cdd_fops,
};
int __init cdd_init(void)
{
int ret=0;
reg_gpio_base_va=ioremap(GPIO_ADRESS_BASE,0x10000);
ret=misc_register(&cdd_dev);
if(ret<0)
{
SUDA_ERR("register failed\n");
}
/*设置管脚复用 */
ret=GPIO_WRITE_REG(GPIO1_CTRL_REG0,0);
ret=GPIO_WRITE_REG(GPIO1_CTRL_REG1,0);
ret=GPIO_WRITE_REG(GPIO5_CTRL_REG7,0);
/*设置为输出*/
ret=GPIO_SET(GPIO1_DIR0,0);
ret=GPIO_SET(GPIO1_DIR1,1);
ret=GPIO_SET(GPIO5_DIR7,7);
return 0;
}
void __exit cdd_exit(void)
{
iounmap(reg_gpio_base_va);
misc_deregister(&cdd_dev);
}
module_init(cdd_init);
module_exit(cdd_exit);
MODULE_LICENSE("GPL");