[SOLVED] Need help with Device Tree for SPI Device
Linux - Embedded & Single-board computerThis forum is for the discussion of Linux on both embedded devices and single-board computers (such as the Raspberry Pi, BeagleBoard and PandaBoard). Discussions involving Arduino, plug computers and other micro-controller like devices are also welcome.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Distribution: Whatever I've cobbled together through Yocto
Posts: 18
Rep:
Need help with Device Tree for SPI Device
Hello all,
I'm a bit new to the embedded Linux world despite having about a decade of general embedded experience at this point. My trouble at the moment is that I'm trying to add a SPI device to an IMX7 board but for some reason it is not configuring the pads to be used for the SPI, they stay configured as GPIOs. If I use devmem, I can modify the memory location where the muxing takes place and see that it will transmit/receive data as I expect so I'm guessing it's just an issue with the device tree.
I've added this to a device tree include that is added to the board's devicetree after everything else.
Distribution: Slackware 10.2 & Windows 98 & Windows XP Pro & ...
Posts: 30
Rep:
I'd double check that you really are triggering the pinmux section. (Check dmesg for errors).
Secondly, are you 100% sure that dts ecspi1 corresponds to pad ecspi1? (They sometimes start from 0/1). That would explain that cs works (as you use it as gpio) while the rest seemingly does not.
Lastly, your pinmux settings of 0x2 are not really ok. Check the datasheet of the imx for more info, or at least check another dts example.
Distribution: Whatever I've cobbled together through Yocto
Posts: 18
Original Poster
Rep:
Quote:
Originally Posted by arre
I'd double check that you really are triggering the pinmux section. (Check dmesg for errors).
I've grep'ed through dmesg for just about everything I can think of and it appears to be behaving. Other pins are being setup appropriately.
Quote:
Originally Posted by arre
Secondly, are you 100% sure that dts ecspi1 corresponds to pad ecspi1? (They sometimes start from 0/1). That would explain that cs works (as you use it as gpio) while the rest seemingly does not.
As far as I can tell it's the correct one. ecspi0 isn't used anywhere in the rest of the tree. The datasheet indexes the SPI ports starting at 1 for some reason as well.
Quote:
Originally Posted by arre
Lastly, your pinmux settings of 0x2 are not really ok. Check the datasheet of the imx for more info, or at least check another dts example.
I've tried a ton of different configs. I lifted this from the ecspi2 which isn't really being used but seemed like it would be good to crib from.
Distribution: Ubuntu, mainly. Too much stuff works out of the box O.o
Posts: 71
Rep:
Quote:
Originally Posted by T_Versicolor
As far as I can tell it's the correct one. ecspi0 isn't used anywhere in the rest of the tree. The datasheet indexes the SPI ports starting at 1 for some reason as well.
I just last week saw when trying to figure out the mapping the data sheet listed spidev's 1-4, but the DTB is 0 based, so it's spidev0-3. So take that into account.
Are you able to post the original DTS w/o changes?
Distribution: Whatever I've cobbled together through Yocto
Posts: 18
Original Poster
Rep:
Quote:
Are you able to post the original DTS w/o changes?
There's not much else I've really changed from imx7d-phyboard-zeta-001.dts. I put the above lines as well as a bit to add a device to an I2C bus into a new include after the other includes.
Also, I did a little experiment and changed it from using the spi-imx to spi-gpio and it worked just fine. So I'm wondering now if there's not something I fucked up with the iomux that I just don't know about.
Distribution: Slackware 10.2 & Windows 98 & Windows XP Pro & ...
Posts: 30
Rep:
Quote:
I fucking hate these DTS's. Always a pain in the ass, docs never clear & concise.
Lol, you pefer the old way of actually having to recompile a different kernel for each board variation then?
Quote:
Also, I did a little experiment and changed it from using the spi-imx to spi-gpio and it worked just fine.
And how exactly did that look? Can you paste the full dts?
Cause.. The only way that would actually work, is if the other SPI pins were in GPIO mode. Assuming you did not change the pinmux, it indeed again points to the pinmux problem.
Since you manually forced the registers before, I'd guess you can do the same and just read them out?
Imx also provides sysfs and debugfs entries for reading out the current pinmux settings. Also check out the "NXP imx linux user manual" datasheet or something for more info. Don't remember by heart, but there is a very easy way to just dump the current pinmux of all pins. That will in all likelyhood point to what is going wrong.
Distribution: Whatever I've cobbled together through Yocto
Posts: 18
Original Poster
Rep:
Quote:
Your kernel was built with SPI support, right? Usually it's disabled by default.
Do you see the actual device in /dev/spidev... ?
Yup, there's SPI support and the device is in the /dev folder
Quote:
And how exactly did that look? Can you paste the full dts?
Do you want like literally everything or just the part that I modified? Cause this tree seems pretty big. I made a python script to pull everything together and there's quite a bit there. I guess I could also give you a dtb or something if you wanted...
Distribution: Ubuntu, mainly. Too much stuff works out of the box O.o
Posts: 71
Rep:
Quote:
Originally Posted by arre
Lol, you pefer the old way of actually having to recompile a different kernel for each board variation then?
Well that's not picnic either but the problem I've found with DTB's is simply that every board manufacturer has a bunch of different options which need to be added to the node and they're never clear in the docs about what they are and what needs to be set; then much Google-fu later you find whatever cryptic ass options the node needs and everything works. Maybe I'd feel differently if I had different board revs.
Quote:
Originally Posted by arre
Cause.. The only way that would actually work, is if the other SPI pins were in GPIO mode. Assuming you did not change the pinmux, it indeed again points to the pinmux problem.
Possibly, but I've had this same exact issue where the SPI won't work because of DTB options, but the same pins bitbang GPIO fine. Pinmux was fine in that case.
Quote:
Originally Posted by T_Versicolor
Yup, there's SPI support and the device is in the /dev folder.
Yeah my bet is on DTB params. Gotta find the SPI configuration docs for that specific chip.
Distribution: Ubuntu, mainly. Too much stuff works out of the box O.o
Posts: 71
Rep:
Quote:
Originally Posted by T_Versicolor
What are DTB params?
Just some extra fields that are manu specific and are passed to the driver via the DTB.
It's possible your board doesn't have any, I'm not sure, but it's what hosed me. I haven't used your family of boards though so take it with a grain of salt.
EDIT:
Does yours have a custom kernel (ie. something that manu tweaked, or include drivers, etc.)? If so, there's likely docs with that which describe these parameters which you can include in the DTS configuration. If there's no kernel modifications and no drivers supplied then you can ignore this possibility as obviously default Linux SPI drivers have default Linux SPI options.
Distribution: Whatever I've cobbled together through Yocto
Posts: 18
Original Poster
Rep:
Quote:
Originally Posted by Syndacate
Does yours have a custom kernel (ie. something that manu tweaked, or include drivers, etc.)? If so, there's likely docs with that which describe these parameters which you can include in the DTS configuration. If there's no kernel modifications and no drivers supplied then you can ignore this possibility as obviously default Linux SPI drivers have default Linux SPI options.
Not exactly. I'm building this via Yocto with a BSP supplied by Phytec which uses what I assume is a modified kernel since it's being pulled from their bitbucket. I'm not sure how I would check that tho. I did tweak this a little by pulling in a patch that I thought might help but didn't.
Distribution: Whatever I've cobbled together through Yocto
Posts: 18
Original Poster
Rep:
Ok, so I got desperate and started looking through the spi-imx driver in spi-imx.c. I'm rather new to this so I'm probably way the hell off here but I don't understand how this driver can work since the driver never references any sort of pinctrl. Is there any other way that the driver might attempt to setup the pins?
Distribution: Ubuntu, mainly. Too much stuff works out of the box O.o
Posts: 71
Rep:
Quote:
Originally Posted by T_Versicolor
Ok, so I got desperate and started looking through the spi-imx driver in spi-imx.c. I'm rather new to this so I'm probably way the hell off here but I don't understand how this driver can work since the driver never references any sort of pinctrl. Is there any other way that the driver might attempt to setup the pins?
That file (or there-abouts) is where those manufacturer specific DTB parameters would get processed. So look for them in there. I think you're on the right track.
Hard for me to say how it works without looking, and I'm by no means a kernel expert, but the equivalent of that file is where I go for params. There's also usually a doc by a similar name in the Documentation directory of the BSP.
EDIT: Look for function: "of_property_read_bool()" in that SPI driver file, that's where it looks for the parameters given in the DTB. May not be bool, it's a whole family of functions, but look for that prefix. As I said though, look for something by a similar name in the "Documentation" directory of the source tree. Mine has a whole .txt on SPI configuration with parameters you can use, what they do, etc.
Distribution: Whatever I've cobbled together through Yocto
Posts: 18
Original Poster
Rep:
Looks like these are the bindings for the driver:
Code:
Required properties:
- compatible :
- "fsl,imx1-cspi" for SPI compatible with the one integrated on i.MX1
- "fsl,imx21-cspi" for SPI compatible with the one integrated on i.MX21
- "fsl,imx27-cspi" for SPI compatible with the one integrated on i.MX27
- "fsl,imx31-cspi" for SPI compatible with the one integrated on i.MX31
- "fsl,imx35-cspi" for SPI compatible with the one integrated on i.MX35
- "fsl,imx51-ecspi" for SPI compatible with the one integrated on i.MX51
- "fsl,imx53-ecspi" for SPI compatible with the one integrated on i.MX53 and later Soc
- "fsl,imx8mq-ecspi" for SPI compatible with the one integrated on i.MX8M
- reg : Offset and length of the register set for the device
- interrupts : Should contain CSPI/eCSPI interrupt
- clocks : Clock specifiers for both ipg and per clocks.
- clock-names : Clock names should include both "ipg" and "per"
See the clock consumer binding,
Documentation/devicetree/bindings/clock/clock-bindings.txt
Recommended properties:
- cs-gpios : GPIOs to use as chip selects, see spi-bus.txt. While the native chip
select lines can be used, they appear to always generate a pulse between each
word of a transfer. Most use cases will require GPIO based chip selects to
generate a valid transaction.
Optional properties:
- num-cs : Number of total chip selects, see spi-bus.txt.
- dmas: DMA specifiers for tx and rx dma. See the DMA client binding,
Documentation/devicetree/bindings/dma/dma.txt.
- dma-names: DMA request names, if present, should include "tx" and "rx".
- fsl,spi-rdy-drctl: Integer, representing the value of DRCTL, the register
controlling the SPI_READY handling. Note that to enable the DRCTL consideration,
the SPI_READY mode-flag needs to be set too.
Valid values are: 0 (disabled), 1 (edge-triggered burst) and 2 (level-triggered burst).
However, that only lists the chipselect GPIO (which worked just fine) but makes no mention of how to supply the other pins necessary to do anything. The driver code doesn't call of_property_* directly that I've seen thus far. spi.c calls it to get a couple different properties but those are just CPOL/CPHA, register, etc.
Am I understanding the hierarchy correctly? The spi-imx driver is the bus itself and spidev driver is what's used to actually talk to what's on the bus, right? If so then it does make sense that the spi-imx would need to know which pads/pins to use, right?
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.