Пример #1
0
static uint64_t
rtc_get_time_impl(struct rtc_interface *rtci, struct s3c2410_rtc *device)
{
    uint64_t unix_time;
    struct rtc_time tm;

    int reads = 0;
    tm.sec = 0;

    /* If BCDSEC is zero then we read during an update, reread. */
    while (tm.sec == 0 && reads <= 1) {
        tm.sec  = BCD2BIN(bcdsec_get_secdata());
        tm.min  = BCD2BIN(bcdmin_get_mindata());
        tm.hour = BCD2BIN(bcdhour_get_hourdata());
        tm.date = BCD2BIN(bcddate_get_datedata());
        tm.mon  = BCD2BIN(bcdmon_get_mondata());
        /* s3c410 rtc only has two digits for year, assumes 21st century. */
        tm.year = bcdyear_get_yeardata();

        reads++;
    }

    if (rtc_to_unix(&unix_time, &tm) != 0) {
        printf("%s: WARNING RTC returned invalid time value\n", __func__);
    }

    //printf("%s: time is: unix_time=%llu ... year=%d, mon=%d, date=%d, hour=%d, min=%d, sec=%d\n", __func__, unix_time, tm.year, tm.mon, tm.date, tm.hour, tm.min, tm.sec);


    return unix_time;
}
Пример #2
0
static inline int rtc_get_status(char *buf)
{
	char *p;
	unsigned int year;
	struct upd4990a_raw_data data;

	p = buf;

	upd4990a_get_time(&data, 0);

	/*
	 * There is no way to tell if the luser has the RTC set for local
	 * time or for Universal Standard Time (GMT). Probably local though.
	 */
	if ((year = BCD2BIN(data.year) + 1900) < 1995)
		year += 100;
	p += sprintf(p,
		     "rtc_time\t: %02d:%02d:%02d\n"
		     "rtc_date\t: %04d-%02d-%02d\n",
		     BCD2BIN(data.hour), BCD2BIN(data.min),
		     BCD2BIN(data.sec),
		     year, data.mon, BCD2BIN(data.mday));

	return  p - buf;
}
Пример #3
0
uint16_t get_year_day(ds1307_time_t *tm) {
	uint16_t day = 0;
	int8_t i = BCD2BIN(tm->month);

	while (--i) {
		day += get_month_days(i, BCD2BIN(tm->year));
	}

	day += BCD2BIN(tm->dom);
	return day;
}
Пример #4
0
static int s35390a_reg2hr(struct s35390a *s35390a, char reg)
{
	unsigned hour;

	if (s35390a->twentyfourhour)
		return BCD2BIN(reg & 0x3f);

	hour = BCD2BIN(reg & 0x3f);
	if (reg & 0x40)
		hour += 12;

	return hour;
}
Пример #5
0
static unsigned rs5c_reg2hr(struct rs5c372 *rs5c, unsigned reg)
{
	unsigned	hour;

	if (rs5c->time24)
		return BCD2BIN(reg & 0x3f);

	hour = BCD2BIN(reg & 0x1f);
	if (hour == 12)
		hour = 0;
	if (reg & 0x20)
		hour += 12;
	return hour;
}
Пример #6
0
// compute unix-timestamp from dcf77_ctx
static inline uint32_t
compute_dcf77_timestamp(void)
{
  clock_datetime_t dcfdate;
  dcfdate.sec = 0;
  dcfdate.min = BCD2BIN(dcf.time[2]);
  dcfdate.hour = BCD2BIN(dcf.time[3]);
  dcfdate.day = BCD2BIN(dcf.time[4]);
  dcfdate.month = BCD2BIN(dcf.time[6]);
  dcfdate.dow = dcf.time[5]; // nach ISO erster Tag Montag, nicht So!
  dcfdate.year = 100 + (BCD2BIN(dcf.time[7]));
  dcfdate.isdst = dcf.isdst;
  return clock_mktime(&dcfdate, 1);
}
Пример #7
0
int
RTCFUNC(get,ds3232)(struct tm *tm, int cent_reg)
{
    unsigned char   date[7];

    ds3232_i2c_read(DS3232_SEC, date, 7);

    tm->tm_sec  = BCD2BIN(date[DS3232_SEC] & 0x7f);
    tm->tm_min  = BCD2BIN(date[DS3232_MIN] & 0x7f);

	if ((date[DS3232_HOUR] & 0x40)) {
		/* the rtc is in 12 hour mode */ 
		int hour = BCD2BIN(date[DS3232_HOUR] & 0x1f);

		if ((date[DS3232_HOUR] & 0x20))  
			tm->tm_hour = (hour == 12) ? 12 : hour + 12; /* pm */
		else
			tm->tm_hour = (hour == 12) ? 0 : hour;  	 /* am */

	} else { 
		/* rejoice! the rtc is in 24 hour mode */ 
     	tm->tm_hour = BCD2BIN(date[DS3232_HOUR] & 0x3f);
	}

    tm->tm_mday = BCD2BIN(date[DS3232_DATE] & 0x3f);
    tm->tm_mon  = BCD2BIN(date[DS3232_MONTH] & 0x1f) - 1;
    tm->tm_year = BCD2BIN(date[DS3232_YEAR] & 0xff);

	if ((date[DS3232_MONTH] & 0x80))  
		tm->tm_year += 100;

    tm->tm_wday = BCD2BIN(date[DS3232_DAY] & 0x7) - 1;

    return(0);
}
Пример #8
0
static int max6902_get_datetime(struct device *dev, struct rtc_time *dt)
{
	unsigned char tmp;
	int century;
	int err;
	struct spi_device *spi = to_spi_device(dev);
	struct max6902 *chip = dev_get_drvdata(dev);
	struct spi_message message;
	struct spi_transfer xfer;
	int status;

	err = max6902_get_reg(dev, MAX6902_REG_CENTURY, &tmp);
	if (err)
		return err;

	/* build the message */
	spi_message_init(&message);
	memset(&xfer, 0, sizeof(xfer));
	xfer.len = 1 + 7;	/* Burst read command + 7 registers */
	xfer.tx_buf = chip->buf;
	xfer.rx_buf = chip->buf;
	chip->buf[0] = 0xbf;	/* Burst read */
	spi_message_add_tail(&xfer, &message);

	/* do the i/o */
	status = spi_sync(spi, &message);
	if (status == 0)
		status = message.status;
	else
		return status;

	/* The chip sends data in this order:
	 * Seconds, Minutes, Hours, Date, Month, Day, Year */
	dt->tm_sec	= BCD2BIN(chip->buf[1]);
	dt->tm_min	= BCD2BIN(chip->buf[2]);
	dt->tm_hour	= BCD2BIN(chip->buf[3]);
	dt->tm_mday	= BCD2BIN(chip->buf[4]);
	dt->tm_mon	= BCD2BIN(chip->buf[5]) - 1;
	dt->tm_wday	= BCD2BIN(chip->buf[6]);
	dt->tm_year = BCD2BIN(chip->buf[7]);

	century = BCD2BIN(tmp) * 100;

	dt->tm_year += century;
	dt->tm_year -= 1900;

#ifdef MAX6902_DEBUG
	printk("\n%s : Read RTC values\n",__FUNCTION__);
	printk("tm_hour: %i\n",dt->tm_hour);
	printk("tm_min : %i\n",dt->tm_min);
	printk("tm_sec : %i\n",dt->tm_sec);
	printk("tm_year: %i\n",dt->tm_year);
	printk("tm_mon : %i\n",dt->tm_mon);
	printk("tm_mday: %i\n",dt->tm_mday);
	printk("tm_wday: %i\n",dt->tm_wday);
#endif

	return 0;
}
Пример #9
0
static int sh_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct sh_rtc *rtc = platform_get_drvdata(pdev);
	unsigned int sec128, sec2, yr, yr100, cf_bit;

	do {
		unsigned int tmp;

		spin_lock_irq(&rtc->lock);

		tmp = readb(rtc->regbase + RCR1);
		tmp &= ~RCR1_CF; /* Clear CF-bit */
		tmp |= RCR1_CIE;
		writeb(tmp, rtc->regbase + RCR1);

		sec128 = readb(rtc->regbase + R64CNT);

		tm->tm_sec	= BCD2BIN(readb(rtc->regbase + RSECCNT));
		tm->tm_min	= BCD2BIN(readb(rtc->regbase + RMINCNT));
		tm->tm_hour	= BCD2BIN(readb(rtc->regbase + RHRCNT));
		tm->tm_wday	= BCD2BIN(readb(rtc->regbase + RWKCNT));
		tm->tm_mday	= BCD2BIN(readb(rtc->regbase + RDAYCNT));
		tm->tm_mon	= BCD2BIN(readb(rtc->regbase + RMONCNT)) - 1;

#if defined(CONFIG_CPU_SH4)
		yr  = readw(rtc->regbase + RYRCNT);
		yr100 = BCD2BIN(yr >> 8);
		yr &= 0xff;
#else
		yr  = readb(rtc->regbase + RYRCNT);
		yr100 = BCD2BIN((yr == 0x99) ? 0x19 : 0x20);
#endif

		tm->tm_year = (yr100 * 100 + BCD2BIN(yr)) - 1900;

		sec2 = readb(rtc->regbase + R64CNT);
		cf_bit = readb(rtc->regbase + RCR1) & RCR1_CF;

		spin_unlock_irq(&rtc->lock);
	} while (cf_bit != 0 || ((sec128 ^ sec2) & RTC_BIT_INVERTED) != 0);

