drivers: mcp23xxx: add support for open-drain chip variants
Pin definitions should correctly reflect the actual drive mode of the GPIO controller, either push-pull or open drain. Signed-off-by: Armin Brauns <armin.brauns@embedded-solutions.at>
This commit is contained in:
parent
054cc09c88
commit
ede19a4337
5 changed files with 20 additions and 13 deletions
|
@ -49,7 +49,9 @@ Device Drivers and Devicetree
|
||||||
``microchip,mcp230xx`` and ``microchip,mcp23sxx`` should change their devicetree ``compatible``
|
``microchip,mcp230xx`` and ``microchip,mcp23sxx`` should change their devicetree ``compatible``
|
||||||
values to the specific chip variant, e.g. :dtcompatible:`microchip,mcp23017`.
|
values to the specific chip variant, e.g. :dtcompatible:`microchip,mcp23017`.
|
||||||
The ``ngpios`` devicetree property has been removed, since it is implied by the model name.
|
The ``ngpios`` devicetree property has been removed, since it is implied by the model name.
|
||||||
(:github:`65797`)
|
Chip variants with open-drain outputs (``mcp23x09``, ``mcp23x18``) now correctly reflect this in
|
||||||
|
their driver API, users of these devices should ensure they pass appropriate values to
|
||||||
|
:c:func:`gpio_pin_set`. (:github:`65797`)
|
||||||
|
|
||||||
Controller Area Network (CAN)
|
Controller Area Network (CAN)
|
||||||
=============================
|
=============================
|
||||||
|
|
|
@ -75,7 +75,7 @@ static int mcp230xx_bus_is_ready(const struct device *dev)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define GPIO_MCP230XX_DEVICE(inst, num_gpios) \
|
#define GPIO_MCP230XX_DEVICE(inst, num_gpios, open_drain) \
|
||||||
static struct mcp23xxx_drv_data mcp230xx_##inst##_drvdata = { \
|
static struct mcp23xxx_drv_data mcp230xx_##inst##_drvdata = { \
|
||||||
/* Default for registers according to datasheet */ \
|
/* Default for registers according to datasheet */ \
|
||||||
.reg_cache.iodir = 0xFFFF, .reg_cache.ipol = 0x0, .reg_cache.gpinten = 0x0, \
|
.reg_cache.iodir = 0xFFFF, .reg_cache.ipol = 0x0, .reg_cache.gpinten = 0x0, \
|
||||||
|
@ -93,6 +93,7 @@ static int mcp230xx_bus_is_ready(const struct device *dev)
|
||||||
.gpio_int = GPIO_DT_SPEC_INST_GET_OR(inst, int_gpios, {0}), \
|
.gpio_int = GPIO_DT_SPEC_INST_GET_OR(inst, int_gpios, {0}), \
|
||||||
.gpio_reset = GPIO_DT_SPEC_INST_GET_OR(inst, reset_gpios, {0}), \
|
.gpio_reset = GPIO_DT_SPEC_INST_GET_OR(inst, reset_gpios, {0}), \
|
||||||
.ngpios = num_gpios, \
|
.ngpios = num_gpios, \
|
||||||
|
.is_open_drain = open_drain, \
|
||||||
.read_fn = mcp230xx_read_port_regs, \
|
.read_fn = mcp230xx_read_port_regs, \
|
||||||
.write_fn = mcp230xx_write_port_regs, \
|
.write_fn = mcp230xx_write_port_regs, \
|
||||||
.bus_fn = mcp230xx_bus_is_ready, \
|
.bus_fn = mcp230xx_bus_is_ready, \
|
||||||
|
@ -102,17 +103,17 @@ static int mcp230xx_bus_is_ready(const struct device *dev)
|
||||||
CONFIG_GPIO_MCP230XX_INIT_PRIORITY, &gpio_mcp23xxx_api_table);
|
CONFIG_GPIO_MCP230XX_INIT_PRIORITY, &gpio_mcp23xxx_api_table);
|
||||||
|
|
||||||
#define DT_DRV_COMPAT microchip_mcp23008
|
#define DT_DRV_COMPAT microchip_mcp23008
|
||||||
DT_INST_FOREACH_STATUS_OKAY_VARGS(GPIO_MCP230XX_DEVICE, 8)
|
DT_INST_FOREACH_STATUS_OKAY_VARGS(GPIO_MCP230XX_DEVICE, 8, false)
|
||||||
#undef DT_DRV_COMPAT
|
#undef DT_DRV_COMPAT
|
||||||
#define DT_DRV_COMPAT microchip_mcp23009
|
#define DT_DRV_COMPAT microchip_mcp23009
|
||||||
DT_INST_FOREACH_STATUS_OKAY_VARGS(GPIO_MCP230XX_DEVICE, 8)
|
DT_INST_FOREACH_STATUS_OKAY_VARGS(GPIO_MCP230XX_DEVICE, 8, true)
|
||||||
#undef DT_DRV_COMPAT
|
#undef DT_DRV_COMPAT
|
||||||
#define DT_DRV_COMPAT microchip_mcp23016
|
#define DT_DRV_COMPAT microchip_mcp23016
|
||||||
DT_INST_FOREACH_STATUS_OKAY_VARGS(GPIO_MCP230XX_DEVICE, 16)
|
DT_INST_FOREACH_STATUS_OKAY_VARGS(GPIO_MCP230XX_DEVICE, 16, false)
|
||||||
#undef DT_DRV_COMPAT
|
#undef DT_DRV_COMPAT
|
||||||
#define DT_DRV_COMPAT microchip_mcp23017
|
#define DT_DRV_COMPAT microchip_mcp23017
|
||||||
DT_INST_FOREACH_STATUS_OKAY_VARGS(GPIO_MCP230XX_DEVICE, 16)
|
DT_INST_FOREACH_STATUS_OKAY_VARGS(GPIO_MCP230XX_DEVICE, 16, false)
|
||||||
#undef DT_DRV_COMPAT
|
#undef DT_DRV_COMPAT
|
||||||
#define DT_DRV_COMPAT microchip_mcp23018
|
#define DT_DRV_COMPAT microchip_mcp23018
|
||||||
DT_INST_FOREACH_STATUS_OKAY_VARGS(GPIO_MCP230XX_DEVICE, 16)
|
DT_INST_FOREACH_STATUS_OKAY_VARGS(GPIO_MCP230XX_DEVICE, 16, true)
|
||||||
#undef DT_DRV_COMPAT
|
#undef DT_DRV_COMPAT
|
||||||
|
|
|
@ -113,7 +113,7 @@ static int mcp23sxx_bus_is_ready(const struct device *dev)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define GPIO_MCP23SXX_DEVICE(inst, num_gpios) \
|
#define GPIO_MCP23SXX_DEVICE(inst, num_gpios, open_drain) \
|
||||||
static struct mcp23xxx_drv_data mcp23sxx_##inst##_drvdata = { \
|
static struct mcp23xxx_drv_data mcp23sxx_##inst##_drvdata = { \
|
||||||
/* Default for registers according to datasheet */ \
|
/* Default for registers according to datasheet */ \
|
||||||
.reg_cache.iodir = 0xFFFF, .reg_cache.ipol = 0x0, .reg_cache.gpinten = 0x0, \
|
.reg_cache.iodir = 0xFFFF, .reg_cache.ipol = 0x0, .reg_cache.gpinten = 0x0, \
|
||||||
|
@ -133,6 +133,7 @@ static int mcp23sxx_bus_is_ready(const struct device *dev)
|
||||||
.gpio_int = GPIO_DT_SPEC_INST_GET_OR(inst, int_gpios, {0}), \
|
.gpio_int = GPIO_DT_SPEC_INST_GET_OR(inst, int_gpios, {0}), \
|
||||||
.gpio_reset = GPIO_DT_SPEC_INST_GET_OR(inst, reset_gpios, {0}), \
|
.gpio_reset = GPIO_DT_SPEC_INST_GET_OR(inst, reset_gpios, {0}), \
|
||||||
.ngpios = num_gpios, \
|
.ngpios = num_gpios, \
|
||||||
|
.is_open_drain = open_drain, \
|
||||||
.read_fn = mcp23sxx_read_port_regs, \
|
.read_fn = mcp23sxx_read_port_regs, \
|
||||||
.write_fn = mcp23sxx_write_port_regs, \
|
.write_fn = mcp23sxx_write_port_regs, \
|
||||||
.bus_fn = mcp23sxx_bus_is_ready \
|
.bus_fn = mcp23sxx_bus_is_ready \
|
||||||
|
@ -143,14 +144,14 @@ static int mcp23sxx_bus_is_ready(const struct device *dev)
|
||||||
|
|
||||||
|
|
||||||
#define DT_DRV_COMPAT microchip_mcp23s08
|
#define DT_DRV_COMPAT microchip_mcp23s08
|
||||||
DT_INST_FOREACH_STATUS_OKAY_VARGS(GPIO_MCP23SXX_DEVICE, 8)
|
DT_INST_FOREACH_STATUS_OKAY_VARGS(GPIO_MCP23SXX_DEVICE, 8, false)
|
||||||
#undef DT_DRV_COMPAT
|
#undef DT_DRV_COMPAT
|
||||||
#define DT_DRV_COMPAT microchip_mcp23s09
|
#define DT_DRV_COMPAT microchip_mcp23s09
|
||||||
DT_INST_FOREACH_STATUS_OKAY_VARGS(GPIO_MCP23SXX_DEVICE, 8)
|
DT_INST_FOREACH_STATUS_OKAY_VARGS(GPIO_MCP23SXX_DEVICE, 8, true)
|
||||||
#undef DT_DRV_COMPAT
|
#undef DT_DRV_COMPAT
|
||||||
#define DT_DRV_COMPAT microchip_mcp23s17
|
#define DT_DRV_COMPAT microchip_mcp23s17
|
||||||
DT_INST_FOREACH_STATUS_OKAY_VARGS(GPIO_MCP23SXX_DEVICE, 16)
|
DT_INST_FOREACH_STATUS_OKAY_VARGS(GPIO_MCP23SXX_DEVICE, 16, false)
|
||||||
#undef DT_DRV_COMPAT
|
#undef DT_DRV_COMPAT
|
||||||
#define DT_DRV_COMPAT microchip_mcp23s18
|
#define DT_DRV_COMPAT microchip_mcp23s18
|
||||||
DT_INST_FOREACH_STATUS_OKAY_VARGS(GPIO_MCP23SXX_DEVICE, 16)
|
DT_INST_FOREACH_STATUS_OKAY_VARGS(GPIO_MCP23SXX_DEVICE, 16, true)
|
||||||
#undef DT_DRV_COMPAT
|
#undef DT_DRV_COMPAT
|
||||||
|
|
|
@ -171,6 +171,7 @@ static int setup_pin_pull(const struct device *dev, uint32_t pin, int flags)
|
||||||
static int mcp23xxx_pin_cfg(const struct device *dev, gpio_pin_t pin, gpio_flags_t flags)
|
static int mcp23xxx_pin_cfg(const struct device *dev, gpio_pin_t pin, gpio_flags_t flags)
|
||||||
{
|
{
|
||||||
struct mcp23xxx_drv_data *drv_data = dev->data;
|
struct mcp23xxx_drv_data *drv_data = dev->data;
|
||||||
|
const struct mcp23xxx_config *config = dev->config;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (k_is_in_isr()) {
|
if (k_is_in_isr()) {
|
||||||
|
@ -179,7 +180,8 @@ static int mcp23xxx_pin_cfg(const struct device *dev, gpio_pin_t pin, gpio_flags
|
||||||
|
|
||||||
k_sem_take(&drv_data->lock, K_FOREVER);
|
k_sem_take(&drv_data->lock, K_FOREVER);
|
||||||
|
|
||||||
if ((flags & GPIO_SINGLE_ENDED) != 0U) {
|
if ((bool)(flags & GPIO_SINGLE_ENDED) != config->is_open_drain ||
|
||||||
|
(bool)(flags & GPIO_LINE_OPEN_DRAIN) != config->is_open_drain) {
|
||||||
ret = -ENOTSUP;
|
ret = -ENOTSUP;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,6 +61,7 @@ struct mcp23xxx_config {
|
||||||
struct gpio_dt_spec gpio_reset;
|
struct gpio_dt_spec gpio_reset;
|
||||||
|
|
||||||
uint8_t ngpios;
|
uint8_t ngpios;
|
||||||
|
bool is_open_drain;
|
||||||
mcp23xxx_read_port_regs read_fn;
|
mcp23xxx_read_port_regs read_fn;
|
||||||
mcp23xxx_write_port_regs write_fn;
|
mcp23xxx_write_port_regs write_fn;
|
||||||
mcp23xxx_bus_is_ready bus_fn;
|
mcp23xxx_bus_is_ready bus_fn;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue