1 /*
2  * Copyright (c) 2021 Laird Connectivity
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef ZEPHYR_INCLUDE_DRIVERS_RTC_MCP7940N_H_
8 #define ZEPHYR_INCLUDE_DRIVERS_RTC_MCP7940N_H_
9 
10 #include <zephyr/sys/timeutil.h>
11 #include <time.h>
12 
13 struct mcp7940n_rtc_sec {
14 	uint8_t sec_one : 4;
15 	uint8_t sec_ten : 3;
16 	uint8_t start_osc : 1;
17 } __packed;
18 
19 struct mcp7940n_rtc_min {
20 	uint8_t min_one : 4;
21 	uint8_t min_ten : 3;
22 	uint8_t nimp : 1;
23 } __packed;
24 
25 struct mcp7940n_rtc_hours {
26 	uint8_t hr_one : 4;
27 	uint8_t hr_ten : 2;
28 	uint8_t twelve_hr : 1;
29 	uint8_t nimp : 1;
30 } __packed;
31 
32 struct mcp7940n_rtc_weekday {
33 	uint8_t weekday : 3;
34 	uint8_t vbaten : 1;
35 	uint8_t pwrfail : 1;
36 	uint8_t oscrun : 1;
37 	uint8_t nimp : 2;
38 } __packed;
39 
40 struct mcp7940n_rtc_date {
41 	uint8_t date_one : 4;
42 	uint8_t date_ten : 2;
43 	uint8_t nimp : 2;
44 } __packed;
45 
46 struct mcp7940n_rtc_month {
47 	uint8_t month_one : 4;
48 	uint8_t month_ten : 1;
49 	uint8_t lpyr : 1;
50 	uint8_t nimp : 2;
51 } __packed;
52 
53 struct mcp7940n_rtc_year {
54 	uint8_t year_one : 4;
55 	uint8_t year_ten : 4;
56 } __packed;
57 
58 struct mcp7940n_rtc_control {
59 	uint8_t sqwfs : 2;
60 	uint8_t crs_trim : 1;
61 	uint8_t ext_osc : 1;
62 	uint8_t alm0_en : 1;
63 	uint8_t alm1_en : 1;
64 	uint8_t sqw_en : 1;
65 	uint8_t out : 1;
66 } __packed;
67 
68 struct mcp7940n_rtc_osctrim {
69 	uint8_t trim_val : 7;
70 	uint8_t sign : 1;
71 } __packed;
72 
73 struct mcp7940n_alm_sec {
74 	uint8_t sec_one : 4;
75 	uint8_t sec_ten : 3;
76 	uint8_t nimp : 1;
77 } __packed;
78 
79 struct mcp7940n_alm_min {
80 	uint8_t min_one : 4;
81 	uint8_t min_ten : 3;
82 	uint8_t nimp : 1;
83 } __packed;
84 
85 struct mcp7940n_alm_hours {
86 	uint8_t hr_one : 4;
87 	uint8_t hr_ten : 2;
88 	uint8_t twelve_hr : 1;
89 	uint8_t nimp : 1;
90 } __packed;
91 
92 struct mcp7940n_alm_weekday {
93 	uint8_t weekday : 3;
94 	uint8_t alm_if : 1;
95 	uint8_t alm_msk : 3;
96 	uint8_t alm_pol : 1;
97 } __packed;
98 
99 struct mcp7940n_alm_date {
100 	uint8_t date_one : 4;
101 	uint8_t date_ten : 2;
102 	uint8_t nimp : 2;
103 } __packed;
104 
105 struct mcp7940n_alm_month {
106 	uint8_t month_one : 4;
107 	uint8_t month_ten : 1;
108 	uint8_t nimp : 3;
109 } __packed;
110 
111 struct mcp7940n_time_registers {
112 	struct mcp7940n_rtc_sec rtc_sec;
113 	struct mcp7940n_rtc_min rtc_min;
114 	struct mcp7940n_rtc_hours rtc_hours;
115 	struct mcp7940n_rtc_weekday rtc_weekday;
116 	struct mcp7940n_rtc_date rtc_date;
117 	struct mcp7940n_rtc_month rtc_month;
118 	struct mcp7940n_rtc_year rtc_year;
119 	struct mcp7940n_rtc_control rtc_control;
120 	struct mcp7940n_rtc_osctrim rtc_osctrim;
121 } __packed;
122 
123 struct mcp7940n_alarm_registers {
124 	struct mcp7940n_alm_sec alm_sec;
125 	struct mcp7940n_alm_min alm_min;
126 	struct mcp7940n_alm_hours alm_hours;
127 	struct mcp7940n_alm_weekday alm_weekday;
128 	struct mcp7940n_alm_date alm_date;
129 	struct mcp7940n_alm_month alm_month;
130 } __packed;
131 
132 enum mcp7940n_register {
133 	REG_RTC_SEC		= 0x0,
134 	REG_RTC_MIN		= 0x1,
135 	REG_RTC_HOUR		= 0x2,
136 	REG_RTC_WDAY		= 0x3,
137 	REG_RTC_DATE		= 0x4,
138 	REG_RTC_MONTH		= 0x5,
139 	REG_RTC_YEAR		= 0x6,
140 	REG_RTC_CONTROL		= 0x7,
141 	REG_RTC_OSCTRIM		= 0x8,
142 	/* 0x9 not implemented */
143 	REG_ALM0_SEC		= 0xA,
144 	REG_ALM0_MIN		= 0xB,
145 	REG_ALM0_HOUR		= 0xC,
146 	REG_ALM0_WDAY		= 0xD,
147 	REG_ALM0_DATE		= 0xE,
148 	REG_ALM0_MONTH		= 0xF,
149 	/* 0x10 not implemented */
150 	REG_ALM1_SEC		= 0x11,
151 	REG_ALM1_MIN		= 0x12,
152 	REG_ALM1_HOUR		= 0x13,
153 	REG_ALM1_WDAY		= 0x14,
154 	REG_ALM1_DATE		= 0x15,
155 	REG_ALM1_MONTH		= 0x16,
156 	/* 0x17 not implemented */
157 	REG_PWR_DWN_MIN		= 0x18,
158 	REG_PWR_DWN_HOUR	= 0x19,
159 	REG_PWR_DWN_DATE	= 0x1A,
160 	REG_PWR_DWN_MONTH	= 0x1B,
161 	REG_PWR_UP_MIN		= 0x1C,
162 	REG_PWR_UP_HOUR		= 0x1D,
163 	REG_PWR_UP_DATE		= 0x1E,
164 	REG_PWR_UP_MONTH	= 0x1F,
165 	SRAM_MIN		= 0x20,
166 	SRAM_MAX		= 0x5F,
167 	REG_INVAL		= 0x60,
168 };
169 
170 /* Mutually exclusive alarm trigger settings */
171 enum mcp7940n_alarm_trigger {
172 	MCP7940N_ALARM_TRIGGER_SECONDS	= 0x0,
173 	MCP7940N_ALARM_TRIGGER_MINUTES	= 0x1,
174 	MCP7940N_ALARM_TRIGGER_HOURS	= 0x2,
175 	MCP7940N_ALARM_TRIGGER_WDAY	= 0x3,
176 	MCP7940N_ALARM_TRIGGER_DATE	= 0x4,
177 	/* TRIGGER_ALL matches seconds, minutes, hours, weekday, date and month */
178 	MCP7940N_ALARM_TRIGGER_ALL	= 0x7,
179 };
180 
181 /** @brief Set the RTC to a given Unix time
182  *
183  * The RTC advances one tick per second with no access to sub-second
184  * precision. This function will convert the given unix_time into seconds,
185  * minutes, hours, day of the week, day of the month, month and year.
186  * A Unix time of '0' means a timestamp of 00:00:00 UTC on Thursday 1st January
187  * 1970.
188  *
189  * @param dev the MCP7940N device pointer.
190  * @param unix_time Unix time to set the rtc to.
191  *
192  * @retval return 0 on success, or a negative error code from an I2C
193  * transaction or invalid parameter.
194  */
195 int mcp7940n_rtc_set_time(const struct device *dev, time_t unix_time);
196 
197 #endif /* ZEPHYR_INCLUDE_DRIVERS_RTC_MCP7940N_H_ */
198