Organizes sensor drivers by vendor to distribute maintainership responsibilities. Signed-off-by: Maureen Helm <maureen.helm@analog.com>
136 lines
3.7 KiB
C
136 lines
3.7 KiB
C
/*
|
|
* Copyright 2023 Daniel DeGrasse <daniel@degrasse.com>
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#define DT_DRV_COMPAT microchip_tcn75a
|
|
|
|
#include <zephyr/logging/log.h>
|
|
LOG_MODULE_REGISTER(tcn75a, CONFIG_SENSOR_LOG_LEVEL);
|
|
|
|
#include "tcn75a.h"
|
|
|
|
int tcn75a_sample_fetch(const struct device *dev, enum sensor_channel chan)
|
|
{
|
|
const struct tcn75a_config *config = dev->config;
|
|
struct tcn75a_data *data = dev->data;
|
|
int ret;
|
|
uint8_t temp_reg = TCN75A_TEMP_REG;
|
|
uint8_t rx_buf[2];
|
|
uint8_t adc_conf[2] = {TCN75A_CONFIG_REG, 0x0};
|
|
/* This sensor only supports ambient temperature */
|
|
if ((chan != SENSOR_CHAN_ALL) && (chan != SENSOR_CHAN_AMBIENT_TEMP)) {
|
|
return -ENOTSUP;
|
|
}
|
|
|
|
if (config->oneshot_mode) {
|
|
/* Oneshot mode, requires one shot bit to be set in config register */
|
|
adc_conf[1] = TCN75A_CONFIG_ONEDOWN;
|
|
ret = i2c_write_dt(&config->i2c_spec, adc_conf, 2);
|
|
if (ret < 0) {
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
/* Fetch a sample from the 2 byte ambient temperature register */
|
|
ret = i2c_write_read_dt(&config->i2c_spec, &temp_reg, sizeof(temp_reg),
|
|
rx_buf, sizeof(rx_buf));
|
|
if (ret < 0) {
|
|
return ret;
|
|
}
|
|
|
|
data->temp_sample = sys_get_be16(rx_buf);
|
|
LOG_DBG("Raw sample: 0x%04x", data->temp_sample);
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int tcn75a_channel_get(const struct device *dev, enum sensor_channel chan,
|
|
struct sensor_value *val)
|
|
{
|
|
struct tcn75a_data *data = dev->data;
|
|
uint32_t temp_lsb;
|
|
|
|
if (chan != SENSOR_CHAN_AMBIENT_TEMP) {
|
|
return -ENOTSUP;
|
|
}
|
|
|
|
/* Convert fixed point to sensor value */
|
|
val->val1 = data->temp_sample >> TCN75A_TEMP_MSB_POS;
|
|
temp_lsb = (data->temp_sample & TCN75A_TEMP_LSB_MASK);
|
|
val->val2 = TCN75A_FIXED_PT_TO_SENSOR(temp_lsb);
|
|
return 0;
|
|
}
|
|
|
|
static const struct sensor_driver_api tcn75a_api = {
|
|
.sample_fetch = &tcn75a_sample_fetch,
|
|
.channel_get = &tcn75a_channel_get,
|
|
#ifdef CONFIG_TCN75A_TRIGGER
|
|
.attr_get = &tcn75a_attr_get,
|
|
.attr_set = &tcn75a_attr_set,
|
|
.trigger_set = &tcn75a_trigger_set,
|
|
#endif
|
|
};
|
|
|
|
static int tcn75a_init(const struct device *dev)
|
|
{
|
|
const struct tcn75a_config *config = dev->config;
|
|
uint8_t adc_conf[2] = {TCN75A_CONFIG_REG, 0x0};
|
|
|
|
if (!i2c_is_ready_dt(&config->i2c_spec)) {
|
|
LOG_ERR("I2C bus is not ready");
|
|
return -ENODEV;
|
|
}
|
|
|
|
/* Set user selected resolution */
|
|
adc_conf[1] |= TCN75A_CONFIG_RES(config->resolution);
|
|
|
|
if (config->oneshot_mode) {
|
|
if (adc_conf[1] != 0) {
|
|
/* Oneshot mode only supports 9 bit resolution */
|
|
LOG_ERR("Oneshot mode requires 9 bit resolution");
|
|
return -ENODEV;
|
|
}
|
|
adc_conf[1] |= TCN75A_CONFIG_SHUTDOWN;
|
|
}
|
|
|
|
#ifdef CONFIG_TCN75A_TRIGGER
|
|
/* If user supplies an ALERT gpio, assume they want trigger support. */
|
|
if (config->alert_gpios.port != NULL) {
|
|
int ret;
|
|
|
|
if (config->oneshot_mode) {
|
|
LOG_ERR("Oneshot mode not supported with trigger");
|
|
return -ENODEV;
|
|
}
|
|
|
|
ret = tcn75a_trigger_init(dev);
|
|
if (ret < 0) {
|
|
return ret;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
return i2c_write_dt(&config->i2c_spec, adc_conf, 2);
|
|
}
|
|
|
|
#ifdef CONFIG_TCN75A_TRIGGER
|
|
#define TCN75A_TRIGGER(n) .alert_gpios = GPIO_DT_SPEC_INST_GET_OR(n, alert_gpios, {}),
|
|
#else
|
|
#define TCN75A_TRIGGER(n)
|
|
#endif
|
|
|
|
#define TCN75A_INIT(n) \
|
|
static struct tcn75a_data tcn75a_data_##n; \
|
|
static const struct tcn75a_config tcn75a_config_##n = { \
|
|
.i2c_spec = I2C_DT_SPEC_INST_GET(n), \
|
|
.resolution = DT_INST_ENUM_IDX(n, resolution), \
|
|
.oneshot_mode = DT_INST_PROP(n, oneshot_mode), \
|
|
TCN75A_TRIGGER(n) \
|
|
}; \
|
|
SENSOR_DEVICE_DT_INST_DEFINE(n, &tcn75a_init, NULL, &tcn75a_data_##n, &tcn75a_config_##n, \
|
|
POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, &tcn75a_api);
|
|
|
|
DT_INST_FOREACH_STATUS_OKAY(TCN75A_INIT)
|