Ejemplo n.º 1
0
static int omap_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
{
	u8 reg;

	/* Much userspace code uses RTC_ALM_SET, thus "don't care" for
	 * day/month/year specifies alarms up to 24 hours in the future.
	 * So we need to handle that ... but let's ignore the "don't care"
	 * values for hours/minutes/seconds.
	 */
	if (alm->time.tm_mday <= 0
			&& alm->time.tm_mon < 0
			&& alm->time.tm_year < 0) {
		struct rtc_time tm;
		unsigned long now, then;

		omap_rtc_read_time(dev, &tm);
		rtc_tm_to_time(&tm, &now);

		alm->time.tm_mday = tm.tm_mday;
		alm->time.tm_mon = tm.tm_mon;
		alm->time.tm_year = tm.tm_year;
		rtc_tm_to_time(&alm->time, &then);

		/* sometimes the alarm wraps into tomorrow */
		if (then < now) {
			rtc_time_to_tm(now + 24 * 60 * 60, &tm);
			alm->time.tm_mday = tm.tm_mday;
			alm->time.tm_mon = tm.tm_mon;
			alm->time.tm_year = tm.tm_year;
		}
	}

	if (tm2bcd(&alm->time) < 0)
		return -EINVAL;

	local_irq_disable();
	rtc_wait_not_busy();

	rtc_write(alm->time.tm_year, OMAP_RTC_ALARM_YEARS_REG);
	rtc_write(alm->time.tm_mon, OMAP_RTC_ALARM_MONTHS_REG);
	rtc_write(alm->time.tm_mday, OMAP_RTC_ALARM_DAYS_REG);
	rtc_write(alm->time.tm_hour, OMAP_RTC_ALARM_HOURS_REG);
	rtc_write(alm->time.tm_min, OMAP_RTC_ALARM_MINUTES_REG);
	rtc_write(alm->time.tm_sec, OMAP_RTC_ALARM_SECONDS_REG);

	reg = rtc_read(OMAP_RTC_INTERRUPTS_REG);
	if (alm->enabled)
		reg |= OMAP_RTC_INTERRUPTS_IT_ALARM;
	else
		reg &= ~OMAP_RTC_INTERRUPTS_IT_ALARM;
	rtc_write(reg, OMAP_RTC_INTERRUPTS_REG);

	local_irq_enable();

	return 0;
}
Ejemplo n.º 2
0
static int omap_rtc_resume(struct platform_device *pdev)
{
	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);

	restore_time_delta(&rtc_delta, &time);
	if (device_may_wakeup(&pdev->dev))
		disable_irq_wake(omap_rtc_alarm);
	else
		rtc_write(irqstat, OMAP_RTC_INTERRUPTS_REG);
	return 0;
}
Ejemplo n.º 3
0
/*
 * rtc_power_off: Set the pmic power off sequence. The RTC generates
 * pmic_pwr_enable control, which can be used to control an external
 * PMIC.
 */
static void rtc_power_off(void)
{
	u32 val;
	struct rtc_time tm;
	unsigned long time;

	/* Set PMIC power enable */
	val = readl(rtc_base + OMAP_RTC_PMIC_REG);
	writel(val | OMAP_RTC_PMIC_POWER_EN_EN, rtc_base + OMAP_RTC_PMIC_REG);

	/* Read rtc time */
	omap_rtc_read_time(NULL, &tm);

	/* Convert Gregorian date to seconds since 01-01-1970 00:00:00 */
	rtc_tm_to_time(&tm, &time);

	/* Add shutdown time to the current value */
	time += SHUTDOWN_TIME_SEC;

	/* Convert seconds since 01-01-1970 00:00:00 to Gregorian date */
	rtc_time_to_tm(time, &tm);

	if (tm2bcd(&tm) < 0)
		return;

	pr_info("System will go to power_off state in approx. %d secs\n",
			SHUTDOWN_TIME_SEC);

	/*
	 * pmic_pwr_enable is controlled by means of ALARM2 event. So here
	 * programming alarm2 expiry time and enabling alarm2 interrupt
	 */
	rtc_write(tm.tm_sec, OMAP_RTC_ALARM2_SECONDS_REG);
	rtc_write(tm.tm_min, OMAP_RTC_ALARM2_MINUTES_REG);
	rtc_write(tm.tm_hour, OMAP_RTC_ALARM2_HOURS_REG);
	rtc_write(tm.tm_mday, OMAP_RTC_ALARM2_DAYS_REG);
	rtc_write(tm.tm_mon, OMAP_RTC_ALARM2_MONTHS_REG);
	rtc_write(tm.tm_year, OMAP_RTC_ALARM2_YEARS_REG);

	/* Enable alarm2 interrupt */
	val = readl(rtc_base + OMAP_RTC_INTERRUPTS_REG);
	writel(val | OMAP_RTC_INTERRUPTS_IT_ALARM2,
				rtc_base + OMAP_RTC_INTERRUPTS_REG);
}
Ejemplo n.º 4
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;
}