ARM-Linux驱动--RTC(实时时钟)驱动分析
时间:11-20
来源:互联网
点击:
- _RTCCON_RTCEN,base+S3C2410_RTCCON);
- }
- if((readb(base+S3C2410_RTCCON)&S3C2410_RTCCON_CNTSEL)){
- dev_info(&pdev->dev,"removingRTCCON_CNTSEL\n");
- tmp=readb(base+S3C2410_RTCCON);
- writeb(tmp&~S3C2410_RTCCON_CNTSEL,base+S3C2410_RTCCON);//设置RTCCON第2位为0,设置BCD计数为混合BCD计数
- }
- if((readb(base+S3C2410_RTCCON)&S3C2410_RTCCON_CLKRST)){
- dev_info(&pdev->dev,"removingRTCCON_CLKRST\n");
- tmp=readb(base+S3C2410_RTCCON);
- writeb(tmp&~S3C2410_RTCCON_CLKRST,base+S3C2410_RTCCON);//RTC时钟计数器复位
- }
- }
- }
[cpp]view plaincopy
- staticints3c_rtc_setfreq(structdevice*dev,intfreq)//设定节拍时间计数值
- {
- unsignedinttmp;
- spin_lock_irq(&s3c_rtc_pie_lock);//获取自旋锁,对资源互斥访问
- tmp=readb(s3c_rtc_base+S3C2410_TICNT)&S3C2410_TICNT_ENABLE;//节拍时间使能有效
- tmp|=(128/freq)-1;
- writeb(tmp,s3c_rtc_base+S3C2410_TICNT);
- spin_unlock_irq(&s3c_rtc_pie_lock);//解锁
- return0;
- }
下面是rtc_class_ops是RTC设备类在RTC驱动核心部分中定义的对RTC设备类进行操作的结构体,类似字符设备在驱动中的file_operations对字符设备进行操作的意思。该结构体被定义在rtc.h中,对RTC的操作主要有打开、关闭、设置或获取时间、设置或获取报警、设置节拍时间计数值等等,该结构体内接口函数的实现都在下面
- staticconststructrtc_class_opss3c_rtcops={
- .open=s3c_rtc_open,
- .release=s3c_rtc_release,
- .read_time=s3c_rtc_gettime,
- .set_time=s3c_rtc_settime,
- .irq_set_freq=s3c_rtc_setfreq,
- .irq_set_state=s3c_rtc_setpie,
- };
- staticints3c_rtc_open(structdevice*dev)
- {
- structplatform_device*pdev=to_platform_device(dev);//从平台设备中获取RTC设备类的数据
- structrtc_device*rtc_dev=platform_get_drvdata(pdev);
- intret;
- ret=request_irq(s3c_rtc_tickno,s3c_rtc_tickirq,
- IRQF_DISABLED,"s3c2410-rtctick",rtc_dev);//申请中断
- if(ret){
- dev_err(dev,"IRQ%derror%d\n",s3c_rtc_tickno,ret);
- gototick_err;
- }
- tick_err:
- returnret;
- }
- staticirqreturn_ts3c_rtc_tickirq(intirq,void*id)
- {
- structrtc_device*rdev=id;
- rtc_update_irq(rdev,1,RTC_PF|RTC_IRQF);
- returnIRQ_HANDLED;
- }
- staticvoids3c_rtc_release(structdevice*dev)
- {
- structplatform_device*pdev=to_platform_device(dev);//从平台设备中获取RTC设备类的数据
- structrtc_device*rtc_dev=platform_get_drvdata(pdev);
- /*donotclearAIEhere,itmaybeneededforwake*/
- s3c_rtc_setpie(dev,0);//函数定义见下面
- free_irq(s3c_rtc_tickno,rtc_dev);
- }
- staticints3c_rtc_setpie(structdevice*dev,intenabled)
- {
- unsignedinttmp;
- pr_debug("%s:pie=%d\n",__func__,enabled);
- spin_lock_irq(&s3c_rtc_pie_lock);
- tmp=readb(s3c_rtc_base+S3C2410_TICNT)&~S3C2410_TICNT_ENABLE;//读取TICNT的值并将最高位清0
- if(enabled)
- tmp|=S3C2410_TICNT_ENABLE;
- writeb(tmp,s3c_rtc_base+S3C2410_TICNT);//写入计算后新的值
- spin_unlock_irq(&s3c_rtc_pie_lock);
- return0;
- }
- staticints3c_rtc_gettime(structdevice*dev,structrtc_time*rtc_tm)
- {
- unsignedinthave_retried=0;
- void__iomem*base=s3c_rtc_base;
- retry_get_time:
- rtc_tm->tm_min=readb(base+S3C2410_RTCMIN);
- rtc_tm->tm_hour=readb(base+S3C2410_RTCHOUR);
- rtc_tm->tm_mday=readb(base+S3C2410_RTCDATE);
- rtc_tm->tm_mon=readb(base+S3C2410_RTCMON);
- rtc_tm->tm_year=readb(base+S3C2410_RTCYEAR);
- rtc_tm->tm_sec=readb(base+S3C2410_RTCSEC);
- /*theonlywaytoworkoutwetherthesystemwasmid-update
- *whenwereaditistocheckthesecondcounter,andifit
- *iszero,thenwere-trytheentireread
- */
- if(rtc_tm->tm_sec==0&&!have_retried){
- have_retried=1;
- gotoretry_get_time;
- }
- pr_debug("readtime%02x.%02x.%02x%02x/%02x/%02x\n",
- rtc_tm->tm_year,rtc_tm->tm_mon,rtc_tm->tm_mday,
- rtc_tm->tm_hour,rtc_tm->tm_min,rtc_tm->tm_sec);
- rtc_tm->tm_sec=bcd2bin(rtc_tm->tm_sec);
- rtc_tm->tm_min=bcd2bin(rtc_tm->rtc_tm->tm_min=bcd2bin(rtc_tm->tm
ARMLinux驱动RTC实时时钟驱动分 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)