免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 5276 | 回复: 12
打印 上一主题 下一主题

linux2.6.27下做DS1302驱动的问题 [复制链接]

论坛徽章:
8
2015年辞旧岁徽章
日期:2015-03-03 16:54:15午马
日期:2015-02-04 12:00:07羊年新春福章
日期:2015-02-04 11:57:56双子座
日期:2014-12-02 11:44:59金牛座
日期:2014-10-08 16:47:08狮子座
日期:2014-08-29 13:37:46巳蛇
日期:2014-08-26 17:32:29NBA常规赛纪念章
日期:2015-05-04 22:32:03
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-04-07 11:41 |只看该作者 |倒序浏览
小弟用的内核版本是2.6.27,处理器AT91RM9200。在内核目录linux-2.6.27/drivers/char,找到ds1302.c文件。大致看了源码,但是不知道如何去修改,请大侠指导。
PA6   <------->   RST
PA22  <------->   CLK
PA23  <------->   I/O

论坛徽章:
8
2015年辞旧岁徽章
日期:2015-03-03 16:54:15午马
日期:2015-02-04 12:00:07羊年新春福章
日期:2015-02-04 11:57:56双子座
日期:2014-12-02 11:44:59金牛座
日期:2014-10-08 16:47:08狮子座
日期:2014-08-29 13:37:46巳蛇
日期:2014-08-26 17:32:29NBA常规赛纪念章
日期:2015-05-04 22:32:03
2 [报告]
发表于 2009-04-07 11:44 |只看该作者
附上ds1302.c的代码。
/*!***************************************************************************
*!
*! FILE NAME  : ds1302.c
*!
*! DESCRIPTION: Implements an interface for the DS1302 RTC
*!
*! Functions exported: ds1302_readreg, ds1302_writereg, ds1302_init, get_rtc_status
*!
*! ---------------------------------------------------------------------------
*!
*! (C) Copyright 1999, 2000, 2001  Axis Communications AB, LUND, SWEDEN
*!
*!***************************************************************************/



#include <linux/fs.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <linux/bcd.h>
#include <linux/smp_lock.h>
#include <linux/uaccess.h>
#include <linux/io.h>

#include <asm/system.h>
#include <asm/rtc.h>
#if defined(CONFIG_M32R)
#include <asm/m32r.h>
#endif

#define RTC_MAJOR_NR 121 /* local major, change later */

static const char ds1302_name[] = "ds1302";

/* Send 8 bits. */
static void
out_byte_rtc(unsigned int reg_addr, unsigned char x)
{
&nbsp;&nbsp;&nbsp;&nbsp;//RST H

&nbsp;&nbsp;&nbsp;&nbsp;outw(0x0001,(unsigned long)PLD_RTCRSTODT);
&nbsp;&nbsp;&nbsp;&nbsp;//write data

&nbsp;&nbsp;&nbsp;&nbsp;outw(((x<<8)|(reg_addr&0xff)),(unsigned long)PLD_RTCWRDATA);
&nbsp;&nbsp;&nbsp;&nbsp;//WE

&nbsp;&nbsp;&nbsp;&nbsp;outw(0x0002,(unsigned long)PLD_RTCCR);
&nbsp;&nbsp;&nbsp;&nbsp;//wait

&nbsp;&nbsp;&nbsp;&nbsp;while(inw((unsigned long)PLD_RTCCR));

&nbsp;&nbsp;&nbsp;&nbsp;//RST L

&nbsp;&nbsp;&nbsp;&nbsp;outw(0x0000,(unsigned long)PLD_RTCRSTODT);

}

