static int omap_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) { local_irq_disable(); rtc_wait_not_busy(); alm->time.tm_sec = rtc_read(OMAP_RTC_ALARM_SECONDS_REG); alm->time.tm_min = rtc_read(OMAP_RTC_ALARM_MINUTES_REG); alm->time.tm_hour = rtc_read(OMAP_RTC_ALARM_HOURS_REG); alm->time.tm_mday = rtc_read(OMAP_RTC_ALARM_DAYS_REG); alm->time.tm_mon = rtc_read(OMAP_RTC_ALARM_MONTHS_REG); alm->time.tm_year = rtc_read(OMAP_RTC_ALARM_YEARS_REG); local_irq_enable(); bcd2tm(&alm->time); alm->enabled = !!(rtc_read(OMAP_RTC_INTERRUPTS_REG) & OMAP_RTC_INTERRUPTS_IT_ALARM); return 0; }
void rtc_get_tm (struct tm *tim) { u16 daysmonth[] = { 0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; /* When this bit is set, rtc is updating the count. * It gives us 244 usecs */ while ((rtc_read (0xa) & 0x80) != 0) ; tim->tm_sec = rtc_read (0); tim->tm_min = rtc_read (2); tim->tm_hour = rtc_read (4); tim->tm_mday = rtc_read (7); tim->tm_mon = rtc_read (8); tim->tm_year = rtc_read (9) + 2000; /* Century will be assumed 20. * This code doesn't always work: */ /* + bcd2int (rtc_read (0x32)) * 100; */ tim->tm_wday = rtc_read (6) - 1; tim->tm_yday = daysmonth[tim->tm_mon] + tim->tm_mday; }
static int omap_rtc_resume(struct device *dev) { u8 irqwake_stat; struct platform_device *pdev = to_platform_device(dev); const struct platform_device_id *id_entry = platform_get_device_id(pdev); /* Enable the clock/module so that we can access the registers */ pm_runtime_get_sync(dev); if (device_may_wakeup(dev)) { disable_irq_wake(omap_rtc_alarm); if (id_entry->driver_data & OMAP_RTC_HAS_IRQWAKEEN) { irqwake_stat = rtc_read(OMAP_RTC_IRQWAKEEN); irqwake_stat &= ~OMAP_RTC_IRQWAKEEN_ALARM_WAKEEN; rtc_write(irqwake_stat, OMAP_RTC_IRQWAKEEN); } } else { rtc_write(irqstat, OMAP_RTC_INTERRUPTS_REG); } return 0; }
static int omap_rtc_suspend(struct platform_device *pdev, pm_message_t state) { struct rtc_time rtc_tm; struct timespec time; time.tv_nsec = 0; omap_rtc_read_time(NULL, &rtc_tm); rtc_tm_to_time(&rtc_tm, &time.tv_sec); save_time_delta(&rtc_delta, &time); irqstat = rtc_read(OMAP_RTC_INTERRUPTS_REG); /* FIXME the RTC alarm is not currently acting as a wakeup event * source, and in fact this enable() call is just saving a flag * that's never used... */ if (device_may_wakeup(&pdev->dev)) enable_irq_wake(omap_rtc_alarm); else rtc_write(0, OMAP_RTC_INTERRUPTS_REG); return 0; }
int main() { time_t seconds; struct tm *timeinfo; rtc_init(); rtc_write(1256729737); // Set RTC time to Wed, 28 Oct 2009 11:35:37 while(1) { seconds = rtc_read(); timeinfo = localtime(&seconds); DBG_8195A("Time as seconds since January 1, 1970 = %d\n", seconds); DBG_8195A("Time as a basic string = %s", ctime(&seconds)); DBG_8195A("Time as a custom formatted string = %d-%d-%d %d:%d:%d ", timeinfo->tm_year, timeinfo->tm_mon, timeinfo->tm_mday, timeinfo->tm_hour, timeinfo->tm_min,timeinfo->tm_sec); wait(1); } }
static int omap_rtc_suspend(struct device *dev) { struct omap_rtc *rtc = dev_get_drvdata(dev); rtc->interrupts_reg = rtc_read(rtc, OMAP_RTC_INTERRUPTS_REG); rtc->type->unlock(rtc); /* * FIXME: the RTC alarm is not currently acting as a wakeup event * source on some platforms, and in fact this enable() call is just * saving a flag that's never used... */ if (device_may_wakeup(dev)) enable_irq_wake(rtc->irq_alarm); else rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, 0); rtc->type->lock(rtc); /* Disable the clock/module */ pm_runtime_put_sync(dev); return 0; }
static int __exit omap_rtc_remove(struct platform_device *pdev) { struct omap_rtc *rtc = platform_get_drvdata(pdev); u8 reg; if (pm_power_off == omap_rtc_power_off && omap_rtc_power_off_rtc == rtc) { pm_power_off = NULL; omap_rtc_power_off_rtc = NULL; } device_init_wakeup(&pdev->dev, 0); if (!IS_ERR(rtc->clk)) clk_disable_unprepare(rtc->clk); rtc->type->unlock(rtc); /* leave rtc running, but disable irqs */ rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, 0); if (rtc->has_ext_clk) { reg = rtc_read(rtc, OMAP_RTC_OSC_REG); reg &= ~OMAP_RTC_OSC_SEL_32KCLK_SRC; rtc_write(rtc, OMAP_RTC_OSC_REG, reg); } rtc->type->lock(rtc); /* Disable the clock/module */ pm_runtime_put_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); /* Remove ext_wakeup pinconf */ pinctrl_unregister(rtc->pctldev); return 0; }
static int omap_rtc_read_time(struct device *dev, struct rtc_time *tm) { /* we don't report wday/yday/isdst ... */ local_irq_disable(); rtc_wait_not_busy(); tm->tm_sec = rtc_read(OMAP_RTC_SECONDS_REG); tm->tm_min = rtc_read(OMAP_RTC_MINUTES_REG); tm->tm_hour = rtc_read(OMAP_RTC_HOURS_REG); tm->tm_mday = rtc_read(OMAP_RTC_DAYS_REG); tm->tm_mon = rtc_read(OMAP_RTC_MONTHS_REG); tm->tm_year = rtc_read(OMAP_RTC_YEARS_REG); local_irq_enable(); bcd2tm(tm); return 0; }
static irqreturn_t rtc_irq(int irq, void *dev_id) { struct omap_rtc *rtc = dev_id; unsigned long events = 0; u8 irq_data; irq_data = rtc_read(rtc, OMAP_RTC_STATUS_REG); /* alarm irq? */ if (irq_data & OMAP_RTC_STATUS_ALARM) { rtc->type->unlock(rtc); rtc_write(rtc, OMAP_RTC_STATUS_REG, OMAP_RTC_STATUS_ALARM); rtc->type->lock(rtc); events |= RTC_IRQF | RTC_AF; } /* 1/sec periodic/update irq? */ if (irq_data & OMAP_RTC_STATUS_1S_EVENT) events |= RTC_IRQF | RTC_UF; rtc_update_irq(rtc->rtc, 1, events); return IRQ_HANDLED; }
/* * Return current RTC time. Note that due to waiting for the update cycle to * complete, this call may take some time. */ static uint64_t rtc_gettimeofday(void) { struct bmk_clock_ymdhms dt; interrupts_disable(); /* * If RTC_UIP is down, we have at least 244us to obtain a * consistent reading before an update can occur. */ while (rtc_read(RTC_STATUS_A) & RTC_UIP) continue; dt.dt_sec = bcdtobin(rtc_read(RTC_SEC)); dt.dt_min = bcdtobin(rtc_read(RTC_MIN)); dt.dt_hour = bcdtobin(rtc_read(RTC_HOUR)); dt.dt_day = bcdtobin(rtc_read(RTC_DAY)); dt.dt_mon = bcdtobin(rtc_read(RTC_MONTH)); dt.dt_year = bcdtobin(rtc_read(RTC_YEAR)) + 2000; interrupts_enable(); return clock_ymdhms_to_secs(&dt) * NSEC_PER_SEC; }
static int omap_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) { struct omap_rtc *rtc = dev_get_drvdata(dev); u8 interrupts; local_irq_disable(); rtc_wait_not_busy(rtc); alm->time.tm_sec = rtc_read(rtc, OMAP_RTC_ALARM_SECONDS_REG); alm->time.tm_min = rtc_read(rtc, OMAP_RTC_ALARM_MINUTES_REG); alm->time.tm_hour = rtc_read(rtc, OMAP_RTC_ALARM_HOURS_REG); alm->time.tm_mday = rtc_read(rtc, OMAP_RTC_ALARM_DAYS_REG); alm->time.tm_mon = rtc_read(rtc, OMAP_RTC_ALARM_MONTHS_REG); alm->time.tm_year = rtc_read(rtc, OMAP_RTC_ALARM_YEARS_REG); local_irq_enable(); bcd2tm(&alm->time); interrupts = rtc_read(rtc, OMAP_RTC_INTERRUPTS_REG); alm->enabled = !!(interrupts & OMAP_RTC_INTERRUPTS_IT_ALARM); return 0; }
int rtc_get(struct rtc_time *rtc) { uchar sec, min, hour, mday, month, year; /* Reading counts register latches the current RTC calendar count. * This guranties the coherence of the read during aprox 500 ms */ sec = rtc_read (DA9052_COUNTS_REG); if (!(sec & DA9052_COUNTS_MONITOR)) { puts("*** ERROR: " DEV_NAME " - incorrect date/time (Power was lost)\n"); } min = rtc_read (DA9052_COUNTMI_REG); hour = rtc_read (DA9052_COUNTH_REG); mday = rtc_read (DA9052_COUNTD_REG); month = rtc_read (DA9052_COUNTMO_REG); year = rtc_read (DA9052_COUNTY_REG); DBG ("Get RTC year: %02d mon: %02d mday: %02d " "hr: %02d min: %02d sec: %02d\n", year, month, mday, hour, min, sec); rtc->tm_sec = sec & DA9052_COUNTS_COUNTSEC; rtc->tm_min = min & DA9052_COUNTMI_COUNTMIN; rtc->tm_hour = hour & DA9052_COUNTH_COUNTHOUR; rtc->tm_mday = mday & DA9052_COUNTD_COUNTDAY; rtc->tm_mon = month & DA9052_COUNTMO_COUNTMONTH; rtc->tm_year = (year & DA9052_COUNTY_COUNTYEAR) + 2000; /* Compute the the day of week, not available in the RTC registers */ GregorianDay(rtc); DBG ("Get DATE: %4d-%02d-%02d TIME: %2d:%02d:%02d\n", rtc->tm_year, rtc->tm_mon, rtc->tm_mday, rtc->tm_hour, rtc->tm_min, rtc->tm_sec); return 0; }
/* * set the rtc chip's idea of the time. * stupidly, some callers call with year unmolested; * and some call with year = year - 1900. thanks. */ static int ds1511_rtc_set_time(struct device *dev, struct rtc_time *rtc_tm) { u8 mon, day, dow, hrs, min, sec, yrs, cen; unsigned long flags; /* * won't have to change this for a while */ if (rtc_tm->tm_year < 1900) { rtc_tm->tm_year += 1900; } if (rtc_tm->tm_year < 1970) { return -EINVAL; } yrs = rtc_tm->tm_year % 100; cen = rtc_tm->tm_year / 100; mon = rtc_tm->tm_mon + 1; /* tm_mon starts at zero */ day = rtc_tm->tm_mday; dow = rtc_tm->tm_wday & 0x7; /* automatic BCD */ hrs = rtc_tm->tm_hour; min = rtc_tm->tm_min; sec = rtc_tm->tm_sec; if ((mon > 12) || (day == 0)) { return -EINVAL; } if (day > rtc_month_days(rtc_tm->tm_mon, rtc_tm->tm_year)) { return -EINVAL; } if ((hrs >= 24) || (min >= 60) || (sec >= 60)) { return -EINVAL; } /* * each register is a different number of valid bits */ sec = bin2bcd(sec) & 0x7f; min = bin2bcd(min) & 0x7f; hrs = bin2bcd(hrs) & 0x3f; day = bin2bcd(day) & 0x3f; mon = bin2bcd(mon) & 0x1f; yrs = bin2bcd(yrs) & 0xff; cen = bin2bcd(cen) & 0xff; spin_lock_irqsave(&ds1511_lock, flags); rtc_disable_update(); rtc_write(cen, RTC_CENTURY); rtc_write(yrs, RTC_YEAR); rtc_write((rtc_read(RTC_MON) & 0xe0) | mon, RTC_MON); rtc_write(day, RTC_DOM); rtc_write(hrs, RTC_HOUR); rtc_write(min, RTC_MIN); rtc_write(sec, RTC_SEC); rtc_write(dow, RTC_DOW); rtc_enable_update(); spin_unlock_irqrestore(&ds1511_lock, flags); return 0; }
int main(void) { uart_t *u0; /* Delay for one second to avoid multiple resets during programming. */ _delay_ms(1000); /* Initialize USART0 and set up stdout to write to it. */ u0 = uart_init("0", UART_BAUD_SELECT(38400, F_CPU)); uart_init_stdout(u0); uart_set_rx_callback(u0, notice_uart_input); i2c_init(); /* * Test if pullup is required on the I2C pins, and enable if the pins are * reading low. This allows external pullups to optionally be used, so that * for example the I2C bus can be pulled up to 3.3V to allow communication * between 3.3V and 5V devices at 3.3V. */ if((PINC & (_BV(PC0) | _BV(PC1))) == 0) { DDRC = _BV(PC0) | _BV(PC1); PORTC = _BV(PC0) | _BV(PC1); } sei(); printf_P(PSTR("\n\nBooted!\n")); printf_P(PSTR("Reading saved configuration...\n\n")); configuration_restore(); printf_P(PSTR( "Configuration:\n" " tz_offset: %2i\n" " dst_offset: %2i\n" "\n" ), configuration.tz_offset, configuration.dst_offset); printf_P(PSTR( "Commands:\n" " Get the current time:\n" " G\n" " Set the current time:\n" " S YYYY-MM-DD hh:mm:ss\n" " Set the timezone offset from UTC:\n" " O <tz_offset> <dst_offset>\n" " Set the time from GPS (if available):" " s\n" "\n" )); rtc_init(rtc); rtc_sqw_enable(rtc); rtc_sqw_rate(rtc, 1); /* Enable pullup and interrupt for PC6/PCINT22, DS1307 SQW pin. */ PORTC |= _BV(PC6); PCMSK2 |= _BV(PCINT22); PCICR |= _BV(PCIE2); /* Initialize the sequencer with 1000Hz tick rate. */ led_sequencer_init(1000); /* Initialize and load the LED Analog Clock LED display. */ led_charlieplex_init(&LED_DISPLAY); led_sequencer_push_front_matrix("c", &LED_DISPLAY); /* * Add empty sequences for hour, minute, second, hourly show, and minutely * show. */ led_sequencer_push_back_sequence("h"); led_sequencer_push_back_sequence("m"); led_sequencer_push_back_sequence("s"); led_sequencer_push_back_sequence("H"); led_sequencer_push_back_sequence("M"); /* * Initially read the time, set last_* for use later, and push a sequencer * step into the second, minute, and hour sequences. The steps pushed * below are never removed, as they are modified in place in update_hms() * with each time change. */ rtc_read(rtc, ¤t_time); last_hour = current_time.hour; last_minute = current_time.minute; last_second = current_time.second; step_hour = led_sequencer_sequence_push_back_step("h", LED_SEQUENCER_STEP_SHOW, "c", led_mapping_qhour[((current_time.hour % 12) * 4) + (current_time.minute / 15)], 255); step_minute = led_sequencer_sequence_push_back_step("m", LED_SEQUENCER_STEP_SHOW, "c", led_mapping_minute[current_time.minute], 255); step_second = led_sequencer_sequence_push_back_step("s", LED_SEQUENCER_STEP_SHOW, "c", led_mapping_minute[current_time.second], 255); enqueue_hourly_show(); led_sequencer_run(); srand(current_time.hour * current_time.minute * current_time.second); /* * Main infinite loop. */ while(1) { /* Handle UART input when ready. */ if(ready_flags & READY_UART_DATA) { ready_flags &= ~READY_UART_DATA; handle_uart_input(u0); } /* A time change has occurred, update the clock display. */ if(ready_flags & READY_UPDATE_HMS) { ready_flags &= ~READY_UPDATE_HMS; update_hms(); } /* * Run one loop through the current sequence, with interrupts disabled. */ cli(); led_sequencer_display(); sei(); } /* Never reached. */ return(0); }
int rtc_get( struct rtc_time *tmp) { if (phantom_flag < 0) phantom_flag = get_phantom_flag(); if (phantom_flag) { unsigned char rtc[8]; phantom_rtc_read(RTC_BASE, rtc); tmp->tm_sec = bcd2bin(rtc[1] & 0x7f); tmp->tm_min = bcd2bin(rtc[2] & 0x7f); tmp->tm_hour = bcd2bin(rtc[3] & 0x1f); tmp->tm_wday = bcd2bin(rtc[4] & 0x7); tmp->tm_mday = bcd2bin(rtc[5] & 0x3f); tmp->tm_mon = bcd2bin(rtc[6] & 0x1f); tmp->tm_year = bcd2bin(rtc[7]) + 1900; tmp->tm_yday = 0; tmp->tm_isdst = 0; if( (rtc[3] & 0x80) && (rtc[3] & 0x40) ) tmp->tm_hour += 12; if (tmp->tm_year < 1970) tmp->tm_year += 100; } else { uchar sec, min, hour; uchar mday, wday, mon, year; int century; uchar reg_a; if (century_flag < 0) century_flag = get_century_flag(); reg_a = rtc_read( RTC_CONTROLA ); /* lock clock registers for read */ rtc_write( RTC_CONTROLA, ( reg_a | RTC_CA_READ )); sec = rtc_read( RTC_SECONDS ); min = rtc_read( RTC_MINUTES ); hour = rtc_read( RTC_HOURS ); mday = rtc_read( RTC_DAY_OF_MONTH ); wday = rtc_read( RTC_DAY_OF_WEEK ); mon = rtc_read( RTC_MONTH ); year = rtc_read( RTC_YEAR ); century = rtc_read( RTC_CENTURY ); /* unlock clock registers after read */ rtc_write( RTC_CONTROLA, ( reg_a & ~RTC_CA_READ )); tmp->tm_sec = bcd2bin( sec & 0x7F ); tmp->tm_min = bcd2bin( min & 0x7F ); tmp->tm_hour = bcd2bin( hour & 0x3F ); tmp->tm_mday = bcd2bin( mday & 0x3F ); tmp->tm_mon = bcd2bin( mon & 0x1F ); tmp->tm_wday = bcd2bin( wday & 0x07 ); if (century_flag) { tmp->tm_year = bcd2bin( year ) + ( bcd2bin( century & 0x3F ) * 100 ); } else { tmp->tm_year = bcd2bin( year ) + 1900; if (tmp->tm_year < 1970) tmp->tm_year += 100; } tmp->tm_yday = 0; tmp->tm_isdst= 0; } return 0; }
void timer_sync_time( void ) { current_time = rtc_read(); }
/** * Update the "h", "m", and "s" sequences, optionally queuing an animation * into "H" or "M" sequences, depending on the new time. This function is * called once per second during the main loop after the interrupt triggered * by the time change marks update_hms_ready. * * The "h", "m", and "s" sequences are updated in-place in order to avoid * additional work and possible memory fragmentation from removing and * re-enqueuing the applicable LED. */ void update_hms(void) { uint8_t rc; rtc_datetime_24h_t offset_time; if(++time_elapsed_since_gps_sync > 1777) { printf_P(PSTR("Maximum time limit exceeded since last GPS sync, syncing...\n")); command_set_from_gps(); time_elapsed_since_gps_sync = 0; } rc = rtc_read(rtc, ¤t_time); if(rc) return; rtc_offset_time(¤t_time, &offset_time, configuration.tz_offset + configuration.dst_offset); if(current_time.hour != last_hour) { configuration.dst_offset = rtc_find_dst_offset(offset_time, usa_dst_dates); rtc_offset_time(¤t_time, &offset_time, configuration.tz_offset + configuration.dst_offset); } led_sequencer_halt(); /* * If the second has changed since the last time the time was checked, * we should update the "second", "minute, and "hour" sequences. In practice * this is nearly always the case, since the interrupts ensure we're only * really called when needed. */ if(current_time.second != last_second) { led_sequencer_sequence_modify_step(step_second, led_mapping_minute[offset_time.second], 255); led_sequencer_sequence_modify_step(step_minute, led_mapping_minute[offset_time.minute], 255); led_sequencer_sequence_modify_step(step_hour, led_mapping_qhour[((offset_time.hour % 12) * 4) + (offset_time.minute / 15)], 255); enqueue_secondly_show(); last_second = current_time.second; } /* Do something nice for New Years */ if(offset_time.month == 1 && offset_time.date == 1 && offset_time.hour == 0 && offset_time.minute == 0 && offset_time.second == 0) { enqueue_nye_show(); last_hour = current_time.hour; last_minute = current_time.minute; } /* * If the hour has changed, enqueue the hourly show. */ else if(current_time.hour != last_hour) { enqueue_hourly_show(); last_hour = current_time.hour; } /* * If the hour is still the same, enqueue the minutely show. */ else if(current_time.minute != last_minute) { enqueue_minutely_show(); last_minute = current_time.minute; } led_sequencer_run(); update_gps(); write_remote_lcd(&offset_time, gps_data.gps_signal_strength); }
static int __init omap_rtc_probe(struct platform_device *pdev) { struct resource *res, *mem; struct rtc_device *rtc; u8 reg, new_ctrl; omap_rtc_timer = platform_get_irq(pdev, 0); if (omap_rtc_timer <= 0) { pr_debug("%s: no update irq?\n", pdev->name); return -ENOENT; } omap_rtc_alarm = platform_get_irq(pdev, 1); if (omap_rtc_alarm <= 0) { pr_debug("%s: no alarm irq?\n", pdev->name); return -ENOENT; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { pr_debug("%s: RTC resource data missing\n", pdev->name); return -ENOENT; } mem = request_mem_region(res->start, resource_size(res), pdev->name); if (!mem) { pr_debug("%s: RTC registers at %08x are not free\n", pdev->name, res->start); return -EBUSY; } rtc_base = ioremap(res->start, resource_size(res)); if (!rtc_base) { pr_debug("%s: RTC registers can't be mapped\n", pdev->name); goto fail; } rtc = rtc_device_register(pdev->name, &pdev->dev, &omap_rtc_ops, THIS_MODULE); if (IS_ERR(rtc)) { pr_debug("%s: can't register RTC device, err %ld\n", pdev->name, PTR_ERR(rtc)); goto fail0; } platform_set_drvdata(pdev, rtc); dev_set_drvdata(&rtc->dev, mem); /* clear pending irqs, and set 1/second periodic, * which we'll use instead of update irqs */ rtc_write(0, OMAP_RTC_INTERRUPTS_REG); /* clear old status */ reg = rtc_read(OMAP_RTC_STATUS_REG); if (reg & (u8) OMAP_RTC_STATUS_POWER_UP) { pr_info("%s: RTC power up reset detected\n", pdev->name); rtc_write(OMAP_RTC_STATUS_POWER_UP, OMAP_RTC_STATUS_REG); } if (reg & (u8) OMAP_RTC_STATUS_ALARM) rtc_write(OMAP_RTC_STATUS_ALARM, OMAP_RTC_STATUS_REG); /* handle periodic and alarm irqs */ if (request_irq(omap_rtc_timer, rtc_irq, IRQF_DISABLED, dev_name(&rtc->dev), rtc)) { pr_debug("%s: RTC timer interrupt IRQ%d already claimed\n", pdev->name, omap_rtc_timer); goto fail1; } if ((omap_rtc_timer != omap_rtc_alarm) && (request_irq(omap_rtc_alarm, rtc_irq, IRQF_DISABLED, dev_name(&rtc->dev), rtc))) { pr_debug("%s: RTC alarm interrupt IRQ%d already claimed\n", pdev->name, omap_rtc_alarm); goto fail2; } /* On boards with split power, RTC_ON_NOFF won't reset the RTC */ reg = rtc_read(OMAP_RTC_CTRL_REG); if (reg & (u8) OMAP_RTC_CTRL_STOP) pr_info("%s: already running\n", pdev->name); /* force to 24 hour mode */ new_ctrl = reg & ~(OMAP_RTC_CTRL_SPLIT|OMAP_RTC_CTRL_AUTO_COMP); new_ctrl |= OMAP_RTC_CTRL_STOP; /* BOARD-SPECIFIC CUSTOMIZATION CAN GO HERE: * * - Device wake-up capability setting should come through chip * init logic. OMAP1 boards should initialize the "wakeup capable" * flag in the platform device if the board is wired right for * being woken up by RTC alarm. For OMAP-L138, this capability * is built into the SoC by the "Deep Sleep" capability. * * - Boards wired so RTC_ON_nOFF is used as the reset signal, * rather than nPWRON_RESET, should forcibly enable split * power mode. (Some chip errata report that RTC_CTRL_SPLIT * is write-only, and always reads as zero...) */ if (new_ctrl & (u8) OMAP_RTC_CTRL_SPLIT) pr_info("%s: split power mode\n", pdev->name); if (reg != new_ctrl) rtc_write(new_ctrl, OMAP_RTC_CTRL_REG); return 0; fail2: free_irq(omap_rtc_timer, rtc); fail1: rtc_device_unregister(rtc); fail0: iounmap(rtc_base); fail: release_mem_region(mem->start, resource_size(mem)); return -EIO; }
rtems_device_driver Clock_initialize( rtems_device_major_number major, rtems_device_minor_number minor, void *pargp ) { unsigned timer_counter_init_value; unsigned char clock_lsb, clock_msb; #ifdef BSP_DEBUG printk("Initializing clock driver in Clock_initialize().\n"); #endif #ifdef LOAD_RTC_AT_START /* Initialize clock from on-board real time clock. This breaks the */ /* test code which assumes which assumes the application will do it. */ { rtems_time_of_day now; #ifdef BSP_DEBUG printk("Loading clock from on-board real-time clock.\n"); #endif init_rtc(); if (rtc_read(&now) >= 0) rtems_clock_set(&now); } #endif Clock_driver_ticks = 0; Clock_isrs = Clock_initial_isr_value = rtems_configuration_get_microseconds_per_tick() / 1000; /* ticks per clock_isr */ /* * configure the counter timer ( should be based on microsecs/tick ) * NB. The divisor(Clock_isrs) resolves the is the same number that appears in confdefs.h * when setting the microseconds_per_tick value. */ ClockOff ( &clockIrqData ); timer_counter_init_value = rtems_configuration_get_microseconds_per_tick() / Clock_isrs; clock_lsb = (unsigned char)timer_counter_init_value; clock_msb = timer_counter_init_value >> 8; outport_byte (TIMER_MODE, TIMER_SEL0|TIMER_16BIT|TIMER_RATEGEN); outport_byte (TIMER_CNTR0, clock_lsb ); /* load LSB first */ outport_byte (TIMER_CNTR0, clock_msb ); /* then MSB */ if (!BSP_install_rtems_irq_handler (&clockIrqData)) { printk("Unable to initialize system clock\n"); rtems_fatal_error_occurred(1); } /* * make major/minor avail to others such as shared memory driver */ rtems_clock_major = major; rtems_clock_minor = minor; return RTEMS_SUCCESSFUL; }
unsigned char time_get(unsigned char addr) { rtc_write(addr); unsigned char ret = rtc_read(); rtc_transm_end(); return ret; }
static int omap_rtc_probe(struct platform_device *pdev) { struct omap_rtc *rtc; struct resource *res; u8 reg, mask, new_ctrl; const struct platform_device_id *id_entry; const struct of_device_id *of_id; int ret; rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL); if (!rtc) return -ENOMEM; of_id = of_match_device(omap_rtc_of_match, &pdev->dev); if (of_id) { rtc->type = of_id->data; rtc->is_pmic_controller = rtc->type->has_pmic_mode && of_property_read_bool(pdev->dev.of_node, "system-power-controller"); } else { id_entry = platform_get_device_id(pdev); rtc->type = (void *)id_entry->driver_data; } rtc->irq_timer = platform_get_irq(pdev, 0); if (rtc->irq_timer <= 0) return -ENOENT; rtc->irq_alarm = platform_get_irq(pdev, 1); if (rtc->irq_alarm <= 0) return -ENOENT; rtc->clk = devm_clk_get(&pdev->dev, "ext-clk"); if (!IS_ERR(rtc->clk)) rtc->has_ext_clk = true; else rtc->clk = devm_clk_get(&pdev->dev, "int-clk"); if (!IS_ERR(rtc->clk)) clk_prepare_enable(rtc->clk); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); rtc->base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(rtc->base)) return PTR_ERR(rtc->base); platform_set_drvdata(pdev, rtc); /* Enable the clock/module so that we can access the registers */ pm_runtime_enable(&pdev->dev); pm_runtime_get_sync(&pdev->dev); rtc->type->unlock(rtc); /* * disable interrupts * * NOTE: ALARM2 is not cleared on AM3352 if rtc_write (writeb) is used */ rtc_writel(rtc, OMAP_RTC_INTERRUPTS_REG, 0); /* enable RTC functional clock */ if (rtc->type->has_32kclk_en) { reg = rtc_read(rtc, OMAP_RTC_OSC_REG); rtc_writel(rtc, OMAP_RTC_OSC_REG, reg | OMAP_RTC_OSC_32KCLK_EN); } /* clear old status */ reg = rtc_read(rtc, OMAP_RTC_STATUS_REG); mask = OMAP_RTC_STATUS_ALARM; if (rtc->type->has_pmic_mode) mask |= OMAP_RTC_STATUS_ALARM2; if (rtc->type->has_power_up_reset) { mask |= OMAP_RTC_STATUS_POWER_UP; if (reg & OMAP_RTC_STATUS_POWER_UP) dev_info(&pdev->dev, "RTC power up reset detected\n"); } if (reg & mask) rtc_write(rtc, OMAP_RTC_STATUS_REG, reg & mask); /* On boards with split power, RTC_ON_NOFF won't reset the RTC */ reg = rtc_read(rtc, OMAP_RTC_CTRL_REG); if (reg & OMAP_RTC_CTRL_STOP) dev_info(&pdev->dev, "already running\n"); /* force to 24 hour mode */ new_ctrl = reg & (OMAP_RTC_CTRL_SPLIT | OMAP_RTC_CTRL_AUTO_COMP); new_ctrl |= OMAP_RTC_CTRL_STOP; /* * BOARD-SPECIFIC CUSTOMIZATION CAN GO HERE: * * - Device wake-up capability setting should come through chip * init logic. OMAP1 boards should initialize the "wakeup capable" * flag in the platform device if the board is wired right for * being woken up by RTC alarm. For OMAP-L138, this capability * is built into the SoC by the "Deep Sleep" capability. * * - Boards wired so RTC_ON_nOFF is used as the reset signal, * rather than nPWRON_RESET, should forcibly enable split * power mode. (Some chip errata report that RTC_CTRL_SPLIT * is write-only, and always reads as zero...) */ if (new_ctrl & OMAP_RTC_CTRL_SPLIT) dev_info(&pdev->dev, "split power mode\n"); if (reg != new_ctrl) rtc_write(rtc, OMAP_RTC_CTRL_REG, new_ctrl); /* * If we have the external clock then switch to it so we can keep * ticking across suspend. */ if (rtc->has_ext_clk) { reg = rtc_read(rtc, OMAP_RTC_OSC_REG); reg &= ~OMAP_RTC_OSC_OSC32K_GZ_DISABLE; reg |= OMAP_RTC_OSC_32KCLK_EN | OMAP_RTC_OSC_SEL_32KCLK_SRC; rtc_writel(rtc, OMAP_RTC_OSC_REG, reg); } rtc->type->lock(rtc); device_init_wakeup(&pdev->dev, true); rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, &omap_rtc_ops, THIS_MODULE); if (IS_ERR(rtc->rtc)) { ret = PTR_ERR(rtc->rtc); goto err; } /* handle periodic and alarm irqs */ ret = devm_request_irq(&pdev->dev, rtc->irq_timer, rtc_irq, 0, dev_name(&rtc->rtc->dev), rtc); if (ret) goto err; if (rtc->irq_timer != rtc->irq_alarm) { ret = devm_request_irq(&pdev->dev, rtc->irq_alarm, rtc_irq, 0, dev_name(&rtc->rtc->dev), rtc); if (ret) goto err; } if (rtc->is_pmic_controller) { if (!pm_power_off) { omap_rtc_power_off_rtc = rtc; pm_power_off = omap_rtc_power_off; } } /* Support ext_wakeup pinconf */ rtc_pinctrl_desc.name = dev_name(&pdev->dev); rtc->pctldev = pinctrl_register(&rtc_pinctrl_desc, &pdev->dev, rtc); if (IS_ERR(rtc->pctldev)) { dev_err(&pdev->dev, "Couldn't register pinctrl driver\n"); return PTR_ERR(rtc->pctldev); } return 0; err: device_init_wakeup(&pdev->dev, false); rtc->type->lock(rtc); pm_runtime_put_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); return ret; }
static inline void rtc_disable_update(void) { rtc_write((rtc_read(RTC_CMD) & ~RTC_TE), RTC_CMD); }
/* * Get the current time from the RTC */ int rtc_get (struct rtc_time *tmp) { int rel = 0; uchar sec, min, hour, mday, wday, mon, year; #ifdef CONFIG_RTC_MCP79411 read_rtc: #endif sec = rtc_read (RTC_SEC_REG_ADDR); min = rtc_read (RTC_MIN_REG_ADDR); hour = rtc_read (RTC_HR_REG_ADDR); wday = rtc_read (RTC_DAY_REG_ADDR); mday = rtc_read (RTC_DATE_REG_ADDR); mon = rtc_read (RTC_MON_REG_ADDR); year = rtc_read (RTC_YR_REG_ADDR); DEBUGR ("Get RTC year: %02x mon: %02x mday: %02x wday: %02x " "hr: %02x min: %02x sec: %02x\n", year, mon, mday, wday, hour, min, sec); #ifdef CONFIG_RTC_DS1307 if (sec & RTC_SEC_BIT_CH) { printf ("### Warning: RTC oscillator has stopped\n"); /* clear the CH flag */ rtc_write (RTC_SEC_REG_ADDR, rtc_read (RTC_SEC_REG_ADDR) & ~RTC_SEC_BIT_CH); rel = -1; } #endif #ifdef CONFIG_RTC_MCP79411 /* make sure that the backup battery is enabled */ if (!(wday & MCP7941X_BIT_VBATEN)) { rtc_write(RTC_DAY_REG_ADDR, wday | MCP7941X_BIT_VBATEN); } /* clock halted? turn it on, so clock can tick. */ if (!(sec & MCP7941X_BIT_ST)) { rtc_write(RTC_SEC_REG_ADDR, MCP7941X_BIT_ST); printf("Started RTC\n"); goto read_rtc; } #endif tmp->tm_sec = bcd2bin (sec & 0x7F); tmp->tm_min = bcd2bin (min & 0x7F); tmp->tm_hour = bcd2bin (hour & 0x3F); tmp->tm_mday = bcd2bin (mday & 0x3F); tmp->tm_mon = bcd2bin (mon & 0x1F); tmp->tm_year = bcd2bin (year) + ( bcd2bin (year) >= 70 ? 1900 : 2000); tmp->tm_wday = bcd2bin ((wday - 1) & 0x07); tmp->tm_yday = 0; tmp->tm_isdst= 0; DEBUGR ("Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, tmp->tm_hour, tmp->tm_min, tmp->tm_sec); return rel; }
/* * ioctl calls for this driver. Why return -ENOTTY upon error? Because * POSIX says so! */ int pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { /* Some sanity checks. */ if (_IOC_TYPE(cmd) != RTC_MAGIC) return -ENOTTY; if (_IOC_NR(cmd) > RTC_MAX_IOCTL) return -ENOTTY; switch (cmd) { case RTC_RD_TIME: { struct rtc_time tm; get_rtc_time(&tm); if (copy_to_user((struct rtc_time *) arg, &tm, sizeof(struct rtc_time))) { return -EFAULT; } return 0; } break; case RTC_SET_TIME: { #ifdef CONFIG_ETRAX_RTC_READONLY return -EPERM; #else int leap; int century; struct rtc_time tm; memset(&tm, 0, sizeof (struct rtc_time)); if (!capable(CAP_SYS_TIME)) return -EPERM; if (copy_from_user(&tm, (struct rtc_time *) arg, sizeof(struct rtc_time))) return -EFAULT; /* Convert from struct tm to struct rtc_time. */ tm.tm_year += 1900; tm.tm_mon += 1; leap = ((tm.tm_mon == 2) && ((tm.tm_year % 4) == 0)) ? 1 : 0; /* Perform some sanity checks. */ if ((tm.tm_year < 1970) || (tm.tm_mon > 12) || (tm.tm_mday == 0) || (tm.tm_mday > days_in_month[tm.tm_mon] + leap) || (tm.tm_hour >= 24) || (tm.tm_min >= 60) || (tm.tm_sec >= 60)) return -EINVAL; century = (tm.tm_year >= 2000) ? 0x80 : 0; tm.tm_year = tm.tm_year % 100; BIN_TO_BCD(tm.tm_year); BIN_TO_BCD(tm.tm_mday); BIN_TO_BCD(tm.tm_hour); BIN_TO_BCD(tm.tm_min); BIN_TO_BCD(tm.tm_sec); tm.tm_mon |= century; rtc_write(RTC_YEAR, tm.tm_year); rtc_write(RTC_MONTH, tm.tm_mon); rtc_write(RTC_DAY_OF_MONTH, tm.tm_mday); rtc_write(RTC_HOURS, tm.tm_hour); rtc_write(RTC_MINUTES, tm.tm_min); rtc_write(RTC_SECONDS, tm.tm_sec); return 0; #endif /* !CONFIG_ETRAX_RTC_READONLY */ } case RTC_VLOW_RD: { int vl_bit = 0; if (rtc_read(RTC_SECONDS) & 0x80) { vl_bit = 1; printk(KERN_WARNING "%s: RTC Voltage Low - reliable " "date/time information is no longer guaranteed!\n", PCF8563_NAME); } if (copy_to_user((int *) arg, &vl_bit, sizeof(int))) return -EFAULT; return 0; } case RTC_VLOW_SET: { /* Clear the VL bit in the seconds register */ int ret = rtc_read(RTC_SECONDS); rtc_write(RTC_SECONDS, (ret & 0x7F)); return 0; } default: return -ENOTTY; } return 0; }
int __init pcf8563_init(void) { static int res; static int first = 1; if (!first) return res; first = 0; /* Initiate the i2c protocol. */ res = i2c_init(); if (res < 0) { printk(KERN_CRIT "pcf8563_init: Failed to init i2c.\n"); return res; } /* * First of all we need to reset the chip. This is done by * clearing control1, control2 and clk freq and resetting * all alarms. */ if (rtc_write(RTC_CONTROL1, 0x00) < 0) goto err; if (rtc_write(RTC_CONTROL2, 0x00) < 0) goto err; if (rtc_write(RTC_CLOCKOUT_FREQ, 0x00) < 0) goto err; if (rtc_write(RTC_TIMER_CONTROL, 0x03) < 0) goto err; /* Reset the alarms. */ if (rtc_write(RTC_MINUTE_ALARM, 0x80) < 0) goto err; if (rtc_write(RTC_HOUR_ALARM, 0x80) < 0) goto err; if (rtc_write(RTC_DAY_ALARM, 0x80) < 0) goto err; if (rtc_write(RTC_WEEKDAY_ALARM, 0x80) < 0) goto err; /* Check for low voltage, and warn about it. */ if (rtc_read(RTC_SECONDS) & 0x80) { voltage_low = 1; printk(KERN_WARNING "%s: RTC Voltage Low - reliable " "date/time information is no longer guaranteed!\n", PCF8563_NAME); } return res; err: printk(KERN_INFO "%s: Error initializing chip.\n", PCF8563_NAME); res = -1; return res; }
static void rtc_enable_update(void) { rtc_write((rtc_read(RTC_CMD) | RTC_TE), RTC_CMD); }
/* * ioctl calls for this driver. Why return -ENOTTY upon error? Because * POSIX says so! */ static int pcf8563_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { /* Some sanity checks. */ if (_IOC_TYPE(cmd) != RTC_MAGIC) return -ENOTTY; if (_IOC_NR(cmd) > RTC_MAX_IOCTL) return -ENOTTY; switch (cmd) { case RTC_RD_TIME: { struct rtc_time tm; mutex_lock(&rtc_lock); memset(&tm, 0, sizeof tm); get_rtc_time(&tm); if (copy_to_user((struct rtc_time *) arg, &tm, sizeof tm)) { mutex_unlock(&rtc_lock); return -EFAULT; } mutex_unlock(&rtc_lock); return 0; } case RTC_SET_TIME: { int leap; int year; int century; struct rtc_time tm; memset(&tm, 0, sizeof tm); if (!capable(CAP_SYS_TIME)) return -EPERM; if (copy_from_user(&tm, (struct rtc_time *) arg, sizeof tm)) return -EFAULT; /* Convert from struct tm to struct rtc_time. */ tm.tm_year += 1900; tm.tm_mon += 1; /* * Check if tm.tm_year is a leap year. A year is a leap * year if it is divisible by 4 but not 100, except * that years divisible by 400 _are_ leap years. */ year = tm.tm_year; leap = (tm.tm_mon == 2) && ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0); /* Perform some sanity checks. */ if ((tm.tm_year < 1970) || (tm.tm_mon > 12) || (tm.tm_mday == 0) || (tm.tm_mday > days_in_month[tm.tm_mon] + leap) || (tm.tm_wday >= 7) || (tm.tm_hour >= 24) || (tm.tm_min >= 60) || (tm.tm_sec >= 60)) return -EINVAL; century = (tm.tm_year >= 2000) ? 0x80 : 0; tm.tm_year = tm.tm_year % 100; tm.tm_year = bin2bcd(tm.tm_year); tm.tm_mon = bin2bcd(tm.tm_mon); tm.tm_mday = bin2bcd(tm.tm_mday); tm.tm_hour = bin2bcd(tm.tm_hour); tm.tm_min = bin2bcd(tm.tm_min); tm.tm_sec = bin2bcd(tm.tm_sec); tm.tm_mon |= century; mutex_lock(&rtc_lock); rtc_write(RTC_YEAR, tm.tm_year); rtc_write(RTC_MONTH, tm.tm_mon); rtc_write(RTC_WEEKDAY, tm.tm_wday); /* Not coded in BCD. */ rtc_write(RTC_DAY_OF_MONTH, tm.tm_mday); rtc_write(RTC_HOURS, tm.tm_hour); rtc_write(RTC_MINUTES, tm.tm_min); rtc_write(RTC_SECONDS, tm.tm_sec); mutex_unlock(&rtc_lock); return 0; } case RTC_VL_READ: if (voltage_low) { printk(KERN_ERR "%s: RTC Voltage Low - " "reliable date/time information is no " "longer guaranteed!\n", PCF8563_NAME); } if (copy_to_user((int *) arg, &voltage_low, sizeof(int))) return -EFAULT; return 0; case RTC_VL_CLR: { /* Clear the VL bit in the seconds register in case * the time has not been set already (which would * have cleared it). This does not really matter * because of the cached voltage_low value but do it * anyway for consistency. */ int ret = rtc_read(RTC_SECONDS); rtc_write(RTC_SECONDS, (ret & 0x7F)); /* Clear the cached value. */ voltage_low = 0; return 0; } default: return -ENOTTY; } return 0; }
static int ds1511_rtc_probe(struct platform_device *pdev) { struct rtc_device *rtc; struct resource *res; struct rtc_plat_data *pdata; int ret = 0; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { return -ENODEV; } pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) return -ENOMEM; pdata->size = resource_size(res); if (!devm_request_mem_region(&pdev->dev, res->start, pdata->size, pdev->name)) return -EBUSY; ds1511_base = devm_ioremap(&pdev->dev, res->start, pdata->size); if (!ds1511_base) return -ENOMEM; pdata->ioaddr = ds1511_base; pdata->irq = platform_get_irq(pdev, 0); /* * turn on the clock and the crystal, etc. */ rtc_write(0, RTC_CMD); rtc_write(0, RTC_CMD1); /* * clear the wdog counter */ rtc_write(0, DS1511_WD_MSEC); rtc_write(0, DS1511_WD_SEC); /* * start the clock */ rtc_enable_update(); /* * check for a dying bat-tree */ if (rtc_read(RTC_CMD1) & DS1511_BLF1) { dev_warn(&pdev->dev, "voltage-low detected.\n"); } spin_lock_init(&pdata->lock); platform_set_drvdata(pdev, pdata); /* * if the platform has an interrupt in mind for this device, * then by all means, set it */ if (pdata->irq > 0) { rtc_read(RTC_CMD1); if (devm_request_irq(&pdev->dev, pdata->irq, ds1511_interrupt, IRQF_SHARED, pdev->name, pdev) < 0) { dev_warn(&pdev->dev, "interrupt not available.\n"); pdata->irq = 0; } } rtc = rtc_device_register(pdev->name, &pdev->dev, &ds1511_rtc_ops, THIS_MODULE); if (IS_ERR(rtc)) return PTR_ERR(rtc); pdata->rtc = rtc; ret = sysfs_create_bin_file(&pdev->dev.kobj, &ds1511_nvram_attr); if (ret) rtc_device_unregister(pdata->rtc); return ret; }
int rtc_get (struct rtc_time *tmp) { uchar sec, min, hour, mday, wday, mon, year; /* check if rtc is available for access */ while( rtc_read(RTC_CONTROL_A) & RTC_CA_UIP) ; sec = rtc_read(RTC_SECONDS); min = rtc_read(RTC_MINUTES); hour = rtc_read(RTC_HOURS); mday = rtc_read(RTC_DATE_OF_MONTH); wday = rtc_read(RTC_DAY_OF_WEEK); mon = rtc_read(RTC_MONTH); year = rtc_read(RTC_YEAR); #ifdef RTC_DEBUG printf( "Get RTC year: %d; mon: %d; mday: %d; wday: %d; " "hr: %d; min: %d; sec: %d\n", year, mon, mday, wday, hour, min, sec ); printf ( "Alarms: hour: %02x min: %02x sec: %02x\n", rtc_read (RTC_HOURS_ALARM), rtc_read (RTC_MINUTES_ALARM), rtc_read (RTC_SECONDS_ALARM) ); #endif if( !(rtc_read(RTC_CONTROL_B) & RTC_CB_DM)) { /* Information is in BCD format */ printf(" Get: Convert BSD to BIN\n"); tmp->tm_sec = bcd2bin (sec & 0x7F); tmp->tm_min = bcd2bin (min & 0x7F); tmp->tm_hour = bcd2bin (hour & 0x3F); tmp->tm_mday = bcd2bin (mday & 0x3F); tmp->tm_mon = bcd2bin (mon & 0x1F); tmp->tm_year = bcd2bin (year); tmp->tm_wday = bcd2bin (wday & 0x07); } else { tmp->tm_sec = sec & 0x7F; tmp->tm_min = min & 0x7F; tmp->tm_hour = hour & 0x3F; tmp->tm_mday = mday & 0x3F; tmp->tm_mon = mon & 0x1F; tmp->tm_year = year; tmp->tm_wday = wday & 0x07; } if(tmp->tm_year<70) tmp->tm_year+=2000; else tmp->tm_year+=1900; tmp->tm_yday = 0; tmp->tm_isdst= 0; #ifdef RTC_DEBUG printf ( "Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, tmp->tm_hour, tmp->tm_min, tmp->tm_sec); #endif return 0; }
satime_t getsecs(void) { uint32_t sec, min, hour, day; #if 0 uint32_t mon, year; #endif satime_t secs; sec = rtc_read(RS5C313_SEC1); sec += rtc_read(RS5C313_SEC10) * 10; min = rtc_read(RS5C313_MIN1); min += rtc_read(RS5C313_MIN10) * 10; hour = rtc_read(RS5C313_HOUR1); hour += rtc_read(RS5C313_HOUR10) * 10; day = rtc_read(RS5C313_DAY1); day += rtc_read(RS5C313_DAY10) * 10; #if 0 mon = rtc_read(RS5C313_MON1); mon += rtc_read(RS5C313_MON10) * 10; year = rtc_read(RS5C313_YEAR1); year += rtc_read(RS5C313_YEAR10) * 10; #endif secs = sec; secs += min * 60; secs += hour * 60 * 60; secs += day * 60 * 60 * 24; #if 0 /* XXX mon, year */ #endif #if defined(DEBUG) printf("getsecs: secs = %d\n", (uint32_t)secs); #endif return secs; }