#if RTC_BIT_INVERTED != 0
	if ((sec128 & RTC_BIT_INVERTED))
		tm->tm_sec--;
#endif

	dev_dbg(dev, "%s: tm is secs=%d, mins=%d, hours=%d, "
		"mday=%d, mon=%d, year=%d, wday=%d\n",
		__FUNCTION__,
		tm->tm_sec, tm->tm_min, tm->tm_hour,
		tm->tm_mday, tm->tm_mon + 1, tm->tm_year, tm->tm_wday);

	if (rtc_valid_tm(tm) < 0)
		dev_err(dev, "invalid date\n");

	return 0;
}
Пример #10
0
static int rs5c_read_alarm(struct device *dev, struct rtc_wkalrm *t)
{
	struct i2c_client	*client = to_i2c_client(dev);
	struct rs5c372		*rs5c = i2c_get_clientdata(client);
	int			status;

	status = rs5c_get_regs(rs5c);
	if (status < 0)
		return status;

	/* report alarm time */
	t->time.tm_sec = 0;
	t->time.tm_min = BCD2BIN(rs5c->regs[RS5C_REG_ALARM_A_MIN] & 0x7f);
	t->time.tm_hour = rs5c_reg2hr(rs5c, rs5c->regs[RS5C_REG_ALARM_A_HOURS]);
	t->time.tm_mday = -1;
	t->time.tm_mon = -1;
	t->time.tm_year = -1;
	t->time.tm_wday = -1;
	t->time.tm_yday = -1;
	t->time.tm_isdst = -1;

	/* ... and status */
	t->enabled = !!(rs5c->regs[RS5C_REG_CTRL1] & RS5C_CTRL1_AALE);
	t->pending = !!(rs5c->regs[RS5C_REG_CTRL2] & RS5C_CTRL2_AAFG);

	return 0;
}
Пример #11
0
static int menelaus_read_time(struct device *dev, struct rtc_time *t)
{
	struct i2c_msg	msg[2];
	char		regs[7];
	int		status;

	/* block read date and time registers */
	regs[0] = MENELAUS_RTC_SEC;

	msg[0].addr = MENELAUS_I2C_ADDRESS;
	msg[0].flags = 0;
	msg[0].len = 1;
	msg[0].buf = regs;

	msg[1].addr = MENELAUS_I2C_ADDRESS;
	msg[1].flags = I2C_M_RD;
	msg[1].len = sizeof(regs);
	msg[1].buf = regs;

	status = i2c_transfer(the_menelaus->client->adapter, msg, 2);
	if (status != 2) {
		dev_err(dev, "%s error %d\n", "read", status);
		return -EIO;
	}

	menelaus_to_time(regs, t);
	t->tm_wday = BCD2BIN(regs[6]);

	return 0;
}
Пример #12
0
/*
 * Decode time/date into rtc_time structure
 */
static void at91_rtc_decodetime(unsigned int timereg, unsigned int calreg,
				struct rtc_time *tm)
{
	unsigned int time, date;

	/* must read twice in case it changes */
	do {
		time = at91_sys_read(timereg);
		date = at91_sys_read(calreg);
	} while ((time != at91_sys_read(timereg)) ||
			(date != at91_sys_read(calreg)));

	tm->tm_sec  = BCD2BIN((time & AT91_RTC_SEC) >> 0);
	tm->tm_min  = BCD2BIN((time & AT91_RTC_MIN) >> 8);
	tm->tm_hour = BCD2BIN((time & AT91_RTC_HOUR) >> 16);

	/*
	 * The Calendar Alarm register does not have a field for
	 * the year - so these will return an invalid value.  When an
	 * alarm is set, at91_alarm_year wille store the current year.
	 */
	tm->tm_year  = BCD2BIN(date & AT91_RTC_CENT) * 100;	/* century */
	tm->tm_year += BCD2BIN((date & AT91_RTC_YEAR) >> 8);	/* year */

	tm->tm_wday = BCD2BIN((date & AT91_RTC_DAY) >> 21) - 1;	/* day of the week [0-6], Sunday=0 */
	tm->tm_mon  = BCD2BIN((date & AT91_RTC_MONTH) >> 16) - 1;
	tm->tm_mday = BCD2BIN((date & AT91_RTC_DATE) >> 24);
}
Пример #13
0
/*
 * In the routines that deal directly with the x1205 hardware, we use
 * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch
 * Epoch is initialized as 2000. Time is set to UTC.
 */
void rtc_get(struct rtc_time *tm)
{
	u8 buf[8];

	i2c_read(CFG_I2C_RTC_ADDR, X1205_CCR_BASE, 2, buf, 8);

	debug("%s: raw read data - sec=%02x, min=%02x, hr=%02x, "
	      "mday=%02x, mon=%02x, year=%02x, wday=%02x, y2k=%02x\n",
	      __FUNCTION__,
	      buf[0], buf[1], buf[2], buf[3],
	      buf[4], buf[5], buf[6], buf[7]);

	tm->tm_sec = BCD2BIN(buf[CCR_SEC]);
	tm->tm_min = BCD2BIN(buf[CCR_MIN]);
	tm->tm_hour = BCD2BIN(buf[CCR_HOUR] & 0x3F); /* hr is 0-23 */
	tm->tm_mday = BCD2BIN(buf[CCR_MDAY]);
	tm->tm_mon = BCD2BIN(buf[CCR_MONTH]); /* mon is 0-11 */
	tm->tm_year = BCD2BIN(buf[CCR_YEAR])
		+ (BCD2BIN(buf[CCR_Y2K]) * 100);
	tm->tm_wday = buf[CCR_WDAY];

	debug("%s: tm is secs=%d, mins=%d, hours=%d, "
	      "mday=%d, mon=%d, year=%d, wday=%d\n",
	      __FUNCTION__,
	      tm->tm_sec, tm->tm_min, tm->tm_hour,
	      tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
}
Пример #14
0
unsigned long m48t37y_get_time(void)
{
#ifdef CONFIG_MIPS64
	unsigned char *rtc_base = (unsigned char*)0xfffffffffc800000;
#else
	unsigned char* rtc_base = (unsigned char*)0xfc800000;
#endif
	unsigned int year, month, day, hour, min, sec;

	/* stop the update */
	rtc_base[0x7ff8] = 0x40;

	year = BCD2BIN(rtc_base[0x7fff]);
	year += BCD2BIN(rtc_base[0x7ff1]) * 100;

	month = BCD2BIN(rtc_base[0x7ffe]);

	day = BCD2BIN(rtc_base[0x7ffd]);

	hour = BCD2BIN(rtc_base[0x7ffb]);
	min = BCD2BIN(rtc_base[0x7ffa]);
	sec = BCD2BIN(rtc_base[0x7ff9]);

	/* start the update */
	rtc_base[0x7ff8] = 0x00;

	return mktime(year, month, day, hour, min, sec);
}
Пример #15
0
int
RTCFUNC(get,m41t00)(struct tm *tm, int cent_reg)
{
    unsigned char   date[7];
    unsigned char   century;

    m41t00_i2c_read(M41T00_SEC, date, 7);

    tm->tm_sec  = BCD2BIN(date[M41T00_SEC] & ~M41T00_SEC_ST);
    tm->tm_min  = BCD2BIN(date[M41T00_MIN]);
    tm->tm_hour = BCD2BIN(date[M41T00_HOUR] & 
                          ~(M41T00_HOUR_CEB|M41T00_HOUR_CB));
    tm->tm_mday = BCD2BIN(date[M41T00_DATE]);
    tm->tm_mon  = BCD2BIN(date[M41T00_MONTH]) - 1;
    tm->tm_year = BCD2BIN(date[M41T00_YEAR]);
    tm->tm_wday = BCD2BIN(date[M41T00_DAY]) - 1;

    if (date[M41T00_HOUR] & M41T00_HOUR_CEB) {
        century = date[M41T00_HOUR] & M41T00_HOUR_CB;
        if (century) {
            if (tm->tm_year < 70) 
                tm->tm_year += 200;
        } else {
            tm->tm_year += 100;
        }
    } else {
        if(tm->tm_year < 70) 
            tm->tm_year += 100;
    }
    return(0);
}
Пример #16
0
static int ds1216_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
    struct platform_device *pdev = to_platform_device(dev);
    struct ds1216_priv *priv = platform_get_drvdata(pdev);
    struct ds1216_regs regs;

    ds1216_switch_ds_to_clock(priv->ioaddr);
    ds1216_read(priv->ioaddr, (u8 *)&regs);

    tm->tm_sec = BCD2BIN(regs.sec);
    tm->tm_min = BCD2BIN(regs.min);
    if (regs.hour & DS1216_HOUR_1224) {
        /* AM/PM mode */
        tm->tm_hour = BCD2BIN(regs.hour & 0x1f);
        if (regs.hour & DS1216_HOUR_AMPM)
            tm->tm_hour += 12;
    } else
        tm->tm_hour = BCD2BIN(regs.hour & 0x3f);
    tm->tm_wday = (regs.wday & 7) - 1;
    tm->tm_mday = BCD2BIN(regs.mday & 0x3f);
    tm->tm_mon = BCD2BIN(regs.month & 0x1f);
    tm->tm_year = BCD2BIN(regs.year);
    if (tm->tm_year < 70)
        tm->tm_year += 100;
    return 0;
}
Пример #17
0
static unsigned long __init get_swarm_time(void)
{
    unsigned int year, mon, day, hour, min, sec, y2k;

    sec = xicor_read(X1241REG_SC);
    min = xicor_read(X1241REG_MN);
    hour = xicor_read(X1241REG_HR);

    if (hour & X1241REG_HR_MIL) {
        hour &= 0x3f;
    } else {
        if (hour & 0x20)
            hour = (hour & 0xf) + 0x12;
    }

    sec = BCD2BIN(sec);
    min = BCD2BIN(min);
    hour = BCD2BIN(hour);

    day = xicor_read(X1241REG_DT);
    mon = xicor_read(X1241REG_MO);
    year = xicor_read(X1241REG_YR);
    y2k = xicor_read(X1241REG_Y2K);

    day = BCD2BIN(day);
    mon = BCD2BIN(mon);
    year = BCD2BIN(year);
    y2k = BCD2BIN(y2k);

    year += (y2k * 100);

    return mktime(year, mon, day, hour, min, sec);
}
Пример #18
0
static int s353xxa_rtc_read_time(struct device *dev, struct rtc_time *t)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct i2c_msg msgs[1];
	u8 buf[7];
	int ret;

	DEBUG_FUNC();

	set_i2c_msg(&msgs[0], client->addr | 0x2, I2C_M_RD, 7, buf);
	ret = i2c_transfer(client->adapter, msgs, 1);
	if (ret != 1)
		return -EIO;

	t->tm_year = BCD2BIN(REVERSE(buf[0]));
	t->tm_mon = BCD2BIN(REVERSE(buf[1]));
	t->tm_mday = BCD2BIN(REVERSE(buf[2]));
	t->tm_wday = BCD2BIN(REVERSE(buf[3]));
	t->tm_hour = BCD2BIN(REVERSE(buf[4]) & 0x3f);
	t->tm_min = BCD2BIN(REVERSE(buf[5]));
	t->tm_sec = BCD2BIN(REVERSE(buf[6]));

	t->tm_year += 100;
	t->tm_mon -= 1;

	DEBUG_INFO("READ: %d/%d/%d(%d) %d:%d:%d\n",
		   t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_wday,
		   t->tm_hour, t->tm_min, t->tm_sec);

	return 0;
}
Пример #19
0
static int
s35392a_read_time(struct device* pDev, struct rtc_time* pTm)
{
	unsigned char rtc_reg[7];
	int ret;

	ret = s35392a_read_reg(S35392A_REALTIME_DATA1, rtc_reg, sizeof(rtc_reg));

	if (ret < 0)
	{
		return ret;
	}

	pTm->tm_sec = BCD2BIN(rtc_reg[6] & S35392A_SEC_MASK);
	pTm->tm_min = BCD2BIN(rtc_reg[5] & S35392A_MIN_MASK);
	pTm->tm_hour = BCD2BIN(rtc_reg[4] & S35392A_HOUR_MASK);
	pTm->tm_wday = BCD2BIN(rtc_reg[3] & S35392A_WDAY_MASK);
	pTm->tm_mday = BCD2BIN(rtc_reg[2] & S35392A_DAY_MASK);
	pTm->tm_mon = BCD2BIN(rtc_reg[1]  & S35392A_MON_MASK) - 1;		/* 0~11 for linux appl, 1~12 for rtc */
	pTm->tm_year = BCD2BIN(rtc_reg[0] & S35392A_YEAR_MASK) + 100;	/* 1900 for linux appl, 2000 for rtc */
	/* don't use tm_yday and tm_dst */

	MYTRACE(("%s : \n", __func__));
	MYTRACE(("YY:MM:DD:HH:MM:SS(%d:%2d:%2d:%2d:%2d:%2d)\n", pTm->tm_year, pTm->tm_mon, pTm->tm_mday, pTm->tm_hour, pTm->tm_min, pTm->tm_sec));

	return 0;
}
Пример #20
0
unsigned long xicor_get_time(void)
{
    unsigned int year, mon, day, hour, min, sec, y2k;
    unsigned long flags;

    spin_lock_irqsave(&rtc_lock, flags);
    sec = xicor_read(X1241REG_SC);
    min = xicor_read(X1241REG_MN);
    hour = xicor_read(X1241REG_HR);

    if (hour & X1241REG_HR_MIL) {
        hour &= 0x3f;
    } else {
        if (hour & 0x20)
            hour = (hour & 0xf) + 0x12;
    }

    day = xicor_read(X1241REG_DT);
    mon = xicor_read(X1241REG_MO);
    year = xicor_read(X1241REG_YR);
    y2k = xicor_read(X1241REG_Y2K);
    spin_unlock_irqrestore(&rtc_lock, flags);

    sec = BCD2BIN(sec);
    min = BCD2BIN(min);
    hour = BCD2BIN(hour);
    day = BCD2BIN(day);
    mon = BCD2BIN(mon);
    year = BCD2BIN(year);
    y2k = BCD2BIN(y2k);

    year += (y2k * 100);

    return mktime(year, mon, day, hour, min, sec);
}
Пример #21
0
unsigned long m48t37y_get_time(void)
{
	unsigned int year, month, day, hour, min, sec;
	unsigned long flags;

	spin_lock_irqsave(&rtc_lock, flags);
	/* stop the update */
	rtc_base[0x7ff8] = 0x40;

	year = BCD2BIN(rtc_base[0x7fff]);
	year += BCD2BIN(rtc_base[0x7ff1]) * 100;

	month = BCD2BIN(rtc_base[0x7ffe]);

	day = BCD2BIN(rtc_base[0x7ffd]);

	hour = BCD2BIN(rtc_base[0x7ffb]);
	min = BCD2BIN(rtc_base[0x7ffa]);
	sec = BCD2BIN(rtc_base[0x7ff9]);

	/* start the update */
	rtc_base[0x7ff8] = 0x00;
	spin_unlock_irqrestore(&rtc_lock, flags);

	return mktime(year, month, day, hour, min, sec);
}
Пример #22
0
/*
 * In order to set the CMOS clock precisely, dec_rtc_set_mmss has to
 * be called 500 ms after the second nowtime has started, because when
 * nowtime is written into the registers of the CMOS clock, it will
 * jump to the next second precisely 500 ms later.  Check the Dallas
 * DS1287 data sheet for details.
 */