static unsigned char
in_byte_rtc(unsigned int reg_addr)
{
&nbsp;&nbsp;&nbsp;&nbsp;unsigned char retval;

&nbsp;&nbsp;&nbsp;&nbsp;//RST H

&nbsp;&nbsp;&nbsp;&nbsp;outw(0x0001,(unsigned long)PLD_RTCRSTODT);
&nbsp;&nbsp;&nbsp;&nbsp;//write data

&nbsp;&nbsp;&nbsp;&nbsp;outw((reg_addr&0xff),(unsigned long)PLD_RTCRDDATA);
&nbsp;&nbsp;&nbsp;&nbsp;//RE

&nbsp;&nbsp;&nbsp;&nbsp;outw(0x0001,(unsigned long)PLD_RTCCR);
&nbsp;&nbsp;&nbsp;&nbsp;//wait

&nbsp;&nbsp;&nbsp;&nbsp;while(inw((unsigned long)PLD_RTCCR));

&nbsp;&nbsp;&nbsp;&nbsp;//read data

&nbsp;&nbsp;&nbsp;&nbsp;retval=(inw((unsigned long)PLD_RTCRDDATA) & 0xff00)>>8;

&nbsp;&nbsp;&nbsp;&nbsp;//RST L

&nbsp;&nbsp;&nbsp;&nbsp;outw(0x0000,(unsigned long)PLD_RTCRSTODT);

&nbsp;&nbsp;&nbsp;&nbsp;return retval;
}

/* Enable writing. */

static void
ds1302_wenable(void)
{
&nbsp;&nbsp;&nbsp;&nbsp;out_byte_rtc(0x8e,0x00);
}

/* Disable writing. */

static void
ds1302_wdisable(void)
{
&nbsp;&nbsp;&nbsp;&nbsp;out_byte_rtc(0x8e,0x80);
}



/* Read a byte from the selected register in the DS1302. */

unsigned char
ds1302_readreg(int reg)
{
&nbsp;&nbsp;&nbsp;&nbsp;unsigned char x;

&nbsp;&nbsp;&nbsp;&nbsp;x=in_byte_rtc((0x81 | (reg << 1))); /* read register */

&nbsp;&nbsp;&nbsp;&nbsp;return x;
}

/* Write a byte to the selected register. */

void
ds1302_writereg(int reg, unsigned char val)
{
&nbsp;&nbsp;&nbsp;&nbsp;ds1302_wenable();
&nbsp;&nbsp;&nbsp;&nbsp;out_byte_rtc((0x80 | (reg << 1)),val);
&nbsp;&nbsp;&nbsp;&nbsp;ds1302_wdisable();
}

void
get_rtc_time(struct rtc_time *rtc_tm)
{
&nbsp;&nbsp;&nbsp;&nbsp;unsigned long flags;

&nbsp;&nbsp;&nbsp;&nbsp;local_irq_save(flags);

&nbsp;&nbsp;&nbsp;&nbsp;rtc_tm->tm_sec = CMOS_READ(RTC_SECONDS);
&nbsp;&nbsp;&nbsp;&nbsp;rtc_tm->tm_min = CMOS_READ(RTC_MINUTES);
&nbsp;&nbsp;&nbsp;&nbsp;rtc_tm->tm_hour = CMOS_READ(RTC_HOURS);
&nbsp;&nbsp;&nbsp;&nbsp;rtc_tm->tm_mday = CMOS_READ(RTC_DAY_OF_MONTH);
&nbsp;&nbsp;&nbsp;&nbsp;rtc_tm->tm_mon = CMOS_READ(RTC_MONTH);
&nbsp;&nbsp;&nbsp;&nbsp;rtc_tm->tm_year = CMOS_READ(RTC_YEAR);

&nbsp;&nbsp;&nbsp;&nbsp;local_irq_restore(flags);

&nbsp;&nbsp;&nbsp;&nbsp;BCD_TO_BIN(rtc_tm->tm_sec);
&nbsp;&nbsp;&nbsp;&nbsp;BCD_TO_BIN(rtc_tm->tm_min);
&nbsp;&nbsp;&nbsp;&nbsp;BCD_TO_BIN(rtc_tm->tm_hour);
&nbsp;&nbsp;&nbsp;&nbsp;BCD_TO_BIN(rtc_tm->tm_mday);
&nbsp;&nbsp;&nbsp;&nbsp;BCD_TO_BIN(rtc_tm->tm_mon);
&nbsp;&nbsp;&nbsp;&nbsp;BCD_TO_BIN(rtc_tm->tm_year);

&nbsp;&nbsp;&nbsp;&nbsp;/*
&nbsp;&nbsp;&nbsp;&nbsp; * Account for differences between how the RTC uses the values
&nbsp;&nbsp;&nbsp;&nbsp; * and how they are defined in a struct rtc_time;
&nbsp;&nbsp;&nbsp;&nbsp; */


&nbsp;&nbsp;&nbsp;&nbsp;if (rtc_tm->tm_year <= 69)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rtc_tm->tm_year += 100;

&nbsp;&nbsp;&nbsp;&nbsp;rtc_tm->tm_mon--;
}

