Skip to content

drivers: SPI: Adds CS flags from devicetree #26269

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

Merged
merged 27 commits into from
Jul 1, 2020
Merged

drivers: SPI: Adds CS flags from devicetree #26269

merged 27 commits into from
Jul 1, 2020

Conversation

JordanYates
Copy link
Collaborator

@JordanYates JordanYates commented Jun 18, 2020

The SPI drivers were previously ignoring the devicetree flags specified for CS pins.
This pull request allows flags such as GPIO_OPEN_SOURCE to be specified and used.
This resolves the issue raised in #26267.

Out of tree drivers that do not setup gpio_dt_flags will retain the same behaviour, as flags of 0x00 corresponds to the old push-pull default.

In the interest of making the diff smaller, ACTIVE_HIGH and ACTIVE_LOW from devicetree are not used to set the CS active levels as this is currently handled in an alternate struct. If it is desirable to use the CS active levels from devicetree, that can be a follow on PR.

Copy link
Collaborator

@tbursztyka tbursztyka left a comment

Choose a reason for hiding this comment

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

@mnkp Is this the idea you had a few months ago? I did not get it that time, sorry for this. And I overlooked the fact gpio_pin_t is 8bits, so it is possible to do all of this without bloating the struct. Quite the contrary in fact as we end up with 16 unused bits in the end.

Copy link
Collaborator

@pabigot pabigot left a comment

Choose a reason for hiding this comment

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

Some comments. Only blocker is resolution of whether devicetree active level flags should be respected or ignored; no change requested until we reach consensus.

