drivers: gpio: pca95xx: use i2c_dt_spec
Simplify driver implementation by using i2c_dt_spec. Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
This commit is contained in:
parent
80ee515c9c
commit
1d449c2924
1 changed files with 17 additions and 37 deletions
|
@ -60,15 +60,8 @@ LOG_MODULE_REGISTER(gpio_pca95xx);
|
||||||
struct gpio_pca95xx_config {
|
struct gpio_pca95xx_config {
|
||||||
/* gpio_driver_config needs to be first */
|
/* gpio_driver_config needs to be first */
|
||||||
struct gpio_driver_config common;
|
struct gpio_driver_config common;
|
||||||
|
struct i2c_dt_spec bus;
|
||||||
/** The master I2C device's name */
|
|
||||||
const char * const i2c_master_dev_name;
|
|
||||||
|
|
||||||
/** The slave address of the chip */
|
|
||||||
uint16_t i2c_slave_addr;
|
|
||||||
|
|
||||||
uint8_t capabilities;
|
uint8_t capabilities;
|
||||||
|
|
||||||
#ifdef CONFIG_GPIO_PCA95XX_INTERRUPT
|
#ifdef CONFIG_GPIO_PCA95XX_INTERRUPT
|
||||||
struct gpio_dt_spec int_gpio;
|
struct gpio_dt_spec int_gpio;
|
||||||
#endif
|
#endif
|
||||||
|
@ -79,9 +72,6 @@ struct gpio_pca95xx_drv_data {
|
||||||
/* gpio_driver_data needs to be first */
|
/* gpio_driver_data needs to be first */
|
||||||
struct gpio_driver_data common;
|
struct gpio_driver_data common;
|
||||||
|
|
||||||
/** Master I2C device */
|
|
||||||
const struct device *i2c_master;
|
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
uint16_t input;
|
uint16_t input;
|
||||||
uint16_t output;
|
uint16_t output;
|
||||||
|
@ -133,16 +123,14 @@ static int read_port_regs(const struct device *dev, uint8_t reg,
|
||||||
const struct gpio_pca95xx_config * const config = dev->config;
|
const struct gpio_pca95xx_config * const config = dev->config;
|
||||||
struct gpio_pca95xx_drv_data * const drv_data =
|
struct gpio_pca95xx_drv_data * const drv_data =
|
||||||
(struct gpio_pca95xx_drv_data * const)dev->data;
|
(struct gpio_pca95xx_drv_data * const)dev->data;
|
||||||
const struct device *i2c_master = drv_data->i2c_master;
|
|
||||||
uint16_t i2c_addr = config->i2c_slave_addr;
|
|
||||||
uint16_t port_data, value;
|
uint16_t port_data, value;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = i2c_burst_read(i2c_master, i2c_addr, reg,
|
ret = i2c_burst_read_dt(&config->bus, reg, (uint8_t *)&port_data,
|
||||||
(uint8_t *)&port_data, sizeof(port_data));
|
sizeof(port_data));
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
LOG_ERR("PCA95XX[0x%X]: error reading register 0x%X (%d)",
|
LOG_ERR("PCA95XX[0x%X]: error reading register 0x%X (%d)",
|
||||||
i2c_addr, reg, ret);
|
config->bus.addr, reg, ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,7 +139,7 @@ static int read_port_regs(const struct device *dev, uint8_t reg,
|
||||||
*buf = value;
|
*buf = value;
|
||||||
|
|
||||||
LOG_DBG("PCA95XX[0x%X]: Read: REG[0x%X] = 0x%X, REG[0x%X] = 0x%X",
|
LOG_DBG("PCA95XX[0x%X]: Read: REG[0x%X] = 0x%X, REG[0x%X] = 0x%X",
|
||||||
i2c_addr, reg, (*buf & 0xFF), (reg + 1), (*buf >> 8));
|
config->bus.addr, reg, (*buf & 0xFF), (reg + 1), (*buf >> 8));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -174,24 +162,22 @@ static int write_port_regs(const struct device *dev, uint8_t reg,
|
||||||
const struct gpio_pca95xx_config * const config = dev->config;
|
const struct gpio_pca95xx_config * const config = dev->config;
|
||||||
struct gpio_pca95xx_drv_data * const drv_data =
|
struct gpio_pca95xx_drv_data * const drv_data =
|
||||||
(struct gpio_pca95xx_drv_data * const)dev->data;
|
(struct gpio_pca95xx_drv_data * const)dev->data;
|
||||||
const struct device *i2c_master = drv_data->i2c_master;
|
|
||||||
uint16_t i2c_addr = config->i2c_slave_addr;
|
|
||||||
uint8_t buf[3];
|
uint8_t buf[3];
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
LOG_DBG("PCA95XX[0x%X]: Write: REG[0x%X] = 0x%X, REG[0x%X] = "
|
LOG_DBG("PCA95XX[0x%X]: Write: REG[0x%X] = 0x%X, REG[0x%X] = "
|
||||||
"0x%X", i2c_addr, reg, (value & 0xFF),
|
"0x%X", config->bus.addr, reg, (value & 0xFF),
|
||||||
(reg + 1), (value >> 8));
|
(reg + 1), (value >> 8));
|
||||||
|
|
||||||
buf[0] = reg;
|
buf[0] = reg;
|
||||||
sys_put_le16(value, &buf[1]);
|
sys_put_le16(value, &buf[1]);
|
||||||
|
|
||||||
ret = i2c_write(i2c_master, buf, sizeof(buf), i2c_addr);
|
ret = i2c_write_dt(&config->bus, buf, sizeof(buf));
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
*cache = value;
|
*cache = value;
|
||||||
} else {
|
} else {
|
||||||
LOG_ERR("PCA95XX[0x%X]: error writing to register 0x%X "
|
LOG_ERR("PCA95XX[0x%X]: error writing to register 0x%X "
|
||||||
"(%d)", i2c_addr, reg, ret);
|
"(%d)", config->bus.addr, reg, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -359,7 +345,6 @@ static int gpio_pca95xx_config(const struct device *dev,
|
||||||
|
|
||||||
#if (CONFIG_GPIO_LOG_LEVEL >= LOG_LEVEL_DEBUG)
|
#if (CONFIG_GPIO_LOG_LEVEL >= LOG_LEVEL_DEBUG)
|
||||||
const struct gpio_pca95xx_config * const config = dev->config;
|
const struct gpio_pca95xx_config * const config = dev->config;
|
||||||
uint16_t i2c_addr = config->i2c_slave_addr;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Does not support disconnected pin */
|
/* Does not support disconnected pin */
|
||||||
|
@ -384,14 +369,14 @@ static int gpio_pca95xx_config(const struct device *dev,
|
||||||
ret = setup_pin_dir(dev, pin, flags);
|
ret = setup_pin_dir(dev, pin, flags);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
LOG_ERR("PCA95XX[0x%X]: error setting pin direction (%d)",
|
LOG_ERR("PCA95XX[0x%X]: error setting pin direction (%d)",
|
||||||
i2c_addr, ret);
|
config->bus.addr, ret);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = setup_pin_pullupdown(dev, pin, flags);
|
ret = setup_pin_pullupdown(dev, pin, flags);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
LOG_ERR("PCA95XX[0x%X]: error setting pin pull up/down "
|
LOG_ERR("PCA95XX[0x%X]: error setting pin pull up/down "
|
||||||
"(%d)", i2c_addr, ret);
|
"(%d)", config->bus.addr, ret);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -580,7 +565,7 @@ static int gpio_pca95xx_pin_interrupt_configure(const struct device *dev,
|
||||||
if ((mode != GPIO_INT_MODE_DISABLED) &&
|
if ((mode != GPIO_INT_MODE_DISABLED) &&
|
||||||
(BIT(pin) & drv_data->reg_cache.dir) != BIT(pin)) {
|
(BIT(pin) & drv_data->reg_cache.dir) != BIT(pin)) {
|
||||||
LOG_ERR("PCA95XX[0x%X]: output pin cannot trigger interrupt",
|
LOG_ERR("PCA95XX[0x%X]: output pin cannot trigger interrupt",
|
||||||
config->i2c_slave_addr);
|
config->bus.addr);
|
||||||
return -ENOTSUP;
|
return -ENOTSUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -612,7 +597,7 @@ static int gpio_pca95xx_pin_interrupt_configure(const struct device *dev,
|
||||||
GPIO_INT_MODE_DISABLED);
|
GPIO_INT_MODE_DISABLED);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
LOG_ERR("PCA95XX[0x%X]: failed to configure interrupt "
|
LOG_ERR("PCA95XX[0x%X]: failed to configure interrupt "
|
||||||
"on pin %d (%d)", config->i2c_slave_addr,
|
"on pin %d (%d)", config->bus.addr,
|
||||||
config->int_gpio.pin, ret);
|
config->int_gpio.pin, ret);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
@ -678,14 +663,10 @@ static int gpio_pca95xx_init(const struct device *dev)
|
||||||
const struct gpio_pca95xx_config * const config = dev->config;
|
const struct gpio_pca95xx_config * const config = dev->config;
|
||||||
struct gpio_pca95xx_drv_data * const drv_data =
|
struct gpio_pca95xx_drv_data * const drv_data =
|
||||||
(struct gpio_pca95xx_drv_data * const)dev->data;
|
(struct gpio_pca95xx_drv_data * const)dev->data;
|
||||||
const struct device *i2c_master;
|
|
||||||
|
|
||||||
/* Find out the device struct of the I2C master */
|
if (!device_is_ready(config->bus.bus)) {
|
||||||
i2c_master = device_get_binding((char *)config->i2c_master_dev_name);
|
return -ENODEV;
|
||||||
if (!i2c_master) {
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
}
|
||||||
drv_data->i2c_master = i2c_master;
|
|
||||||
|
|
||||||
k_sem_init(&drv_data->lock, 1, 1);
|
k_sem_init(&drv_data->lock, 1, 1);
|
||||||
|
|
||||||
|
@ -704,7 +685,7 @@ static int gpio_pca95xx_init(const struct device *dev)
|
||||||
/* Configure GPIO interrupt pin */
|
/* Configure GPIO interrupt pin */
|
||||||
if (!device_is_ready(config->int_gpio.port)) {
|
if (!device_is_ready(config->int_gpio.port)) {
|
||||||
LOG_ERR("PCA95XX[0x%X]: interrupt GPIO not ready",
|
LOG_ERR("PCA95XX[0x%X]: interrupt GPIO not ready",
|
||||||
config->i2c_slave_addr);
|
config->bus.addr);
|
||||||
err = -ENODEV;
|
err = -ENODEV;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
@ -712,7 +693,7 @@ static int gpio_pca95xx_init(const struct device *dev)
|
||||||
ret = gpio_pin_configure_dt(&config->int_gpio, GPIO_INPUT);
|
ret = gpio_pin_configure_dt(&config->int_gpio, GPIO_INPUT);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
LOG_ERR("PCA95XX[0x%X]: failed to configure interrupt"
|
LOG_ERR("PCA95XX[0x%X]: failed to configure interrupt"
|
||||||
" pin %d (%d)", config->i2c_slave_addr,
|
" pin %d (%d)", config->bus.addr,
|
||||||
config->int_gpio.pin, ret);
|
config->int_gpio.pin, ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -733,8 +714,7 @@ static const struct gpio_pca95xx_config gpio_pca95xx_##inst##_cfg = { \
|
||||||
.common = { \
|
.common = { \
|
||||||
.port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(inst), \
|
.port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(inst), \
|
||||||
}, \
|
}, \
|
||||||
.i2c_master_dev_name = DT_INST_BUS_LABEL(inst), \
|
.bus = I2C_DT_SPEC_INST_GET(inst), \
|
||||||
.i2c_slave_addr = DT_INST_REG_ADDR(inst), \
|
|
||||||
.capabilities = \
|
.capabilities = \
|
||||||
(DT_INST_PROP(inst, has_pud) ? \
|
(DT_INST_PROP(inst, has_pud) ? \
|
||||||
PCA_HAS_PUD : 0) | \
|
PCA_HAS_PUD : 0) | \
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue