drivers: gpio: implement GPIOs in ADS114S08
Implement GPIO exander within the ADC ADS114S08. Signed-off-by: Benedikt Schmidt <benedikt.schmidt@embedded-solutions.at>
This commit is contained in:
parent
53683f6195
commit
ecac441171
|
@ -23,3 +23,13 @@ config ADC_ADS114S0X_ACQUISITION_THREAD_STACK_SIZE
|
|||
help
|
||||
Size of the stack used for the internal data acquisition
|
||||
thread.
|
||||
|
||||
config ADC_ADS114S0X_GPIO
|
||||
bool "GPIO support"
|
||||
default n
|
||||
depends on GPIO && ADC_ADS114S0X
|
||||
help
|
||||
Enable GPIO child device support in the ADS114S0x ADC driver.
|
||||
|
||||
The GPIO functionality is handled by the ADS114S0x GPIO
|
||||
driver.
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <zephyr/device.h>
|
||||
#include <zephyr/devicetree.h>
|
||||
#include <zephyr/drivers/adc.h>
|
||||
#include <zephyr/drivers/adc/ads114s0x.h>
|
||||
#include <zephyr/drivers/spi.h>
|
||||
#include <zephyr/drivers/gpio.h>
|
||||
#include <zephyr/logging/log.h>
|
||||
|
@ -26,6 +27,7 @@ LOG_MODULE_REGISTER(ads114s0x, CONFIG_ADC_LOG_LEVEL);
|
|||
#define ADS114S0X_INPUT_SELECTION_AINCOM 12
|
||||
#define ADS114S0X_RESOLUTION 16
|
||||
#define ADS114S0X_REF_INTERNAL 2500
|
||||
#define ADS114S0X_GPIO_MAX 3
|
||||
#define ADS114S0X_POWER_ON_RESET_TIME_IN_US 2200
|
||||
|
||||
/* Not mentioned in the datasheet, but instead determined experimentally. */
|
||||
|
@ -272,6 +274,70 @@ enum ads114s0x_register {
|
|||
#define ADS114S0X_REGISTER_REF_REFCON_SET(target, value) \
|
||||
ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_REF_REFCON_POS, \
|
||||
ADS114S0X_REGISTER_REF_REFCON_LENGTH)
|
||||
#define ADS114S0X_REGISTER_IDACMAG_FL_RAIL_EN_LENGTH 1
|
||||
#define ADS114S0X_REGISTER_IDACMAG_FL_RAIL_EN_POS 7
|
||||
#define ADS114S0X_REGISTER_IDACMAG_FL_RAIL_EN_GET(value) \
|
||||
ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_IDACMAG_FL_RAIL_EN_POS, \
|
||||
ADS114S0X_REGISTER_IDACMAG_FL_RAIL_EN_LENGTH)
|
||||
#define ADS114S0X_REGISTER_IDACMAG_FL_RAIL_EN_SET(target, value) \
|
||||
ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_IDACMAG_FL_RAIL_EN_POS, \
|
||||
ADS114S0X_REGISTER_IDACMAG_FL_RAIL_EN_LENGTH)
|
||||
#define ADS114S0X_REGISTER_IDACMAG_PSW_LENGTH 1
|
||||
#define ADS114S0X_REGISTER_IDACMAG_PSW_POS 6
|
||||
#define ADS114S0X_REGISTER_IDACMAG_PSW_GET(value) \
|
||||
ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_IDACMAG_PSW_POS, \
|
||||
ADS114S0X_REGISTER_IDACMAG_PSW_LENGTH)
|
||||
#define ADS114S0X_REGISTER_IDACMAG_PSW_SET(target, value) \
|
||||
ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_IDACMAG_PSW_POS, \
|
||||
ADS114S0X_REGISTER_IDACMAG_PSW_LENGTH)
|
||||
#define ADS114S0X_REGISTER_IDACMAG_IMAG_LENGTH 4
|
||||
#define ADS114S0X_REGISTER_IDACMAG_IMAG_POS 0
|
||||
#define ADS114S0X_REGISTER_IDACMAG_IMAG_GET(value) \
|
||||
ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_IDACMAG_IMAG_POS, \
|
||||
ADS114S0X_REGISTER_IDACMAG_IMAG_LENGTH)
|
||||
#define ADS114S0X_REGISTER_IDACMAG_IMAG_SET(target, value) \
|
||||
ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_IDACMAG_IMAG_POS, \
|
||||
ADS114S0X_REGISTER_IDACMAG_IMAG_LENGTH)
|
||||
#define ADS114S0X_REGISTER_IDACMUX_I2MUX_LENGTH 4
|
||||
#define ADS114S0X_REGISTER_IDACMUX_I2MUX_POS 4
|
||||
#define ADS114S0X_REGISTER_IDACMUX_I2MUX_GET(value) \
|
||||
ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_IDACMUX_I2MUX_POS, \
|
||||
ADS114S0X_REGISTER_IDACMUX_I2MUX_LENGTH)
|
||||
#define ADS114S0X_REGISTER_IDACMUX_I2MUX_SET(target, value) \
|
||||
ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_IDACMUX_I2MUX_POS, \
|
||||
ADS114S0X_REGISTER_IDACMUX_I2MUX_LENGTH)
|
||||
#define ADS114S0X_REGISTER_IDACMUX_I1MUX_LENGTH 4
|
||||
#define ADS114S0X_REGISTER_IDACMUX_I1MUX_POS 0
|
||||
#define ADS114S0X_REGISTER_IDACMUX_I1MUX_GET(value) \
|
||||
ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_IDACMUX_I1MUX_POS, \
|
||||
ADS114S0X_REGISTER_IDACMUX_I1MUX_LENGTH)
|
||||
#define ADS114S0X_REGISTER_IDACMUX_I1MUX_SET(target, value) \
|
||||
ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_IDACMUX_I1MUX_POS, \
|
||||
ADS114S0X_REGISTER_IDACMUX_I1MUX_LENGTH)
|
||||
#define ADS114S0X_REGISTER_GPIODAT_DIR_LENGTH 4
|
||||
#define ADS114S0X_REGISTER_GPIODAT_DIR_POS 4
|
||||
#define ADS114S0X_REGISTER_GPIODAT_DIR_GET(value) \
|
||||
ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_GPIODAT_DIR_POS, \
|
||||
ADS114S0X_REGISTER_GPIODAT_DIR_LENGTH)
|
||||
#define ADS114S0X_REGISTER_GPIODAT_DIR_SET(target, value) \
|
||||
ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_GPIODAT_DIR_POS, \
|
||||
ADS114S0X_REGISTER_GPIODAT_DIR_LENGTH)
|
||||
#define ADS114S0X_REGISTER_GPIODAT_DAT_LENGTH 4
|
||||
#define ADS114S0X_REGISTER_GPIODAT_DAT_POS 0
|
||||
#define ADS114S0X_REGISTER_GPIODAT_DAT_GET(value) \
|
||||
ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_GPIODAT_DAT_POS, \
|
||||
ADS114S0X_REGISTER_GPIODAT_DAT_LENGTH)
|
||||
#define ADS114S0X_REGISTER_GPIODAT_DAT_SET(target, value) \
|
||||
ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_GPIODAT_DAT_POS, \
|
||||
ADS114S0X_REGISTER_GPIODAT_DAT_LENGTH)
|
||||
#define ADS114S0X_REGISTER_GPIOCON_CON_LENGTH 4
|
||||
#define ADS114S0X_REGISTER_GPIOCON_CON_POS 0
|
||||
#define ADS114S0X_REGISTER_GPIOCON_CON_GET(value) \
|
||||
ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_GPIOCON_CON_POS, \
|
||||
ADS114S0X_REGISTER_GPIOCON_CON_LENGTH)
|
||||
#define ADS114S0X_REGISTER_GPIOCON_CON_SET(target, value) \
|
||||
ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_GPIOCON_CON_POS, \
|
||||
ADS114S0X_REGISTER_GPIOCON_CON_LENGTH)
|
||||
|
||||
/*
|
||||
* - AIN0 as positive input
|
||||
|
@ -330,12 +396,18 @@ struct ads114s0x_data {
|
|||
struct adc_context ctx;
|
||||
#if CONFIG_ADC_ASYNC
|
||||
struct k_thread thread;
|
||||
#endif
|
||||
#endif /* CONFIG_ADC_ASYNC */
|
||||
struct gpio_callback callback_data_ready;
|
||||
struct k_sem data_ready_signal;
|
||||
struct k_sem acquire_signal;
|
||||
int16_t *buffer;
|
||||
int16_t *buffer_ptr;
|
||||
#if CONFIG_ADC_ADS114S0X_GPIO
|
||||
struct k_mutex gpio_lock;
|
||||
uint8_t gpio_enabled; /* one bit per GPIO, 1 = enabled */
|
||||
uint8_t gpio_direction; /* one bit per GPIO, 1 = input */
|
||||
uint8_t gpio_value; /* one bit per GPIO, 1 = high */
|
||||
#endif /* CONFIG_ADC_ADS114S0X_GPIO */
|
||||
};
|
||||
|
||||
static void ads114s0x_data_ready_handler(const struct device *dev, struct gpio_callback *gpio_cb,
|
||||
|
@ -870,6 +942,227 @@ static void ads114s0x_acquisition_thread(struct device *dev)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ADC_ADS114S0X_GPIO
|
||||
static int ads114s0x_gpio_write_config(const struct device *dev)
|
||||
{
|
||||
struct ads114s0x_data *data = dev->data;
|
||||
const struct ads114s0x_config *config = dev->config;
|
||||
uint8_t register_addresses[2];
|
||||
uint8_t register_values[ARRAY_SIZE(register_addresses)];
|
||||
uint8_t gpio_dat = 0;
|
||||
uint8_t gpio_con = 0;
|
||||
|
||||
ADS114S0X_REGISTER_GPIOCON_CON_SET(gpio_con, data->gpio_enabled);
|
||||
ADS114S0X_REGISTER_GPIODAT_DAT_SET(gpio_dat, data->gpio_value);
|
||||
ADS114S0X_REGISTER_GPIODAT_DIR_SET(gpio_dat, data->gpio_direction);
|
||||
|
||||
register_values[0] = gpio_dat;
|
||||
register_values[1] = gpio_con;
|
||||
register_addresses[0] = ADS114S0X_REGISTER_GPIODAT;
|
||||
register_addresses[1] = ADS114S0X_REGISTER_GPIOCON;
|
||||
return ads114s0x_write_multiple_registers(&config->bus, register_addresses, register_values,
|
||||
ARRAY_SIZE(register_values));
|
||||
}
|
||||
|
||||
static int ads114s0x_gpio_write_value(const struct device *dev)
|
||||
{
|
||||
struct ads114s0x_data *data = dev->data;
|
||||
const struct ads114s0x_config *config = dev->config;
|
||||
uint8_t gpio_dat = 0;
|
||||
|
||||
ADS114S0X_REGISTER_GPIODAT_DAT_SET(gpio_dat, data->gpio_value);
|
||||
ADS114S0X_REGISTER_GPIODAT_DIR_SET(gpio_dat, data->gpio_direction);
|
||||
|
||||
return ads114s0x_write_register(&config->bus, ADS114S0X_REGISTER_GPIODAT, gpio_dat);
|
||||
}
|
||||
|
||||
int ads114s0x_gpio_set_output(const struct device *dev, uint8_t pin, bool initial_value)
|
||||
{
|
||||
struct ads114s0x_data *data = dev->data;
|
||||
int result = 0;
|
||||
|
||||
if (pin > ADS114S0X_GPIO_MAX) {
|
||||
LOG_ERR("invalid pin %i", pin);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
k_mutex_lock(&data->gpio_lock, K_FOREVER);
|
||||
|
||||
data->gpio_enabled |= BIT(pin);
|
||||
data->gpio_direction &= ~BIT(pin);
|
||||
|
||||
if (initial_value) {
|
||||
data->gpio_value |= BIT(pin);
|
||||
} else {
|
||||
data->gpio_value &= ~BIT(pin);
|
||||
}
|
||||
|
||||
result = ads114s0x_gpio_write_config(dev);
|
||||
|
||||
k_mutex_unlock(&data->gpio_lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int ads114s0x_gpio_set_input(const struct device *dev, uint8_t pin)
|
||||
{
|
||||
struct ads114s0x_data *data = dev->data;
|
||||
int result = 0;
|
||||
|
||||
if (pin > ADS114S0X_GPIO_MAX) {
|
||||
LOG_ERR("invalid pin %i", pin);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
k_mutex_lock(&data->gpio_lock, K_FOREVER);
|
||||
|
||||
data->gpio_enabled |= BIT(pin);
|
||||
data->gpio_direction |= BIT(pin);
|
||||
data->gpio_value &= ~BIT(pin);
|
||||
|
||||
result = ads114s0x_gpio_write_config(dev);
|
||||
|
||||
k_mutex_unlock(&data->gpio_lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int ads114s0x_gpio_deconfigure(const struct device *dev, uint8_t pin)
|
||||
{
|
||||
struct ads114s0x_data *data = dev->data;
|
||||
int result = 0;
|
||||
|
||||
if (pin > ADS114S0X_GPIO_MAX) {
|
||||
LOG_ERR("invalid pin %i", pin);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
k_mutex_lock(&data->gpio_lock, K_FOREVER);
|
||||
|
||||
data->gpio_enabled &= ~BIT(pin);
|
||||
data->gpio_direction |= BIT(pin);
|
||||
data->gpio_value &= ~BIT(pin);
|
||||
|
||||
result = ads114s0x_gpio_write_config(dev);
|
||||
|
||||
k_mutex_unlock(&data->gpio_lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int ads114s0x_gpio_set_pin_value(const struct device *dev, uint8_t pin, bool value)
|
||||
{
|
||||
struct ads114s0x_data *data = dev->data;
|
||||
int result = 0;
|
||||
|
||||
if (pin > ADS114S0X_GPIO_MAX) {
|
||||
LOG_ERR("invalid pin %i", pin);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
k_mutex_lock(&data->gpio_lock, K_FOREVER);
|
||||
|
||||
if ((BIT(pin) & data->gpio_enabled) == 0) {
|
||||
LOG_ERR("gpio pin %i not configured", pin);
|
||||
result = -EINVAL;
|
||||
} else if ((BIT(pin) & data->gpio_direction) != 0) {
|
||||
LOG_ERR("gpio pin %i not configured as output", pin);
|
||||
result = -EINVAL;
|
||||
} else {
|
||||
data->gpio_value |= BIT(pin);
|
||||
|
||||
result = ads114s0x_gpio_write_value(dev);
|
||||
}
|
||||
|
||||
k_mutex_unlock(&data->gpio_lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int ads114s0x_gpio_get_pin_value(const struct device *dev, uint8_t pin, bool *value)
|
||||
{
|
||||
struct ads114s0x_data *data = dev->data;
|
||||
const struct ads114s0x_config *config = dev->config;
|
||||
int result = 0;
|
||||
uint8_t gpio_dat;
|
||||
|
||||
if (pin > ADS114S0X_GPIO_MAX) {
|
||||
LOG_ERR("invalid pin %i", pin);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
k_mutex_lock(&data->gpio_lock, K_FOREVER);
|
||||
|
||||
if ((BIT(pin) & data->gpio_enabled) == 0) {
|
||||
LOG_ERR("gpio pin %i not configured", pin);
|
||||
result = -EINVAL;
|
||||
} else if ((BIT(pin) & data->gpio_direction) == 0) {
|
||||
LOG_ERR("gpio pin %i not configured as input", pin);
|
||||
result = -EINVAL;
|
||||
} else {
|
||||
result = ads114s0x_read_register(&config->bus, ADS114S0X_REGISTER_GPIODAT,
|
||||
&gpio_dat);
|
||||
data->gpio_value = ADS114S0X_REGISTER_GPIODAT_DAT_GET(gpio_dat);
|
||||
*value = (BIT(pin) & data->gpio_value) != 0;
|
||||
}
|
||||
|
||||
k_mutex_unlock(&data->gpio_lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int ads114s0x_gpio_port_get_raw(const struct device *dev, gpio_port_value_t *value)
|
||||
{
|
||||
struct ads114s0x_data *data = dev->data;
|
||||
const struct ads114s0x_config *config = dev->config;
|
||||
int result = 0;
|
||||
uint8_t gpio_dat;
|
||||
|
||||
k_mutex_lock(&data->gpio_lock, K_FOREVER);
|
||||
|
||||
result = ads114s0x_read_register(&config->bus, ADS114S0X_REGISTER_GPIODAT, &gpio_dat);
|
||||
data->gpio_value = ADS114S0X_REGISTER_GPIODAT_DAT_GET(gpio_dat);
|
||||
*value = data->gpio_value;
|
||||
|
||||
k_mutex_unlock(&data->gpio_lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int ads114s0x_gpio_port_set_masked_raw(const struct device *dev, gpio_port_pins_t mask,
|
||||
gpio_port_value_t value)
|
||||
{
|
||||
struct ads114s0x_data *data = dev->data;
|
||||
int result = 0;
|
||||
|
||||
k_mutex_lock(&data->gpio_lock, K_FOREVER);
|
||||
|
||||
data->gpio_value = ((data->gpio_value & ~mask) | (mask & value)) & data->gpio_enabled &
|
||||
~data->gpio_direction;
|
||||
result = ads114s0x_gpio_write_value(dev);
|
||||
|
||||
k_mutex_unlock(&data->gpio_lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int ads114s0x_gpio_port_toggle_bits(const struct device *dev, gpio_port_pins_t pins)
|
||||
{
|
||||
struct ads114s0x_data *data = dev->data;
|
||||
int result = 0;
|
||||
|
||||
k_mutex_lock(&data->gpio_lock, K_FOREVER);
|
||||
|
||||
data->gpio_value = (data->gpio_value ^ pins) & data->gpio_enabled & ~data->gpio_direction;
|
||||
result = ads114s0x_gpio_write_value(dev);
|
||||
|
||||
k_mutex_unlock(&data->gpio_lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_ADC_ADS114S0X_GPIO */
|
||||
|
||||
static int ads114s0x_init(const struct device *dev)
|
||||
{
|
||||
uint8_t status = 0;
|
||||
|
@ -884,6 +1177,10 @@ static int ads114s0x_init(const struct device *dev)
|
|||
k_sem_init(&data->data_ready_signal, 0, 1);
|
||||
k_sem_init(&data->acquire_signal, 0, 1);
|
||||
|
||||
#ifdef CONFIG_ADC_ADS114S0X_GPIO
|
||||
k_mutex_init(&data->gpio_lock);
|
||||
#endif /* CONFIG_ADC_ADS114S0X_GPIO */
|
||||
|
||||
if (!spi_is_ready_dt(&config->bus)) {
|
||||
LOG_ERR("SPI device is not ready");
|
||||
return -ENODEV;
|
||||
|
@ -986,6 +1283,19 @@ static int ads114s0x_init(const struct device *dev)
|
|||
return -EIO;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ADC_ADS114S0X_GPIO
|
||||
data->gpio_enabled = 0x00;
|
||||
data->gpio_direction = 0x0F;
|
||||
data->gpio_value = 0x00;
|
||||
|
||||
result = ads114s0x_gpio_write_config(dev);
|
||||
|
||||
if (result != 0) {
|
||||
LOG_ERR("unable to configure defaults for GPIOs");
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
adc_context_unlock_unconditionally(&data->ctx);
|
||||
|
||||
return result;
|
||||
|
|
|
@ -37,6 +37,7 @@ zephyr_library_sources_ifdef(CONFIG_GPIO_STELLARIS gpio_stellaris.c)
|
|||
zephyr_library_sources_ifdef(CONFIG_GPIO_RPI_PICO gpio_rpi_pico.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_GPIO_RV32M1 gpio_rv32m1.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_GPIO_LMP90XXX gpio_lmp90xxx.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_GPIO_ADS114S0X gpio_ads114s0x.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_GPIO_LITEX gpio_litex.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_GPIO_LPC11U6X gpio_lpc11u6x.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_GPIO_XLNX_AXI gpio_xlnx_axi.c)
|
||||
|
|
|
@ -127,6 +127,8 @@ source "drivers/gpio/Kconfig.rv32m1"
|
|||
|
||||
source "drivers/gpio/Kconfig.lmp90xxx"
|
||||
|
||||
source "drivers/gpio/Kconfig.ads114s0x"
|
||||
|
||||
source "drivers/gpio/Kconfig.litex"
|
||||
|
||||
source "drivers/gpio/Kconfig.lpc11u6x"
|
||||
|
|
25
drivers/gpio/Kconfig.ads114s0x
Normal file
25
drivers/gpio/Kconfig.ads114s0x
Normal file
|
@ -0,0 +1,25 @@
|
|||
# ADS114S0x GPIO configuration options
|
||||
|
||||
# Copyright (c) 2023 SILA Embedded Solutions GmbH
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
menuconfig GPIO_ADS114S0X
|
||||
bool "ADS114S0x GPIO driver"
|
||||
default y
|
||||
depends on DT_HAS_TI_ADS114S0X_GPIO_ENABLED
|
||||
depends on ADC_ADS114S0X_GPIO
|
||||
help
|
||||
Enable GPIO driver for ADS114S0x.
|
||||
|
||||
The ADS114S0x is a multi-channel analog frontend (AFE).
|
||||
|
||||
The GPIO port of the ADS114S0x (GPIO0 to GPIO3) is exposed as a
|
||||
GPIO controller driver with read/write support.
|
||||
|
||||
config GPIO_ADS114S0X_INIT_PRIORITY
|
||||
int "Driver init priority"
|
||||
default 99
|
||||
depends on GPIO_ADS114S0X
|
||||
help
|
||||
Device driver initialization priority. This driver must be
|
||||
initialized after the ADS114S0x ADC driver.
|
157
drivers/gpio/gpio_ads114s0x.c
Normal file
157
drivers/gpio/gpio_ads114s0x.c
Normal file
|
@ -0,0 +1,157 @@
|
|||
/*
|
||||
* Copyright (c) 2023 SILA Embedded Solutions GmbH
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief GPIO driver for the ADS114S0x AFE.
|
||||
*/
|
||||
|
||||
#define DT_DRV_COMPAT ti_ads114s0x_gpio
|
||||
|
||||
#include <zephyr/drivers/gpio.h>
|
||||
#include <zephyr/kernel.h>
|
||||
|
||||
#define LOG_LEVEL CONFIG_GPIO_LOG_LEVEL
|
||||
#include <zephyr/logging/log.h>
|
||||
LOG_MODULE_REGISTER(gpio_ads114s0x);
|
||||
|
||||
#include <zephyr/drivers/adc/ads114s0x.h>
|
||||
|
||||
#include <zephyr/drivers/gpio/gpio_utils.h>
|
||||
|
||||
struct gpio_ads114s0x_config {
|
||||
/* gpio_driver_config needs to be first */
|
||||
struct gpio_driver_config common;
|
||||
const struct device *parent;
|
||||
};
|
||||
|
||||
struct gpio_ads114s0x_data {
|
||||
/* gpio_driver_data needs to be first */
|
||||
struct gpio_driver_data common;
|
||||
};
|
||||
|
||||
static int gpio_ads114s0x_config(const struct device *dev, gpio_pin_t pin, gpio_flags_t flags)
|
||||
{
|
||||
const struct gpio_ads114s0x_config *config = dev->config;
|
||||
int err = 0;
|
||||
|
||||
if ((flags & (GPIO_INPUT | GPIO_OUTPUT)) == GPIO_DISCONNECTED) {
|
||||
return ads114s0x_gpio_deconfigure(config->parent, pin);
|
||||
}
|
||||
|
||||
if ((flags & GPIO_SINGLE_ENDED) != 0) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
if ((flags & (GPIO_PULL_UP | GPIO_PULL_DOWN)) != 0) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
if (flags & GPIO_INT_ENABLE) {
|
||||
/* ads114s0x GPIOs do not support interrupts */
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
switch (flags & GPIO_DIR_MASK) {
|
||||
case GPIO_INPUT:
|
||||
err = ads114s0x_gpio_set_input(config->parent, pin);
|
||||
break;
|
||||
case GPIO_OUTPUT:
|
||||
err = ads114s0x_gpio_set_output(config->parent, pin,
|
||||
(flags & GPIO_OUTPUT_INIT_HIGH) != 0);
|
||||
break;
|
||||
default:
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int gpio_ads114s0x_port_get_raw(const struct device *dev, gpio_port_value_t *value)
|
||||
{
|
||||
const struct gpio_ads114s0x_config *config = dev->config;
|
||||
|
||||
return ads114s0x_gpio_port_get_raw(config->parent, value);
|
||||
}
|
||||
|
||||
static int gpio_ads114s0x_port_set_masked_raw(const struct device *dev, gpio_port_pins_t mask,
|
||||
gpio_port_value_t value)
|
||||
{
|
||||
const struct gpio_ads114s0x_config *config = dev->config;
|
||||
|
||||
return ads114s0x_gpio_port_set_masked_raw(config->parent, mask, value);
|
||||
}
|
||||
|
||||
static int gpio_ads114s0x_port_set_bits_raw(const struct device *dev, gpio_port_pins_t pins)
|
||||
{
|
||||
const struct gpio_ads114s0x_config *config = dev->config;
|
||||
|
||||
return ads114s0x_gpio_port_set_masked_raw(config->parent, pins, pins);
|
||||
}
|
||||
|
||||
static int gpio_ads114s0x_port_clear_bits_raw(const struct device *dev, gpio_port_pins_t pins)
|
||||
{
|
||||
const struct gpio_ads114s0x_config *config = dev->config;
|
||||
|
||||
return ads114s0x_gpio_port_set_masked_raw(config->parent, pins, 0);
|
||||
}
|
||||
|
||||
static int gpio_ads114s0x_port_toggle_bits(const struct device *dev, gpio_port_pins_t pins)
|
||||
{
|
||||
const struct gpio_ads114s0x_config *config = dev->config;
|
||||
|
||||
return ads114s0x_gpio_port_toggle_bits(config->parent, pins);
|
||||
}
|
||||
|
||||
static int gpio_ads114s0x_pin_interrupt_configure(const struct device *dev, gpio_pin_t pin,
|
||||
enum gpio_int_mode mode, enum gpio_int_trig trig)
|
||||
{
|
||||
ARG_UNUSED(dev);
|
||||
ARG_UNUSED(pin);
|
||||
ARG_UNUSED(mode);
|
||||
ARG_UNUSED(trig);
|
||||
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
static int gpio_ads114s0x_init(const struct device *dev)
|
||||
{
|
||||
const struct gpio_ads114s0x_config *config = dev->config;
|
||||
|
||||
if (!device_is_ready(config->parent)) {
|
||||
LOG_ERR("parent ads114s0x device '%s' not ready", config->parent->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct gpio_driver_api gpio_ads114s0x_api = {
|
||||
.pin_configure = gpio_ads114s0x_config,
|
||||
.port_set_masked_raw = gpio_ads114s0x_port_set_masked_raw,
|
||||
.port_set_bits_raw = gpio_ads114s0x_port_set_bits_raw,
|
||||
.port_clear_bits_raw = gpio_ads114s0x_port_clear_bits_raw,
|
||||
.port_toggle_bits = gpio_ads114s0x_port_toggle_bits,
|
||||
.pin_interrupt_configure = gpio_ads114s0x_pin_interrupt_configure,
|
||||
.port_get_raw = gpio_ads114s0x_port_get_raw,
|
||||
};
|
||||
|
||||
BUILD_ASSERT(CONFIG_GPIO_ADS114S0X_INIT_PRIORITY > CONFIG_ADC_INIT_PRIORITY,
|
||||
"ADS114S0X GPIO driver must be initialized after ADS114S0X ADC driver");
|
||||
|
||||
#define GPIO_ADS114S0X_DEVICE(id) \
|
||||
static const struct gpio_ads114s0x_config gpio_ads114s0x_##id##_cfg = { \
|
||||
.common = {.port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(id)}, \
|
||||
.parent = DEVICE_DT_GET(DT_INST_BUS(id)), \
|
||||
}; \
|
||||
\
|
||||
static struct gpio_ads114s0x_data gpio_ads114s0x_##id##_data; \
|
||||
\
|
||||
DEVICE_DT_INST_DEFINE(id, &gpio_ads114s0x_init, NULL, &gpio_ads114s0x_##id##_data, \
|
||||
&gpio_ads114s0x_##id##_cfg, POST_KERNEL, \
|
||||
CONFIG_GPIO_ADS114S0X_INIT_PRIORITY, &gpio_ads114s0x_api);
|
||||
|
||||
DT_INST_FOREACH_STATUS_OKAY(GPIO_ADS114S0X_DEVICE)
|
35
include/zephyr/drivers/adc/ads114s0x.h
Normal file
35
include/zephyr/drivers/adc/ads114s0x.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright (c) 2023 SILA Embedded Solutions GmbH
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_INCLUDE_DRIVERS_ADC_ADS114S0X_H_
|
||||
#define ZEPHYR_INCLUDE_DRIVERS_ADC_ADS114S0X_H_
|
||||
|
||||
#include <zephyr/device.h>
|
||||
#include <zephyr/drivers/gpio.h>
|
||||
|
||||
int ads114s0x_gpio_set_output(const struct device *dev, uint8_t pin, bool initial_value);
|
||||
|
||||
int ads114s0x_gpio_set_input(const struct device *dev, uint8_t pin);
|
||||
|
||||
int ads114s0x_gpio_deconfigure(const struct device *dev, uint8_t pin);
|
||||
|
||||
int ads114s0x_gpio_set_pin_value(const struct device *dev, uint8_t pin,
|
||||
bool value);
|
||||
|
||||
int ads114s0x_gpio_get_pin_value(const struct device *dev, uint8_t pin,
|
||||
bool *value);
|
||||
|
||||
int ads114s0x_gpio_port_get_raw(const struct device *dev,
|
||||
gpio_port_value_t *value);
|
||||
|
||||
int ads114s0x_gpio_port_set_masked_raw(const struct device *dev,
|
||||
gpio_port_pins_t mask,
|
||||
gpio_port_value_t value);
|
||||
|
||||
int ads114s0x_gpio_port_toggle_bits(const struct device *dev,
|
||||
gpio_port_pins_t pins);
|
||||
|
||||
#endif /* ZEPHYR_INCLUDE_DRIVERS_ADC_ADS114S0X_H_ */
|
Loading…
Reference in a new issue