return -EINVAL;
}
writeb(bin2bcd(tm->tm_sec), base + S3C2410_RTCSEC);
writeb(bin2bcd(tm->tm_min), base + S3C2410_RTCMIN);
writeb(bin2bcd(tm->tm_hour), base + S3C2410_RTCHOUR);
writeb(bin2bcd(tm->tm_mday), base + S3C2410_RTCDATE);
writeb(bin2bcd(tm->tm_mon + 1), base + S3C2410_RTCMON);
writeb(bin2bcd(year), base + S3C2410_RTCYEAR);
return 0;
}
/* 读取RTC报警时间值 */
static int s3c_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm)
{
struct rtc_time *alm_tm = &alrm->time;
void __iomem *base = s3c_rtc_base;
unsigned int alm_en;
alm_tm->tm_sec = readb(base + S3C2410_ALMSEC);
alm_tm->tm_min = readb(base + S3C2410_ALMMIN);
alm_tm->tm_hour = readb(base + S3C2410_ALMHOUR);
alm_tm->tm_mon = readb(base + S3C2410_ALMMON);
alm_tm->tm_mday = readb(base + S3C2410_ALMDATE);
alm_tm->tm_year = readb(base + S3C2410_ALMYEAR);
alm_en = readb(base + S3C2410_RTCALM);
alrm->enabled = (alm_en & S3C2410_RTCALM_ALMEN) ? 1 : 0;
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)
alm_tm->tm_sec = bcd2bin(alm_tm->tm_sec);
else
alm_tm->tm_sec = 0xff;
if (alm_en & S3C2410_RTCALM_MINEN)
alm_tm->tm_min = bcd2bin(alm_tm->tm_min);
else
alm_tm->tm_min = 0xff;
if (alm_en & S3C2410_RTCALM_HOUREN)
alm_tm->tm_hour = bcd2bin(alm_tm->tm_hour);
else
alm_tm->tm_hour = 0xff;
if (alm_en & S3C2410_RTCALM_DAYEN)
alm_tm->tm_mday = bcd2bin(alm_tm->tm_mday);
else
alm_tm->tm_mday = 0xff;
if (alm_en & S3C2410_RTCALM_MONEN) {
alm_tm->tm_mon = bcd2bin(alm_tm->tm_mon);
alm_tm->tm_mon -= 1; //这里减1有待研究,为什么只有月没有年减1
} else {
alm_tm->tm_mon = 0xff;
}
if (alm_en & S3C2410_RTCALM_YEAREN)
alm_tm->tm_year = bcd2bin(alm_tm->tm_year);
else
alm_tm->tm_year = 0xffff;
return 0;
}
/* 与s3c_rtc_getalarm功能相反 */
static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
{
struct rtc_time *tm = &alrm->time;
void __iomem *base = s3c_rtc_base;
unsigned int alrm_en;
pr_debug('s3c_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);
alrm_en = readb(base + S3C2410_RTCALM) & S3C2410_RTCALM_ALMEN;
writeb(0x00, base + S3C2410_RTCALM);
if (tm->tm_sec < 60 && tm->tm_sec >= 0) {
alrm_en |= S3C2410_RTCALM_SECEN;
writeb(bin2bcd(tm->tm_sec), base + S3C2410_ALMSEC);
}
if (tm->tm_min < 60 && tm->tm_min >= 0) {
alrm_en |= S3C2410_RTCALM_MINEN;
writeb(bin2bcd(tm->tm_min), base + S3C2410_ALMMIN);
}
if (tm->tm_hour < 24 && tm->tm_hour >= 0) {
alrm_en |= S3C2410_RTCALM_HOUREN;
writeb(bin2bcd(tm->tm_hour), base + S3C2410_ALMHOUR);
}
pr_debug('setting S3C2410_RTCALM to %08xn', alrm_en);
writeb(alrm_en, base + S3C2410_RTCALM);
s3c_rtc_setaie(alrm->enabled);
/*根据全局报警使能的状态来决定是唤醒RTC报警中断还是睡眠RTC报警中断*/
if (alrm->enabled)
enable_irq_wake(s3c_rtc_alarmno);
else
disable_irq_wake(s3c_rtc_alarmno);
return 0;
}
static int s3c_rtc_proc(struct device *dev, struct seq_file *seq)
{
unsigned int ticnt = readb(s3c_rtc_base + S3C2410_TICNT);
seq_printf(seq, 'periodic_IRQt: %sn',
(ticnt & S3C2410_TICNT_ENABLE) ? 'yes' : 'no' );
return 0;
}
/*RTC设备类打开接口函数*/
static int s3c_rtc_open(struct device *dev)
{
/*这里主要的目的是从系统平台设备中获取RTC设备类的数据,和RTC探测函数rtc_probe中
的platform_set_drvdata(pdev, rtc)的操作刚好相反。定义在platform_device.h中*/
struct platform_device *pdev = to_platform_device(dev);
struct rtc_device *rtc_dev = platform_get_drvdata(pdev);
int ret;
ret = request_irq(s3c_rtc_alarmno, s3c_rtc_alarmirq,
IRQF_DISABLED, 's3c2410-rtc alarm', rtc_dev);
if (ret) {
上一篇:S3C2440驱动篇—Linux平台设备驱动
下一篇:S3C2440-SDRAM连线分析
推荐阅读最新更新时间:2024-11-13 16:51
设计资源 培训 开发板 精华推荐
- TLV431系列限流稳压器的典型应用
- 共享充电宝
- RH1078M 的典型应用 - 微功耗、双电源、单电源精密运算放大器
- RTL8821CU的USB无线网卡
- OpenEarable开源入耳式无线耳机(成品版)
- 具有可编程时序的 ADM1186-2ARQZ 升序和降序器和监视器的典型应用电路
- DC1317A-G,使用 LT1952EGN-1 的演示板,Vin=9V 至 36V,Vout=12V at 5A 单开关同步正向控制器
- L7806A 可调输出稳压器的典型应用(7 至 30 V)
- SY89468U,用于 GB 以太网交换机时钟缓冲器的评估板
- LTC3577EUFF-3 演示板,高度集成的便携式导航 PMIC