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);
}
Beispiel #2
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");
}
Beispiel #3
0
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;
}
Beispiel #4
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);
}
Beispiel #5
0
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;
}
Beispiel #6
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;
}
Beispiel #7
0
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));
}
Beispiel #8
0
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;
}
Beispiel #10
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);
}
Beispiel #11
0
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;
}