[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: Slackware 10.2 & Windows 98 & Windows XP Pro & ...
Posts: 30
Rep:
Welcome to the wonderful world that is the linux kernel.
As it is open source, you can indeed track what exactly is happening as far as you want.
As Syndacate has mentioned, the Documentation folder of the source tree is your friend. It explains the kernel subsystems, as well as documents some of the kernel device tree bindings.
What it does not document very well, is the hardware it drives. That's because that's all described already in the hardware's datasheet.
As you undoubtably already know, the IMX has as a number of hardware subsystems. One of them is the the HW pinmux system. Another other is the SPI peripheral. By the good old way of writing special memory-mapped registers, you can configure the hardware to do what you want. For SPI, instead of having to bitbang all the lines, you can let the hardware take care of most of the work, and just feed it or consume useful data. (As long as you service interrupts and stuff, and all the items a classic SPI driver would do).
Anyway, the spi-imx driver is just one of many SPI drivers the linux subsystem supports. It specifically knows how to talk to the IMX hardware. However, as with almost all hardware subsystems, it is kept agnostic of pincontrol. Instead, the higher-level abstraction above the SPI subsystem itself (https://elixir.bootlin.com/linux/lat...base/dd.c#L486) allows setting a specific pinmux for any newly probed device. If you specified those pinctrl-0 thingies in your device tree, pinctrl_bind_pins will be called from the pinctrl linux kernel subsystem, which eventually finds its way into the pinctrl-imx driver which is specific for doing pinctrl on imx devices.
Coming back to the actual question you had:
Quote:
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?
No. The spi-imx is the hardware implementation of the spi bus (the generic implementation being inside spi.c). All devices on that bus (which have to be specified in the device tree as well) are bound to other drivers. For example an spi screen/spi led chip/any chip connected on the bus would have a corresponding driver that uses generic, hw agnostic calls to spi_sync(), which eventually function-point all the way to the spi-imx code in your case.
The spidev is a special kind of device-driver that emulates a fake device. It is a "hack-driver", made for the soul purpose of forcing SPI communication out on the bus .. usually to be able to test it and scope it or whatever. In terms of architecture, it is more of a brain-fart-hack rather than a good example. But in any case and as mentioned before, the pinctrl is done somewhere totally different and has nothing to do with either the bus subsystem nor the spi device drivers themselves.
Eventually, you'll probably get there by going through code.. But it will take you some time. Possibly alot of it. I still would recommend you to simply order a working evualution kit of some other imx project with a working spi device tree, and go from there. But that's up to you Good luck.
Distribution: Whatever I've cobbled together through Yocto
Posts: 18
Original Poster
Rep:
Alright, I got to the root of the issue. And, because the cardinal sin of programming is not posting a write-up for the next poor bastard who comes along (even tho I doubt anyone will ever have this exact problem), here's what I got:
The key was pinctrl. According to the pinctrl source, (pinctrl_register() in pinctrl/core.c) to actually be able to use any pinctrl, you have to have the pinctrl-names = "default" (as above) at the minimum and then the corresponding pinctrl property. It's, for some reason, not an error to have a pinctrl property without the pinctrl-names setup correctly so I didn't ever see it fail. It does log to dev_dbg() but I could not for the life of me figure out where that actually logs to. Or maybe I didn't have something configured correctly? I don't know.
The only things I'm not quite sure about at the moment are the necessity to specify the pinmux setup for the gpio that cs-gpio is using and including it in the pinctrl.
Also, I'm aware that "rohm,dh2228fv" is not necessarily what I should be using but this project is already way behind schedule so I'll deal with that part later.
Distribution: Slackware 10.2 & Windows 98 & Windows XP Pro & ...
Posts: 30
Rep:
Glad to hear you figured it out!
Just for the record, dyndbg works if two conditions are met: 1) dyndbg kernel support is enabled as kernel compile option and 2) the logging for the subsystem is explicitly enabled. Again, the kernel docs explain this alot better then I can, but the gist is that a kernel cmdline option with some magic dyndbg statements in it would probably have done the trick in your case.
Distribution: Ubuntu, mainly. Too much stuff works out of the box O.o
Posts: 71
Rep:
Quote:
Originally Posted by T_Versicolor
Alright, I got to the root of the issue. And, because the cardinal sin of programming is not posting a write-up for the next poor bastard who comes along (even tho I doubt anyone will ever have this exact problem), here's what I got:
The key was pinctrl. According to the pinctrl source, (pinctrl_register() in pinctrl/core.c) to actually be able to use any pinctrl, you have to have the pinctrl-names = "default" (as above) at the minimum and then the corresponding pinctrl property. It's, for some reason, not an error to have a pinctrl property without the pinctrl-names setup correctly so I didn't ever see it fail. It does log to dev_dbg() but I could not for the life of me figure out where that actually logs to. Or maybe I didn't have something configured correctly? I don't know.
The only things I'm not quite sure about at the moment are the necessity to specify the pinmux setup for the gpio that cs-gpio is using and including it in the pinctrl.
Also, I'm aware that "rohm,dh2228fv" is not necessarily what I should be using but this project is already way behind schedule so I'll deal with that part later.
Anyway. Thanks, everyone!
Awesome! Glad you got it figured out! I just checked my most common DTS for SPI & it doesn't even have any pinctrl field. I guess they're mostly manufacturer specific parameters. This stuff seems like black magic sometimes.
I found that last part is especially true with DTB's, sometimes you just gotta take what you can get, and it's not 100% ideal.
Somebody should write a book on how to fill out DTB configurations, but I'm pretty sure that book would be a nightmare of a read, lol.
How did you track this field down in specific? Just statically staring at the source? You said the print log wasn't working.
Distribution: Whatever I've cobbled together through Yocto
Posts: 18
Original Poster
Rep:
Quote:
Originally Posted by Syndacate
Just statically staring at the source?
Ya, basically. I started looking at the SPI drivers to see where the pins are setup and then realized it wasn't there at all. So I tried figuring out where in the various structures pinmux information was stored, found that and searched around looking for where that got used. Eventually found pinctrl/core.c and saw the thing with the pinctrl names.
Quote:
Originally Posted by Syndacate
Somebody should write a book on how to fill out DTB configurations, but I'm pretty sure that book would be a nightmare of a read, lol.
Ya, I did a lot of research into the device tree and it looks like it's used kinda sorta however people want to use it. I read through the specification only to find that Raspberry Pi's hardware has a bunch of extra crap they put into their device tree files like __overrides__ and __overlay__ which aren't part of the original specification. But, hey, if you wanted to write that book, I'd donate to your patreon and contribute what little knowledge I have.
Last edited by T_Versicolor; 06-25-2019 at 07:48 AM.
Reason: accidentally a word
Distribution: Ubuntu, mainly. Too much stuff works out of the box O.o
Posts: 71
Rep:
Quote:
Originally Posted by T_Versicolor
Ya, basically. I started looking at the SPI drivers to see where the pins are setup and then realized it wasn't there at all. So I tried figuring out where in the various structures pinmux information was stored, found that and searched around looking for where that got used. Eventually found pinctrl/core.c and saw the thing with the pinctrl names.
Well damn good job at tracking it down, but very unfortunate you had to do it that way. I was hoping you found some Rosetta stone for DTB's or something, lol.
Quote:
Originally Posted by T_Versicolor
Ya, I did a lot of research into the device tree and it looks like it's used kinda sorta however people want to use it. I read through the specification only to find that Raspberry Pi's hardware has a bunch of extra crap they put into their device tree files like __overrides__ and __overlay__ which aren't part of the original specification. But, hey, if you wanted to write that book, I'd donate to your patreon and contribute what little knowledge I have.
Yeah that was similar conclusion is what I came to. There's some "standard" fields like "compatibility", but most of the fields seem to be manufacturer specific parameters for the driver, and without proper docs it's really hard to figure out what options are available and what they mean. Sometimes the source is about the only help you can get in that direction, unfortunately.
Wish I had the know-how to write the book, haha; though I think with how manufacturer dependent it all is, I'm not sure anybody could write a useful generic book on it.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.