Skip to content

Conversation

@zacck
Copy link
Contributor

@zacck zacck commented Dec 9, 2025

Introduce I2C to SPI bridge driver GPIO support for the SC18IS6906 bridge from NXP.

This adds an GPIO controller available on the bridge from NXP. Ideally this enables one to add an GPIO extension through i2c

@zacck
Copy link
Contributor Author

zacck commented Dec 9, 2025

Odd, tests and compliance are passing for me locally, Compliance is failing on a line 239 of a 234 line file too.

@zacck zacck force-pushed the pr-sc18is606-gpio branch from 8461744 to 37a0517 Compare December 9, 2025 15:24
@zacck
Copy link
Contributor Author

zacck commented Dec 10, 2025

@kartben sorry for the ping but usually you can really see where I have messed up, please tell me how I could fix these compliance fails. Locally the test passes and the lines being complained about no longer exist, thank you so much for the time!

@zacck zacck force-pushed the pr-sc18is606-gpio branch from 37a0517 to fffe960 Compare December 11, 2025 14:16
Added a driver implementation for the GPIO Controller
on the sc18is606

Signed-off-by: Zacck Osiemo <[email protected]>
Apply device tree overlay for SC18IS606

Signed-off-by: Zacck Osiemo <[email protected]>
@zacck zacck force-pushed the pr-sc18is606-gpio branch from fffe960 to 2ec1456 Compare December 11, 2025 14:29
@sonarqubecloud
Copy link

@zacck zacck requested a review from Holt-Sun December 11, 2025 14:34
@zacck
Copy link
Contributor Author

zacck commented Dec 11, 2025

@mmahadevan108 it would be awesome if I could get your review on this please, Kind Regards

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces GPIO controller support for the NXP SC18IS606 I2C to SPI bridge device, enabling GPIO extension functionality through I2C.

Key Changes:

  • New GPIO driver implementation supporting 3 GPIO pins with configurable modes (input, push-pull output, open-drain output)
  • Device tree bindings and example overlays for the GPIO controller
  • Build system integration (Kconfig and CMakeLists)

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 13 comments.

Show a summary per file
File Description
drivers/gpio/gpio_sc18is606.c Main GPIO driver implementation with pin configuration, read/write operations, and hardware interface
drivers/gpio/Kconfig.sc18is606 Kconfig configuration for the GPIO driver with dependency on SPI_SC18IS606
drivers/gpio/Kconfig Integration of the new Kconfig file into the GPIO subsystem
drivers/gpio/CMakeLists.txt Build system integration to compile the driver when enabled
dts/bindings/gpio/nxp,sc18is606-gpio.yaml Device tree binding definition for the GPIO controller
dts/bindings/mfd/nxp,sc18is606.yaml Example usage in the MFD parent binding documentation
tests/drivers/build_all/mfd/app.overlay Test overlay demonstrating GPIO controller instantiation

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@@ -0,0 +1,18 @@
# Copyright (c) 2025 tinyvision.ai SPDX-License-Identifier: Apache-2.0
Copy link

Copilot AI Dec 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing space after copyright notice. There should be a space between "tinyvision.ai" and "SPDX-License-Identifier" on this line.

Copilot uses AI. Check for mistakes.
LOG_ERR("Failed to enable GPIO (%d)", ret);
}

data->conf |= pin_conf << (pin * 2);
Copy link

Copilot AI Dec 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The configuration data stored in data->conf is never cleared for the specific pin before setting new configuration. This means old configuration bits will remain set when reconfiguring a pin. The correct approach is to first clear the two-bit field for the pin being configured, then set the new value.

Suggested change
data->conf |= pin_conf << (pin * 2);
data->conf &= ~(SC18IS606_GPIO_CONF_MASK << (pin * 2));
data->conf |= (pin_conf & SC18IS606_GPIO_CONF_MASK) << (pin * 2);

