static int da8xx_rtc_bin2bcd(struct rtc_time *tm) { if (rtc_valid_tm(tm) != 0) return -EINVAL; tm->tm_sec = BIN2BCD(tm->tm_sec); tm->tm_min = BIN2BCD(tm->tm_min); tm->tm_hour = BIN2BCD(tm->tm_hour); tm->tm_mday = BIN2BCD(tm->tm_mday); tm->tm_mon = BIN2BCD(tm->tm_mon + 1); tm->tm_year = BIN2BCD(tm->tm_year % 100); return 0; }
static int stk17ta8_rtc_set_time(struct device *dev, struct rtc_time *tm) { struct platform_device *pdev = to_platform_device(dev); struct rtc_plat_data *pdata = platform_get_drvdata(pdev); void __iomem *ioaddr = pdata->ioaddr; u8 flags; flags = readb(pdata->ioaddr + RTC_FLAGS); writeb(flags | RTC_WRITE, pdata->ioaddr + RTC_FLAGS); writeb(BIN2BCD(tm->tm_year % 100), ioaddr + RTC_YEAR); writeb(BIN2BCD(tm->tm_mon + 1), ioaddr + RTC_MONTH); writeb(BIN2BCD(tm->tm_wday) & RTC_DAY_MASK, ioaddr + RTC_DAY); writeb(BIN2BCD(tm->tm_mday), ioaddr + RTC_DATE); writeb(BIN2BCD(tm->tm_hour), ioaddr + RTC_HOURS); writeb(BIN2BCD(tm->tm_min), ioaddr + RTC_MINUTES); writeb(BIN2BCD(tm->tm_sec) & RTC_SECONDS_MASK, ioaddr + RTC_SECONDS); writeb(BIN2BCD((tm->tm_year + 1900) / 100), ioaddr + RTC_CENTURY); writeb(flags & ~RTC_WRITE, pdata->ioaddr + RTC_FLAGS); return 0; }
int m48t37y_set_time(unsigned long sec) { #ifdef CONFIG_MIPS64 unsigned char* rtc_base = (unsigned char*)0xfffffffffc800000; #else unsigned char* rtc_base = (unsigned char*)0xfc800000; #endif struct rtc_time tm; /* convert to a more useful format -- note months count from 0 */ to_tm(sec, &tm); tm.tm_mon += 1; /* enable writing */ rtc_base[0x7ff8] = 0x80; /* year */ rtc_base[0x7fff] = BIN2BCD(tm.tm_year % 100); rtc_base[0x7ff1] = BIN2BCD(tm.tm_year / 100); /* month */ rtc_base[0x7ffe] = BIN2BCD(tm.tm_mon); /* day */ rtc_base[0x7ffd] = BIN2BCD(tm.tm_mday); /* hour/min/sec */ rtc_base[0x7ffb] = BIN2BCD(tm.tm_hour); rtc_base[0x7ffa] = BIN2BCD(tm.tm_min); rtc_base[0x7ff9] = BIN2BCD(tm.tm_sec); /* day of week -- not really used, but let's keep it up-to-date */ rtc_base[0x7ffc] = BIN2BCD(tm.tm_wday + 1); /* disable writing */ rtc_base[0x7ff8] = 0x00; return 0; }
int RTCFUNC(set,ds15x1)(struct tm *tm, int cent_reg) { unsigned seconds; unsigned minutes; unsigned hours; unsigned day; unsigned month; unsigned year; unsigned cent; unsigned ctrlb; /* convert binary to BCD */ seconds = BIN2BCD(tm->tm_sec); minutes = BIN2BCD(tm->tm_min); hours = BIN2BCD(tm->tm_hour); day = BIN2BCD(tm->tm_mday); month = BIN2BCD(tm->tm_mon + 1); year = BIN2BCD(tm->tm_year % 100); cent = BIN2BCD((tm->tm_year / 100) + 19); #ifdef DIAG fprintf(stderr,"rtc set: cent=%d; year=%d (after adjustment)\n",cent,year); #endif month |= chip_read8(5) & 0xE0; /* EOSC#/E32K#/BB32 */ ctrlb = chip_read8(DS15x1_CONTROLB); chip_write8(DS15x1_CONTROLB, ctrlb & ~TRANSFER_ENABLE); chip_write8(0, seconds); chip_write8(1, minutes); chip_write8(2, hours); chip_write8(3, tm->tm_wday + 1); chip_write8(4, day); chip_write8(5, month); chip_write8(6, year); if (cent_reg >= 0) chip_write8(cent_reg, cent); chip_write8(DS15x1_CONTROLB, ctrlb | TRANSFER_ENABLE); return (0); }
int RTCFUNC(set,ds1386)(struct tm *tm, int cent_reg) { unsigned seconds; unsigned minutes; unsigned hours; unsigned day; unsigned month; unsigned year; unsigned cent; // convert binary to BCD seconds = BIN2BCD(tm->tm_sec); minutes = BIN2BCD(tm->tm_min); hours = BIN2BCD(tm->tm_hour); day = BIN2BCD(tm->tm_mday); month = BIN2BCD(tm->tm_mon + 1); year = BIN2BCD(tm->tm_year % 100); cent = BIN2BCD((tm->tm_year / 100) + 19); #ifdef DIAG fprintf(stderr,"rtc set: cent=%d; year=%d (after adjustment)\n",cent,year); #endif month |= chip_read8(9) & 0x40; /* ESQW# */ chip_write8(9, 0); /* turn off clock */ chip_write8(0, 0); //hundredth's of second chip_write8(1, seconds); chip_write8(2, minutes); chip_write8(4, hours | MILTIME); chip_write8(6, tm->tm_wday + 1); chip_write8(8, day); chip_write8(10, year); if(cent_reg >= 0) { chip_write8(cent_reg, cent); } chip_write8(9, month & 0x5f); /* EOSC# low to start clock */ chip_write8(CMD_REG, chip_read8(CMD_REG) | TRANSFER_ENABLE); return(0); }
int rtc_set (struct rtc_time* tm) { if(tm->tm_year < 2000) tm->tm_year -= 1900; else tm->tm_year -= 2000; RTCCON |= 1; BCDYEAR = BIN2BCD(tm->tm_year); BCDMON = BIN2BCD(tm->tm_mon); BCDDAY = BIN2BCD(tm->tm_mday); BCDDATE = BIN2BCD(tm->tm_wday); BCDHOUR = BIN2BCD(tm->tm_hour); BCDMIN = BIN2BCD(tm->tm_min); BCDSEC = BIN2BCD(tm->tm_sec); RTCCON &= 1; return 0; }
static int s3c2410_rtc_settime(struct rtc_time *tm) { /* the rtc gets round the y2k problem by just not supporting it */ if (tm->tm_year < 100) return -EINVAL; writeb(BIN2BCD(tm->tm_sec), S3C2410_RTCSEC); writeb(BIN2BCD(tm->tm_min), S3C2410_RTCMIN); writeb(BIN2BCD(tm->tm_hour), S3C2410_RTCHOUR); writeb(BIN2BCD(tm->tm_mday), S3C2410_RTCDATE); writeb(BIN2BCD(tm->tm_mon + 1), S3C2410_RTCMON); writeb(BIN2BCD(tm->tm_year - 100), S3C2410_RTCYEAR); return 0; }
int m41t81_set_time(unsigned long t) { struct rtc_time tm; to_tm(t, &tm); /* * Note the write order matters as it ensures the correctness. * When we write sec, 10th sec is clear. It is reasonable to * believe we should finish writing min within a second. */ tm.tm_sec = BIN2BCD(tm.tm_sec); m41t81_write(M41T81REG_SC, tm.tm_sec); tm.tm_min = BIN2BCD(tm.tm_min); m41t81_write(M41T81REG_MN, tm.tm_min); tm.tm_hour = BIN2BCD(tm.tm_hour); tm.tm_hour = (tm.tm_hour & 0x3f) | (m41t81_read(M41T81REG_HR) & 0xc0); m41t81_write(M41T81REG_HR, tm.tm_hour); /* tm_wday starts from 0 to 6 */ if (tm.tm_wday == 0) tm.tm_wday = 7; tm.tm_wday = BIN2BCD(tm.tm_wday); m41t81_write(M41T81REG_DY, tm.tm_wday); tm.tm_mday = BIN2BCD(tm.tm_mday); m41t81_write(M41T81REG_DT, tm.tm_mday); /* tm_mon starts from 0, *ick* */ tm.tm_mon ++; tm.tm_mon = BIN2BCD(tm.tm_mon); m41t81_write(M41T81REG_MO, tm.tm_mon); /* we don't do century, everything is beyond 2000 */ tm.tm_year %= 100; tm.tm_year = BIN2BCD(tm.tm_year); m41t81_write(M41T81REG_YR, tm.tm_year); return 0; }
int m48t37y_set_time(unsigned long sec) { struct rtc_time tm; unsigned long flags; /* convert to a more useful format -- note months count from 0 */ to_tm(sec, &tm); tm.tm_mon += 1; spin_lock_irqsave(&rtc_lock, flags); /* enable writing */ rtc_base[0x7ff8] = 0x80; /* year */ rtc_base[0x7fff] = BIN2BCD(tm.tm_year % 100); rtc_base[0x7ff1] = BIN2BCD(tm.tm_year / 100); /* month */ rtc_base[0x7ffe] = BIN2BCD(tm.tm_mon); /* day */ rtc_base[0x7ffd] = BIN2BCD(tm.tm_mday); /* hour/min/sec */ rtc_base[0x7ffb] = BIN2BCD(tm.tm_hour); rtc_base[0x7ffa] = BIN2BCD(tm.tm_min); rtc_base[0x7ff9] = BIN2BCD(tm.tm_sec); /* day of week -- not really used, but let's keep it up-to-date */ rtc_base[0x7ffc] = BIN2BCD(tm.tm_wday + 1); /* disable writing */ rtc_base[0x7ff8] = 0x00; spin_unlock_irqrestore(&rtc_lock, flags); return 0; }
int m48t37y_set_time(unsigned long sec) { struct rtc_time tm; unsigned long flags; /* convert to a more useful format -- note months count from 0 */ to_tm(sec, &tm); tm.tm_mon += 1; spin_lock_irqsave(&rtc_lock, flags); /* enable writing */ m48t37_base->control = 0x80; /* year */ m48t37_base->year = BIN2BCD(tm.tm_year % 100); m48t37_base->century = BIN2BCD(tm.tm_year / 100); /* month */ m48t37_base->month = BIN2BCD(tm.tm_mon); /* day */ m48t37_base->date = BIN2BCD(tm.tm_mday); /* hour/min/sec */ m48t37_base->hour = BIN2BCD(tm.tm_hour); m48t37_base->min = BIN2BCD(tm.tm_min); m48t37_base->sec = BIN2BCD(tm.tm_sec); /* day of week -- not really used, but let's keep it up-to-date */ m48t37_base->day = BIN2BCD(tm.tm_wday + 1); /* disable writing */ m48t37_base->control = 0x00; spin_unlock_irqrestore(&rtc_lock, flags); return 0; }
int RTCFUNC(set,mc9s08dz60)(struct tm *tm, int cent_reg) { uint8_t date[7]; date[MC9S08DZ60_SEC] = BIN2BCD(tm->tm_sec) | MC9S08DZ60_RTC_RUN; date[MC9S08DZ60_MIN] = BIN2BCD(tm->tm_min); date[MC9S08DZ60_HOUR] = BIN2BCD(tm->tm_hour); date[MC9S08DZ60_DAY] = BIN2BCD(tm->tm_wday + 1); date[MC9S08DZ60_DATE] = BIN2BCD(tm->tm_mday - 1); date[MC9S08DZ60_MONTH] = BIN2BCD(tm->tm_mon); date[MC9S08DZ60_YEAR] = BIN2BCD(tm->tm_year % 100); if (mc9s08dz60_i2c_write(MC9S08DZ60_REAL_TIME_DATA, date, 7) != EOK) { fprintf(stderr, "Unable to write data to I2C device\n"); return -1; } return(0); }
/*! * \brief Set an PCF85XX hardware clock. * * New time will be taken over at the beginning of the next second. * * \param rtc Specifies the RTC device. * \param tm Points to a structure which contains the date and time * information. * * \return 0 on success or -1 in case of an error. */ static int I2cPcfSetClock(NUTRTC *rtc, const struct _tm *tm) { uint8_t data[8]; data[0] = 2; data[1] = BIN2BCD(tm->tm_sec); data[2] = BIN2BCD(tm->tm_min); data[3] = BIN2BCD(tm->tm_hour); data[4] = BIN2BCD(tm->tm_mday); data[5] = tm->tm_wday; data[6] = BIN2BCD(tm->tm_mon + 1); if (tm->tm_year > 99) { data[7] = BIN2BCD(tm->tm_year - 100); data[6] |= 0x80; } else { data[7] = BIN2BCD(tm->tm_year); } return NutI2cMasterTransceive(rtc->dcb, data, 8, NULL, 0); }
static int ds1742_rtc_set_time(struct device *dev, struct rtc_time *tm) { struct platform_device *pdev = to_platform_device(dev); struct rtc_plat_data *pdata = platform_get_drvdata(pdev); void __iomem *ioaddr = pdata->ioaddr_rtc; u8 century; century = BIN2BCD((tm->tm_year + 1900) / 100); writeb(RTC_WRITE, ioaddr + RTC_CONTROL); writeb(BIN2BCD(tm->tm_year % 100), ioaddr + RTC_YEAR); writeb(BIN2BCD(tm->tm_mon + 1), ioaddr + RTC_MONTH); writeb(BIN2BCD(tm->tm_wday) & RTC_DAY_MASK, ioaddr + RTC_DAY); writeb(BIN2BCD(tm->tm_mday), ioaddr + RTC_DATE); writeb(BIN2BCD(tm->tm_hour), ioaddr + RTC_HOURS); writeb(BIN2BCD(tm->tm_min), ioaddr + RTC_MINUTES); writeb(BIN2BCD(tm->tm_sec) & RTC_SECONDS_MASK, ioaddr + RTC_SECONDS); /* RTC_CENTURY and RTC_CONTROL share same register */ writeb(RTC_WRITE | (century & RTC_CENTURY_MASK), ioaddr + RTC_CENTURY); writeb(century & RTC_CENTURY_MASK, ioaddr + RTC_CONTROL); return 0; }
static int max6902_set_datetime(struct device *dev, struct rtc_time *dt) { dt->tm_year = dt->tm_year+1900; #ifdef MAX6902_DEBUG printk("\n%s : Setting RTC values\n",__FUNCTION__); printk("tm_sec : %i\n",dt->tm_sec); printk("tm_min : %i\n",dt->tm_min); printk("tm_hour: %i\n",dt->tm_hour); printk("tm_mday: %i\n",dt->tm_mday); printk("tm_wday: %i\n",dt->tm_wday); printk("tm_year: %i\n",dt->tm_year); #endif /* Remove write protection */ max6902_set_reg(dev, 0xF, 0); max6902_set_reg(dev, 0x01, BIN2BCD(dt->tm_sec)); max6902_set_reg(dev, 0x03, BIN2BCD(dt->tm_min)); max6902_set_reg(dev, 0x05, BIN2BCD(dt->tm_hour)); max6902_set_reg(dev, 0x07, BIN2BCD(dt->tm_mday)); max6902_set_reg(dev, 0x09, BIN2BCD(dt->tm_mon+1)); max6902_set_reg(dev, 0x0B, BIN2BCD(dt->tm_wday)); max6902_set_reg(dev, 0x0D, BIN2BCD(dt->tm_year%100)); max6902_set_reg(dev, 0x13, BIN2BCD(dt->tm_year/100)); /* Compulab used a delay here. However, the datasheet * does not mention a delay being required anywhere... */ /* delay(2000); */ /* Write protect */ max6902_set_reg(dev, 0xF, 0x80); return 0; }
int RTCFUNC(set,m41t6x)(struct tm *tm, int cent_reg) { unsigned char date[7]; char century; date[M41T6x_SEC] = BIN2BCD(tm->tm_sec); /* implicitly clears stop bit */ date[M41T6x_MIN] = BIN2BCD(tm->tm_min); date[M41T6x_HOUR] = BIN2BCD(tm->tm_hour); date[M41T6x_DAY] = BIN2BCD(tm->tm_wday + 1); date[M41T6x_DATE] = BIN2BCD(tm->tm_mday); date[M41T6x_MONTH] = BIN2BCD(tm->tm_mon + 1); date[M41T6x_YEAR] = BIN2BCD(tm->tm_year % 100); century = tm->tm_year / 100 - 1; date[M41T6x_MONTH] |= century << 6; m41t6x_i2c_write(M41T6x_REGOFFSET, date, 7); return(0); }
static int menelaus_set_time(struct device *dev, struct rtc_time *t) { int status; /* write date and time registers */ status = time_to_menelaus(t, MENELAUS_RTC_SEC); if (status < 0) return status; status = menelaus_write_reg(MENELAUS_RTC_WKDAY, BIN2BCD(t->tm_wday)); if (status < 0) { dev_err(&the_menelaus->client->dev, "rtc write reg %02x" "err %d\n", MENELAUS_RTC_WKDAY, status); return status; } /* now commit the write */ status = menelaus_write_reg(MENELAUS_RTC_UPDATE, RTC_UPDATE_EVERY); if (status < 0) dev_err(&the_menelaus->client->dev, "rtc commit time, err %d\n", status); return 0; }
static int r9701_set_datetime(struct device *dev, struct rtc_time *dt) { int ret, year; year = dt->tm_year + 1900; if (year >= 2100 || year < 2000) return -EINVAL; ret = write_reg(dev, RHRCNT, BIN2BCD(dt->tm_hour)); ret = ret ? ret : write_reg(dev, RMINCNT, BIN2BCD(dt->tm_min)); ret = ret ? ret : write_reg(dev, RSECCNT, BIN2BCD(dt->tm_sec)); ret = ret ? ret : write_reg(dev, RDAYCNT, BIN2BCD(dt->tm_mday)); ret = ret ? ret : write_reg(dev, RMONCNT, BIN2BCD(dt->tm_mon + 1)); ret = ret ? ret : write_reg(dev, RYRCNT, BIN2BCD(dt->tm_year - 100)); ret = ret ? ret : write_reg(dev, RWKCNT, 1 << dt->tm_wday); return ret; }
static int pcf8563_set_datetime(struct i2c_client *client, struct rtc_time *tm) { int i, err; unsigned char buf[9]; dev_dbg(&client->dev, "%s: 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); /* hours, minutes and seconds */ buf[PCF8563_REG_SC] = BIN2BCD(tm->tm_sec); buf[PCF8563_REG_MN] = BIN2BCD(tm->tm_min); buf[PCF8563_REG_HR] = BIN2BCD(tm->tm_hour); buf[PCF8563_REG_DM] = BIN2BCD(tm->tm_mday); /* month, 1 - 12 */ buf[PCF8563_REG_MO] = BIN2BCD(tm->tm_mon + 1); /* year and century */ buf[PCF8563_REG_YR] = BIN2BCD(tm->tm_year % 100); if (tm->tm_year / 100) buf[PCF8563_REG_MO] |= PCF8563_MO_C; buf[PCF8563_REG_DW] = tm->tm_wday & 0x07; /* write register's data */ for (i = 0; i < 7; i++) { unsigned char data[2] = { PCF8563_REG_SC + i, buf[PCF8563_REG_SC + i] }; err = i2c_master_send(client, data, sizeof(data)); if (err != sizeof(data)) { dev_err(&client->dev, "%s: err=%d addr=%02x, data=%02x\n", __FUNCTION__, err, data[0], data[1]); return -EIO; } }; return 0; }
int RTCFUNC(set,m41t00)(struct tm *tm, int cent_reg) { unsigned char date[7]; char century; date[M41T00_SEC] = BIN2BCD(tm->tm_sec); /* implicitly clears stop bit */ date[M41T00_MIN] = BIN2BCD(tm->tm_min); date[M41T00_HOUR] = BIN2BCD(tm->tm_hour) | M41T00_HOUR_CEB; date[M41T00_DAY] = BIN2BCD(tm->tm_wday + 1); date[M41T00_DATE] = BIN2BCD(tm->tm_mday); date[M41T00_MONTH] = BIN2BCD(tm->tm_mon + 1); date[M41T00_YEAR] = BIN2BCD(tm->tm_year % 100); century = tm->tm_year / 100 - 1; if (century != 0) date[M41T00_HOUR] |= M41T00_HOUR_CB; m41t00_i2c_write(M41T00_SEC, date, 7); return(0); }
/* this hardware doesn't support "don't care" alarm fields */ static int tm2bcd(struct rtc_time *tm) { if (rtc_valid_tm(tm) != 0) return -EINVAL; tm->tm_sec = BIN2BCD(tm->tm_sec); tm->tm_min = BIN2BCD(tm->tm_min); tm->tm_hour = BIN2BCD(tm->tm_hour); tm->tm_mday = BIN2BCD(tm->tm_mday); tm->tm_mon = BIN2BCD(tm->tm_mon + 1); /* epoch == 1900 */ if (tm->tm_year < 100 || tm->tm_year > 199) return -EINVAL; tm->tm_year = BIN2BCD(tm->tm_year - 100); return 0; }
/*! * \brief Set an PCF8563 hardware clock. * * New time will be taken over at the beginning of the next second. * * \param tm Points to a structure which contains the date and time * information. * * \return 0 on success or -1 in case of an error. */ int PcfRtcSetClock(NUTRTC *rtc, const struct _tm *tm) { uint8_t data[8]; memset(data, 0, sizeof(data)); if (tm) { data[0] = 0x02; data[1] = BIN2BCD(tm->tm_sec); data[2] = BIN2BCD(tm->tm_min); data[3] = BIN2BCD(tm->tm_hour); data[4] = BIN2BCD(tm->tm_mday); data[5] = tm->tm_wday; data[6] = BIN2BCD(tm->tm_mon + 1); if (tm->tm_year > 99) { data[7] = BIN2BCD(tm->tm_year - 100); data[6] |= 0x80; } else { data[7] = BIN2BCD(tm->tm_year); } } return PcfRtcWrite(0, data, 8); }
int rtc_set(struct rtc_time *tm) { int i; u8 buf[8]; debug("Set DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_wday, tm->tm_hour, tm->tm_min, tm->tm_sec); buf[CCR_SEC] = BIN2BCD(tm->tm_sec); buf[CCR_MIN] = BIN2BCD(tm->tm_min); /* set hour and 24hr bit */ buf[CCR_HOUR] = BIN2BCD(tm->tm_hour) | X1205_HR_MIL; buf[CCR_MDAY] = BIN2BCD(tm->tm_mday); /* month, 1 - 12 */ buf[CCR_MONTH] = BIN2BCD(tm->tm_mon); /* year, since the rtc epoch*/ buf[CCR_YEAR] = BIN2BCD(tm->tm_year % 100); buf[CCR_WDAY] = tm->tm_wday & 0x07; buf[CCR_Y2K] = BIN2BCD(tm->tm_year / 100); /* this sequence is required to unlock the chip */ rtc_write(X1205_REG_SR, X1205_SR_WEL); rtc_write(X1205_REG_SR, X1205_SR_WEL | X1205_SR_RWEL); /* write register's data */ for (i = 0; i < 8; i++) rtc_write(X1205_CCR_BASE + i, buf[i]); rtc_write(X1205_REG_SR, 0); return 0; }
static int twl4030_rtc_set_time(struct device *dev, struct rtc_time *tm) { unsigned char save_control; unsigned char rtc_data[ALL_TIME_REGS + 1]; int ret; /* Month range is 01..12 */ tm->tm_mon++; rtc_data[1] = BIN2BCD(tm->tm_sec); rtc_data[2] = BIN2BCD(tm->tm_min); rtc_data[3] = BIN2BCD(tm->tm_hour); rtc_data[4] = BIN2BCD(tm->tm_mday); rtc_data[5] = BIN2BCD(tm->tm_mon); rtc_data[6] = BIN2BCD(tm->tm_year); /* Stop RTC while updating the TC registers */ ret = twl4030_rtc_read_u8(&save_control, REG_RTC_CTRL_REG); if (ret < 0) goto out; save_control &= ~BIT_RTC_CTRL_REG_STOP_RTC_M; twl4030_rtc_write_u8(save_control, REG_RTC_CTRL_REG); if (ret < 0) goto out; /* update all the alarm registers in one shot */ ret = twl4030_i2c_write(TWL4030_MODULE_RTC, rtc_data, REG_SECONDS_REG, ALL_TIME_REGS); if (ret < 0) { printk(KERN_ERR "twl4030: twl4030_i2c_write error.\n"); goto out; } /* Start back RTC */ save_control |= BIT_RTC_CTRL_REG_STOP_RTC_M; ret = twl4030_rtc_write_u8(save_control, REG_RTC_CTRL_REG); out: return ret; }
int set_time(unsigned int year0,unsigned int year1,unsigned int month,unsigned int day,unsigned int hour,unsigned int min,unsigned int sec) { int i; unsigned char buf[7]; unsigned char i2cdata[3]; rtc_tm.tm_year =year1; rtc_tm.tm_mon = month; rtc_tm.tm_mday = day; rtc_tm.tm_hour = hour; rtc_tm.tm_min = min; rtc_tm.tm_sec = sec; DebugPrintf("\nwrite rtc %02d%02d%02d%02d%d.%02d",rtc_tm.tm_mon,rtc_tm.tm_mday,rtc_tm.tm_hour,rtc_tm.tm_min,rtc_tm.tm_year,rtc_tm.tm_sec); buf[0] = BIN2BCD(rtc_tm.tm_sec); buf[1] = BIN2BCD(rtc_tm.tm_min); buf[2] = BIN2BCD(rtc_tm.tm_hour); buf[3] = 0x01; //由于设置时间时不用星期这个项,故每次设置时默认为星期一 buf[4] = BIN2BCD(rtc_tm.tm_mday); buf[5] = BIN2BCD(rtc_tm.tm_mon); buf[6] = BIN2BCD(rtc_tm.tm_year); if (fd_i2c) { for(i=0;i<7;i++) { i2cdata[0] = i; i2cdata[1] = buf[i]; if (write(fd_i2c,&i2cdata[0], 2) != 2) { DebugPrintf("\nWrite error at %d", i); return -1; } } } return 0; }
/*! * \brief Set alarm of an X12xx hardware clock. * * \deprecated New applications must use NutRtcSetAlarm(). * * \param idx Zero based index. Two alarms are supported. * \param tm Points to a structure which contains the date and time * information. May be NULL to clear the alarm. * \param aflgs Each bit enables a specific comparision. * - Bit 0: Seconds * - Bit 1: Minutes * - Bit 2: Hours * - Bit 3: Day of month * - Bit 4: Month * - Bit 7: Day of week (Sunday is zero) * * \return 0 on success or -1 in case of an error. */ int X12RtcSetAlarm(int idx, CONST struct _tm *tm, int aflgs) { u_char data[10]; int flags; memset(data, 0, sizeof(data)); data[1] = idx * 8; if (tm) { if (aflgs & RTC_ALARM_SECOND) { data[2] = BIN2BCD(tm->tm_sec) | X12RTC_SCA_ESC; } if (aflgs & RTC_ALARM_MINUTE) { data[3] = BIN2BCD(tm->tm_min) | X12RTC_MNA_EMN; } if (aflgs & RTC_ALARM_HOUR) { data[4] = BIN2BCD(tm->tm_hour) | X12RTC_HRA_EHR; } if (aflgs & RTC_ALARM_MDAY) { data[5] = BIN2BCD(tm->tm_mday) | X12RTC_DTA_EDT; } if (aflgs & RTC_ALARM_MONTH) { data[6] = BIN2BCD(tm->tm_mon + 1) | X12RTC_MOA_EMO; } if (aflgs & RTC_ALARM_WDAY) { data[8] = BIN2BCD(tm->tm_wday) | X12RTC_DWA_EDW; } } X12RtcGetAlarm(1, &test, &flags); //printf("\n set Alarm: date: %d-%d-%d Time: %d:%d:%d \n", test.tm_year, test.tm_mon, test.tm_mday, test.tm_hour, test.tm_min, test.tm_sec); return(X12RtcWrite(1, data, 10)); }
static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { volatile MK48T08ptr_t rtc = (MK48T08ptr_t)MVME_RTC_BASE; unsigned long flags; struct rtc_time wtime; switch (cmd) { case RTC_RD_TIME: /* Read the time/date from RTC */ { save_flags(flags); cli(); /* Ensure clock and real-time-mode-register are accessible */ rtc->ctrl = RTC_READ; wtime.tm_sec = BCD2BIN(rtc->bcd_sec); wtime.tm_min = BCD2BIN(rtc->bcd_min); wtime.tm_hour = BCD2BIN(rtc->bcd_hr); wtime.tm_mday = BCD2BIN(rtc->bcd_dom); wtime.tm_mon = BCD2BIN(rtc->bcd_mth)-1; wtime.tm_year = BCD2BIN(rtc->bcd_year); if (wtime.tm_year < 70) wtime.tm_year += 100; wtime.tm_wday = BCD2BIN(rtc->bcd_dow)-1; rtc->ctrl = 0; restore_flags(flags); return copy_to_user((void *)arg, &wtime, sizeof wtime) ? -EFAULT : 0; } case RTC_SET_TIME: /* Set the RTC */ { struct rtc_time rtc_tm; unsigned char mon, day, hrs, min, sec, leap_yr; unsigned int yrs; if (!capable(CAP_SYS_ADMIN)) return -EACCES; if (copy_from_user(&rtc_tm, (struct rtc_time*)arg, sizeof(struct rtc_time))) return -EFAULT; yrs = rtc_tm.tm_year; if (yrs < 1900) yrs += 1900; mon = rtc_tm.tm_mon + 1; /* tm_mon starts at zero */ day = rtc_tm.tm_mday; hrs = rtc_tm.tm_hour; min = rtc_tm.tm_min; sec = rtc_tm.tm_sec; leap_yr = ((!(yrs % 4) && (yrs % 100)) || !(yrs % 400)); if ((mon > 12) || (day == 0)) return -EINVAL; if (day > (days_in_mo[mon] + ((mon == 2) && leap_yr))) return -EINVAL; if ((hrs >= 24) || (min >= 60) || (sec >= 60)) return -EINVAL; if (yrs >= 2070) return -EINVAL; save_flags(flags); cli(); rtc->ctrl = RTC_WRITE; rtc->bcd_sec = BIN2BCD(sec); rtc->bcd_min = BIN2BCD(min); rtc->bcd_hr = BIN2BCD(hrs); rtc->bcd_dom = BIN2BCD(day); rtc->bcd_mth = BIN2BCD(mon); rtc->bcd_year = BIN2BCD(yrs%100); rtc->ctrl = 0; restore_flags(flags); return 0; } default: return -EINVAL; } }
static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { struct rtc_time wtime; switch (cmd) { case RTC_RD_TIME: /* Read the time/date from RTC */ { get_rtc_time(&wtime); break; } case RTC_SET_TIME: /* Set the RTC */ { struct rtc_time rtc_tm; unsigned char mon, day, hrs, min, sec, leap_yr; unsigned int yrs; if (!capable(CAP_SYS_TIME)) return -EACCES; if (copy_from_user(&rtc_tm, (struct rtc_time*)arg, sizeof(struct rtc_time))) return -EFAULT; yrs = rtc_tm.tm_year + 1900; mon = rtc_tm.tm_mon + 1; /* tm_mon starts at zero */ day = rtc_tm.tm_mday; hrs = rtc_tm.tm_hour; min = rtc_tm.tm_min; sec = rtc_tm.tm_sec; if (yrs < 1970) return -EINVAL; leap_yr = ((!(yrs % 4) && (yrs % 100)) || !(yrs % 400)); if ((mon > 12) || (day == 0)) return -EINVAL; if (day > (days_in_mo[mon] + ((mon == 2) && leap_yr))) return -EINVAL; if ((hrs >= 24) || (min >= 60) || (sec >= 60)) return -EINVAL; if ((yrs -= epoch) > 255) /* They are unsigned */ return -EINVAL; if (yrs > 169) return -EINVAL; if (yrs >= 100) yrs -= 100; sec = BIN2BCD(sec); min = BIN2BCD(min); hrs = BIN2BCD(hrs); day = BIN2BCD(day); mon = BIN2BCD(mon); yrs = BIN2BCD(yrs); spin_lock_irq(&rtc_lock); rtc->control |= M48T35_RTC_SET; rtc->year = yrs; rtc->month = mon; rtc->date = day; rtc->hour = hrs; rtc->min = min; rtc->sec = sec; rtc->control &= ~M48T35_RTC_SET; spin_unlock_irq(&rtc_lock); return 0; } default: return -EINVAL; } return copy_to_user((void *)arg, &wtime, sizeof wtime) ? -EFAULT : 0; }
//------------------------------------------------------------------------------ // // Function: OALIoCtlHalInitRTC // // This function is called by WinCE OS to initialize the time after boot. // Input buffer contains SYSTEMTIME structure with default time value. // // BOOL OALIoCtlHalInitRTC( UINT32 code, VOID *pInBuffer, UINT32 inSize, VOID *pOutBuffer, UINT32 outSize, UINT32 *pOutSize ) { BOOL rc = FALSE; SYSTEMTIME *pGivenTime = (LPSYSTEMTIME) pInBuffer; UCHAR bcdTime[6]; UCHAR status; UCHAR secure; UNREFERENCED_PARAMETER(pOutSize); UNREFERENCED_PARAMETER(outSize); UNREFERENCED_PARAMETER(pOutBuffer); UNREFERENCED_PARAMETER(inSize); UNREFERENCED_PARAMETER(code); OALMSG(OAL_TIMER && OAL_FUNC, (L"+OALIoCtlHalInitRTC()\r\n")); // Initialize RTC critical section InitializeCriticalSection(&s_rtc.cs); // Set CPU GPIO_64 (T2 MSECURE) to be output/high (unsecure) // This allows write access to the T2 RTC calendar/time registers // OMAP35XX GP only if( dwOEMHighSecurity == OEM_HIGH_SECURITY_GP ) { BSPSetT2MSECURE(TRUE); } // First read RTC status from Triton s_rtc.hTWL = TWLOpen(); if (s_rtc.hTWL == NULL) { OALMSG(OAL_ERROR, (L" OALIoCtlHalInitRTC(): Failed to open Triton\r\n")); goto cleanUp; } // Read secure registers for secure hash status = 0; TWLReadByteReg(s_rtc.hTWL, TWL_SECURED_REG_A, &secure); status |= secure; TWLReadByteReg(s_rtc.hTWL, TWL_SECURED_REG_B, &secure); status |= secure; TWLReadByteReg(s_rtc.hTWL, TWL_SECURED_REG_C, &secure); status |= secure; TWLReadByteReg(s_rtc.hTWL, TWL_SECURED_REG_D, &secure); status |= secure; OALMSG(OAL_TIMER && OAL_FUNC, (L" OALIoCtlHalInitRTC(): RTC TWL_SECURED_REG_= 0x%x\r\n", status)); #if 1 // brian // Not needed for CE embedded, only need to reset RTC if TWL/TPS PMIC is reset // Check for a clean boot of device - if so, reset date/time to system default (LTK2026) //pColdBoot = OALArgsQuery(OAL_ARGS_QUERY_COLDBOOT); //if ((pColdBoot != NULL) && *pColdBoot) // { OALMSG(OAL_TIMER && OAL_FUNC, (L" OALIoCtlHalInitRTC(): Clean boot, reset date time\r\n")); status = 0; // } #endif // Start RTC when it isn't running if (status == 0 && pGivenTime != NULL) { OALMSG(OAL_TIMER && OAL_FUNC, (L" OALIoCtlHalInitRTC(): Resetting RTC\r\n")); // Write power_up and alarm bits to clear power up flag (and any interrupt flag) TWLWriteByteReg(s_rtc.hTWL, TWL_RTC_STATUS_REG, TWL_RTC_STATUS_POWER_UP|TWL_RTC_STATUS_ALARM); // Convert system time to BCD bcdTime[5] = BIN2BCD(pGivenTime->wYear - RTC_BASE_YEAR_MIN); bcdTime[4] = BIN2BCD(pGivenTime->wMonth); bcdTime[3] = BIN2BCD(pGivenTime->wDay); bcdTime[2] = BIN2BCD(pGivenTime->wHour); bcdTime[1] = BIN2BCD(pGivenTime->wMinute); bcdTime[0] = BIN2BCD(pGivenTime->wSecond); // Initialize RTC with given values TWLWriteByteReg(s_rtc.hTWL, TWL_YEARS_REG, bcdTime[5]); TWLWriteByteReg(s_rtc.hTWL, TWL_MONTHS_REG, bcdTime[4]); TWLWriteByteReg(s_rtc.hTWL, TWL_DAYS_REG, bcdTime[3]); TWLWriteByteReg(s_rtc.hTWL, TWL_HOURS_REG, bcdTime[2]); TWLWriteByteReg(s_rtc.hTWL, TWL_MINUTES_REG, bcdTime[1]); TWLWriteByteReg(s_rtc.hTWL, TWL_SECONDS_REG, bcdTime[0]); // Enable RTC TWLWriteByteReg(s_rtc.hTWL, TWL_RTC_CTRL_REG, TWL_RTC_CTRL_RUN); // Write fake hash to secure regs TWLWriteByteReg(s_rtc.hTWL, TWL_SECURED_REG_A, 0xAA); TWLWriteByteReg(s_rtc.hTWL, TWL_SECURED_REG_B, 0xBB); TWLWriteByteReg(s_rtc.hTWL, TWL_SECURED_REG_C, 0xCC); TWLWriteByteReg(s_rtc.hTWL, TWL_SECURED_REG_D, 0xDD); // Convert given time initialization date/time to FILETIME NKSystemTimeToFileTime(pGivenTime, (FILETIME*)&s_rtc.baseFiletime); // Set a default value for base offset s_rtc.baseOffset = 0; // Save off base offset to the backup regs WriteBaseOffset( &s_rtc.baseOffset ); } else { SYSTEMTIME baseSystemTime; OALMSG(OAL_TIMER && OAL_FUNC, (L" OALIoCtlHalInitRTC(): Getting RTC\r\n")); // Set get time flag TWLReadByteReg(s_rtc.hTWL, TWL_RTC_CTRL_REG, &status); status |= TWL_RTC_CTRL_RUN | TWL_RTC_CTRL_GET_TIME; TWLWriteByteReg(s_rtc.hTWL, TWL_RTC_CTRL_REG, status); // Get date and time from RTC TWLReadByteReg(s_rtc.hTWL, TWL_YEARS_REG, &bcdTime[5]); TWLReadByteReg(s_rtc.hTWL, TWL_MONTHS_REG, &bcdTime[4]); TWLReadByteReg(s_rtc.hTWL, TWL_DAYS_REG, &bcdTime[3]); TWLReadByteReg(s_rtc.hTWL, TWL_HOURS_REG, &bcdTime[2]); TWLReadByteReg(s_rtc.hTWL, TWL_MINUTES_REG, &bcdTime[1]); TWLReadByteReg(s_rtc.hTWL, TWL_SECONDS_REG, &bcdTime[0]); // Convert current RTC date/time to FILETIME baseSystemTime.wYear = BCD2BIN(bcdTime[5]) + RTC_BASE_YEAR_MIN; baseSystemTime.wMonth = BCD2BIN(bcdTime[4]); baseSystemTime.wDay = BCD2BIN(bcdTime[3]); baseSystemTime.wHour = BCD2BIN(bcdTime[2]); baseSystemTime.wMinute = BCD2BIN(bcdTime[1]); baseSystemTime.wSecond = BCD2BIN(bcdTime[0]); baseSystemTime.wMilliseconds = 0; NKSystemTimeToFileTime(&baseSystemTime, (FILETIME*)&s_rtc.baseFiletime); // Read the offset from the backup regs ReadBaseOffset( &s_rtc.baseOffset ); } OALMSG(OAL_TIMER && OAL_FUNC, (L" OALIoCtlHalInitRTC(): RTC = %s\r\n", HWTimeToString(bcdTime))); // Now update RTC state values s_rtc.initialized = TRUE; s_rtc.baseTickCount = OEMGetTickCount(); // Success rc = TRUE; cleanUp: OALMSG(OAL_TIMER && OAL_FUNC, (L"-OALIoCtlHalInitRTC() rc = %d\r\n", rc)); return rc; }
static int x1205_set_datetime(struct i2c_client *client, struct rtc_time *tm, int datetoo, u8 reg_base, unsigned char alm_enable) { int i, xfer, nbytes; unsigned char buf[8]; unsigned char rdata[10] = { 0, reg_base }; static const unsigned char wel[3] = { 0, X1205_REG_SR, X1205_SR_WEL }; static const unsigned char rwel[3] = { 0, X1205_REG_SR, X1205_SR_WEL | X1205_SR_RWEL }; static const unsigned char diswe[3] = { 0, X1205_REG_SR, 0 }; dev_dbg(&client->dev, "%s: secs=%d, mins=%d, hours=%d\n", __func__, tm->tm_sec, tm->tm_min, tm->tm_hour); buf[CCR_SEC] = BIN2BCD(tm->tm_sec); buf[CCR_MIN] = BIN2BCD(tm->tm_min); /* set hour and 24hr bit */ buf[CCR_HOUR] = BIN2BCD(tm->tm_hour) | X1205_HR_MIL; /* should we also set the date? */ if (datetoo) { dev_dbg(&client->dev, "%s: mday=%d, mon=%d, year=%d, wday=%d\n", __func__, tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); buf[CCR_MDAY] = BIN2BCD(tm->tm_mday); /* month, 1 - 12 */ buf[CCR_MONTH] = BIN2BCD(tm->tm_mon + 1); /* year, since the rtc epoch*/ buf[CCR_YEAR] = BIN2BCD(tm->tm_year % 100); buf[CCR_WDAY] = tm->tm_wday & 0x07; buf[CCR_Y2K] = BIN2BCD(tm->tm_year / 100); } /* If writing alarm registers, set compare bits on registers 0-4 */ if (reg_base < X1205_CCR_BASE) for (i = 0; i <= 4; i++) buf[i] |= 0x80; /* this sequence is required to unlock the chip */ if ((xfer = i2c_master_send(client, wel, 3)) != 3) { dev_err(&client->dev, "%s: wel - %d\n", __func__, xfer); return -EIO; } if ((xfer = i2c_master_send(client, rwel, 3)) != 3) { dev_err(&client->dev, "%s: rwel - %d\n", __func__, xfer); return -EIO; } /* write register's data */ if (datetoo) nbytes = 8; else nbytes = 3; for (i = 0; i < nbytes; i++) rdata[2+i] = buf[i]; xfer = i2c_master_send(client, rdata, nbytes+2); if (xfer != nbytes+2) { dev_err(&client->dev, "%s: result=%d addr=%02x, data=%02x\n", __func__, xfer, rdata[1], rdata[2]); return -EIO; } /* If we wrote to the nonvolatile region, wait 10msec for write cycle*/ if (reg_base < X1205_CCR_BASE) { unsigned char al0e[3] = { 0, X1205_REG_INT, 0 }; msleep(10); /* ...and set or clear the AL0E bit in the INT register */ /* Need to set RWEL again as the write has cleared it */ xfer = i2c_master_send(client, rwel, 3); if (xfer != 3) { dev_err(&client->dev, "%s: aloe rwel - %d\n", __func__, xfer); return -EIO; } if (alm_enable) al0e[2] = X1205_INT_AL0E; xfer = i2c_master_send(client, al0e, 3); if (xfer != 3) { dev_err(&client->dev, "%s: al0e - %d\n", __func__, xfer); return -EIO; } /* and wait 10msec again for this write to complete */ msleep(10); } /* disable further writes */ if ((xfer = i2c_master_send(client, diswe, 3)) != 3) { dev_err(&client->dev, "%s: diswe - %d\n", __func__, xfer); return -EIO; } return 0; }
static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { struct rtc_time wtime; struct upd4990a_raw_data raw; switch (cmd) { case RTC_UIE_OFF: /* Mask ints from RTC updates. */ spin_lock_irq(&rtc_lock); if (rtc_status & RTC_UIE_TIMER_ON) { rtc_status &= ~RTC_UIE_TIMER_ON; del_timer(&rtc_uie_timer); } spin_unlock_irq(&rtc_lock); return 0; case RTC_UIE_ON: /* Allow ints for RTC updates. */ spin_lock_irq(&rtc_lock); rtc_irq_data = 0; if (!(rtc_status & RTC_UIE_TIMER_ON)) { rtc_status |= RTC_UIE_TIMER_ON; rtc_uie_timer.expires = jiffies + 1; add_timer(&rtc_uie_timer); } /* Just in case... */ upd4990a_serial_command(UPD4990A_REGISTER_HOLD); old_refclk = ~UPD4990A_READ_DATA(); spin_unlock_irq(&rtc_lock); return 0; case RTC_RD_TIME: /* Read the time/date from RTC */ spin_lock_irq(&rtc_lock); upd4990a_get_time(&raw, 0); spin_unlock_irq(&rtc_lock); wtime.tm_sec = BCD2BIN(raw.sec); wtime.tm_min = BCD2BIN(raw.min); wtime.tm_hour = BCD2BIN(raw.hour); wtime.tm_mday = BCD2BIN(raw.mday); wtime.tm_mon = raw.mon - 1; /* convert to 0-base */ wtime.tm_wday = raw.wday; /* * Account for differences between how the RTC uses the values * and how they are defined in a struct rtc_time; */ if ((wtime.tm_year = BCD2BIN(raw.year)) < 95) wtime.tm_year += 100; wtime.tm_isdst = 0; break; case RTC_SET_TIME: /* Set the RTC */ { int leap_yr; if (!capable(CAP_SYS_TIME)) return -EACCES; if (copy_from_user(&wtime, (struct rtc_time *) arg, sizeof (struct rtc_time))) return -EFAULT; /* Valid year is 1995 - 2094, inclusive. */ if (wtime.tm_year < 95 || wtime.tm_year > 194) return -EINVAL; if (wtime.tm_mon > 11 || wtime.tm_mday == 0) return -EINVAL; /* For acceptable year domain (1995 - 2094), this IS sufficient. */ leap_yr = !(wtime.tm_year % 4); if (wtime.tm_mday > (days_in_mo[wtime.tm_mon] + (wtime.tm_mon == 2 && leap_yr))) return -EINVAL; if (wtime.tm_hour >= 24 || wtime.tm_min >= 60 || wtime.tm_sec >= 60) return -EINVAL; if (wtime.tm_wday > 6) return -EINVAL; raw.sec = BIN2BCD(wtime.tm_sec); raw.min = BIN2BCD(wtime.tm_min); raw.hour = BIN2BCD(wtime.tm_hour); raw.mday = BIN2BCD(wtime.tm_mday); raw.mon = wtime.tm_mon + 1; raw.wday = wtime.tm_wday; raw.year = BIN2BCD(wtime.tm_year % 100); spin_lock_irq(&rtc_lock); upd4990a_set_time(&raw, 0); spin_unlock_irq(&rtc_lock); return 0; } default: return -EINVAL; } return copy_to_user((void *)arg, &wtime, sizeof wtime) ? -EFAULT : 0; }