lin
2025-08-21 57113df3a0e2be01232281fad9a5f2c060567981
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
/*
 * Some macro and struct of SUNXI RTC.
 *
 * Copyright (C) 2016 Allwinner.
 *
 * Matteo <duanmintao@allwinnertech.com>
 *
 * This file is licensed under the terms of the GNU General Public
 * License version 2.  This program is licensed "as is" without any
 * warranty of any kind, whether express or implied.
 */
 
#ifndef _RTC_SUNXI_H_
#define _RTC_SUNXI_H_
 
#define SUNXI_LOSC_CTRL                0x0000
#define SUNXI_LOSC_CTRL_RTC_ALARM_ACC        BIT(9)
#define SUNXI_LOSC_CTRL_RTC_HMS_ACC        BIT(8)
#define SUNXI_LOSC_CTRL_RTC_YMD_ACC        BIT(7)
#define REG_LOSCCTRL_MAGIC            0x16aa0000
#define REG_CLK32K_AUTO_SWT_EN            BIT(14)
#define REG_CLK32K_AUTO_SWT_BYPASS        BIT(15)
#define RTC_SOURCE_EXTERNAL            0x00000001
#define EXT_LOSC_GSM                0x00000008
#define SUNXI_ALARM_CONFIG                      0x0050
#define SUNXI_ALRM_WAKEUP_OUTPUT_EN             BIT(0)
 
/* alarm0 which based on seconds can power on system,
 * while alarm1 can't, so alarm1 is not used.
 */
/* #define SUNXI_ALARM1_USED */
#if (defined CONFIG_ARCH_SUN8IW16) \
   || (defined CONFIG_ARCH_SUN50IW9) \
   || (defined CONFIG_ARCH_SUN50IW10)
#define SUNXI_SIMPLIFIED_TIMER
#endif
 
#if defined CONFIG_ARCH_SUN8IW15 || (defined CONFIG_ARCH_SUN50IW9)
#define SUNXI_RTC_CALI_REG        0x0c
#define REG_CLK32K_CALI_FUNC_EN        BIT(0)
#define REG_CLK32K_CALI_EN        BIT(1)
#define SUNXI_RTC_XO_CTRL        0x160
#define REG_DC_XO_EN            BIT(1)
#define SUNXI_RTC_VDD_REG        0x190
#define REG_V_SEL            BIT(4)
#endif    /*end of CONFIG_ARCH_SUN8IW15 || CONFIG_ARCH_SUN50IW9 */
 
#if (defined CONFIG_ARCH_SUN8IW7) || (defined CONFIG_ARCH_SUN8IW11) \
               || (defined CONFIG_ARCH_SUN8IW12) \
               || (defined CONFIG_ARCH_SUN8IW15) \
               || (defined CONFIG_ARCH_SUN8IW16) \
               || (defined CONFIG_ARCH_SUN8IW17) \
               || (defined CONFIG_ARCH_SUN50IW1) \
               || (defined CONFIG_ARCH_SUN50IW3) \
               || (defined CONFIG_ARCH_SUN50IW6) \
               || (defined CONFIG_ARCH_SUN50IW8) \
               || (defined CONFIG_ARCH_SUN50IW9) \
               || (defined CONFIG_ARCH_SUN50IW10)
#define SUNXI_RTC_YMD                0x0010
 
#define SUNXI_RTC_HMS                0x0014
 
#ifdef SUNXI_ALARM1_USED
 
#define SUNXI_ALRM_DHMS                0x0040
 
#define SUNXI_ALRM_EN                0x0044
#define SUNXI_ALRM_EN_CNT_EN            BIT(8)
 
#define SUNXI_ALRM_IRQ_EN            0x0048
#define SUNXI_ALRM_IRQ_EN_CNT_IRQ_EN        BIT(0)
 
#define SUNXI_ALRM_IRQ_STA            0x004c
#define SUNXI_ALRM_IRQ_STA_CNT_IRQ_PEND        BIT(0)
 
#else
 
#define SUNXI_ALRM_DAY                0X0020
#define SUNXI_ALRM_COUNTER                      0x0020
#define SUNXI_ALRM_CURRENT                      0x0024
#define SUNXI_ALRM_HMS                0X0024
 
#define SUNXI_ALRM_EN                           0x0028
#define SUNXI_ALRM_EN_CNT_EN                    BIT(0)
 
#define SUNXI_ALRM_IRQ_EN                       0x002c
#define SUNXI_ALRM_IRQ_EN_CNT_IRQ_EN            BIT(0)
 
#define SUNXI_ALRM_IRQ_STA                      0x0030
#define SUNXI_ALRM_IRQ_STA_CNT_IRQ_PEND         BIT(0)
 
#endif /* end of SUNXI_ALARM1_USED */
 
#else
 
#define SUNXI_RTC_YMD                0x0004
 
#define SUNXI_RTC_HMS                0x0008
 
#define SUNXI_ALRM_DHMS                0x000c
 
#define SUNXI_ALRM_EN                0x0014
#define SUNXI_ALRM_EN_CNT_EN            BIT(8)
 
#define SUNXI_ALRM_IRQ_EN            0x0018
#define SUNXI_ALRM_IRQ_EN_CNT_IRQ_EN        BIT(0)
 
#define SUNXI_ALRM_IRQ_STA            0x001c
#define SUNXI_ALRM_IRQ_STA_CNT_IRQ_PEND        BIT(0)
 
#endif
 
