#include <linux/fs.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/cdev.h>
#include <linux/ioport.h>
#include <linux/pci.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <linux/interrupt.h>
#include <asm/mach/irq.h>
#include <asm/arch/regs-gpio.h>
#include <linux/poll.h>
#include <linux/platform_device.h>
#include <asm/irq.h>
#define BCDTODEC(val) ((val/16)*10+(val%16))
#define DECTOBCD(val) ((val/10)*16+(val%10))
static unsigned int fs2410_rtc_major =0;
static struct class *fs2410_rtc_class =NULL;
static volatile unsigned long *rtccon =NULL;
static volatile unsigned long *ticnt =NULL;
static volatile unsigned long *rtcrst=NULL;
static volatile unsigned long *bcdsec=NULL;
static volatile unsigned long *bcdmin=NULL;
static volatile unsigned long *bcdhour=NULL;
static volatile unsigned long *bcdday=NULL;
static volatile unsigned long *bcdweek=NULL;
static volatile unsigned long *bcdmon=NULL;
static volatile unsigned long *bcdyear=NULL;
static volatile unsigned long *rtcalm=NULL;
static volatile unsigned long *almsec=NULL;
static volatile unsigned long *almmin=NULL;
static volatile unsigned long *almhour=NULL;
static volatile unsigned long *almday=NULL;
static volatile unsigned long *almmon=NULL;
static volatile unsigned long *almyear=NULL;
static struct rtc_time{
int type;
unsigned int sec;
unsigned int min;
unsigned int hour;
unsigned int day;
unsigned int week;
unsigned int mon;
unsigned int year;
unsigned int alarm_sec;
unsigned int alarm_min;
unsigned int alarm_hour;
unsigned int alarm_day;
unsigned int alarm_mon;
unsigned int alarm_year;
};
static irqreturn_t rtc_irq_handle(int irq, void *dev_id)
{
printk("rtc alrm!\n");
*rtcalm = 0x0;
return IRQ_HANDLED;
}
static int fs2410_rtc_open(struct inode *inode, struct file *file)
{
*rtccon |= (1<<0);
int ret =request_irq(IRQ_RTC, rtc_irq_handle, IRQF_TRIGGER_FALLING,"rtc_alarm",NULL);
return 0;
}
static ssize_t fs2410_rtc_write(struct file *file, const char __user *buf, size_t count, loff_t *opps)
{
int ret;
struct rtc_time set_rtc_buf;
ret = copy_from_user(&set_rtc_buf,buf, count);
if(set_rtc_buf.type == 0)
{
*rtccon =0x5;
*ticnt = 0xff;
*rtcrst = 0xd;
*bcdsec = DECTOBCD(set_rtc_buf.sec);
*bcdmin = DECTOBCD(set_rtc_buf.min);
*bcdhour= DECTOBCD(set_rtc_buf.hour);
*bcdday = DECTOBCD(set_rtc_buf.day);
*bcdweek= DECTOBCD(set_rtc_buf.week);
*bcdmon= DECTOBCD(set_rtc_buf.mon);
*bcdyear= DECTOBCD(set_rtc_buf.year);
*rtccon = 0x0;
}
*rtcalm = 0xff;
*almsec = DECTOBCD(set_rtc_buf.alarm_sec);
*almmin = DECTOBCD(set_rtc_buf.alarm_min);
*almhour= DECTOBCD(set_rtc_buf.alarm_hour);
*almday= DECTOBCD(set_rtc_buf.alarm_day);
*almmon = DECTOBCD(set_rtc_buf.alarm_mon);
*almyear= DECTOBCD(set_rtc_buf.alarm_year);
return 0;
}
static ssize_t fs2410_rtc_read(struct file *file, char __user *buf, size_t count, loff_t *opps)
{
static struct rtc_time val;
val.sec=BCDTODEC(*bcdsec);
val.min=BCDTODEC(*bcdmin);;
val.hour=BCDTODEC(*bcdhour);;
val.day=BCDTODEC(*bcdday);
val.week=BCDTODEC(*bcdweek);
val.mon=BCDTODEC(*bcdmon);
val.year =BCDTODEC(*bcdyear)+1920;
//*rtccon = 0x0;
copy_to_user(buf, &val, count);
return 0;
}
struct file_operations fs2410_rtc_fops ={
.owner =THIS_MODULE,
.open =fs2410_rtc_open,
.read =fs2410_rtc_read,
.write =fs2410_rtc_write,
};
int fs2410_rtc_probe(struct platform_device *pdev)
{
struct resource *res;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
rtccon = ioremap(res->start, res->end -res->start);
ticnt = rtccon+1;
rtcalm = rtccon + 4;
almsec = rtccon + 5;
almmin = rtccon + 6;
almhour = rtccon +7;
almday= rtccon +8;
almmon = rtccon +9;
almyear = rtccon +10;
rtcrst = rtccon+11;
bcdsec = rtccon+12;
bcdmin = rtccon+13;
bcdhour = rtccon+14;
bcdday = rtccon+15;
bcdweek = rtccon+16;
bcdmon = rtccon+17;
bcdyear = rtccon+18;
fs2410_rtc_major =register_chrdev(0, "rtcs",&fs2410_rtc_fops);
fs2410_rtc_class =class_create(THIS_MODULE, "rtc_class");
class_device_create(fs2410_rtc_class, NULL,MKDEV(fs2410_rtc_major, 0), NULL, "rtc");
return 0;
}
int fs2410_rtc_remove(struct platform_device *pdev)
{
unregister_chrdev(fs2410_rtc_major, "rtcs");
class_device_destroy(fs2410_rtc_class, MKDEV(fs2410_rtc_major, 0));
class_destroy(fs2410_rtc_class);
iounmap(rtccon);
return 0;
}
struct platform_driver fs2410_rtc_driver ={
.probe =fs2410_rtc_probe,
.remove =fs2410_rtc_remove,
.driver ={
.owner =THIS_MODULE,
.name ="fs2410-rtc",
},
};
static int __init fs2410_rtc_drv_init(void)
{
platform_driver_register(&fs2410_rtc_driver);
return 0;
}
static void __exit fs2410_rtc_drv_exit(void)
{
platform_driver_unregister(&fs2410_rtc_driver);
}
module_init(fs2410_rtc_drv_init);
module_exit(fs2410_rtc_drv_exit);
MODULE_LICENSE("GPL");
评论0
最新资源