static int dec_rtc_set_mmss(unsigned long nowtime)
{
	int retval = 0;
	int real_seconds, real_minutes, cmos_minutes;
	unsigned char save_control, save_freq_select;

	/* tell the clock it's being set */
	save_control = CMOS_READ(RTC_CONTROL);
	CMOS_WRITE((save_control | RTC_SET), RTC_CONTROL);

	/* stop and reset prescaler */
	save_freq_select = CMOS_READ(RTC_FREQ_SELECT);
	CMOS_WRITE((save_freq_select | RTC_DIV_RESET2), RTC_FREQ_SELECT);

	cmos_minutes = CMOS_READ(RTC_MINUTES);
	if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
		cmos_minutes = BCD2BIN(cmos_minutes);

	/*
	 * 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) {
		if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
			real_seconds = BIN2BCD(real_seconds);
			real_minutes = BIN2BCD(real_minutes);
		}
		CMOS_WRITE(real_seconds, RTC_SECONDS);
		CMOS_WRITE(real_minutes, RTC_MINUTES);
	} else {
		printk(KERN_WARNING
		       "set_rtc_mmss: can't update from %d to %d\n",
		       cmos_minutes, real_minutes);
		retval = -1;
	}

	/* The following flags have to be released exactly in this order,
	 * otherwise the DS1287 will not reset the oscillator and will not
	 * update precisely 500 ms later.  You won't find this mentioned
	 * in the Dallas Semiconductor data sheets, but who believes data
	 * sheets anyway ...                           -- Markus Kuhn
	 */
	CMOS_WRITE(save_control, RTC_CONTROL);
	CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);

	return retval;
}
Пример #23
0
static uint64_t
rtc_get_alarm_impl(struct rtc_interface *ti,
                   struct s3c2410_rtc *device)
{
    uint64_t unix_time;
    struct rtc_time tm;

