-
Notifications
You must be signed in to change notification settings - Fork 8.4k
drivers: gpio: Introduce SC18IS606 GPIO Extension drivers #100743
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
f45ac52 to
8461744
Compare
|
Odd, tests and compliance are passing for me locally, Compliance is failing on a line 239 of a 234 line file too. |
8461744 to
37a0517
Compare
|
@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! |
37a0517 to
fffe960
Compare
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]>
fffe960 to
2ec1456
Compare
|
|
@mmahadevan108 it would be awesome if I could get your review on this please, Kind Regards |
There was a problem hiding this 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 | |||
Copilot
AI
Dec 14, 2025
There was a problem hiding this comment.
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.
| LOG_ERR("Failed to enable GPIO (%d)", ret); | ||
| } | ||
|
|
||
| data->conf |= pin_conf << (pin * 2); |
Copilot
AI
Dec 14, 2025
There was a problem hiding this comment.
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.
| data->conf |= pin_conf << (pin * 2); | |
| data->conf &= ~(SC18IS606_GPIO_CONF_MASK << (pin * 2)); | |
| data->conf |= (pin_conf & SC18IS606_GPIO_CONF_MASK) << (pin * 2); |
| 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); | ||
| } |
Copilot
AI
Dec 14, 2025
There was a problem hiding this comment.
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.
| ret = nxp_sc18is606_transfer(cfg->bridge, buf, sizeof(buf), NULL, 0, NULL); | ||
| if (ret < 0) { | ||
| LOG_ERR("Failed to configure GPIO (%d)", ret); | ||
| } |
Copilot
AI
Dec 14, 2025
There was a problem hiding this comment.
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.
| /*current port state*/ | ||
| uint8_t output_state; | ||
|
|
||
| /*current port pin config*/ |
Copilot
AI
Dec 14, 2025
There was a problem hiding this comment.
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.
| /*current port pin config*/ | |
| /* current port pin config */ |
| /*current port state*/ | ||
| uint8_t output_state; | ||
|
|
||
| /*current port pin config*/ |
Copilot
AI
Dec 14, 2025
There was a problem hiding this comment.
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.
| /*current port state*/ | |
| uint8_t output_state; | |
| /*current port pin config*/ | |
| /* current port state */ | |
| uint8_t output_state; | |
| /* current port pin config */ |
| } | ||
| if (flags & GPIO_OUTPUT_INIT_LOW) { |
Copilot
AI
Dec 14, 2025
There was a problem hiding this comment.
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.
| } | |
| if (flags & GPIO_OUTPUT_INIT_LOW) { | |
| } else if (flags & GPIO_OUTPUT_INIT_LOW) { |
| # SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
|
|
||
| description: GPIO Controller part for the SC18IS606 bridge |
Copilot
AI
Dec 14, 2025
There was a problem hiding this comment.
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.
| description: GPIO Controller part for the SC18IS606 bridge | |
| description: GPIO Controller part for the SC18IS606 bridge. |
| data->conf |= pin_conf << (pin * 2); | ||
| buf[1] = data->conf; |
Copilot
AI
Dec 14, 2025
There was a problem hiding this comment.
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.
| 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]; |
Copilot
AI
Dec 14, 2025
There was a problem hiding this comment.
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.



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