static unsigned char days_in_mo[] =
&nbsp;&nbsp;&nbsp;&nbsp;{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

/* ioctl that supports RTC_RD_TIME and RTC_SET_TIME (read and set time/date). */

static long rtc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
&nbsp;&nbsp;&nbsp;&nbsp;unsigned long flags;

&nbsp;&nbsp;&nbsp;&nbsp;switch(cmd) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case RTC_RD_TIME:&nbsp;&nbsp;&nbsp;&nbsp;/* read the time/date from RTC&nbsp;&nbsp;&nbsp;&nbsp;*/
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;struct rtc_time rtc_tm;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;memset(&rtc_tm, 0, sizeof (struct rtc_time));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lock_kernel();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;get_rtc_time(&rtc_tm);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unlock_kernel();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (copy_to_user((struct rtc_time*)arg, &rtc_tm, sizeof(struct rtc_time)))
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return -EFAULT;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return 0;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case RTC_SET_TIME:&nbsp;&nbsp;&nbsp;&nbsp;/* set the RTC */
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;struct rtc_time rtc_tm;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unsigned char mon, day, hrs, min, sec, leap_yr;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unsigned int yrs;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (!capable(CAP_SYS_TIME))
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return -EPERM;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (copy_from_user(&rtc_tm, (struct rtc_time*)arg, sizeof(struct rtc_time)))
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return -EFAULT;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;yrs = rtc_tm.tm_year + 1900;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mon = rtc_tm.tm_mon + 1;   /* tm_mon starts at zero */
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;day = rtc_tm.tm_mday;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hrs = rtc_tm.tm_hour;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;min = rtc_tm.tm_min;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sec = rtc_tm.tm_sec;


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ((yrs < 1970) || (yrs > 2069))
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return -EINVAL;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;leap_yr = ((!(yrs % 4) && (yrs % 100)) || !(yrs % 400));

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ((mon > 12) || (day == 0))
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return -EINVAL;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (day > (days_in_mo[mon] + ((mon == 2) && leap_yr)))
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return -EINVAL;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ((hrs >= 24) || (min >= 60) || (sec >= 60))
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return -EINVAL;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (yrs >= 2000)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;yrs -= 2000;&nbsp;&nbsp;&nbsp;&nbsp;/* RTC (0, 1, ... 69) */
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;yrs -= 1900;&nbsp;&nbsp;&nbsp;&nbsp;/* RTC (70, 71, ... 99) */

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BIN_TO_BCD(sec);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BIN_TO_BCD(min);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BIN_TO_BCD(hrs);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BIN_TO_BCD(day);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BIN_TO_BCD(mon);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BIN_TO_BCD(yrs);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lock_kernel();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;local_irq_save(flags);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CMOS_WRITE(yrs, RTC_YEAR);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CMOS_WRITE(mon, RTC_MONTH);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CMOS_WRITE(day, RTC_DAY_OF_MONTH);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CMOS_WRITE(hrs, RTC_HOURS);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CMOS_WRITE(min, RTC_MINUTES);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CMOS_WRITE(sec, RTC_SECONDS);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;local_irq_restore(flags);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unlock_kernel();

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* Notice that at this point, the RTC is updated but
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * the kernel is still running with the old time.
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * You need to set that separately with settimeofday
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * or adjtimex.
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return 0;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case RTC_SET_CHARGE: /* set the RTC TRICKLE CHARGE register */
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int tcs_val;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (!capable(CAP_SYS_TIME))
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return -EPERM;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(copy_from_user(&tcs_val, (int*)arg, sizeof(int)))
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return -EFAULT;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lock_kernel();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tcs_val = RTC_TCR_PATTERN | (tcs_val & 0x0F);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ds1302_writereg(RTC_TRICKLECHARGER, tcs_val);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unlock_kernel();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return 0;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;default:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return -EINVAL;
&nbsp;&nbsp;&nbsp;&nbsp;}
}