    tm.sec  = BCD2BIN(almsec_get_secdata());
    tm.min  = BCD2BIN(almmin_get_mindata());
    tm.hour = BCD2BIN(almhour_get_hourdata());
    tm.date = BCD2BIN(almdate_get_datedata());
    tm.mon  = BCD2BIN(almmon_get_mondata());
    tm.year = almyear_get_yeardata();

    if (rtc_to_unix(&unix_time, &tm) != 0) {
        printf("%s: WARNING RTC returned invalid time value\n", __func__);
    }

    return unix_time;
}
Пример #24
0
static __init unsigned long get_m48t35_time(void)
{
        unsigned int year, month, date, hour, min, sec;
	struct m48t35_rtc *rtc;
	nasid_t nid;

	nid = get_nasid();
	rtc = (struct m48t35_rtc *)(KL_CONFIG_CH_CONS_INFO(nid)->memory_base +
							IOC3_BYTEBUS_DEV0);

	rtc->control |= M48T35_RTC_READ;
	sec = rtc->sec;
	min = rtc->min;
	hour = rtc->hour;
	date = rtc->date;
	month = rtc->month;
	year = rtc->year;
	rtc->control &= ~M48T35_RTC_READ;

        sec = BCD2BIN(sec);
        min = BCD2BIN(min);
        hour = BCD2BIN(hour);
        date = BCD2BIN(date);
        month = BCD2BIN(month);
        year = BCD2BIN(year);

        year += 1970;

        return mktime(year, month, date, hour, min, sec);
}
Пример #25
0
/*
 * note that mktime uses month from 1 to 12 while to_tm
 * uses 0 to 11.
 */
