You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
77 lines
2.1 KiB
77 lines
2.1 KiB
/* |
|
* Copyright (c) 2024 Gergo Vari <work@gergovari.com> |
|
* SPDX-License-Identifier: Apache-2.0 |
|
*/ |
|
|
|
#include <zephyr/drivers/mfd/ds3231.h> |
|
|
|
#include <zephyr/kernel.h> |
|
#include <zephyr/drivers/i2c.h> |
|
|
|
#include <zephyr/sys/util.h> |
|
|
|
#include <zephyr/logging/log.h> |
|
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)
|
|
|