int
get_rtc_status(char *buf)
{
&nbsp;&nbsp;&nbsp;&nbsp;char *p;
&nbsp;&nbsp;&nbsp;&nbsp;struct rtc_time tm;

&nbsp;&nbsp;&nbsp;&nbsp;p = buf;

&nbsp;&nbsp;&nbsp;&nbsp;get_rtc_time(&tm);

&nbsp;&nbsp;&nbsp;&nbsp;/*
&nbsp;&nbsp;&nbsp;&nbsp; * There is no way to tell if the luser has the RTC set for local
&nbsp;&nbsp;&nbsp;&nbsp; * time or for Universal Standard Time (GMT). Probably local though.
&nbsp;&nbsp;&nbsp;&nbsp; */


&nbsp;&nbsp;&nbsp;&nbsp;p += sprintf(p,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"rtc_time\t: %02d:%02d:%02d\n"
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"rtc_date\t: %04d-%02d-%02d\n",
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tm.tm_hour, tm.tm_min, tm.tm_sec,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);

&nbsp;&nbsp;&nbsp;&nbsp;return  p - buf;
}


/* The various file operations we support. */

static const struct file_operations rtc_fops = {
&nbsp;&nbsp;&nbsp;&nbsp;.owner&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= THIS_MODULE,
&nbsp;&nbsp;&nbsp;&nbsp;.unlocked_ioctl&nbsp;&nbsp;&nbsp;&nbsp;= rtc_ioctl,
};

/* Probe for the chip by writing something to its RAM and try reading it back. */

#define MAGIC_PATTERN 0x42

static int __init
ds1302_probe(void)
{
&nbsp;&nbsp;&nbsp;&nbsp;int retval, res, baur;

&nbsp;&nbsp;&nbsp;&nbsp;baur=(boot_cpu_data.bus_clock/(2*1000*1000));

&nbsp;&nbsp;&nbsp;&nbsp;printk("%s: Set PLD_RTCBAUR = %d\n", ds1302_name,baur);

&nbsp;&nbsp;&nbsp;&nbsp;outw(0x0000,(unsigned long)PLD_RTCCR);
&nbsp;&nbsp;&nbsp;&nbsp;outw(0x0000,(unsigned long)PLD_RTCRSTODT);
&nbsp;&nbsp;&nbsp;&nbsp;outw(baur,(unsigned long)PLD_RTCBAUR);

&nbsp;&nbsp;&nbsp;&nbsp;/* Try to talk to timekeeper. */

&nbsp;&nbsp;&nbsp;&nbsp;ds1302_wenable();
&nbsp;&nbsp;&nbsp;&nbsp;/* write RAM byte 0 */
&nbsp;&nbsp;&nbsp;&nbsp;/* write something magic */
&nbsp;&nbsp;&nbsp;&nbsp;out_byte_rtc(0xc0,MAGIC_PATTERN);

&nbsp;&nbsp;&nbsp;&nbsp;/* read RAM byte 0 */
&nbsp;&nbsp;&nbsp;&nbsp;if((res = in_byte_rtc(0xc1)) == MAGIC_PATTERN) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;char buf[100];
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ds1302_wdisable();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printk("%s: RTC found.\n", ds1302_name);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;get_rtc_status(buf);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printk(buf);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;retval = 1;
&nbsp;&nbsp;&nbsp;&nbsp;} else {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printk("%s: RTC not found.\n", ds1302_name);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;retval = 0;
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;return retval;
}


/* Just probe for the RTC and register the device to handle the ioctl needed. */

int __init
ds1302_init(void)
{
&nbsp;&nbsp;&nbsp;&nbsp;if (!ds1302_probe()) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return -1;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;return 0;
}

static int __init ds1302_register(void)
{
&nbsp;&nbsp;&nbsp;&nbsp;ds1302_init();
&nbsp;&nbsp;&nbsp;&nbsp;if (register_chrdev(RTC_MAJOR_NR, ds1302_name, &rtc_fops)) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printk(KERN_INFO "%s: unable to get major %d for rtc\n",
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;       ds1302_name, RTC_MAJOR_NR);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return -1;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;return 0;
}

module_init(ds1302_register);


[ 本帖最后由 dreamice 于 2009-4-7 12:40 编辑 ]

论坛徽章:
3
金牛座
日期:2014-06-14 22:04:062015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:49:45
3 [报告]
发表于 2009-04-07 12:42 |只看该作者

回复 #1 zhj1011 的帖子

你先把你要做什么,以及这段代码是如何工作的搞清楚再说吧

论坛徽章:
8
2015年辞旧岁徽章
日期:2015-03-03 16:54:15午马
日期:2015-02-04 12:00:07羊年新春福章
日期:2015-02-04 11:57:56双子座
日期:2014-12-02 11:44:59金牛座
日期:2014-10-08 16:47:08狮子座
日期:2014-08-29 13:37:46巳蛇
日期:2014-08-26 17:32:29NBA常规赛纪念章
日期:2015-05-04 22:32:03
4 [报告]
发表于 2009-04-07 17:00 |只看该作者

回复 #3 dreamice 的帖子

谢谢楼主

论坛徽章:
3
金牛座
日期:2014-06-14 22:04:062015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:49:45
5 [报告]
发表于 2009-04-07 19:27 |只看该作者
原帖由 zhj1011 于 2009-4-7 17:00 发表
谢谢楼主



You are楼主

论坛徽章:
5
6 [报告]
发表于 2009-04-08 09:16 |只看该作者
原帖由 dreamice 于 2009/4/7 19:27 发表



You are楼主


BZ先生, 不要这么惊讶

论坛徽章:
5
7 [报告]
发表于 2009-04-08 09:17 |只看该作者
LZ, 内核里有了驱动, 你还要做什么呢? 你没有详述你的需要和问题.

论坛徽章:
8
2015年辞旧岁徽章
日期:2015-03-03 16:54:15午马
日期:2015-02-04 12:00:07羊年新春福章
日期:2015-02-04 11:57:56双子座
日期:2014-12-02 11:44:59金牛座
日期:2014-10-08 16:47:08狮子座
日期:2014-08-29 13:37:46巳蛇
日期:2014-08-26 17:32:29NBA常规赛纪念章
日期:2015-05-04 22:32:03
8 [报告]
发表于 2009-04-08 10:24 |只看该作者

回复 #7 yidou 的帖子

是这样的 2.6内核下面 有两个ds1302的驱动 一个位于drivers/char/ds1302.c 一个是drivers/rtc/rtc-ds1302.c
看了char下的Kconfig和rtc/Kconfig
drivers/char/ds1302.c 依赖于 M32R && (PLAT_M32700UT || PLAT_OPSPUT)
drivers/rtc/rtc-ds1302.c依赖于 depends on SH_SECUREEDGE5410
这两个驱动都不是针对ARM体系结构的。
我现在是要做一个AT91RM9200上的DS1302驱动 通过三个GPIO管脚实现通信
我现在修改char/ds1302.c代码 编译通过后 加载到内核后 出错
移植这个非ARM体系结构的去到ARM体系结构下 需要修改哪些东西呢? 只是一些管脚的具体定义就OK了吗? 谢谢

论坛徽章:
0
9 [报告]
发表于 2009-04-08 11:33 |只看该作者
好像不止三个口啊,并口? arch/cris/arch-v10/drivers 下面有个 ds1302 的好像才是模拟的

[ 本帖最后由 star316 于 2009-4-8 11:37 编辑 ]

论坛徽章:
5
10 [报告]
发表于 2009-04-08 11:41 |只看该作者
手头没有2.6.27.   看了一下2.6.28的ds1302.c,  我认为你要先确认RTC的地址正确, 几个函数都是针对地址/寄存器的操作.
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP