diff --git a/doc/releases/release-notes-4.0.rst b/doc/releases/release-notes-4.0.rst index d13c4233726..48f57ad7137 100644 --- a/doc/releases/release-notes-4.0.rst +++ b/doc/releases/release-notes-4.0.rst @@ -212,6 +212,9 @@ Drivers and Sensors * GPIO + * tle9104: Add support for the parallel output mode via setting the properties ``parallel-out12`` and + ``parallel-out34``. + * Hardware info * I2C diff --git a/drivers/gpio/gpio_tle9104.c b/drivers/gpio/gpio_tle9104.c index 9108c4d916a..1bbead5281b 100644 --- a/drivers/gpio/gpio_tle9104.c +++ b/drivers/gpio/gpio_tle9104.c @@ -22,6 +22,8 @@ struct tle9104_gpio_config { struct gpio_driver_config common; /* parent MFD */ const struct device *parent; + bool parallel_mode_out12; + bool parallel_mode_out34; }; struct tle9104_gpio_data { @@ -80,6 +82,16 @@ static int tle9104_gpio_pin_configure(const struct device *dev, gpio_pin_t pin, return -ENOTSUP; } + if (config->parallel_mode_out12 && pin == 1) { + LOG_ERR("cannot configure OUT2 if parallel mode is enabled for OUT1 and OUT2"); + return -EINVAL; + } + + if (config->parallel_mode_out34 && pin == 3) { + LOG_ERR("cannot configure OUT4 if parallel mode is enabled for OUT3 and OUT4"); + return -EINVAL; + } + k_mutex_lock(&data->lock, K_FOREVER); if ((flags & GPIO_OUTPUT_INIT_LOW) != 0) { @@ -110,6 +122,16 @@ static int tle9104_gpio_port_set_masked_raw(const struct device *dev, uint32_t m struct tle9104_gpio_data *data = dev->data; int result; + if (config->parallel_mode_out12 && (BIT(1) & mask) != 0) { + LOG_ERR("cannot set OUT2 if parallel mode is enabled for OUT1 and OUT2"); + return -EINVAL; + } + + if (config->parallel_mode_out34 && (BIT(3) & mask) != 0) { + LOG_ERR("cannot set OUT4 if parallel mode is enabled for OUT3 and OUT4"); + return -EINVAL; + } + /* cannot execute a bus operation in an ISR context */ if (k_is_in_isr()) { return -EWOULDBLOCK; @@ -139,6 +161,16 @@ static int tle9104_gpio_port_toggle_bits(const struct device *dev, uint32_t mask struct tle9104_gpio_data *data = dev->data; int result; + if (config->parallel_mode_out12 && (BIT(1) & mask) != 0) { + LOG_ERR("cannot toggle OUT2 if parallel mode is enabled for OUT1 and OUT2"); + return -EINVAL; + } + + if (config->parallel_mode_out34 && (BIT(3) & mask) != 0) { + LOG_ERR("cannot toggle OUT4 if parallel mode is enabled for OUT3 and OUT4"); + return -EINVAL; + } + /* cannot execute a bus operation in an ISR context */ if (k_is_in_isr()) { return -EWOULDBLOCK; @@ -176,6 +208,7 @@ static int tle9104_gpio_init(const struct device *dev) { const struct tle9104_gpio_config *config = dev->config; struct tle9104_gpio_data *data = dev->data; + int result; LOG_DBG("initialize TLE9104 GPIO instance %s", dev->name); @@ -184,7 +217,7 @@ static int tle9104_gpio_init(const struct device *dev) return -EINVAL; } - int result = k_mutex_init(&data->lock); + result = k_mutex_init(&data->lock); if (result != 0) { LOG_ERR("unable to initialize mutex"); return result; @@ -199,6 +232,8 @@ static int tle9104_gpio_init(const struct device *dev) .port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(inst), \ }, \ .parent = DEVICE_DT_GET(DT_PARENT(DT_DRV_INST(inst))), \ + .parallel_mode_out12 = DT_PROP(DT_PARENT(DT_DRV_INST(inst)), parallel_out12), \ + .parallel_mode_out34 = DT_PROP(DT_PARENT(DT_DRV_INST(inst)), parallel_out34), \ }; \ \ static struct tle9104_gpio_data tle9104_gpio_##inst##_drvdata; \ diff --git a/drivers/mfd/mfd_tle9104.c b/drivers/mfd/mfd_tle9104.c index 313c59d5d78..710c6d1d8a5 100644 --- a/drivers/mfd/mfd_tle9104.c +++ b/drivers/mfd/mfd_tle9104.c @@ -36,6 +36,8 @@ #define TLE9104_CFG_CWDTIME_LENGTH 2 #define TLE9104_CFG_CWDTIME_POS 6 +#define TLE9104_CFG_OUT34PAR_POS 5 +#define TLE9104_CFG_OUT12PAR_POS 4 #define TLE9104_OFFDIAGCFG_DIAGFILTCFG_LENGTH 2 #define TLE9104_OFFDIAGCFG_DIAGFILTCFG_POS 4 @@ -101,6 +103,8 @@ struct tle9104_config { uint16_t diagnostic_filter_time; uint16_t overcurrent_shutdown_delay_time; uint16_t overcurrent_shutdown_threshold; + bool parallel_mode_out12; + bool parallel_mode_out34; }; struct tle9104_data { @@ -527,6 +531,16 @@ static int tle9104_init(const struct device *dev) tle9104_set_register_bits(®ister_cfg, TLE9104_CFG_CWDTIME_POS, TLE9104_CFG_CWDTIME_LENGTH, 0); + if (config->parallel_mode_out12) { + LOG_DBG("use parallel mode for OUT1 and OUT2"); + register_cfg |= BIT(TLE9104_CFG_OUT12PAR_POS); + } + + if (config->parallel_mode_out34) { + LOG_DBG("use parallel mode for OUT3 and OUT4"); + register_cfg |= BIT(TLE9104_CFG_OUT34PAR_POS); + } + result = tle9104_write_register(dev, TLE9104REGISTER_CFG, register_cfg); if (result != 0) { LOG_ERR("unable to write configuration"); @@ -598,6 +612,8 @@ static int tle9104_init(const struct device *dev) DT_INST_ENUM_IDX(inst, overcurrent_shutdown_delay_time), \ .overcurrent_shutdown_threshold = \ DT_INST_ENUM_IDX(inst, overcurrent_shutdown_threshold), \ + .parallel_mode_out12 = DT_INST_PROP(inst, parallel_out12), \ + .parallel_mode_out34 = DT_INST_PROP(inst, parallel_out34), \ }; \ \ static struct tle9104_data tle9104_##inst##_data; \ diff --git a/dts/bindings/mfd/infineon,tle9104.yaml b/dts/bindings/mfd/infineon,tle9104.yaml index f9a5512296e..f8b7bab2d8b 100644 --- a/dts/bindings/mfd/infineon,tle9104.yaml +++ b/dts/bindings/mfd/infineon,tle9104.yaml @@ -76,3 +76,11 @@ properties: description: overcurrent shutdown threshold in mA, default matches power on reset value + + parallel-out12: + type: boolean + description: Enables parallel mode for OUT1 and OUT2 + + parallel-out34: + type: boolean + description: Enables parallel mode for OUT3 and OUT4