首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

RTC实时时钟驱动(7)

RTC实时时钟驱动(7)

RTC实时时钟的使能函数s3c_rtc_enable()
RTC实时时钟可以设置相应的寄存器来控制实时时钟的状态。这些状态包括使实时时钟开始工作,也包括使实时时钟停止工作。s3c_rtc_enable()函数用来设置实时时钟的工作状态。第一个参数是RTC的平台设备指针,第二个参数是使能标志en,en等于0时,表示实时时钟停止工作,en不等于0时,表示实时时钟开始工作。

static void s3c_rtc_enable(struct platform_device *pdev, int en)
{
    void __iomem *base = s3c_rtc_base;               //将虚拟地址s3c_rtc_base赋给base指针
    unsigned int tmp;                                             

    if (s3c_rtc_base == NULL)                               //如果为空,则返回。这表示没有成功申请到内存,设备驱动退出
        return;

    if (!en) {                                                              //如果en等于0,表示不允许RTC实时时钟工作,这时,需要RTCCON寄存器的最低位置0,表示不允许实时时钟计数。同时,需   
                                                                                要将TICNT寄存器的最高位置为0,表示不允许实时时钟产生报警中断
        tmp = readb(base + S3C2410_RTCCON);
        writeb(tmp & ~S3C2410_RTCCON_RTCEN, base + S3C2410_RTCCON);         //不允许实时时钟计数

        tmp = readb(base + S3C2410_TICNT);
        writeb(tmp & ~S3C2410_TICNT_ENABLE, base + S3C2410_TICNT);                  //不允许实时时钟产生报警中断
    } else {
        /* re-enable the device, and check it is ok */

        if ((readb(base+S3C2410_RTCCON) & S3C2410_RTCCON_RTCEN) == 0){                //将RTCCON的最低位置为0,使实时时钟工作起来
            dev_info(&pdev->dev, "rtc disabled, re-enabling\n");

            tmp = readb(base + S3C2410_RTCCON);
            writeb(tmp|S3C2410_RTCCON_RTCEN, base+S3C2410_RTCCON);
        }

        if ((readb(base + S3C2410_RTCCON) & S3C2410_RTCCON_CNTSEL)){                           //将RTCCON第2位置为0,不使用BCD计数选择器
            dev_info(&pdev->dev, "removing RTCCON_CNTSEL\n");

            tmp = readb(base + S3C2410_RTCCON);
            writeb(tmp& ~S3C2410_RTCCON_CNTSEL, base+S3C2410_RTCCON);
        }

        if ((readb(base + S3C2410_RTCCON) & S3C2410_RTCCON_CLKRST)){                           //将RTCCON的第3位置为0,不重新设置计数器
            dev_info(&pdev->dev, "removing RTCCON_CLKRST\n");

            tmp = readb(base + S3C2410_RTCCON);
            writeb(tmp & ~S3C2410_RTCCON_CLKRST, base+S3C2410_RTCCON);
        }
    }
}


set_rtc_setfreq()函数用来设置时钟脉冲中断的频率,即多少时间产生一次中断。第一个参数表示RTC的设备结构体,第二个参数表示频率,即多久产生一次中断。如果freq等于1,则表示1秒钟产生一次中断;等于2,表示每秒产生2次中断
static int s3c_rtc_setfreq(struct device *dev, int freq)
{
    unsigned int tmp;

    if (!is_power_of_2(freq))                               //判断是不是2的倍数,不是返回
        return -EINVAL;

    spin_lock_irq(&s3c_rtc_pie_lock);

    tmp = readb(s3c_rtc_base + S3C2410_TICNT) & S3C2410_TICNT_ENABLE;
    tmp |= (128 / freq)-1;                           //时钟脉冲1秒中产生128次时钟滴答。Period = (n+1) / 128 second      => freq = 128 / (n+1)     => n = 128 / freq - 1

    writeb(tmp, s3c_rtc_base + S3C2410_TICNT);
    spin_unlock_irq(&s3c_rtc_pie_lock);

    return 0;
}
继承事业,薪火相传
返回列表