您的位置:首页 > 编程语言

ARM11 paltform驱动代码完成,最简单的测试直接在装载设备中运行,实现秒读

2013-12-11 10:39 555 查看
#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 RTC

temp = 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:30

rtc_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");
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