Skip to content

Commit

Permalink
drivers: rtc: rv8263-c8: Alarm reworking
Browse files Browse the repository at this point in the history
- Fix typos for alarm field identification
- Fix a bug where an alarm interrupt starts
update interrupts
- Rework interrupt code to reduce code size
and complexity

Signed-off-by: Daniel Kampert <danielkampert@kampis-elektroecke.de>
  • Loading branch information
Kampi authored and mmahadevan108 committed Nov 6, 2024
1 parent e20c095 commit ec10d56
Showing 1 changed file with 43 additions and 51 deletions.
94 changes: 43 additions & 51 deletions drivers/rtc/rtc_rv8263.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,16 +86,18 @@ struct rv8263c8_data {
struct gpio_callback gpio_cb;
#endif

#if (CONFIG_RTC_ALARM || CONFIG_RTC_UPDATE) && DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios)
struct k_work interrupt_work;
#endif

#if CONFIG_RTC_ALARM && DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios)
rtc_alarm_callback alarm_cb;
void *alarm_cb_data;
struct k_work alarm_work;
#endif

#if CONFIG_RTC_UPDATE && DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios)
rtc_update_callback update_cb;
void *update_cb_data;
struct k_work update_work;
#endif
};

Expand Down Expand Up @@ -126,41 +128,12 @@ static void rv8263c8_gpio_callback_handler(const struct device *p_port, struct g

struct rv8263c8_data *data = CONTAINER_OF(p_cb, struct rv8263c8_data, gpio_cb);

#if CONFIG_RTC_ALARM
k_work_submit(&data->alarm_work);
#endif

#if CONFIG_RTC_UPDATE
k_work_submit(&data->update_work);
#if CONFIG_RTC_ALARM || CONFIG_RTC_UPDATE
k_work_submit(&data->interrupt_work);
#endif
}
#endif

#if CONFIG_RTC_ALARM && DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios)
static void rv8263c8_alarm_worker(struct k_work *p_work)
{
struct rv8263c8_data *data = CONTAINER_OF(p_work, struct rv8263c8_data, alarm_work);
const struct rv8263c8_config *config = data->dev->config;

LOG_DBG("Process alarm worker from interrupt");

if (data->alarm_cb != NULL) {
uint8_t reg;

i2c_reg_read_byte_dt(&config->i2c_bus, RV8263C8_REGISTER_CONTROL_2, &reg);

if (reg & RV8263C8_BM_AF) {
reg &= ~RV8263C8_BM_AF;

LOG_DBG("Calling alarm callback");
data->alarm_cb(data->dev, 0, data->alarm_cb_data);

i2c_reg_write_byte_dt(&config->i2c_bus, RV8263C8_REGISTER_CONTROL_2, reg);
}
}
}
#endif

#if CONFIG_RTC_UPDATE && DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios)
static int rv8263c8_update_enable_timer(const struct device *dev)
{
Expand All @@ -181,27 +154,48 @@ static int rv8263c8_update_enable_timer(const struct device *dev)
RV8263_BM_TI_TP_PULSE;
return i2c_write_dt(&config->i2c_bus, buf, 2);
}
#endif

