static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { struct rtc_time rtc_tm; ulong curr_time; switch (cmd) { case RTC_RD_TIME: /* Read the time/date from RTC */ curr_time = rtc_get_time(); to_tm(curr_time, &rtc_tm); rtc_tm.tm_year -= 1900; return copy_to_user((void *) arg, &rtc_tm, sizeof(rtc_tm)) ? -EFAULT : 0; case RTC_SET_TIME: /* Set the RTC */ if (!capable(CAP_SYS_TIME)) return -EACCES; if (copy_from_user(&rtc_tm, (struct rtc_time *) arg, sizeof(struct rtc_time))) return -EFAULT; curr_time = mktime(rtc_tm.tm_year + 1900, rtc_tm.tm_mon, rtc_tm.tm_mday, rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec); return rtc_set_time(curr_time); default: return -EINVAL; } }
static int alarm_set_rtc(struct timespec *ts) { struct rtc_time new_rtc_tm; struct rtc_device *rtc_dev; unsigned long flags; int rv = 0; rtc_time_to_tm(ts->tv_sec, &new_rtc_tm); alarm_dbg(INFO, "set rtc %ld %ld - rtc %02d:%02d:%02d %02d/%02d/%04d\n", ts->tv_sec, ts->tv_nsec, new_rtc_tm.tm_hour, new_rtc_tm.tm_min, new_rtc_tm.tm_sec, new_rtc_tm.tm_mon + 1, new_rtc_tm.tm_mday, new_rtc_tm.tm_year + 1900); rtc_dev = alarmtimer_get_rtcdev(); rv = do_settimeofday(ts); if (rv < 0) return rv; if (rtc_dev) rv = rtc_set_time(rtc_dev, &new_rtc_tm); spin_lock_irqsave(&alarm_slock, flags); alarm_pending |= ANDROID_ALARM_TIME_CHANGE_MASK; wake_up(&alarm_wait_queue); spin_unlock_irqrestore(&alarm_slock, flags); return rv; }
static void rtc_reset(void) { struct rtc_date dt; struct rtc_time tm; RTC_ALRM_DIS(); // Set date and time dt.ten_cent = 0; dt.cent = 0; dt.ten_yr = 0; dt.yr = 0; dt.ten_mth = 0; dt.mth = 0; dt.ten_day = 0; dt.day = 0; tm.dow = 0; tm.ten_hr = 0; tm.hr = 0; tm.ten_min = 0; tm.min = 0; tm.ten_sec = 0; tm.sec = 0; tm.sos = 0; rtc_set_date(&dt); rtc_set_time(&tm); }
/** * \brief Set the time using a spinner widget */ static void set_time_application(void) { struct keyboard_event input; struct calendar_date date; uint32_t timestamp; uint8_t tz_hours; uint8_t tz_minutes; struct gfx_mono_spinctrl hour_spinner; struct gfx_mono_spinctrl minute_spinner; struct gfx_mono_spinctrl_spincollection time_spinners; uint8_t spinner_status; int16_t spinner_results[2]; // Prepare the spinner widget for time selection gfx_mono_spinctrl_init(&hour_spinner, SPINTYPE_INTEGER, datetime_date_spinner_string_hour, NULL, 0, 23, 0); gfx_mono_spinctrl_init(&minute_spinner, SPINTYPE_INTEGER, datetime_date_spinner_string_minute, NULL, 0, 59, 0); // Create time spincollector gfx_mono_spinctrl_spincollection_init(&time_spinners); gfx_mono_spinctrl_spincollection_add_spinner(&hour_spinner, &time_spinners); gfx_mono_spinctrl_spincollection_add_spinner(&minute_spinner, &time_spinners); // Get timezone settings tz_hours = timezone_get_hours(); tz_minutes = timezone_get_minutes(); timestamp = rtc_get_time(); calendar_timestamp_to_date_tz(timestamp, tz_hours, tz_minutes, &date); // Set spinners to current time as initial position hour_spinner.integer_data = date.hour; minute_spinner.integer_data = date.minute; gfx_mono_spinctrl_spincollection_show(&time_spinners); do { do { keyboard_get_key_state(&input); // Wait for key release } while (input.type != KEYBOARD_RELEASE); // Send key to spinnercollection spinner_status = gfx_mono_spinctrl_spincollection_process_key( &time_spinners, input.keycode, spinner_results); } while (spinner_status != GFX_MONO_SPINCTRL_EVENT_FINISH); date.hour = spinner_results[0]; date.minute = spinner_results[1]; timestamp = calendar_date_to_timestamp_tz(&date, tz_hours, tz_minutes); if(timestamp != 0) { rtc_set_time(timestamp); } }
static int rtc_sub_alarm_test(u32 f_time, u32 f_date) { volatile int hit; int result = 0; rtc_reset(); printf("RTC Time = W%d %d%d:%d%d:%d%d:%d\n", tm.dow, tm.ten_hr, tm.hr, \ tm.ten_min, tm.min, tm.ten_sec, tm.sec, tm.sos); printf("RTC Date = C%d%d %d%d/%d%d/%d%d\n", dt.ten_cent, dt.cent, dt.ten_yr, dt.yr, \ dt.ten_mth, dt.mth, dt.ten_day, dt.day); printf("Alarm Time = W%d %d%d:%d%d:%d%d:%d\n", tm_a.dow, tm_a.ten_hr, tm_a.hr, \ tm_a.ten_min, tm_a.min, tm_a.ten_sec, tm_a.sec, tm_a.sos); printf("Alarm Date = C%d%d %d%d/%d%d/%d%d\n", dt_a.ten_cent, dt_a.cent, dt_a.ten_yr, dt_a.yr, \ dt_a.ten_mth, dt_a.mth, dt_a.ten_day, dt_a.day); printf("Alarm Time on: "); if (f_time & SOCLE_RTC_TALRM_CSOS) printf("\"Sixteen of Second\" "); if (f_time & SOCLE_RTC_TALRM_CS) printf("\"Second\" "); if (f_time & SOCLE_RTC_TALRM_CM) printf("\"Minute\" "); if (f_time & SOCLE_RTC_TALRM_CH) printf("\"Hour\" "); if (f_time & SOCLE_RTC_TALRM_CDOW) printf("\"Day of Week\""); printf("\n"); printf("Alarm Date on: "); if (f_date & SOCLE_RTC_DALRM_CD) printf("\"Day\" "); if (f_date & SOCLE_RTC_DALRM_CM) printf("\"Month\" "); if (f_date & SOCLE_RTC_DALRM_CY) printf("\"Year\" "); if (f_date & SOCLE_RTC_DALRM_CC) printf("\"Century\""); printf("\n"); rtc_set_time_alarm(&tm_a, f_time); rtc_set_date_alarm(&dt_a, f_date); hit = 0; rtc_set_date(&dt); rtc_set_time(&tm); printf("alarm after 15 second...\n"); return result; }
static int __init rtc_hctosys(void) { int err = -ENODEV; struct rtc_time tm; struct timespec tv = { .tv_nsec = NSEC_PER_SEC >> 1, }; struct rtc_device *rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE); if (rtc == NULL) { pr_err("%s: unable to open rtc device (%s)\n", __FILE__, CONFIG_RTC_HCTOSYS_DEVICE); goto err_open; } err = rtc_read_time(rtc, &tm); if (err) { dev_err(rtc->dev.parent, "hctosys: unable to read the hardware clock\n"); goto err_read; } err = rtc_valid_tm(&tm); if (err) { dev_err(rtc->dev.parent, "hctosys: invalid date/time\n"); goto err_invalid; } if(tm.tm_year < 100) { tm.tm_year += 13; rtc_set_time(rtc, &tm); } rtc_tm_to_time(&tm, &tv.tv_sec); do_settimeofday(&tv); dev_info(rtc->dev.parent, "setting system clock to " "%d-%02d-%02d %02d:%02d:%02d UTC (%u)\n", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, (unsigned int) tv.tv_sec); err_invalid: err_read: rtc_class_close(rtc); rtc_hctohc(tm); err_open: rtc_hctosys_ret = err; return err; } late_initcall(rtc_hctosys);
static void _rtc_settime(char **argv) { struct tm now; if (_parse_time(argv, &now) == 0) { if (rtc_set_time(&now) == -1) { puts("rtc: error setting time"); } } }
void set_timestamp(uint32_t time) { #ifdef RTC rtc_set_time(time); #else ATOMIC_BLOCK(ATOMIC_FORCEON) { timestamp = time; } #endif }
int set_rtc_time(struct rtc_time *time) { unsigned long nowtime; int ret; spin_lock(&mips_rtc_lock); nowtime = mktime(time->tm_year+1900, time->tm_mon+1, time->tm_mday, time->tm_hour, time->tm_min, time->tm_sec); ret = rtc_set_time(nowtime); spin_unlock(&mips_rtc_lock); return ret; }
static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm) { void __iomem *base = s3c_rtc_base; // int year = tm->tm_year;//- 100; int year = tm->tm_year-100; #ifdef CONFIG_RTC_DRV_S5M struct rtc_device *rtc1 ; #endif printk("%s() %d-%d-%d %d:%d:%d\n", __FUNCTION__, tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); pr_debug("set time %04d.%02d.%02d %02d:%02d:%02d\n", 1900 + tm->tm_year, tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); /* we get around y2k by simply not supporting it */ // printk("year %d\n",year); // if (year < 70) { // dev_err(dev, "rtc only supports from year 1970\n"); // return -EINVAL; // } writeb(bin2bcd(tm->tm_sec), base + S3C2410_RTCSEC); writeb(bin2bcd(tm->tm_min), base + S3C2410_RTCMIN); writeb(bin2bcd(tm->tm_hour), base + S3C2410_RTCHOUR); writeb(bin2bcd(tm->tm_mday), base + S3C2410_RTCDATE); writeb(bin2bcd(tm->tm_mon + 1), base + S3C2410_RTCMON); writeb(bin2bcd(year), base + S3C2410_RTCYEAR); #ifdef CONFIG_RTC_DRV_S5M rtc1 = rtc_class_open("rtc1"); if(rtc1 == NULL) { pr_err("!!!!!! %s: unable to open rtc1 device!!!!!\n", __FILE__); } else { rtc_set_time(rtc1,tm); rtc_class_close(rtc1); } #endif return 0; }
extern int rtc_set_time_test(int autotest) { rtc_time_t time; printf("Please input the RTC time, ex: on Monday, 5:30:40:00 PM\n"); printf("Set Time = 1:17:30:40:00, Your Time = "); scanf("%d:%1d%1d:%1d%1d:%1d%1d:%d", &time.dow, &time.ten_hr, &time.hr, \ &time.ten_min, &time.min, &time.ten_sec, &time.sec, &time.sos); PDEBUG("Input Time = %d:%d%d:%d%d:%d%d:%d\n", time.dow, time.ten_hr, time.hr, \ time.ten_min, time.min, time.ten_sec, time.sec, time.sos); rtc_set_time(&time); return 0; }
void rt_timer_interrupt(struct pt_regs *regs) { int cpu = smp_processor_id(); int cpuA = ((cputoslice(cpu)) == 0); int irq = 9; /* XXX Assign number */ irq_enter(); write_seqlock(&xtime_lock); again: LOCAL_HUB_S(cpuA ? PI_RT_PEND_A : PI_RT_PEND_B, 0); /* Ack */ ct_cur[cpu] += CYCLES_PER_JIFFY; LOCAL_HUB_S(cpuA ? PI_RT_COMPARE_A : PI_RT_COMPARE_B, ct_cur[cpu]); if (LOCAL_HUB_L(PI_RT_COUNT) >= ct_cur[cpu]) goto again; kstat_this_cpu.irqs[irq]++; /* kstat only for bootcpu? */ if (cpu == 0) do_timer(regs); #ifdef CONFIG_SMP update_process_times(user_mode(regs)); #endif /* CONFIG_SMP */ /* * If we have an externally synchronized Linux clock, then update * RTC clock accordingly every ~11 minutes. Set_rtc_mmss() has to be * called as close as possible to when a second starts. */ if ((time_status & STA_UNSYNC) == 0 && xtime.tv_sec > last_rtc_update + 660 && (xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 && (xtime.tv_nsec / 1000) <= 500000 + ((unsigned) TICK_SIZE) / 2) { if (rtc_set_time(xtime.tv_sec) == 0) { last_rtc_update = xtime.tv_sec; } else { last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */ } } write_sequnlock(&xtime_lock); irq_exit(); }
void main(void) { struct tm timeinfo; rtc_init(); // Give RTC a initial value: 2015/4/15 (Wed) 12:00:00 rtc_set_time(2015, 4, 15, 3, 12, 0, 0); while (1) { rtc_read_time(&timeinfo); DBG_8195A("%d-%d-%d[%d] %d:%d:%d\r\n", timeinfo.tm_year, timeinfo.tm_mon, timeinfo.tm_mday, timeinfo.tm_wday, timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec); wait_ms(1000); } rtc_deinit(); }
/** * \brief Configure RTC for test * \Set alarm ewery second */ void configure_rtc (void) { uint32_t status; struct _time MTU = {00, 00, 00}; struct _time MTA = {18, 30, 00}; struct _date MDT = {2015, 06, 01, 1}; rtc_set_hour_mode(0); // mode 24h status = rtc_set_time(&MTU); status |= rtc_set_date(&MDT); status |= rtc_set_time_alarm(&MTA); status |= rtc_set_time_event (RTC_CR_TIMEVSEL_MINUTE); rtc_disable_it (RTC_IER_ACKEN | RTC_IER_ALREN | RTC_IER_SECEN | RTC_IER_TIMEN | RTC_IER_CALEN); rtc_enable_it (RTC_IER_SECEN); aic_set_source_vector(ID_SYSC, rtc_irq_handler); aic_enable(ID_SYSC); }
static int rtc_post_load(void *opaque, int version_id) { RTCState *s = opaque; if (version_id <= 2) { rtc_set_time(s); s->offset = 0; check_update_timer(s); } #ifdef TARGET_I386 if (version_id >= 2) { if (s->lost_tick_policy == LOST_TICK_SLEW) { rtc_coalesced_timer_update(s); } } #endif return 0; }
/** * RTCの時間を設定します。 * * @param[in] year 年を指定します。 * @param[in] mon 月を指定します。 * @param[in] day 日を指定します。 * @param[in] hour 時を指定します。 * @param[in] min 分を指定します。 * @param[in] sec 秒を指定します。 * @param[in] week 曜日を指定します。 * * @return 時間の設定に成功した場合はtrueを返却します。失敗した場合はfalseを返却します。 * * @attention なし ***************************************************************************/ bool RTC::setDateTime(int year, int mon, int day, int hour, int min, int sec, int week) { bool bError = true; RTC_TIMETYPE time; time.year = year; time.mon = mon; time.day = day; time.hour = hour; time.min = min; time.second = sec; time.weekday= week; if (rtc_set_time(&time) == 0) { bError = false; } return (bError); }
static int alarm_set_rtc(struct timespec *ts) { struct rtc_time new_rtc_tm; struct rtc_device *rtc_dev; unsigned long flags; int rv = 0; rtc_time_to_tm(ts->tv_sec, &new_rtc_tm); rtc_dev = alarmtimer_get_rtcdev(); rv = do_settimeofday(ts); if (rv < 0) return rv; if (rtc_dev) rv = rtc_set_time(rtc_dev, &new_rtc_tm); spin_lock_irqsave(&alarm_slock, flags); alarm_pending |= ANDROID_ALARM_TIME_CHANGE_MASK; wake_up(&alarm_wait_queue); spin_unlock_irqrestore(&alarm_slock, flags); return rv; }
THD_FUNCTION(TimeKeeper::TimekeeperThread, arg) { chRegSetThreadName("Timekeeper"); TimeKeeper *self = static_cast<TimeKeeper *>(arg); self->GNSS.subscribe(&gps); while (!chThdShouldTerminateX()) { if ((gps.fresh) && (gps.fix > 0) && (0 == gps.msec)) { int64_t tmp = 1000000; tmp *= mktime(&gps.time); osalSysLock(); time_gps_us = tmp; if (! time_verified) { time_verified = true; unix_usec = time_gps_us; } osalSysUnlock(); /* now correct time in internal RTC (if needed) */ int32_t t1 = time_gps_us / 1000000; int32_t t2 = rtc_get_time_unix(nullptr); int32_t dt = t1 - t2; if (abs(dt) > TIME_CORRECTION_THRESHOLD) rtc_set_time(&gps.time); } if (gps.fresh) { gps.fresh = false; } osalThreadSleepMilliseconds(20); } self->GNSS.unsubscribe(&gps); chThdExit(MSG_OK); }
/** * \brief Callback function for RTC compare interrupt handler * * The function executes when the RTC compare interrupt occurs and loop * through all timeout channels. The timeout_array[channel_index] which * contains the remaining ticks before timeout is decremented and the timeout * active/expired masks are updated. */ static void tick_handler(uint32_t time) { uint8_t i; /* Loop through all timeout channels */ for (i = 0; i < TIMEOUT_COUNT; i++) { /* Skip processing on current channel if not active */ if (!(timeout_active & (1 << i))) { continue; } /* Decrement current channel with one tick */ timeout_array[i].count--; /* Skip further processing on current channel if not expired */ if (timeout_array[i].count) { continue; } else { /* Update expired bit mask with current channel */ timeout_expired |= 1 << i; /* If Periodic timer, reset timeout counter to period * time */ if (timeout_array[i].period) { timeout_array[i].count = timeout_array[i].period; } /* If not periodic timeout, set current channel to * in-active */ else { timeout_active &= ~(1 << i); } } } /* Reset RTC before next tick */ rtc_set_time(0); rtc_set_alarm(TIMEOUT_COMP); }
/** * \brief Initialize RTC32 and VBAT * * This function checks the RTC32 and VBAT systems' status, initializing them if * necessary. If the status is OK, only the RTC32 is reset. * * To ensure that WDT resets occur with correct timing, the RTC32 is reset to * the last time which was read out from it. */ static void main_init_rtc32(void) { /* RTC32 clock must be enabled after sysclk_init() to check VBAT */ sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_RTC); while (RTC32.SYNCCTRL & RTC32_SYNCBUSY_bm) { /* Wait for synchronization */ } /* Initialize the RTC32 and VBAT if its status is not OK */ if (rtc_vbat_system_check(false) != VBAT_STATUS_OK) { rtc_init(); /* Otherwise, just ensure the RTC32 is enabled with correct period */ } else { RTC32.CTRL = ~RTC32_ENABLE_bm; while (RTC32.SYNCCTRL & RTC32_SYNCBUSY_bm) { } RTC32.PER = 0xffffffff; RTC32.CTRL = RTC32_ENABLE_bm; } /* Reset the time */ rtc_set_time(classb_last_wdt_reset); }
static int __init rtc_hctosys(void) { int err, rtc_init = 0; struct rtc_time tm; struct rtc_device *rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE); if (rtc == NULL) { printk("%s: unable to open rtc device (%s)\n", __FILE__, CONFIG_RTC_HCTOSYS_DEVICE); return -ENODEV; } err = rtc_read_time(rtc, &tm); #if 1 // charles debug printk("============== RTC Debug Param =================\n"); printk("tm_year = %d\n", tm.tm_year); printk("tm_mon = %d\n", tm.tm_mon); printk("tm_mday = %d\n", tm.tm_mday); printk("tm_hour = %d\n", tm.tm_hour); printk("tm_min = %d\n", tm.tm_min); printk("tm_sec = %d\n", tm.tm_sec); printk("================================================\n"); #endif // android system time valid check, // rtc read time is invalid, set to default system time 2010, jan, 1, 00:00:00 if((tm.tm_year+1900)<=1970 || (tm.tm_year+1900)>2037) { printk("%s[%d]: invalid system time -> set to default system time.. \n", __FILE__,__LINE__); rtc_init = 1; } if (err == 0) { err = rtc_valid_tm(&tm); if(err || rtc_init) { // RTC default value setting (2010-01-01, 0:0:0) tm.tm_year = 110; tm.tm_mon = 0; tm.tm_mday = 1; tm.tm_hour = 0; tm.tm_min = 0; tm.tm_sec = 0; err = rtc_valid_tm(&tm); if(err == 0) { printk("============== RTC set to default system time =================\n"); printk("tm_year = %d\n", tm.tm_year); printk("tm_mon = %d\n", tm.tm_mon); printk("tm_mday = %d\n", tm.tm_mday); printk("tm_hour = %d\n", tm.tm_hour); printk("tm_min = %d\n", tm.tm_min); printk("tm_sec = %d\n", tm.tm_sec); printk("===============================================================\n"); rtc_set_time(rtc, &tm); } } if (err == 0) { struct timespec tv; tv.tv_nsec = NSEC_PER_SEC >> 1; rtc_tm_to_time(&tm, &tv.tv_sec); do_settimeofday(&tv); dev_info(rtc->dev.parent, "setting system clock to " "%d-%02d-%02d %02d:%02d:%02d UTC (%u)\n", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, (unsigned int) tv.tv_sec); } else
static void cmos_ioport_write(void *opaque, hwaddr addr, uint64_t data, unsigned size) { RTCState *s = opaque; if ((addr & 1) == 0) { s->cmos_index = data & 0x7f; } else { CMOS_DPRINTF("cmos: write index=0x%02x val=0x%02x\n", s->cmos_index, data); switch(s->cmos_index) { case RTC_SECONDS_ALARM: case RTC_MINUTES_ALARM: case RTC_HOURS_ALARM: s->cmos_data[s->cmos_index] = data; check_update_timer(s); break; case RTC_IBM_PS2_CENTURY_BYTE: s->cmos_index = RTC_CENTURY; /* fall through */ case RTC_CENTURY: case RTC_SECONDS: case RTC_MINUTES: case RTC_HOURS: case RTC_DAY_OF_WEEK: case RTC_DAY_OF_MONTH: case RTC_MONTH: case RTC_YEAR: s->cmos_data[s->cmos_index] = data; /* if in set mode, do not update the time */ if (rtc_running(s)) { rtc_set_time(s); check_update_timer(s); } break; case RTC_REG_A: if ((data & 0x60) == 0x60) { if (rtc_running(s)) { rtc_update_time(s); } /* What happens to UIP when divider reset is enabled is * unclear from the datasheet. Shouldn't matter much * though. */ s->cmos_data[RTC_REG_A] &= ~REG_A_UIP; } else if (((s->cmos_data[RTC_REG_A] & 0x60) == 0x60) && (data & 0x70) <= 0x20) { /* when the divider reset is removed, the first update cycle * begins one-half second later*/ if (!(s->cmos_data[RTC_REG_B] & REG_B_SET)) { s->offset = 500000000; rtc_set_time(s); } s->cmos_data[RTC_REG_A] &= ~REG_A_UIP; } /* UIP bit is read only */ s->cmos_data[RTC_REG_A] = (data & ~REG_A_UIP) | (s->cmos_data[RTC_REG_A] & REG_A_UIP); periodic_timer_update(s, qemu_get_clock_ns(rtc_clock)); check_update_timer(s); break; case RTC_REG_B: if (data & REG_B_SET) { /* update cmos to when the rtc was stopping */ if (rtc_running(s)) { rtc_update_time(s); } /* set mode: reset UIP mode */ s->cmos_data[RTC_REG_A] &= ~REG_A_UIP; data &= ~REG_B_UIE; } else { /* if disabling set mode, update the time */ if ((s->cmos_data[RTC_REG_B] & REG_B_SET) && (s->cmos_data[RTC_REG_A] & 0x70) <= 0x20) { s->offset = get_guest_rtc_ns(s) % NSEC_PER_SEC; rtc_set_time(s); } } /* if an interrupt flag is already set when the interrupt * becomes enabled, raise an interrupt immediately. */ if (data & s->cmos_data[RTC_REG_C] & REG_C_MASK) { s->cmos_data[RTC_REG_C] |= REG_C_IRQF; qemu_irq_raise(s->irq); } else { s->cmos_data[RTC_REG_C] &= ~REG_C_IRQF; qemu_irq_lower(s->irq); } s->cmos_data[RTC_REG_B] = data; periodic_timer_update(s, qemu_get_clock_ns(rtc_clock)); check_update_timer(s); break; case RTC_REG_C: case RTC_REG_D: /* cannot write to them */ break; default: s->cmos_data[s->cmos_index] = data; break; } } }
extern int auto_poweroff_alarm_test(int autotest) { int count_down_s = 5; rtc_reset(); // Set alarm date and alarm time // alarm date = C21 06/12/31 dt_a.ten_cent = 2; dt_a.cent = 1; dt_a.ten_yr = 0; dt_a.yr = 6; dt_a.ten_mth = 1; dt_a.mth = 2; dt_a.ten_day = 3; dt_a.day = 1; rtc_set_date_alarm(&dt_a, SOCLE_RTC_DALRM_CD | SOCLE_RTC_DALRM_CM | SOCLE_RTC_DALRM_CY | SOCLE_RTC_DALRM_CC); // alarm time = Wed 17:58:1count_down_s.10 tm_a.dow = 3; tm_a.ten_hr = 1; tm_a.hr = 7; tm_a.ten_min = 5; tm_a.min = 8; tm_a.ten_sec = 1; tm_a.sec = count_down_s; tm_a.sos = 10; rtc_set_time_alarm(&tm_a, SOCLE_RTC_TALRM_CSOS | SOCLE_RTC_TALRM_CS | SOCLE_RTC_TALRM_CM | SOCLE_RTC_TALRM_CH | SOCLE_RTC_TALRM_CDOW); // Set date and time // date = C21 06/12/31 dt.ten_cent = 2; dt.cent = 1; dt.ten_yr = 0; dt.yr = 6; dt.ten_mth = 1; dt.mth = 2; dt.ten_day = 3; dt.day = 1; rtc_set_date(&dt); // time = Wed 17:58:10.2 tm.dow = 3; tm.ten_hr = 1; tm.hr = 7; tm.ten_min = 5; tm.min = 8; tm.ten_sec = 1; tm.sec = 0; tm.sos = 2; rtc_set_time(&tm); printf("Count down %d seconds...\n", count_down_s); printf("Sleeping...\n"); EN_RTC_ALARM_POWER_ON(); ENTER_RTC_POWER_OFF_MODE(); return 0; }
static int rtc_sub_alarm_test(u32_t f_time, u32_t f_date) { volatile int hit; int result = 0; rtc_reset(); printf("RTC Time = W%d %d%d:%d%d:%d%d:%d\n", tm.dow, tm.ten_hr, tm.hr, \ tm.ten_min, tm.min, tm.ten_sec, tm.sec, tm.sos); printf("RTC Date = C%d%d %d%d/%d%d/%d%d\n", dt.ten_cent, dt.cent, dt.ten_yr, dt.yr, \ dt.ten_mth, dt.mth, dt.ten_day, dt.day); printf("Alarm Time = W%d %d%d:%d%d:%d%d:%d\n", tm_a.dow, tm_a.ten_hr, tm_a.hr, \ tm_a.ten_min, tm_a.min, tm_a.ten_sec, tm_a.sec, tm_a.sos); printf("Alarm Date = C%d%d %d%d/%d%d/%d%d\n", dt_a.ten_cent, dt_a.cent, dt_a.ten_yr, dt_a.yr, \ dt_a.ten_mth, dt_a.mth, dt_a.ten_day, dt_a.day); printf("Alarm Time on: "); if (f_time & SOCLE_RTC_TALRM_CSOS) printf("\"Sixteen of Second\" "); if (f_time & SOCLE_RTC_TALRM_CS) printf("\"Second\" "); if (f_time & SOCLE_RTC_TALRM_CM) printf("\"Minute\" "); if (f_time & SOCLE_RTC_TALRM_CH) printf("\"Hour\" "); if (f_time & SOCLE_RTC_TALRM_CDOW) printf("\"Day of Week\""); printf("\n"); printf("Alarm Date on: "); if (f_date & SOCLE_RTC_DALRM_CD) printf("\"Day\" "); if (f_date & SOCLE_RTC_DALRM_CM) printf("\"Month\" "); if (f_date & SOCLE_RTC_DALRM_CY) printf("\"Year\" "); if (f_date & SOCLE_RTC_DALRM_CC) printf("\"Century\""); printf("\n"); rtc_set_time_alarm(&tm_a, f_time); rtc_set_date_alarm(&dt_a, f_date); hit = 0; // enable interrupt request_irq(RTC_INT, rtc_isr_alarm_hit, (void *)&hit); rtc_set_date(&dt); rtc_set_time(&tm); printf("Waiting for the alarm...\n"); if (socle_wait_for_int(&hit, 10)) { printf("Timeout!!\n"); result = -1; } // disable interrupt free_irq(RTC_INT); return result; }
static int rtc_ioport_write(void *opaque, uint32_t addr, uint32_t data) { RTCState *s = opaque; struct domain *d = vrtc_domain(s); uint32_t orig; spin_lock(&s->lock); if ( (addr & 1) == 0 ) { data &= 0x7f; s->hw.cmos_index = data; spin_unlock(&s->lock); return (data < RTC_CMOS_SIZE); } if ( s->hw.cmos_index >= RTC_CMOS_SIZE ) { spin_unlock(&s->lock); return 0; } orig = s->hw.cmos_data[s->hw.cmos_index]; switch ( s->hw.cmos_index ) { case RTC_SECONDS_ALARM: case RTC_MINUTES_ALARM: case RTC_HOURS_ALARM: s->hw.cmos_data[s->hw.cmos_index] = data; alarm_timer_update(s); break; case RTC_SECONDS: case RTC_MINUTES: case RTC_HOURS: case RTC_DAY_OF_WEEK: case RTC_DAY_OF_MONTH: case RTC_MONTH: case RTC_YEAR: /* if in set mode, just write the register */ if ( (s->hw.cmos_data[RTC_REG_B] & RTC_SET) ) s->hw.cmos_data[s->hw.cmos_index] = data; else { /* Fetch the current time and update just this field. */ s->current_tm = gmtime(get_localtime(d)); rtc_copy_date(s); s->hw.cmos_data[s->hw.cmos_index] = data; rtc_set_time(s); } alarm_timer_update(s); break; case RTC_REG_A: /* UIP bit is read only */ s->hw.cmos_data[RTC_REG_A] = (data & ~RTC_UIP) | (orig & RTC_UIP); if ( (data ^ orig) & ~RTC_UIP ) rtc_timer_update(s); break; case RTC_REG_B: if ( data & RTC_SET ) { /* set mode: reset UIP mode */ s->hw.cmos_data[RTC_REG_A] &= ~RTC_UIP; /* adjust cmos before stopping */ if (!(orig & RTC_SET)) { s->current_tm = gmtime(get_localtime(d)); rtc_copy_date(s); } } else { /* if disabling set mode, update the time */ if ( orig & RTC_SET ) rtc_set_time(s); } check_for_pf_ticks(s); s->hw.cmos_data[RTC_REG_B] = data; /* * If the interrupt is already set when the interrupt becomes * enabled, raise an interrupt immediately. */ rtc_update_irq(s); if ( (data ^ orig) & RTC_PIE ) { TRACE_0D(TRC_HVM_EMUL_RTC_STOP_TIMER); destroy_periodic_time(&s->pt); s->period = 0; rtc_timer_update(s); } if ( (data ^ orig) & RTC_SET ) check_update_timer(s); if ( (data ^ orig) & (RTC_24H | RTC_DM_BINARY | RTC_SET) ) alarm_timer_update(s); break; case RTC_REG_C: case RTC_REG_D: /* cannot write to them */ break; } spin_unlock(&s->lock); return 1; }
static int tcube_rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { struct rtc_time tm; unsigned long curr_time; #if defined(RTC_ALARM_SUPPORT) unsigned char ctrl_reg[2]; #endif switch (cmd) { case RTC_AIE_OFF: #if defined(RTC_ALARM_SUPPORT) spin_lock_irq (&rtc_lock); rtc_get_ctrl_reg(&ctrl_reg[0]); ctrl_reg[0] ^= 0x40; rtc_set_ctrl_reg(&ctrl_reg[0]); spin_unlock_irq (&rtc_lock); #else return -EINVAL; #endif break; case RTC_AIE_ON: #if defined(RTC_ALARM_SUPPORT) spin_lock_irq (&rtc_lock); rtc_get_ctrl_reg(&ctrl_reg[0]); ctrl_reg[0] |= 0x40; rtc_set_ctrl_reg(&ctrl_reg[0]); spin_unlock_irq (&rtc_lock); #else return -EINVAL; #endif break; case RTC_UIE_OFF: return -EINVAL; break; case RTC_UIE_ON: return -EINVAL; break; case RTC_ALM_READ: rtc_get_alm_time(&tm); break; case RTC_ALM_SET: if (copy_from_user (&tm, (struct rtc_time*)arg, sizeof (tm))) return -EFAULT; return rtc_set_alm_time(&tm); case RTC_RD_TIME: /* Read the time/date from RTC */ curr_time = rtc_get_time(); to_tm(curr_time, &tm); tm.tm_year -= 1900; break; case RTC_SET_TIME: /* Set the time/date from RTC */ if (!capable(CAP_SYS_TIME)) return -EACCES; if (copy_from_user (&tm, (struct rtc_time*)arg, sizeof (tm))) return -EFAULT; tm.tm_year += 1900; if (tm.tm_year < 1970 || (unsigned)tm.tm_mon >= 12 || tm.tm_mday < 1 || tm.tm_mday > (days_in_mo[tm.tm_mon] + (tm.tm_mon == 1 && is_leap(tm.tm_year))) || (unsigned)tm.tm_hour >= 24 || (unsigned)tm.tm_min >= 60 || (unsigned)tm.tm_sec >= 60) return -EINVAL; curr_time = mktime (tm.tm_year, tm.tm_mon + 1, /* tm_mon starts from 0 */ tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); return rtc_set_time(curr_time); case RTC_PIE_ON: case RTC_PIE_OFF: case RTC_IRQP_READ: case RTC_IRQP_SET: case RTC_EPOCH_READ: case RTC_EPOCH_SET: case RTC_WKALM_SET: case RTC_WKALM_RD: default: return -EINVAL; } return copy_to_user ((void *)arg, &tm, sizeof (tm)) ? -EFAULT : 0; }
static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { struct rtc_ops *ops = file->private_data; struct rtc_time tm; struct rtc_wkalrm alrm; void __user *uarg = (void __user *)arg; int ret = -EINVAL; switch (cmd) { case RTC_ALM_READ: ret = rtc_read_alarm(ops, &alrm); if (ret) break; ret = copy_to_user(uarg, &alrm.time, sizeof(tm)); if (ret) ret = -EFAULT; break; case RTC_ALM_SET: ret = copy_from_user(&alrm.time, uarg, sizeof(tm)); if (ret) { ret = -EFAULT; break; } alrm.enabled = 0; alrm.pending = 0; alrm.time.tm_mday = -1; alrm.time.tm_mon = -1; alrm.time.tm_year = -1; alrm.time.tm_wday = -1; alrm.time.tm_yday = -1; alrm.time.tm_isdst = -1; ret = rtc_set_alarm(ops, &alrm); break; case RTC_RD_TIME: ret = rtc_read_time(ops, &tm); if (ret) break; ret = copy_to_user(uarg, &tm, sizeof(tm)); if (ret) ret = -EFAULT; break; case RTC_SET_TIME: if (!capable(CAP_SYS_TIME)) { ret = -EACCES; break; } ret = copy_from_user(&tm, uarg, sizeof(tm)); if (ret) { ret = -EFAULT; break; } ret = rtc_set_time(ops, &tm); break; case RTC_EPOCH_SET: #ifndef rtc_epoch /* * There were no RTC clocks before 1900. */ if (arg < 1900) { ret = -EINVAL; break; } if (!capable(CAP_SYS_TIME)) { ret = -EACCES; break; } rtc_epoch = arg; ret = 0; #endif break; case RTC_EPOCH_READ: ret = put_user(rtc_epoch, (unsigned long __user *)uarg); break; case RTC_WKALM_SET: ret = copy_from_user(&alrm, uarg, sizeof(alrm)); if (ret) { ret = -EFAULT; break; } ret = rtc_set_alarm(ops, &alrm); break; case RTC_WKALM_RD: ret = rtc_read_alarm(ops, &alrm); if (ret) break; ret = copy_to_user(uarg, &alrm, sizeof(alrm)); if (ret) ret = -EFAULT; break; default: if (ops->ioctl) ret = ops->ioctl(cmd, arg); break; } return ret; }
static void cmos_ioport_write(void *opaque, uint32_t addr, uint32_t data) { RTCState *s = opaque; if ((addr & 1) == 0) { s->cmos_index = data & 0x7f; } else { #ifdef DEBUG_CMOS printf("cmos: write index=0x%02x val=0x%02x\n", s->cmos_index, data); #endif switch(s->cmos_index) { case RTC_SECONDS_ALARM: case RTC_MINUTES_ALARM: case RTC_HOURS_ALARM: /* XXX: not supported */ s->cmos_data[s->cmos_index] = data; break; case RTC_SECONDS: case RTC_MINUTES: case RTC_HOURS: case RTC_DAY_OF_WEEK: case RTC_DAY_OF_MONTH: case RTC_MONTH: case RTC_YEAR: s->cmos_data[s->cmos_index] = data; /* if in set mode, do not update the time */ if (!(s->cmos_data[RTC_REG_B] & REG_B_SET)) { rtc_set_time(s); } break; case RTC_REG_A: /* UIP bit is read only */ s->cmos_data[RTC_REG_A] = (data & ~REG_A_UIP) | (s->cmos_data[RTC_REG_A] & REG_A_UIP); rtc_timer_update(s, qemu_get_clock(vm_clock)); break; case RTC_REG_B: if (data & REG_B_SET) { /* set mode: reset UIP mode */ s->cmos_data[RTC_REG_A] &= ~REG_A_UIP; data &= ~REG_B_UIE; } else { /* if disabling set mode, update the time */ if (s->cmos_data[RTC_REG_B] & REG_B_SET) { rtc_set_time(s); } } s->cmos_data[RTC_REG_B] = data; rtc_timer_update(s, qemu_get_clock(vm_clock)); break; case RTC_REG_C: case RTC_REG_D: /* cannot write to them */ break; default: s->cmos_data[s->cmos_index] = data; break; } } }
int main(int argc, char *argv[]) { int r, i; struct tm t; endpoint_t user, caller; message m; int ipc_status, reply_status; env_setargs(argc, argv); r = i2cdriver_env_parse(&bus, &addresses[0], valid_addrs); if (r < 0) { log_warn(&log, "Expecting -args 'bus=X address=0xYY'\n"); log_warn(&log, "Example -args 'bus=1 address=0x48'\n"); return EXIT_FAILURE; } else if (r > 0) { log_warn(&log, "Invalid slave address for device, expecting 0x48\n"); return EXIT_FAILURE; } sef_local_startup(); while (TRUE) { /* Receive Message */ r = sef_receive_status(ANY, &m, &ipc_status); if (r != OK) { log_warn(&log, "sef_receive_status() failed\n"); continue; } if (is_ipc_notify(ipc_status)) { if (m.m_source == DS_PROC_NR) { for (i = 0; i < NADDRESSES; i++) { /* changed state, update endpoint */ i2cdriver_handle_bus_update (&bus_endpoint, bus, addresses[i]); } } /* Do not reply to notifications. */ continue; } caller = m.m_source; log_debug(&log, "Got message 0x%x from 0x%x\n", m.m_type, caller); switch (m.m_type) { case RTCDEV_GET_TIME_G: /* Any user can read the time */ reply_status = rtc_get_time(&t, m.RTCDEV_FLAGS); if (reply_status != OK) { break; } /* write results back to calling process */ reply_status = store_t(caller, (cp_grant_id_t) m.RTCDEV_GRANT, &t); break; case RTCDEV_SET_TIME_G: /* Only super user is allowed to set the time */ if (getnuid(caller) == SUPER_USER) { /* read time from calling process */ reply_status = fetch_t(caller, (cp_grant_id_t) m.RTCDEV_GRANT, &t); if (reply_status != OK) { break; } reply_status = rtc_set_time(&t, m.RTCDEV_FLAGS); } else { reply_status = EPERM; } break; case RTCDEV_PWR_OFF: reply_status = ENOSYS; break; default: /* Unrecognized call */ reply_status = EINVAL; break; } /* Send Reply */ m.m_type = RTCDEV_REPLY; m.RTCDEV_STATUS = reply_status; log_debug(&log, "Sending Reply"); r = sendnb(caller, &m); if (r != OK) { log_warn(&log, "sendnb() failed\n"); continue; } } rtc_exit(); return 0; }
static void cmos_ioport_write(void *opaque, uint32_t addr, uint32_t data) { RTCState *s = opaque; if ((addr & 1) == 0) { s->cmos_index = data & 0x7f; } else { CMOS_DPRINTF("cmos: write index=0x%02x val=0x%02x\n", s->cmos_index, data); switch(s->cmos_index) { case RTC_SECONDS_ALARM: case RTC_MINUTES_ALARM: case RTC_HOURS_ALARM: s->cmos_data[s->cmos_index] = data; break; case RTC_SECONDS: case RTC_MINUTES: case RTC_HOURS: case RTC_DAY_OF_WEEK: case RTC_DAY_OF_MONTH: case RTC_MONTH: case RTC_YEAR: s->cmos_data[s->cmos_index] = data; /* if in set mode, do not update the time */ if (!(s->cmos_data[RTC_REG_B] & REG_B_SET)) { rtc_set_time(s); } break; case RTC_REG_A: /* UIP bit is read only */ s->cmos_data[RTC_REG_A] = (data & ~REG_A_UIP) | (s->cmos_data[RTC_REG_A] & REG_A_UIP); rtc_timer_update(s, qemu_get_clock_ns(rtc_clock)); break; case RTC_REG_B: if (data & REG_B_SET) { /* set mode: reset UIP mode */ s->cmos_data[RTC_REG_A] &= ~REG_A_UIP; data &= ~REG_B_UIE; } else { /* if disabling set mode, update the time */ if (s->cmos_data[RTC_REG_B] & REG_B_SET) { rtc_set_time(s); } } if (((s->cmos_data[RTC_REG_B] ^ data) & (REG_B_DM | REG_B_24H)) && !(data & REG_B_SET)) { /* If the time format has changed and not in set mode, update the registers immediately. */ s->cmos_data[RTC_REG_B] = data; rtc_copy_date(s); } else { s->cmos_data[RTC_REG_B] = data; } rtc_timer_update(s, qemu_get_clock_ns(rtc_clock)); break; case RTC_REG_C: case RTC_REG_D: /* cannot write to them */ break; default: s->cmos_data[s->cmos_index] = data; break; } } }