1 /*
2  * Copyright (c) 2024 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 <zephyr/arch/common/ffs.h>
14 #include "rtc_utils.h"
15 
16 /* Registers */
17 #define RV8803_SECONDS_REG               0x00
18 #define RV8803_MINUTES_REG               0x01
19 #define RV8803_HOURS_REG                 0x02
20 #define RV8803_WEEKDAY_REG               0x03
21 #define RV8803_DATE_REG                  0x04
22 #define RV8803_MONTH_REG                 0x05
23 #define RV8803_YEAR_REG                  0x06
24 #define RV8803_RAM_REG                   0x07
25 #define RV8803_MINUTES_ALARM_REG         0x08
26 #define RV8803_HOURS_ALARM_REG           0x09
27 #define RV8803_WEEKDAY_OR_DATE_ALARM_REG 0x0A
28 #define RV8803_EXTENSION_REG             0x0D
29 #define RV8803_FLAG_REG                  0x0E
30 #define RV8803_CONTROL_REG               0x0F
31 #define RV8803_OFFSET_REG                0x2C
32 
33 /* Bitmasks */
34 #define RV8803_SECONDS_MASK GENMASK(6, 0)
35 #define RV8803_MINUTES_MASK GENMASK(6, 0)
36 #define RV8803_HOURS_MASK   GENMASK(5, 0)
37 #define RV8803_WEEKDAY_MASK GENMASK(6, 0)
38 #define RV8803_DATE_MASK    GENMASK(5, 0)
39 #define RV8803_MONTH_MASK   GENMASK(4, 0)
40 #define RV8803_YEAR_MASK    GENMASK(7, 0)
41 
42 #define RV8803_MINUTES_ALARM_AE_M_BIT          BIT(7)
43 #define RV8803_MINUTES_ALARM_MASK              GENMASK(6, 0)
44 #define RV8803_HOURS_ALARM_AE_H_BIT            BIT(7)
45 #define RV8803_HOURS_ALARM_MASK                GENMASK(5, 0)
46 #define RV8803_WEEKDAY_OR_DATE_ALARM_AE_WD_BIT BIT(7)
47 #define RV8803_WEEKDAY_ALARM_MASK              GENMASK(6, 0)
48 #define RV8803_DATE_ALARM_MASK                 GENMASK(5, 0)
49 
50 #define RV8803_EXTENSION_TEST_BIT BIT(7)
51 #define RV8803_EXTENSION_WADA_BIT BIT(6)
52 #define RV8803_EXTENSION_USEL_BIT BIT(5)
53 #define RV8803_EXTENSION_TE_BIT   BIT(4)
54 #define RV8803_EXTENSION_FD_MASK  GENMASK(3, 2)
55 #define RV8803_EXTENSION_TD_MASK  GENMASK(1, 0)
56 
57 #define RV8803_EXTENSION_FD_32768Hz FIELD_PREP(RV8803_EXTENSION_FD_MASK, 0x00)
58 #define RV8803_EXTENSION_FD_1024Hz  FIELD_PREP(RV8803_EXTENSION_FD_MASK, 0x01)
59 #define RV8803_EXTENSION_FD_1Hz     FIELD_PREP(RV8803_EXTENSION_FD_MASK, 0x02)
60 
61 #define RV8803_FLAG_UF_BIT  BIT(5)
62 #define RV8803_FLAG_TF_BIT  BIT(4)
63 #define RV8803_FLAG_AF_BIT  BIT(3)
64 #define RV8803_FLAG_EVF_BIT BIT(2)
65 #define RV8803_FLAG_V2F_BIT BIT(1)
66 #define RV8803_FLAG_V1F_BIT BIT(0)
67 
68 #define RV8803_CONTROL_UIE_BIT   BIT(5)
69 #define RV8803_CONTROL_TIE_BIT   BIT(4)
70 #define RV8803_CONTROL_AIE_BIT   BIT(3)
71 #define RV8803_CONTROL_EIE_BIT   BIT(2)
72 #define RV8803_CONTROL_RESET_BIT BIT(0)
73 
74 #define RV8803_MONDAY_MASK    BIT(0)
75 #define RV8803_TUESDAY_MASK   BIT(1)
76 #define RV8803_WEDNESDAY_MASK BIT(2)
77 #define RV8803_THURSDAY_MASK  BIT(3)
78 #define RV8803_FRIDAY_MASK    BIT(4)
79 #define RV8803_SATURDAY_MASK  BIT(5)
80 #define RV8803_SUNDAY_MASK    BIT(6)
81 
82 #define RV8803_OFFSET_MASK GENMASK(5, 0)
83 
84 /* Offset between first tm_year and first RV8803 year */
85 #define RV8803_YEAR_OFFSET (2000 - 1900)
86 
87 /* RV8803 enumerates months 1 to 12 */
88 #define RV8803_MONTH_OFFSET -1
89 
90 /* Max value of seconds, needed for readout procedure workaround */
91 #define RV8803_SECONDS_MAX_VALUE 59
92 
93 /* See RV-8803-C7 Application Manual p. 22, 3.9. */
94 #define RV8803_OFFSET_PPB_PER_LSB    238
95 #define RV8803_OFFSET_PPB_MIN        (-32 * RV8803_OFFSET_PPB_PER_LSB)
96 #define RV8803_OFFSET_PPB_MAX        (31 * RV8803_OFFSET_PPB_PER_LSB)
97 #define RV8803_OFFSET_SIGN_BIT_INDEX 5 /* Required for aging offset sign extension */
98 
99 /* CLKOUT property enum values */
100 #define RV8803_PROP_ENUM_1HZ     0
101 #define RV8803_PROP_ENUM_1024HZ  1
102 #define RV8803_PROP_ENUM_32768HZ 2
103 
104 #define DT_DRV_COMPAT microcrystal_rv8803
105 
106 #if DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 0
107 #warning "Micro Crystal RV8803 driver enabled without any devices"
108 #endif
109 
110 /* RTC time fields supported by RV8803 */
111 #define RV8803_RTC_TIME_MASK                                                                       \
112 	(RTC_ALARM_TIME_MASK_SECOND | RTC_ALARM_TIME_MASK_MINUTE | RTC_ALARM_TIME_MASK_HOUR |      \
113 	 RTC_ALARM_TIME_MASK_MONTH | RTC_ALARM_TIME_MASK_MONTHDAY | RTC_ALARM_TIME_MASK_YEAR |     \
114 	 RTC_ALARM_TIME_MASK_WEEKDAY)
115 
116 /* RTC alarm time fields supported by RV8803 */
117 #define RV8803_RTC_ALARM_TIME_MASK                                                                 \
118 	(RTC_ALARM_TIME_MASK_MINUTE | RTC_ALARM_TIME_MASK_HOUR | RTC_ALARM_TIME_MASK_MONTHDAY |    \
119 	 RTC_ALARM_TIME_MASK_WEEKDAY)
120 
121 /* Helper macro to guard GPIO interrupt related stuff */
122 #if DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios) &&                                                 \
123 	(defined(CONFIG_RTC_ALARM) || defined(CONFIG_RTC_UPDATE))
124 #define RV8803_INT_GPIOS_IN_USE 1
125 #endif
126 
127 LOG_MODULE_REGISTER(rv8803, CONFIG_RTC_LOG_LEVEL);
128 
129 struct rv8803_config {
130 	const struct i2c_dt_spec i2c;
131 #ifdef RV8803_INT_GPIOS_IN_USE
132 	struct gpio_dt_spec gpio_int;
133 #endif
134 	uint16_t clkout_freq;
135 };
136 
137 struct rv8803_data {
138 	struct k_sem lock;
139 #ifdef RV8803_INT_GPIOS_IN_USE
140 	const struct device *dev;
141 	struct gpio_callback irq_callback;
142 	struct k_work work;
143 
144 #ifdef CONFIG_RTC_ALARM
145 	rtc_alarm_callback alarm_callback;
146 	void *alarm_user_data;
147 #endif
148 
149 #ifdef CONFIG_RTC_UPDATE
150 	rtc_update_callback update_callback;
151 	void *update_user_data;
152 #endif
153 #endif
154 };
155 
rv8803_lock_sem(const struct device * dev)156 static void rv8803_lock_sem(const struct device *dev)
157 {
158 	struct rv8803_data *data = dev->data;
159 
160 	k_sem_take(&data->lock, K_FOREVER);
161 }
162 
rv8803_unlock_sem(const struct device * dev)163 static void rv8803_unlock_sem(const struct device *dev)
164 {
165 	struct rv8803_data *data = dev->data;
166 
167 	k_sem_give(&data->lock);
168 }
169 
rv8803_read_regs(const struct device * dev,uint8_t addr,void * buffer,size_t size)170 static int rv8803_read_regs(const struct device *dev, uint8_t addr, void *buffer, size_t size)
171 {
172 	const struct rv8803_config *config = dev->config;
173 	int err;
174 
175 	err = i2c_write_read_dt(&config->i2c, &addr, sizeof(addr), buffer, size);
176 	if (err) {
177 		LOG_ERR("Failed to read %zuB from register 0x%02X, error: %d", size, addr, err);
178 	}
179 	return err;
180 }
181 
rv8803_read_reg8(const struct device * dev,uint8_t addr,uint8_t * val)182 static int rv8803_read_reg8(const struct device *dev, uint8_t addr, uint8_t *val)
183 {
184 	return rv8803_read_regs(dev, addr, val, sizeof(*val));
185 }
186 
rv8803_write_regs(const struct device * dev,uint8_t addr,const void * buffer,size_t size)187 static int rv8803_write_regs(const struct device *dev, uint8_t addr, const void *buffer,
188 			     size_t size)
189 {
190 	const struct rv8803_config *config = dev->config;
191 	const size_t i2c_data_size = sizeof(addr) + size;
192 	uint8_t i2c_data[i2c_data_size];
193 	int err;
194 
195 	/* Prepend data with I2C device address */
196 	i2c_data[0] = addr;
197 	memcpy(&i2c_data[1], buffer, size);
198 
199 	err = i2c_write_dt(&config->i2c, i2c_data, i2c_data_size);
200 	if (err) {
201 		LOG_ERR("Failed to write %zuB to register 0x%02X, error: %d", i2c_data_size, addr,
202 			err);
203 	}
204 
205 	return err;
206 }
207 
208 #if defined(RV8803_INT_GPIOS_IN_USE) || defined(CONFIG_RTC_ALARM) || defined(CONFIG_RTC_CALIBRATION)
rv8803_write_reg8(const struct device * dev,uint8_t addr,uint8_t val)209 static int rv8803_write_reg8(const struct device *dev, uint8_t addr, uint8_t val)
210 {
211 	return rv8803_write_regs(dev, addr, &val, sizeof(val));
212 }
213 #endif
214 
rv8803_update_reg8(const struct device * dev,uint8_t addr,uint8_t mask,uint8_t val)215 static int rv8803_update_reg8(const struct device *dev, uint8_t addr, uint8_t mask, uint8_t val)
216 {
217 	const struct rv8803_config *config = dev->config;
218 	int err;
219 
220 	err = i2c_reg_update_byte_dt(&config->i2c, addr, mask, val);
221 	if (err) {
222 		LOG_ERR("Failed to update register 0x%02X with value 0x%02X and mask 0x%02X, "
223 			"error: %d",
224 			addr, val, mask, err);
225 	}
226 	return err;
227 }
228 
rv8803_weekday2mask(int weekday)229 static uint8_t rv8803_weekday2mask(int weekday)
230 {
231 	return (1 << weekday);
232 }
233 
rv8803_mask2weekday(uint8_t mask)234 static int rv8803_mask2weekday(uint8_t mask)
235 {
236 	return find_lsb_set(mask) - 1;
237 }
238 
239 #ifdef RV8803_INT_GPIOS_IN_USE
240 
rv8803_work_callback(struct k_work * work)241 static void rv8803_work_callback(struct k_work *work)
242 {
243 	struct rv8803_data *data = CONTAINER_OF(work, struct rv8803_data, work);
244 	const struct device *dev = data->dev;
245 	rtc_alarm_callback alarm_callback = NULL;
246 	void *alarm_user_data = NULL;
247 	rtc_update_callback update_callback = NULL;
248 	void *update_user_data = NULL;
249 	int err;
250 	uint8_t flags;
251 
252 	rv8803_lock_sem(dev);
253 
254 	do {
255 		/* Read flags register */
256 		err = rv8803_read_reg8(dev, RV8803_FLAG_REG, &flags);
257 		if (err) {
258 			break;
259 		}
260 
261 #ifdef CONFIG_RTC_ALARM
262 		/* Handle alarm event */
263 		if ((flags & RV8803_FLAG_AF_BIT) && (data->alarm_callback != NULL)) {
264 			flags &= ~RV8803_FLAG_AF_BIT;
265 			alarm_callback = data->alarm_callback;
266 			alarm_user_data = data->alarm_user_data;
267 		}
268 #endif
269 
270 #ifdef CONFIG_RTC_UPDATE
271 		/* Handle update event */
272 		if ((flags & RV8803_FLAG_UF_BIT) && (data->update_callback != NULL)) {
273 			flags &= ~RV8803_FLAG_UF_BIT;
274 			update_callback = data->update_callback;
275 			update_user_data = data->update_user_data;
276 		}
277 #endif
278 
279 		/* Clear flags */
280 		err = rv8803_write_reg8(dev, RV8803_FLAG_REG, flags);
281 		if (err) {
282 			break;
283 		}
284 
285 		/* Check if any interrupt occurred between flags register read/write */
286 		err = rv8803_read_reg8(dev, RV8803_FLAG_REG, &flags);
287 		if (err) {
288 			break;
289 		}
290 
291 		if (((flags & RV8803_FLAG_AF_BIT) && (alarm_callback != NULL)) ||
292 		    ((flags & RV8803_FLAG_UF_BIT) && (update_callback != NULL))) {
293 			/* Another interrupt occurred while servicing this one */
294 			k_work_submit(&data->work);
295 		}
296 	} while (0);
297 
298 	rv8803_unlock_sem(dev);
299 
300 	if (alarm_callback != NULL) {
301 		/* ID is always zero, there's only one set of alarm regs on chip */
302 		alarm_callback(dev, 0, alarm_user_data);
303 		alarm_callback = NULL;
304 	}
305 
306 	if (update_callback != NULL) {
307 		update_callback(dev, update_user_data);
308 		update_callback = NULL;
309 	}
310 }
311 
rv8803_irq_handler(const struct device * port,struct gpio_callback * callback,gpio_port_pins_t pins)312 static void rv8803_irq_handler(const struct device *port, struct gpio_callback *callback,
313 			       gpio_port_pins_t pins)
314 {
315 	ARG_UNUSED(port);
316 	ARG_UNUSED(pins);
317 
318 	struct rv8803_data *data = CONTAINER_OF(callback, struct rv8803_data, irq_callback);
319 
320 	k_work_submit(&data->work);
321 }
322 
323 #endif
324 
rv8803_set_time(const struct device * dev,const struct rtc_time * timeptr)325 static int rv8803_set_time(const struct device *dev, const struct rtc_time *timeptr)
326 {
327 	uint8_t date[7];
328 	int err;
329 
330 	if ((timeptr == NULL) || !rtc_utils_validate_rtc_time(timeptr, RV8803_RTC_TIME_MASK) ||
331 	    (timeptr->tm_year < RV8803_YEAR_OFFSET)) {
332 		return -EINVAL;
333 	}
334 
335 	rv8803_lock_sem(dev);
336 
337 	date[0] = bin2bcd(timeptr->tm_sec) & RV8803_SECONDS_MASK;
338 	date[1] = bin2bcd(timeptr->tm_min) & RV8803_MINUTES_MASK;
339 	date[2] = bin2bcd(timeptr->tm_hour) & RV8803_HOURS_MASK;
340 	date[3] = rv8803_weekday2mask(timeptr->tm_wday);
341 	date[4] = bin2bcd(timeptr->tm_mday) & RV8803_DATE_MASK;
342 	date[5] = bin2bcd(timeptr->tm_mon - RV8803_MONTH_OFFSET) & RV8803_MONTH_MASK;
343 	date[6] = bin2bcd(timeptr->tm_year - RV8803_YEAR_OFFSET) & RV8803_YEAR_MASK;
344 
345 	do {
346 		/* Reset and freeze countdown chain */
347 		err = rv8803_update_reg8(dev, RV8803_CONTROL_REG, RV8803_CONTROL_RESET_BIT,
348 					 RV8803_CONTROL_RESET_BIT);
349 		if (err) {
350 			break;
351 		}
352 
353 		/* Write new time value */
354 		err = rv8803_write_regs(dev, RV8803_SECONDS_REG, date, sizeof(date));
355 		if (err) {
356 			break;
357 		}
358 
359 		/* Clear Voltage Low flags */
360 		err = rv8803_update_reg8(dev, RV8803_FLAG_REG,
361 					 RV8803_FLAG_V1F_BIT | RV8803_FLAG_V2F_BIT, 0);
362 		if (err) {
363 			break;
364 		}
365 
366 		/* Release countdown chain lock */
367 		err = rv8803_update_reg8(dev, RV8803_CONTROL_REG, RV8803_CONTROL_RESET_BIT, 0);
368 		if (err) {
369 			break;
370 		}
371 	} while (0);
372 
373 	rv8803_unlock_sem(dev);
374 
375 	if (!err) {
376 		LOG_DBG("Set time: year: %d, month: %d, month day: %d, week day: %d, hour: %d, "
377 			"minute: %d, second: %d",
378 			timeptr->tm_year, timeptr->tm_mon, timeptr->tm_mday, timeptr->tm_wday,
379 			timeptr->tm_hour, timeptr->tm_min, timeptr->tm_sec);
380 	}
381 
382 	return err;
383 }
384 
rv8803_get_time(const struct device * dev,struct rtc_time * timeptr)385 static int rv8803_get_time(const struct device *dev, struct rtc_time *timeptr)
386 {
387 	uint8_t flags;
388 	uint8_t date_1[7];
389 	uint8_t date_2[7];
390 	uint8_t *date = date_1;
391 	uint8_t seconds_1;
392 	uint8_t seconds_2;
393 	int err;
394 
395 	if (timeptr == NULL) {
396 		return -EINVAL;
397 	}
398 
399 	err = rv8803_read_reg8(dev, RV8803_FLAG_REG, &flags);
400 	if (err) {
401 		return err;
402 	}
403 
404 	/* Voltage Flag 2 indicates data loss */
405 	if (flags & RV8803_FLAG_V2F_BIT) {
406 		return -ENODATA;
407 	}
408 
409 	/* Time readout procedure to bypass the inability to freeze registers. */
410 	/* See RV-8803-C7 Application Manual p. 42, 4.12.2. */
411 	err = rv8803_read_regs(dev, RV8803_SECONDS_REG, date_1, sizeof(date_1));
412 	if (err) {
413 		return err;
414 	}
415 	seconds_1 = bcd2bin(date_1[0] & RV8803_SECONDS_MASK);
416 	if (seconds_1 == RV8803_SECONDS_MAX_VALUE) {
417 		err = rv8803_read_regs(dev, RV8803_SECONDS_REG, date_2, sizeof(date_2));
418 		if (err) {
419 			return err;
420 		}
421 
422 		seconds_2 = bcd2bin(date_2[0] & RV8803_SECONDS_MASK);
423 		if (seconds_2 != RV8803_SECONDS_MAX_VALUE) {
424 			date = date_2;
425 		}
426 	}
427 
428 	memset(timeptr, 0, sizeof(*timeptr));
429 	timeptr->tm_sec = bcd2bin(date[0] & RV8803_SECONDS_MASK);
430 	timeptr->tm_min = bcd2bin(date[1] & RV8803_MINUTES_MASK);
431 	timeptr->tm_hour = bcd2bin(date[2] & RV8803_HOURS_MASK);
432 	timeptr->tm_wday = rv8803_mask2weekday(date[3] & RV8803_WEEKDAY_MASK);
433 	timeptr->tm_mday = bcd2bin(date[4] & RV8803_DATE_MASK);
434 	timeptr->tm_mon = bcd2bin(date[5] & RV8803_MONTH_MASK) + RV8803_MONTH_OFFSET;
435 	timeptr->tm_year = bcd2bin(date[6] & RV8803_YEAR_MASK) + RV8803_YEAR_OFFSET;
436 	timeptr->tm_yday = -1;  /* Unsupported */
437 	timeptr->tm_isdst = -1; /* Unsupported */
438 	timeptr->tm_nsec = 0;   /* Unsupported */
439 
440 	LOG_DBG("Read time: year: %d, month: %d, month day: %d, week day: %d, hour: %d, minute: "
441 		"%d, second: %d",
442 		timeptr->tm_year, timeptr->tm_mon, timeptr->tm_mday, timeptr->tm_wday,
443 		timeptr->tm_hour, timeptr->tm_min, timeptr->tm_sec);
444 
445 	return 0;
446 }
447 
448 #ifdef CONFIG_RTC_ALARM
449 
rv8803_alarm_get_supported_fields(const struct device * dev,uint16_t id,uint16_t * mask)450 static int rv8803_alarm_get_supported_fields(const struct device *dev, uint16_t id, uint16_t *mask)
451 {
452 	ARG_UNUSED(dev);
453 
454 	if (id != 0) {
455 		LOG_ERR("Invalid alarm ID: %d", id);
456 		return -EINVAL;
457 	}
458 
459 	*mask = RV8803_RTC_ALARM_TIME_MASK;
460 
461 	return 0;
462 }
463 
rv8803_alarm_set_time(const struct device * dev,uint16_t id,uint16_t mask,const struct rtc_time * timeptr)464 static int rv8803_alarm_set_time(const struct device *dev, uint16_t id, uint16_t mask,
465 				 const struct rtc_time *timeptr)
466 {
467 	uint8_t regs[3];
468 	uint8_t reg_val;
469 	int err;
470 
471 	if (id != 0) {
472 		LOG_ERR("Invalid alarm ID: %d", id);
473 		return -EINVAL;
474 	}
475 
476 	if (mask & ~RV8803_RTC_ALARM_TIME_MASK) {
477 		LOG_ERR("Unsupported alarm mask 0x%04X, excess field(s): 0x%04X", mask,
478 			mask & ~(int16_t)RV8803_RTC_ALARM_TIME_MASK);
479 		return -EINVAL;
480 	}
481 
482 	if ((mask & RTC_ALARM_TIME_MASK_MONTHDAY) && (mask & RTC_ALARM_TIME_MASK_WEEKDAY)) {
483 		LOG_ERR("Month day and week day alarms cannot be set simultaneously");
484 		return -EINVAL;
485 	}
486 
487 	if (!rtc_utils_validate_rtc_time(timeptr, mask)) {
488 		LOG_ERR("Invalid alarm time");
489 		return -EINVAL;
490 	}
491 
492 	if (mask & RTC_ALARM_TIME_MASK_MINUTE) {
493 		regs[0] = bin2bcd(timeptr->tm_min) & RV8803_MINUTES_ALARM_MASK;
494 	} else {
495 		regs[0] = RV8803_MINUTES_ALARM_AE_M_BIT;
496 	}
497 
498 	if (mask & RTC_ALARM_TIME_MASK_HOUR) {
499 		regs[1] = bin2bcd(timeptr->tm_hour) & RV8803_HOURS_ALARM_MASK;
500 	} else {
501 		regs[1] = RV8803_HOURS_ALARM_AE_H_BIT;
502 	}
503 
504 	if (mask & RTC_ALARM_TIME_MASK_MONTHDAY) {
505 		regs[2] = bin2bcd(timeptr->tm_mday) & RV8803_DATE_ALARM_MASK;
506 	} else if (mask & RTC_ALARM_TIME_MASK_WEEKDAY) {
507 		regs[2] = rv8803_weekday2mask(timeptr->tm_wday) & RV8803_WEEKDAY_ALARM_MASK;
508 	} else {
509 		regs[2] = RV8803_WEEKDAY_OR_DATE_ALARM_AE_WD_BIT;
510 	}
511 
512 	/* Update WADA bit */
513 	if ((mask & RTC_ALARM_TIME_MASK_MONTHDAY) || (mask & RTC_ALARM_TIME_MASK_WEEKDAY)) {
514 		reg_val = (mask & RTC_ALARM_TIME_MASK_MONTHDAY) ? RV8803_EXTENSION_WADA_BIT : 0;
515 		err = rv8803_update_reg8(dev, RV8803_EXTENSION_REG, RV8803_EXTENSION_WADA_BIT,
516 					 reg_val);
517 		if (err) {
518 			return err;
519 		}
520 	}
521 
522 	/* Update alarm registers */
523 	err = rv8803_write_regs(dev, RV8803_MINUTES_ALARM_REG, regs, sizeof(regs));
524 	if (err) {
525 		return err;
526 	}
527 
528 	LOG_DBG("Set alarm: month day: %d, week day: %d, hour: %d, minute: %d, mask: 0x%04X",
529 		timeptr->tm_mday, timeptr->tm_wday, timeptr->tm_hour, timeptr->tm_min, mask);
530 
531 	return 0;
532 }
533 
rv8803_alarm_get_time(const struct device * dev,uint16_t id,uint16_t * mask,struct rtc_time * timeptr)534 static int rv8803_alarm_get_time(const struct device *dev, uint16_t id, uint16_t *mask,
535 				 struct rtc_time *timeptr)
536 {
537 	uint8_t regs[3];
538 	uint8_t reg_val;
539 	int err;
540 
541 	if (id != 0) {
542 		LOG_ERR("Invalid alarm ID: %d", id);
543 		return -EINVAL;
544 	}
545 
546 	err = rv8803_read_regs(dev, RV8803_MINUTES_ALARM_REG, regs, sizeof(regs));
547 	if (err) {
548 		return err;
549 	}
550 
551 	/* Read extension register to get WADA bit */
552 	err = rv8803_read_reg8(dev, RV8803_EXTENSION_REG, &reg_val);
553 	if (err) {
554 		return err;
555 	}
556 
557 	memset(timeptr, 0, sizeof(*timeptr));
558 	*mask = 0;
559 
560 	if ((regs[0] & RV8803_MINUTES_ALARM_AE_M_BIT) == 0) {
561 		timeptr->tm_min = bcd2bin(regs[0] & RV8803_MINUTES_ALARM_MASK);
562 		*mask |= RTC_ALARM_TIME_MASK_MINUTE;
563 	}
564 
565 	if ((regs[1] & RV8803_HOURS_ALARM_AE_H_BIT) == 0) {
566 		timeptr->tm_hour = bcd2bin(regs[1] & RV8803_HOURS_ALARM_MASK);
567 		*mask |= RTC_ALARM_TIME_MASK_HOUR;
568 	}
569 
570 	if ((regs[2] & RV8803_WEEKDAY_OR_DATE_ALARM_AE_WD_BIT) == 0) {
571 		if (reg_val & RV8803_EXTENSION_WADA_BIT) {
572 			timeptr->tm_mday = bcd2bin(regs[2] & RV8803_DATE_ALARM_MASK);
573 			*mask |= RTC_ALARM_TIME_MASK_MONTHDAY;
574 		} else {
575 			timeptr->tm_wday = find_lsb_set(regs[2] & RV8803_WEEKDAY_ALARM_MASK);
576 			*mask |= RTC_ALARM_TIME_MASK_WEEKDAY;
577 		}
578 	}
579 
580 	LOG_DBG("Get alarm: month day: %d, week day: %d, hour: %d, minute: %d, mask: 0x%04X",
581 		timeptr->tm_mday, timeptr->tm_wday, timeptr->tm_hour, timeptr->tm_min, *mask);
582 
583 	return 0;
584 }
585 
rv8803_alarm_is_pending(const struct device * dev,uint16_t id)586 static int rv8803_alarm_is_pending(const struct device *dev, uint16_t id)
587 {
588 	uint8_t flags;
589 	int err;
590 
591 	if (id != 0) {
592 		LOG_ERR("Invalid alarm ID: %d", id);
593 		return -EINVAL;
594 	}
595 
596 	rv8803_lock_sem(dev);
597 
598 	do {
599 		err = rv8803_read_reg8(dev, RV8803_FLAG_REG, &flags);
600 		if (err) {
601 			break;
602 		}
603 
604 		if (flags & RV8803_FLAG_AF_BIT) {
605 			flags &= ~RV8803_FLAG_AF_BIT;
606 
607 			err = rv8803_write_reg8(dev, RV8803_FLAG_REG, flags);
608 			if (err) {
609 				break;
610 			}
611 
612 			/* Indicate that alarm is pending */
613 			err = 1;
614 		}
615 	} while (0);
616 
617 	rv8803_unlock_sem(dev);
618 
619 	return err;
620 }
621 
622 #ifdef RV8803_INT_GPIOS_IN_USE
623 
rv8803_alarm_set_callback(const struct device * dev,uint16_t id,rtc_alarm_callback callback,void * user_data)624 static int rv8803_alarm_set_callback(const struct device *dev, uint16_t id,
625 				     rtc_alarm_callback callback, void *user_data)
626 {
627 	const struct rv8803_config *config = dev->config;
628 	struct rv8803_data *data = dev->data;
629 	uint8_t reg_val;
630 	int err;
631 
632 	if (config->gpio_int.port == NULL) {
633 		return -ENOTSUP;
634 	}
635 
636 	if (id != 0) {
637 		LOG_ERR("Invalid alarm ID: %d", id);
638 		return -EINVAL;
639 	}
640 
641 	rv8803_lock_sem(dev);
642 
643 	data->alarm_callback = callback;
644 	data->alarm_user_data = user_data;
645 
646 	/* Enable alarm interrupt if callback provided */
647 	reg_val = (callback != NULL) ? RV8803_CONTROL_AIE_BIT : 0;
648 	err = rv8803_update_reg8(dev, RV8803_CONTROL_REG, RV8803_CONTROL_AIE_BIT, reg_val);
649 
650 	rv8803_unlock_sem(dev);
651 
652 	/* Alarm IRQ might have already been triggered */
653 	k_work_submit(&data->work);
654 
655 	return err;
656 }
657 
658 #endif
659 
660 #endif
661 
662 #if defined(RV8803_INT_GPIOS_IN_USE) && defined(CONFIG_RTC_UPDATE)
663 
rv8803_update_set_callback(const struct device * dev,rtc_update_callback callback,void * user_data)664 static int rv8803_update_set_callback(const struct device *dev, rtc_update_callback callback,
665 				      void *user_data)
666 {
667 	const struct rv8803_config *config = dev->config;
668 	struct rv8803_data *data = dev->data;
669 	uint8_t reg_val;
670 	int err;
671 
672 	if (config->gpio_int.port == NULL) {
673 		return -ENOTSUP;
674 	}
675 
676 	rv8803_lock_sem(dev);
677 
678 	data->update_callback = callback;
679 	data->update_user_data = user_data;
680 
681 	/* Enable update interrupt if callback provided */
682 	reg_val = (callback != NULL) ? RV8803_CONTROL_UIE_BIT : 0;
683 	err = rv8803_update_reg8(dev, RV8803_CONTROL_REG, RV8803_CONTROL_UIE_BIT, reg_val);
684 
685 	rv8803_unlock_sem(dev);
686 
687 	/* Update IRQ might have already been triggered */
688 	k_work_submit(&data->work);
689 
690 	return err;
691 }
692 
693 #endif
694 
695 #ifdef CONFIG_RTC_CALIBRATION
696 
rv8803_set_calibration(const struct device * dev,int32_t freq_ppb)697 static int rv8803_set_calibration(const struct device *dev, int32_t freq_ppb)
698 {
699 	int8_t offset;
700 
701 	if ((freq_ppb < RV8803_OFFSET_PPB_MIN) || (freq_ppb > RV8803_OFFSET_PPB_MAX)) {
702 		LOG_ERR("Calibration value %d ppb out of range", freq_ppb);
703 		return -EINVAL;
704 	}
705 
706 	offset = (freq_ppb / RV8803_OFFSET_PPB_PER_LSB) & RV8803_OFFSET_MASK;
707 
708 	LOG_DBG("Set calibration: frequency ppb: %d, offset value: %d", freq_ppb, offset);
709 
710 	return rv8803_write_reg8(dev, RV8803_OFFSET_REG, offset);
711 }
712 
rv8803_get_calibration(const struct device * dev,int32_t * freq_ppb)713 static int rv8803_get_calibration(const struct device *dev, int32_t *freq_ppb)
714 {
715 	int8_t offset;
716 	int err;
717 
718 	err = rv8803_read_reg8(dev, RV8803_OFFSET_REG, &offset);
719 	if (err) {
720 		return err;
721 	}
722 
723 	*freq_ppb = sign_extend(offset, RV8803_OFFSET_SIGN_BIT_INDEX) * RV8803_OFFSET_PPB_PER_LSB;
724 
725 	LOG_DBG("Get calibration: frequency ppb: %d, offset value: %d", *freq_ppb, offset);
726 
727 	return 0;
728 }
729 #endif
730 
rv8803_init(const struct device * dev)731 static int rv8803_init(const struct device *dev)
732 {
733 	const struct rv8803_config *config = dev->config;
734 	struct rv8803_data *data = dev->data;
735 	uint8_t freq;
736 	uint8_t regs[3];
737 	int err;
738 
739 	k_sem_init(&data->lock, 1, 1);
740 
741 	if (!i2c_is_ready_dt(&config->i2c)) {
742 		LOG_ERR("I2C bus not ready");
743 		return -ENODEV;
744 	}
745 
746 #ifdef RV8803_INT_GPIOS_IN_USE
747 	if (config->gpio_int.port != NULL) {
748 		if (!gpio_is_ready_dt(&config->gpio_int)) {
749 			LOG_ERR("GPIO not ready");
750 			return -ENODEV;
751 		}
752 
753 		err = gpio_pin_configure_dt(&config->gpio_int, GPIO_INPUT);
754 		if (err) {
755 			LOG_ERR("Failed to configure interrupt GPIO, error: %d", err);
756 			return err;
757 		}
758 
759 		err = gpio_pin_interrupt_configure_dt(&config->gpio_int, GPIO_INT_EDGE_TO_ACTIVE);
760 		if (err) {
761 			LOG_ERR("Failed to enable GPIO interrupt, error: %d", err);
762 			return err;
763 		}
764 
765 		gpio_init_callback(&data->irq_callback, rv8803_irq_handler,
766 				   BIT(config->gpio_int.pin));
767 
768 		err = gpio_add_callback_dt(&config->gpio_int, &data->irq_callback);
769 		if (err) {
770 			LOG_ERR("Failed to add GPIO callback, error: %d", err);
771 			return err;
772 		}
773 
774 		data->dev = dev;
775 		data->work.handler = rv8803_work_callback;
776 	}
777 #endif
778 
779 	/* Configure CLKOUT frequency */
780 	switch (config->clkout_freq) {
781 	case RV8803_PROP_ENUM_1HZ:
782 		freq = RV8803_EXTENSION_FD_1Hz;
783 		break;
784 	case RV8803_PROP_ENUM_1024HZ:
785 		freq = RV8803_EXTENSION_FD_1024Hz;
786 		break;
787 	case RV8803_PROP_ENUM_32768HZ:
788 	default:
789 		freq = RV8803_EXTENSION_FD_32768Hz;
790 		break;
791 	}
792 	err = rv8803_update_reg8(dev, RV8803_EXTENSION_REG, RV8803_EXTENSION_FD_MASK, freq);
793 	if (err) {
794 		return -ENODEV;
795 	}
796 
797 	/* Clear alarm and update flag */
798 	err = rv8803_update_reg8(dev, RV8803_CONTROL_REG, RV8803_FLAG_AF_BIT | RV8803_FLAG_UF_BIT,
799 				 RV8803_FLAG_AF_BIT | RV8803_FLAG_UF_BIT);
800 	if (err) {
801 		return -ENODEV;
802 	}
803 
804 	/* Disable IRQs */
805 	err = rv8803_update_reg8(dev, RV8803_CONTROL_REG,
806 				 RV8803_CONTROL_AIE_BIT | RV8803_CONTROL_UIE_BIT, 0);
807 	if (err) {
808 		return -ENODEV;
809 	}
810 
811 	/* Disable alarms */
812 	err = rv8803_read_regs(dev, RV8803_MINUTES_ALARM_REG, regs, sizeof(regs));
813 	if (err) {
814 		return -ENODEV;
815 	}
816 
817 	regs[0] |= RV8803_MINUTES_ALARM_AE_M_BIT;
818 	regs[1] |= RV8803_HOURS_ALARM_AE_H_BIT;
819 	regs[2] |= RV8803_WEEKDAY_OR_DATE_ALARM_AE_WD_BIT;
820 
821 	err = rv8803_write_regs(dev, RV8803_MINUTES_ALARM_REG, regs, sizeof(regs));
822 	if (err) {
823 		return -ENODEV;
824 	}
825 
826 	return 0;
827 }
828 
829 static DEVICE_API(rtc, rv8803_driver_api) = {
830 	.set_time = rv8803_set_time,
831 	.get_time = rv8803_get_time,
832 #ifdef CONFIG_RTC_ALARM
833 	.alarm_get_supported_fields = rv8803_alarm_get_supported_fields,
834 	.alarm_set_time = rv8803_alarm_set_time,
835 	.alarm_get_time = rv8803_alarm_get_time,
836 	.alarm_is_pending = rv8803_alarm_is_pending,
837 #ifdef RV8803_INT_GPIOS_IN_USE
838 	.alarm_set_callback = rv8803_alarm_set_callback,
839 #endif
840 #endif
841 #if defined(RV8803_INT_GPIOS_IN_USE) && defined(CONFIG_RTC_UPDATE)
842 	.update_set_callback = rv8803_update_set_callback,
843 #endif
844 #ifdef CONFIG_RTC_CALIBRATION
845 	.set_calibration = rv8803_set_calibration,
846 	.get_calibration = rv8803_get_calibration
847 #endif
848 };
849 
850 #define RV8803_INIT(inst)                                                                          \
851 	static const struct rv8803_config rv8803_config_##inst = {                                 \
852 		.i2c = I2C_DT_SPEC_INST_GET(inst),                                                 \
853 		.clkout_freq = DT_INST_ENUM_IDX_OR(inst, clkout_frequency, 0),                     \
854 		IF_ENABLED(                                                                        \
855 			RV8803_INT_GPIOS_IN_USE,                                                   \
856 			(.gpio_int = GPIO_DT_SPEC_INST_GET_OR(inst, int_gpios, {0}))               \
857 		)                                                                                  \
858 	};                                                                                         \
859                                                                                                    \
860 	static struct rv8803_data rv8803_data_##inst;                                              \
861                                                                                                    \
862 	DEVICE_DT_INST_DEFINE(inst, rv8803_init, NULL, &rv8803_data_##inst, &rv8803_config_##inst, \
863 			      POST_KERNEL, CONFIG_RTC_INIT_PRIORITY, &rv8803_driver_api);
864 
865 DT_INST_FOREACH_STATUS_OKAY(RV8803_INIT);
866