static void rv8263c8_update_worker(struct k_work *p_work)
#if (CONFIG_RTC_ALARM || CONFIG_RTC_UPDATE) && DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios)
static void rv8263c8_interrupt_worker(struct k_work *p_work)
{
uint8_t reg;
struct rv8263c8_data *data = CONTAINER_OF(p_work, struct rv8263c8_data, update_work);
struct rv8263c8_data *data = CONTAINER_OF(p_work, struct rv8263c8_data, interrupt_work);
const struct rv8263c8_config *config = data->dev->config;

LOG_DBG("Process update worker from interrupt");
i2c_reg_read_byte_dt(&config->i2c_bus, RV8263C8_REGISTER_CONTROL_2, &reg);

if (data->update_cb != NULL) {
i2c_reg_read_byte_dt(&config->i2c_bus, RV8263C8_REGISTER_CONTROL_2, &reg);
#if CONFIG_RTC_ALARM
/* An alarm interrupt occurs. Clear the timer flag, */
/* and call the callback. */
if (reg & RV8263C8_BM_AF) {
LOG_DBG("Process alarm interrupt");
reg &= ~RV8263C8_BM_AF;

if (reg & RV8263C8_BM_TF) {
if (data->alarm_cb != NULL) {
LOG_DBG("Calling alarm callback");
data->alarm_cb(data->dev, 0, data->alarm_cb_data);
}
}
#endif

#if CONFIG_RTC_UPDATE
/* A timer interrupt occurs. Clear the timer flag, */
/* enable the timer again and call the callback. */
if (reg & RV8263C8_BM_TF) {
LOG_DBG("Process update interrupt");
reg &= ~RV8263C8_BM_TF;

if (data->update_cb != NULL) {
LOG_DBG("Calling update callback");
data->update_cb(data->dev, data->update_cb_data);
}

rv8263c8_update_enable_timer(data->dev);
}
#endif

rv8263c8_update_enable_timer(data->dev);
i2c_reg_update_byte_dt(&config->i2c_bus, RV8263C8_REGISTER_CONTROL_2, RV8263C8_BM_TF,
RV8263C8_BM_TF);
i2c_reg_write_byte_dt(&config->i2c_bus, RV8263C8_REGISTER_CONTROL_2, reg);
}
#endif

Expand Down Expand Up @@ -336,6 +330,7 @@ static int rv8263c8_init(const struct device *dev)
#endif

#if (CONFIG_RTC_ALARM || CONFIG_RTC_UPDATE) && DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios)
LOG_DBG("Configure interrupt pin");
if (!gpio_is_ready_dt(&config->int_gpio)) {
LOG_ERR("GPIO not ready!");
return err;
Expand Down Expand Up @@ -364,18 +359,15 @@ static int rv8263c8_init(const struct device *dev)
#endif

(void)k_sem_take(&data->lock, K_FOREVER);
#if CONFIG_RTC_ALARM && DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios)
data->alarm_work.handler = rv8263c8_alarm_worker;
#endif

#if CONFIG_RTC_UPDATE && DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios)
data->update_work.handler = rv8263c8_update_worker;
#if (CONFIG_RTC_ALARM || CONFIG_RTC_UPDATE) && DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios)
data->interrupt_work.handler = rv8263c8_interrupt_worker;
#endif

#if (CONFIG_RTC_ALARM || CONFIG_RTC_UPDATE) && DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios)
data->dev = dev;
#endif
k_sem_give(&data->lock);
LOG_DBG("Done");

return 0;
}
Expand Down Expand Up @@ -442,19 +434,19 @@ static int rv8263c8_alarm_set_time(const struct device *dev, uint16_t id, uint16
}

if (mask & RTC_ALARM_TIME_MASK_HOUR) {
regs[3] = bin2bcd(timeptr->tm_min) & HOURS_BITS;
regs[3] = bin2bcd(timeptr->tm_hour) & HOURS_BITS;
} else {
regs[3] = RV8263C8_BM_ALARM_DISABLE;
}

if (mask & RTC_ALARM_TIME_MASK_MONTHDAY) {
regs[4] = bin2bcd(timeptr->tm_min) & DATE_BITS;
regs[4] = bin2bcd(timeptr->tm_mday) & DATE_BITS;
} else {
regs[4] = RV8263C8_BM_ALARM_DISABLE;
}

if (mask & RTC_ALARM_TIME_MASK_WEEKDAY) {
regs[5] = bin2bcd(timeptr->tm_min) & WEEKDAY_BITS;
regs[5] = bin2bcd(timeptr->tm_wday) & WEEKDAY_BITS;
} else {
regs[5] = RV8263C8_BM_ALARM_DISABLE;
}
Expand Down

0 comments on commit ec10d56

Please sign in to comment.