/* * Ranges from 0x40 to 0x78 provide RTC time setup for year, month, * day of month, day of week, hour, minute and second.
*/ #define MTK_RTC_TREG(_t, _f) (0x40 + (0x4 * (_f)) + ((_t) * 0x20))
/* * The offset is used in the translation for the year between in struct * rtc_time and in hardware register MTK_RTC_TREG(x,MTK_YEA)
*/ #define MTK_RTC_TM_YR_OFFSET 100
/* * The lowest value for the valid tm_year. RTC hardware would take incorrectly * tm_year 100 as not a leap year and thus it is also required being excluded * from the valid options.
*/ #define MTK_RTC_TM_YR_L (MTK_RTC_TM_YR_OFFSET + 1)
/* * The most year the RTC can hold is 99 and the next to 99 in year register * would be wraparound to 0, for MT7622.
*/ #define MTK_RTC_HW_YR_LIMIT 99
/* The highest value for the valid tm_year */ #define MTK_RTC_TM_YR_H (MTK_RTC_TM_YR_OFFSET + MTK_RTC_HW_YR_LIMIT)
/* Simple macro helps to check whether the hardware supports the tm_year */ #define MTK_RTC_TM_YR_VALID(_y) ((_y) >= MTK_RTC_TM_YR_L && \
(_y) <= MTK_RTC_TM_YR_H)
/* Types of the function the RTC provides are time counter and alarm. */ enum {
MTK_TC,
MTK_AL,
};
/* Indexes are used for the pointer to relevant registers in MTK_RTC_TREG */ enum {
MTK_YEA,
MTK_MON,
MTK_DOM,
MTK_DOW,
MTK_HOU,
MTK_MIN,
MTK_SEC
};
/* * Read again until the field of the second is not changed which * ensures all fields in the consistent state. Note that MTK_SEC must * be read first. In this way, it guarantees the others remain not * changed when the results for two MTK_SEC consecutive reads are same.
*/ do {
sec = mtk_r32(hw, MTK_RTC_TREG(time_alarm, MTK_SEC));
min = mtk_r32(hw, MTK_RTC_TREG(time_alarm, MTK_MIN));
hour = mtk_r32(hw, MTK_RTC_TREG(time_alarm, MTK_HOU));
wday = mtk_r32(hw, MTK_RTC_TREG(time_alarm, MTK_DOW));
mday = mtk_r32(hw, MTK_RTC_TREG(time_alarm, MTK_DOM));
mon = mtk_r32(hw, MTK_RTC_TREG(time_alarm, MTK_MON));
year = mtk_r32(hw, MTK_RTC_TREG(time_alarm, MTK_YEA));
} while (sec != mtk_r32(hw, MTK_RTC_TREG(time_alarm, MTK_SEC)));
if (!MTK_RTC_TM_YR_VALID(alrm_tm->tm_year)) return -EINVAL;
/* * Stop the alarm also implicitly including disables interrupt before * setting a new one.
*/
mtk_clr(hw, MTK_RTC_AL_CTL, RTC_AL_EN);
/* * Avoid contention between mtk_rtc_setalarm and IRQ handler so that * disabling the interrupt and awaiting for pending IRQ handler to * complete.
*/
synchronize_irq(hw->irq);
mtk_rtc_set_alarm_or_time(hw, alrm_tm, MTK_AL);
/* Restart the alarm with the new setup */
mtk_w32(hw, MTK_RTC_AL_CTL, RTC_AL_ALL);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.