#include <linux/module.h>
#include <linux/fs.h>#include <linux/string.h>#include <linux/init.h>#include <linux/miscdevice.h>#include <linux/platform_device.h>#include <linux/interrupt.h>#include <linux/rtc.h>#include <linux/bcd.h>#include <linux/clk.h>#include <linux/log2.h>#include <linux/slab.h>#include <linux/rtc.h>#include <linux/ioport.h>#include <linux/delay.h>#include <mach/hardware.h>
#include <asm/uaccess.h>#include <asm/io.h>#include <asm/irq.h>#include <plat/regs-rtc.h>#include <plat/devs.h>#include <mach/map.h>struct resource *yzh_rtc_mem;
struct clk *rtc_clk;//struct rtc_device *rtc; struct rtc_time rtc_test;static void __iomem *rtc_reg_base;
//(*(volatile unsigned long *)#define rtc_reg(x) (rtc_reg_base + x)int yzh_rtc_open(struct device *dev)
{ int temp = 0;temp = readb(rtc_reg(S3C2410_RTCCON));
temp |= S3C2410_RTCCON_RTCEN; writeb(temp,rtc_reg(S3C2410_RTCCON));temp = readb(rtc_reg(S3C2410_RTCCON));
temp &= ~(S3C2410_RTCCON_CNTSEL); writeb(temp,rtc_reg(S3C2410_RTCCON));temp = readb(rtc_reg(S3C2410_RTCCON));
temp &= ~(S3C2410_RTCCON_CLKRST); writeb(temp,rtc_reg(S3C2410_RTCCON));temp = readb(rtc_reg(S3C2410_RTCCON));
temp |= S3C64XX_RTCCON_TICEN; writeb(temp,rtc_reg(S3C2410_RTCCON));temp = readb(rtc_reg(S3C2410_RTCCON));
temp |= 0 << 4; writeb(temp,rtc_reg(S3C2410_RTCCON));printk("yzh rtc is open \n\r");
return 0;
} static void yzh_rtc_release(struct device *dev){ int temp = 0; temp = readb(rtc_reg(S3C2410_RTCCON)); temp &= ~S3C2410_RTCCON_RTCEN; writeb(temp,rtc_reg(S3C2410_RTCCON)); //stop RTCtemp = readb(rtc_reg(S3C2410_RTCCON));
temp &= ~S3C64XX_RTCCON_TICEN; writeb(temp,rtc_reg(S3C2410_RTCCON)); printk("the yzh rtc release \n\r");}int yzh_rtc_set_time(struct device *dev, struct rtc_time *rtc_set)
{ //set time: 2013-11-22 23:59:30rtc_set -> tm_sec = 30;
rtc_set -> tm_min = 59; rtc_set -> tm_hour = 23; rtc_set -> tm_mday = 22; rtc_set -> tm_mon = 11;// rtc_set -> tm_year += 113; rtc_set -> tm_year = 0;writeb(bin2bcd(rtc_set -> tm_sec),rtc_reg(S3C2410_RTCSEC));
writeb(bin2bcd(rtc_set -> tm_min),rtc_reg(S3C2410_RTCMIN)); writeb(bin2bcd(rtc_set -> tm_hour),rtc_reg(S3C2410_RTCHOUR)); writeb(bin2bcd(rtc_set -> tm_mday),rtc_reg(S3C2410_RTCDAY)); writeb(bin2bcd(rtc_set -> tm_mon),rtc_reg(S3C2410_RTCMON)); writeb(bin2bcd(rtc_set -> tm_year),rtc_reg(S3C2410_RTCYEAR));printk("time has seted \n\r");
return 0;}int yzh_rtc_read_time(struct device *dev, struct rtc_time *read_time)
{ read_time -> tm_sec = bcd2bin(readb(rtc_reg(S3C2410_RTCSEC))); read_time -> tm_min = bcd2bin(readb(rtc_reg(S3C2410_RTCMIN))); read_time -> tm_hour = bcd2bin(readb(rtc_reg(S3C2410_RTCHOUR))); read_time -> tm_mday = bcd2bin(readb(rtc_reg(S3C2410_RTCDAY))); read_time -> tm_mon = bcd2bin(readb(rtc_reg(S3C2410_RTCMON))); read_time -> tm_year = bcd2bin(readb(rtc_reg(S3C2410_RTCYEAR)));printk("time:%d-%d-%d %d:%d:%d \n\r",read_time -> tm_year,read_time -> tm_mon,read_time -> tm_mday,read_time -> tm_hour,read_time -> tm_min,read_time -> tm_sec);
return 0;}struct rtc_class_ops yzh_rtc_ops = {
.open = yzh_rtc_open, .release = yzh_rtc_release, .set_time = yzh_rtc_set_time, .read_time = yzh_rtc_read_time,// .proc = , };static void yzh_rtc_test(void)
{ int i; yzh_rtc_open(NULL); yzh_rtc_set_time(NULL,&rtc_test); for(i=0;i<50;i++) { yzh_rtc_read_time(NULL,&rtc_test); mdelay(500);mdelay(500); }}int yzh_rtc_probe(struct platform_device *pdev)
{ struct resource *res;/* yzh_systick_irq = platform_get_irq(pdev,1);
if(yzh_systick_irq < 0) { printk("yzh_systick_irq is fail \n\r"); return 0; }*/res = platform_get_resource(pdev,IORESOURCE_MEM,0);
if(res == NULL) { printk("res resource fail \n\r"); return 0; }yzh_rtc_mem = request_mem_region(res -> start,res -> end - res -> start + 1, pdev -> name);
if(yzh_rtc_mem == NULL) { printk("yzh_rtc_mem fail \n\r"); return 0; }rtc_reg_base = ioremap(res -> start,res -> end - res -> start + 1);
if(rtc_reg_base == NULL) { printk("rtc_reg_base iomem has fail \n\r"); return 0; } rtc_clk = clk_get(&pdev -> dev,"yzh_rtc_clk"); if(rtc_clk == NULL) { printk("rtc_clk is not get \n\r"); return 0; }clk_enable(rtc_clk);
// rtc = rtc_device_register("yzh_rtc_device",&pdev -> dev,&yzh_rtc_ops,THIS_MODULE);return 0;
}int yzh_rtc_remove(struct platform_device *pdev)
{ // rtc_device_unregister(rtc);// clk_disable(rtc_clk);
// clk_put(rtc_clk);// rtc_clk = NULL;iounmap(rtc_reg_base);
release_resource(yzh_rtc_mem); kfree(yzh_rtc_mem);printk("yzh_rtc_remove \n\r");
return 0;}/*struct platform_device_id yzh_rtc_ids[] = {
{ .name = "s3c64xx-rtc", },{},};MODULE_DEVICE_TABLE(platform, yzh_rtc_ids);*/
static struct platform_driver s3c_rtc_driver = {
.probe = yzh_rtc_probe, .remove = yzh_rtc_remove,// .id_table = yzh_rtc_ids, .driver = { .name = "s3c64xx-rtc", .owner = THIS_MODULE, },};static int rtc_init(void)
{ int ret; ret = platform_driver_register(&s3c_rtc_driver); yzh_rtc_test(); printk("the rtc module has install \n\r"); return ret;}static void rtc_exit(void)
{ platform_driver_unregister(&s3c_rtc_driver); printk("the rtc module has uninstall \n\r"); }module_init(rtc_init);
module_exit(rtc_exit);MODULE_LICENSE("GPL");