/* debug */
#define SUNXI_DEBUG_MODE_FLAG           (0x59)
/* efex */
#define SUNXI_EFEX_CMD_FLAG             (0x5A)
/* boot-resignature */
#define SUNXI_BOOT_RESIGNATURE_FLAG     (0x5B)
/* recovery or boot-recovery */
#define SUNXI_BOOT_RECOVERY_FLAG        (0x5C)
/* sysrecovery */
#define SUNXI_SYS_RECOVERY_FLAG         (0x5D)
/* usb-recovery*/
#define SUNXI_USB_RECOVERY_FLAG         (0x5E)
/* bootloader */
#define SUNXI_FASTBOOT_FLAG             (0x5F)
/* uboot */
#define SUNXI_UBOOT_FLAG                (0x60)
 
#if defined(CONFIG_ARCH_SUN8IW12)
#define SUNXI_RTC_COMP_CTRL 0x11b0
#define SUNXI_COMP_ENABLE BIT(31)
#define SUNXI_ADC_VDD_ON_DISABLE  BIT(29)
#endif
 
#define SUNXI_MASK_DH                0x0000001f
#define SUNXI_MASK_SM                0x0000003f
#define SUNXI_MASK_M                0x0000000f
#define SUNXI_MASK_LY                0x00000001
#define SUNXI_MASK_D                0x00000ffe
 
#define SUNXI_GET(x, mask, shift)        (((x) & ((mask) << (shift))) \
                           >> (shift))
 
#define SUNXI_SET(x, mask, shift)        (((x) & (mask)) << (shift))
 
/*
 * Get date values
 */
#define SUNXI_DATE_GET_DAY_VALUE(x)        SUNXI_GET(x, SUNXI_MASK_DH, 0)
#define SUNXI_DATE_GET_MON_VALUE(x)        SUNXI_GET(x, SUNXI_MASK_M, 8)
#define SUNXI_DATE_GET_YEAR_VALUE(x, d)    SUNXI_GET(x, (d)->mask, (d)->yshift)
 
/*
 * Get time values
 */
#define SUNXI_TIME_GET_SEC_VALUE(x)        SUNXI_GET(x, SUNXI_MASK_SM, 0)
#define SUNXI_TIME_GET_MIN_VALUE(x)        SUNXI_GET(x, SUNXI_MASK_SM, 8)
#define SUNXI_TIME_GET_HOUR_VALUE(x)    SUNXI_GET(x, SUNXI_MASK_DH, 16)
 
/*
 * Get alarm values
 */
#define SUNXI_ALRM_GET_SEC_VALUE(x)        SUNXI_GET(x, SUNXI_MASK_SM, 0)
#define SUNXI_ALRM_GET_MIN_VALUE(x)        SUNXI_GET(x, SUNXI_MASK_SM, 8)
#define SUNXI_ALRM_GET_HOUR_VALUE(x)    SUNXI_GET(x, SUNXI_MASK_DH, 16)
 
/*
 * Set date values
 */
#define SUNXI_DATE_SET_DAY_VALUE(x)        SUNXI_DATE_GET_DAY_VALUE(x)
#define SUNXI_DATE_SET_MON_VALUE(x)        SUNXI_SET(x, SUNXI_MASK_M, 8)
#define SUNXI_DATE_SET_YEAR_VALUE(x, d)    SUNXI_SET(x, (d)->mask, (d)->yshift)
#define SUNXI_LEAP_SET_VALUE(x, shift)    SUNXI_SET(x, SUNXI_MASK_LY, shift)
 
/*
 * Set time values
 */
#define SUNXI_TIME_SET_SEC_VALUE(x)        SUNXI_TIME_GET_SEC_VALUE(x)
#define SUNXI_TIME_SET_MIN_VALUE(x)        SUNXI_SET(x, SUNXI_MASK_SM, 8)
#define SUNXI_TIME_SET_HOUR_VALUE(x)    SUNXI_SET(x, SUNXI_MASK_DH, 16)
 
/*
 * Set alarm values
 */
#define SUNXI_ALRM_SET_SEC_VALUE(x)        SUNXI_ALRM_GET_SEC_VALUE(x)
#define SUNXI_ALRM_SET_MIN_VALUE(x)        SUNXI_SET(x, SUNXI_MASK_SM, 8)
#define SUNXI_ALRM_SET_HOUR_VALUE(x)    SUNXI_SET(x, SUNXI_MASK_DH, 16)
#define SUNXI_ALRM_SET_DAY_VALUE(x)        SUNXI_SET(x, SUNXI_MASK_D, 21)
 
/*
 * Time unit conversions
 */
#define SEC_IN_MIN                60
#define SEC_IN_HOUR                (60 * SEC_IN_MIN)
#define SEC_IN_DAY                (24 * SEC_IN_HOUR)
 
/*
 * The year parameter passed to the driver is usually an offset relative to
 * the year 1900. This macro is used to convert this offset to another one
 * relative to the minimum year allowed by the hardware.
 */
#define SUNXI_YEAR_OFF(x)            ((x)->min - 1900)
 
/*
 * min and max year are arbitrary set considering the limited range of the
 * hardware register field
 */
struct sunxi_rtc_data_year {
   unsigned int min;        /* min year allowed */
   unsigned int max;        /* max year allowed */
   unsigned int mask;        /* mask for the year field */
   unsigned int yshift;        /* bit shift to get the year */
   unsigned char leap_shift;    /* bit shift to get the leap year */
};
 
struct sunxi_rtc_dev {
   struct rtc_device *rtc;
   struct device *dev;
   struct sunxi_rtc_data_year *data_year;
   void __iomem *base;
   int irq;
};
 
#endif /* end of _RTC_SUNXI_H_ */