Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:05

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @ingroup shared_tod_abeoz9_rtc
0007  *
0008  * @brief This file provides the interfaces of @ref shared_tod_abeoz9_rtc.
0009  */
0010 
0011 /*
0012  * Copyright (C) 2024 embedded brains GmbH & Co. KG
0013  *
0014  * Redistribution and use in source and binary forms, with or without
0015  * modification, are permitted provided that the following conditions
0016  * are met:
0017  * 1. Redistributions of source code must retain the above copyright
0018  *    notice, this list of conditions and the following disclaimer.
0019  * 2. Redistributions in binary form must reproduce the above copyright
0020  *    notice, this list of conditions and the following disclaimer in the
0021  *    documentation and/or other materials provided with the distribution.
0022  *
0023  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0024  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0025  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0026  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0027  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0028  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0029  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0030  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0031  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0032  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0033  * POSSIBILITY OF SUCH DAMAGE.
0034  */
0035 
0036 #include <dev/i2c/i2c.h>
0037 #include <libchip/abeoz9-rtc.h>
0038 
0039 #include <stdint.h>
0040 
0041 #define REG_ABEOZ9_CONTROL_1 0x00u
0042 
0043 #define ABEOZ9_CONTROL_1_WE     (0x1u << 0)
0044 #define ABEOZ9_CONTROL_1_TE     (0x1u << 1)
0045 #define ABEOZ9_CONTROL_1_TAR    (0x1u << 2)
0046 #define ABEOZ9_CONTROL_1_EERE   (0x1u << 3)
0047 #define ABEOZ9_CONTROL_1_SROn   (0x1u << 4)
0048 #define ABEOZ9_CONTROL_1_TD0    (0x1u << 5)
0049 #define ABEOZ9_CONTROL_1_TD1    (0x1u << 6)
0050 #define ABEOZ9_CONTROL_1_ClkInt (0x1u << 7)
0051 
0052 #define REG_ABEOZ9_CONTROL_INT 0x01u
0053 
0054 #define ABEOZ9_CONTROL_INT_AIE  (0x1u << 0)
0055 #define ABEOZ9_CONTROL_INT_TIE  (0x1u << 1)
0056 #define ABEOZ9_CONTROL_INT_V1IE (0x1u << 2)
0057 #define ABEOZ9_CONTROL_INT_V2IE (0x1u << 3)
0058 #define ABEOZ9_CONTROL_INT_SRIE (0x1u << 4)
0059 
0060 #define REG_ABEOZ9_CONTROL_INT_FLAG 0x02u
0061 
0062 #define ABEOZ9_CONTROL_INT_FLAG_AF   (0x1u << 0)
0063 #define ABEOZ9_CONTROL_INT_FLAG_TF   (0x1u << 1)
0064 #define ABEOZ9_CONTROL_INT_FLAG_V1IF (0x1u << 2)
0065 #define ABEOZ9_CONTROL_INT_FLAG_V2IF (0x1u << 3)
0066 #define ABEOZ9_CONTROL_INT_FLAG_SRF  (0x1u << 4)
0067 
0068 #define REG_ABEOZ9_CONTROL_STATUS 0x03u
0069 
0070 #define ABEOZ9_CONTROL_STATUS_V1F    (0x1u << 2)
0071 #define ABEOZ9_CONTROL_STATUS_V2F    (0x1u << 3)
0072 #define ABEOZ9_CONTROL_STATUS_SR     (0x1u << 4)
0073 #define ABEOZ9_CONTROL_STATUS_PON    (0x1u << 5)
0074 #define ABEOZ9_CONTROL_STATUS_EEBusy (0x1u << 7)
0075 
0076 #define REG_ABEOZ9_CONTROL_RESET 0x04u
0077 
0078 #define ABEOZ9_CONTROL_RESET_SysR (0x1u << 1)
0079 
0080 #define REG_ABEOZ9_CLOCK_SEC 0x08u
0081 #define REG_ABEOZ9_CLOCK_MIN 0x09u
0082 #define REG_ABEOZ9_CLOCK_HOUR 0x0au
0083 #define REG_ABEOZ9_CLOCK_WKDAY 0x0bu
0084 #define REG_ABEOZ9_CLOCK_DATE 0x0cu
0085 #define REG_ABEOZ9_CLOCK_MTH 0x0du
0086 #define REG_ABEOZ9_CLOCK_YEAR 0x0eu
0087 #define CLOCK_LEN (REG_ABEOZ9_CLOCK_YEAR + 1 - REG_ABEOZ9_CLOCK_SEC)
0088 
0089 #define REG_ABEOZ9_ALARM_SEC 0x10u
0090 #define REG_ABEOZ9_ALARM_MIN 0x11u
0091 #define REG_ABEOZ9_ALARM_HOUR 0x12u
0092 #define REG_ABEOZ9_ALARM_WKDAY 0x13u
0093 #define REG_ABEOZ9_ALARM_DATE 0x14u
0094 #define REG_ABEOZ9_ALARM_MTH 0x15u
0095 #define REG_ABEOZ9_ALARM_YEAR 0x16u
0096 #define ALARM_LEN (REG_ABEOZ9_ALARM_YEAR + 1 - REG_ABEOZ9_ALARM_SEC)
0097 
0098 int abeoz9_rtc_hw_init(struct i2c_rtc_base *base)
0099 {
0100   uint8_t reg;
0101   ssize_t rv;
0102   struct abeoz9_rtc *ctx =
0103       RTEMS_CONTAINER_OF(base, struct abeoz9_rtc, base);
0104 
0105   /*
0106    * Check PON bit. If that is set, we are starting with an uninitialized chip.
0107    */
0108   rv = i2c_rtc_read(&ctx->base, REG_ABEOZ9_CONTROL_STATUS, &reg, 1);
0109   if (rv == 0) {
0110     if ((reg & (ABEOZ9_CONTROL_STATUS_PON | ABEOZ9_CONTROL_STATUS_SR)) != 0) {
0111       /*
0112        * First power up after a reset or a self recovery reset. Init state is
0113        * like follows (from the data sheet):
0114        *
0115        * - CLKOUT is selected at CLKOUT pin, default frequency is 32.768 kHz
0116        *   defined in register EEPROM Control
0117        * - Timer and Timer Auto-Reload mode are disabled; Timer Source Clock
0118        *   frequency is set to 32Hz
0119        * - Self Recovery function is enabled
0120        * - Automatic EEPROM Refresh every hour is enabled
0121        * - 24 hour mode is selected, no Alarm is set
0122        * - All Interrupts are disabled
0123        * - At Power-On Reset, "PON" Flag is set = "1" and has to be cleared by
0124        *   writing = "0"
0125        * - At Self-Recovery Reset or System Reset, "SR" Flag is set = "1" and
0126        *   has to be cleared by writing = "0".
0127        * - Values in the clock page are undefined.
0128        *
0129        * That's a quite sensible default. Only a well defined value for the time
0130        * and the PON / SR flags have to be set.
0131        */
0132       uint8_t clock[CLOCK_LEN] = {0, 0, 0, 1, 1, 1, 1};
0133 
0134       rv = i2c_rtc_write(&ctx->base, REG_ABEOZ9_CLOCK_SEC, clock, CLOCK_LEN);
0135 
0136       if (rv == 0) {
0137         reg &= ~(ABEOZ9_CONTROL_STATUS_PON | ABEOZ9_CONTROL_STATUS_SR);
0138         rv = i2c_rtc_write(&ctx->base, REG_ABEOZ9_CONTROL_STATUS, &reg, 1);
0139       }
0140     } else {
0141       /*
0142        * RTC already active. Disable all alarms and similar functionality.
0143        * Otherwise leave it in default state.
0144        */
0145       uint8_t alarm[ALARM_LEN] = {0, 0, 0, 0, 0, 0, 0};
0146 
0147       reg = 0;
0148       rv = i2c_rtc_write(&ctx->base, REG_ABEOZ9_CONTROL_INT, &reg, 1);
0149 
0150       reg = 0;
0151       rv = i2c_rtc_write(&ctx->base, REG_ABEOZ9_ALARM_SEC, alarm, ALARM_LEN);
0152     }
0153   }
0154 
0155   return rv;
0156 }