1 /*
2  * Copyright (c) 2025 Marcin Lyda <elektromarcin@gmail.com>
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/kernel.h>
8 #include <zephyr/sys/util.h>
9 #include <zephyr/logging/log.h>
10 #include <zephyr/drivers/i2c.h>
11 #include <zephyr/drivers/rtc.h>
12 #include <zephyr/drivers/gpio.h>
13 #include "rtc_utils.h"
14 
15 LOG_MODULE_REGISTER(ds1337, CONFIG_RTC_LOG_LEVEL);
16 
17 #define DT_DRV_COMPAT maxim_ds1337
18 
19 #if DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 0
20 #warning "Maxim DS1337 RTC driver enabled without any devices"
21 #endif
22 
23 /* Registers */
24 #define DS1337_SECONDS_REG          0x00
25 #define DS1337_ALARM_1_SECONDS_REG  0x07
26 #define DS1337_ALARM_2_MINUTES_REG  0x0B
27 #define DS1337_CONTROL_REG          0x0E
28 #define DS1337_STATUS_REG           0x0F
29 
30 /* Bitmasks */
31 #define DS1337_SECONDS_MASK       GENMASK(6, 0)
32 #define DS1337_MINUTES_MASK       GENMASK(6, 0)
33 #define DS1337_HOURS_MASK         GENMASK(5, 0)
34 #define DS1337_DAY_MASK           GENMASK(2, 0)
35 #define DS1337_DATE_MASK          GENMASK(5, 0)
36 #define DS1337_MONTH_MASK         GENMASK(4, 0)
37 #define DS1337_YEAR_MASK          GENMASK(7, 0)
38 #define DS1337_ALARM_SECONDS_MASK GENMASK(6, 0)
39 #define DS1337_ALARM_MINUTES_MASK GENMASK(6, 0)
40 #define DS1337_ALARM_HOURS_MASK   GENMASK(5, 0)
41 #define DS1337_ALARM_DAY_MASK     GENMASK(3, 0)
42 #define DS1337_ALARM_DATE_MASK    GENMASK(5, 0)
43 
44 #define DS1337_12_24_MODE_MASK BIT(6)
45 #define DS1337_CENTURY_MASK    BIT(7)
46 #define DS1337_DY_DT_MASK      BIT(6)
47 
48 #define DS1337_ALARM_DISABLE_MASK BIT(7)
49 
50 #define DS1337_EOSC_MASK  BIT(7)
51 #define DS1337_RS_MASK    GENMASK(4, 3)
52 #define DS1337_INTCN_MASK BIT(2)
53 #define DS1337_A2IE_MASK  BIT(1)
54 #define DS1337_A1IE_MASK  BIT(0)
55 
56 #define DS1337_OSF_MASK BIT(7)
57 #define DS1337_A2F_MASK BIT(1)
58 #define DS1337_A1F_MASK BIT(0)
59 
60 #define DS1337_SQW_FREQ_1Hz     FIELD_PREP(DS1337_RS_MASK, 0x00)
61 #define DS1337_SQW_FREQ_4096Hz  FIELD_PREP(DS1337_RS_MASK, 0x01)
62 #define DS1337_SQW_FREQ_8192Hz  FIELD_PREP(DS1337_RS_MASK, 0x02)
63 #define DS1337_SQW_FREQ_32768Hz FIELD_PREP(DS1337_RS_MASK, 0x03)
64 
65 /* DS1337 features two independent alarms */
66 #define DS1337_ALARM_1_ID   0
67 #define DS1337_ALARM_2_ID   1
68 #define DS1337_ALARMS_COUNT 2
69 
70 /* SQW frequency property enum values */
71 #define DS1337_SQW_PROP_ENUM_1HZ     0
72 #define DS1337_SQW_PROP_ENUM_4096HZ  1
73 #define DS1337_SQW_PROP_ENUM_8192HZ  2
74 #define DS1337_SQW_PROP_ENUM_32768HZ 3
75 
76 /* DS1337 counts weekdays from 1 to 7 */
77 #define DS1337_DAY_OFFSET -1
78 
79 /* DS1337 counts months 1 to 12 */
80 #define DS1337_MONTH_OFFSET -1
81 
82 /* Year 2000 value represented as tm_year value */
83 #define DS1337_TM_YEAR_2000 (2000 - 1900)
84 
85 /* RTC time fields supported by DS1337 */
86 #define DS1337_RTC_TIME_MASK                                                                       \
87 	(RTC_ALARM_TIME_MASK_SECOND | RTC_ALARM_TIME_MASK_MINUTE | RTC_ALARM_TIME_MASK_HOUR |      \
88 	 RTC_ALARM_TIME_MASK_MONTH | RTC_ALARM_TIME_MASK_MONTHDAY | RTC_ALARM_TIME_MASK_YEAR |     \
89 	 RTC_ALARM_TIME_MASK_WEEKDAY)
90 
91 /* RTC alarm 1 fields supported by DS1337 */
92 #define DS1337_RTC_ALARM_TIME_1_MASK                                                               \
93 	(RTC_ALARM_TIME_MASK_SECOND | RTC_ALARM_TIME_MASK_MINUTE | RTC_ALARM_TIME_MASK_HOUR |      \
94 	 RTC_ALARM_TIME_MASK_MONTHDAY | RTC_ALARM_TIME_MASK_WEEKDAY)
95 
96 /* RTC alarm 2 fields supported by DS1337 */
97 #define DS1337_RTC_ALARM_TIME_2_MASK                                                               \
98 	(RTC_ALARM_TIME_MASK_MINUTE | RTC_ALARM_TIME_MASK_HOUR | RTC_ALARM_TIME_MASK_MONTHDAY |    \
99 	 RTC_ALARM_TIME_MASK_WEEKDAY)
100 
101 /* Helper macro to guard GPIO interrupt related stuff */
102 #if DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios) && defined(CONFIG_RTC_ALARM)
103 #define DS1337_INT_GPIOS_IN_USE 1
104 #endif
105 
106 struct ds1337_config {
107 	const struct i2c_dt_spec i2c;
108 #ifdef DS1337_INT_GPIOS_IN_USE
109 	struct gpio_dt_spec gpio_int;
110 #endif
111 	uint8_t sqw_freq;
112 };
113 
114 struct ds1337_data {
115 	struct k_sem lock;
116 #ifdef DS1337_INT_GPIOS_IN_USE
117 	const struct device *dev;
118 	struct gpio_callback irq_callback;
119 	struct k_work work;
120 #ifdef CONFIG_RTC_ALARM
121 	rtc_alarm_callback alarm_callbacks[DS1337_ALARMS_COUNT];
122 	void *alarm_user_data[DS1337_ALARMS_COUNT];
123 #endif
124 #endif
125 };
126 
ds1337_lock_sem(const struct device * dev)127 static void ds1337_lock_sem(const struct device *dev)
128 {
129 	struct ds1337_data *data = dev->data;
130 
131 	(void)k_sem_take(&data->lock, K_FOREVER);
132 }
133 
ds1337_unlock_sem(const struct device * dev)134 static void ds1337_unlock_sem(const struct device *dev)
135 {
136 	struct ds1337_data *data = dev->data;
137 
138 	k_sem_give(&data->lock);
139 }
140 
ds1337_validate_alarm_mask(uint16_t alarm_mask,uint16_t alarm_id)141 static bool ds1337_validate_alarm_mask(uint16_t alarm_mask, uint16_t alarm_id)
142 {
143 	const uint16_t allowed_configs[6] = {
144 		0,
145 		RTC_ALARM_TIME_MASK_SECOND,
146 		RTC_ALARM_TIME_MASK_SECOND | RTC_ALARM_TIME_MASK_MINUTE,
147 		RTC_ALARM_TIME_MASK_SECOND | RTC_ALARM_TIME_MASK_MINUTE | RTC_ALARM_TIME_MASK_HOUR,
148 		RTC_ALARM_TIME_MASK_SECOND | RTC_ALARM_TIME_MASK_MINUTE | RTC_ALARM_TIME_MASK_HOUR |
149 			RTC_ALARM_TIME_MASK_WEEKDAY,
150 		RTC_ALARM_TIME_MASK_SECOND | RTC_ALARM_TIME_MASK_MINUTE | RTC_ALARM_TIME_MASK_HOUR |
151 			RTC_ALARM_TIME_MASK_MONTHDAY
152 	};
153 
154 	const uint16_t available_fields =
155 		(alarm_id == 0) ? DS1337_RTC_ALARM_TIME_1_MASK : DS1337_RTC_ALARM_TIME_2_MASK;
156 	if (alarm_mask & ~available_fields) {
157 		return false;
158 	}
159 
160 	ARRAY_FOR_EACH_PTR(allowed_configs, config) {
161 		if (alarm_mask == (*config & available_fields)) {
162 			return true;
163 		}
164 	}
165 	return false;
166 }
167 
168 #ifdef DS1337_INT_GPIOS_IN_USE
169 
ds1337_work_callback(struct k_work * work)170 static void ds1337_work_callback(struct k_work *work)
171 {
172 	struct ds1337_data *data = CONTAINER_OF(work, struct ds1337_data, work);
173 	const struct device *dev = data->dev;
174 	const struct ds1337_config *config = dev->config;
175 	rtc_alarm_callback alarm_callbacks[DS1337_ALARMS_COUNT] = {NULL};
176 	void *alarm_user_data[DS1337_ALARMS_COUNT] = {NULL};
177 	uint8_t status_reg;
178 	int err;
179 
180 	ds1337_lock_sem(dev);
181 
182 	/* Read status register */
183 	err = i2c_reg_read_byte_dt(&config->i2c, DS1337_STATUS_REG, &status_reg);
184 	if (err) {
185 		goto out_unlock;
186 	}
187 
188 #ifdef CONFIG_RTC_ALARM
189 	/* Handle alarm 1 event */
190 	if ((status_reg & DS1337_A1F_MASK) && (data->alarm_callbacks[DS1337_ALARM_1_ID] != NULL)) {
191 		status_reg &= ~DS1337_A1F_MASK;
192 		alarm_callbacks[DS1337_ALARM_1_ID] = data->alarm_callbacks[DS1337_ALARM_1_ID];
193 		alarm_user_data[DS1337_ALARM_1_ID] = data->alarm_user_data[DS1337_ALARM_1_ID];
194 	}
195 
196 	/* Handle alarm 2 event */
197 	if ((status_reg & DS1337_A2F_MASK) && (data->alarm_callbacks[DS1337_ALARM_2_ID] != NULL)) {
198 		status_reg &= ~DS1337_A2F_MASK;
199 		alarm_callbacks[DS1337_ALARM_2_ID] = data->alarm_callbacks[DS1337_ALARM_2_ID];
200 		alarm_user_data[DS1337_ALARM_2_ID] = data->alarm_user_data[DS1337_ALARM_2_ID];
201 	}
202 #endif
203 
204 	/* Clear alarm flag(s) */
205 	err = i2c_reg_write_byte_dt(&config->i2c, DS1337_STATUS_REG, status_reg);
206 	if (err) {
207 		goto out_unlock;
208 	}
209 
210 	/* Check if any interrupt occurred between flags register read/write */
211 	err = i2c_reg_read_byte_dt(&config->i2c, DS1337_STATUS_REG, &status_reg);
212 	if (err) {
213 		goto out_unlock;
214 	}
215 
216 	if (((status_reg & DS1337_A1F_MASK) && (alarm_callbacks[0] != NULL)) ||
217 	    ((status_reg & DS1337_A2F_MASK) && (alarm_callbacks[1] != NULL))) {
218 		/* Another interrupt occurred while servicing this one */
219 		(void)k_work_submit(&data->work);
220 	}
221 
222 out_unlock:
223 	ds1337_unlock_sem(dev);
224 
225 	/* Execute alarm callback(s) */
226 	for (uint8_t alarm_id = DS1337_ALARM_1_ID; alarm_id < DS1337_ALARMS_COUNT; ++alarm_id) {
227 		if (alarm_callbacks[alarm_id] != NULL) {
228 			alarm_callbacks[alarm_id](dev, alarm_id, alarm_user_data[alarm_id]);
229 			alarm_callbacks[alarm_id] = NULL;
230 		}
231 	}
232 }
233 
ds1337_irq_handler(const struct device * port,struct gpio_callback * callback,gpio_port_pins_t pins)234 static void ds1337_irq_handler(const struct device *port, struct gpio_callback *callback,
235 			       gpio_port_pins_t pins)
236 {
237 	ARG_UNUSED(port);
238 	ARG_UNUSED(pins);
239 
240 	struct ds1337_data *data = CONTAINER_OF(callback, struct ds1337_data, irq_callback);
241 
242 	(void)k_work_submit(&data->work);
243 }
244 
245 #endif
246 
ds1337_set_time(const struct device * dev,const struct rtc_time * timeptr)247 static int ds1337_set_time(const struct device *dev, const struct rtc_time *timeptr)
248 {
249 	const struct ds1337_config *config = dev->config;
250 	uint8_t regs[7];
251 	int err;
252 
253 	if ((timeptr == NULL) || !rtc_utils_validate_rtc_time(timeptr, DS1337_RTC_TIME_MASK)) {
254 		return -EINVAL;
255 	}
256 
257 	ds1337_lock_sem(dev);
258 
259 	regs[0] = bin2bcd(timeptr->tm_sec) & DS1337_SECONDS_MASK;
260 	regs[1] = bin2bcd(timeptr->tm_min) & DS1337_MINUTES_MASK;
261 	regs[2] = bin2bcd(timeptr->tm_hour) & DS1337_HOURS_MASK;
262 	regs[3] = bin2bcd(timeptr->tm_wday - DS1337_DAY_OFFSET) & DS1337_DAY_MASK;
263 	regs[4] = bin2bcd(timeptr->tm_mday) & DS1337_DATE_MASK;
264 	regs[5] = bin2bcd(timeptr->tm_mon - DS1337_MONTH_OFFSET) & DS1337_MONTH_MASK;
265 
266 	/* Determine which century we're in */
267 	if (timeptr->tm_year >= DS1337_TM_YEAR_2000) {
268 		regs[5] |= DS1337_CENTURY_MASK;
269 		regs[6] = bin2bcd(timeptr->tm_year - DS1337_TM_YEAR_2000) & DS1337_YEAR_MASK;
270 	} else {
271 		regs[6] = bin2bcd(timeptr->tm_year) & DS1337_YEAR_MASK;
272 	}
273 
274 	/* Set new time */
275 	err = i2c_burst_write_dt(&config->i2c, DS1337_SECONDS_REG, regs, sizeof(regs));
276 	if (err) {
277 		goto out_unlock;
278 	}
279 
280 	/* Clear Oscillator Stop Flag, indicating data validity */
281 	err = i2c_reg_update_byte_dt(&config->i2c, DS1337_STATUS_REG, DS1337_OSF_MASK, 0);
282 
283 out_unlock:
284 	ds1337_unlock_sem(dev);
285 
286 	if (!err) {
287 		LOG_DBG("Set time: year: %d, month: %d, month day: %d, week day: %d, hour: %d, "
288 			"minute: %d, second: %d",
289 			timeptr->tm_year, timeptr->tm_mon, timeptr->tm_mday, timeptr->tm_wday,
290 			timeptr->tm_hour, timeptr->tm_min, timeptr->tm_sec);
291 	}
292 
293 	return err;
294 }
295 
ds1337_get_time(const struct device * dev,struct rtc_time * timeptr)296 static int ds1337_get_time(const struct device *dev, struct rtc_time *timeptr)
297 {
298 	const struct ds1337_config *config = dev->config;
299 	uint8_t regs[7];
300 	uint8_t status_reg;
301 	int err;
302 
303 	if (timeptr == NULL) {
304 		return -EINVAL;
305 	}
306 
307 	ds1337_lock_sem(dev);
308 
309 	/* Check data validity */
310 	err = i2c_reg_read_byte_dt(&config->i2c, DS1337_STATUS_REG, &status_reg);
311 	if (err) {
312 		goto out_unlock;
313 	}
314 	if (status_reg & DS1337_OSF_MASK) {
315 		err = -ENODATA;
316 		goto out_unlock;
317 	}
318 
319 	/* Read time data */
320 	err = i2c_burst_read_dt(&config->i2c, DS1337_SECONDS_REG, regs, sizeof(regs));
321 	if (err) {
322 		goto out_unlock;
323 	}
324 
325 	timeptr->tm_sec = bcd2bin(regs[0] & DS1337_SECONDS_MASK);
326 	timeptr->tm_min = bcd2bin(regs[1] & DS1337_MINUTES_MASK);
327 	timeptr->tm_hour = bcd2bin(regs[2] & DS1337_HOURS_MASK);
328 	timeptr->tm_wday = bcd2bin(regs[3] & DS1337_DAY_MASK) + DS1337_DAY_OFFSET;
329 	timeptr->tm_mday = bcd2bin(regs[4] & DS1337_DATE_MASK);
330 	timeptr->tm_mon = bcd2bin(regs[5] & DS1337_MONTH_MASK) + DS1337_MONTH_OFFSET;
331 	timeptr->tm_year = bcd2bin(regs[6] & DS1337_YEAR_MASK);
332 	timeptr->tm_yday = -1;  /* Unsupported */
333 	timeptr->tm_isdst = -1; /* Unsupported */
334 	timeptr->tm_nsec = 0;   /* Unsupported */
335 
336 	/* Apply century offset */
337 	if (regs[5] & DS1337_CENTURY_MASK) {
338 		timeptr->tm_year += DS1337_TM_YEAR_2000;
339 	}
340 
341 out_unlock:
342 	ds1337_unlock_sem(dev);
343 
344 	if (!err) {
345 		LOG_DBG("Read time: year: %d, month: %d, month day: %d, week day: %d, hour: %d, "
346 			"minute: %d, second: %d",
347 			timeptr->tm_year, timeptr->tm_mon, timeptr->tm_mday, timeptr->tm_wday,
348 			timeptr->tm_hour, timeptr->tm_min, timeptr->tm_sec);
349 	}
350 
351 	return err;
352 }
353 
354 #ifdef CONFIG_RTC_ALARM
355 
ds1337_alarm_get_supported_fields(const struct device * dev,uint16_t id,uint16_t * mask)356 static int ds1337_alarm_get_supported_fields(const struct device *dev, uint16_t id, uint16_t *mask)
357 {
358 	ARG_UNUSED(dev);
359 
360 	if (id == DS1337_ALARM_1_ID) {
361 		*mask = DS1337_RTC_ALARM_TIME_1_MASK;
362 		return 0;
363 	} else if (id == DS1337_ALARM_2_ID) {
364 		*mask = DS1337_RTC_ALARM_TIME_2_MASK;
365 		return 0;
366 	}
367 
368 	LOG_ERR("Invalid alarm ID: %d", id);
369 	return -EINVAL;
370 }
371 
ds1337_alarm_set_time(const struct device * dev,uint16_t id,uint16_t mask,const struct rtc_time * timeptr)372 static int ds1337_alarm_set_time(const struct device *dev, uint16_t id, uint16_t mask,
373 				 const struct rtc_time *timeptr)
374 {
375 	const struct ds1337_config *config = dev->config;
376 	uint8_t regs[4];
377 	uint8_t reg_addr;
378 	uint8_t reg_offset;
379 	int err;
380 
381 	if (id >= DS1337_ALARMS_COUNT) {
382 		LOG_ERR("Invalid alarm ID: %d", id);
383 		return -EINVAL;
384 	}
385 
386 	if ((mask & RTC_ALARM_TIME_MASK_MONTHDAY) && (mask & RTC_ALARM_TIME_MASK_WEEKDAY)) {
387 		LOG_ERR("Month day and week day alarms cannot be set simultaneously");
388 		return -EINVAL;
389 	}
390 
391 	if (!ds1337_validate_alarm_mask(mask, id)) {
392 		LOG_ERR("Unsupported mask 0x%04X for alarm %d", mask, id);
393 		return -EINVAL;
394 	}
395 
396 	if (!rtc_utils_validate_rtc_time(timeptr, mask)) {
397 		LOG_ERR("Invalid alarm time");
398 		return -EINVAL;
399 	}
400 
401 	if (mask & RTC_ALARM_TIME_MASK_SECOND) {
402 		regs[0] = bin2bcd(timeptr->tm_sec) & DS1337_ALARM_SECONDS_MASK;
403 	} else {
404 		regs[0] = DS1337_ALARM_DISABLE_MASK;
405 	}
406 
407 	if (mask & RTC_ALARM_TIME_MASK_MINUTE) {
408 		regs[1] = bin2bcd(timeptr->tm_min) & DS1337_ALARM_MINUTES_MASK;
409 	} else {
410 		regs[1] = DS1337_ALARM_DISABLE_MASK;
411 	}
412 
413 	if (mask & RTC_ALARM_TIME_MASK_HOUR) {
414 		regs[2] = bin2bcd(timeptr->tm_hour) & DS1337_ALARM_HOURS_MASK;
415 	} else {
416 		regs[2] = DS1337_ALARM_DISABLE_MASK;
417 	}
418 
419 	if (mask & RTC_ALARM_TIME_MASK_MONTHDAY) {
420 		regs[3] = bin2bcd(timeptr->tm_mday) & DS1337_ALARM_DATE_MASK;
421 	} else if (mask & RTC_ALARM_TIME_MASK_WEEKDAY) {
422 		regs[3] = bin2bcd(timeptr->tm_wday - DS1337_DAY_OFFSET) & DS1337_ALARM_DAY_MASK;
423 		regs[3] |= DS1337_DY_DT_MASK;
424 	} else {
425 		regs[3] = DS1337_ALARM_DISABLE_MASK;
426 	}
427 
428 	/* Update alarm registers */
429 	if (id == DS1337_ALARM_1_ID) {
430 		reg_addr = DS1337_ALARM_1_SECONDS_REG;
431 		reg_offset = 0;
432 	} else {
433 		reg_addr = DS1337_ALARM_2_MINUTES_REG;
434 		reg_offset = 1;
435 	}
436 
437 	err = i2c_burst_write_dt(&config->i2c, reg_addr, &regs[reg_offset],
438 				 sizeof(regs) - reg_offset);
439 	if (err) {
440 		return err;
441 	}
442 
443 	LOG_DBG("Set alarm: month day: %d, week day: %d, hour: %d, minute: %d, second: %d mask: "
444 		"0x%04X",
445 		timeptr->tm_mday, timeptr->tm_wday, timeptr->tm_hour, timeptr->tm_min,
446 		timeptr->tm_sec, mask);
447 
448 	return 0;
449 }
450 
ds1337_alarm_get_time(const struct device * dev,uint16_t id,uint16_t * mask,struct rtc_time * timeptr)451 static int ds1337_alarm_get_time(const struct device *dev, uint16_t id, uint16_t *mask,
452 				 struct rtc_time *timeptr)
453 {
454 	const struct ds1337_config *config = dev->config;
455 	uint8_t regs[4];
456 	uint8_t reg_addr;
457 	uint8_t reg_offset;
458 	int err;
459 
460 	if (id >= DS1337_ALARMS_COUNT) {
461 		LOG_ERR("Invalid alarm ID: %d", id);
462 		return -EINVAL;
463 	}
464 
465 	/* Read alarm registers */
466 	if (id == DS1337_ALARM_1_ID) {
467 		reg_addr = DS1337_ALARM_1_SECONDS_REG;
468 		reg_offset = 0;
469 	} else {
470 		reg_addr = DS1337_ALARM_2_MINUTES_REG;
471 		reg_offset = 1;
472 	}
473 	err = i2c_burst_read_dt(&config->i2c, reg_addr, &regs[reg_offset],
474 				sizeof(regs) - reg_offset);
475 	if (err) {
476 		return err;
477 	}
478 
479 	(void)memset(timeptr, 0, sizeof(*timeptr));
480 	*mask = 0;
481 
482 	if ((regs[0] & DS1337_ALARM_DISABLE_MASK) == 0) {
483 		timeptr->tm_sec = bcd2bin(regs[0] & DS1337_ALARM_SECONDS_MASK);
484 		*mask |= RTC_ALARM_TIME_MASK_SECOND;
485 	}
486 
487 	if ((regs[1] & DS1337_ALARM_DISABLE_MASK) == 0) {
488 		timeptr->tm_min = bcd2bin(regs[1] & DS1337_ALARM_MINUTES_MASK);
489 		*mask |= RTC_ALARM_TIME_MASK_MINUTE;
490 	}
491 
492 	if ((regs[2] & DS1337_ALARM_DISABLE_MASK) == 0) {
493 		timeptr->tm_hour = bcd2bin(regs[2] & DS1337_ALARM_HOURS_MASK);
494 		*mask |= RTC_ALARM_TIME_MASK_HOUR;
495 	}
496 
497 	if ((regs[3] & DS1337_ALARM_DISABLE_MASK) == 0) {
498 		if ((regs[3] & DS1337_DY_DT_MASK) == 0) {
499 			timeptr->tm_mday = bcd2bin(regs[3] & DS1337_ALARM_DATE_MASK);
500 			*mask |= RTC_ALARM_TIME_MASK_MONTHDAY;
501 		} else {
502 			timeptr->tm_wday =
503 				bcd2bin(regs[3] & DS1337_ALARM_DAY_MASK) + DS1337_DAY_OFFSET;
504 			*mask |= RTC_ALARM_TIME_MASK_WEEKDAY;
505 		}
506 	}
507 
508 	LOG_DBG("Get alarm: month day: %d, week day: %d, hour: %d, minute: %d, second: %d mask: "
509 		"0x%04X",
510 		timeptr->tm_mday, timeptr->tm_wday, timeptr->tm_hour, timeptr->tm_min,
511 		timeptr->tm_sec, *mask);
512 
513 	return 0;
514 }
515 
ds1337_alarm_is_pending(const struct device * dev,uint16_t id)516 static int ds1337_alarm_is_pending(const struct device *dev, uint16_t id)
517 {
518 	const struct ds1337_config *config = dev->config;
519 	uint8_t pending = 0;
520 	uint8_t status_reg;
521 	int err;
522 
523 	if (id >= DS1337_ALARMS_COUNT) {
524 		LOG_ERR("Invalid alarm ID: %d", id);
525 		return -EINVAL;
526 	}
527 
528 	ds1337_lock_sem(dev);
529 
530 	err = i2c_reg_read_byte_dt(&config->i2c, DS1337_STATUS_REG, &status_reg);
531 	if (err) {
532 		goto out_unlock;
533 	}
534 
535 	if (id == DS1337_ALARM_1_ID) {
536 		if (status_reg & DS1337_A1F_MASK) {
537 			status_reg &= ~DS1337_A1F_MASK;
538 			pending = 1;
539 		}
540 	} else {
541 		if (status_reg & DS1337_A2F_MASK) {
542 			status_reg &= ~DS1337_A2F_MASK;
543 			pending = 1;
544 		}
545 	}
546 
547 	err = i2c_reg_write_byte_dt(&config->i2c, DS1337_STATUS_REG, status_reg);
548 	if (err) {
549 		goto out_unlock;
550 	}
551 
552 out_unlock:
553 	ds1337_unlock_sem(dev);
554 
555 	if (err) {
556 		return err;
557 	}
558 	return pending;
559 }
560 
561 #ifdef DS1337_INT_GPIOS_IN_USE
562 
ds1337_alarm_set_callback(const struct device * dev,uint16_t id,rtc_alarm_callback callback,void * user_data)563 static int ds1337_alarm_set_callback(const struct device *dev, uint16_t id,
564 				     rtc_alarm_callback callback, void *user_data)
565 {
566 	const struct ds1337_config *config = dev->config;
567 	struct ds1337_data *data = dev->data;
568 	uint8_t reg_val = 0;
569 	uint8_t mask = 0;
570 	int err;
571 
572 	if (config->gpio_int.port == NULL) {
573 		return -ENOTSUP;
574 	}
575 
576 	if (id >= DS1337_ALARMS_COUNT) {
577 		LOG_ERR("Invalid alarm ID: %d", id);
578 		return -EINVAL;
579 	}
580 
581 	ds1337_lock_sem(dev);
582 
583 	data->alarm_callbacks[id] = callback;
584 	data->alarm_user_data[id] = user_data;
585 
586 	/* Enable alarm interrupt if callback provided */
587 	if (id == DS1337_ALARM_1_ID) {
588 		mask = DS1337_A1IE_MASK;
589 		reg_val = (callback != NULL) ? DS1337_A1IE_MASK : 0;
590 	} else {
591 		mask = DS1337_A2IE_MASK;
592 		reg_val = (callback != NULL) ? DS1337_A2IE_MASK : 0;
593 	}
594 	err = i2c_reg_update_byte_dt(&config->i2c, DS1337_CONTROL_REG, mask, reg_val);
595 
596 	ds1337_unlock_sem(dev);
597 
598 	/* Alarm IRQ might have already been triggered */
599 	(void)k_work_submit(&data->work);
600 
601 	return err;
602 }
603 
604 #endif
605 
606 #endif
607 
ds1337_init(const struct device * dev)608 static int ds1337_init(const struct device *dev)
609 {
610 	const struct ds1337_config *config = dev->config;
611 	struct ds1337_data *data = dev->data;
612 	uint8_t reg_val;
613 	int err;
614 
615 	(void)k_sem_init(&data->lock, 1, 1);
616 
617 	if (!i2c_is_ready_dt(&config->i2c)) {
618 		LOG_ERR("I2C bus not ready");
619 		return -ENODEV;
620 	}
621 
622 #ifdef DS1337_INT_GPIOS_IN_USE
623 	if (config->gpio_int.port != NULL) {
624 		if (!gpio_is_ready_dt(&config->gpio_int)) {
625 			LOG_ERR("GPIO not ready");
626 			return -ENODEV;
627 		}
628 
629 		err = gpio_pin_configure_dt(&config->gpio_int, GPIO_INPUT);
630 		if (err) {
631 			LOG_ERR("Failed to configure interrupt GPIO, error: %d", err);
632 			return err;
633 		}
634 
635 		err = gpio_pin_interrupt_configure_dt(&config->gpio_int, GPIO_INT_EDGE_TO_ACTIVE);
636 		if (err) {
637 			LOG_ERR("Failed to enable GPIO interrupt, error: %d", err);
638 			return err;
639 		}
640 
641 		gpio_init_callback(&data->irq_callback, ds1337_irq_handler,
642 				   BIT(config->gpio_int.pin));
643 
644 		err = gpio_add_callback_dt(&config->gpio_int, &data->irq_callback);
645 		if (err) {
646 			LOG_ERR("Failed to add GPIO callback, error: %d", err);
647 			return err;
648 		}
649 
650 		data->dev = dev;
651 		data->work.handler = ds1337_work_callback;
652 	}
653 #endif
654 
655 	/* Display warning if alarm flags are set */
656 	err = i2c_reg_read_byte_dt(&config->i2c, DS1337_STATUS_REG, &reg_val);
657 	if (err) {
658 		return err;
659 	}
660 	if (reg_val & DS1337_A1F_MASK) {
661 		LOG_WRN("Alarm 1 might have been missed!");
662 	}
663 	if (reg_val & DS1337_A2F_MASK) {
664 		LOG_WRN("Alarm 2 might have been missed!");
665 	}
666 
667 	/* Enable oscillator */
668 	err = i2c_reg_update_byte_dt(&config->i2c, DS1337_CONTROL_REG, DS1337_EOSC_MASK, 0);
669 	if (err) {
670 		return err;
671 	}
672 
673 	/* Configure SQW output frequency */
674 	switch (config->sqw_freq) {
675 	case DS1337_SQW_PROP_ENUM_1HZ:
676 		reg_val = DS1337_SQW_FREQ_1Hz;
677 		break;
678 	case DS1337_SQW_PROP_ENUM_4096HZ:
679 		reg_val = DS1337_SQW_FREQ_4096Hz;
680 		break;
681 	case DS1337_SQW_PROP_ENUM_8192HZ:
682 		reg_val = DS1337_SQW_FREQ_8192Hz;
683 		break;
684 	case DS1337_SQW_PROP_ENUM_32768HZ:
685 	default:
686 		reg_val = DS1337_SQW_FREQ_32768Hz;
687 		break;
688 	}
689 
690 	/*
691 	 * Set SQW frequency, enable oscillator, clear INTCN (both alarms will trigger INTA),
692 	 * disable IRQs
693 	 */
694 	err = i2c_reg_write_byte_dt(&config->i2c, DS1337_CONTROL_REG, reg_val);
695 	if (err) {
696 		return err;
697 	}
698 
699 	/* Clear alarm flags */
700 	err = i2c_reg_update_byte_dt(&config->i2c, DS1337_STATUS_REG,
701 				     DS1337_A1F_MASK | DS1337_A2F_MASK, 0);
702 	if (err) {
703 		return err;
704 	}
705 
706 	return 0;
707 }
708 
709 static DEVICE_API(rtc, ds1337_driver_api) = {
710 	.get_time = ds1337_get_time,
711 	.set_time = ds1337_set_time,
712 #ifdef CONFIG_RTC_ALARM
713 	.alarm_get_supported_fields = ds1337_alarm_get_supported_fields,
714 	.alarm_set_time = ds1337_alarm_set_time,
715 	.alarm_get_time = ds1337_alarm_get_time,
716 	.alarm_is_pending = ds1337_alarm_is_pending,
717 #ifdef DS1337_INT_GPIOS_IN_USE
718 	.alarm_set_callback = ds1337_alarm_set_callback,
719 #endif
720 #endif
721 };
722 
723 #define DS1337_INIT(inst)                                                                          \
724 	static struct ds1337_data ds1337_data_##inst;                                              \
725 	static const struct ds1337_config ds1337_config_##inst = {                                 \
726 		.i2c = I2C_DT_SPEC_INST_GET(inst),                                                 \
727 		.sqw_freq = DT_INST_ENUM_IDX_OR(inst, sqw_frequency, DS1337_SQW_PROP_ENUM_1HZ),    \
728 		IF_ENABLED(                                                                        \
729 			DS1337_INT_GPIOS_IN_USE,                                                   \
730 			(.gpio_int = GPIO_DT_SPEC_INST_GET_OR(inst, int_gpios, {0}))               \
731 		)										   \
732 		};										   \
733 	DEVICE_DT_INST_DEFINE(inst, &ds1337_init, NULL, &ds1337_data_##inst,                       \
734 			      &ds1337_config_##inst, POST_KERNEL, CONFIG_RTC_INIT_PRIORITY,        \
735 			      &ds1337_driver_api);
736 
737 DT_INST_FOREACH_STATUS_OKAY(DS1337_INIT)
738