Source
x
/*
* Real Time Clock driver for Wolfson Microelectronics WM8350
*
* Copyright (C) 2007, 2008 Wolfson Microelectronics PLC.
*
* Author: Liam Girdwood
* linux@wolfsonmicro.com
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
*/
/*
* Read current time and date in RTC
*/
static int wm8350_rtc_readtime(struct device *dev, struct rtc_time *tm)
{
struct wm8350 *wm8350 = dev_get_drvdata(dev);
u16 time1[4], time2[4];
int retries = WM8350_GET_TIME_RETRIES, ret;
/*
* Read the time twice and compare.
* If time1 == time2, then time is valid else retry.
*/
do {
ret = wm8350_block_read(wm8350, WM8350_RTC_SECONDS_MINUTES,
4, time1);
if (ret < 0)
return ret;
ret = wm8350_block_read(wm8350, WM8350_RTC_SECONDS_MINUTES,
4, time2);
if (ret < 0)
return ret;
if (memcmp(time1, time2, sizeof(time1)) == 0) {
tm->tm_sec = time1[0] & WM8350_RTC_SECS_MASK;
tm->tm_min = (time1[0] & WM8350_RTC_MINS_MASK)
>> WM8350_RTC_MINS_SHIFT;
tm->tm_hour = time1[1] & WM8350_RTC_HRS_MASK;
tm->tm_wday = ((time1[1] >> WM8350_RTC_DAY_SHIFT)
& 0x7) - 1;
tm->tm_mon = ((time1[2] & WM8350_RTC_MTH_MASK)
>> WM8350_RTC_MTH_SHIFT) - 1;
tm->tm_mday = (time1[2] & WM8350_RTC_DATE_MASK);
tm->tm_year = ((time1[3] & WM8350_RTC_YHUNDREDS_MASK)
>> WM8350_RTC_YHUNDREDS_SHIFT) * 100;
tm->tm_year += time1[3] & WM8350_RTC_YUNITS_MASK;
tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon,
tm->tm_year);
tm->tm_year -= 1900;
dev_dbg(dev, "Read (%d left): %04x %04x %04x %04x\n",
retries,
time1[0], time1[1], time1[2], time1[3]);
return 0;
}
} while (retries--);
dev_err(dev, "timed out reading RTC time\n");
return -EIO;
}
/*