static unsigned long indy_rtc_get_time(void)
{
	unsigned int yrs, mon, day, hrs, min, sec;
	unsigned int save_control;
	unsigned long flags;

	spin_lock_irqsave(&rtc_lock, flags);
	save_control = hpc3c0->rtcregs[RTC_CMD] & 0xff;
	hpc3c0->rtcregs[RTC_CMD] = save_control | RTC_TE;

	sec = BCD2BIN(hpc3c0->rtcregs[RTC_SECONDS] & 0xff);
	min = BCD2BIN(hpc3c0->rtcregs[RTC_MINUTES] & 0xff);
	hrs = BCD2BIN(hpc3c0->rtcregs[RTC_HOURS] & 0x3f);
	day = BCD2BIN(hpc3c0->rtcregs[RTC_DATE] & 0xff);
	mon = BCD2BIN(hpc3c0->rtcregs[RTC_MONTH] & 0x1f);
	yrs = BCD2BIN(hpc3c0->rtcregs[RTC_YEAR] & 0xff);

	hpc3c0->rtcregs[RTC_CMD] = save_control;
	spin_unlock_irqrestore(&rtc_lock, flags);

	if (yrs < 45)
		yrs += 30;
	if ((yrs += 40) < 70)
		yrs += 100;

	return mktime(yrs + 1900, mon, day, hrs, min, sec);
}
Пример #26
0
// see http://wiki.osdev.org/CMOS
//int syscalls
void syscall_get_time(struct rtc_time * time)
{
	uint8_t registerB = get_rtc_crt(RTC_STATS_MASK_STATUS_REGISTER_B);

	unsigned char sec 	= get_rtc_seconds();
	unsigned char min 	= get_rtc_minutes();
	unsigned char hour	= get_rtc_hours();
	unsigned char mon	= get_rtc_month();
	unsigned char year	= get_rtc_year();
	unsigned char day	= get_rtc_day_of_month();

    // Convert BCD to binary values if necessary
	if (!(registerB & 0x04)) {
	    sec 	= BCD2BIN(sec);
	    min 	= BCD2BIN(min);
	    hour 	= BCD2BIN(hour);
	    day 	= BCD2BIN(day);
	    mon 	= BCD2BIN(mon);
	    year 	= BCD2BIN(year);
	}

	// Convert 12 hour clock to 24 hour clock if necessary

	if (!(registerB & 0x02) && (hour & 0x80)) {
	    hour = ((hour & 0x7F) + 12) % 24;
	}

	time->sec 	= sec;
	time->min 	= min;
	time->hour	= hour;
	time->mon	= mon;
	time->year	= year;
	time->day	= day;
}
Пример #27
0
int
RTCFUNC(get,m41t81)(struct tm *tm, int cent_reg) {
	unsigned	sec;
	unsigned	min;
	unsigned	hour;
	unsigned	mday;
	unsigned	mon;
	unsigned	year;


	// convert BCD to binary 
	sec 	= smbus_readrtc(RTC_SLAVE_ADDR,M41T81REG_SC) & 0xFF;
	min 	= smbus_readrtc(RTC_SLAVE_ADDR,M41T81REG_MN) & 0xFF;	
	hour	= smbus_readrtc(RTC_SLAVE_ADDR,M41T81REG_HR) & ~(M41T81_CENT | M41T81_CEB);
	mday	= smbus_readrtc(RTC_SLAVE_ADDR,M41T81REG_DT) & 0xFF;
	mon		= smbus_readrtc(RTC_SLAVE_ADDR,M41T81REG_MO) & 0xFF;
	year	= smbus_readrtc(RTC_SLAVE_ADDR,M41T81REG_YR) & 0xFF;

	tm->tm_sec 	= BCD2BIN(sec);
	tm->tm_min 	= BCD2BIN(min);
	tm->tm_hour	= BCD2BIN(hour);
	tm->tm_mday	= BCD2BIN(mday);
	tm->tm_mon	= BCD2BIN(mon) - 1;
	tm->tm_year	= BCD2BIN(year);

	if ( smbus_readrtc(RTC_SLAVE_ADDR,M41T81REG_HR) & M41T81_CENT )
		tm->tm_year += 100;

	return(0);
}
Пример #28
0
unsigned long m41t81_get_time(void)
{
	unsigned int year, mon, day, hour, min, sec;
	unsigned long flags;

	/*
	 * min is valid if two reads of sec are the same.
	 */
	for (;;) {
		spin_lock_irqsave(&rtc_lock, flags);
		sec = m41t81_read(M41T81REG_SC);
		min = m41t81_read(M41T81REG_MN);
		if (sec == m41t81_read(M41T81REG_SC)) break;
		spin_unlock_irqrestore(&rtc_lock, flags);
	}
	hour = m41t81_read(M41T81REG_HR) & 0x3f;
	day = m41t81_read(M41T81REG_DT);
	mon = m41t81_read(M41T81REG_MO);
	year = m41t81_read(M41T81REG_YR);
	spin_unlock_irqrestore(&rtc_lock, flags);

	sec = BCD2BIN(sec);
	min = BCD2BIN(min);
	hour = BCD2BIN(hour);
	day = BCD2BIN(day);
	mon = BCD2BIN(mon);
	year = BCD2BIN(year);

	year += 2000;

	return mktime(year, mon, day, hour, min, sec);
}
Пример #29
0
int
RTCFUNC(get,omap)(struct tm *tm, int cent_reg) {
	unsigned	sec;
	unsigned	min;
	unsigned	hour;
	unsigned	mday;
	unsigned	mon;
	unsigned	year;


	// convert BCD to binary 
	sec 	= chip_read(OMAP_RTC_SECONDS,32) & 0xff;
	min 	= chip_read(OMAP_RTC_MINUTES,32) & 0xff;	
	hour	= chip_read(OMAP_RTC_HOURS,32) & 0xff;
	mday	= chip_read(OMAP_RTC_DAYS,32) & 0xff;
	mon		= chip_read(OMAP_RTC_MONTHS,32) & 0xff;
	year	= chip_read(OMAP_RTC_YEARS,32)& 0xff;

	tm->tm_sec 	= BCD2BIN(sec);
	tm->tm_min 	= BCD2BIN(min);
	tm->tm_hour	= BCD2BIN(hour);
	tm->tm_mday	= BCD2BIN(mday);
	tm->tm_mon	= BCD2BIN(mon);
	tm->tm_year	= BCD2BIN(year) + 100;

	return(0);
}
Пример #30
0
int rtc_get(struct rtc_time *tm)
{
	u8 buf[M41T62_DATETIME_REG_SIZE];

	i2c_read(CONFIG_SYS_I2C_RTC_ADDR, 0, 1, buf, M41T62_DATETIME_REG_SIZE);

	debug("%s: raw read data - sec=%02x, min=%02x, hr=%02x, "
	      "mday=%02x, mon=%02x, year=%02x, wday=%02x, y2k=%02x\n",
	      __FUNCTION__,
	      buf[0], buf[1], buf[2], buf[3],
	      buf[4], buf[5], buf[6], buf[7]);

	tm->tm_sec = BCD2BIN(buf[M41T62_REG_SEC] & 0x7f);
	tm->tm_min = BCD2BIN(buf[M41T62_REG_MIN] & 0x7f);
	tm->tm_hour = BCD2BIN(buf[M41T62_REG_HOUR] & 0x3f);
	tm->tm_mday = BCD2BIN(buf[M41T62_REG_DAY] & 0x3f);
	tm->tm_wday = buf[M41T62_REG_WDAY] & 0x07;
	tm->tm_mon = BCD2BIN(buf[M41T62_REG_MON] & 0x1f);

	/* assume 20YY not 19YY, and ignore the Century Bit */
	/* U-Boot needs to add 1900 here */
	tm->tm_year = BCD2BIN(buf[M41T62_REG_YEAR]) + 100 + 1900;

	debug("%s: tm is secs=%d, mins=%d, hours=%d, "
	      "mday=%d, mon=%d, year=%d, wday=%d\n",
	      __FUNCTION__,
	      tm->tm_sec, tm->tm_min, tm->tm_hour,
	      tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);

	return 0;
}