Copilot uses AI. Check for mistakes.
Comment on lines +138 to +141
ret = nxp_sc18is606_transfer(cfg->bridge, enable_buf, sizeof(enable_buf), NULL, 0, NULL);
if (ret < 0) {
LOG_ERR("Failed to enable GPIO (%d)", ret);
}
Copy link

Copilot AI Dec 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The bridge is claimed but not released if the enable GPIO transfer fails. This creates a resource leak where the bridge remains locked. The release should occur in all error paths, or error handling should properly unwind the claim.

Copilot uses AI. Check for mistakes.
Comment on lines +146 to +149
ret = nxp_sc18is606_transfer(cfg->bridge, buf, sizeof(buf), NULL, 0, NULL);
if (ret < 0) {
LOG_ERR("Failed to configure GPIO (%d)", ret);
}
Copy link

Copilot AI Dec 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The bridge is not released if the configure GPIO transfer fails. This creates a resource leak where the bridge remains locked. The release at line 160 will only execute if this function completes normally, but not if an early return occurs due to error.

Copilot uses AI. Check for mistakes.
/*current port state*/
uint8_t output_state;

/*current port pin config*/
Copy link

Copilot AI Dec 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing space in comment. Should be "current port pin config" with spaces after the comment markers.

Suggested change
/*current port pin config*/
/* current port pin config */

Copilot uses AI. Check for mistakes.
Comment on lines +45 to +48
/*current port state*/
uint8_t output_state;

/*current port pin config*/
Copy link

Copilot AI Dec 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing space in comment. Should be "current port state" instead of running the comment directly into the code.

Suggested change
/*current port state*/
uint8_t output_state;
/*current port pin config*/
/* current port state */
uint8_t output_state;
/* current port pin config */

Copilot uses AI. Check for mistakes.
Comment on lines +154 to +155
}
if (flags & GPIO_OUTPUT_INIT_LOW) {
Copy link

Copilot AI Dec 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both GPIO_OUTPUT_INIT_HIGH and GPIO_OUTPUT_INIT_LOW could theoretically be set together (though unlikely). The current implementation would set the pin high first, then low. Consider making these mutually exclusive checks with an else-if statement to clarify the intended behavior.

Suggested change
}
if (flags & GPIO_OUTPUT_INIT_LOW) {
} else if (flags & GPIO_OUTPUT_INIT_LOW) {

Copilot uses AI. Check for mistakes.
# SPDX-License-Identifier: Apache-2.0


description: GPIO Controller part for the SC18IS606 bridge
Copy link

Copilot AI Dec 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inconsistent documentation format: The description should end with a period for consistency with standard documentation practices.

Suggested change
description: GPIO Controller part for the SC18IS606 bridge
description: GPIO Controller part for the SC18IS606 bridge.

Copilot uses AI. Check for mistakes.
Comment on lines +143 to +144
data->conf |= pin_conf << (pin * 2);
buf[1] = data->conf;
Copy link

Copilot AI Dec 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Potential race condition: The pin configuration function modifies data->conf without any locking mechanism. If multiple threads call gpio_sc18is606_pin_configure concurrently for different pins, they could overwrite each other's configuration updates since data->conf is shared state. The claim/release only protects the hardware access, not the software state.

Copilot uses AI. Check for mistakes.
Comment on lines +68 to +79
buf[1] &= ~mask;
buf[1] |= (value & mask);
buf[1] ^= toggle;

ret = nxp_sc18is606_transfer(cfg->bridge, buf, sizeof(buf), NULL, 0, NULL);

if (ret < 0) {
LOG_ERR("Failed to write to GPIO (%d)", ret);
return ret;
}

data->output_state = buf[1];
Copy link

Copilot AI Dec 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Potential race condition: The output_state is read, modified, and written without proper synchronization. If multiple threads call port_set_raw concurrently, they could overwrite each other's updates since they all read the same initial value of data->output_state before applying their changes.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants