summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2015-02-13 11:49:04 -0600
committerGregory Nutt <gnutt@nuttx.org>2015-02-13 11:49:04 -0600
commit95436927da26bb57df62da5876b33a7cd920f704 (patch)
tree1120381e414193b53fe7dc792256b7b2afa31fce
parent7b6682a837dedda1aa1aad58ac9d830428296c74 (diff)
downloadnuttx-95436927da26bb57df62da5876b33a7cd920f704.tar.gz
nuttx-95436927da26bb57df62da5876b33a7cd920f704.tar.bz2
nuttx-95436927da26bb57df62da5876b33a7cd920f704.zip
Add an RTC upper half driver. This is the driver that is documented in include/nutt/rtc.h
-rw-r--r--nuttx/drivers/timers/rtc.c589
-rw-r--r--nuttx/include/nuttx/rtc.h65
2 files changed, 624 insertions, 30 deletions
diff --git a/nuttx/drivers/timers/rtc.c b/nuttx/drivers/timers/rtc.c
new file mode 100644
index 000000000..74f041c8c
--- /dev/null
+++ b/nuttx/drivers/timers/rtc.c
@@ -0,0 +1,589 @@
+/****************************************************************************
+ * drivers/timers/rtc.c
+ *
+ * Copyright (C) 2015 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include <nuttx/kmalloc.h>
+#include <nuttx/fs/fs.h>
+#include <nuttx/rtc.h>
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct rtc_upperhalf_s
+{
+ FAR struct rtc_lowerhalf_s *lower; /* Contained lower half driver */
+ uint8_t crefs; /* Number of open references */
+ bool unlinked; /* True if the driver has been unlinked */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Internal logic */
+
+static void rtc_destroy(FAR struct rtc_upperhalf_s *upper);
+
+/* Character driver methods */
+
+static int rtc_open(FAR struct file *filep);
+static int rtc_close(FAR struct file *filep);
+static ssize_t rtc_read(FAR struct file *filep, FAR char *, size_t);
+static ssize_t rtc_write(FAR struct file *filep, FAR const char *buffer,
+ size_t buflen);
+static int rtc_ioctl(FAR struct file *filep, int cmd, unsigned long arg);
+static int rtc_unlink(FAR struct inode *inode);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static const struct file_operations rtc_fops =
+{
+ rtc_open, /* open */
+ rtc_close, /* close */
+ rtc_read, /* read */
+ rtc_write, /* write */
+ 0, /* seek */
+ rtc_ioctl, /* ioctl */
+#ifndef CONFIG_DISABLE_POLL
+ 0, /* poll */
+#endif
+ rtc_unlink /* unlink */
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: rtc_read
+ ****************************************************************************/
+
+static void rtc_destroy(FAR struct rtc_upperhalf_s *upper)
+{
+ /* If the lower half driver provided a destroy method, then call that
+ * method now in order order to clean up resources used by the lower-half
+ * driver.
+ */
+
+ DEBUGASSERT(upper->lower && upper->lower->ops);
+ if (upper->lower->ops->destroy)
+ {
+ upper->lower->ops->destroy(upper->lower);
+ }
+
+ /* And free our container */
+
+ kmm_free(upper);
+}
+
+/****************************************************************************
+ * Name: rtc_open
+ ****************************************************************************/
+
+static int rtc_open(FAR struct file *filep)
+{
+ FAR struct inode *inode;
+ FAR struct rtc_upperhalf_s *upper;
+
+ /* Get the reference to our internal state structure from the inode
+ * structure.
+ */
+
+ DEBUGASSERT(filep);
+ inode = filep->f_inode;
+ DEBUGASSERT(inode && inode->i_private);
+ upper = inode->i_private;
+
+ /* Increment the count of open references on the RTC driver */
+
+ upper->crefs++;
+ DEBUGASSERT(upper->crefs > 0);
+ return OK;
+}
+
+/****************************************************************************
+ * Name: rtc_close
+ ****************************************************************************/
+
+static int rtc_close(FAR struct file *filep)
+{
+ FAR struct inode *inode;
+ FAR struct rtc_upperhalf_s *upper;
+
+ /* Get the reference to our internal state structure from the inode
+ * structure.
+ */
+
+ DEBUGASSERT(filep);
+ inode = filep->f_inode;
+ DEBUGASSERT(inode && inode->i_private);
+ upper = inode->i_private;
+
+ /* Decrement the count of open references on the RTC driver */
+
+ DEBUGASSERT(upper->crefs > 0);
+ upper->crefs--;
+
+ /* If the count has decremented to zero and the driver has been unlinked,
+ * then commit Hara-Kiri now.
+ */
+
+ if (upper->crefs == 0 && upper->unlinked)
+ {
+ rtc_destroy(upper);
+ }
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: rtc_read
+ ****************************************************************************/
+
+static ssize_t rtc_read(FAR struct file *filep, FAR char *buffer, size_t len)
+{
+ return 0; /* Return EOF */
+}
+
+/****************************************************************************
+ * Name: rtc_write
+ ****************************************************************************/
+
+static ssize_t rtc_write(FAR struct file *filep, FAR const char *buffer, size_t len)
+{
+ return len; /* Say that everything was written */
+}
+
+/****************************************************************************
+ * Name: rtc_ioctl
+ ****************************************************************************/
+
+static int rtc_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
+{
+ FAR struct inode *inode;
+ FAR struct rtc_upperhalf_s *upper;
+ FAR const struct rtc_ops_s *ops;
+ int ret = -ENOSYS;
+
+ /* Get the reference to our internal state structure from the inode
+ * structure.
+ */
+
+ DEBUGASSERT(filep);
+ inode = filep->f_inode;
+ DEBUGASSERT(inode && inode->i_private);
+ upper = inode->i_private;
+ DEBUGASSERT(upper->lower && upper->lower->ops);
+
+ /* We simply forward all ioctl() commands to the lower half. The upper
+ * half is nothing more than a thin driver shell over the lower level
+ * RTC implementation.
+ */
+
+ ops = upper->lower->ops;
+ switch (cmd)
+ {
+ /* RTC_RD_TIME returns the current RTC time.
+ *
+ * Argument: A writeable reference to a struct rtc_time to receive the
+ * RTC's time.
+ */
+
+ case RTC_RD_TIME:
+ {
+ FAR struct rtc_time *rtctime = (FAR struct rtc_time *)((uintptr_t)arg);
+
+ if (ops->rdtime)
+ {
+ ret = ops->rdtime(upper->lower, rtctime);
+ }
+ }
+ break;
+
+ /* RTC_SET_TIME sets the RTC's time
+ *
+ * Argument: A read-only reference to a struct rtc_time containing the
+ * the new time to be set.
+ */
+
+ case RTC_SET_TIME:
+ {
+ FAR const struct rtc_time *rtctime =
+ (FAR const struct rtc_time *)((uintptr_t)arg);
+
+ if (ops->settime)
+ {
+ ret = ops->settime(upper->lower, rtctime);
+ }
+ }
+ break;
+
+ /* RTC_ALM_READ reads the alarm time (for RTCs that support alarms)
+ *
+ * Argument: A writeable reference to a struct rtc_time to receive the
+ * RTC's alarm time.
+ */
+
+ case RTC_ALM_READ:
+ {
+ FAR struct rtc_time *almtime = (FAR struct rtc_time *)((uintptr_t)arg);
+
+ if (ops->almread)
+ {
+ ret = ops->almread(upper->lower, almtime);
+ }
+ }
+ break;
+
+ /* RTC_ALM_SET sets the alarm time (for RTCs that support alarms).
+ *
+ * Argument: A read-only reference to a struct rtc_time containing the
+ * new alarm time to be set.
+ */
+
+ case RTC_ALM_SET:
+ {
+ FAR const struct rtc_time *almtime =
+ (FAR const struct rtc_time *)((uintptr_t)arg);
+
+ if (ops->almset)
+ {
+ ret = ops->almset(upper->lower, almtime);
+ }
+ }
+ break;
+
+ /* RTC_IRQP_READ read the frequency for periodic interrupts (for RTCs
+ * that support periodic interrupts)
+ *
+ * Argument: A pointer to a writeable unsigned long value in which to
+ * receive the frequency value.
+ */
+
+ case RTC_IRQP_READ:
+ {
+ FAR unsigned long *irqpfreq = (FAR unsigned long *)((uintptr_t)arg);
+
+ if (ops->irqpread)
+ {
+ ret = ops->irqpread(upper->lower, irqpfreq);
+ }
+ }
+ break;
+
+ /* RTC_IRQP_SET set the frequency for periodic interrupts (for RTCs that
+ * support periodic interrupts)
+ *
+ * Argument: An unsigned long value providing the new periodic frequency
+ */
+
+ case RTC_IRQP_SET:
+ {
+ if (ops->irqpset)
+ {
+ ret = ops->irqpset(upper->lower, arg);
+ }
+ }
+ break;
+
+ /* RTC_AIE_ON enable alarm interrupts (for RTCs that support alarms)
+ *
+ * Argument: None
+ */
+
+ case RTC_AIE_ON:
+ {
+ if (ops->aie)
+ {
+ ret = ops->aie(upper->lower, true);
+ }
+ }
+ break;
+
+ /* RTC_AIE_OFF disable the alarm interrupt (for RTCs that support
+ * alarms)
+ *
+ * Argument: None
+ */
+
+ case RTC_AIE_OFF:
+ {
+ if (ops->aie)
+ {
+ ret = ops->aie(upper->lower, false);
+ }
+ }
+ break;
+
+ /* RTC_UIE_ON enable the interrupt on every clock update (for RTCs that
+ * support this once-per-second interrupt).
+ *
+ * Argument: None
+ */
+
+ case RTC_UIE_ON:
+ {
+ if (ops->uie)
+ {
+ ret = ops->uie(upper->lower, true);
+ }
+ }
+ break;
+
+ /* RTC_UIE_OFF disable the interrupt on every clock update (for RTCs
+ * that support this once-per-second interrupt).
+ *
+ * Argument: None
+ */
+
+ case RTC_UIE_OFF:
+ {
+ if (ops->uie)
+ {
+ ret = ops->uie(upper->lower, false);
+ }
+ }
+ break;
+
+ /* RTC_PIE_ON enable the periodic interrupt (for RTCs that support these
+ * periodic interrupts).
+ *
+ * Argument: None
+ */
+
+ case RTC_PIE_ON:
+ {
+ if (ops->pie)
+ {
+ ret = ops->pie(upper->lower, true);
+ }
+ }
+ break;
+
+ /* RTC_PIE_OFF disable the periodic interrupt (for RTCs that support
+ * these periodic interrupts).
+ *
+ * Argument: None
+ */
+
+ case RTC_PIE_OFF:
+ {
+ if (ops->pie)
+ {
+ ret = ops->pie(upper->lower, false);
+ }
+ }
+ break;
+
+ /* RTC_EPOCH_READ read the Epoch.
+ *
+ * Argument: A reference to a writeable unsigned low variable that will
+ * receive the Epoch value.
+ */
+
+ case RTC_EPOCH_READ:
+ {
+ FAR unsigned long *epoch = (FAR unsigned long *)((uintptr_t)arg);
+
+ if (ops->rdepoch)
+ {
+ ret = ops->rdepoch(upper->lower, epoch);
+ }
+ }
+ break;
+
+ /* RTC_EPOCH_SET set the Epoch
+ *
+ * Argument: An unsigned long value containing the new Epoch value to be
+ * set.
+ */
+
+ case RTC_EPOCH_SET:
+ {
+ if (ops->setepoch)
+ {
+ ret = ops->setepoch(upper->lower, arg);
+ }
+ }
+ break;
+
+ /* RTC_WKALM_RD read the current alarm
+ *
+ * Argument: A writeable reference to struct rtc_wkalrm to receive the
+ * current alarm settings.
+ */
+
+ case RTC_WKALM_RD:
+ {
+ FAR struct rtc_wkalrm *wkalrm = (FAR struct rtc_wkalrm *)((uintptr_t)arg);
+
+ if (ops->rdwkalm)
+ {
+ ret = ops->rdwkalm(upper->lower, wkalrm);
+ }
+ }
+ break;
+
+ /* RTC_WKALM_SET set the alarm.
+ *
+ * Argument: A read-only reference to struct rtc_wkalrm containing the
+ * new alarm settings.
+ */
+
+ case RTC_WKALM_SET:
+ {
+ FAR const struct rtc_wkalrm *wkalrm =
+ (FAR const struct rtc_wkalrm *)((uintptr_t)arg);
+
+ if (ops->setwkalm)
+ {
+ ret = ops->setwkalm(upper->lower, wkalrm);
+ }
+ }
+ break;
+
+ default:
+ ret = -ENOTTY;
+ break;
+ }
+
+ return ret;
+}
+
+/****************************************************************************
+ * Name: rtc_unlink
+ ****************************************************************************/
+
+static int rtc_unlink(FAR struct inode *inode)
+{
+ FAR struct rtc_upperhalf_s *upper;
+
+ /* Get the reference to our internal state structure from the inode
+ * structure.
+ */
+
+ DEBUGASSERT(inode && inode->i_private);
+ upper = inode->i_private;
+
+ /* Indicate that the driver has been unlinked */
+
+ upper->unlinked = true;
+
+ /* If there are no further open references to the driver, then commit
+ * Hara-Kiri now.
+ */
+
+ if (upper->crefs == 0)
+ {
+ rtc_destroy(upper);
+ }
+
+ return OK;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: rtc_initialize
+ *
+ * Description:
+ * Create an RTC driver by binding to the lower half RTC driver instance
+ * provided to this function. The resulting RTC driver will be registered
+ * at /dev/rtcN where N is the minor number provided to this function.
+ *
+ * Input parameters:
+ * minor - The minor number of the RTC device. The N in /dev/rtcN
+ * lower - The lower half driver instance.
+ *
+ * Returned Value:
+ * Zero (OK) on success; A negated errno value on failure.
+ *
+ ****************************************************************************/
+
+int rtc_initialize(int minor, FAR struct rtc_lowerhalf_s *lower)
+{
+ FAR struct rtc_upperhalf_s *upper;
+ char devpath[16];
+ int ret;
+
+ DEBUGASSERT(lower && lower->ops && minor >= 0 && minor < 1000);
+
+ /* Allocate an upper half container structure */
+
+ upper = (FAR struct rtc_upperhalf_s *)kmm_malloc(sizeof(struct rtc_upperhalf_s));
+ if (!upper)
+ {
+ return -ENOMEM;
+ }
+
+ /* Initialize the upper half container */
+
+ upper->lower = lower; /* Contain lower half driver */
+ upper->crefs = 0; /* No open references */
+ upper->unlinked = false; /* Driver is not unlinked */
+
+ /* Create the driver name. There is space for the a minor number up to 6
+ * characters
+ */
+
+ snprintf(devpath, 16, "/dev/rtc%d", minor);
+
+ /* And, finally, register the new RTC driver */
+
+ ret = register_driver(devpath, &rtc_fops, 0666, upper);
+ if (ret < 0)
+ {
+ kmm_free(upper);
+ return ret;
+ }
+
+ return OK;
+}
diff --git a/nuttx/include/nuttx/rtc.h b/nuttx/include/nuttx/rtc.h
index 20d498c48..ff337a1d4 100644
--- a/nuttx/include/nuttx/rtc.h
+++ b/nuttx/include/nuttx/rtc.h
@@ -118,30 +118,30 @@
/* RTC_RD_TIME returns the current RTC time.
*
* Argument: A writeable reference to a struct rtc_time to receive the RTC's
- * time.
+ * time.
*/
#define RTC_RD_TIME _RTCIOC(0x0001)
/* RTC_SET_TIME sets the RTC's time
*
- * Argument: A read-only reference to a struct rtc_time containing the the
+ * Argument: A read-only reference to a struct rtc_time containing the
* new time to be set.
*/
#define RTC_SET_TIME _RTCIOC(0x0002)
-
+
/* RTC_ALM_READ reads the alarm time (for RTCs that support alarms)
*
* Argument: A writeable reference to a struct rtc_time to receive the RTC's
* alarm time.
*/
-
+
#define RTC_ALM_READ _RTCIOC(0x0003)
/* RTC_ALM_SET sets the alarm time (for RTCs that support alarms).
*
- * Argument: A read-only reference to a struct rtc_time containing the the
+ * Argument: A read-only reference to a struct rtc_time containing the
* new alarm time to be set.
*/
@@ -175,7 +175,7 @@
*
* Argument: None
*/
-
+
#define RTC_AIE_OFF _RTCIOC(0x0008)
/* RTC_UIE_ON enable the interrupt on every clock update (for RTCs that
@@ -193,7 +193,7 @@
*/
#define RTC_UIE_OFF _RTCIOC(0x000a)
-
+
/* RTC_PIE_ON enable the periodic interrupt (for RTCs that support these
* periodic interrupts).
*
@@ -201,7 +201,7 @@
*/
#define RTC_PIE_ON _RTCIOC(0x000b)
-
+
/* RTC_PIE_OFF disable the periodic interrupt (for RTCs that support these
* periodic interrupts).
*
@@ -209,7 +209,7 @@
*/
#define RTC_PIE_OFF _RTCIOC(0x000c)
-
+
/* RTC_EPOCH_READ and RTC_EPOCH_SET.
*
* Many RTCs encode the year in an 8-bit register which is either interpreted
@@ -224,11 +224,11 @@
/* RTC_EPOCH_READ read the Epoch.
*
* Argument: A reference to a writeable unsigned low variable that will
- * receive the the Epoch value.
+ * receive the Epoch value.
*/
#define RTC_EPOCH_READ _RTCIOC(0x000d)
-
+
/* RTC_EPOCH_SET set the Epoch
*
* Argument: An unsigned long value containing the new Epoch value to be set.
@@ -311,80 +311,85 @@ struct rtc_wkalrm
* A NULL value should be provided for any unsupported methods.
*/
-struct rtc_lowerhalf_f;
+struct rtc_lowerhalf_s;
struct rtc_ops_s
{
/* rdtime() returns the current RTC time. */
- CODE int (*rdtime)(FAR struct rtc_lowerhalf_f *lower,
+ CODE int (*rdtime)(FAR struct rtc_lowerhalf_s *lower,
FAR struct rtc_time *rtctime);
/* settime sets the RTC's time */
- CODE int (*settime)(FAR struct rtc_lowerhalf_f *lower,
+ CODE int (*settime)(FAR struct rtc_lowerhalf_s *lower,
FAR const struct rtc_time *rtctime);
-
/* almread reads the alarm time (for RTCs that support alarms) */
- CODE int (*almread)(FAR struct rtc_lowerhalf_f *lower,
+ CODE int (*almread)(FAR struct rtc_lowerhalf_s *lower,
FAR struct rtc_time *almtime);
/* almset sets the alarm time (for RTCs that support alarms). */
- CODE int (*almset)(FAR struct rtc_lowerhalf_f *lower,
+ CODE int (*almset)(FAR struct rtc_lowerhalf_s *lower,
FAR const struct rtc_time *almtime);
/* irqpread the frequency for periodic interrupts (for RTCs that support
* periodic interrupts)
*/
- CODE int (*irqpread)(FAR struct rtc_lowerhalf_f *lower,
+ CODE int (*irqpread)(FAR struct rtc_lowerhalf_s *lower,
FAR unsigned long *irqpfreq);
/* irqpset set the frequency for periodic interrupts (for RTCs that
* support periodic interrupts)
*/
- CODE int (*irqpset)(FAR struct rtc_lowerhalf_f *lower,
+ CODE int (*irqpset)(FAR struct rtc_lowerhalf_s *lower,
unsigned long irqpfreq);
/* aie enable/disable alarm interrupts (for RTCs that support alarms) */
- CODE int (*aie)(FAR struct rtc_lowerhalf_f *lower, bool enable);
+ CODE int (*aie)(FAR struct rtc_lowerhalf_s *lower, bool enable);
/* uie enable/disable the interrupt on every clock update (for RTCs that
* support this once-per-second interrupt).
*/
- CODE int (*uie)(FAR struct rtc_lowerhalf_f *lower, bool enable);
+ CODE int (*uie)(FAR struct rtc_lowerhalf_s *lower, bool enable);
/* pie enable the periodic interrupt (for RTCs that support these periodic
* interrupts).
*/
- CODE int (*pie)(FAR struct rtc_lowerhalf_f *lower, bool enable);
+ CODE int (*pie)(FAR struct rtc_lowerhalf_s *lower, bool enable);
/* rdepoch read the Epoch. */
- CODE int (*rdepoch)(FAR struct rtc_lowerhalf_f *lower,
+ CODE int (*rdepoch)(FAR struct rtc_lowerhalf_s *lower,
FAR unsigned long *epoch);
/* setepoch set the Epoch */
- CODE int (*setepoch)(FAR struct rtc_lowerhalf_f *lower,
+ CODE int (*setepoch)(FAR struct rtc_lowerhalf_s *lower,
unsigned long epoch);
/* rdwkalm read the current alarm */
- CODE int (*rdwkalm)(FAR struct rtc_lowerhalf_f *lower,
- FAR struct rtc_time *rtc_wkalrm);
+ CODE int (*rdwkalm)(FAR struct rtc_lowerhalf_s *lower,
+ FAR struct rtc_wkalrm *wkalrm);
/* setwkalm set the alarm. */
- CODE int (*setwkalm)(FAR struct rtc_lowerhalf_f *lower,
- FAR const struct rtc_time *rtc_wkalrm);
+ CODE int (*setwkalm)(FAR struct rtc_lowerhalf_s *lower,
+ FAR const struct rtc_wkalrm *wkalrm);
+
+ /* The driver has been unlinked and there are no further open references
+ * to the driver.
+ */
+
+ CODE int (*destroy)(FAR struct rtc_lowerhalf_s *lower);
};
/* When the RTC driver is instantiated, a reference to struct
@@ -440,6 +445,6 @@ int rtc_initialize(int minor, FAR struct rtc_lowerhalf_s *lower);
}
#endif
-#enif /* CONFIG_RTC_DRIVER */
-#enif /* CONFIG_RTC */
+#endif /* CONFIG_RTC_DRIVER */
+#endif /* CONFIG_RTC */
#endif /* __INCLUDE_NUTTX_RTC_H */