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 <w...@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.

--
You received this message because you are subscribed to the Google Groups 
"linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to linux-sunxi+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to