/* * Copyright (c) 2024 Gergo Vari * SPDX-License-Identifier: Apache-2.0 */ #include #include #include #include #include LOG_MODULE_REGISTER(mfd_ds3231, CONFIG_MFD_LOG_LEVEL); #define DT_DRV_COMPAT maxim_ds3231_mfd struct mfd_ds3231_data { struct k_sem lock; const struct device *dev; }; struct mfd_ds3231_conf { struct i2c_dt_spec i2c_bus; }; int mfd_ds3231_i2c_get_registers(const struct device *dev, uint8_t start_reg, uint8_t *buf, const size_t buf_size) { struct mfd_ds3231_data *data = dev->data; const struct mfd_ds3231_conf *config = dev->config; /* FIXME: bad start_reg/buf_size values break i2c for that run */ (void)k_sem_take(&data->lock, K_FOREVER); int err = i2c_burst_read_dt(&config->i2c_bus, start_reg, buf, buf_size); k_sem_give(&data->lock); return err; } int mfd_ds3231_i2c_set_registers(const struct device *dev, uint8_t start_reg, const uint8_t *buf, const size_t buf_size) { struct mfd_ds3231_data *data = dev->data; const struct mfd_ds3231_conf *config = dev->config; (void)k_sem_take(&data->lock, K_FOREVER); int err = i2c_burst_write_dt(&config->i2c_bus, start_reg, buf, buf_size); k_sem_give(&data->lock); return err; } static int mfd_ds3231_init(const struct device *dev) { struct mfd_ds3231_data *data = dev->data; const struct mfd_ds3231_conf *config = (struct mfd_ds3231_conf *)(dev->config); k_sem_init(&data->lock, 1, 1); if (!i2c_is_ready_dt(&(config->i2c_bus))) { LOG_ERR("I2C bus not ready."); return -ENODEV; } return 0; } #define MFD_DS3231_DEFINE(inst) \ static const struct mfd_ds3231_conf config##inst = {.i2c_bus = \ I2C_DT_SPEC_INST_GET(inst)}; \ static struct mfd_ds3231_data data##inst; \ DEVICE_DT_INST_DEFINE(inst, &mfd_ds3231_init, NULL, &data##inst, &config##inst, \ POST_KERNEL, CONFIG_MFD_INIT_PRIORITY, NULL); DT_INST_FOREACH_STATUS_OKAY(MFD_DS3231_DEFINE)