summaryrefslogtreecommitdiffstats
path: root/bsps
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2018-04-23 09:55:15 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2018-04-23 15:18:44 +0200
commit4fb1b79a804ca8de866be0ef718e54e1f62fa3ec (patch)
tree11b85c98244db22c927e7f1323ed222c43a589b0 /bsps
parentbsps: Move legacy network drivers to bsps (diff)
downloadrtems-4fb1b79a804ca8de866be0ef718e54e1f62fa3ec.tar.bz2
bsps: Move RTC drivers to bsps
This patch is a part of the BSP source reorganization. Update #3285.
Diffstat (limited to 'bsps')
-rw-r--r--bsps/arm/altera-cyclone-v/rtc/rtc.c835
-rw-r--r--bsps/arm/atsam/rtc/rtc-config.c104
-rw-r--r--bsps/arm/lpc176x/rtc/rtc-config.c125
-rw-r--r--bsps/arm/lpc24xx/rtc/rtc-config.c96
-rw-r--r--bsps/arm/lpc32xx/rtc/rtc-config.c142
-rw-r--r--bsps/m68k/mcf5206elite/rtc/ds1307.c206
-rw-r--r--bsps/m68k/mcf5206elite/rtc/todcfg.c80
-rw-r--r--bsps/m68k/mvme162/rtc/tod.c88
-rw-r--r--bsps/powerpc/beatnik/rtc/todcfg.c32
-rw-r--r--bsps/powerpc/gen5200/rtc/pcf8563.c228
-rw-r--r--bsps/powerpc/gen5200/rtc/pcf8563.h99
-rw-r--r--bsps/powerpc/gen5200/rtc/todcfg.c102
-rw-r--r--bsps/powerpc/mvme3100/rtc/todcfg.c24
-rw-r--r--bsps/powerpc/mvme5500/rtc/todcfg.c32
-rw-r--r--bsps/powerpc/qoriq/rtc/rtc-config.c67
-rw-r--r--bsps/powerpc/shared/rtc/todcfg.c66
16 files changed, 2326 insertions, 0 deletions
diff --git a/bsps/arm/altera-cyclone-v/rtc/rtc.c b/bsps/arm/altera-cyclone-v/rtc/rtc.c
new file mode 100644
index 0000000000..e0e468892b
--- /dev/null
+++ b/bsps/arm/altera-cyclone-v/rtc/rtc.c
@@ -0,0 +1,835 @@
+/*
+ * Copyright (c) 2014 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <info@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+/*
+ * Driver for the DS1339 RTC (Maxim Semiconductors) -> RTC1
+ * and the M41ST87 RTC (ST Microelectronics) -> RTC2
+ *
+ * Please note the following points:
+ * - The day of week is ignored.
+ * - The century bit is interpreted the following way:
+ * - century not set: TOD_BASE_YEAR .. 1999
+ * - century set: 2000 .. 2099
+ * - century not set: 2100 .. (TOD_BASE_YEAR + 200)
+ */
+
+#include <libchip/rtc.h>
+#include <assert.h>
+#include <rtems/score/todimpl.h>
+#include <sys/filio.h>
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+#include <bsp/i2cdrv.h>
+
+#define ALTERA_CYCLONE_V_RTC_NUMBER 2
+
+
+/* ******************************* DS1339 ********************************** */
+
+
+#define DS1339_I2C_ADDRESS (0xD0 >> 1) /* 7-bit addressing! */
+#define DS1339_I2C_BUS_DEVICE "/dev/i2c0"
+
+#define DS1339_ADDR_TIME 0x00
+
+#define DS1339_ADDR_CTRL 0x0E
+#define DS1339_CTRL_EOSC 0x80
+#define DS1339_CTRL_BBSQI 0x20
+#define DS1339_CTRL_RS2 0x10
+#define DS1339_CTRL_RS1 0x08
+#define DS1339_CTRL_INTCN 0x04
+#define DS1339_CTRL_A2IE 0x02
+#define DS1339_CTRL_A1IE 0x01
+
+#define DS1339_CTRL_DEFAULT (0x00)
+
+#define DS1339_ADDR_STATUS 0x0F
+#define DS1339_STATUS_OSF 0x80
+#define DS1339_STATUS_A2F 0x02
+#define DS1339_STATUS_A1F 0x01
+
+#define DS1339_STATUS_CLEAR (0x00)
+
+#define DS1339_ADDR_TRICKLE_CHARGE 0x10
+
+
+typedef struct
+{
+ uint8_t seconds;
+ uint8_t minutes;
+ uint8_t hours;
+#define DS1339_HOURS_12_24_FLAG 0x40
+#define DS1339_HOURS_AM_PM_FLAG_OR_20_HOURS 0x20
+#define DS1339_HOURS_10_HOURS 0x10
+ uint8_t weekday;
+ uint8_t date;
+ uint8_t month;
+#define DS1339_MONTH_CENTURY 0x80
+ uint8_t year;
+}
+ds1339_time_t;
+
+
+/* The longest write transmission is writing the time + one address bit */
+#define DS1339_MAX_WRITE_SIZE (sizeof(ds1339_time_t) + 1)
+
+
+/* Functions for converting the fields */
+static unsigned int ds1339_get_seconds(ds1339_time_t* time)
+{
+ uint8_t tens = time->seconds >> 4;
+ uint8_t ones = time->seconds & 0x0F;
+
+ return tens * 10 + ones;
+}
+
+
+static unsigned int ds1339_get_minutes(ds1339_time_t* time)
+{
+ uint8_t tens = time->minutes >> 4;
+ uint8_t ones = time->minutes & 0x0F;
+
+ return tens * 10 + ones;
+}
+
+
+static unsigned int ds1339_get_hours(ds1339_time_t* time)
+{
+
+ uint8_t value = time->hours & 0x0F;
+
+ if (time->hours & DS1339_HOURS_10_HOURS)
+ {
+ value += 10;
+ }
+ if (time->hours & DS1339_HOURS_AM_PM_FLAG_OR_20_HOURS)
+ {
+ if (time->hours & DS1339_HOURS_12_24_FLAG)
+ value += 12;
+ else
+ value += 20;
+ }
+
+ return value;
+}
+
+
+static unsigned int ds1339_get_day_of_month(ds1339_time_t* time)
+{
+
+ uint8_t tens = time->date >> 4;
+ uint8_t ones = time->date & 0x0F;
+
+ return tens * 10 + ones;
+}
+
+
+static unsigned int ds1339_get_month(ds1339_time_t* time)
+{
+
+ uint8_t tens = (time->month >> 4) & 0x07;
+ uint8_t ones = time->month & 0x0F;
+
+ return tens * 10 + ones;
+}
+
+
+static unsigned int ds1339_get_year(ds1339_time_t* time)
+{
+
+ unsigned int year = 1900;
+
+ year += (time->year >> 4) * 10;
+ year += time->year & 0x0F;
+ if (time->month & DS1339_MONTH_CENTURY)
+ year += 100;
+ if (year < TOD_BASE_YEAR)
+ year += 200;
+
+ return year;
+}
+
+
+static void ds1339_set_time(ds1339_time_t* time,
+ unsigned int second,
+ unsigned int minute,
+ unsigned int hour,
+ unsigned int day,
+ unsigned int month,
+ unsigned int year)
+{
+
+ unsigned int tens;
+ unsigned int ones;
+ uint8_t century = 0;
+
+ tens = second / 10;
+ ones = second % 10;
+ time->seconds = tens << 4 | ones;
+
+ tens = minute / 10;
+ ones = minute % 10;
+ time->minutes = tens << 4 | ones;
+
+ tens = hour / 10;
+ ones = hour % 10;
+ time->hours = tens << 4 | ones;
+
+ /* Weekday is not used. Therefore it can be set to an arbitrary valid value */
+ time->weekday = 1;
+
+ tens = day / 10;
+ ones = day % 10;
+ time->date = tens << 4 | ones;
+
+ tens = month / 10;
+ ones = month % 10;
+ if ((year >= 2000) && (year < 2100))
+ century = DS1339_MONTH_CENTURY;
+ time->month = century | tens << 4 | ones;
+
+ tens = (year % 100) / 10;
+ ones = year % 10;
+ time->year = tens << 4 | ones;
+
+}
+
+
+
+static rtems_status_code ds1339_open_file(int* fd)
+{
+
+ int rv = 0;
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+
+ *fd = open(DS1339_I2C_BUS_DEVICE, O_RDWR);
+ if (*fd == -1)
+ sc = RTEMS_IO_ERROR;
+
+ if (sc == RTEMS_SUCCESSFUL)
+ {
+ rv = ioctl(*fd, I2C_IOC_SET_SLAVE_ADDRESS, DS1339_I2C_ADDRESS);
+ if (rv == -1)
+ sc = RTEMS_IO_ERROR;
+ }
+
+ return sc;
+}
+
+
+/* Read size bytes from ds1339 register address addr to buf. */
+static rtems_status_code ds1339_read(uint8_t addr, void* buf, size_t size)
+{
+
+ int fd = -1;
+ int rv = 0;
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+
+ sc = ds1339_open_file(&fd);
+
+ if (sc == RTEMS_SUCCESSFUL)
+ {
+ rv = write(fd, &addr, sizeof(addr));
+ if (rv != sizeof(addr))
+ sc = RTEMS_IO_ERROR;
+ }
+
+ if (sc == RTEMS_SUCCESSFUL)
+ {
+ rv = read(fd, buf, size);
+ if (rv != size)
+ sc = RTEMS_IO_ERROR;
+ }
+
+ rv = close(fd);
+ if (rv != 0)
+ sc = RTEMS_IO_ERROR;
+
+ return sc;
+}
+
+
+/* Write size bytes from buf to ds1339 register address addr. */
+static rtems_status_code ds1339_write(uint8_t addr, void* buf, size_t size)
+{
+
+ int fd = -1;
+ int rv = 0;
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+ /* The driver never writes many bytes. Therefore it should be less expensive
+ * to reserve the maximum number of bytes that will be written in one go than
+ * use a malloc. */
+ uint8_t local_buf[DS1339_MAX_WRITE_SIZE];
+ int write_size = size + 1;
+
+ assert(write_size <= DS1339_MAX_WRITE_SIZE);
+
+ local_buf[0] = addr;
+ memcpy(&local_buf[1], buf, size);
+
+ sc = ds1339_open_file(&fd);
+
+ if (sc == RTEMS_SUCCESSFUL)
+ {
+ rv = write(fd, local_buf, write_size);
+ if (rv != write_size)
+ sc = RTEMS_IO_ERROR;
+ }
+
+ rv = close(fd);
+ if (rv != 0)
+ sc = RTEMS_IO_ERROR;
+
+ return RTEMS_SUCCESSFUL;
+}
+
+
+static void altera_cyclone_v_ds1339_initialize(int minor)
+{
+
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+ uint8_t status = 0;
+
+ /* Check RTC valid */
+ sc = ds1339_read(DS1339_ADDR_STATUS, &status, sizeof(status));
+ assert(sc == RTEMS_SUCCESSFUL);
+
+ if (status & DS1339_STATUS_OSF)
+ {
+ /* RTC has been stopped. Initialise it. */
+ ds1339_time_t time;
+
+ uint8_t write = DS1339_CTRL_DEFAULT;
+ sc = ds1339_write(DS1339_ADDR_CTRL, &write, sizeof(write));
+ assert(sc == RTEMS_SUCCESSFUL);
+
+ write = DS1339_STATUS_CLEAR;
+ sc = ds1339_write(DS1339_ADDR_STATUS, &write, sizeof(write));
+ assert(sc == RTEMS_SUCCESSFUL);
+
+ ds1339_set_time(&time, 0, 0, 0, 1, 1, TOD_BASE_YEAR);
+ sc = ds1339_write(DS1339_ADDR_TIME, &time, sizeof(time));
+ assert(sc == RTEMS_SUCCESSFUL);
+ }
+
+}
+
+
+static int altera_cyclone_v_ds1339_get_time(int minor, rtems_time_of_day* tod)
+{
+
+ ds1339_time_t time;
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+ rtems_time_of_day temp_tod;
+
+ sc = ds1339_read(DS1339_ADDR_TIME, &time, sizeof(time));
+
+ if (sc == RTEMS_SUCCESSFUL)
+ {
+ temp_tod.ticks = 0;
+ temp_tod.second = ds1339_get_seconds(&time);
+ temp_tod.minute = ds1339_get_minutes(&time);
+ temp_tod.hour = ds1339_get_hours(&time);
+ temp_tod.day = ds1339_get_day_of_month(&time);
+ temp_tod.month = ds1339_get_month(&time);
+ temp_tod.year = ds1339_get_year(&time);
+
+ if (_TOD_Validate(&temp_tod))
+ memcpy(tod, &temp_tod, sizeof(temp_tod));
+ else
+ sc = RTEMS_INVALID_CLOCK;
+ }
+
+ return -sc;
+}
+
+
+static int altera_cyclone_v_ds1339_set_time(int minor, const rtems_time_of_day* tod)
+{
+
+ ds1339_time_t time;
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+
+ ds1339_set_time(&time,
+ tod->second,
+ tod->minute,
+ tod->hour,
+ tod->day,
+ tod->month,
+ tod->year
+ );
+
+ sc = ds1339_write(DS1339_ADDR_TIME, &time, sizeof(time));
+
+ return -sc;
+}
+
+
+static bool altera_cyclone_v_ds1339_probe(int minor)
+{
+
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+ uint8_t buf;
+
+ /* try to read from register address 0x00 */
+ sc = ds1339_read(0x00, &buf, 1);
+ if (sc != RTEMS_SUCCESSFUL)
+ /* no RTC implemented */
+ return false;
+ /* try to read from register address 0x20 (not implemented in DS1339) */
+ sc = ds1339_read(0x20, &buf, 1);
+ if (sc == RTEMS_SUCCESSFUL)
+ /* RTC is not DS1339 */
+ return false;
+
+ return true;
+
+}
+
+
+/* ******************************* M41ST87 ********************************** */
+
+
+#define M41ST87_I2C_ADDRESS (0xD0 >> 1) /* 7-bit addressing! */
+#define M41ST87_I2C_BUS_DEVICE "/dev/i2c0"
+
+#define M41ST87_ADDR_TIME 0x00
+
+#define M41ST87_ADDR_CTRL 0x08
+#define M41ST87_CTRL_OUT 0x80
+#define M41ST87_CTRL_FT 0x40
+#define M41ST87_CTRL_S 0x20
+#define M41ST87_CTRL_CAL 0x1F
+
+#define M41ST87_ADDR_ALARM_HOUR 0x0C
+#define M41ST87_BIT_HT 0x40
+
+#define M41ST87_ADDR_FLAGS 0x0F
+#define M41ST87_FLAG_WDF 0x80
+#define M41ST87_FLAG_AF 0x40
+#define M41ST87_FLAG_BL 0x10
+#define M41ST87_FLAG_OF 0x04
+#define M41ST87_FLAG_TB1 0x02
+#define M41ST87_FLAG_TB2 0x01
+
+#define M41ST87_ADDR_USER_RAM 0x20
+
+
+typedef struct
+{
+ uint8_t sec100;
+ uint8_t seconds;
+#define M41ST87_BIT_ST 0x80
+ uint8_t minutes;
+#define M41ST87_BIT_OFIE 0x80
+ uint8_t hours;
+#define M41ST87_BIT_CB1 0x80
+#define M41ST87_BIT_CB0 0x40
+ uint8_t weekday;
+#define M41ST87_BIT_TR 0x80
+#define M41ST87_BIT_THS 0x40
+#define M41ST87_BIT_CLRPW1 0x20
+#define M41ST87_BIT_CLRPW0 0x10
+#define M41ST87_BIT_32KE 0x08
+ uint8_t day;
+#define M41ST87_BIT_PFOD 0x80
+ uint8_t month;
+ uint8_t year;
+}
+m41st87_time_t;
+
+
+/* The longest write transmission is writing the time + one address bit */
+#define M41ST87_MAX_WRITE_SIZE (sizeof(m41st87_time_t) + 1)
+
+
+/* Functions for converting the fields */
+
+/*
+static unsigned int m41st87_get_sec100(m41st87_time_t* time)
+{
+
+ uint8_t tens = time->sec100 >> 4;
+ uint8_t ones = time->sec100 & 0x0F;
+
+ return tens * 10 + ones;
+}
+*/
+
+
+static unsigned int m41st87_get_seconds(m41st87_time_t* time)
+{
+
+ uint8_t tens = (time->seconds >> 4) & 0x07;
+ uint8_t ones = time->seconds & 0x0F;
+
+ return tens * 10 + ones;
+}
+
+
+static unsigned int m41st87_get_minutes(m41st87_time_t* time)
+{
+
+ uint8_t tens = (time->minutes >> 4) & 0x07;
+ uint8_t ones = time->minutes & 0x0F;
+
+ return tens * 10 + ones;
+}
+
+
+static unsigned int m41st87_get_hours(m41st87_time_t* time)
+{
+
+ uint8_t tens = (time->hours >> 4) & 0x03;
+ uint8_t ones = time->hours & 0x0F;
+
+ return tens * 10 + ones;
+}
+
+
+/*
+static unsigned int m41st87_get_day_of_week(m41st87_time_t* time)
+{
+
+ return time->weekday & 0x07;
+}
+*/
+
+
+static unsigned int m41st87_get_day_of_month(m41st87_time_t* time)
+{
+
+ uint8_t tens = (time->day >> 4) & 0x03;
+ uint8_t ones = time->day & 0x0F;
+
+ return tens * 10 + ones;
+}
+
+
+static unsigned int m41st87_get_month(m41st87_time_t* time)
+{
+
+ uint8_t tens = (time->month >> 4) & 0x01;
+ uint8_t ones = time->month & 0x0F;
+
+ return tens * 10 + ones;
+}
+
+
+static unsigned int m41st87_get_year(m41st87_time_t* time)
+{
+
+ uint8_t century = time->hours >> 6;
+ uint8_t tens = time->year >> 4;
+ uint8_t ones = time->year & 0x0F;
+
+ return 1900 + century * 100 + tens * 10 + ones;
+}
+
+
+static void m41st87_set_time(m41st87_time_t* time,
+ unsigned int second,
+ unsigned int minute,
+ unsigned int hour,
+ unsigned int day,
+ unsigned int month,
+ unsigned int year)
+{
+
+ unsigned int century;
+ unsigned int tens;
+ unsigned int ones;
+
+ if (year < 1900)
+ year = 1900;
+ if (year > 2399)
+ year = 2399;
+ century = (year - 1900) / 100;
+
+ /* Hundreds of seconds is not used, set to 0 */
+ time->sec100 = 0;
+
+ tens = second / 10;
+ ones = second % 10;
+ time->seconds = (time->seconds & 0x80) | (tens << 4) | ones;
+
+ tens = minute / 10;
+ ones = minute % 10;
+ time->minutes = (time->minutes & 0x80) | (tens << 4) | ones;
+
+ tens = hour / 10;
+ ones = hour % 10;
+ time->hours = (century << 6) | (tens << 4) | ones;
+
+ /* Weekday is not used. Therefore it can be set to an arbitrary valid value */
+ time->weekday = (time->weekday & 0xF8) | 1;
+
+ tens = day / 10;
+ ones = day % 10;
+ time->day = (time->day & 0x80) | (tens << 4) | ones;
+
+ tens = month / 10;
+ ones = month % 10;
+ time->month = (tens << 4) | ones;
+
+ tens = (year % 100) / 10;
+ ones = year % 10;
+ time->year = (tens << 4) | ones;
+
+}
+
+
+
+static rtems_status_code m41st87_open_file(int* fd)
+{
+
+ int rv = 0;
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+
+ *fd = open(M41ST87_I2C_BUS_DEVICE, O_RDWR);
+ if (*fd == -1)
+ sc = RTEMS_IO_ERROR;
+
+ if (sc == RTEMS_SUCCESSFUL)
+ {
+ rv = ioctl(*fd, I2C_IOC_SET_SLAVE_ADDRESS, M41ST87_I2C_ADDRESS);
+ if (rv == -1)
+ sc = RTEMS_IO_ERROR;
+ }
+
+ return sc;
+}
+
+
+/* Read size bytes from m41st87 register address addr to buf. */
+static rtems_status_code m41st87_read(uint8_t addr, void* buf, size_t size)
+{
+
+ int fd = -1;
+ int rv = 0;
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+
+ sc = m41st87_open_file(&fd);
+
+ if (sc == RTEMS_SUCCESSFUL)
+ {
+ rv = write(fd, &addr, sizeof(addr));
+ if (rv != sizeof(addr))
+ sc = RTEMS_IO_ERROR;
+ }
+
+ if (sc == RTEMS_SUCCESSFUL)
+ {
+ rv = read(fd, buf, size);
+ if (rv != size)
+ sc = RTEMS_IO_ERROR;
+ }
+
+ rv = close(fd);
+ if (rv != 0)
+ sc = RTEMS_IO_ERROR;
+
+ return sc;
+}
+
+
+/* Write size bytes from buf to m41st87 register address addr. */
+static rtems_status_code m41st87_write(uint8_t addr, void* buf, size_t size)
+{
+
+ int fd = -1;
+ int rv = 0;
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+ /* The driver never writes many bytes. Therefore it should be less expensive
+ * to reserve the maximum number of bytes that will be written in one go than
+ * use a malloc. */
+ uint8_t local_buf[M41ST87_MAX_WRITE_SIZE];
+ int write_size = size + 1;
+
+ assert(write_size <= M41ST87_MAX_WRITE_SIZE);
+
+ local_buf[0] = addr;
+ memcpy(&local_buf[1], buf, size);
+
+ sc = m41st87_open_file(&fd);
+
+ if (sc == RTEMS_SUCCESSFUL)
+ {
+ rv = write(fd, local_buf, write_size);
+ if (rv != write_size)
+ sc = RTEMS_IO_ERROR;
+ }
+
+ rv = close(fd);
+ if (rv != 0)
+ sc = RTEMS_IO_ERROR;
+
+ return RTEMS_SUCCESSFUL;
+}
+
+
+static void altera_cyclone_v_m41st87_initialize(int minor)
+{
+
+ m41st87_time_t time;
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+ uint8_t value;
+
+ /* Check RTC valid */
+ sc = m41st87_read(M41ST87_ADDR_TIME, &time, sizeof(time));
+ assert(sc == RTEMS_SUCCESSFUL);
+
+ if (time.seconds & M41ST87_BIT_ST)
+ {
+ /* RTC has been stopped. Reset stop flag. */
+ time.seconds = 0;
+ /* Initialise RTC. */
+ m41st87_set_time(&time, 0, 0, 0, 1, 1, TOD_BASE_YEAR);
+ sc = m41st87_write(M41ST87_ADDR_TIME, &time, sizeof(time));
+ assert(sc == RTEMS_SUCCESSFUL);
+ }
+
+ /* Reset HT bit */
+ sc = m41st87_read(M41ST87_ADDR_ALARM_HOUR, &value, 1);
+ assert(sc == RTEMS_SUCCESSFUL);
+ value &= ~M41ST87_BIT_HT;
+ sc = m41st87_write(M41ST87_ADDR_ALARM_HOUR, &value, 1);
+ assert(sc == RTEMS_SUCCESSFUL);
+
+}
+
+
+static int altera_cyclone_v_m41st87_get_time(int minor, rtems_time_of_day* tod)
+{
+
+ m41st87_time_t time;
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+ rtems_time_of_day temp_tod;
+
+ sc = m41st87_read(M41ST87_ADDR_TIME, &time, sizeof(time));
+ if (sc != RTEMS_SUCCESSFUL)
+ return -sc;
+
+ temp_tod.ticks = 0;
+ temp_tod.second = m41st87_get_seconds(&time);
+ temp_tod.minute = m41st87_get_minutes(&time);
+ temp_tod.hour = m41st87_get_hours(&time);
+ temp_tod.day = m41st87_get_day_of_month(&time);
+ temp_tod.month = m41st87_get_month(&time);
+ temp_tod.year = m41st87_get_year(&time);
+
+ if (_TOD_Validate(&temp_tod))
+ memcpy(tod, &temp_tod, sizeof(temp_tod));
+ else
+ sc = RTEMS_INVALID_CLOCK;
+
+ return -sc;
+}
+
+
+static int altera_cyclone_v_m41st87_set_time(int minor, const rtems_time_of_day* tod)
+{
+
+ m41st87_time_t time;
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+
+ /* first read to preserve the additional flags */
+ sc = m41st87_read(M41ST87_ADDR_TIME, &time, sizeof(time));
+ if (sc != RTEMS_SUCCESSFUL)
+ return -sc;
+
+ m41st87_set_time(&time,
+ tod->second,
+ tod->minute,
+ tod->hour,
+ tod->day,
+ tod->month,
+ tod->year
+ );
+
+ sc = m41st87_write(M41ST87_ADDR_TIME, &time, sizeof(time));
+
+ return -sc;
+}
+
+
+static bool altera_cyclone_v_m41st87_probe(int minor)
+{
+
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+ uint8_t buf;
+
+ /* try to read from register address 0x00 */
+ sc = m41st87_read(0x00, &buf, 1);
+ if (sc != RTEMS_SUCCESSFUL)
+ /* no RTC implemented */
+ return false;
+ /* try to read from register address 0x20 (implemented in M41ST87) */
+ sc = m41st87_read(0x20, &buf, 1);
+ if (sc != RTEMS_SUCCESSFUL)
+ /* RTC is not M41ST87 */
+ return false;
+
+ return true;
+
+}
+
+
+/* **************************************** General ********************************** */
+
+
+const rtc_fns altera_cyclone_v_ds1339_ops =
+{
+ .deviceInitialize = altera_cyclone_v_ds1339_initialize,
+ .deviceGetTime = altera_cyclone_v_ds1339_get_time,
+ .deviceSetTime = altera_cyclone_v_ds1339_set_time
+};
+
+
+const rtc_fns altera_cyclone_v_m41st87_ops =
+{
+ .deviceInitialize = altera_cyclone_v_m41st87_initialize,
+ .deviceGetTime = altera_cyclone_v_m41st87_get_time,
+ .deviceSetTime = altera_cyclone_v_m41st87_set_time
+};
+
+
+size_t RTC_Count = ALTERA_CYCLONE_V_RTC_NUMBER;
+
+rtc_tbl RTC_Table[ALTERA_CYCLONE_V_RTC_NUMBER] =
+{
+ {
+ .sDeviceName = "/dev/rtc",
+ .deviceType = RTC_CUSTOM,
+ .pDeviceFns = &altera_cyclone_v_ds1339_ops,
+ .deviceProbe = altera_cyclone_v_ds1339_probe,
+ .pDeviceParams = NULL,
+ .ulCtrlPort1 = 0,
+ .ulDataPort = 0,
+ .getRegister = NULL,
+ .setRegister = NULL
+ },
+ {
+ .sDeviceName = "/dev/rtc",
+ .deviceType = RTC_CUSTOM,
+ .pDeviceFns = &altera_cyclone_v_m41st87_ops,
+ .deviceProbe = altera_cyclone_v_m41st87_probe,
+ .pDeviceParams = NULL,
+ .ulCtrlPort1 = 0,
+ .ulDataPort = 0,
+ .getRegister = NULL,
+ .setRegister = NULL
+ }
+};
diff --git a/bsps/arm/atsam/rtc/rtc-config.c b/bsps/arm/atsam/rtc/rtc-config.c
new file mode 100644
index 0000000000..dca33668ad
--- /dev/null
+++ b/bsps/arm/atsam/rtc/rtc-config.c
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2016 embedded brains GmbH
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <info@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <libchip/chip.h>
+#include <libchip/rtc.h>
+
+#include <bsp.h>
+
+#define ARBITRARY_DAY_OF_WEEK 1
+
+void atsam_rtc_get_time(rtems_time_of_day *tod)
+{
+ Rtc *rtc = RTC;
+ uint8_t hour;
+ uint8_t minute;
+ uint8_t second;
+ uint16_t year;
+ uint8_t month;
+ uint8_t day;
+ uint8_t week;
+
+ RTC_GetDate(rtc, &year, &month, &day, &week);
+ RTC_GetTime(rtc, &hour, &minute, &second);
+
+ tod->ticks = 0;
+ tod->second = second;
+ tod->minute = minute;
+ tod->hour = hour;
+ tod->day = day;
+ tod->month = month;
+ tod->year = year;
+}
+
+static void atsam_rtc_device_initialize(int minor)
+{
+ Rtc *rtc = RTC;
+
+ RTC_DisableIt(rtc, 0x1F);
+}
+
+static int atsam_rtc_device_get_time(int minor, rtems_time_of_day *tod)
+{
+ atsam_rtc_get_time(tod);
+
+ return 0;
+}
+
+static int atsam_rtc_device_set_time(int minor, const rtems_time_of_day *tod)
+{
+ Rtc *rtc = RTC;
+ uint8_t hour;
+ uint8_t minute;
+ uint8_t second;
+ uint16_t year;
+ uint8_t month;
+ uint8_t day;
+ uint8_t week;
+
+ second = (uint8_t) tod->second;
+ minute = (uint8_t) tod->minute;
+ hour = (uint8_t) tod->hour;
+ day = (uint8_t) tod->day;
+ month = (uint8_t) tod->month;
+ week = ARBITRARY_DAY_OF_WEEK;
+ year = (uint16_t) tod->year;
+
+ RTC_SetDate(rtc, year, month, day, week);
+ RTC_SetTime(rtc, hour, minute, second);
+
+ return 0;
+}
+
+static bool atsam_rtc_device_probe(int minor)
+{
+ return true;
+}
+
+const rtc_fns atsam_rtc_device_ops = {
+ .deviceInitialize = atsam_rtc_device_initialize,
+ .deviceGetTime = atsam_rtc_device_get_time,
+ .deviceSetTime = atsam_rtc_device_set_time
+};
+
+rtc_tbl RTC_Table[] = {
+ {
+ .sDeviceName = "/dev/rtc",
+ .deviceType = RTC_CUSTOM,
+ .pDeviceFns = &atsam_rtc_device_ops,
+ .deviceProbe = atsam_rtc_device_probe
+ }
+};
+
+size_t RTC_Count = RTEMS_ARRAY_SIZE(RTC_Table);
diff --git a/bsps/arm/lpc176x/rtc/rtc-config.c b/bsps/arm/lpc176x/rtc/rtc-config.c
new file mode 100644
index 0000000000..7d1512c01a
--- /dev/null
+++ b/bsps/arm/lpc176x/rtc/rtc-config.c
@@ -0,0 +1,125 @@
+/**
+ * @file
+ *
+ * @ingroup lpc176x
+ *
+ * @brief RTC configuration.
+ */
+
+/*
+ * Copyright (c) 2008
+ * Embedded Brains GmbH
+ * Obere Lagerstr. 30
+ * D-82178 Puchheim
+ * Germany
+ * rtems@embedded-brains.de
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <libchip/rtc.h>
+#include <bsp/io.h>
+
+#define LPC176X_RTC_NUMBER 1U
+
+void bsp_rtc_initialize( void );
+int bsp_rtc_get_time( rtems_time_of_day *tod );
+int bsp_rtc_set_time( const rtems_time_of_day *tod );
+bool bsp_rtc_probe( void );
+
+/**
+ * @brief Initialize the rtc device.
+ */
+void bsp_rtc_initialize( void )
+{
+ /* Enable module power */
+ lpc176x_module_enable( LPC176X_MODULE_RTC, LPC176X_MODULE_PCLK_DEFAULT );
+
+ /* Enable the RTC and use external clock */
+ RTC_CCR = RTC_CCR_CLKEN | RTC_CCR_CLKSRC;
+
+ /* Disable interrupts */
+ RTC_CIIR = 0U;
+ RTC_CISS = 0U;
+ RTC_AMR = 0xFFU;
+
+ /* Clear interrupts */
+ RTC_ILR = RTC_ILR_RTCCIF | RTC_ILR_RTCALF | RTC_ILR_RTSSF;
+}
+
+/**
+ * @brief Gets the information according to the current time.
+ *
+ * @param tod Value to be modified.
+ * @return 0
+ */
+int bsp_rtc_get_time( rtems_time_of_day *tod )
+{
+ tod->ticks = 0;
+ tod->second = RTC_SEC;
+ tod->minute = RTC_MIN;
+ tod->hour = RTC_HOUR;
+ tod->day = RTC_DOM;
+ tod->month = RTC_MONTH;
+ tod->year = RTC_YEAR;
+
+ return 0;
+}
+
+/**
+ * @brief Sets the information according to the current time.
+ *
+ * @param tod Value to get the new information.
+ * @return 0
+ */
+int bsp_rtc_set_time( const rtems_time_of_day *tod )
+{
+ RTC_SEC = tod->second;
+ RTC_MIN = tod->minute;
+ RTC_HOUR = tod->hour;
+ RTC_DOM = tod->day;
+ RTC_MONTH = tod->month;
+ RTC_YEAR = tod->year;
+
+ return 0;
+}
+
+/**
+ * @brief Used to probe. At the moment is not used.
+ *
+ * @return true.
+ */
+bool bsp_rtc_probe( void )
+{
+ return true;
+}
+
+/**
+ * @brief Represents the real time clock options.
+ */
+const rtc_fns lpc176x_rtc_ops = {
+ .deviceInitialize = (void *) bsp_rtc_initialize,
+ .deviceGetTime = (void *) bsp_rtc_get_time,
+ .deviceSetTime = (void *) bsp_rtc_set_time
+};
+
+size_t RTC_Count = LPC176X_RTC_NUMBER;
+
+/**
+ * @brief Table to describes the rtc device.
+ */
+rtc_tbl RTC_Table[ LPC176X_RTC_NUMBER ] = {
+ {
+ .sDeviceName = "/dev/rtc",
+ .deviceType = RTC_CUSTOM,
+ .pDeviceFns = &lpc176x_rtc_ops,
+ .deviceProbe = (void *) bsp_rtc_probe,
+ .pDeviceParams = NULL,
+ .ulCtrlPort1 = 0,
+ .ulDataPort = 0,
+ .getRegister = NULL,
+ .setRegister = NULL
+ }
+};
diff --git a/bsps/arm/lpc24xx/rtc/rtc-config.c b/bsps/arm/lpc24xx/rtc/rtc-config.c
new file mode 100644
index 0000000000..c154a98196
--- /dev/null
+++ b/bsps/arm/lpc24xx/rtc/rtc-config.c
@@ -0,0 +1,96 @@
+/**
+ * @file
+ *
+ * @ingroup lpc24xx
+ *
+ * @brief RTC configuration.
+ */
+
+/*
+ * Copyright (c) 2008
+ * Embedded Brains GmbH
+ * Obere Lagerstr. 30
+ * D-82178 Puchheim
+ * Germany
+ * rtems@embedded-brains.de
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <libchip/rtc.h>
+
+#include <bsp/lpc24xx.h>
+#include <bsp/io.h>
+
+#define LPC24XX_RTC_NUMBER 1
+
+static void lpc24xx_rtc_initialize(int minor)
+{
+ /* Enable module power */
+ lpc24xx_module_enable(LPC24XX_MODULE_RTC, LPC24XX_MODULE_PCLK_DEFAULT);
+
+ /* Enable the RTC and use external clock */
+ RTC_CCR = RTC_CCR_CLKEN | RTC_CCR_CLKSRC;
+
+ /* Disable interrupts */
+ RTC_CIIR = 0;
+ RTC_CISS = 0;
+ RTC_AMR = 0xff;
+
+ /* Clear interrupts */
+ RTC_ILR = RTC_ILR_RTCCIF | RTC_ILR_RTCALF | RTC_ILR_RTSSF;
+}
+
+static int lpc24xx_rtc_get_time(int minor, rtems_time_of_day *tod)
+{
+ tod->ticks = 0;
+ tod->second = RTC_SEC;
+ tod->minute = RTC_MIN;
+ tod->hour = RTC_HOUR;
+ tod->day = RTC_DOM;
+ tod->month = RTC_MONTH;
+ tod->year = RTC_YEAR;
+
+ return 0;
+}
+
+static int lpc24xx_rtc_set_time(int minor, const rtems_time_of_day *tod)
+{
+ RTC_SEC = tod->second;
+ RTC_MIN = tod->minute;
+ RTC_HOUR = tod->hour;
+ RTC_DOM = tod->day;
+ RTC_MONTH = tod->month;
+ RTC_YEAR = tod->year;
+
+ return 0;
+}
+
+static bool lpc24xx_rtc_probe(int minor)
+{
+ return true;
+}
+
+const rtc_fns lpc24xx_rtc_ops = {
+ .deviceInitialize = lpc24xx_rtc_initialize,
+ .deviceGetTime = lpc24xx_rtc_get_time,
+ .deviceSetTime = lpc24xx_rtc_set_time
+};
+
+size_t RTC_Count = LPC24XX_RTC_NUMBER;
+
+rtc_tbl RTC_Table [LPC24XX_RTC_NUMBER] = {
+ {
+ .sDeviceName = "/dev/rtc",
+ .deviceType = RTC_CUSTOM,
+ .pDeviceFns = &lpc24xx_rtc_ops,
+ .deviceProbe = lpc24xx_rtc_probe,
+ .pDeviceParams = NULL,
+ .ulCtrlPort1 = 0,
+ .ulDataPort = 0,
+ .getRegister = NULL,
+ .setRegister = NULL
+ }
+};
diff --git a/bsps/arm/lpc32xx/rtc/rtc-config.c b/bsps/arm/lpc32xx/rtc/rtc-config.c
new file mode 100644
index 0000000000..bd225248b3
--- /dev/null
+++ b/bsps/arm/lpc32xx/rtc/rtc-config.c
@@ -0,0 +1,142 @@
+/**
+ * @file
+ *
+ * @ingroup arm_lpc32xx
+ *
+ * @brief RTC configuration.
+ */
+
+/*
+ * Copyright (c) 2009-2011 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Obere Lagerstr. 30
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <libchip/rtc.h>
+
+#include <bsp.h>
+#include <bsp/lpc32xx.h>
+
+#define LPC32XX_RTC_COUNT 1U
+
+#define LPC32XX_RTC_COUNTER_DELTA 0xfffffffeU
+
+#define LPC32XX_RTC_KEY 0xb5c13f27U
+
+#define LPC32XX_RTC_CTRL_FORCE_ONSW (1U << 7)
+#define LPC32XX_RTC_CTRL_STOP (1U << 6)
+#define LPC32XX_RTC_CTRL_RESET (1U << 4)
+#define LPC32XX_RTC_CTRL_MATCH_1_ONSW (1U << 3)
+#define LPC32XX_RTC_CTRL_MATCH_0_ONSW (1U << 2)
+#define LPC32XX_RTC_CTRL_MATCH_1_INTR (1U << 1)
+#define LPC32XX_RTC_CTRL_MATCH_0_INTR (1U << 0)
+
+static void lpc32xx_rtc_set(uint32_t val)
+{
+ unsigned i = lpc32xx_arm_clk() / LPC32XX_OSCILLATOR_RTC;
+
+ lpc32xx.rtc.ctrl |= LPC32XX_RTC_CTRL_STOP;
+ lpc32xx.rtc.ucount = val;
+ lpc32xx.rtc.dcount = LPC32XX_RTC_COUNTER_DELTA - val;
+ lpc32xx.rtc.ctrl &= ~LPC32XX_RTC_CTRL_STOP;
+
+ /* It needs some time before we can read the values back */
+ while (i != 0) {
+ __asm__ volatile ("nop");
+ --i;
+ }
+}
+
+static void lpc32xx_rtc_reset(void)
+{
+ lpc32xx.rtc.ctrl = LPC32XX_RTC_CTRL_RESET;
+ lpc32xx.rtc.ctrl = 0;
+ lpc32xx.rtc.key = LPC32XX_RTC_KEY;
+ lpc32xx_rtc_set(0);
+}
+
+static void lpc32xx_rtc_initialize(int minor)
+{
+ uint32_t up_first = 0;
+ uint32_t up_second = 0;
+ uint32_t down_first = 0;
+ uint32_t down_second = 0;
+
+ if (lpc32xx.rtc.key != LPC32XX_RTC_KEY) {
+ lpc32xx_rtc_reset();
+ }
+
+ do {
+ up_first = lpc32xx.rtc.ucount;
+ down_first = lpc32xx.rtc.dcount;
+ up_second = lpc32xx.rtc.ucount;
+ down_second = lpc32xx.rtc.dcount;
+ } while (up_first != up_second || down_first != down_second);
+
+ if (up_first + down_first != LPC32XX_RTC_COUNTER_DELTA) {
+ lpc32xx_rtc_reset();
+ }
+}
+
+static int lpc32xx_rtc_get_time(int minor, rtems_time_of_day *tod)
+{
+ struct timeval now = {
+ .tv_sec = lpc32xx.rtc.ucount,
+ .tv_usec = 0
+ };
+ struct tm time;
+
+ gmtime_r(&now.tv_sec, &time);
+
+ tod->year = time.tm_year + 1900;
+ tod->month = time.tm_mon + 1;
+ tod->day = time.tm_mday;
+ tod->hour = time.tm_hour;
+ tod->minute = time.tm_min;
+ tod->second = time.tm_sec;
+ tod->ticks = 0;
+
+ return RTEMS_SUCCESSFUL;
+}
+
+static int lpc32xx_rtc_set_time(int minor, const rtems_time_of_day *tod)
+{
+ lpc32xx_rtc_set(_TOD_To_seconds(tod));
+
+ return 0;
+}
+
+static bool lpc32xx_rtc_probe(int minor)
+{
+ return true;
+}
+
+const rtc_fns lpc32xx_rtc_ops = {
+ .deviceInitialize = lpc32xx_rtc_initialize,
+ .deviceGetTime = lpc32xx_rtc_get_time,
+ .deviceSetTime = lpc32xx_rtc_set_time
+};
+
+size_t RTC_Count = LPC32XX_RTC_COUNT;
+
+rtc_tbl RTC_Table [LPC32XX_RTC_COUNT] = {
+ {
+ .sDeviceName = "/dev/rtc",
+ .deviceType = RTC_CUSTOM,
+ .pDeviceFns = &lpc32xx_rtc_ops,
+ .deviceProbe = lpc32xx_rtc_probe,
+ .pDeviceParams = NULL,
+ .ulCtrlPort1 = 0,
+ .ulDataPort = 0,
+ .getRegister = NULL,
+ .setRegister = NULL
+ }
+};
diff --git a/bsps/m68k/mcf5206elite/rtc/ds1307.c b/bsps/m68k/mcf5206elite/rtc/ds1307.c
new file mode 100644
index 0000000000..ab7fc7daac
--- /dev/null
+++ b/bsps/m68k/mcf5206elite/rtc/ds1307.c
@@ -0,0 +1,206 @@
+/*
+ * This file interfaces with the real-time clock found in a
+ * Dallas Semiconductor DS1307/DS1308 serial real-time clock chip.
+ * This RTC have I2C bus interface. BSP have to provide I2C bus primitives
+ * to make this driver working. getRegister and setRegister primitives is
+ * not used here to avoid multiple transactions over I2C bus (each transaction
+ * require significant time and error when date/time information red may
+ * occurs). ulControlPort contains I2C bus number; ulDataPort contains
+ * RTC I2C device address.
+ *
+ * Year 2000 Note:
+ *
+ * This chip only uses a two digit field to store the year. This code
+ * uses the RTEMS Epoch as a pivot year. This lets us map the two digit
+ * year field as follows:
+ *
+ * + two digit years 00-87 are mapped to 2000-2087
+ * + two digit years 88-99 are mapped to 1988-1999
+ */
+
+/*
+ * Copyright (C) 2000 OKTET Ltd., St.-Petersburg, Russia
+ * Author: Victor V. Vengerov <vvv@oktet.ru>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <rtems.h>
+#include <libchip/rtc.h>
+#include <string.h>
+#include "ds1307.h"
+#include "i2c.h"
+
+/* Convert from/to Binary-Coded Decimal representation */
+#define From_BCD( _x ) ((((_x) >> 4) * 10) + ((_x) & 0x0F))
+#define To_BCD( _x ) ((((_x) / 10) << 4) + ((_x) % 10))
+
+/* ds1307_initialize --
+ * Initialize DS1307 real-time clock chip. If RTC is halted, this
+ * function resume counting.
+ *
+ * PARAMETERS:
+ * minor -- minor RTC device number
+ */
+static void ds1307_initialize(int minor)
+{
+ i2c_message_status status;
+ int try;
+ uint8_t sec;
+ i2c_bus_number bus;
+ i2c_address addr;
+
+ bus = RTC_Table[minor].ulCtrlPort1;
+ addr = RTC_Table[minor].ulDataPort;
+
+ /* Read SECONDS register */
+ try = 0;
+ do {
+ status = i2c_wbrd(bus, addr, 0, &sec, sizeof(sec));
+ try++;
+ } while ((status != I2C_SUCCESSFUL) && (try < 15));
+
+ /* If clock is halted, reset and start the clock */
+ if ((sec & DS1307_SECOND_HALT) != 0) {
+ uint8_t start[8];
+ memset(start, 0, sizeof(start));
+ start[0] = DS1307_SECOND;
+ try = 0;
+ do {
+ status = i2c_write(bus, addr, start, 2);
+ } while ((status != I2C_SUCCESSFUL) && (try < 15));
+ }
+}
+
+/* ds1307_get_time --
+ * read current time from DS1307 real-time clock chip and convert it
+ * to the rtems_time_of_day structure.
+ *
+ * PARAMETERS:
+ * minor -- minor RTC device number
+ * time -- place to put return value (date and time)
+ *
+ * RETURNS:
+ * 0, if time obtained successfully
+ * -1, if error occured
+ */
+static int ds1307_get_time(int minor, rtems_time_of_day *time)
+{
+ i2c_bus_number bus;
+ i2c_address addr;
+ uint8_t info[8];
+ uint32_t v1, v2;
+ i2c_message_status status;
+ int try;
+
+ if (time == NULL)
+ return -1;
+
+ bus = RTC_Table[minor].ulCtrlPort1;
+ addr = RTC_Table[minor].ulDataPort;
+
+ memset(time, 0, sizeof(rtems_time_of_day));
+ try = 0;
+ do {
+ status = i2c_wbrd(bus, addr, 0, info, sizeof(info));
+ try++;
+ } while ((status != I2C_SUCCESSFUL) && (try < 10));
+
+ if (status != I2C_SUCCESSFUL) {
+ return -1;
+ }
+
+ v1 = info[DS1307_YEAR];
+ v2 = From_BCD(v1);
+ if (v2 < 88)
+ time->year = 2000 + v2;
+ else
+ time->year = 1900 + v2;
+
+ v1 = info[DS1307_MONTH] & ~0xE0;
+ time->month = From_BCD(v1);
+
+ v1 = info[DS1307_DAY] & ~0xC0;
+ time->day = From_BCD(v1);
+
+ v1 = info[DS1307_HOUR];
+ if (v1 & DS1307_HOUR_12) {
+ v2 = v1 & ~0xE0;
+ if (v1 & DS1307_HOUR_PM) {
+ time->hour = From_BCD(v2) + 12;
+ } else {
+ time->hour = From_BCD(v2);
+ }
+ } else {
+ v2 = v1 & ~0xC0;
+ time->hour = From_BCD(v2);
+ }
+
+ v1 = info[DS1307_MINUTE] & ~0x80;
+ time->minute = From_BCD(v1);
+
+ v1 = info[DS1307_SECOND];
+ v2 = v1 & ~0x80;
+ time->second = From_BCD(v2);
+
+ return 0;
+}
+
+/* ds1307_set_time --
+ * set time to the DS1307 real-time clock chip
+ *
+ * PARAMETERS:
+ * minor -- minor RTC device number
+ * time -- new date and time to be written to DS1307
+ *
+ * RETURNS:
+ * 0, if time obtained successfully
+ * -1, if error occured
+ */
+static int ds1307_set_time(int minor, const rtems_time_of_day *time)
+{
+ i2c_bus_number bus;
+ i2c_address addr;
+ uint8_t info[8];
+ i2c_message_status status;
+ int try;
+
+ if (time == NULL)
+ return -1;
+
+ bus = RTC_Table[minor].ulCtrlPort1;
+ addr = RTC_Table[minor].ulDataPort;
+
+ if (time->year >= 2088)
+ rtems_fatal_error_occurred(RTEMS_INVALID_NUMBER);
+
+ info[0] = DS1307_SECOND;
+ info[1 + DS1307_YEAR] = To_BCD(time->year % 100);
+ info[1 + DS1307_MONTH] = To_BCD(time->month);
+ info[1 + DS1307_DAY] = To_BCD(time->day);
+ info[1 + DS1307_HOUR] = To_BCD(time->hour);
+ info[1 + DS1307_MINUTE] = To_BCD(time->minute);
+ info[1 + DS1307_SECOND] = To_BCD(time->second);
+ info[1 + DS1307_DAY_OF_WEEK] = 1; /* Do not set day of week */
+
+ try = 0;
+ do {
+ status = i2c_write(bus, addr, info, 8);
+ try++;
+ } while ((status != I2C_SUCCESSFUL) && (try < 10));
+
+ if (status != I2C_SUCCESSFUL)
+ return -1;
+ else
+ return 0;
+}
+
+/* Driver function table */
+
+rtc_fns ds1307_fns = {
+ ds1307_initialize,
+ ds1307_get_time,
+ ds1307_set_time
+};
diff --git a/bsps/m68k/mcf5206elite/rtc/todcfg.c b/bsps/m68k/mcf5206elite/rtc/todcfg.c
new file mode 100644
index 0000000000..aacb8575bd
--- /dev/null
+++ b/bsps/m68k/mcf5206elite/rtc/todcfg.c
@@ -0,0 +1,80 @@
+/*
+ * This file contains the RTC driver table for Motorola MCF5206eLITE
+ * ColdFire evaluation board.
+ *
+ * Copyright (C) 2000 OKTET Ltd., St.-Petersburg, Russia
+ * Author: Victor V. Vengerov <vvv@oktet.ru>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ *
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <i2c.h>
+#include <libchip/rtc.h>
+#include <ds1307.h>
+
+/* Forward function declaration */
+bool mcf5206elite_ds1307_probe(int minor);
+
+extern rtc_fns ds1307_fns;
+
+/* The following table configures the RTC drivers used in this BSP */
+rtc_tbl RTC_Table[] = {
+ {
+ "/dev/rtc", /* sDeviceName */
+ RTC_CUSTOM, /* deviceType */
+ &ds1307_fns, /* pDeviceFns */
+ mcf5206elite_ds1307_probe, /* deviceProbe */
+ NULL, /* pDeviceParams */
+ 0x00, /* ulCtrlPort1, for DS1307-I2C bus number */
+ DS1307_I2C_ADDRESS, /* ulDataPort, for DS1307-I2C device addr */
+ NULL, /* getRegister - not applicable to DS1307 */
+ NULL /* setRegister - not applicable to DS1307 */
+ }
+};
+
+/* Some information used by the RTC driver */
+
+#define NUM_RTCS (sizeof(RTC_Table)/sizeof(rtc_tbl))
+
+size_t RTC_Count = NUM_RTCS;
+
+/* mcf5206elite_ds1307_probe --
+ * RTC presence probe function. Return TRUE, if device is present.
+ * Device presence checked by probe access to RTC device over I2C bus.
+ *
+ * PARAMETERS:
+ * minor - minor RTC device number
+ *
+ * RETURNS:
+ * TRUE, if RTC device is present
+ */
+bool
+mcf5206elite_ds1307_probe(int minor)
+{
+ int try = 0;
+ i2c_message_status status;
+ rtc_tbl *rtc;
+ i2c_bus_number bus;
+ i2c_address addr;
+
+ if (minor >= NUM_RTCS)
+ return false;
+
+ rtc = RTC_Table + minor;
+
+ bus = rtc->ulCtrlPort1;
+ addr = rtc->ulDataPort;
+ do {
+ status = i2c_wrbyte(bus, addr, 0);
+ if (status == I2C_NO_DEVICE)
+ return false;
+ try++;
+ } while ((try < 15) && (status != I2C_SUCCESSFUL));
+ if (status == I2C_SUCCESSFUL)
+ return true;
+ else
+ return false;
+}
diff --git a/bsps/m68k/mvme162/rtc/tod.c b/bsps/m68k/mvme162/rtc/tod.c
new file mode 100644
index 0000000000..abd353d11b
--- /dev/null
+++ b/bsps/m68k/mvme162/rtc/tod.c
@@ -0,0 +1,88 @@
+/*
+ * Real Time Clock (MK48T08) for RTEMS on MVME162
+ *
+ * Author:
+ * COPYRIGHT (C) 1997
+ * by Katsutoshi Shibuya - BU Denken Co.,Ltd. - Sapporo - JAPAN
+ * ALL RIGHTS RESERVED
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ *
+ * This material is a part of the MVME162 Board Support Package
+ * for the RTEMS executive. Its licensing policies are those of the
+ * RTEMS above.
+ */
+
+#include <rtems.h>
+#include <rtems/tod.h>
+
+#define tod ((volatile unsigned char *)0xfffc1ff8)
+
+static int getTod(int n, unsigned char mask)
+{
+ unsigned char x;
+
+ x = tod[n]&mask;
+ return (x>>4)*10+(x&0x0f);
+}
+
+static void setTod(int n, unsigned char d)
+{
+ tod[n] = ((d/10)<<4)+(d%10);
+}
+
+void setRealTimeToRTEMS(void)
+{
+ rtems_time_of_day t;
+
+ tod[0] |= 0x40; /* Stop read register */
+ t.year = 1900+getTod(7,0xff);
+ t.month = getTod(6,0x1f);
+ t.day = getTod(5,0x3f);
+ t.hour = getTod(3,0x3f);
+ t.minute = getTod(2,0x7f);
+ t.second = getTod(1,0x7f);
+ t.ticks = 0;
+ tod[0] &= 0x3f; /* Release read register */
+
+ rtems_clock_set(&t);
+}
+
+void setRealTimeFromRTEMS()
+{
+ rtems_time_of_day t;
+
+ rtems_clock_get_tod(&t);
+ t.year -= 1900;
+
+ tod[0] |= 0x80; /* Stop write register */
+ setTod(7,t.year);
+ setTod(6,t.month);
+ setTod(5,t.day);
+ setTod(4,1); /* I don't know which day of week is */
+ setTod(3,t.hour);
+ setTod(2,t.minute);
+ setTod(1,t.second);
+ tod[0] &= 0x3f; /* Write these parameters */
+}
+
+int checkRealTime()
+{
+ rtems_time_of_day t;
+ int d;
+
+ tod[0] |= 0x40; /* Stop read register */
+ rtems_clock_get_tod(&t);
+ if((t.year != 1900+getTod(7,0xff))
+ || (t.month != getTod(6,0x1f))
+ || (t.day != getTod(5,0x3f)))
+ d = 9999;
+ else
+ d = (t.hour-getTod(3,0x3f))*3600
+ + (t.minute-getTod(3,0x7f))*60
+ + (t.second - getTod(1,0x7f));
+ tod[1] &= 0x3f;
+ return d;
+}
diff --git a/bsps/powerpc/beatnik/rtc/todcfg.c b/bsps/powerpc/beatnik/rtc/todcfg.c
new file mode 100644
index 0000000000..e8faccc840
--- /dev/null
+++ b/bsps/powerpc/beatnik/rtc/todcfg.c
@@ -0,0 +1,32 @@
+/*
+ * This file contains the RTC driver table for Motorola shared BSPs.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp.h>
+#include <libchip/rtc.h>
+#include <libchip/m48t08.h>
+
+/* The following table configures the RTC drivers used in this BSP */
+rtc_tbl RTC_Table[] = {
+ {
+ "/dev/rtc", /* sDeviceName */
+ RTC_M48T08, /* deviceType */
+ &m48t08_fns, /* pDeviceFns */
+ rtc_probe, /* deviceProbe */
+ NULL, /* pDeviceParams */
+ BSP_NVRAM_RTC_START, /* ulCtrlPort1 */
+ 0x00, /* ulDataPort */
+ m48t08_get_register, /* getRegister */
+ m48t08_set_register /* setRegister */
+ }
+};
+
+/* Some information used by the RTC driver */
+
+#define NUM_RTCS (sizeof(RTC_Table)/sizeof(rtc_tbl))
+
+size_t RTC_Count = NUM_RTCS;
diff --git a/bsps/powerpc/gen5200/rtc/pcf8563.c b/bsps/powerpc/gen5200/rtc/pcf8563.c
new file mode 100644
index 0000000000..e41e3b48d2
--- /dev/null
+++ b/bsps/powerpc/gen5200/rtc/pcf8563.c
@@ -0,0 +1,228 @@
+/*===============================================================*\
+| Project: RTEMS generic MPC5200 BSP |
++-----------------------------------------------------------------+
+| Partially based on the code references which are named below. |
+| Adaptions, modifications, enhancements and any recent parts of |
+| the code are: |
+| Copyright (c) 2005 |
+| Embedded Brains GmbH |
+| Obere Lagerstr. 30 |
+| D-82178 Puchheim |
+| Germany |
+| rtems@embedded-brains.de |
++-----------------------------------------------------------------+
+| The license and distribution terms for this file may be |
+| found in the file LICENSE in this distribution or at |
+| |
+| http://www.rtems.org/license/LICENSE. |
+| |
++-----------------------------------------------------------------+
+| this file contains the tod driver for a Philips pcf8563 I2C RTC |
+\*===============================================================*/
+/*
+ * This file interfaces with the real-time clock found in a
+ * Philips PCF8563 serial real-time clock chip.
+ * This RTC have I2C bus interface. BSP have to provide I2C bus primitives
+ * to make this driver working. getRegister and setRegister primitives is
+ * not used here to avoid multiple transactions over I2C bus (each transaction
+ * require significant time and error when date/time information red may
+ * occurs). ulControlPort contains I2C bus number; ulDataPort contains
+ * RTC I2C device address.
+ *
+ * Based on a ds1307 driver from:
+ *
+ * Copyright (C) 2000 OKTET Ltd., St.-Petersburg, Russia
+ * Author: Victor V. Vengerov <vvv@oktet.ru>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ *
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <rtems.h>
+#include <bsp/fatal.h>
+#include <bsp/i2c.h>
+#include <libchip/rtc.h>
+#include <string.h>
+#include "pcf8563.h"
+
+/* Convert from/to Binary-Coded Decimal representation */
+#define From_BCD( _x ) ((((_x) >> 4) * 10) + ((_x) & 0x0F))
+#define To_BCD( _x ) ((((_x) / 10) << 4) + ((_x) % 10))
+
+/* pcf8563_initialize --
+ * Initialize PCF8563 real-time clock chip. If RTC is halted, this
+ * function resume counting.
+ *
+ * PARAMETERS:
+ * minor -- minor RTC device number
+ */
+static void
+pcf8563_initialize(int minor)
+{
+ i2c_message_status status;
+ int try;
+ uint8_t ctrl1;
+ i2c_bus_number bus;
+ i2c_address addr;
+
+ bus = RTC_Table[minor].ulCtrlPort1;
+ addr = RTC_Table[minor].ulDataPort;
+
+ /* Read SECONDS register */
+ try = 0;
+ do {
+ status = i2c_wbrd(bus, addr, PCF8563_CONTROL1_ADR,
+ &ctrl1, sizeof(ctrl1));
+ try++;
+ } while ((status != I2C_SUCCESSFUL) && (try < 15));
+
+ /* If clock is halted, reset and start the clock */
+ if ((ctrl1 & PCF8563_CONTROL1_STOP) != 0)
+ {
+ uint8_t start[8];
+ memset(start, 0, sizeof(start));
+ start[0] = PCF8563_CONTROL1_ADR;
+ try = 0;
+ do {
+ status = i2c_write(bus, addr, start, 2);
+ } while ((status != I2C_SUCCESSFUL) && (try < 15));
+ }
+}
+
+/* pcf8563_get_time --
+ * read current time from PCF8563 real-time clock chip and convert it
+ * to the rtems_time_of_day structure.
+ *
+ * PARAMETERS:
+ * minor -- minor RTC device number
+ * time -- place to put return value (date and time)
+ *
+ * RETURNS:
+ * 0, if time obtained successfully
+ * -1, if error occured
+ */
+static int
+pcf8563_get_time(int minor, rtems_time_of_day *time)
+{
+ i2c_bus_number bus;
+ i2c_address addr;
+ uint8_t info[10];
+ uint32_t v1, v2;
+ i2c_message_status status;
+ int try;
+
+ if (time == NULL)
+ return -1;
+
+ bus = RTC_Table[minor].ulCtrlPort1;
+ addr = RTC_Table[minor].ulDataPort;
+
+ memset(time, 0, sizeof(rtems_time_of_day));
+ try = 0;
+ do {
+ status = i2c_wbrd(bus, addr, PCF8563_SECOND_ADR, info, sizeof(info));
+ try++;
+ } while ((status != I2C_SUCCESSFUL) && (try < 10));
+
+ if (status != I2C_SUCCESSFUL)
+ {
+ return -1;
+ }
+
+ v1 = info[PCF8563_YEAR_ADR-PCF8563_SECOND_ADR];
+ v2 = From_BCD(v1);
+ if ((info[PCF8563_MONTH_ADR-PCF8563_SECOND_ADR]
+ & PCF8563_MONTH_CENTURY) == 0) {
+ time->year = 1900 + v2;
+ }
+ else {
+ time->year = 2000 + v2;
+ }
+
+ v1 = info[PCF8563_MONTH_ADR-PCF8563_SECOND_ADR] & PCF8563_MONTH_MASK;
+ time->month = From_BCD(v1);
+
+ v1 = info[PCF8563_DAY_ADR-PCF8563_SECOND_ADR] & PCF8563_DAY_MASK;
+ time->day = From_BCD(v1);
+
+ v1 = info[PCF8563_HOUR_ADR-PCF8563_SECOND_ADR] & PCF8563_HOUR_MASK;
+ time->hour = From_BCD(v1);
+
+ v1 = info[PCF8563_MINUTE_ADR-PCF8563_SECOND_ADR] & PCF8563_MINUTE_MASK;
+ time->minute = From_BCD(v1);
+
+ v1 = info[PCF8563_SECOND_ADR-PCF8563_SECOND_ADR] & PCF8563_SECOND_MASK;
+ time->second = From_BCD(v1);
+
+ return 0;
+}
+
+/* pcf8563_set_time --
+ * set time to the PCF8563 real-time clock chip
+ *
+ * PARAMETERS:
+ * minor -- minor RTC device number
+ * time -- new date and time to be written to PCF8563
+ *
+ * RETURNS:
+ * 0, if time obtained successfully
+ * -1, if error occured
+ */
+static int
+pcf8563_set_time(int minor, const rtems_time_of_day *time)
+{
+ i2c_bus_number bus;
+ i2c_address addr;
+ uint8_t info[8];
+ i2c_message_status status;
+ int try;
+
+ if (time == NULL)
+ return -1;
+
+ bus = RTC_Table[minor].ulCtrlPort1;
+ addr = RTC_Table[minor].ulDataPort;
+
+ if ((time->year >= 2100) || (time->year < 1900)) {
+ bsp_fatal(MPC5200_FATAL_PCF8563_INVALID_YEAR);
+ }
+ info[0] = PCF8563_SECOND_ADR;
+ info[1 + PCF8563_YEAR_ADR -PCF8563_SECOND_ADR] = To_BCD(time->year % 100);
+ info[1 + PCF8563_MONTH_ADR -PCF8563_SECOND_ADR] = To_BCD(time->month);
+ info[1 + PCF8563_DAY_ADR -PCF8563_SECOND_ADR] = To_BCD(time->day);
+ info[1 + PCF8563_HOUR_ADR -PCF8563_SECOND_ADR] = To_BCD(time->hour);
+ info[1 + PCF8563_MINUTE_ADR-PCF8563_SECOND_ADR] = To_BCD(time->minute);
+ info[1 + PCF8563_SECOND_ADR-PCF8563_SECOND_ADR] = To_BCD(time->second);
+ /* Do not set day of week */
+ info[1 + PCF8563_DAY_OF_WEEK_ADR-PCF8563_SECOND_ADR] = 1;
+
+ /*
+ * add century info
+ */
+ if (time->year >= 2000) {
+ info[1 + PCF8563_MONTH_ADR -PCF8563_SECOND_ADR] |= PCF8563_MONTH_CENTURY;
+ }
+ /*
+ * send to device
+ */
+ try = 0;
+ do {
+ status = i2c_write(bus, addr, info,sizeof(info));
+ try++;
+ } while ((status != I2C_SUCCESSFUL) && (try < 10));
+
+ if (status != I2C_SUCCESSFUL)
+ return -1;
+ else
+ return 0;
+}
+
+/* Driver function table */
+
+rtc_fns pcf8563_fns = {
+ pcf8563_initialize,
+ pcf8563_get_time,
+ pcf8563_set_time
+};
diff --git a/bsps/powerpc/gen5200/rtc/pcf8563.h b/bsps/powerpc/gen5200/rtc/pcf8563.h
new file mode 100644
index 0000000000..f46b03e531
--- /dev/null
+++ b/bsps/powerpc/gen5200/rtc/pcf8563.h
@@ -0,0 +1,99 @@
+/*===============================================================*\
+| Project: RTEMS generic MPC5200 BSP |
++-----------------------------------------------------------------+
+| Partially based on the code references which are named below. |
+| Adaptions, modifications, enhancements and any recent parts of |
+| the code are: |
+| Copyright (c) 2005 |
+| Embedded Brains GmbH |
+| Obere Lagerstr. 30 |
+| D-82178 Puchheim |
+| Germany |
+| rtems@embedded-brains.de |
++-----------------------------------------------------------------+
+| The license and distribution terms for this file may be |
+| found in the file LICENSE in this distribution or at |
+| |
+| http://www.rtems.org/license/LICENSE. |
+| |
++-----------------------------------------------------------------+
+| this file contains declarations for the pcf8563 RTC driver |
+\*===============================================================*/
+/*
+ * This file contains the definitions for Dallas Semiconductor
+ * DS1307/DS1308 serial real-time clock/NVRAM.
+ *
+ * Copyright (C) 2000 OKTET Ltd., St.-Petersburg, Russia
+ * Author: Victor V. Vengerov <vvv@oktet.ru>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ *
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#ifndef __RTC_PCF8563__
+#define __RTC_PCF8563__
+
+#define PCF8563_I2C_ADDRESS (0xA2) /* I2C bus address assigned to PCF8563 */
+
+#define PCF8563_CONTROL1_ADR (0x00)
+#define PCF8563_CONTROL1_TEST1 (0x80) /* EXT_CLK test mode */
+#define PCF8563_CONTROL1_STOP (0x20) /* stop RTC source clock, clear divider*/
+#define PCF8563_CONTROL1_TESTC (0x08) /* enable power-on reset override */
+ /***********/
+#define PCF8563_CONTROL2_ADR (0x01)
+#define PCF8563_CONTROL2_TITP (0x10) /* 0: int output is level */
+#define PCF8563_CONTROL2_AF (0x08) /* alarm flag */
+#define PCF8563_CONTROL2_TF (0x04) /* timer flag */
+#define PCF8563_CONTROL2_AIE (0x02) /* alarm interrupt enable */
+#define PCF8563_CONTROL2_TIE (0x01) /* timer interrupt enable */
+ /***********/
+
+#define PCF8563_SECOND_ADR (0x02)
+#define PCF8563_SECOND_VL (0x80) /* clock integrity no longer guaranteed */
+#define PCF8563_SECOND_MASK (0x7f)
+ /***********/
+
+#define PCF8563_MINUTE_ADR (0x03)
+#define PCF8563_MINUTE_MASK (0x7f)
+ /***********/
+
+#define PCF8563_HOUR_ADR (0x04)
+#define PCF8563_HOUR_MASK (0x3f)
+ /***********/
+
+#define PCF8563_DAY_ADR (0x05)
+#define PCF8563_DAY_MASK (0x3f)
+
+#define PCF8563_DAY_OF_WEEK_ADR (0x06)
+#define PCF8563_DAY_OF_WEEK_MASK (0x07)
+
+#define PCF8563_MONTH_ADR (0x07)
+#define PCF8563_MONTH_MASK (0x1f)
+#define PCF8563_MONTH_CENTURY (0x80)
+ /***********/
+
+#define PCF8563_YEAR_ADR (0x08)
+#define PCF8563_YEAR_MASK (0xff)
+
+#define PCF8563_MINUTE_ALARM_ADR (0x09)
+#define PCF8563_HOUR_ALARM_ADR (0x0A)
+#define PCF8563_DAY_ALARM_ADR (0x0B)
+#define PCF8563_DAY_OF_WEEK_ALARM_ADR (0x0C)
+#define PCF8563_XXX_ALARM_AE (0x80)
+ /***********/
+
+#define PCF8563_CLKOUTCTL_ADR (0x0D)
+#define PCF8563_CLKOUTCTL_FE (0x80) /* */
+#define PCF8563_CLKOUTCTL_FD (0x03) /* */
+ /***********/
+
+#define PCF8563_TIMERCTL_ADR (0x0E)
+#define PCF8563_TIMERCTL_FE (0x80) /* */
+#define PCF8563_TIMERCTL_FD (0x03) /* */
+ /***********/
+
+#define PCF8563_TIMER_ADR (0x0F)
+
+#endif /* __RTC_PCF8563__ */
diff --git a/bsps/powerpc/gen5200/rtc/todcfg.c b/bsps/powerpc/gen5200/rtc/todcfg.c
new file mode 100644
index 0000000000..076de70b28
--- /dev/null
+++ b/bsps/powerpc/gen5200/rtc/todcfg.c
@@ -0,0 +1,102 @@
+/*===============================================================*\
+| Project: RTEMS generic MPC5200 BSP |
++-----------------------------------------------------------------+
+| Partially based on the code references which are named below. |
+| Adaptions, modifications, enhancements and any recent parts of |
+| the code are: |
+| Copyright (c) 2005 |
+| Embedded Brains GmbH |
+| Obere Lagerstr. 30 |
+| D-82178 Puchheim |
+| Germany |
+| rtems@embedded-brains.de |
++-----------------------------------------------------------------+
+| The license and distribution terms for this file may be |
+| found in the file LICENSE in this distribution or at |
+| |
+| http://www.rtems.org/license/LICENSE. |
+| |
++-----------------------------------------------------------------+
+| this file configures the pcf8563 RTC for a PM520 board |
+\*===============================================================*/
+/*
+ * This file contains the RTC driver table for Motorola MCF5206eLITE
+ * ColdFire evaluation board.
+ *
+ * Copyright (C) 2000 OKTET Ltd., St.-Petersburg, Russia
+ * Author: Victor V. Vengerov <vvv@oktet.ru>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ *
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp.h>
+#include <bsp/i2c.h>
+#include <libchip/rtc.h>
+#include "pcf8563.h"
+
+/* Forward function declaration */
+bool mpc5200_pcf8563_probe(int minor);
+
+extern rtc_fns pcf8563_fns;
+
+/* The following table configures the RTC drivers used in this BSP */
+rtc_tbl RTC_Table[] = {
+ {
+ "/dev/rtc", /* sDeviceName */
+ RTC_CUSTOM, /* deviceType */
+ &pcf8563_fns, /* pDeviceFns */
+ mpc5200_pcf8563_probe, /* deviceProbe */
+ NULL, /* pDeviceParams */
+ 0x01, /* ulCtrlPort1, for PCF8563-I2C bus number */
+ PCF8563_I2C_ADDRESS, /* ulDataPort, for PCF8563-I2C device addr */
+ NULL, /* getRegister - not applicable to PCF8563 */
+ NULL /* setRegister - not applicable to PCF8563 */
+ }
+};
+
+/* Some information used by the RTC driver */
+
+#define NUM_RTCS (sizeof(RTC_Table)/sizeof(rtc_tbl))
+
+size_t RTC_Count = NUM_RTCS;
+
+/* mpc5200_pcf8563_probe --
+ * RTC presence probe function. Return TRUE, if device is present.
+ * Device presence checked by probe access to RTC device over I2C bus.
+ *
+ * PARAMETERS:
+ * minor - minor RTC device number
+ *
+ * RETURNS:
+ * TRUE, if RTC device is present
+ */
+bool
+mpc5200_pcf8563_probe(int minor)
+{
+ int try = 0;
+ i2c_message_status status;
+ rtc_tbl *rtc;
+ i2c_bus_number bus;
+ i2c_address addr;
+
+ if (minor >= NUM_RTCS)
+ return false;
+
+ rtc = RTC_Table + minor;
+
+ bus = rtc->ulCtrlPort1;
+ addr = rtc->ulDataPort;
+ do {
+ status = i2c_wrbyte(bus, addr, 0);
+ if (status == I2C_NO_DEVICE)
+ return false;
+ try++;
+ } while ((try < 15) && (status != I2C_SUCCESSFUL));
+ if (status == I2C_SUCCESSFUL)
+ return true;
+ else
+ return false;
+}
diff --git a/bsps/powerpc/mvme3100/rtc/todcfg.c b/bsps/powerpc/mvme3100/rtc/todcfg.c
new file mode 100644
index 0000000000..939bea0258
--- /dev/null
+++ b/bsps/powerpc/mvme3100/rtc/todcfg.c
@@ -0,0 +1,24 @@
+/*
+ * This file contains the RTC driver table for the MVME3100 BSP
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ *
+ * Modified for mvme3100 by T. Straumann, 2007
+ */
+
+#include <bsp.h>
+#include <libchip/rtc.h>
+#include <libchip/ds1375-rtc.h>
+
+/* The following table configures the RTC drivers used in this BSP */
+rtc_tbl RTC_Table[] = {
+ DS1375_RTC_TBL_ENTRY(BSP_I2C_DS1375_RAW_DEV_NAME),
+};
+
+/* Some information used by the RTC driver */
+
+#define NUM_RTCS (sizeof(RTC_Table)/sizeof(rtc_tbl))
+
+size_t RTC_Count = NUM_RTCS;
diff --git a/bsps/powerpc/mvme5500/rtc/todcfg.c b/bsps/powerpc/mvme5500/rtc/todcfg.c
new file mode 100644
index 0000000000..39089db710
--- /dev/null
+++ b/bsps/powerpc/mvme5500/rtc/todcfg.c
@@ -0,0 +1,32 @@
+/*
+ * This file contains the RTC driver table for Motorola shared BSPs.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp.h>
+#include <libchip/rtc.h>
+#include <libchip/m48t08.h>
+
+/* The following table configures the RTC drivers used in this BSP */
+rtc_tbl RTC_Table[] = {
+ {
+ "/dev/rtc", /* sDeviceName */
+ RTC_M48T08, /* deviceType */
+ &m48t08_fns, /* pDeviceFns */
+ rtc_probe, /* deviceProbe */
+ NULL, /* pDeviceParams */
+ 0xF1117FF8, /* ulCtrlPort1 */
+ 0x00, /* ulDataPort */
+ m48t08_get_register, /* getRegister */
+ m48t08_set_register /* setRegister */
+ }
+};
+
+/* Some information used by the RTC driver */
+
+#define NUM_RTCS (sizeof(RTC_Table)/sizeof(rtc_tbl))
+
+size_t RTC_Count = NUM_RTCS;
diff --git a/bsps/powerpc/qoriq/rtc/rtc-config.c b/bsps/powerpc/qoriq/rtc/rtc-config.c
new file mode 100644
index 0000000000..c3e39e0830
--- /dev/null
+++ b/bsps/powerpc/qoriq/rtc/rtc-config.c
@@ -0,0 +1,67 @@
+/**
+ * @file
+ *
+ * @ingroup QorIQ
+ *
+ * @brief RTC configuration.
+ */
+
+/*
+ * Copyright (c) 2010 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Obere Lagerstr. 30
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <libchip/rtc.h>
+
+#define RTC_COUNT 1
+
+static void qoriq_rtc_initialize(int minor)
+{
+ /* FIXME */
+}
+
+static int qoriq_rtc_get_time(int minor, rtems_time_of_day *tod)
+{
+ return -1;
+}
+
+static int qoriq_rtc_set_time(int minor, const rtems_time_of_day *tod)
+{
+ return -1;
+}
+
+static bool qoriq_rtc_probe(int minor)
+{
+ return false;
+}
+
+const rtc_fns qoriq_rtc_ops = {
+ .deviceInitialize = qoriq_rtc_initialize,
+ .deviceGetTime = qoriq_rtc_get_time,
+ .deviceSetTime = qoriq_rtc_set_time
+};
+
+size_t RTC_Count = RTC_COUNT;
+
+rtc_tbl RTC_Table [RTC_COUNT] = {
+ {
+ .sDeviceName = "/dev/rtc",
+ .deviceType = RTC_CUSTOM,
+ .pDeviceFns = &qoriq_rtc_ops,
+ .deviceProbe = qoriq_rtc_probe,
+ .pDeviceParams = NULL,
+ .ulCtrlPort1 = 0,
+ .ulDataPort = 0,
+ .getRegister = NULL,
+ .setRegister = NULL
+ }
+};
diff --git a/bsps/powerpc/shared/rtc/todcfg.c b/bsps/powerpc/shared/rtc/todcfg.c
new file mode 100644
index 0000000000..17ef18d5b5
--- /dev/null
+++ b/bsps/powerpc/shared/rtc/todcfg.c
@@ -0,0 +1,66 @@
+/*
+ * This file contains the RTC driver table for Motorola shared BSPs.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp.h>
+#include <libchip/rtc.h>
+#include <libchip/m48t08.h>
+
+/* Forward function declaration */
+#if !defined(mvme2100)
+uint32_t mvmertc_get_register( uintptr_t, uint8_t );
+void mvmertc_set_register( uintptr_t, uint8_t, uint32_t );
+#endif
+
+/* The following table configures the RTC drivers used in this BSP */
+rtc_tbl RTC_Table[] = {
+ {
+ "/dev/rtc", /* sDeviceName */
+ RTC_M48T08, /* deviceType -- actually M48T59 */
+ &m48t08_fns, /* pDeviceFns */
+ rtc_probe, /* deviceProbe */
+ NULL, /* pDeviceParams */
+#if defined(mvme2100)
+ 0xFFE81ff8, /* ulCtrlPort1 */
+ 0x00, /* ulDataPort */
+ m48t08_get_register, /* getRegister */
+ m48t08_set_register /* setRegister */
+#else
+ 0xFFE81ff8, /* ulCtrlPort1 */
+ 0x00, /* ulDataPort */
+ mvmertc_get_register, /* getRegister */
+ mvmertc_set_register /* setRegister */
+#endif
+ }
+};
+
+/* Some information used by the RTC driver */
+
+#define NUM_RTCS (sizeof(RTC_Table)/sizeof(rtc_tbl))
+
+size_t RTC_Count = NUM_RTCS;
+
+#if !defined(mvme2100)
+#include <rtems/bspIo.h>
+void mvmertc_set_register(
+ uintptr_t base,
+ uint8_t reg,
+ uint32_t value
+)
+{
+ printk( "RTC SUPPORT NOT IMPLEMENTED ON THIS BOARD\n");
+}
+
+uint32_t mvmertc_get_register(
+ uintptr_t base,
+ uint8_t reg
+)
+{
+ printk( "RTC SUPPORT NOT IMPLEMENTED ON THIS BOARD\n");
+ return 0;
+}
+#endif