@@ -129,11 +130,17 @@ extern "C" {
* to act as a CS line
* @param delay is a delay in microseconds to wait before starting the
* transmission and before releasing the CS line
* @param gpio_dt_flags is the devicetree flags corresponding to how the CS
* line should be driven. GPIO_ACTIVE_LOW and GPIO_ACTIVE_HIGH are ignored
* in favor of SPI_CS_ACTIVE_HIGH and SPI_CS_ACTIVE_LOW options in struct
Copy link
Collaborator

Choose a reason for hiding this comment

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

May need to update if devicetree flags are respected as suggested above.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The original documentation was to that effect. From @tbursztyka's review I gathered transitioning to the devicetree flags for active level wouldn't be possible due to non GPIO CS controllers

Copy link
Collaborator

Choose a reason for hiding this comment

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

See my comment below about an assert that would check SPI_CS_ACTIV_* vs GPIO_ACTIVE_* compliance

gpio_flags_t flags = spi_context_cs_active_level(ctx);
/* ACTIVE_HIGH & ACTIVE_LOW from DT must be ignored */
gpio_dt_flags_t flags = ctx->config->cs->gpio_dt_flags &
~GPIO_ACTIVE_LOW;
Copy link
Collaborator

@pabigot pabigot Jun 18, 2020

Choose a reason for hiding this comment

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

I'm going to disagree with @tbursztyka here, and would ask @mnkp to weigh in.

I propose that the active level flags from devicetree should be respected, as a particular signal may pass through an inverter in hardware. SPI_CS_ACTIVE, via spi_context_cs_{,in}active_value(), should still be used to determine the value passed to gpio_pin_set(), and affect the selection of GPIO_OUTPUT_level in gpio_pin_configure().

AFAICT SPI_CS_ACTIVE_ is only supported with GPIO (in-tree at least) so perhaps it should be deprecated.

Copy link
Collaborator

Choose a reason for hiding this comment

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

We used to have a controller that could manage that internally (an intel controller afaik). I am actually surprised to see that many controllers which have CS lines and are thus managing them, do not provide a way for the user to tweak the CS active mode, forcing the user to switch to a gpio line. Let's keep it at it is.

Copy link
Member

Choose a reason for hiding this comment

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

cs-gpios property attached to spi controller node is there strictly to describe a gpio pin (pin controlled by a GPIO driver) that the SPI driver should use. It cannot be used if the CS pin is to be driven by the SPI module itself. To configure a pin that is driven directly by the SPI module one would have to use pinctrl properties (which we don't support yet).

So in this case we should honor all the supported flags, including GPIO_ACTIVE_LOW. At some point SPI_CS_ACTIVE_ should be deprecated, definitely when we have pinctrl support. And if the following is the case

AFAICT SPI_CS_ACTIVE_ is only supported with GPIO (in-tree at least) so perhaps it should be deprecated.

we could deprecate SPI_CS_ACTIVE_ already.

Copy link
Collaborator

Choose a reason for hiding this comment

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

To configure a pin that is driven directly by the SPI module one would have to use pinctrl properties (which we don't support yet).

Thus let's deprecate once we support pinctrl. It does not make sens to deprecate if there is no replacement already available.

Copy link
Collaborator

Choose a reason for hiding this comment

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

From what I can tell @mnkp and I agree that the devicetree flags should define the base active level for GPIO control of CS. @tbursztyka can you accept this?

Whether SPI_CS_ACTIVE_HIGH is deprecated can be a separate discussion. The only in-tree uses of that flag are in drivers that return an error if it's set, so it doesn't seem worthwhile to make it to affect GPIO CS (overriding the devicetree flags), especially as there's agreement to deprecate once pinmux is fully implemented.

So it looks like there are changes to be made to both implementation and documention. Do we need to bring this to dev-review to try to get agreement on what those changes are?

Copy link
Collaborator

@tbursztyka tbursztyka Jun 22, 2020

Choose a reason for hiding this comment

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

From what I can tell @mnkp and I agree that the devicetree flags should define the base active level for GPIO control of CS. @tbursztyka can you accept this?

Yes. However SPI_CS_ACTIVE_* should be checked for compliance, so maybe an assert to verify that the gpio dt flags follows the SPI flag would be nice. (@JordanYates could you add this in your PR?)

Do we need to bring this to dev-review to try to get agreement on what those changes are?

This PR is pretty concise by itself and already gathered relevant stakeholders (reviewers list).

Let's bring the deprecation of SPI_CS_ACTIVE_* flags when there will be a pinctrl API. That's unrelated to that PR.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

CS active level is now taken from devicetree, with checks that it is equivalent to the SPI_CS_ACTIVE_* value.

@@ -55,6 +55,7 @@ struct mcp23s17_config {
const uint32_t freq;
const char *const cs_dev;
const uint32_t cs_pin;
const uint8_t cs_flags;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Since the structure is being modified it would be nice to adjust these to use the (new-ish) canonical types gpio_pin_t and gpio_dt_flags_t (after confirming that usage doesn't require gpio_flags_t). But I'd accept an "out of scope" judgment from the contributor.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

When going through the various drivers, I think I found 4 different ways that the SPI buses are handled through configuration. I would prefer to leave that out of this pull request, but wholeheartedly support a cleanup effort.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Actually, your comments make me think there is an actual issue in these drivers: it would be worth modifying these so instead of setting custom attributes in a custom *_config structure, that they would directly initialize their dedicated spi_cs_control attribute in their private data. That would lower the size of their *_config structure, and avoid unnecessary copy of these values.

That would be for another PR, nothing to be fixed here.

@galak galak requested a review from mbolivar-nordic June 19, 2020 01:43
Copy link
Member

@mnkp mnkp left a comment

Choose a reason for hiding this comment

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

@mnkp Is this the idea you had a few months ago?

Yes, the fact that SPI drivers don't fully honor cs-gpios property defined in DTS breaks the pattern (and the promise we make to the users) so this should be considered a bug.

gpio_flags_t flags = spi_context_cs_active_level(ctx);
/* ACTIVE_HIGH & ACTIVE_LOW from DT must be ignored */
gpio_dt_flags_t flags = ctx->config->cs->gpio_dt_flags &
~GPIO_ACTIVE_LOW;
Copy link
Member

Choose a reason for hiding this comment

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

cs-gpios property attached to spi controller node is there strictly to describe a gpio pin (pin controlled by a GPIO driver) that the SPI driver should use. It cannot be used if the CS pin is to be driven by the SPI module itself. To configure a pin that is driven directly by the SPI module one would have to use pinctrl properties (which we don't support yet).

So in this case we should honor all the supported flags, including GPIO_ACTIVE_LOW. At some point SPI_CS_ACTIVE_ should be deprecated, definitely when we have pinctrl support. And if the following is the case

AFAICT SPI_CS_ACTIVE_ is only supported with GPIO (in-tree at least) so perhaps it should be deprecated.

we could deprecate SPI_CS_ACTIVE_ already.

@mbolivar-nordic
Copy link
Contributor

Was this closed on purpose?

@JordanYates
Copy link
Collaborator Author

JordanYates commented Jun 20, 2020

It was not, not sure how I managed that...

@JordanYates JordanYates reopened this Jun 20, 2020
@JordanYates
Copy link
Collaborator Author

As far as I can tell, the CI failures are unrelated to this PR.

@pabigot
Copy link
Collaborator

pabigot commented Jun 22, 2020

@JordanYates Could you squash the first two commits? They really seem to belong together, especially since the second modifies what the first did.

@JordanYates
Copy link
Collaborator Author

@JordanYates Could you squash the first two commits? They really seem to belong together, especially since the second modifies what the first did.

Done

@mbolivar-nordic
Copy link
Contributor

At least some of the CI warnings-turned-errors seem relevant:

/home/buildslave/src/github.com/zephyrproject-rtos/zephyr/drivers/spi/spi_context.h: In function 'spi_context_cs_configure':
/home/buildslave/src/github.com/zephyrproject-rtos/zephyr/drivers/spi/spi_context.h:165:19: error: unused variable 'dt_level' [-Werror=unused-variable]
  165 |   gpio_dt_flags_t dt_level = ctx->config->cs->gpio_dt_flags &
      |                   ^~~~~~~~
/home/buildslave/src/github.com/zephyrproject-rtos/zephyr/drivers/spi/spi_context.h:164:19: error: unused variable 'ctx_level' [-Werror=unused-variable]
  164 |   gpio_dt_flags_t ctx_level = spi_context_cs_active_level(ctx);
      |                   ^~~~~~~~~
cc1: all warnings being treated as errors

@JordanYates JordanYates requested a review from tbursztyka June 23, 2020 00:22
Jordan Yates added 2 commits June 23, 2020 11:51
Add an additional option to the spi_cs_control struct that records how
the pin has been configured in devicetree. For drivers that are not
updated, the CS behaviour is the same as before (Push-Pull).

Use the devicetree knowledge with the GPIO subsystem so that the correct
physical pin levels for the CS pin are automatically selected.

Fixes #26267

Signed-off-by: Jordan Yates <[email protected]>
Adds the chip select devicetree flags to the spi_cs_control instance.

Signed-off-by: Jordan Yates <[email protected]>
Jordan Yates added 3 commits June 23, 2020 11:51
Adds the chip select devicetree flags to the spi_cs_control instance.

Signed-off-by: Jordan Yates <[email protected]>
Adds the chip select devicetree flags to the spi_cs_control instance.

Signed-off-by: Jordan Yates <[email protected]>
Adds the chip select devicetree flags to the spi_cs_control instance.

Signed-off-by: Jordan Yates <[email protected]>
@JordanYates
Copy link
Collaborator Author

JordanYates commented Jun 23, 2020

At least some of the CI warnings-turned-errors seem relevant:

Issues have been resolved.

@mbolivar-nordic
Copy link
Contributor

Can someone please merge? The buildkite failures look spurious to me; they're the usual timing related false negatives

@galak galak merged commit ab3e778 into zephyrproject-rtos:master Jul 1, 2020
@galak
Copy link
Collaborator

galak commented Jul 1, 2020

Merged by hand as the CI failures are not related to this PR at all.

@JordanYates JordanYates deleted the spi_cs_c99 branch July 1, 2020 23:09
@jfischer-no
Copy link
Collaborator

Who will fix all the broken boards and shields?

@JordanYates
Copy link
Collaborator Author

I didn't realize it at the time, but the late decision to use the active level from devicetree rather than the struct spi_control does indeed change the default behavior of the SPI drivers when the flags are not provided. As it wasn't part of the original pull request, I didn't make any modifications to boards etc.

@vanwinkeljan
Copy link
Member

Could we revert this PR as it breaks some of the shields?

@pabigot
Copy link
Collaborator

pabigot commented Jul 6, 2020

Could, but it's also fairly easy to fix:

git grep -wl cs-gpios -- '*/*.dts*' \
  | xargs sed -i -r -e '/cs-gpios/s@ 0>@ GPIO_ACTIVE_LOW>@g'
git grep -wl cs-gpios -- '*/*.overlay' \
  | xargs sed -i -r -e '/cs-gpios/s@ 0>@ GPIO_ACTIVE_LOW>@g'

does 90% of the work.

I'll do a PR for that then we can see which way to proceed.

@pabigot
Copy link
Collaborator

pabigot commented Jul 6, 2020

does 90% of the work.

No, it only handles devicetree. All the drivers that receive those flags also need to be updated, in part because we haven't addressed #23691.

I'd still rather see this fixed than revert.

@MaureenHelm
Copy link
Member

There's also a problem with tests/drivers/spi/spi_loopback

@jfischer-no
Copy link
Collaborator

jfischer-no commented Jul 7, 2020

Could we revert this PR as it breaks some of the shields?

#26670 fixes display shields, I had no time to go through the leftover I am not familiar with.

It is not always a flag in device-tree, probably there are still few drivers to adapt.

@jfischer-no jfischer-no mentioned this pull request Jul 7, 2020
NZSmartie added a commit to NZSmartie/zephyr that referenced this pull request Sep 10, 2020
The pull request zephyrproject-rtos#26269
drivers: SPI: Adds CS flags from devicetree
missed out on the APA102 led_strip driver, most likely due to the driver
not utilising the chip select signal until zephyrproject-rtos#25310
drivers: led_strip: Add support for external SPI CS on APA102 LED strips

Signed-off-by: Roman Vaughan <[email protected]>
MaureenHelm pushed a commit that referenced this pull request Sep 14, 2020
The pull request #26269
drivers: SPI: Adds CS flags from devicetree
missed out on the APA102 led_strip driver, most likely due to the driver
not utilising the chip select signal until #25310
drivers: led_strip: Add support for external SPI CS on APA102 LED strips

Signed-off-by: Roman Vaughan <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: API Changes to public APIs area: Sensors Sensors area: SPI SPI bus
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants