int snapgear_rtc_settimeofday(const struct timeval *tv) { int retval = 0; int real_seconds, real_minutes, cmos_minutes; unsigned long nowtime; if (!use_ds1302) { sh_rtc_settimeofday(tv); return(0); } /* * This is called direct from the kernel timer handling code. * It is supposed to synchronize the kernel clock to the RTC. */ nowtime = tv->tv_sec; #if 1 printk("SnapGear RTC: snapgear_rtc_settimeofday(nowtime=%ld)\n", nowtime); #endif /* STOP RTC */ ds1302_writebyte(RTC_ADDR_SEC, ds1302_readbyte(RTC_ADDR_SEC) | 0x80); cmos_minutes = bcd2int(ds1302_readbyte(RTC_ADDR_MIN)); /* * since we're only adjusting minutes and seconds, * don't interfere with hour overflow. This avoids * messing with unknown time zones but requires your * RTC not to be off by more than 15 minutes */ real_seconds = nowtime % 60; real_minutes = nowtime / 60; if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1) real_minutes += 30; /* correct for half hour time zone */ real_minutes %= 60; if (abs(real_minutes - cmos_minutes) < 30) { ds1302_writebyte(RTC_ADDR_MIN, int2bcd(real_minutes)); ds1302_writebyte(RTC_ADDR_SEC, int2bcd(real_seconds)); } else { printk(KERN_WARNING "SnapGear RTC: can't update from %d to %d\n", cmos_minutes, real_minutes); retval = -1; } /* START RTC */ ds1302_writebyte(RTC_ADDR_SEC, ds1302_readbyte(RTC_ADDR_SEC) & ~0x80); return(0); }
void __init secureedge5410_rtc_init(void) { unsigned char *test = "snapgear"; int i; ds1302_reset(); use_ds1302 = 1; for (i = 0; test[i]; i++) ds1302_writebyte(32 + i, test[i]); for (i = 0; test[i]; i++) if (ds1302_readbyte(32 + i) != test[i]) { use_ds1302 = 0; break; } if (use_ds1302) { rtc_sh_get_time = snapgear_rtc_gettimeofday; rtc_sh_set_time = snapgear_rtc_settimeofday; } printk("SnapGear RTC: using %s rtc.\n", use_ds1302 ? "ds1302" : "internal"); }
static int __init ds1302_rtc_probe(struct platform_device *pdev) { struct rtc_device *rtc; if (ds1302_hw_init()) { dev_err(&pdev->dev, "Failed to init communication channel"); return -EINVAL; } /* Reset */ ds1302_reset(); /* Write a magic value to the DS1302 RAM, and see if it sticks. */ ds1302_writebyte(RTC_ADDR_RAM0, 0x42); if (ds1302_readbyte(RTC_ADDR_RAM0) != 0x42) { dev_err(&pdev->dev, "Failed to probe"); return -ENODEV; } rtc = rtc_device_register("ds1302", &pdev->dev, &ds1302_rtc_ops, THIS_MODULE); if (IS_ERR(rtc)) return PTR_ERR(rtc); platform_set_drvdata(pdev, rtc); return 0; }
unsigned char secureedge5410_cmos_read(int addr) { unsigned char val = 0; if (!use_ds1302) return(__CMOS_READ(addr, w)); switch(addr) { case RTC_SECONDS: val = ds1302_readbyte(RTC_ADDR_SEC); break; case RTC_SECONDS_ALARM: break; case RTC_MINUTES: val = ds1302_readbyte(RTC_ADDR_MIN); break; case RTC_MINUTES_ALARM: break; case RTC_HOURS: val = ds1302_readbyte(RTC_ADDR_HOUR); break; case RTC_HOURS_ALARM: break; case RTC_DAY_OF_WEEK: val = ds1302_readbyte(RTC_ADDR_DAY); break; case RTC_DAY_OF_MONTH: val = ds1302_readbyte(RTC_ADDR_DATE); break; case RTC_MONTH: val = ds1302_readbyte(RTC_ADDR_MON); break; case RTC_YEAR: val = ds1302_readbyte(RTC_ADDR_YEAR); break; case RTC_REG_A: /* RTC_FREQ_SELECT */ break; case RTC_REG_B: /* RTC_CONTROL */ break; case RTC_REG_C: /* RTC_INTR_FLAGS */ break; case RTC_REG_D: val = RTC_VRT /* RTC_VALID */; break; default: break; } return(val); }
static int ds1302_rtc_set_time(struct device *dev, struct rtc_time *tm) { /* Stop RTC */ ds1302_writebyte(RTC_ADDR_SEC, ds1302_readbyte(RTC_ADDR_SEC) | 0x80); ds1302_writebyte(RTC_ADDR_SEC, bin2bcd(tm->tm_sec)); ds1302_writebyte(RTC_ADDR_MIN, bin2bcd(tm->tm_min)); ds1302_writebyte(RTC_ADDR_HOUR, bin2bcd(tm->tm_hour)); ds1302_writebyte(RTC_ADDR_DAY, bin2bcd(tm->tm_wday)); ds1302_writebyte(RTC_ADDR_DATE, bin2bcd(tm->tm_mday)); ds1302_writebyte(RTC_ADDR_MON, bin2bcd(tm->tm_mon + 1)); ds1302_writebyte(RTC_ADDR_YEAR, bin2bcd(tm->tm_year % 100)); /* Start RTC */ ds1302_writebyte(RTC_ADDR_SEC, ds1302_readbyte(RTC_ADDR_SEC) & ~0x80); return 0; }
/********************************************************************* Function:ds1302_read Description:读取指定的值 Calls: ds1302_writebyte ds1302_readbyte GPIO_Write Table Accessed: Table Updated: Input: cmd 指定标志 Output:读取到的数据 Return:读取到的数据 Others: **********************************************************************/ WCAPI u8 ds1302_read(u8 cmd) { u8 dat = 0; GPIO_WriteBit(D_RSTPort, D_RSTPin, Bit_RESET); GPIO_WriteBit(D_SCLKPort, D_SCLKPin, Bit_RESET); GPIO_WriteBit(D_RSTPort, D_RSTPin, Bit_SET); //delay_us(1); ds1302_writebyte(cmd); dat = ds1302_readbyte(); GPIO_WriteBit(D_SCLKPort, D_SCLKPin, Bit_RESET); GPIO_WriteBit(D_RSTPort, D_RSTPin, Bit_RESET); return dat; }
void ds1302_gettod(int *year, int *mon, int *day, int *hour, int *min, int *sec) { #if 0 printk("ds1302_gettod()\n"); #endif *year = bcd2int(ds1302_readbyte(RTC_ADDR_YEAR)); *mon = bcd2int(ds1302_readbyte(RTC_ADDR_MON)); *day = bcd2int(ds1302_readbyte(RTC_ADDR_DATE)); *hour = bcd2int(ds1302_readbyte(RTC_ADDR_HOUR)); *min = bcd2int(ds1302_readbyte(RTC_ADDR_MIN)); *sec = bcd2int(ds1302_readbyte(RTC_ADDR_SEC)); }
static ssize_t ds1302_read(struct file *fp, char *buf, size_t count, loff_t *ptr) { int total; #if 0 printk("ds1302_read(buf=%x,count=%d)\n", (int) buf, count); #endif if (fp->f_pos >= DS1302_MSIZE) return(0); if (count > (DS1302_MSIZE - fp->f_pos)) count = DS1302_MSIZE - fp->f_pos; for (total = 0; (total < count); total++) put_user(ds1302_readbyte(fp->f_pos + total), buf++); fp->f_pos += total; return(total); }
static int __init ds1302_rtc_probe(struct platform_device *pdev) { struct rtc_device *rtc; /* Reset */ set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK)); /* Write a magic value to the DS1302 RAM, and see if it sticks. */ ds1302_writebyte(RTC_ADDR_RAM0, 0x42); if (ds1302_readbyte(RTC_ADDR_RAM0) != 0x42) return -ENODEV; rtc = rtc_device_register("ds1302", &pdev->dev, &ds1302_rtc_ops, THIS_MODULE); if (IS_ERR(rtc)) return PTR_ERR(rtc); platform_set_drvdata(pdev, rtc); return 0; }
static int ds1302_rtc_read_time(struct device *dev, struct rtc_time *tm) { tm->tm_sec = bcd2bin(ds1302_readbyte(RTC_ADDR_SEC)); tm->tm_min = bcd2bin(ds1302_readbyte(RTC_ADDR_MIN)); tm->tm_hour = bcd2bin(ds1302_readbyte(RTC_ADDR_HOUR)); tm->tm_wday = bcd2bin(ds1302_readbyte(RTC_ADDR_DAY)); tm->tm_mday = bcd2bin(ds1302_readbyte(RTC_ADDR_DATE)); tm->tm_mon = bcd2bin(ds1302_readbyte(RTC_ADDR_MON)) - 1; tm->tm_year = bcd2bin(ds1302_readbyte(RTC_ADDR_YEAR)); if (tm->tm_year < 70) tm->tm_year += 100; dev_dbg(dev, "%s: tm is secs=%d, mins=%d, hours=%d, " "mday=%d, mon=%d, year=%d, wday=%d\n", __func__, tm->tm_sec, tm->tm_min, tm->tm_hour, tm->tm_mday, tm->tm_mon + 1, tm->tm_year, tm->tm_wday); return rtc_valid_tm(tm); }
void snapgear_rtc_gettimeofday(struct timespec *ts) { unsigned int sec, min, hr, day, mon, yr; if (!use_ds1302) { sh_rtc_gettimeofday(ts); return; } sec = bcd2int(ds1302_readbyte(RTC_ADDR_SEC)); min = bcd2int(ds1302_readbyte(RTC_ADDR_MIN)); hr = bcd2int(ds1302_readbyte(RTC_ADDR_HOUR)); day = bcd2int(ds1302_readbyte(RTC_ADDR_DATE)); mon = bcd2int(ds1302_readbyte(RTC_ADDR_MON)); yr = bcd2int(ds1302_readbyte(RTC_ADDR_YEAR)); bad_time: if (yr > 99 || mon < 1 || mon > 12 || day > 31 || day < 1 || hr > 23 || min > 59 || sec > 59) { printk(KERN_ERR "SnapGear RTC: invalid value, resetting to 1 Jan 2000\n"); ds1302_writebyte(RTC_ADDR_MIN, min = 0); ds1302_writebyte(RTC_ADDR_HOUR, hr = 0); ds1302_writebyte(RTC_ADDR_DAY, 7); ds1302_writebyte(RTC_ADDR_DATE, day = 1); ds1302_writebyte(RTC_ADDR_MON, mon = 1); ds1302_writebyte(RTC_ADDR_YEAR, yr = 0); ds1302_writebyte(RTC_ADDR_SEC, sec = 0); } ts->tv_sec = mktime(2000 + yr, mon, day, hr, min, sec); if (ts->tv_sec < 0) { #if 0 printk("BAD TIME %d %d %d %d %d %d\n", yr, mon, day, hr, min, sec); #endif yr = 100; goto bad_time; } ts->tv_nsec = 0; }