(1)rtc平台设备驱动源码如下,gzliu_2440_rtc.c:
相关的函数及结构体参见:http://www.linuxidc.com/Linux/2011-08/41676p2.htm
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
// 包含RTC_AF的声明
#include
#undef S3C24XX_VA_RTC
#define S3C24XX_VA_RTC s3c2440_rtc_base
static struct resource *s3c2440_rtc_mem = NULL;
static void __iomem *s3c2440_rtc_base = NULL;
static int s3c2440_rtc_alarm_irq = NO_IRQ;
static int s3c2440_rtc_tick_irq = NO_IRQ;
static int s3c2440_rtc_freq = 1; // rtc tick中断频率
static DEFINE_SPINLOCK(s3c2440_rtc_pie_lock);
static int s3c2440_rtc_proc(char *buf)
{
unsigned int rtcalm = readb(S3C2410_RTCALM);
unsigned int ticnt = readb (S3C2410_TICNT);
char *p = buf;
printk("@@@@@@@@@@@@@@@@@@@@@@ngzliu s3c2440_rtc_proc()n@@@@@@@@@@@@@@@@@@@@@@@@n");
p += sprintf(p, "alarm_IRQt: %sn", (rtcalm & S3C2410_RTCALM_ALMEN) ? "yes" : "no" );
p += sprintf(p, "periodic_IRQt: %sn", (ticnt & S3C2410_TICNT_ENABLE) ? "yes" : "no" );
p += sprintf(p, "periodic_freqt: %dn", s3c2440_rtc_freq);
return p - buf;
}
static int s3c2440_rtc_getalarm(struct rtc_wkalrm *alrm)
{
struct rtc_time *alm_tm = &alrm->time;
unsigned int alm_en;
printk("@@@@@@@@@@@@@@@@@@@@@@ngzliu s3c2440_rtc_getalarm()n@@@@@@@@@@@@@@@@@@@@@@@@n");
alm_tm->tm_sec = readb(S3C2410_ALMSEC);
alm_tm->tm_min = readb(S3C2410_ALMMIN);
alm_tm->tm_hour = readb(S3C2410_ALMHOUR);
alm_tm->tm_mon = readb(S3C2410_ALMMON);
alm_tm->tm_mday = readb(S3C2410_ALMDATE);
alm_tm->tm_year = readb(S3C2410_ALMYEAR);
alm_en = readb(S3C2410_RTCALM);
pr_debug("read alarm %02x %02x.%02x.%02x %02x/%02x/%02xn", alm_en, alm_tm->tm_year, alm_tm->tm_mon, alm_tm->tm_mday, alm_tm->tm_hour, alm_tm->tm_min, alm_tm->tm_sec);
/* decode the alarm enable field */
if (alm_en & S3C2410_RTCALM_SECEN)
{
BCD_TO_BIN(alm_tm->tm_sec);
}
else
{
alm_tm->tm_sec = 0xff;
}
if (alm_en & S3C2410_RTCALM_MINEN)
{
BCD_TO_BIN(alm_tm->tm_min);
}
else
{
alm_tm->tm_min = 0xff;
}
if (alm_en & S3C2410_RTCALM_HOUREN)
{
BCD_TO_BIN(alm_tm->tm_hour);
}
else
{
alm_tm->tm_hour = 0xff;
}
if (alm_en & S3C2410_RTCALM_DAYEN)
{
BCD_TO_BIN(alm_tm->tm_mday);
}
else
{
alm_tm->tm_mday = 0xff;
}
if (alm_en & S3C2410_RTCALM_MONEN)
{
BCD_TO_BIN(alm_tm->tm_mon);
alm_tm->tm_mon -= 1;
}
else
{
alm_tm->tm_mon = 0xff;
}
if (alm_en & S3C2410_RTCALM_YEAREN)
{
BCD_TO_BIN(alm_tm->tm_year);
}
else
{
alm_tm->tm_year = 0xffff;
}
/* todo - set alrm->enabled ? */
return 0;
}/* s3c2440_rtc_getalarm(struct rtc_wkalrm *alrm) */
static int s3c2440_rtc_setalarm(struct rtc_wkalrm *alrm)
{
struct rtc_time *tm = &alrm->time;
unsigned int alrm_en;
printk("@@@@@@@@@@@@@@@@@@@@@@ngzliu s3c2440_rtc_setalarm()n@@@@@@@@@@@@@@@@@@@@@@@@n");
pr_debug("s3c2410_rtc_setalarm: %d, %02x/%02x/%02x %02x.%02x.%02xn", alrm->enabled, tm->tm_mday & 0xff, tm->tm_mon & 0xff, tm->tm_year & 0xff, tm->tm_hour & 0xff, tm->tm_min & 0xff, tm->tm_sec);
if (alrm->enabled || 1)
{
alrm_en = readb(S3C2410_RTCALM) & S3C2410_RTCALM_ALMEN;
writeb(0x00, S3C2410_RTCALM);
if (tm->tm_sec < 60 && tm->tm_sec >= 0)
{
alrm_en |= S3C2410_RTCALM_SECEN;
writeb(BIN2BCD(tm->tm_sec), S3C2410_ALMSEC);
}
if (tm->tm_min < 60 && tm->tm_min >= 0)
{
alrm_en |= S3C2410_RTCALM_MINEN;
writeb(BIN2BCD(tm->tm_min), S3C2410_ALMMIN);
}
-
if (tm->tm_hour < 24 && tm->tm_hour >= 0)