[PATCH v3 1/6] rtc: sun6i: Add sun6i RTC driver
Varka Bhadram
varkabhadram at gmail.com
Fri Jul 25 03:36:01 PDT 2014
On 07/25/2014 02:43 PM, Chen-Yu Tsai wrote:
> This patch introduces the driver for the RTC in the Allwinner A31 and
> A23 SoCs.
>
> Unlike the RTC found in A10/A20 SoCs, which was part of the timer, the
> RTC in A31/A23 are a separate hardware block, which also contain a few
> controls for the RTC block hardware (a regulator and RTC block GPIO pin
> latches), while also having separate interrupts for the alarms.
>
> The hardware is different enough to make a different driver for it.
>
> Signed-off-by: Chen-Yu Tsai <wens at csie.org>
> ---
> .../devicetree/bindings/rtc/sun6i-rtc.txt | 17 +
> drivers/rtc/Kconfig | 7 +
> drivers/rtc/Makefile | 1 +
> drivers/rtc/rtc-sun6i.c | 447 +++++++++++++++++++++
> 4 files changed, 472 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/rtc/sun6i-rtc.txt
> create mode 100644 drivers/rtc/rtc-sun6i.c
>
(....)
> +static int sun6i_rtc_settime(struct device *dev, struct rtc_time *rtc_tm)
> +{
> + struct sun6i_rtc_dev *chip = dev_get_drvdata(dev);
> + u32 date = 0;
> + u32 time = 0;
> + int year;
> +
> + year = rtc_tm->tm_year + 1900;
> + if (year < SUN6I_YEAR_MIN || year > SUN6I_YEAR_MAX) {
> + dev_err(dev, "rtc only supports year in range %d - %d\n",
> + SUN6I_YEAR_MIN, SUN6I_YEAR_MAX);
dev_err(dev, "rtc only supports year in range %d - %d\n",
SUN6I_YEAR_MIN, SUN6I_YEAR_MAX);
> + return -EINVAL;
> + }
> +
> + rtc_tm->tm_year -= SUN6I_YEAR_OFF;
> + rtc_tm->tm_mon += 1;
> +
> + date = SUN6I_DATE_SET_DAY_VALUE(rtc_tm->tm_mday) |
> + SUN6I_DATE_SET_MON_VALUE(rtc_tm->tm_mon) |
> + SUN6I_DATE_SET_YEAR_VALUE(rtc_tm->tm_year);
> +
> + if (is_leap_year(year))
> + date |= SUN6I_LEAP_SET_VALUE(1);
> +
> + time = SUN6I_TIME_SET_SEC_VALUE(rtc_tm->tm_sec) |
> + SUN6I_TIME_SET_MIN_VALUE(rtc_tm->tm_min) |
> + SUN6I_TIME_SET_HOUR_VALUE(rtc_tm->tm_hour);
> +
> + /* Check whether registers are writable */
> + if (sun6i_rtc_wait(chip, SUN6I_LOSC_CTRL,
> + SUN6I_LOSC_CTRL_ACC_MASK, 50)) {
if (sun6i_rtc_wait(chip, SUN6I_LOSC_CTRL,
SUN6I_LOSC_CTRL_ACC_MASK, 50)
> + dev_err(dev, "rtc is still busy.\n");
> + return -EBUSY;
> + }
> +
> + writel(time, chip->base + SUN6I_RTC_HMS);
> +
> + /*
> + * After writing the RTC HH-MM-SS register, the
> + * SUN6I_LOSC_CTRL_RTC_HMS_ACC bit is set and it will not
> + * be cleared until the real writing operation is finished
> + */
> +
> + if (sun6i_rtc_wait(chip, SUN6I_LOSC_CTRL,
> + SUN6I_LOSC_CTRL_RTC_HMS_ACC, 50)) {
same..
> + dev_err(dev, "Failed to set rtc time.\n");
> + return -ETIMEDOUT;
> + }
> +
> + writel(date, chip->base + SUN6I_RTC_YMD);
> +
> + /*
> + * After writing the RTC YY-MM-DD register, the
> + * SUN6I_LOSC_CTRL_RTC_YMD_ACC bit is set and it will not
> + * be cleared until the real writing operation is finished
> + */
> +
> + if (sun6i_rtc_wait(chip, SUN6I_LOSC_CTRL,
> + SUN6I_LOSC_CTRL_RTC_YMD_ACC, 50)) {
same...
--
Regards,
Varka Bhadram.
More information about the linux-arm-kernel
mailing list