gpio: nct38xx: Remove reg access wrappers
Remove the register access wrappers used to read/write the NCT38xx register space. Signed-off-by: Keith Short <keithshort@google.com>
This commit is contained in:
parent
ea40f3af24
commit
c9f822df27
|
@ -35,6 +35,8 @@ struct gpio_nct38xx_data {
|
|||
const struct device *dev;
|
||||
/* lock NCT38xx register access */
|
||||
struct k_sem *lock;
|
||||
/* I2C device for the MFD parent */
|
||||
const struct i2c_dt_spec *i2c_dev;
|
||||
};
|
||||
|
||||
void nct38xx_gpio_alert_handler(const struct device *dev)
|
||||
|
@ -55,8 +57,8 @@ static int nct38xx_init_interrupt(const struct device *dev)
|
|||
k_sem_take(data->lock, K_FOREVER);
|
||||
|
||||
/* Disable all interrupt */
|
||||
if (nct38xx_reg_burst_write(dev, NCT38XX_REG_ALERT_MASK, (uint8_t *)&alert_mask,
|
||||
sizeof(alert_mask))) {
|
||||
if (i2c_burst_write_dt(data->i2c_dev, NCT38XX_REG_ALERT_MASK, (uint8_t *)&alert_mask,
|
||||
sizeof(alert_mask))) {
|
||||
ret = -EIO;
|
||||
goto unlock;
|
||||
}
|
||||
|
@ -65,21 +67,21 @@ static int nct38xx_init_interrupt(const struct device *dev)
|
|||
alert_mask |= BIT(NCT38XX_REG_ALERT_MASK_VENDOR_DEFINDED_ALERT);
|
||||
|
||||
/* Clear alert */
|
||||
if (nct38xx_reg_burst_read(dev, NCT38XX_REG_ALERT, (uint8_t *)&alert, sizeof(alert))) {
|
||||
if (i2c_burst_read_dt(data->i2c_dev, NCT38XX_REG_ALERT, (uint8_t *)&alert, sizeof(alert))) {
|
||||
ret = -EIO;
|
||||
goto unlock;
|
||||
}
|
||||
alert &= alert_mask;
|
||||
if (alert) {
|
||||
if (nct38xx_reg_burst_write(dev, NCT38XX_REG_ALERT, (uint8_t *)&alert,
|
||||
sizeof(alert))) {
|
||||
if (i2c_burst_write_dt(data->i2c_dev, NCT38XX_REG_ALERT, (uint8_t *)&alert,
|
||||
sizeof(alert))) {
|
||||
ret = -EIO;
|
||||
goto unlock;
|
||||
}
|
||||
}
|
||||
|
||||
if (nct38xx_reg_burst_write(dev, NCT38XX_REG_ALERT_MASK, (uint8_t *)&alert_mask,
|
||||
sizeof(alert_mask))) {
|
||||
if (i2c_burst_write_dt(data->i2c_dev, NCT38XX_REG_ALERT_MASK, (uint8_t *)&alert_mask,
|
||||
sizeof(alert_mask))) {
|
||||
ret = -EIO;
|
||||
goto unlock;
|
||||
}
|
||||
|
@ -101,6 +103,7 @@ static int nct38xx_gpio_init(const struct device *dev)
|
|||
}
|
||||
|
||||
data->lock = mfd_nct38xx_get_lock_reference(config->mfd);
|
||||
data->i2c_dev = mfd_nct38xx_get_i2c_dt_spec(config->mfd);
|
||||
|
||||
if (IS_ENABLED(CONFIG_GPIO_NCT38XX_ALERT)) {
|
||||
nct38xx_init_interrupt(dev);
|
||||
|
|
|
@ -18,6 +18,13 @@
|
|||
#include <zephyr/logging/log.h>
|
||||
LOG_MODULE_DECLARE(gpio_ntc38xx, CONFIG_GPIO_LOG_LEVEL);
|
||||
|
||||
struct nct38xx_mfd {
|
||||
/* Lock for NCT38xx register access */
|
||||
struct k_sem *lock;
|
||||
/* I2C device used for register access */
|
||||
const struct i2c_dt_spec *i2c_dev;
|
||||
};
|
||||
|
||||
/* Driver config */
|
||||
struct nct38xx_alert_config {
|
||||
/* Alert GPIO pin */
|
||||
|
@ -36,6 +43,8 @@ struct nct38xx_alert_data {
|
|||
struct gpio_callback gpio_cb;
|
||||
/* Alert worker */
|
||||
struct k_work alert_worker;
|
||||
/* Lock for NCT38xx register access */
|
||||
struct nct38xx_mfd *mfd;
|
||||
};
|
||||
|
||||
static void nct38xx_alert_callback(const struct device *dev, struct gpio_callback *cb,
|
||||
|
@ -47,39 +56,58 @@ static void nct38xx_alert_callback(const struct device *dev, struct gpio_callbac
|
|||
k_work_submit(&data->alert_worker);
|
||||
}
|
||||
|
||||
static bool nct38xx_alert_is_active(struct nct38xx_mfd *mfd)
|
||||
{
|
||||
int ret;
|
||||
uint16_t alert, mask;
|
||||
|
||||
k_sem_take(mfd->lock, K_FOREVER);
|
||||
|
||||
/* Clear alert */
|
||||
ret = i2c_burst_read_dt(mfd->i2c_dev, NCT38XX_REG_ALERT, (uint8_t *)&alert,
|
||||
sizeof(alert));
|
||||
if (ret < 0) {
|
||||
goto release_lock;
|
||||
}
|
||||
ret = i2c_burst_read_dt(mfd->i2c_dev, NCT38XX_REG_ALERT_MASK,
|
||||
(uint8_t *)&mask, sizeof(mask));
|
||||
if (ret < 0) {
|
||||
goto release_lock;
|
||||
}
|
||||
|
||||
alert &= mask;
|
||||
if (alert) {
|
||||
ret = i2c_burst_write_dt(mfd->i2c_dev, NCT38XX_REG_ALERT,
|
||||
(uint8_t *)&alert, sizeof(alert));
|
||||
}
|
||||
|
||||
release_lock:
|
||||
k_sem_give(mfd->lock);
|
||||
|
||||
if (ret < 0) {
|
||||
LOG_ERR("i2c access failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (alert & BIT(NCT38XX_REG_ALERT_VENDOR_DEFINDED_ALERT)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void nct38xx_alert_worker(struct k_work *work)
|
||||
{
|
||||
struct nct38xx_alert_data *const data =
|
||||
CONTAINER_OF(work, struct nct38xx_alert_data, alert_worker);
|
||||
const struct nct38xx_alert_config *const config = data->alert_dev->config;
|
||||
uint16_t alert, mask;
|
||||
|
||||
do {
|
||||
/* NCT38XX device handler */
|
||||
for (int i = 0; i < config->nct38xx_num; i++) {
|
||||
/* Clear alert */
|
||||
if (nct38xx_reg_burst_read(config->nct38xx_dev[i], NCT38XX_REG_ALERT,
|
||||
(uint8_t *)&alert, sizeof(alert))) {
|
||||
LOG_ERR("i2c access failed");
|
||||
return;
|
||||
}
|
||||
if (nct38xx_reg_burst_read(config->nct38xx_dev[i], NCT38XX_REG_ALERT_MASK,
|
||||
(uint8_t *)&mask, sizeof(mask))) {
|
||||
LOG_ERR("i2c access failed");
|
||||
return;
|
||||
}
|
||||
struct nct38xx_mfd *mfd = &data->mfd[i];
|
||||
|
||||
alert &= mask;
|
||||
if (alert) {
|
||||
if (nct38xx_reg_burst_write(config->nct38xx_dev[i],
|
||||
NCT38XX_REG_ALERT, (uint8_t *)&alert,
|
||||
sizeof(alert))) {
|
||||
LOG_ERR("i2c access failed");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (alert & BIT(NCT38XX_REG_ALERT_VENDOR_DEFINDED_ALERT)) {
|
||||
if (nct38xx_alert_is_active(mfd)) {
|
||||
nct38xx_gpio_alert_handler(config->nct38xx_dev[i]);
|
||||
}
|
||||
}
|
||||
|
@ -99,6 +127,9 @@ static int nct38xx_alert_init(const struct device *dev)
|
|||
LOG_ERR("%s device not ready", config->nct38xx_dev[i]->name);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
data->mfd[i].lock = mfd_nct38xx_get_lock_reference(config->nct38xx_dev[i]);
|
||||
data->mfd[i].i2c_dev = mfd_nct38xx_get_i2c_dt_spec(config->nct38xx_dev[i]);
|
||||
}
|
||||
|
||||
/* Set the alert pin for handling the interrupt */
|
||||
|
@ -130,8 +161,9 @@ BUILD_ASSERT(CONFIG_GPIO_NCT38XX_ALERT_INIT_PRIORITY > CONFIG_GPIO_NCT38XX_INIT_
|
|||
DEVICE_DT_GET(DT_PHANDLE_BY_IDX(node_id, prop, idx)),
|
||||
|
||||
#define NCT38XX_ALERT_DEVICE_INSTANCE(inst) \
|
||||
const struct device *nct38xx_dev_##inst[] = { DT_INST_FOREACH_PROP_ELEM( \
|
||||
inst, nct38xx_dev, NCT38XX_DEV_AND_COMMA) }; \
|
||||
const struct device *nct38xx_dev_##inst[] = { \
|
||||
DT_INST_FOREACH_PROP_ELEM(inst, nct38xx_dev, NCT38XX_DEV_AND_COMMA)}; \
|
||||
static struct nct38xx_mfd nct38xx_mfd_##inst[DT_INST_PROP_LEN(inst, nct38xx_dev)]; \
|
||||
static const struct nct38xx_alert_config nct38xx_alert_cfg_##inst = { \
|
||||
.irq_gpio = GPIO_DT_SPEC_INST_GET(inst, irq_gpios), \
|
||||
.nct38xx_dev = &nct38xx_dev_##inst[0], \
|
||||
|
@ -139,6 +171,7 @@ BUILD_ASSERT(CONFIG_GPIO_NCT38XX_ALERT_INIT_PRIORITY > CONFIG_GPIO_NCT38XX_INIT_
|
|||
}; \
|
||||
static struct nct38xx_alert_data nct38xx_alert_data_##inst = { \
|
||||
.alert_dev = DEVICE_DT_INST_GET(inst), \
|
||||
.mfd = nct38xx_mfd_##inst, \
|
||||
}; \
|
||||
DEVICE_DT_INST_DEFINE(inst, nct38xx_alert_init, NULL, &nct38xx_alert_data_##inst, \
|
||||
&nct38xx_alert_cfg_##inst, POST_KERNEL, \
|
||||
|
|
|
@ -33,6 +33,8 @@ struct gpio_nct38xx_port_data {
|
|||
sys_slist_t cb_list_gpio;
|
||||
/* lock NCT38xx register access */
|
||||
struct k_sem *lock;
|
||||
/* I2C device for the MFD parent */
|
||||
const struct i2c_dt_spec *i2c_dev;
|
||||
};
|
||||
|
||||
/* GPIO api functions */
|
||||
|
@ -40,8 +42,8 @@ static int gpio_nct38xx_pin_config(const struct device *dev, gpio_pin_t pin, gpi
|
|||
{
|
||||
const struct gpio_nct38xx_port_config *const config = dev->config;
|
||||
struct gpio_nct38xx_port_data *const data = dev->data;
|
||||
uint32_t mask = BIT(pin);
|
||||
uint8_t reg, new_reg;
|
||||
uint32_t mask;
|
||||
uint8_t new_reg;
|
||||
int ret;
|
||||
|
||||
/* Don't support simultaneous in/out mode */
|
||||
|
@ -63,16 +65,14 @@ static int gpio_nct38xx_pin_config(const struct device *dev, gpio_pin_t pin, gpi
|
|||
|
||||
/* Pin multiplexing */
|
||||
if (config->gpio_port == 0) {
|
||||
ret = nct38xx_reg_read_byte(config->mfd, NCT38XX_REG_MUX_CONTROL, ®);
|
||||
if (ret < 0) {
|
||||
goto done;
|
||||
}
|
||||
/* Set the mux control bit, but ensure the reserved fields
|
||||
* are cleared. Note that pinmux_mask contains the set
|
||||
* of non-reserved bits.
|
||||
*/
|
||||
new_reg = BIT(pin) & config->pinmux_mask;
|
||||
mask = BIT(pin) | ~config->pinmux_mask;
|
||||
|
||||
new_reg = reg | mask;
|
||||
/* NCT3807 bit3 must be set to 0 */
|
||||
new_reg &= config->pinmux_mask;
|
||||
|
||||
ret = nct38xx_reg_update(config->mfd, NCT38XX_REG_MUX_CONTROL, reg, new_reg);
|
||||
ret = i2c_reg_update_byte_dt(data->i2c_dev, NCT38XX_REG_MUX_CONTROL, mask, new_reg);
|
||||
if (ret < 0) {
|
||||
goto done;
|
||||
}
|
||||
|
@ -80,63 +80,45 @@ static int gpio_nct38xx_pin_config(const struct device *dev, gpio_pin_t pin, gpi
|
|||
|
||||
/* Configure pin as input. */
|
||||
if (flags & GPIO_INPUT) {
|
||||
ret = nct38xx_reg_read_byte(config->mfd,
|
||||
NCT38XX_REG_GPIO_DIR(config->gpio_port), ®);
|
||||
if (ret < 0) {
|
||||
goto done;
|
||||
}
|
||||
new_reg = reg & ~mask;
|
||||
ret = nct38xx_reg_update(config->mfd,
|
||||
NCT38XX_REG_GPIO_DIR(config->gpio_port), reg, new_reg);
|
||||
/* Clear the direction bit to set as an input */
|
||||
new_reg = 0;
|
||||
mask = BIT(pin);
|
||||
ret = i2c_reg_update_byte_dt(data->i2c_dev, NCT38XX_REG_GPIO_DIR(config->gpio_port),
|
||||
mask, new_reg);
|
||||
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Select open drain 0:push-pull 1:open-drain */
|
||||
ret = nct38xx_reg_read_byte(config->mfd, NCT38XX_REG_GPIO_OD_SEL(config->gpio_port),
|
||||
®);
|
||||
if (ret < 0) {
|
||||
goto done;
|
||||
}
|
||||
mask = BIT(pin);
|
||||
if (flags & GPIO_OPEN_DRAIN) {
|
||||
new_reg = reg | mask;
|
||||
new_reg = mask;
|
||||
} else {
|
||||
new_reg = reg & ~mask;
|
||||
new_reg = 0;
|
||||
}
|
||||
ret = nct38xx_reg_update(config->mfd, NCT38XX_REG_GPIO_OD_SEL(config->gpio_port),
|
||||
reg, new_reg);
|
||||
ret = i2c_reg_update_byte_dt(data->i2c_dev, NCT38XX_REG_GPIO_OD_SEL(config->gpio_port),
|
||||
mask, new_reg);
|
||||
if (ret < 0) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Set level 0:low 1:high */
|
||||
ret = nct38xx_reg_read_byte(config->mfd,
|
||||
NCT38XX_REG_GPIO_DATA_OUT(config->gpio_port),
|
||||
®);
|
||||
if (ret < 0) {
|
||||
goto done;
|
||||
}
|
||||
if (flags & GPIO_OUTPUT_INIT_HIGH) {
|
||||
new_reg = reg | mask;
|
||||
new_reg = mask;
|
||||
} else if (flags & GPIO_OUTPUT_INIT_LOW) {
|
||||
new_reg = reg & ~mask;
|
||||
new_reg = 0;
|
||||
}
|
||||
ret = nct38xx_reg_update(config->mfd, NCT38XX_REG_GPIO_DATA_OUT(config->gpio_port),
|
||||
reg, new_reg);
|
||||
ret = i2c_reg_update_byte_dt(data->i2c_dev, NCT38XX_REG_GPIO_DATA_OUT(config->gpio_port),
|
||||
mask, new_reg);
|
||||
if (ret < 0) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Configure pin as output, if requested 0:input 1:output */
|
||||
if (flags & GPIO_OUTPUT) {
|
||||
ret = nct38xx_reg_read_byte(config->mfd,
|
||||
NCT38XX_REG_GPIO_DIR(config->gpio_port), ®);
|
||||
if (ret < 0) {
|
||||
goto done;
|
||||
}
|
||||
new_reg = reg | mask;
|
||||
ret = nct38xx_reg_update(config->mfd,
|
||||
NCT38XX_REG_GPIO_DIR(config->gpio_port), reg, new_reg);
|
||||
new_reg = BIT(pin);
|
||||
ret = i2c_reg_update_byte_dt(data->i2c_dev, NCT38XX_REG_GPIO_DIR(config->gpio_port),
|
||||
mask, new_reg);
|
||||
}
|
||||
|
||||
done:
|
||||
|
@ -161,7 +143,7 @@ int gpio_nct38xx_pin_get_config(const struct device *dev, gpio_pin_t pin, gpio_f
|
|||
goto done;
|
||||
}
|
||||
|
||||
ret = nct38xx_reg_read_byte(config->mfd, NCT38XX_REG_MUX_CONTROL, ®);
|
||||
ret = i2c_reg_read_byte_dt(data->i2c_dev, NCT38XX_REG_MUX_CONTROL, ®);
|
||||
if (ret < 0) {
|
||||
goto done;
|
||||
}
|
||||
|
@ -172,8 +154,7 @@ int gpio_nct38xx_pin_get_config(const struct device *dev, gpio_pin_t pin, gpio_f
|
|||
}
|
||||
}
|
||||
|
||||
ret = nct38xx_reg_read_byte(config->mfd, NCT38XX_REG_GPIO_DIR(config->gpio_port),
|
||||
®);
|
||||
ret = i2c_reg_read_byte_dt(data->i2c_dev, NCT38XX_REG_GPIO_DIR(config->gpio_port), ®);
|
||||
if (ret < 0) {
|
||||
goto done;
|
||||
}
|
||||
|
@ -183,8 +164,8 @@ int gpio_nct38xx_pin_get_config(const struct device *dev, gpio_pin_t pin, gpio_f
|
|||
*flags = GPIO_OUTPUT;
|
||||
|
||||
/* 0 - push-pull, 1 - open-drain */
|
||||
ret = nct38xx_reg_read_byte(config->mfd,
|
||||
NCT38XX_REG_GPIO_OD_SEL(config->gpio_port), ®);
|
||||
ret = i2c_reg_read_byte_dt(data->i2c_dev,
|
||||
NCT38XX_REG_GPIO_OD_SEL(config->gpio_port), ®);
|
||||
if (ret < 0) {
|
||||
goto done;
|
||||
}
|
||||
|
@ -194,8 +175,8 @@ int gpio_nct38xx_pin_get_config(const struct device *dev, gpio_pin_t pin, gpio_f
|
|||
}
|
||||
|
||||
/* Output value */
|
||||
ret = nct38xx_reg_read_byte(config->mfd,
|
||||
NCT38XX_REG_GPIO_DATA_OUT(config->gpio_port), ®);
|
||||
ret = i2c_reg_read_byte_dt(data->i2c_dev,
|
||||
NCT38XX_REG_GPIO_DATA_OUT(config->gpio_port), ®);
|
||||
if (ret < 0) {
|
||||
goto done;
|
||||
}
|
||||
|
@ -224,8 +205,8 @@ static int gpio_nct38xx_port_get_raw(const struct device *dev, gpio_port_value_t
|
|||
|
||||
k_sem_take(data->lock, K_FOREVER);
|
||||
|
||||
ret = nct38xx_reg_read_byte(config->mfd,
|
||||
NCT38XX_REG_GPIO_DATA_IN(config->gpio_port), (uint8_t *)value);
|
||||
ret = i2c_reg_read_byte_dt(data->i2c_dev, NCT38XX_REG_GPIO_DATA_IN(config->gpio_port),
|
||||
(uint8_t *)value);
|
||||
|
||||
k_sem_give(data->lock);
|
||||
return ret;
|
||||
|
@ -236,21 +217,13 @@ static int gpio_nct38xx_port_set_masked_raw(const struct device *dev, gpio_port_
|
|||
{
|
||||
const struct gpio_nct38xx_port_config *const config = dev->config;
|
||||
struct gpio_nct38xx_port_data *const data = dev->data;
|
||||
uint8_t reg, new_reg;
|
||||
int ret;
|
||||
|
||||
k_sem_take(data->lock, K_FOREVER);
|
||||
|
||||
ret = nct38xx_reg_read_byte(config->mfd,
|
||||
NCT38XX_REG_GPIO_DATA_OUT(config->gpio_port), ®);
|
||||
if (ret < 0) {
|
||||
goto done;
|
||||
}
|
||||
new_reg = ((reg & ~mask) | (value & mask));
|
||||
ret = nct38xx_reg_update(config->mfd, NCT38XX_REG_GPIO_DATA_OUT(config->gpio_port),
|
||||
reg, new_reg);
|
||||
ret = i2c_reg_update_byte_dt(data->i2c_dev, NCT38XX_REG_GPIO_DATA_OUT(config->gpio_port),
|
||||
mask, value);
|
||||
|
||||
done:
|
||||
k_sem_give(data->lock);
|
||||
|
||||
return ret;
|
||||
|
@ -260,21 +233,13 @@ static int gpio_nct38xx_port_set_bits_raw(const struct device *dev, gpio_port_pi
|
|||
{
|
||||
const struct gpio_nct38xx_port_config *const config = dev->config;
|
||||
struct gpio_nct38xx_port_data *const data = dev->data;
|
||||
uint8_t reg, new_reg;
|
||||
int ret;
|
||||
|
||||
k_sem_take(data->lock, K_FOREVER);
|
||||
|
||||
ret = nct38xx_reg_read_byte(config->mfd,
|
||||
NCT38XX_REG_GPIO_DATA_OUT(config->gpio_port), ®);
|
||||
if (ret < 0) {
|
||||
goto done;
|
||||
}
|
||||
new_reg = reg | mask;
|
||||
ret = nct38xx_reg_update(config->mfd, NCT38XX_REG_GPIO_DATA_OUT(config->gpio_port),
|
||||
reg, new_reg);
|
||||
ret = i2c_reg_update_byte_dt(data->i2c_dev, NCT38XX_REG_GPIO_DATA_OUT(config->gpio_port),
|
||||
mask, mask);
|
||||
|
||||
done:
|
||||
k_sem_give(data->lock);
|
||||
|
||||
return ret;
|
||||
|
@ -284,21 +249,13 @@ static int gpio_nct38xx_port_clear_bits_raw(const struct device *dev, gpio_port_
|
|||
{
|
||||
const struct gpio_nct38xx_port_config *const config = dev->config;
|
||||
struct gpio_nct38xx_port_data *const data = dev->data;
|
||||
uint8_t reg, new_reg;
|
||||
int ret;
|
||||
|
||||
k_sem_take(data->lock, K_FOREVER);
|
||||
|
||||
ret = nct38xx_reg_read_byte(config->mfd,
|
||||
NCT38XX_REG_GPIO_DATA_OUT(config->gpio_port), ®);
|
||||
if (ret < 0) {
|
||||
goto done;
|
||||
}
|
||||
new_reg = reg & ~mask;
|
||||
ret = nct38xx_reg_update(config->mfd, NCT38XX_REG_GPIO_DATA_OUT(config->gpio_port),
|
||||
reg, new_reg);
|
||||
ret = i2c_reg_update_byte_dt(data->i2c_dev, NCT38XX_REG_GPIO_DATA_OUT(config->gpio_port),
|
||||
mask, 0);
|
||||
|
||||
done:
|
||||
k_sem_give(data->lock);
|
||||
|
||||
return ret;
|
||||
|
@ -313,14 +270,16 @@ static int gpio_nct38xx_port_toggle_bits(const struct device *dev, gpio_port_pin
|
|||
|
||||
k_sem_take(data->lock, K_FOREVER);
|
||||
|
||||
ret = nct38xx_reg_read_byte(config->mfd, NCT38XX_REG_GPIO_DATA_OUT(config->gpio_port),
|
||||
®);
|
||||
ret = i2c_reg_read_byte_dt(data->i2c_dev, NCT38XX_REG_GPIO_DATA_OUT(config->gpio_port),
|
||||
®);
|
||||
if (ret < 0) {
|
||||
goto done;
|
||||
}
|
||||
new_reg = reg ^ mask;
|
||||
ret = nct38xx_reg_update(config->mfd, NCT38XX_REG_GPIO_DATA_OUT(config->gpio_port),
|
||||
reg, new_reg);
|
||||
if (new_reg != reg) {
|
||||
ret = i2c_reg_write_byte_dt(data->i2c_dev,
|
||||
NCT38XX_REG_GPIO_DATA_OUT(config->gpio_port), new_reg);
|
||||
}
|
||||
|
||||
done:
|
||||
k_sem_give(data->lock);
|
||||
|
@ -333,24 +292,16 @@ static int gpio_nct38xx_pin_interrupt_configure(const struct device *dev, gpio_p
|
|||
{
|
||||
const struct gpio_nct38xx_port_config *const config = dev->config;
|
||||
struct gpio_nct38xx_port_data *const data = dev->data;
|
||||
uint8_t reg, new_reg, rise, new_rise, fall, new_fall;
|
||||
uint8_t new_reg, new_rise, new_fall;
|
||||
int ret;
|
||||
uint32_t mask = BIT(pin);
|
||||
|
||||
k_sem_take(data->lock, K_FOREVER);
|
||||
|
||||
/* Disable irq before configuring them */
|
||||
ret = nct38xx_reg_read_byte(config->mfd,
|
||||
NCT38XX_REG_GPIO_ALERT_MASK(config->gpio_port), ®);
|
||||
if (ret < 0) {
|
||||
goto done;
|
||||
}
|
||||
new_reg = reg & ~mask;
|
||||
ret = nct38xx_reg_update(config->mfd,
|
||||
NCT38XX_REG_GPIO_ALERT_MASK(config->gpio_port), reg, new_reg);
|
||||
if (ret < 0) {
|
||||
goto done;
|
||||
}
|
||||
new_reg = 0;
|
||||
ret = i2c_reg_update_byte_dt(data->i2c_dev, NCT38XX_REG_GPIO_ALERT_MASK(config->gpio_port),
|
||||
mask, new_reg);
|
||||
|
||||
/* Configure and enable interrupt? */
|
||||
if (mode == GPIO_INT_MODE_DISABLED) {
|
||||
|
@ -358,69 +309,52 @@ static int gpio_nct38xx_pin_interrupt_configure(const struct device *dev, gpio_p
|
|||
}
|
||||
|
||||
/* set edge register */
|
||||
ret = nct38xx_reg_read_byte(config->mfd,
|
||||
NCT38XX_REG_GPIO_ALERT_RISE(config->gpio_port), &rise);
|
||||
if (ret < 0) {
|
||||
goto done;
|
||||
}
|
||||
ret = nct38xx_reg_read_byte(config->mfd,
|
||||
NCT38XX_REG_GPIO_ALERT_FALL(config->gpio_port), &fall);
|
||||
if (ret < 0) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (mode == GPIO_INT_MODE_EDGE) {
|
||||
if (trig == GPIO_INT_TRIG_LOW) {
|
||||
new_rise = rise & ~mask;
|
||||
new_fall = fall | mask;
|
||||
new_rise = 0;
|
||||
new_fall = mask;
|
||||
} else if (trig == GPIO_INT_TRIG_HIGH) {
|
||||
new_rise = rise | mask;
|
||||
new_fall = fall & ~mask;
|
||||
new_rise = mask;
|
||||
new_fall = 0;
|
||||
} else if (trig == GPIO_INT_TRIG_BOTH) {
|
||||
new_rise = rise | mask;
|
||||
new_fall = fall | mask;
|
||||
new_rise = mask;
|
||||
new_fall = mask;
|
||||
} else {
|
||||
LOG_ERR("Invalid interrupt trigger type %d", trig);
|
||||
return -EINVAL;
|
||||
}
|
||||
} else {
|
||||
/* level mode */
|
||||
new_rise = rise & ~mask;
|
||||
new_fall = fall & ~mask;
|
||||
new_rise = 0;
|
||||
new_fall = 0;
|
||||
}
|
||||
|
||||
ret = nct38xx_reg_update(config->mfd,
|
||||
NCT38XX_REG_GPIO_ALERT_RISE(config->gpio_port), rise, new_rise);
|
||||
ret = i2c_reg_update_byte_dt(data->i2c_dev, NCT38XX_REG_GPIO_ALERT_RISE(config->gpio_port),
|
||||
mask, new_rise);
|
||||
if (ret < 0) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = nct38xx_reg_update(config->mfd,
|
||||
NCT38XX_REG_GPIO_ALERT_FALL(config->gpio_port), fall, new_fall);
|
||||
ret = i2c_reg_update_byte_dt(data->i2c_dev, NCT38XX_REG_GPIO_ALERT_FALL(config->gpio_port),
|
||||
mask, new_fall);
|
||||
if (ret < 0) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (mode == GPIO_INT_MODE_LEVEL) {
|
||||
/* set active high/low */
|
||||
ret = nct38xx_reg_read_byte(config->mfd,
|
||||
NCT38XX_REG_GPIO_ALERT_LEVEL(config->gpio_port), ®);
|
||||
if (ret < 0) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (trig == GPIO_INT_TRIG_LOW) {
|
||||
new_reg = reg & ~mask;
|
||||
new_reg = 0;
|
||||
} else if (trig == GPIO_INT_TRIG_HIGH) {
|
||||
new_reg = reg | mask;
|
||||
new_reg = mask;
|
||||
} else {
|
||||
LOG_ERR("Invalid interrupt trigger type %d", trig);
|
||||
ret = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
ret = nct38xx_reg_update(config->mfd,
|
||||
NCT38XX_REG_GPIO_ALERT_LEVEL(config->gpio_port), reg,
|
||||
new_reg);
|
||||
ret = i2c_reg_update_byte_dt(data->i2c_dev,
|
||||
NCT38XX_REG_GPIO_ALERT_LEVEL(config->gpio_port), mask,
|
||||
new_reg);
|
||||
|
||||
if (ret < 0) {
|
||||
goto done;
|
||||
|
@ -428,21 +362,16 @@ static int gpio_nct38xx_pin_interrupt_configure(const struct device *dev, gpio_p
|
|||
}
|
||||
|
||||
/* Clear pending bit */
|
||||
ret = nct38xx_reg_write_byte(config->mfd,
|
||||
NCT38XX_REG_GPIO_ALERT_STAT(config->gpio_port), mask);
|
||||
ret = i2c_reg_write_byte_dt(data->i2c_dev, NCT38XX_REG_GPIO_ALERT_STAT(config->gpio_port),
|
||||
mask);
|
||||
if (ret < 0) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Enable it after configuration is completed */
|
||||
ret = nct38xx_reg_read_byte(config->mfd,
|
||||
NCT38XX_REG_GPIO_ALERT_MASK(config->gpio_port), ®);
|
||||
if (ret < 0) {
|
||||
goto done;
|
||||
}
|
||||
new_reg = reg | mask;
|
||||
ret = nct38xx_reg_update(config->mfd,
|
||||
NCT38XX_REG_GPIO_ALERT_MASK(config->gpio_port), reg, new_reg);
|
||||
new_reg = mask;
|
||||
ret = i2c_reg_update_byte_dt(data->i2c_dev, NCT38XX_REG_GPIO_ALERT_MASK(config->gpio_port),
|
||||
mask, new_reg);
|
||||
|
||||
done:
|
||||
k_sem_give(data->lock);
|
||||
|
@ -472,8 +401,7 @@ static int gpio_nct38xx_port_get_direction(const struct device *dev, gpio_port_p
|
|||
if (config->gpio_port == 0) {
|
||||
uint8_t enabled_gpios;
|
||||
/* Remove the disabled GPIOs from the mask */
|
||||
ret = nct38xx_reg_read_byte(config->mfd, NCT38XX_REG_MUX_CONTROL,
|
||||
&enabled_gpios);
|
||||
ret = i2c_reg_read_byte_dt(data->i2c_dev, NCT38XX_REG_MUX_CONTROL, &enabled_gpios);
|
||||
mask &= (enabled_gpios & config->common.port_pin_mask);
|
||||
|
||||
if (ret < 0) {
|
||||
|
@ -482,8 +410,8 @@ static int gpio_nct38xx_port_get_direction(const struct device *dev, gpio_port_p
|
|||
}
|
||||
|
||||
/* Read direction register, 0 - input, 1 - output */
|
||||
ret = nct38xx_reg_read_byte(config->mfd, NCT38XX_REG_GPIO_DIR(config->gpio_port),
|
||||
&dir_reg);
|
||||
ret = i2c_reg_read_byte_dt(data->i2c_dev, NCT38XX_REG_GPIO_DIR(config->gpio_port),
|
||||
&dir_reg);
|
||||
if (ret < 0) {
|
||||
goto done;
|
||||
}
|
||||
|
@ -511,25 +439,24 @@ int gpio_nct38xx_dispatch_port_isr(const struct device *dev)
|
|||
|
||||
do {
|
||||
k_sem_take(data->lock, K_FOREVER);
|
||||
ret = nct38xx_reg_read_byte(config->mfd,
|
||||
NCT38XX_REG_GPIO_ALERT_STAT(config->gpio_port),
|
||||
&alert_pins);
|
||||
ret = i2c_reg_read_byte_dt(
|
||||
data->i2c_dev, NCT38XX_REG_GPIO_ALERT_STAT(config->gpio_port), &alert_pins);
|
||||
if (ret < 0) {
|
||||
k_sem_give(data->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = nct38xx_reg_read_byte(config->mfd,
|
||||
NCT38XX_REG_GPIO_ALERT_MASK(config->gpio_port), &mask);
|
||||
ret = i2c_reg_read_byte_dt(data->i2c_dev,
|
||||
NCT38XX_REG_GPIO_ALERT_MASK(config->gpio_port), &mask);
|
||||
if (ret < 0) {
|
||||
k_sem_give(data->lock);
|
||||
return ret;
|
||||
}
|
||||
alert_pins &= mask;
|
||||
if (alert_pins) {
|
||||
ret = nct38xx_reg_write_byte(config->mfd,
|
||||
NCT38XX_REG_GPIO_ALERT_STAT(config->gpio_port),
|
||||
alert_pins);
|
||||
ret = i2c_reg_write_byte_dt(data->i2c_dev,
|
||||
NCT38XX_REG_GPIO_ALERT_STAT(config->gpio_port),
|
||||
alert_pins);
|
||||
if (ret < 0) {
|
||||
k_sem_give(data->lock);
|
||||
return ret;
|
||||
|
@ -577,6 +504,7 @@ static int gpio_nct38xx_port_init(const struct device *dev)
|
|||
}
|
||||
|
||||
data->lock = mfd_nct38xx_get_lock_reference(config->mfd);
|
||||
data->i2c_dev = mfd_nct38xx_get_i2c_dt_spec(config->mfd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -37,43 +37,11 @@ struct k_sem *mfd_nct38xx_get_lock_reference(const struct device *dev)
|
|||
return &data->lock;
|
||||
}
|
||||
|
||||
int nct38xx_reg_read_byte(const struct device *dev, uint8_t reg_addr, uint8_t *val)
|
||||
const struct i2c_dt_spec *mfd_nct38xx_get_i2c_dt_spec(const struct device *dev)
|
||||
{
|
||||
const struct mfd_nct38xx_config *const config = dev->config;
|
||||
const struct mfd_nct38xx_config *config = dev->config;
|
||||
|
||||
return i2c_reg_read_byte_dt(&config->i2c_dev, reg_addr, val);
|
||||
}
|
||||
|
||||
int nct38xx_reg_burst_read(const struct device *dev, uint8_t start_addr, uint8_t *buf,
|
||||
uint32_t num_bytes)
|
||||
{
|
||||
const struct mfd_nct38xx_config *const config = dev->config;
|
||||
|
||||
return i2c_burst_read_dt(&config->i2c_dev, start_addr, buf, num_bytes);
|
||||
}
|
||||
|
||||
int nct38xx_reg_write_byte(const struct device *dev, uint8_t reg_addr, uint8_t val)
|
||||
{
|
||||
const struct mfd_nct38xx_config *const config = dev->config;
|
||||
|
||||
return i2c_reg_write_byte_dt(&config->i2c_dev, reg_addr, val);
|
||||
}
|
||||
|
||||
int nct38xx_reg_burst_write(const struct device *dev, uint8_t start_addr, uint8_t *buf,
|
||||
uint32_t num_bytes)
|
||||
{
|
||||
const struct mfd_nct38xx_config *const config = dev->config;
|
||||
|
||||
return i2c_burst_write_dt(&config->i2c_dev, start_addr, buf, num_bytes);
|
||||
}
|
||||
|
||||
int nct38xx_reg_update(const struct device *dev, uint8_t reg_addr, uint8_t reg_val, uint8_t new_val)
|
||||
{
|
||||
if (reg_val == new_val) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return nct38xx_reg_write_byte(dev, reg_addr, new_val);
|
||||
return &config->i2c_dev;
|
||||
}
|
||||
|
||||
#define MFD_NCT38XX_DEFINE(inst) \
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#define ZEPHYR_INCLUDE_DRIVERS_MFD_NCT38XX_H_
|
||||
|
||||
#include <zephyr/device.h>
|
||||
#include <zephyr/drivers/i2c.h>
|
||||
#include <zephyr/kernel.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -24,65 +25,13 @@ extern "C" {
|
|||
struct k_sem *mfd_nct38xx_get_lock_reference(const struct device *dev);
|
||||
|
||||
/**
|
||||
* @brief Read a NCT38XX register
|
||||
* @brief Get the I2C DT spec reference for a NCT38xx instance.
|
||||
*
|
||||
* @param dev NCT38XX multi-function device
|
||||
* @param reg_addr Register address
|
||||
* @param val A pointer to a buffer for the data to return
|
||||
* @param[in] dev Pointer to device struct of the driver instance
|
||||
*
|
||||
* @return 0 if successful, otherwise failed.
|
||||
* @return Address of the I2C DT spec
|
||||
*/
|
||||
int nct38xx_reg_read_byte(const struct device *dev, uint8_t reg_addr, uint8_t *val);
|
||||
|
||||
/**
|
||||
* @brief Read a sequence of NCT38XX registers
|
||||
*
|
||||
* @param dev NCT38XX multi-function device
|
||||
* @param start_addr The register start address
|
||||
* @param buf A pointer to a buffer for the data to return
|
||||
* @param num_bytes Number of data to read
|
||||
*
|
||||
* @return 0 if successful, otherwise failed.
|
||||
*/
|
||||
int nct38xx_reg_burst_read(const struct device *dev, uint8_t start_addr, uint8_t *buf,
|
||||
uint32_t num_bytes);
|
||||
|
||||
/**
|
||||
* @brief Write a NCT38XX register
|
||||
*
|
||||
* @param dev NCT38XX device
|
||||
* @param reg_addr Register address
|
||||
* @param val Data to write
|
||||
*
|
||||
* @return 0 if successful, otherwise failed.
|
||||
*/
|
||||
int nct38xx_reg_write_byte(const struct device *dev, uint8_t reg_addr, uint8_t val);
|
||||
|
||||
/**
|
||||
* @brief Write a sequence of NCT38XX registers
|
||||
*
|
||||
* @param dev NCT38XX device
|
||||
* @param start_addr The register start address
|
||||
* @param buf A pointer to a buffer for the data to write
|
||||
* @param num_bytes Number of data to write
|
||||
*
|
||||
* @return 0 if successful, otherwise failed.
|
||||
*/
|
||||
int nct38xx_reg_burst_write(const struct device *dev, uint8_t start_addr, uint8_t *buf,
|
||||
uint32_t num_bytes);
|
||||
|
||||
/**
|
||||
* @brief Compare data & write a NCT38XX register
|
||||
*
|
||||
* @param dev NCT38XX device
|
||||
* @param reg_addr Register address
|
||||
* @param reg_val Old register data
|
||||
* @param new_val New register data
|
||||
*
|
||||
* @return 0 if successful, otherwise failed.
|
||||
*/
|
||||
int nct38xx_reg_update(const struct device *dev, uint8_t reg_addr, uint8_t reg_val,
|
||||
uint8_t new_val);
|
||||
const struct i2c_dt_spec *mfd_nct38xx_get_i2c_dt_spec(const struct device *dev);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue